Buzz #20
31 декабря 2001

IM2 еще раз о наболевшем - Проблема вектора прерываний.

<b>IM2 еще раз о наболевшем</b> - Проблема вектора прерываний.
                      ЕЩЕ РАЗ О НАБОЛЕВШЕМ

Я уже писал подобную статью раньше, но, к сожалению, отправил ее
в  фидошную  эху  ZX.SPECTRUM,  откуда  получил только критику и
никакого позитивного результата. Теперь я повторюсь, но  уже  на
экранах  этого e-zina. Надеюсь, его авторитетные экраны и авторы
добавят  убедительности  моим   советам.   Многим   эти   советы
показались  и  снова  покажутся  неактуальными или неважными, но
суть в том, чтобы выслушать и по возможности воспринять их.

   Пункт 1 -> Проблема вектора прерываний
   
Всем известно, что для  эффективного  создания  любой  программы
нужно  использовать  прерывание  IM2,  но  иногда  используют не
совсем верный способ установки этих  прерываний.  Заранее  прошу
извинения  за  повторение  прописных истин, но для некоторых эти
истины не до конца  прописаны.  Так  вот,  в  классическом  виде
установка прерываний IM2 происходит следующим путём:

а) создание таблицы  прерываний;
б)  установка  указателя  на   подпрограмму прерывания;
в) запрещение текущих прерываний;
г) установка нового вектора таблицы прерываний;
д) переход в режим IM2;
е)  разрешение уже вновь установленных прерываний IM2.
 
В этом месте, конечно, многие скажут: "Да, все верно, так это  и
происходит"  -  но некоторые "экономы" сразу заметят то, что они
пропускают один или несколько из вышеперечисленных шагов.  Сразу
проясню,  что же происходит, если не совсем корректно установить
прерывания IM2. Все достаточно просто:  в  момент  возникновения
самого  прерывания,  переход программы происходит не совсем в ту
подпрограмму, которая задумана, и даже вовсе в  случайное  место
памяти.  Главный  нюанс  всей проблемы в том, что это происходит
далеко не на всех компьютерах и  не  всегда  одинаково.  А  суть
этого  кроется  в  не  совсем  отлаженной  плате компьютера, как
правило, самопального. Решение же этой  проблемы  заключается  в
правильном способе установки в своей программе прерывания IM2, и
тогда на любом, самом трухлявом Пентагоне, все  будет  нормально
работать.   Приведу   для  примера  кусок  программы,  правильно
ставящей IM2, и если кто-то не хочет  углубляться  далее  в  эту
проблему, просто скопируйте этот участок себе в код.
 
       LD   HL,#BE00
       LD   DE,#BE01
       LD   BC,#1BF
       LD   A,H
       LD   (HL),C
       LDIR
       LD   (HL),#C3
       LD   HL,MY_INT_ROUTINE
       LD   (#BFC0),HL
       DI
       LD   I,A
       IM   2
       EI
       ....
 
Здесь  мы  задействуем  под  прерывание  IM2   области   памяти:
#BE00..#BF01 и #BFBF..#BFC1.

По сути, этот участок и есть классическая  установка  IM2.  Чаще
всего  некоторым кодерам не хочется жертвовать 257-ю байтами для
полной таблицы прерываний, и они устанавливают указатель таблицы
в различные места - кто куда придумает, в основном им полюбилась
область ПЗУ, из-за этого обычно и происходят фатальные зависы их
программ у некоторых юзеров.

Вот  вам  первый  постулат:

*  Нежелательно  устанавливать  вектор  прерываний  вне  области
памяти   #8000..#BF00.   В   области   памяти  #4000..#7f00  или
#C000..#FF00 не  стоит  ставить  вектор  таблицы,  поскольку  на
многих компьютерах с медленной памятью по этим адресам как раз и
располагается эта самая медленная память.  Фатальных  глюков  не
происходит,  но  сама  программа может работать заторможено. А в
области памяти #0000..#3F00  вообще  лучше  никогда  не  ставить
вектор  таблицы,  поскольку  там  невозможно  создать нормальную
таблицу прерываний.

А вот второй постулат:

*  При  создании  самой  таблицы  прерываний  корректнее   всего
заполнить всю таблицу (257 байт) одним и тем же значением.
 
Это, пожалуй, самое злосчастное место, ведь используя таблицу из
ПЗУ (т.е. заполненную мусором), или не заполняя её в ОЗУ, вы тем
самым допускаете вероятность перехода процессора в ложное  место
памяти, ведь никто со 100% вероятностью вам не гарантировал, что
переход  происходит  только  по  2  последним  байтам   (включая
Клайва).  Т.е.  я не говорю, что подобное явление носит массовый
характер, но, судя по нашему городу, могу утверждать, что с этим
часто  сталкивались  многие. Когда спек был больше распостранён,
да и программ делали больше, это явление встречалось часто, т.е.
то  у кого-то одно не работает, то у другого другое. Сейчас могу
точно сказать, что у одного из четырех  спектрумистов,  знакомых
мне  (включая  меня  :),  не  работает  ни  одна  из программ, с
хреновой таблицей прерываний. У меня, по странному капризу моего
Пентагона,  подобные программы могут проработать довольно долго,
но кончают  все  одинаково  -  сбросом  через  некоторое  время.
Напоследок приведу свой способ установки прерываний IM2, который
мне кажется удобней:
  
Где-то в начале программы:
  
       ORG  #8000
       DEFS 257,#81 ; в ALASMe заполняет 257 байт кодом #81
       ....
      
       ORG  #8181
       DI
       
       ; INTERRUPT ROUTINE
       
       EI
       RET
       ....
ENTRY:
       ....
       DI
       LD   A,#80
       LD   I,A
       IM   2
       EI
       ....
       
Таким образом таблица и  сопутствующие  действия  происходят  на
этапе   трансляции   программы,  что  избавляет  вас  от  лишних
действий, к тому  же  вы  как  бы  включаете  таблицу  в  размер
программы,  тем  самым  заранее  соглашаетесь с лишними занятыми
257-ю байтами, которые на самом деле никогда не были  решающими.
Кстати,  нетрудно  заметить,  что по адресу #8101 получаются 128
свободных  байт,  которые  можно  использовать  как  ячейки  для
переменных.   Необходимо   добавить,  что  если  в  конце  вашей
программы нужно передать управление системе,  то  лучше  сделать
это следующим способом:
 
       DI
       LD   A,#3F
       LD   I,A
       IM   1
       RET    (оооох ! чуть не написал rts ;-)
 
Почему это стоит делать именно таким образом, читайте далее.

   Пункт 2 -> Вектор прерываний и TR-DOS.
   
Создав  правильную  таблицу  прерываний  IM2  согласно   советам
предыдущего  пункта,  вы  ещё  не  до  конца  освобождаетесь  от
потенциальных проблем с прерываниями. Если вы захотите  вдруг  в
середине  программы,  где  уже  работает  ваше  прерывание  IM2,
загрузить что-нибудь с диска, то обычно  используете  для  этого
подпрограммы  TR-DOS.  Мы  сейчас  не рассматриваем загрузчики с
включенными  прерываниями  IM2,  это   уже   рассматривалось   в
различных  статьях. Следующий комментарий в равной степени будет
относиться и к стандартной работе с  TR-DOS  через  #3D13,  и  к
часто  используемым  быстрым  загрузчикам  (через  прямой  вызов
низкоуровневых подпрограмм  работы  с  ВГ93).  Перед  работой  с
TR-DOS  многие отключают музыку и прерывания посредством команды
DI.  Как  показывает  грустная  практика,  этого   недостаточно,
особенно  при  использовании  низкоуровневых подпрограмм TR-DOS.
Другими словами, перед вызовом любой подпрограммы  TR-DOS  лучше
перейти в режим прерывания IM1 c вектором #3F:

       DI
       LD   A,#3F
       LD   I,A
       IM   1
       CALL TR-DOS
       
Эта проблема очень похожа на описанную в предыдущем  пункте,  но
здесь  уже  происходит  конфликт  между  ВГ93 и процом. Особо не
углубляясь   в   детали,   советую   использовать    приведенную
конструкцию  для  доступа  в  TR-DOS.  При использовании быстрых
загрузчиков  с  использованием  низкоуровневых  вызовов   TR-DOS
хватит лишь добавления IM1/#3F в начало цикла счета секторов для
загрузки или записи.

   Пункт 3 -> Опрос клавиатуры.
  
Предполагаю, что к этому пункту вряд ли прислушаются, но не могу
не  поведать  о  такой  проблеме,  как опрос клавиатуры. Я думаю
многие не понаслышке  знакомы  с  таким  понятием,  как  дребезг
клавиатуры.  Я  с ним вплотную познакомился именно на Пентагоне.
Другими словами, при не очень  удачном  коде  опроса  клавиатуры
хрен  чего  наберешь  потом.  Сразу могу однозначно сказать, что
самый лучший способ опросить клавиатуру для  набора  какого-либо
текста... это использовать подпрограмму в ПЗУ Бейсика 48. Многие
могут мне возразить, что,  мол,  нам  не  пристало  пользоваться
подпрограммами  ПЗУ,  мы, мол, сами все можем написать. Но опять
же грустная практика показала, что  самая  удачная  подпрограмма
опроса  именно  для  набора текста - это ПЗУшная подпрограмма из
обработки прерывания IM1. Можно ее, конечно, просто  скопировать
оттуда, но не проще ли сделать RST#38?! Я использую ее следующем
образом :
 
       XOR  A
       LD   (23560),A
       LD   IY,#5C3A
       RST  #38
   
Этот участок  располагаю  внутри  моего  прерывания  IM2.  Такой
способ  конечно  не  отличается  большой  скоростью  выполнения,
однако он  очень  короткий  и  главное  -  довольно  безглючный.
Последнюю  нажатую  клавишу  затем  можно получить в любом месте
программы из ячейки по адресу 23560.  Дополнительную  информацию
про   такой   опрос   клавиатуры  можно  получить  из  различных
справочных книг по спеку. Всю эту, на первый взгляд,  ересь  для
продвинутого  кодера  я рассказываю не случайно. Дело в том, что
проблема всплывает в различных случаях, когда самые корректные с
виду  подпрограммы  опроса  клавиатуры  начинают  барахлить. Это
имеет место по различным причинам, в частности:

а) при использовании  конроллера  пц-клавы;
б) при изменении каких-то внутренних характеристик компа (обычно
Пентагона, будь он неладен) - как правило при старение железа;
в) турбирование проца.

Опять  же  отмечу,  что  это  происходит   редко,   однако   эти
прискорбные  случае  были  много  раз зафиксированы мною в нашем
регионе. Ну и, как вы уже  догадались,  единственная  программа,
которая   выдержала   проверку   по   глючности,  -  это  именно
подпрограмма опроса в ПЗУ Бейсика 48. Честно  скажу,  так  и  не
понял,  что  в  ней магического, может, потому, что она именно в
ПЗУ расположена, а может, и по  нескольким  особенностям  сразу,
только  она практически никогда не глючит. Если вы просто хотите
опросить несколько  клавиш  на  предмет  нажатости,  то  хороший
способ  -  воспользоваться  командой  IN A,(C), а не IN A,(254).
Другими словами, чтение из порта клавиатуры с  помощью  пары  BC
происходит    надежнее,   видимо,   вследствие   технологической
особенности Z80.
 
Все эти рекомендации многим могут показаться странными,  но  все
это проверено на собственном опыте. Практическое применение этих
методик вы можете найти в нашей  последней  игре  FARSPACE  (для
CC01), если залезете туда STS-ом. :)

fyrex@klax.tula.ru

----------------------------------------------------------------
by Fyrex/Mayhem (c) Buzz 2002
 



Другие статьи номера:

21st century's swapper - свапер 21 века или на спековской сцене сейчас сваперов почти нет?

Are the Gods against design? - какая демка круче LifeForms или Stellar Contour?

ASCii 2002 final results - результаты ASCii'2002.

Booze charts - правила чартов.

CAFe 2002 rules - правила нового демопати в Казани.

Catch tne buzzards - Обратная связь.

CC'001 graphics compo review - обзор графики с CC'001.

Copyright notice - Газета BUZZ распространяется на условиях FREEWARE.

Dman's CC'001 report Dman's - отчет о CC'001.

Editorial - наконец-то дождались 20-й Buzz.

Forever'3 final results - результаты Forever'3.

How to make cool ASCII logo - как нарисовать крутое лого в ASCII.

I'm the only one in TNL! - Весь основной TNL уже давно забил на Спектрум...

IM2 еще раз о наболевшем - Проблема вектора прерываний.

Interview with Arty Noonzen - интервью с организатором Digital Reality.

Interview with Pheel - интервью с известным спектрумовским художником.

List of voters - не обьективные и устаревшие результаты анкетирования.

Mast is a skinflint?! - Freeman откывает правду про Mast'a.

Mukpockon - рассуждение Stanly на уже надоевшую тему 'Demo vs Game'.

Navigation - новая крутая оболочка! Как с ней управляться?

Paracels speaking - новости от: BrainWave, CPU, Demiurge Ash, Digital Reality, Excess, Extreme, Fenomen, Freeart.

Paracels speaking - новости от: GAS13, Hardwave Crew, Hooy-Program, Mayhem, OCA, Perspective Group, Phantasy, Phantom Family, Placebo, POS, Progress.

Paracels speaking - новости от: Rain Group, Raww Arse, Remedy, Skrju, Studio Stall, Techno Lab, 4D, Triebkraft, Wlodeck Black.

Paradox 2002 rules - правила демопати.

Phat 1 graphics compo review - обзор графики с Phat'1.

re:никология - о том как же людям приходило в голову самого себя обозвать.

Realise VS release - какими должны быть электронные журналы (рассуждает Diver).

Sceners VS newcomers - сценеры против ньюбов.

Stanly's CC'001 report - репортаж Stanly.

Support us - газете требуется помощь: Музыкантом, художник и авторов статей.

Thank you! - пишите нам!

What's next? - Следующий номер Buzz'a выйдет?

Who are the buzzards? - кто сделал BUZZ?!

ZpiXel review - обзор нового сайта посвященного графике на ZX Spectrum.

ZpiXel.Past,present & future - история и будущее проекта.

Абзац - Газета "АБзац": как всё начиналось.


Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
Мозжечек - Нездоровые сны: юмористический рассказ с участием персонажей со Спектрума.
Программирование - Как определить сколько килобайт у вашей тачки. Определение наличия у Компа музыкальной платы. Определение типа музыкальной платы. Определение количества тактова за одно прерывание. Проверка наличия 128Кб. Определение наличия теневого ОЗУ. Проверка наличия порта #FF. Определение наличия модемной платы. Определение CDOS-модема и порта к которому он подключен.
Вступление - пара слов о новом номере газеты.
Железяка - подробное описание компьютера Sprinter.
Бедный Кнок - Пауль Кнок, ефрейтор 193-го пехотного полка 18-й дивизии.

В этот день...   21 ноября