ZX Review #5-6
04 ноября 1997
  TR-DOS  

Читатель-читателю - TR-DOS: как не допустить ошибки?

<b>Читатель-читателю</b> - TR-DOS: как не допустить ошибки?
┌──────────────────────────────┐
│                              │
│     ЧИТАТЕЛЬ - ЧИТАТЕЛЮ      │
│                              │
└──────────────────────────────┘

(c) Иван Рощин, г.Москва, 1996

           TR-DOS:
   как не допустить ошибки ?

   Вы  удивитесь, если  узнаете,
сколько программ  не  распознают
ошибки  при работе с диском, не-
правильно распознают их, а также
зависают или сбрасываются при их
возникновении.  Разумеется,  при
написании  собственных  программ
таких ситуаций следует избегать,
хотя это не так-то просто.  Дело
в том, что корректная  обработка
ошибок становится возможной лишь
при работе напрямую с  микрокон-
троллером дискового  интерфейса,
а это доступно далеко не  каждо-
му. Несмотря на это,  надежность
программ можно значительно  уве-
личить, если использовать  наря-
ду с обычными  функциями  TR-DOS
специальные процедуры для распо-
знавания ошибочных ситуаций.

   В этой статье пойдет речь  об
одной из самых  распространенных
ошибок ввода-вывода - отсутствии
диска в дисководе.  Также  будет
сказано  несколько слов о прямом
программировании ВГ93 и  о  про-
граммах,  контролирующих   смену
диска.

   Известно, что  перед  началом
любой дисковой операции, связан-
ной с чтением или  записью  дан-
ных, необходимо, чтобы диск  был
установлен в дисковод  и  дверца
дисковода была закрыта. Если это
условие не выполняется, програм-
ма (если она грамотно  написана)
обычно выдает одно из  следующих
сообщений:

 - No disk
 - Disk not present
 - Disk not ready

   Специальная процедура для оп-
ределения наличия диска в диско-
воде  была  бы  очень  полезной.
Приведу лишь один  из  возможных
примеров ее использования:  если
ваша программа использует интер-
претатор    системных    функций
TR-DOS и не осуществляет  перех-
ват ошибок, то при их  возникно-
вении (в частности,  при  отсут-
ствии  диска)  может   произойти
сброс компьютера (что очень  не-
желательно). Но если  с  помощью
указанной  процедуры  обнаружить
отсутствие диска еще  до  вызова
интерпретатора,  можно  избежать
неприятных последствий (конечно,
если не произойдет  какой-нибудь
другой ошибки).

   Рассмотрим несколько  возмож-
ных  способов  реализации  такой
процедуры:

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

   Недостатки: неудачное  считы-
вание сектора еще не значит, что
диск отсутствует.  Вполне  может
быть, что сектор был  записан  с
ошибкой или сектора с таким  но-
мером  вообще  нет  на   дорожке
(т.к. в общем случае формат дис-
ка может быть произвольным).

   Достоинства:  при  работе   с
диском  фиксированного   формата
этот способ вполне подходит.

   2) Делаем  попытку  прочитать
первый  встреченный    заголовок
сектора. В случае  неудачи  счи-
таем, что диска нет.

   Недостатки:  в  общем  случае
диск может быть  и  неформатиро-
ванным, при этом  ничего  прочи-
тать не удастся,  и  мы  получим
неверный результат.

   Достоинства: этот способ  го-
дится для любого форматированно-
го диска и  достаточно  прост  в
реализации.

   3) Используем регистр состоя-
ний микроконтроллера.
   Прежде чем  говорить  о  дос-
тоинствах  и  недостатках  этого
метода, вспомним, что такое  ре-
гистр состояний и что можно  уз-
нать с его помощью.

   Регистр  состояний   отражает
корректность заданной команды, а
также состояния  микроконтролле-
ра при ее выполнении. Каждый бит
в нем указывает на  определенный
параметр и связан с  выполнением
конкретной команды. При выполне-
нии команд восстановления и  по-
зиционирования  биты  системного
регистра имеют следующее  назна-
чение:

0 - занято, идет выполнение
    команды;
1 - индексный импульс;
2 - магнитная головка находится
    в исходном положении;
3 - ошибка в контрольном коде;
4 - ошибка позиционирования;
5 - магнитная головка находится
    в рабочем положении;
6 - защита записи;
7 - указывает на готовность дис-
    ковода к выполнению команды.

   Нас будут интересовать лишь 1
и  6  биты  регистра  состояний,
поэтому поговорим о них  подроб-
нее.

   Если посмотреть  на  дискету,
мы увидим  большое  отверстие  в
центре, а рядом  с ним - малень-
кое  круглое  отверстие  в  кор-
пусе дискеты  и  отверстие  чуть
меньшего диаметра на самом  маг-
нитном диске. Это  так  называе-
мое индексное  отверстие,  кото-
рое служит для  ориентации  маг-
нитной головки дисковода на дис-
кете. Когда отверстия в  корпусе
и на самом  диске  совпадают  (а
это происходит при каждом оборо-
те диска),  контроллер  считает,
что магнитная головка  находится
в  начале  дорожки.  Отмечу, что
вероятность случайного  совпаде-
ния отверстий составляет пример-
но 3%.

   Значение 1-го  бита  регистра
состояний  определяется  состоя-
нием индексного отверстия:

┌───────────────────┬────────────────────┐
│ ситуация          │ значение 1-го бита │
├───────────────────┼────────────────────┤
│Диска нет          │ 1                  │
├───────────────────┼────────────────────┤
│Диск есть,         │                    │
│отверстия в корпусе│ 1                  │
│и на самом диске   │                    │
│совпадают          │                    │
├───────────────────┼────────────────────┤
│Диск есть,         │                    │
│отверстия в корпусе│ 0                  │
│и на самом диске   │                    │
│не совпадают       │                    │
└───────────────────┴────────────────────┘

   Шестой бит системного  регис-
тра отражает  состояние  прорези
для защиты записи:

┌───────────────────┬────────────────────┐
│ ситуация          │ значение 6-го бита │
├───────────────────┼────────────────────┤
│Диска нет          │ 0                  │
├───────────────────┼────────────────────┤
│Диск есть,         │                    │
│прорезь открыта    │ 0                  │
├───────────────────┼────────────────────┤
│Диск есть,         │                    │
│прорезь закрыта    │ 1                  │
└───────────────────┴────────────────────┘

   Ясно, что если 1-й бит  равен
0 или 6-й бит равен 1, диск при-
сутствует.  Но,  во-первых,  при
наличии  диска  эти  биты  могут
принимать, вообще говоря,  любые
значения, а во-вторых, совершен-
но неизвестно, закрыта ли  двер-
ца дисковода. Как же  узнать  ее
состояние?  Вспомним,  что  если
она закрыта и двигатель дисково-
да  вращается,  то  будет   вра-
щаться и диск.  Если  же  дверца
открыта, диск вращаться  не  бу-
дет. Ну а как  определить,  вра-
щается  диск  или  нет,  мы  уже
знаем - нужно циклически  прове-
рять значение первого  бита  ре-
гистра  состояний.  При   каждом
обороте диска  этот  бит  меняет
свое значение с 0 (отверстие  на
корпусе диска не совпадает с от-
верстием на диске) на 1  (отвер-
стия совпадают), и далее - опять
на 0. Если этот бит не будет ме-
нять своего значения -  либо   в
дисководе нет диска, либо дверца
открыта.

   Теперь мы  легко  можем  ука-
зать искомый алгоритм:

   - прочитать значение регистра
состояний.  Пусть  s1 - значение
1-го  бита, s2  - значение  6-го
бита.

   - пусть s3=1, если диск  вра-
щается, и 0, если диск не враща-
ется.

   - определить ситуацию по таб-
лице:

    s1│s2│s3│ Номер ситуации
    ──┼──┼──┼────────────────
     0│ 0│ 0│ 2
     0│ 0│ 1│ 3
     0│ 1│ 0│ 2
     0│ 1│ 1│ 3
     1│ 0│ 0│ 1
     1│ 0│ 1│ 3
     1│ 1│ 0│ 2
     1│ 1│ 1│ 3

   Расшифровка номера ситуации:

1 - в дисководе нет диска;
2 - диск есть, но дверца  диско-
    вода не закрыта;
3 - диск есть и дверца дисковода
    закрыта.

   Примечание:  с   вероятностью
примерно 3% ситуация  (2)  может
быть  распознана   как  ситуация
(1).

   Ну что  же,  осталось  только
привести текст процедуры на  ас-
семблере:
140.
;***********************************************
;ПРОЦЕДУРА D_READY ОПРЕДЕЛЯЕТ, ВСТАВЛЕН ЛИ
;ДИСК В ДИСКОВОД И ЗАКРЫТА ЛИ ДВЕРЦА ДИСКОВОДА.
;В РЕГИСТРЕ A ВОЗВРАЩАЕТСЯ ЧИСЛО 1,2 ИЛИ 3,
;ОБОЗНАЧАЮЩЕЕ НОМЕР СИТУАЦИИ:
;
; 1 -в дисководе нет диска;
; 2 -диск есть, но дверца дисковода не
;    закрыта;
; 3 -диск есть и дверца дисковода закрыта.
;
;   Примечание: с вероятностью примерно 3% ситуация (2)
;может быть распознана как ситуация (1).

D_READY XOR     A        ;УСТАНАВЛИВАЕМ ОДИН И ТОТ ЖЕ
        LD      C,#3F    ;НОМЕР ЦИЛИНДРА
        CALL    TO_WG93  ;В РЕГИСТРЕ ДОРОЖКИ
        LD      C,#7F    ;И В РЕГИСТРЕ ДАННЫХ.
        CALL    TO_WG93

        LD      A,#18    ;ПОЗИЦИОНИРОВАНИЕ. ГОЛОВКА НЕ БУДЕТ
        CALL    TO_1F    ;ДВИГАТЬСЯ, НО ДВИГАТЕЛЬ ВКЛЮЧИТСЯ.
        CALL    READY    ;ЖДЕМ ВЫПОЛНЕНИЯ...
        CALL    STATUS   ;ЧИТАЕМ РЕГИСТР СОСТОЯНИЯ.
        LD      B,A      ;И СОХРАНЯЕМ В РЕГИСТРЕ B.

;ТЕПЕРЬ ЧИТАЕМ РЕГИСТР СОСТОЯНИЯ В ЦИКЛЕ,
;ЧТОБЫ ОПРЕДЕЛИТЬ, ВРАЩАЕТСЯ ЛИ ДИСК.
;ЕСЛИ #300 РАЗ БУДЕТ СЧИТАНО ОДНО И ТО ЖЕ
;ЗНАЧЕНИЕ, ЗНАЧИТ, ДИСК НЕ ВРАЩАЕТСЯ.
;
;  ПРИМЕЧАНИЕ: ЧИСЛО #300 ПОДОБРАНО ОПЫТНЫМ ПУТЕМ,
;ИСХОДЯ ИЗ МАКСИМАЛЬНОГО ВРЕМЕНИ РАБОТЫ ЦИКЛА
;(ЭТО ЧУТЬ БОЛЬШЕ ВРЕМЕНИ ОДНОГО ОБОРОТА ДИСКА,
;ИЛИ3 200ms). ЕСЛИ ПРОЦЕССОР РАБОТАЕТ БЫСТРЕЕ ИЛИ
;ДИСК ВРАЩАЕТСЯ МЕДЛЕННЕЕ, ЧИСЛО НУЖНО УВЕЛИЧИТЬ.

        LD      HL,#300 ;СЧЕТЧИК
LOOP_D  PUSH    HL
        PUSH    BC
        CALL    STATUS
        POP     BC
        POP     HL
        DEC     HL
        CP      B         ;СРАВНИВАЕМ СЧИТАННОЕ И РАНЕЕ ПОЛУЧЕННОЕ ЗНАЧЕНИЯ
        LD      A,1       ;ФОРМИРУЕМ 0-Й БИТ РЕГИСТРА A
        JR      NZ,DISK_R ;ЕСЛИ ДИСК КРУТИТСЯ
        LD      A,H
        OR      L
        JR      NZ,LOOP_D ;ПРОДОЛЖАЕМ СЧИТЫВАТЬ ЗНАЧЕНИЕ...

;ФОРМИРУЕМ В РЕГИСТРЕ A БАЙТ С ТАКИМ СОДЕРЖИМЫМ:
;
;  БИТ 0: 0-ДИСК НЕ КРУТИТСЯ, 1-КРУТИТСЯ;
;  БИТ 1: ТО ЖЕ, ЧТО БЫЛО В 6-М БИТЕ РЕГИСТРА СОСТОЯНИЙ
;  БИТ 2: ТО ЖЕ, ЧТО БЫЛО В 1-М БИТЕ РЕГИСТРА СОСТОЯНИЙ
;
;В РЕЗУЛЬТАТЕ В РЕГИСТРЕ A ПОЛУЧАЕМ ЧИСЛО ОТ 0 ДО 7,
;И ДАЛЕЕ ОПРЕДЕЛЯЕМ НОМЕР СИТУАЦИИ ПО ТАБЛИЦЕ.

DISK_R  BIT     6,B
        JR      Z,READY1
        SET     1,A

;УСТАНОВЛЕНО ЗНАЧЕНИЕ 1-ГО БИТА.

READY1  BIT     1,B
        JR      Z,READY2
        SET     2,A

;В A ПОЛУЧЕНО НУЖНОЕ ЗНАЧЕНИЕ

READY2  LD      (THIS_B+2),A ;МОДИФИЦИРУЕМ КОМАНДУ

;НО СНАЧАЛА ОТКЛЮЧАЕМ ДИСКОВОД:

        XOR     A         ;ЭТИ КОМАНДЫ,
        CALL    TO_1F     ;В ПРИНЦИПЕ,
        LD      A,#D0     ;МОЖНО
        CALL    TO_1F     ;ВЫБРОСИТЬ.

;ЭТА КОМАНДА СООТВЕТСТВУЕТ LD A,(IX+0)...LD A,(IX+7):

        LD      IX,TABL
THIS_B  LD      A,(IX)       ;ПОЛУЧИЛИ НОМЕР СИТУАЦИИ
        EI
        RET

;ТАБЛИЦА ДЛЯ ОПРЕДЕЛЕНИЯ НОМЕРА СИТУАЦИИ:

TABL    DB      2,3,2,3,1,3,2,3

;***************************************
;ВСПОМОГАТЕЛЬНЫЕ ПРОЦЕДУРЫ:

TO_1F   LD      C,#1F

140.
TO_WG93 LD      IX,#2A53
        JR      TO_DOS

READY   LD      IX,#3EF5
TO_DOS  PUSH    IX
        JP      #3D2F

;***************************************
;ПРОЦЕДУРА STATUS ВОЗВРАЩАЕТ СОДЕРЖИМОЕ
;РЕГИСТРА СОСТОЯНИЯ.
;ВХОД:  A -СОДЕРЖИМОЕ РЕГИСТРА ДОРОЖКИ,
;       B -СОДЕРЖИМОЕ РЕГИСТРА СЕКТОРА,
;       КОТОРЫЕ БУДУТ УСТАНОВЛЕНЫ ПОСЛЕ
;       ВЫХОДА ИЗ ПРОЦЕДУРЫ.
;ВЫХОД: A -ЗНАЧЕНИЕ, СЧИТАННОЕ ИЗ ПОРТА #1F.
;ПРЕРЫВАНИЯ ПОСЛЕ ВЫХОДА ЗАПРЕЩЕНЫ!

STATUS  DI
        LD      C,#7F    ;A=N ЦИЛИНДРА
        CALL    TO_WG93  ;В РЕГИСТР ДАННЫХ

        LD      (RG_D+1),A  ;ДОРОЖКА
        LD      A,B
        LD      (RG_S+1),A  ;СЕКТОР

;СОХРАНЯЕМ СОДЕРЖИМОЕ ЯЧЕЕК, КОТОРЫЕ
;МОГУТ БЫТЬ ИСПОРЧЕНЫ:

        LD      A,(#5D0E)
        LD      (ST1+1),A
        LD      A,(#5D0C)
        LD      (ST2+1),A
        LD      A,(#5CB6)
        LD      (ST3+1),A
        LD      A,(#5D1F)
        LD      (ST4+1),A
        LD      A,(#5C3A)
        LD      (ST5+1),A
        LD      A,(#5D17)
        LD      (ST6+1),A
        LD      HL,(#5D1A)
        LD      (ST7+1),HL
        LD      HL,(#5D1C)
        LD      (ST8+1),HL
        LD      HL,(#5CF8)
        LD      (ST9+1),HL

;УСТАНАВЛИВАЕМ СОДЕРЖИМОЕ НЕКОТОРЫХ
;ЯЧЕЕК ДЛЯ ПРАВИЛЬНОЙ РАБОТЫ:

        LD      A,#FF
        LD      (#5D0C),A
        LD      (#5D1F),A
        DEC     A
        LD      (#5D0E),A
        LD      A,#F4
        LD      (#5CB6),A

        LD      HL,S_SPEC
        LD      (#5D1A),HL
        LD      HL,0
        ADD     HL,SP
        LD      DE,-12
        ADD     HL,DE
        LD      (#5D1C),HL

        LD      A,0     ;0 В РЕГИСТР
        LD      C,#3F   ;ДОРОЖКИ
        CALL    TO_WG93
        LD      A,#0A   ;#A В РЕГИСТР
        LD      C,#5F   ;СЕКТОРА
        CALL    TO_WG93
        LD      D,1
        LD      IX,16179
        CALL    TO_DOS  ;ОПРЕДЕЛИЛИ #1F

;ТЕПЕРЬ ВОССТАНАВЛИВАЕМ СОДЕРЖИМОЕ
;РЕГИСТРОВ ДОРОЖКИ И СЕКТОРА:

RG_D    LD      A,0
        LD      C,#3F
        CALL    TO_WG93
RG_S    LD      A,0
        LD      C,#5F
        CALL    TO_WG93

;ВОССТАНАВЛИВАЕМ РАНЕЕ ЗАПОМНЕННОЕ
;СОДЕРЖИМОЕ ЯЧЕЕК:

ST1     LD      A,0
        LD      (#5D0E),A
ST2     LD      A,0
        LD      (#5D0C),A
ST3     LD      A,0
        LD      (#5CB6),A
ST4     LD      A,0
        LD      (#5D1F),A
ST5     LD      A,0
        LD      (#5C3A),A
ST6     LD      A,0
        LD      (#5D17),A
ST7     LD      HL,0
        LD      (#5D1A),HL
ST8     LD      HL,0
        LD      (#5D1C),HL
ST9     LD      HL,0
        LD      (#5CF8),HL
        LD      A,B
        RET

;СЮДА БУДЕТ ПЕРЕДАНО УПРАВЛЕНИЕ, ЕСЛИ
;0-Й БИТ РЕГИСТРА СОСТОЯНИЙ РАВЕН 1:

S_SPEC  POP     BC     ;СОДЕРЖИМОЕ ПОРТА
        LD      HL,(#5D1C)
        LD      DE,12   ;ВОССТАНАВЛИВАЕМ
        ADD     HL,DE   ;УКАЗАТЕЛЬ
        LD      SP,HL   ;СТЕКА
        JR      RG_D


2   Вам  наверняка    встречались
программы, контролирующие  смену
диска  в  дисководе   (например,
Jemmini Commander). В них прове-
ряются именно указанные выше би-
ты системного регистра (в  прин-
ципе, достаточно следить за  из-
менением лишь какого-нибудь  од-
ного из двух битов).  Вот  прос-
тейший  алгоритм  работы   такой
программы:

Шаг 1: Прочитать значение регис-
       тра состояний. Если  пер-
       вый бит равен 1,  перейти
       к шагу 4.

Шаг 2: N="Диск есть".

Шаг 3: Прочитать значение регис-
       тра состояний. Если  пер-
       вый бит равен 0,  перейти
       к шагу 3.

Шаг 4: N="Диска нет".

Шаг 5: Прочитать значение регис-
       тра состояний. Если  пер-
       вый бит равен 1,  перейти
       к шагу 5, иначе к шагу 2.

   Примечание:  программа  рабо-
тоспособна при условии, что  от-
верстие на самом диске не совпа-
дает  с  отверстием  на  корпусе
диска (это связано с использова-
нием 1-го бита регистра  состоя-
ний).

   Кстати,  у  такой   программы
есть одна  особенность,  связан-
ная с чтением  регистра  состоя-
ний. Чтобы прочесть  его  значе-
ние, нужно, чтобы двигатель дис-
ковода  работал.  Поэтому    ис-
пользуется следующий прием:  вы-
полняется команда позиционирова-
ния на  дорожку,  номер  которой
уже записан в  регистр  дорожки.
При этом головка не  будет  дви-
гаться, но  двигатель  дисковода
включится. После  окончания  вы-
полнения этой  команды  читается
регистр состояний.  Сразу  после
этого  двигатель    выключается,
например, с помощью записи  0  в
порт #FF (или в порт #1F).  Меж-
ду двумя последовательными  чте-
ниями регистра состояний делает-
ся пауза, обычно  1/50  секунды.
При этом двигатель  не  успевает
раскрутиться, и лампочка  диско-
вода не загорается. Но если вни-
мательно  присмотреться,  видно,
что лампочка  все  же  чуть-чуть
светится (яркость  свечения  об-
ратно пропорциональна длине пау-
зы). Так вот, на некоторых  дис-
ководах  (а именно - на ЕС 5323.
01) было замечено, что при рабо-
те программ, контролирующих сме-
ну диска, лампочка постоянно го-
рит и двигатель работает.

   Привожу текст  небольшой  де-
монстрационной  программы,  кон-
тролирующей смену диска  по  вы-
шеуказанному алгоритму. Програм-
ма выводит  на  экран  сообщения
"DISK PRESENT" и  "DISK NOT PRE-
SENT".  Выход - по нажатию любой
клавиши  (когда диск присутству-
ет).
140.
        CALL    3435    ;CLS
        LD      A,2
        CALL    5633

M_1     CALL    READ_S
        BIT     1,A
        JR      NZ,M_4

M_2     LD      A,1
        LD      (N),A
        LD      DE,TEXT1
        LD      BC,23
        CALL    8252    ;"DISK PRESENT"

M_3     XOR     A
        IN      A,(254)
        AND     31
        CP      31
        RET     NZ      ;ЕСЛИ НАЖАТА КЛАВИША, ВЫХОДИМ

        CALL    READ_S
        BIT     1,A
        JR      Z,M_3

M_4     XOR     A
        LD      (N),A
        LD      DE,TEXT2
        LD      BC,23
        CALL    8252    ;"DISK NOT PRESENT"

M_5     CALL    READ_S
        BIT     1,A
        JR      NZ,M_5
        JR      M_2

N       DB      0       ;1-ЕСТЬ ДИСК, 0-НЕТ.
TEXT1   DB      22,0,0,16,7,17,0,"DISK PRESENT    "
TEXT2   DB      22,0,0,16,7,17,0,"DISK NOT PRESENT"

;***************************************
;ПРОЦЕДУРА READ_S ОСУЩЕСТВЛЯЕТ ЧТЕНИЕ
;РЕГИСТРА СОСТОЯНИЙ. ПЕРЕД ЧТЕНИЕМ
;ПРОИЗВОДИТСЯ ВКЛЮЧЕНИЕ ДВИГАТЕЛЯ
;ДИСКОВОДА, А ПОСЛЕ ЧТЕНИЯ -ВЫКЛЮЧЕНИЕ И
;ПАУЗА В3 1/50 СЕКУНДЫ.

READ_S  XOR     A        ;УСТАНАВЛИВАЕМ ОДИН И ТОТ ЖЕ
        LD      C,#3F    ;НОМЕР ЦИЛИНДРА
        CALL    TO_WG93  ;В РЕГИСТРЕ ДОРОЖКИ
        LD      C,#7F    ;И В РЕГИСТРЕ ДАННЫХ.
        CALL    TO_WG93

        LD      A,#18    ;ПОЗИЦИОНИРОВАНИЕ. ГОЛОВКА НЕ БУДЕТ
        CALL    TO_1F    ;ДВИГАТЬСЯ, НО ДВИГАТЕЛЬ ВКЛЮЧИТСЯ.
        CALL    READY    ;ЖДЕМ ВЫПОЛНЕНИЯ...
        CALL    STATUS   ;ЧИТАЕМ РЕГИСТР СОСТОЯНИЯ.
        EI               ;РАЗРЕШАЕМ РАНЕЕ ЗАПРЕЩЕННЫЕ ПРЕРЫВАНИЯ
        PUSH    AF
        XOR     A
        CALL    TO_1F    ;ВЫКЛЮЧАЕМ ДВИГАТЕЛЬ
        LD      A,#D0
        CALL    TO_1F
        HALT          3   ;ЗАДЕРЖКА 1/50 СЕКУНДЫ
        POP     AF
        RET

;***************************************
;ВСПОМОГАТЕЛЬНЫЕ ПРОЦЕДУРЫ:

TO_1F   LD      C,#1F
TO_WG93 LD      IX,#2A53
        JR      TO_DOS

READY   LD      IX,#3EF5
TO_DOS  PUSH    IX
        JP      #3D2F

;***************************************
;ПРОЦЕДУРА STATUS ВОЗВРАЩАЕТ СОДЕРЖИМОЕ
;РЕГИСТРА СОСТОЯНИЯ.
;ВХОД:  A -СОДЕРЖИМОЕ РЕГИСТРА ДОРОЖКИ,
;       B -СОДЕРЖИМОЕ РЕГИСТРА СЕКТОРА,
;       КОТОРЫЕ БУДУТ УСТАНОВЛЕНЫ ПОСЛЕ
;       ВЫХОДА ИЗ ПРОЦЕДУРЫ.
;ВЫХОД: A -ЗНАЧЕНИЕ, СЧИТАННОЕ ИЗ ПОРТА #1F.
;ПРЕРЫВАНИЯ ПОСЛЕ ВЫХОДА ЗАПРЕЩЕНЫ!

STATUS  DI
        LD      C,#7F    ;A=N ЦИЛИНДРА
        CALL    TO_WG93  ;В РЕГИСТР ДАННЫХ

        LD      (RG_D+1),A  ;ДОРОЖКА
        LD      A,B
        LD      (RG_S+1),A  ;СЕКТОР

;СОХРАНЯЕМ СОДЕРЖИМОЕ ЯЧЕЕК, КОТОРЫЕ
;МОГУТ БЫТЬ ИСПОРЧЕНЫ:

        LD      A,(#5D0E)
        LD      (ST1+1),A
        LD      A,(#5D0C)
        LD      (ST2+1),A
        LD      A,(#5CB6)
        LD      (ST3+1),A
        LD      A,(#5D1F)
        LD      (ST4+1),A
        LD      A,(#5C3A)
        LD      (ST5+1),A
        LD      A,(#5D17)
        LD      (ST6+1),A
        LD      HL,(#5D1A)
        LD      (ST7+1),HL
        LD      HL,(#5D1C)
        LD      (ST8+1),HL
        LD      HL,(#5CF8)
        LD      (ST9+1),HL

;УСТАНАВЛИВАЕМ СОДЕРЖИМОЕ НЕКОТОРЫХ
;ЯЧЕЕК ДЛЯ ПРАВИЛЬНОЙ РАБОТЫ:

        LD      A,#FF
        LD      (#5D0C),A
        LD      (#5D1F),A
        DEC     A
        LD      (#5D0E),A
        LD      A,#F4
        LD      (#5CB6),A

        LD      HL,S_SPEC
        LD      (#5D1A),HL
        LD      HL,0
        ADD     HL,SP
        LD      DE,-12
        ADD     HL,DE
        LD      (#5D1C),HL

        LD      A,0     ;0 В РЕГИСТР
        LD      C,#3F   ;ДОРОЖКИ
        CALL    TO_WG93
        LD      A,#0A   ;#A В РЕГИСТР
        LD      C,#5F   ;СЕКТОРА
        CALL    TO_WG93
        LD      D,1
        LD      IX,16179
        CALL    TO_DOS  ;ОПРЕДЕЛИЛИ #1F

;ТЕПЕРЬ ВОССТАНАВЛИВАЕМ СОДЕРЖИМОЕ
;РЕГИСТРОВ ДОРОЖКИ И СЕКТОРА:

RG_D    LD      A,0
        LD      C,#3F
        CALL    TO_WG93
RG_S    LD      A,0
        LD      C,#5F
        CALL    TO_WG93

;ВОССТАНАВЛИВАЕМ РАНЕЕ ЗАПОМНЕННОЕ
;СОДЕРЖИМОЕ ЯЧЕЕК:

ST1     LD      A,0
        LD      (#5D0E),A
ST2     LD      A,0
        LD      (#5D0C),A
ST3     LD      A,0
        LD      (#5CB6),A
ST4     LD      A,0
        LD      (#5D1F),A
ST5     LD      A,0
        LD      (#5C3A),A
ST6     LD      A,0
        LD      (#5D17),A
ST7     LD      HL,0
        LD      (#5D1A),HL
ST8     LD      HL,0
        LD      (#5D1C),HL
ST9     LD      HL,0
        LD      (#5CF8),HL

        LD      A,B
        RET

;СЮДА БУДЕТ ПЕРЕДАНО УПРАВЛЕНИЕ, ЕСЛИ
;0-Й БИТ РЕГИСТРА СОСТОЯНИЙ РАВЕН 1:

S_SPEC  POP     BC     ;СОДЕРЖИМОЕ ПОРТА
        LD      HL,(#5D1C)
        LD      DE,12   ;ВОССТАНАВЛИВАЕМ
        ADD     HL,DE   ;УКАЗАТЕЛЬ
        LD      SP,HL   ;СТЕКА
        JR      RG_D

           *   *   *
2



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

Adventure Project - Проектирование и разработака Адвентюрных и RPG игр.

Adventure Project - Русификация адвентюр.

TR-DOS для начинающих - Продолжение.

Авторская разработка - Scorpion 2000 (С.Зонов).

Авторская разработка - Трамплин (С.Веремеенко).

Визитная карточка - новый электронный юмористический журнал "SpectrofUn".

Перекресток драконов - Раскрутка игры Finders Keepers.

Перекресток драконов - Раскрутка игры Knight Tyme.

Перекресток драконов - Раскрутка игры Spellbound.

Перекресток драконов - Раскрутка игры Stormbringer.

Ретро - 40 лучших процедур: Слияние картинок, Вращение символа по часовой стрелке, Инвертирование символов, Изменение атрибута, Закрашивание контура, Построение шаблонов (Дж.Хардман, Э.Хьюзон.).

Советы экспертов - Total Eclipse 2.

Советы экспертов Super League.

Форум-игры - Описание игры Страна Мифов.

Форум-игры - Прохождение Renegade.

Форум-игры - Тонкости торговли в игре Elite

Форум - Изучение и отладка @-файлов с помощью STS 5.1. Особенности отладки программ с помощью монитора STS. Исправление ошибки STS 5.1.

Форум - Компрессия программ.

форум - О сокращении времени форматирования. О записи секторов одновременно с форматированием. Перестроение экрана за одно прерывание.

Форум - Особенности ассемблера ZX ASM 3.0.

Форум - По поводу компилятора бейсика "Blast".

Форум - По поводу релоцируемых программ.

Форум - Программы "Пламя" и "Дракон".

Читатель-читателю - TR-DOS: как не допустить ошибки?

Читатель-читателю - Эффективная работа с дисководом .

Этиды - Расчет адреса в файле атрибутов. Программа скроллирования заданного окна на 1 пиксел вправо. Программа очистки заданного окна. Процедура вывода картинки из буфера.

Этюды - Индикатор каналов музыкального процессора. Процедура очистки экрана. Предложение по стандартизации.

Этюды - Набор из восьми программ "расширения" экрана. Две процедуры проявления экрана.

Этюды - Новые темы для разработок.

Этюды - Программа воспроизведения инструмента от редакторов оцифрованной музыки.

Этюды - Программа обработки @-бейсик файлов.

Этюды - Процедура поворота символа на 90 градусов по часовой стрелке.

Этюды - Процедура поиска текстовых файлов.

Этюды - Экранная процедура "UP HL".


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

Похожие статьи:
Опрос - результаты анкетирования 45 Спектрумистов.
Смак - рыба под маринадом.
Рекалама - реклама и обьявления во Львове.
Реклама - реклама и объявления.
News - актуальные новости от: Research, Arhon, Gasman, Fatal Snipe, Skrju, ZX Time team, Newart, Elph.

В этот день...   24 апреля