ZX Review #3-4
22 июля 1997
  TR-DOS  

TR-DOS для начинающих - Часть 1.

<b>TR-DOS для начинающих</b> - Часть 1.
┌──────────────────────────────┐
│                              │
│    TR-DOS ДЛЯ НАЧИНАЮЩИХ     │
│                              │
└──────────────────────────────┘

          В.Сироткин.

Продолжение.  Начало см. в ZX
РЕВЮ 1996 NN 1-2, 4-5, 6, 7-8,
ZX РЕВЮ 1997 NN 1-2.

  ПРОГРАММИРОВАНИЕ КОНТРОЛЛЕРА.
  ─────────────────────────────
   Из предыдущего  материала  мы
узнали, что компьютер общается с
контроллером   дисковода   через
специально выделенные порты. Так
как с этими портами нам и  пред-
стоит  в  дальнейшем   работать,
здесь еще раз  приводится  крат-
кая табличка  назначения  портов
ввода/вывода/управления контрол-
лера ТРДОС.

      ┌─────────────────────────────────────────────────┐
      │ ПОРТ #1F  - Регистр Состояния - ЧТЕНИЕ          │
      │ ПОРТ #1F  - Регистр Команд    - ЗАПИСЬ          │
      │ ПОРТ #3F  - Регистр Дорожки   - ЗАПИСЬ / ЧТЕНИЕ │
      │ ПОРТ #5F  - Регистр Сектора   - ЗАПИСЬ / ЧТЕНИЕ │
      │ ПОРТ #7F  - Регистр Данных    - ЗАПИСЬ / ЧТЕНИЕ │
      │                                                 │
      │ ПОРТ #FF  - Регистр Управления -ЗАПИСЬ          │
      │                                                 │
      │ - 0,1 биты - номер дисковода ('A'= 0,0)         │
      │ - 2   бит  - сброс ВГ93      (при=0)            │
      │ - 3   бит  - подготовиться   (при=1)            │
      │                                                 │
      │ - 4   бит  - сторона диска   (при=1 верх)       │
      │ - 5   -//--------------------//---------        │
      │ - 6   бит  - плотность       (при=0 двойная)    │
      │ - 7   -//--------------------//---------        │
      │                                                 │
      │ ПОРТ #FF  - Регистр Управления - ЧТЕНИЕ         │
      │                                                 │
      │ - 6  бит - строб байта данных (при =1 есть      │
      │                                      данные)    │
      │ - 7  бит - готовность         (при =1 готов)    │
      └─────────────────────────────────────────────────┘

   Как нам уже  известно, прямым
путем записать или  считать  ин-
формацию по этим портам команда-
ми OUT или IN  нам  не  удастся,
так как эти порты подключаются к
компьютеру  только  тогда, когда
включена ПЗУ  ТРДОС  и, соответ-
ственно, блокированы  все  порты
компютера.
   Возникает  закономерный  воп-
рос: "А что же делать ?". Дело в
том, что  в  адресном  простран-
стве ПЗУ  ТРДОС, которое  совпа-
дает с адресами, задействованны-
ми на перехват и включение ТРДОС
контроллера  (а как мы помним из
первой главы  -  это  промежуток
адресов  с #3D00 по #3DFF), есть
точка входа, как раз  предназна-
ченная для таких случаев.  (Спа-
сибо  программистам  -  хоть  ее
предусмотрели !)

              * * *
       ЭТО ТОЧКА С АДРЕСОМ
         #3D2F или #3D30.
              * * *

А выглядит эта точка в ПЗУ ТРДОС
вот так:140.
          #3D2F    NOP
          #3D30    RET2

   "Ну и что?  Как она может нам
помочь? Как за то время  включе-
ния ПЗУ ТРДОС нам  дать  команду
портам?" - воскликните вы! Очень
просто! Перед вызовом этой  точ-
ки командой  'JP' мы  занесем  в
стек сначала адрес возврата, за-
тем адрес подпрограммы ПЗУ  ДОС,
где есть нужная нам  подпрограм-
ма. По  команде  'RET'  в  точке
#3D30 процессор возьмет из стека
адрес  и  исполнит  подпрограмму
ПЗУ ТРДОС, т.к.  в  этот  момент
она будет подключена.
   Единственное   условие:   эта
подпрограмма в ПЗУ должна  окан-
чиваться командой 'RET' для  то-
го, чтобы все вернулось  на  тот
адрес возврата, который  мы  за-
несли в стек первым.
   Короче говоря, если нам  надо
исполнить какую-нибудь  подпрог-
рамму в ПЗУ ТРДОС, то наши  дей-
ствия:

   1) Занести в стек адрес, куда
вернется программа после  выхода
из ПЗУ ДОС.
   2) Занести в стек  адрес нуж-
ной подпрограммы ПЗУ ДОС.
   3) Дать команду JP #3D2F (или
#3D30).

   Такой способ вызова называет-
ся  "Косвенная  адресация  через
стек".
   Если нам необходимо, чтобы  в
ПЗУ исполнились две -  три  под-
программы, то в стек  загружают-
ся (после адреса возврата) два -
три адреса подпрограмм.  Послед-
ним  в стек  должен быть помещен
адрес подпрограммы, которая  бу-
дет выполняться первой!
   Вроде бы  ничего сложного, но
вот тут-то и начинаются неприят-
ности...
   Дело в том, что если содержи-
мое точки вызова #3D30 для  всех
версий ТР ДОС одинаково, то  АД-
РЕСА  ПОДПРОГРАММ-УТИЛИТ   ТРДОС
ДЛЯ РАЗЛИЧНЫХ ВЕРСИЙ  РАЗЛИЧНЫ !
Для версии 5.01 это одни адреса,
а для 5.03 это другие адреса.
   И вот, если Вы составите свою
программу, основываясь на  адре-
сах версии, которая зашита в ПЗУ
Вашего  контроллера, то  это  не
значит, что программа будет  ра-
ботать с контроллером  приятеля,
у которого другая версия ТР ДОС.
   Может статься, что в 50% слу-
чаев Ваша программа  просто  за-
виснет или, того хуже, -  запор-
тит Вашему  приятелю  данные  на
диске.
   Пример  из  практики:  автору
этой книги попалась адаптирован-
ная  под  диск программа 'WORD'-
текстовый редактор, которая была
рассчитана на версию ТРДОС-5.03.
(Загрузка самого редактора  тоже
производилась через подпрограммы
ПЗУ ТРДОС).
   Запущенная   с   контроллером
версии 5.01, эта программа уже в
процессе загрузки "успешно" фор-
матировала нулевую и первую  до-
рожки диска.
   После чего так же успешно за-
висала. Представьте себе: Вы бе-
рете диск с целым пакетом  прог-
рамм, запускаете редактор, а по-
том...диск приходится форматиро-
вать заново.
   И самое главное, что  никаких
надписей, с какой версией  ТРДОС
этот редактор работает...  Хоро-
шая адаптация - нечего сказать !
   При  ближайшем   рассмотрении
оказалось,  что  адреса  в   ПЗУ
5.03 подпрограммы "чтения секто-
ра"  в версии 5.01 лежат по дру-
гим адресам, а по этим адресам в
версии 5.01 расположена подпрог-
рамма "форматирование".

   Так вот правило НОМЕР ОДИН:

 Если Вы программируете  на  са-
 мом низком уровне, т.е. с выхо-
 дом на  подпрограммы  ТРДОС, то
 Ваша программа  должна  опреде-
 лять (или  запрашивать)  версию
 ТРДОС  и  затем  корректировать
 адреса вызовов подпрограмм ПЗУ.
 В крайнем случае Ваша  програм-
 ма  должна  выводить  на  экран
 НОМЕР  ВЕРСИИ  ТРДОС, на  какую
 программа адаптирована.
  Это правило хорошего тона !!!

   Далее в  примерах  будут при-
сутствовать адреса  и версии  ТР
ДОС 5.01, и  версии 5.03.

 За основу приняты  адреса  вер-
 сии 5.01 !!!  А  адреса  версии
 5.03  будут  даваться  рядом, в
 угловых скобках: < адрес >.

   Итак, точка входа у нас есть,
остались только адреса  подпрог-
рамм, которые бы работали с нуж-
ными портами.
   Таких подпрограмм в ПЗУ  мно-
жество. Но они так тесно  увяза-
ны друг с другом, что если выде-
лить  только  те, которые  после
команд  'IN'  или  'OUT'   сразу
имеют  команду  'RET', то  таких
подпрограмм окажется совсем нем-
ного...140.

  1. Запись в порт #1F (регистр команд).

Адреса в ПЗУ      Мнемоника
──────────────────────────────────────────────
#2F79  < #2FC3 >  OUT (#1F),A  ; подать команду
                  RET          ; вернуться


  2. Запись в порт #1F (регистр команд).

#3ED5  < #3EDF>   OUT (#1F),A   ; подать команду
                  LD A,(#5CD1)  ; опросить ОЗУ
                  CP #FF        ; вернуться, если
                  RET Z         ; там байт #FF


  3. Запись в порт #3F (регистр дорожки).

#1DFE  < #1E3A >  OUT (#3F),A
                  RET


  4. Запись в порт #3F (регистр дорожки).

#3E8B  < #3E95 >  OUT (#3F),A   ; номер дорожки
                  LD A,(#5CCD)  ; опросить ОЗУ
                  OR A          ; венуться, если
                  RET Z         ; там байт 00


  5. Запись в порт #FF (управление).

#1FB7  < #1FF3 >  OUT (#FF),A
                  RET


  6. Запись в порт #FF (управление).

#2EC2  < #2F0C >  OUT (#FF),A
                  RET


  7. Запись в любой порт  по регистру 'C'.

#2A09  < #2A53 >  OUT (C),A   ; номер порта в 'C'
                  RET2

   Вы, наверное,  заметили,  что
многих портов в этих подпрограм-
мах не хватает, а чтения из пор-
тов нет вообще!  Чтобы заставить
контроллер что-то  делать, необ-
ходимо  выполнить ряд действий в
совокупности.  Одной командой, в
большинстве  случаев,  не  обой-
тись.
   Весь процесс обмена  ДИСК <->
ПРОЦЕССОР состоит из 2,3,4  под-
программ ПЗУ, которые  выполняют
ряд  взаимосвязанных    действий
сразу с несколькими портами.  Но
даже с теми  подпрограммами, ко-
торые у нас уже есть, можно  вы-
полнить определенные действия.
   Например:  воздействовать  на
порт управления (#FF) и дать ко-
манду  первого  типа  (адреса  в
примерах - для версии 5.01).147.

  1. Сброс микросхемы ВГ93 и переход на 0 дорожку.

START  LD IX,ENDE     ; адрес возврата -> в стек
       PUSH IX
       LD IX,#1FB7    ; адрес п/п ДОС
                      ;  (запись в порт #FF)
       PUSH IX        ; занести в стек
       LD A,0         ; управляющая команда СБРОС
       JP #3D2F       ; исполнить п/п в ПЗУ
ENDE   RET            ; выйти вообще
2
!!! Кстати, если дать такую  ко-
манду, то потом, при нажатии  на
'МАГИК'  кнопку, вместо  'магик'
файла  Вы  получите  испорченный
диск, т.к. микросхема будет пос-
тоянно НЕ ГОТОВА по порту #FF и,
чтобы вывести ее из  этого  сос-
тояния, необходимо не только по-
дать в порт #FF 'готовность', но
и подать команду ПРЕРЫВАНИЕ, ко-
торая начисто отсутствует в под-
программе   обработки    'МАГИК'
кнопки !!!147.

  2. Выбор номера диска, плотности, подача готовности
     и выбор верхней стороны диска...

START  LD IX,ENDE       ; адрес возврата - в стек
       PUSH IX
       LD IX,#1FB7      ; адрес п/п ДОС (запись в
                        ; порт #FF)
       PUSH IX          ; в стек
       LD A,%00111100   ; управляющая команда:
                        ; диск 'A', и т.д
       JP #3D2F         ; исполнить п/п в ПЗУ
ENDE   RET              ; выйти вообще


  3. Поиск нужного цилиндра на диске.

START  LD C,#FF     ; порт  #FF в регистр 'C'
       LD A,#3C     ; готовность , диск A и тд.
       CALL TRDOS   ; записать в порт #FF

       LD C,#7F     ; регистр данных
       LD A,5       ; команда - найти 5-й  цилиндр
       CALL TRDOS   ; записать в регистр данных

       LD C,#1F     ; регистр команд
       LD A,#1C     ; команда ПОИСК ЦИЛИНДРА с
                    ; опущенными головками, с провер-
                    ; кой и с минимальной задержкой
       CALL TRDOS   ; дать команду на поиск

ENDE   RET          ; выход из программы

;- - - - - подпрограмма записи данных в порт - - -

TRDOS  LD IX,#2A09  ; адрес п/п в ПЗУ 'запись в
                    ; порт по регистру 'C' байта
                    ; из регистра 'A'
       PUSH IX
       JP #3D2F     ; исполнить и вернуться потом,
                    ; как из подпрограммы2

   Таким методом  можно  записы-
вать данные в  управляющий  порт
#FF, в регистры  ДОРОЖКИ, СЕКТО-
РА  и подавать команды для ВГ93,
но организовать диалог (т.е. об-
мен данными и  проверку) процес-
сор <-> контроллер очень затруд-
нительно.
   Вообще, обмен  данными  между
контроллером и процессором  дол-
жен идти  по следующему алгорит-
му:
    1.  Даем байт  управления  в
порт #FF. Так как этот порт под-
ключен к триггеру с защелкой, то
эта  информация  сохраняется  до
прихода следующего байта в  этот
порт  (выбираем  дисковод,  даем
подготовительную     готовность,
сторону диска и плотность).
    2.  Даем  в  РЕГИСТР команд,
порт #1F, байт КОМАНДЫ и  обяза-
тельно самая первая  команда пе-
ред командами  ЧТЕНИЕ  -  ЗАПИСЬ
должна  быть  команда    ПЕРВОГО
ТИПА, с модификатором  'опустить
головку на диск' (это связано со
схемотехническими  особенностями
всего контроллера ТРДОС).
    3. Начинаем опрашивать  порт
#FF на 7-й бит  (бит  готовности
микросхемы ВГ93) до тех пор, по-
ка  там  не установится ЕДИНИЦА,
т.е. наша команда выполнена.
    4. Если команда была  связа-
на с ЧТЕНИЕМ  или  ЗАПИСЬЮ, т.е.
команды типа 2 и типа 3, то сов-
местно с опросом  бита  7  порта
#FF необходимо перед каждым бай-
том ДАННЫХ, идущим  с диска  или
на диск, опрашивать 6-й бит пор-
та #FF  (строб  данных).  И если
бит 6 установился в  ЕДИНИЦУ, то
принять или передать байт в порт
#7F (регистр данных).
    5.  Как только бит  7  порта
#FF установится в ЕДИНИЦУ, можно
приступать  к  записи  следующей
команды (перед подачей следующей
команды можно дать небольшую за-
держку пустым циклом).
    6.  Опросить регистр СОСТОЯ-
НИЯ ВГ93 (порт #1F) и определить
правильность  выполненной коман-
ды.  Если  команда выполнена без
ошибок, и все в норме, то из ре-
гистра СОСТОЯНИЯ  считается байт
#80.
    7. Если в регистре СОСТОЯНИЯ
устанавливаются биты, то в зави-
симости от того, какой бит уста-
новился,  принимаются   соответ-
ствующие действия.
   Например:  при  команде  'за-
пись':
 - Если  установлен  бит  6,  то
придется прервать операции пода-
чей команды 'ПРЕРЫВАНИЕ'  и  вы-
вести  надпись  на  экран: "ДИСК
ЗАЩИЩЕН".
 - Если выставился бит 2  (поте-
ря данных), то придется или пов-
торить операцию заново, или вый-
ти с надписью на экране  "ошибка
записи".
 - Если бит 0 установлен в  еди-
ницу, то это значит, что  диско-
вод занят и придется ждать, пока
он не освободится.
   Поначалу  данная   последова-
тельность  кажется  длинной    и
очень сложной, но так как в  ПЗУ
ТРДОС эти подпрограммы уже  есть
в совокупности, то весь  процесс
выльется в  вызов  2-х  или  3-х
соответствующих  подпрограмм че-
рез стек из ПЗУ.
   Необходимо запомнить еще  од-
но правило:  правило  последова-
тельности подачи команд.

       ПРАВИЛО НОМЕР ДВА:

   Из-за  схемотехнической  осо-
бенности контроллера ТРДОС вклю-
чение двигателя дисковода и при-
жатие  головки  к диску произво-
дится только  командами  ПЕРВОГО
ТИПА, с модификатором  МАГНИТНАЯ
ГОЛОВКА В РАБОТЕ (т.е. когда го-
ловка  прижата  к  диску  и диск
раскручен).
   Третий бит  кода команды дол-
жен быть равен 1. Так как диско-
вод является медленнодействующим
устройством, то  после  выполне-
ния команды первого типа остает-
ся достаточно времени для подачи
следующих команд  ЧТЕНИЯ ИЛИ ЗА-
ПИСИ.
   Давайте рассмотрим  несколько
примеров  дисковых  процедур  из
ПЗУ.

           ПРИМЕР 1.
Подпрограмма  ЧТЕНИЯ  из  порта.
   Номер порта в регистре 'C'.
   Перед вызовом данной процеду-
ры НЕОБХОДИМО:  если  считывание
производится из регистра  данных
(т.е. считывание с диска), то  в
регистр КОМАНД (порт #1F)  нужно
записать команду, а в порт #FF -
записать готовность.
   Естественно,  головки   диска
должны быть установлены на  нуж-
ную дорожку и прижаты к диску.
   (Адреса в примерах для  ТРДОС
5.01). В регистр 'HL'  поместить
адрес ОЗУ, куда  будем считывать
информацию. В регистр 'C' -  но-
мер порта.140.

#3FDB < #3FE5 > IN A,(#FF) ; опрос выполнения и
                           ; строба данных
                AND #C0
                JR Z,#3FDB ; если не выполнено и нет
                           ; строба, то опять читаем
                           ; порт #FF
                RET M      ; выполнено - выход
                INI        ; чтение байта из порта
                           ; в адрес M (HL)
                JR #3FDB   ; повторим, если групповая
                           ; операция
2
   Вообще-то эта процедура пред-
назначена  для   чтения  массива
данных  с диска (из  СЕКТОРа или
ДОРОЖКИ), но ее можно  использо-
вать и для чтения  из  регистров
ДОРОЖКИ, УПРАВЛЕНИЯ  и  СЕКТОРА,
если в регистр 'C' занести соот-
ветствующий  порт. В этом случае 
подпрограмма сработает ОДИН раз,
и у Вас в адресе M (HL) окажется 
считанный байт.

    ВНИМАНИЕ!  РЕГИСТР СОСТОЯНИЯ
(ПОРТ #1F) ЭТОЙ ПРОЦЕДУРОЙ ОПРА-
ШИВАТЬ НЕЛЬЗЯ.   Так как при его
опросе бит ГОТОВНОСТЬ порта  #FF 
сбросится в 0 и все зациклится !

           ПРИМЕР 2.
Подпрограмма ЗАПИСЬ В ПОРТ.  Но-
мер порта в регистре 'C'.
   Эта процедура является обрат-
ной копией предыдущей процедуры.
Перед вызовом  данной  процедуры
НЕОБХОДИМО:
   Если  запись  производится  в
регистр данных  (т.е. запись  на
диск), то в регистр КОМАНД (порт
#1F) нужно записать команду, а в
порт #FF - записать  готовность.
Естественно, головки диска  дол-
жны быть установлены  на  нужную
дорожку и прижаты к диску. В ре-
гистр 'HL' поместить адрес  ОЗУ,
ОТКУДА будем записывать информа-
цию. В регистр 'C'- номер порта.140.

#3FC0 < #3FCA > IN A,(#FF)  ; опрос выполнения и
                            ; строба данных
                AND #C0
                JR Z,#3FC0  ; если не выполнено и
                            ; нет строба,то опять
                            ; читаем порт #FF
                RET M       ; выполнено - выход

                OUTI        ; запись байта в порт
                            ; из адреса  M (HL)
                JR #3FDB    ; повторим, если группо-
                            ; вая операция
2
   Этой   процедурой,   конечно,
можно  записать  байт  в   любой
порт, но для этого есть  другие,
менее длинные  процедуры (смотри
выше).
   Сразу же  возникает  законный
вопрос: "А как все  же  опросить
порт #1F, т.е.  Регистр  Состоя-
ния ?"
   Дело в том, что программисты,
которые писали ТРДОС, не предус-
мотрели  возможности  без  помех
опросить этот регистр  из  прог-
рамм  пользователя.  Все  опросы
порта #1F в ПЗУ тесно увязаны  с
другими  подпрограммами  чтения-
записи.
   Есть, правда, точка по адресу
#3F28 < #3F32 >, вызвав которую, 
можно опросить  Регистр  Состоя-
ния.  Но там сразу же происходит
и проверка битов с переходом  на 
адреса печати сообщений об ошиб-
ках и сбоях диска.
   Эту точку входа можно исполь-
зовать в  программах, в  которых
не  нарушена  системная  область 
BASIC'а  и  TRDOS, так  как  при  
возникновении каких-либо  ошибок  
система будет вызывать программу 
печати сообщений на экран.
   А если область системных  пе-
ременных нарушена ???  Есть  два
способа  выйти  из этого положе-
ния.
  Первый - если в программе про-
исходит ЧТЕНИЕ с диска, то после 
прочтения   сектора   (секторов)
произвести  подсчет  контрольной 
суммы  считанного  блока и срав-
нить с той  суммой, которая  из-
вестна (заранее просчитана).
   Если же происходит ЗАПИСЬ  на
диск, то тут придется или  запи-
сывать 2 раза один и тот же сек-
тор  (для уверенности), или  тут
же считать этот сектор обратно в
какое-нибудь свободное  место  в
ОЗУ и сравнить считанный блок  с
тем, который пытались  записать.
И если они не идентичны, то про-
бовать записать еще раз.  Как Вы 
понимаете, это  не лучший  выход
из положения !
   Второй способ - довольно  эк-
зотический, но очень эффективный  
и  позволяет   опросить  Регистр
Состояния в любое время из прог-
раммы пользователя.  Этот способ
основан на методе ВТОРОГО ПРЕРЫ-
ВАНИЯ! ("Вот так-так" - восклик-
нет внимательный читатель и нач-
нет  искать  те страницы  книги,
где написано, что ТРДОС не любит  
прерывания  ДВА.  Все  верно, не 
ищите и не торопитесь с выводами 
и руганью в адрес автора. Дело в
том, что действительно, большин-
ство подпрограмм ТРДОС  "боятся"
второго прерывания.  Это те под-
программы, которые  ответственны  
за  чтение/запись информации  на
диск.
   Мы же не будем  обращаться  к
диску, а опросим всего лишь порт
Состояния ВГ93). Итак...  В  ПЗУ
ТРДОС по адресу #2D3D < #2D87  >
есть  следующая   последователь-
ность команд.140.

;--подпрограмма 'опрос порта #1F'  #2D3D < #2D87 >

#2D3D < #2D87 > IN A,(#1F)   ; прочитать порт #1F
                AND #7F      ; выделим все уста-
                             ; новленные биты
                RET Z        ; вернемся, если НЕТ
                             ; ошибок
                DEC D        ; уменьшить регистр D
                PUSH HL      ; HL в стек
                PUSH DE      ; DE в стек
                JR NZ,#2D31  ; если регистр
                             ; 'D' <> 0 ,то
                             ; перейти выше,
                             ; а нам это не надобно
                HALT         ; Ждать прихода преры-
                             ; вающих импульсов INT
                ...          ; Далее
                             ; нас не интересует..
2
   Воспользуемся тем, что в этой
процедуре  есть  команда   HALT.
Если вспомнить, то, встретив эту
команду, процессор как бы приос-
танавливается  и  ждет   прихода
сигнала прерывания на вход  INT,
а  потом  уходит  на  исполнение
программы прерывания. В СПЕКТРУ-
МЕ импульсы прерывания следуют с 
частотой 50 Герц, и 50 раз в се-
кунду опрашивается клавиатура по 
прерыванию 1.  Мы  же, установив 
ПРЕРЫВАНИЕ 2,  перехватим  выход
из этой  процедуры на свою прог-
рамму.
   Единственное, не забудем  пе-
ред вызовом процедуры из ПЗУ за-
нести в регистр  'D'  ЕДИНИЦУ, а
на выходе, в прерывающей  проце-
дуре, продвинуть указатель СТЕКА
вверх по ОЗУ на 3 СЛОВА  (напри-
мер, три раза  дать команду 'POP
AF').
140.
; Программа вызова процедуры опроса порта #1F...

START LD A,#FD       ; занесем вектор прерывания,
                     ; равный,
      LD I,A         ; например, #FD (полный адрес
                     ; равен #FDFF)
      LD HL,VARIABLE ; адрес прерывающей процедуры
      LD (#FDFF),HL  ; занесем в адрес вектора
                     ; прерывания адрес программы
      LD D,1         ; регистр должен=1 для того,
                     ; чтобы программа в ПЗУ отра-
                     ; ботала ОДИН раз
      LD IX,#2D3D    ; адрес подпрограммы ТРДОС
                     ; (для версии ТРДОС 5.01 !)
      EI             ; прерывания разрешить
      HALT           ; приостановить процессор и
      IM 2           ; включить прерывание ДВА
      CALL TRDOS     ; вызвать программу из ТРДОС с
                     ; последующей отработкой прог-
                     ; раммы прерывания
      DI             ; запрет прерываниям
      IM 1           ; прерывание ОДИН
      EI             ; разрешить прерывания
      RET            ; выйти из программы

;- - - - - - - прерывающая программа - - - - -

VARIABLE  DI      ; запретим прерывание
          POP HL  ; извлечем из стека адрес
                  ; возврата на
          POP HL  ; программу в ПЗУ после HALT,
          POP HL  ; а также еще два слова
          IM 1    ; прерывание в 1
          RET     ; вернуться

;- - - - - - - - - - - -
TRDOS     PUSH IX  ; вызов программы из ПЗУ ТРДОС
          JP #3D2F ;
;- - - - - - - - - - - -
2
   После  запуска  программы   с
метки START она отработает, и мы 
получим на выходе в регистре 'A' 
НОЛЬ - если все в порядке  (пре-
рывающая  процедура  не включит-
ся).
   Если же Регистр Состояния со-
держал установленные биты, то  в
этом случае включится наша  пре-
рывающая программа, и  в  регис-
тре 'A' мы  получим  байт, кото-
рый можно в дальнейшем проанали-
зировать любым способом.
   Единственным недостатком  та-
кого метода является  резервиро-
вание ячеек ОЗУ под вектор - где
содержится  адрес    прерывающей
программы (в  нашем  случае  это
ячейки ОЗУ с  адресами  #FDFF  и
#FE00), а также  требование сох-
ранять 'старый' регистр 'I', ес-
ли переделываемая программа  ра-
ботала с прерыванием 2.
   Так как младший байт  вектора
прерывания всегда равен  #FF, то
таких адресов в  адресном  прос-
транстве компьютера насчитывает-
ся всего 255. Если исключить ад-
реса, падающие на ПЗУ (а их 63),
то нам останется 255  минус  63,
всего 192 произвольных адреса. А
это достаточно много.
   В ПЗУ ТРДОС есть еще несколь-
ко подпрограмм опроса порта #1F,
которые можно вызвать  таким  же
способом.  Одна из них находится
по адресу #3DAB < #3DB5 >.140.

#3DAB  < #3DB5 >  IN A,(#1F) ; прочитаем порт
                  AND 02     ; выделим бит 'ЗАПРОС
                             ; ДАННЫХ'
                             ; при операциях чтения
                             ; -записи
                             ; или бит 'ИНДЕКС'
                             ; при остальных опера-
                             ; циях

                 LD B,A      ; спрячем полученное
                             ; значение
          LOOP1  IN A,(#1F)  ; еще раз прочитаем
                             ; порт
                 AND 02      ; выделим бит
                 CP B        ; сравним с прежним
                 RET NZ      ; если бит установлен
                             ; - выйдем
                 INC DE      ; увеличим значение
                 LD A,E      ; если попытки не
                             ; кончились,
                 OR A        ;
                 JR NZ,LOOP1 ; то повторить чтение
                             ; порта
2
   Эту подпрограмму удобно вызы-
вать в случаях:
 - когда надо засинхронизировать
выполнение программы на  прохож-
дение Индексного отверстия, т.е.
на  новый оборот диска, или  уз-
нать, вставлен ли диск  и  готов
ли он?
 - при операциях чтения/записи -
ожидая сигнала ЗАПРОС ДАННЫХ.
   Как мы видим, в этой подпрог-
рамме отсутствует команда  HALT,
по  которой  ВТОРЫМ  прерыванием
точно  перехватывается  управле-
ние на  программу  пользователя.
Но в любом случае при  появлении
прерывающего импульса  INT  про-
цессор будет  отрабатывать  цикл
LOOP1, и перехват все равно сос-
тоится, а в регистре 'B'  или  в
'A' будет нужный нам байт с  вы-
деленным ВТОРЫМ битом.
   Как и  в  предыдущем  случае,
сначала надо  установить  Вектор
прерывания, а в прерывающей про-
грамме   передвинуть   Указатель
стека на ДВА байта вверх  (чтобы
вернуться не в ПЗУ, а в програм-
му пользователя). Перед  вызовом
подпрограммы ПЗУ в регистры 'DE' 
необходимо занести 00 для макси-
мального цикла опроса. Ну, и ес-
тественно,  дать  команды  EI  и
IM2.
140.
; Программа вызова процедуры  #3DAB < #3DB5 >

start  LD A,VECTOR             ; установим вектор
                               ; прерывания
       LD I,A
       LD HL,VARIABLE          ; занесем по адресу
                               ; вектора
       LD (VECTOR *256+255),HL ; адрес прерывающей
                               ; программы
       EI
       HALT
       LD DE,00       ; число попыток
       LD IX,#3DAB    ; программа в ПЗУ (для v.5.01)
       IM 2           ; второе прерывание
       CALL TRDOS     ; исполнить программу В ПЗУ и
                      ; прерывающую подпрограмму
       IM 1           ;
       RET            ; вернуться, в регистре 'A' и
                      ; 'B' будет значение из
                      ; порта #1F
;- - - - - - - - - -
TRDOS         PUSH IX
              JP #3D2F
;- - - - - - - - - -
VARIABLE     DI
             POP HL
             RET
;- - - - - - - - - -
2
   Для полноты  изложения  можно
еще привести адрес  подпрограммы
опроса порта  #1F  с  выделением
ЧЕТВЕРТОГО бита "ПОТЕРЯ ДАННЫХ",
если была операция  ЧТЕНИЯ/ЗАПИ-
СИ.  При  остальных  операциях -
бит "ГОЛОВКА в  ИСХОДНОМ СОСТОЯ-
НИИ".
   Вызывают  эту    подпрограмму
ОБЫЧНЫМ  способом,  без   всяких
ухищрений.  Единственное, в  ре-
гистр 'C' перед вызовом надо за-
нести число 1  -  для  отработки
подпрограммы всего один раз.
140.
;... процедура чтения порта #1F с выделением бита 4
;... перед вызовом дать комманду LD C,1
#3E30  < #3E3A >   IN A,(#1F) ; опросить порт
                   AND 04     ; выделить бит 4
                   RET NZ     ; если он установлен
                              ; - выйти
                   INC B      ; увеличить 'B'
                   DEC C      ; уменьшить 'C'
                   RET Z      ; если 'C'=0, то выйти
                   ...
2
   Теперь,  когда  мы  научились
опрашивать порт  Состояния,  нам
надо решить, что же  должна  де-
лать  программа  пользователя  в
случае установки какого-либо би-
та в этом порту, т.е. при  ошиб-
ке операций.

При операциях ЧТЕНИЯ/ЗАПИСИ:
 - Установлен
 2-й бит - 'ПОТЕРЯ ДАННЫХ'
       и/или
 3-й бит - 'ОШИБКА КОНТРОЛЬНОГО
           КОДА'
       и/или
 4-й бит - 'МАССИВ НЕ НАЙДЕН'
       и/или
 5-й бит - 'ОШИБКА ЗАПИСИ'

   В этом случае Вам  необходимо
повторить операцию  определенное
количество раз, и если  бит  все
так же будет установлен, то  это
значит, что у Вас сбойный  диск.
Обрываете   операцию    командой
'ПРИНУДИТЕЛЬНОЕ  ПРЕРЫВАНИЕ',  а
дальше поступаете так, как  счи-
таете нужным.

- Установлен  6-й  бит - 'ЗАЩИТА
ЗАПИСИ' (т.е. диск защищен).

   В этом случае также прерывае-
те  операцию  подачей    команды
'ПРЕРЫВАНИЕ' и  любезно  просите
снять  защиту  с  диска, или  не
просите...

- Сброшен 7-й  бит - 'ГОТОВНОСТЬ
ДИСКОВОДА'

   А в этом случае Ваша програм-
ма должна просто  подождать  го-
товности  дисковода  пустым цик-
лом. А теперь  давайте продолжим  
и посмотрим, что же еще полезно-
го есть в ПЗУ ТРДОС.

  Процедура определения НОМЕРА
     ЦИЛИНДРА под головками.
     ~~~~~~~~~~~~~~~~~~~~~~~
     Адрес #1DFA  < #1E36 >.

   После вызова этой подпрограм-
мы в регистре  'A'  возвращается
НОМЕР ЦИЛИНДРА;  этот  же  номер
сразу заносится в Регистр Дорож-
ки контроллера.  Также при своей
работе  подпрограмма  опрашивает
клавишу 'BREAK' = C/SH+SPACE   и
печатает сообщение, если клавиша
нажата.
   Эта подпрограмма является за-
конченной, т.е. не  нуждается  в
подготовительных  действиях.   К
сожалению, при ее работе  затра-
гивается ряд адресов в ОЗУ  Сис-
темных переменных.

Условия вызова:
- в регистр IY занести  значение
  #5C3A;
- в  регистре  'B'  должен  быть
  НОЛЬ;
- в адресе ОЗУ #5C3A должно быть
  значение #FF.

  Купируются, т.е. изменяются  в
  процессе  работы  подпрограммы
  адреса ОЗУ #5D16 и #5CCD.


Процедура 'Поиск нужной ДОРОЖКИ'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      Адрес #3E59 <#3E63>.

   При работе подпрограмма нахо-
дит на диске нужную ДОРОЖКУ (вы-
ходит на нужный ЦИЛИНДР и прижи-
мает ВЕРХНЮЮ или НИЖНЮЮ  головку
исходя  из   заданного    номера
ДОРОЖКИ). Также  опрашивает кла-
вишу 'BREAK' = C/SH+SPACE.  Под-
программа является законченной и
работает даже на неформатирован-
ном диске.

Условия вызова:
- в регистр IY занести  значение
  #5C3A;
- в  регистре  'A'  должен  быть
  НОМЕР требуемой ДОРОЖКИ. (Если
  номер 0 или четный, то дорожка
  верхняя, если нечетный -  ниж-
  няя);
- в адресе ОЗУ #5C3A должен быть
  байт #FF;
- в адресах #5CF6 И #5CF7 должны
  быть НУЛИ;
- в  адресе  #5CC8  должно  быть
  значение #83;
- в адрес  #5CFA  занести 08 или
  00.

  Купируется, т.е.  уничтожается
  содержимое ячеек памяти по ад-
  ресам #5D16 и #5CCD.


Процедура 'ПОИСК нужной ДОРОЖКИ'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  Адрес вызова #2EF0 < #2F3A >

   Это вторая процедура  ПОИСКА.
Она более приемлема  в  програм-
мах с дефицитом места в  памяти.
Во время своей работы  процедура
портит всего  лишь  одну  ячейку
памяти по адресу #5C00. При  ра-
боте  подпрограмма  находит   на
диске нужную ДОРОЖКУ (выходит на
нужный ЦИЛИНДР  и прижимает ВЕР-
ХНЮЮ или  НИЖНЮЮ головку, исходя
из  заданного  номера  ДОРОЖКИ).
Подпрограмма  является закончен-
ной  и работает даже на неотфор-
матированном диске.

Условия вызова:
- в адресе ОЗУ #5C00 должен быть
  НОЛЬ;
- в регистр  'C' заносится номер
  ДОРОЖКИ.

В эту программу можно войти  еще
по адресу:
        #2EFB < #2F45 >
В этом случае ячейка  ОЗУ  #5C00
не затрагивается, но перед вызо-
вом  подпрограммы  необходимо  в
порт  #FF  подать  БАЙТ  'ГОТОВ-
НОСТЬ, ВЕРХНЯЯ  СТОРОНА ДИСКА  и
т.д.', а в регистр 'C' перед вы-
зовом занести Номер ДОРОЖКИ.
   Если  кого-то  не  устраивают
данные методы поиска ДОРОЖКИ  на
диске, то можно написать  проце-
дуру 'ПОИСК  ДОРОЖКИ', основыва-
ясь на команде микросхемы 'ШАГ'.
   Правда,  это  будет  занимать
больше места в ОЗУ, и по быстро-
действию она будет намного  мед-
леннее всех подпрограмм ПОИСКА в
ПЗУ ТРДОС.
   А выглядит это приблизительно
так:
- подать команду 'ВОСТАНОВЛЕНИЕ'
- подать в порт #FF биты  ГОТОВ-
  НОСТИ  и  ВЕРХНЕЙ  ПОВЕРХНОСТИ
  (и др.);
- занести в регистр (например, в
  'C') НОМЕР ДОРОЖКИ;
- скорректировать номер  дорожки
  в НОМЕР ЦИЛИНДРА  И  в  повер-
  хность диска и давать  команду
  контроллеру  'ШАГ  ВПЕРЕД'  (с
  установленными  модификаторами
  'головку прижать, изменять ре-
  гистр  дорожки')    полученное
  число раз...
140.
; Подпрограмма поиска дорожки командой 'ШАГ'.

     ld c,#20    ; номер ДОРОЖКИ

     ld a,0      ; КОМАНДА ВОССТАНОВЛЕНИЕ
     call trdos  ; ЗАНЕСТИ В ПОРТ #1F

     ld a,#3C    ; готовность, ВЕРХ
     call trdos  ; занести в регистр #FF

     ld a,c      ; сдублировать номер дорожки
     or a        ; сбросить регистр флагов
     rra         ; разделить Номер дорожки на 2
                 ; в 'A' теперь номер ЦИЛИНДРА
     ld b,a      ; поместить в счетчик цикла
     jr nc ,STEP ; число 'Номер Дорожки' было
                 ; четное ? Если да - переход.

     ld a,#2C    ; нет - значит поверхность НИЗ
     call trdos  ; занести в порт #FF
STEP ld a,#5b    ; команда 'ШАГ ВПЕРЕД'
     call trdos  ; исполнить команду
     djnz  STEP  ; повторять 'B' чило раз.
                  ..........

; Метка "trdos" в этом случае является подпрограммой
; вызова процедур ТРДОС, которые напрямую работают с
; портами через точку #3D2F.
2
   Как мы видим  из примера, та-
кой  метод  довольмо  неудобен и
громоздок...


Процедура'ЗАПИСЬ ОДНОГО СЕКТОРА'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      Адрес #3F00 < #3F0A>

  Процедура записывает один сек-
тор на текущую ДОРОЖКУ (на кото-
рой стоят  головки  дисковода) и
выбранную поверхность.

Условия вызова:
- головка дисковода должна  быть
  выведена на нужную  дорожку  и
  прижата к диску;
- в адресах  #5D00/#5D01  должен
  быть помещен адрес ОЗУ, из ко-
  торого будут записываться  256
  байтов в сектор;
- в адрес #5CFF должен быть  по-
  мещен  ЛОГИЧЕСКИЙ НОМЕР СЕКТО-
  РА, (т.е.  нумерация  секторов
  начинается  с  0, подпрограмма
  потом скорректирует этот номер
  до физического).
- сохранить  данные  из   адреса
  #5CFE, так как этот адрес  при
  работе  купируется,  т.е.  ис-
  пользуется при работе.

  !!! Самым, пожалуй, сложным  в
условии вызова процедуры являет-
ся  условие  ПРИЖАТЬ  ГОЛОВКИ  К
ДИСКУ. Решается это простыми ме-
тодами. Так как  запись  сектора
является  как  бы   продолжением
действия программы  пользователя
в цепочке  действий,  то  данная
процедура  должна  следовать  за
процедурой ПОИСК НУЖНОЙ ДОРОЖКИ.
   А так  как  'ПОИСК'  является
командой,  которая  и  прижимает
головки к диску, вызвав програм-
му 'ЗАПИСЬ' сразу же после окон-
чания действия 'ПОИСКА', мы  без
труда выполним нужное условие.
   Если же в программе пользова-
теля вызов процедуры 'ПОИСК' от-
стоит от вызова 'ЗАПИСИ'  далеко
по времени, и программа не успе-
вает подать команду 'ЗАПИСЬ'  на
прижатые  головки,  то,   вызвав
повторно подпрограмму 'ПОИСК'  с
теми же параметрами, мы загрузим
(прижмем) головки.  Можно  также
дать команду дисководу  'ШАГ НА-
ЗАД' и следом 'ШАГ ВПЕРЕД' с мо-
дификаторами  кода  'ПРИЖАТЬ ГО-
ЛОВКИ'.


Процедура'ЧТЕНИЕ одного СЕКТОРА'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      Адрес #2ED1 <#2F1B>

Условия вызова:
- в регистре HL должен быть  ад-
  рес  ОЗУ,  куда  будет  считы-
  ваться сектор;
- в регистре 'E' должен быть но-
  мер СЕКТОРА (номер ЛОГИЧЕСКИЙ,
  т.е. нумерация с НУЛЯ).

   Подпрограмма вызывается  пос-
ле вывода головок на нужный  ци-
линдр и после прижатия головок к
нужной поверхности.
   Подпрограмма в  своей  работе
опрашивает порт СОСТОЯНИЯ  (#1F)
и повторяет свои действия,  если
был сбой в чтении.


Процедура'ЧТЕНИЕ ОДНОГО СЕКТОРА'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       Адрес #3F04 <#3F0E>

   Это вторая подпрограмма  чте-
ния сектора.

Условия вызова:
- головка дисковода должна  быть
  выведена на нужную  дорожку  и
  прижата к диску;
- в адресах  #5D00/#5D01  должен
  быть помещен адрес ОЗУ, в  ко-
  торый  будут  считываться  256
  байтов из сектора;
- в адрес #5CFF должен быть  по-
  мещен ЛОГИЧЕСКИЙ НОМЕР СЕКТОРА
  (т.е. нумерация секторов начи-
  нается с 0,  подпрограмма  по-
  том скорректирует  этот  номер
  до физического);
- Сохранить  данные  из   адреса
  #5CFE, так как этот адрес  при
  работе  купируется,  т.е.  ис-
  пользуется при работе.


Процедура 'Подача команд ПЕРВОГО
типа с ожиданием их исполнения'.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      Адрес #2F0D <#2F57 >

   Эту подпрограмму удобно вызы-
вать, когда требуется  исполнить
команды  'ВОСТАНОВЛЕНИЕ', 'ШАГ',
'ПОИСК'.
   Подпрограмма при своей  рабо-
те записывает код команды в порт
#1F и затем, опрашивая порт #FF,
ждет, когда  эта  команда испол-
нится.

Условия вызова:
- в регистре 'A' должен быть код
команды.


 Процедура 'ЦИКЛИЧЕСКАЯ ЗАПИСЬ
            В ПОРТ'.
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       Адрес #2075 <#20B1>

   Обычно эта  подпрограмма  ис-
пользуется в процессе ФОРМАТИРО-
ВАНИЯ  ДОРОЖКИ.  Но ее можно ис-
пользовать для нестандартной за-
писи информации на дорожку  (на-
пример,  создание   юстировочной
дорожки, или для полного уничто-
жения информации на дорожке).  А
если исхитриться, то можно запи-
сывать информацию и в СЕКТОР.

Условия вызова:
- головки должны  быть  выведены
  на нужный цилиндр и прижаты  к
  нужной поверхности диска;
- Подать команду  'ЗАПИСЬ'  (до-
  рожки или сектора). Если запи-
  сывается СЕКТОР, то в  регистр
  СЕКТОРА поместить номер секто-
  ра;
- В  регистре  'D'  должен  быть
  байт для записи"
- В  регистре  'B'  должно  быть
  число:  сколько  раз  записать
  байт из регистра 'D';
- В регистре 'C' должно быть #7F
  (порт данных).


Процедура "ФОРМАТИРОВАНИЕ  ОДНОЙ
            ДОРОЖКИ".
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       Адрес #1FC1 <#1FFD>

   Подпрограмма форматирует одну
дорожку   стандартным  способом.
Опрашивает  порт состояния (#1F)
и выдает надпись на экран,  если
диск защищен от записи.

Условия вызова:
- головки должны  быть  выведены
  на нужный цилиндр и прижаты  к
  нужной стороне;
- В ЯЧЕЙКЕ ОЗУ с  адресом  #5CD8
  должно быть значение, отличное
  от НУЛЯ;
- В регистр 'E'  необходимо  по-
  местить номер ЦИЛИНДРА  (от  0
  до 79), на котором  стоят  го-
  ловки. Если  у  Вас  позволяет
  дисковод, то,  выведя  головки
  на цилиндр, больший чем 79, Вы
  можете разметить 80, и 81,и 82
  и т.д. цилиндры  до  тех  пор,
  пока у Вас головки не  упрутся
  в ограничитель.

   Если же  Вы хотите отформати-
ровать нестандартно  -  пожалуй-
ста. Вы  можете,  например,  1-й
трек отформатировать  с  систем-
ным номером 255, но  работать  с
таким диском в ТРДОС СТАНДАРТНЫ-
МИ командами будет трудновато!!!

   Для  форматирования   дорожки
нестандартным образом можно  ис-
пользовать точку входа этой под-
программы:
          #1FC9 <#2005 >

   В  этом  случае,  кроме  всех
предыдущих условий, необходимо:

- в регистре  'HL'  должен  быть
  помещен  адрес  дампа  данных,
  где последовательно  размещены
  номера  СЕКТОРОВ  диска   (для
  нормального  выхода  ПОСЛЕДНИМ
  НОМЕРОМ в  дампе  должен  быть
  номер #10!).  ТРДОС использует
  адрес  дампа  данных  в ПЗУ по
  адресу #1F7D <#1FB9>;
- в  порт  КОМАНД  (#1F)  должна
  быть занесена команда ФОРМАТИ-
  РОВАНИЕ (например, байт #F4).

   Подробнее о процессе ФОРМАТИ-
РОВАНИЯ  будет  рассказано  чуть
позднее.


   Процедуры 'ЦИКЛ ЗАДЕРЖКИ'.
   ~~~~~~~~~~~~~~~~~~~~~~~~~~
    Адрес 1.  #3DF3 <#3DFE>
    Адрес 2.  #3E96 <#3EA0>

   Это подпрограмма задержки для
ожидания исполнения команд  дис-
ководом. Иногда ее полезно вызы-
вать,  чтобы  быть  уверенным  в
том,  что  последующая   команда
дисководу поступит  на него тог-
да, когда он свободен.
   Первая  подпрограмма:  задер-
жка  составляет   приблизительно
0.3 секунды, а вторая задержка -
приблизительно 1.2 секунды.


  Процедура 'ПЕРЕСЫЛКА ДАМПА'.
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Адрес 1.  #17DD <#180D>
    Адрес 2.  #28A5 <#2FEB>

   По этому адресу в  ПЗУ  ТРДОС
находятся команды:

              LDIR
              RET

   Вызов этой  подпрограммы  бы-
вает полезен тогда,  когда  надо
заморочить голову  хаккерам  или
для перекачки информации из  ПЗУ
ТРДОС в ОЗУ: например, части ка-
кой-либо процедуры.
   Условия вызова такие же,  как
и обыкновенной команды 'LDIR'.
   Можно было  бы  привести  еще
множество  полезных  подпрограмм
из ПЗУ.
   Но все вышеизложенное  доста-
точно для того,  чтобы  написать
какую угодно программу работы  с
диском, и мы  ограничимся  этими
подпрограммами, которые  являют-
ся главенствующими.
   В  процессе  написания  своих
программ или при разборе  других
аналогичных программ  Вы  можете
обнаружить,  что   необязательно
вызывать подпрограммы  ТРДОС  по
указанным выше адресам. В  конце
этой главы, в приложении,  будут
приведены листинги наиболее важ-
ных подпрограмм ПЗУ ТРДОС с ука-
занием адресов, и вам самим  ре-
шать, по какому адресу  вызывать
ту или иную процедуру.

    (продолжение следует...)




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

TR-DOS для начинающих - Часть 1.

Авторская разработка - General Sound - мультимедиа для ZX Spectrum!

Визитная карточка - Представляем новый электронный журнал "Major Wares" (c) Codebusters & V.M.G.

Компьютерная новелла - Knight Lore "Преданья рыцарских времен".

Новые программы - И.Рощин. HELP_Z80. В.Давыдов. Catalog's Base v1.8.

Описание оболочки журнала "ZX-РЕВЮ"

Перекресток драконов - Aavlon, Castle of Dreams, Erik the Viking.

Перекресток драконов - Eureka!, Eye of Bain, Kentilla.

Перекресток - Sherlock, Apollo, Shadows of Mordor, Rigels Revenge, Temple of Terror, ID, That's the Spirit, Return to Ithaka.

Ретро - Дж.Хардман, Э.Хьюзон. 40 лучших процедур.

Советы экспертов - Castle Master.

Советы экспертов - Firelord.

Советы экспертов - Stonkers.

Форум-игры - Insult Megademo, Catch 23, Livingstone, Rock Star ate my Hampster, НЛО-2: Дьяволы Бездны, Terminator 2, Venturama, The Spririts, Nipper, Sweewo'S World, King's Bounti-2, Hacker 2, Black Magic, Satcom, Звёздное Наследие.

Форум - А.Гура. Кодекс программиста.

Форум - А.Стрельников. Перспективы развития ZX Spectrum.

Форум - В.Давыдов. По материалам, опубликованным в ZX-РЕВЮ: Некоторые вопросы, связанные с автостартом Бейсик-программ. Redefine Keys. Процедура печати 42 символов в строке. Процедура умножения HL=B*C. Доработка посекторных загрузчиков. Мини-драйвер дисковых операций.

Форум - Группа 'Light'. Музыкальный процессор для ZX-Speccy.

Форум - Д.Федоров: Печать картинки с маской с точностью до пиксела. Алгоритм расчета адреса по координатам с точностью до пиксела.

Форум - И.Рощин. Совместное использование ZX ASM 3.0 и STS 5.1.

Форум - М.Бекарев. Расчет адреса экранной области по знакоместу и наоборот.

Форум - П.Федин. Доработка Profi для бесконфликтного подключения периферии.

Форум - С.Астров. Генератор псевдослучайных чисел.

Читатель-читателю - В.Сироткин. Защита программ (взгляд на проблему).

Читатель-читателю - И.Рощин. Драйвер экрана для компьютера "Пентагон-128".

Этюды - А.Савинов: Процедура вывода на экран символов двойной высоты. Процедура "растворения" символов.

Этюды - А.Уржа. Процедура рисования окружности.

Этюды - В.Сироткин. Программа подсчета контрольной суммы.

Этюды - Е.Волчков. Улучшение подпрограммы вычисления адреса в дисплейном файле.

Этюды - Е.Мороз. Бегущая строчка.

Этюды - И.Командин. Программа проявления экрана.

Этюды - И.Рощин. Два графических эффекта.

Этюды - М.Лазутов: Программа модернизации шрифта. Программа кодирования/декодирования блока кодов. Эффект с атрибутами.

Этюды - О.Смолянкин: Процедуры очистки экрана. Вывод текстовых сообщений на экран.


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

Похожие статьи:
Поиск - поиск игр, программ.
Вступление - оглавление.
Проходилка - Paradise Lost (demo).
Приколы №3 - Объявления и приколы и др. шутки.
Humor - СКАЗКА О ПРОГРАММИСТЕ.

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