ZX Time #08
30 апреля 2002
  TR-DOS  

Кодерам - частные моменты в работе с TR-DOS (TR-DOS на уровне портов).

<b>Кодерам</b> - частные моменты в работе с TR-DOS (TR-DOS на уровне портов).
Кодерам
────────────────────────────────────────
                                    Nuts

    Частные моменты в работе с TR-DOS
   ───────────────────────────────────

  Итак,  сегодня мы поговорим про работу
с  TR-DOS  на уровне портов. Вопрос этот
уже неоднократно обмусоливался в различ-
ной  прессе,  я  же просто хочу отметить
несколько  моментов, которые упоминались
только  в  малораспротранненых газетах и
журналах:  кто-то  уже  давно пользуется
ими в программах, а кто-то продолжает не
знать.

  В  первую  очередь  речь идет о чтении
пресловутого  порта  #1F  TR-DOS. Кратко
вспомним его назначение.

  Бит 0 - занято, идет выполнение коман-
ды.

  Бит 1  - индексный  импульс (маленькое
отверстие  в дискете находится между оп-
топарой фотодатчика) - "начало дорожки".

  Бит 2  - магнитная головка находится в
исходном положении.

  Бит 3 - ошибка в CRC сектора.

  Бит 4 - ошибка позиционирования.

  Бит 5 -  магнитная головка находится в
рабочем положении.

  Бит 6 - на диске есть наклейка для за-
щиты от записи.

  Как  известно,  стандартная ПЗУ TR-DOS
не  позволяет напрямую читать этот порт.
Поэтому  еще  Ларченко  и Родионов еще в
начале  90-х годов прошлого столетия по-
рылись в этом самом ПЗУ и придумали спо-
соб  косвенного чтения этого порта: если
по  хитрому утановить некоторые регистры
и переменные, то в одной из процедур ПЗУ
совпадут  переходы аккурат на нормальный
RET.

  Способ  этот  был  опубликован в книге
вышеупомянутых: "ZX  SPECTRUM  &  TR-DOS
для  пользователей и организмов"... т.е.
тьфу... ПРОГРАММИСТОВ..." вот. Книга эта
получила  известное  распространение,  а
по  сему и способ тоже. От него плясал и
изестный  и  уважаемый всеми Иван Рощин.
Он   опубликовал  в  различных  источних
большое  количество поправок и коммента-
риев к данному методу. Поэтому произошла
определенная концентрация мыслей на дан-
ном методе.

    Но это же не единственный метод!

  Можно,  например,  решить  проблему  в
лоб:  взять  и прошить в ПЗУ пару-тройку
байтов  чтения  порта.  Развитие  такого
способа произвела, по-моему, фирма МИКРО
АРТ  со  своим АТМ ТУРБО, в ПЗУ которого
такие   байты   были.   Известный  HONEY
COMMANDER,  который бескомпромиссно тре-
бовал  именно  этих байт в ПЗУ, не желая
работать  без  них.  Кроме того, хочется
упомянуть  еще  ELS COMMANDER, (c) 1995,
Электрон  Сервис,  г.Гомель - он тоже не
желал. Оставим в покое этот вопрос, т.к.
существует  куча  версий  ПЗУ со всякими
изменениями - всех не упомнить!

  Другие  методы тоже часто применяются,
но  поскольку  ажиотаж на страницах ЭСМИ
не  утихает - надо  про них еще раз ска-
зать.

  Ниже  приведены  пара  методов,  более
или менее используемых программистами:

  1)  Способ,  выдранный  из  MultiColor
Studio  v2.0, (c)  OHG. Он применяется в
каждой  второй  программе, и даже где-то
опубликован.

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

  Вот  как  выглядит  используемый кусок
процедуры:

#2099   IN A,(#1F) ;ЧИТАЕМ ПОРТ
        AND A,#7F  ;ВЫДЕЛЯЕМ БИТЫ 0-6
        POP BC     ;ЧТО-ТО  ВОССТАНАВЛИ-
                   ;ВАЕМ СО СТЕКА
        JR Z,#20A6 ;нет ошибок - перехо-
                   ;дим
        LD HL,#5CD6;адрес  переменной  -
                   ;число  плохих секто-
                   ;ров
        INC (HL)   ;увеличиваем его
#20A6   POP HL     ;ЧТО-ТО  ВОССТАНАВЛИ-
                   ;ВАЕМ СО СТЕКА
        LD A,(HL)  ;делаем
        INC HL     ;проверку
        CP 1       ;должна быть 1
        JR NZ,#20A8;иначе  куда-то  пры-
                   ;гаем
        EI         ;а если 1 ->
        RET        ;вертаемся

  Таким  образом, чтобы прочитать значе-
ние порта #1F и проверить, равны ли нулю
его биты 0-6 необходимо:

  1) записать ноль в пременную #5CD6;

  2) положить че нито на стек;

  3)  положить на стек адрес по которому
точно размещается число 1;

  4)  положить на стек адрес продолжения
программы  после того, как она выйдет из
ПЗУ;

  5) положить на стек адрес подпрограммы
#2099;

  6) прыгнуть в ПЗУ на #3D2F

  7)  в продолжении программы (после то-
го, как она выйдет из ПЗУ) проверить пе-
ременную #5CD6: ежель там ноль, то рабо-
тать далее, иначе - обрабатывать ошибку.

  Нижеприведенная  процедурка  реализует
данный алгоритм.

READ1F  LD B,1
        XOR A
        LD (#5CD6),A ;обнуляем
        LD HL,TEMP   ;адрес где 1
        LD (HL),1
        LD DE,#2099
        LD IX,CONTIN
        PUSH IX
        PUSH HL      ;все кладем
        PUSH BC      ;на стек
        JP DOS_DE    ;и прыгаем в ПЗУ
CONTIN  LD A,(#5CD6) ;продолжение
        DI
        OR A         ;проверяем
        JR NZ,DERR ;ошибка !
        ;работаем дальше

TEMP    DB 0;ВРЕМЕННАЯ ПЕРЕМЕННАЯ

DOS_DE  PUSH DE  ;прыгаем в ПЗУ ДОС
        JP #3D2F ;через точку

  Вот и все.

  2)  Cпособ  чтения  порта  при  помощи
процедуры  TR-DOS, находящейся по адресу
#3FE5.  Применяется в извесной программе
RDS  v3.1 (c) RokSoftware. Эта процедура
обычно предназначенна для чтения массива
данных из порта (C), с синхронизацией по
по  битам 6 и 7 (строб и готовность дан-
ных) порта #FF.

  Здесь  же используется не совсем стан-
дартное  обращение, т.к. если сразу сде-
лать  переход  на  эту процедуру, то она
зациклится на опросе этих битов. Поэтому
мы вначале зададим контроллеру дисковода
относительно  длительную  команду, опро-
сим порт и как раз к исполнению этой ко-
манды  и придем на опрос битов. Происхо-
дит это обращение по адресу #3FEC:

#3FEC   INI ;читаем порт (C)
            ;и  кладем  его
            ;содерщимое в (HL)
        JR #3FE5 ;преходим

#3FE5   IN A,(#FF) ;опрашиваем
        AND #C0    ;биты
        JR Z,#3FE5 ;готовности
        RET M      ;вертаемся
                   ;если все прочтено

  Таким  образом  для чтения порта и за-
писи его содержимого по заданному адресу
необходимо:

  1)  Запустить  на  выполнение  команду
дисководу.  Для  этой  цели  обычно  ис-
пользуется команда позиционирования. Де-
ло  в том, что дисковод будет позициони-
роваться на текущую дорожку, т.е. просто
запустится. Это ограничивает возможности
по применению способа: его можно исполь-
зовать  в составе процедуры проверки на-
личия дискеты в дисководе;

  2)  Записать  в регистр C номер порта:
#1F;

  3)  Записать в HL адрес куда будет пи-
саться значение порта;

  4) Неплохо бы и остановить дисковод

  По этому алгоритму работает нижеприве-
денная  процедура  проверки  на  наличие
диска в дисководе.

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

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

DREADY  LD A,#3C   ;запись в #FF
        CALL TOFF
        LD A,#1F   ;позицианирование на
        CALL TO1F  ;текущую дорожку
        LD A,#D8   ;прерывание опреации
        CALL TO1F
        LD HL,TEMP  ;читаем сюда
        LD C,#1F    ;из порта #1F
        LD DE,#3FEC
        CALL DOS_DE ;читаем
        XOR A      ;сброс контроллера
        CALL TO1F
        LD A,#D8   ;прерывание опреации
        CALL TO1F
        LD A,(TEMP) ;проверяем бит 6
        AND #40
        RET Z      ;сброшен
        LD A,1
        RET        ;установлен

TOFF    LD C,#FF  ;запись в #FF
        JR TOWG
TO1F    LD C,#1F  ;запись в #1F
TOWG    LD IX,#2A53 ;OUT (C),A
DOS_IX  PUSH IX ;переход в ПЗУ
        JP 15663

TEMP    DB 0 ;временная переменная



     Сверхбыстрое позиционирование
               дисковода

  Этот  прием  применяется  очень редко,
хотя  обеспечивает тихое и быстрое пере-
мещение головки дисковода. Практически -
это замена аппаратному турбированию дис-
ковода. Минусом данной продудуры являет-
ся ее несовместимость с некоторыми типа-
ми "медленных  дисководов"  с  червячным
("винтовым")  методом  перемещения голо-
вок.  Собственно  говоря,  эта процедура
используется  в  MultiColor Studio v2.0,
(c)  OHG.  Так  что если эта программа у
вас  не  идет, то винить надо дисковод и
авторов  программы,  не  предусмотревших
настроек процедуры.

  В  общем случае, желательно предусмот-
реть  отключение такого свербыстрого по-
зиционирования,  кроме  того этот способ
можно "подстраховать"     дополнительной
командой   позиционирования  контроллера
дисковода.  Сама же программа использует
команды "Шаг  впред" и "Шаг назад". Ско-
рость  премещения определяется задержкой
между двумя такими командами (желательно
предусмотреть возможность ее регулирова-
ния!).

  Предварительно   необходимо   записать
нужные значения в регистры #7F (дорожка)
и  #FF (статус контроллера). Кроме того,
необходимо  хранить значение текущей до-
рожки (в   переменной  TRACK),  так  как
от  нее отсчитывается число шагов, необ-
ходимых  для перемещения на заданную до-
рожку.  Ее содержимое - логический номер
дорожки (0-166).

  На  входе процедуры, в регистре A дол-
жен  быть  указан  номер  дорожки,  куда
осуществляется премещение.

POSIT   PUSH AF ;запоминаем
        SRL A   ;получаем  физический
        LD C,A  ;номер дорожки
        LD A,(TRACK) ;текущая
        SRL A      ;физическая дорожка
        CP C
        JR Z,POSI_OK ;уже тут
        JR C,POSI_UP ;вперед
        SUB C        ;назад на
        LD B,A       ;В дорожек
        LD A,#78     ;"Шаг назад"
        JR POSITI
POSI_UP LD D,A
        LD A,C
        SUB D        ;назад на
        LD B,A       ;В дорожек
        LD A,#58     ;"Шаг назад"
POSITI  LD (POS_COM),A ;код команды
        CALL PAUSE     ;пауза
POSITIC PUSH BC
        LD DE,#2FC1
        CALL DOS_DE
POS_COM EQU $+1
        LD A,#58     ;код
        LD DE,#2FC3  ;команды
        CALL DOS_DE
        CALL PAUSE   ;ждем немного
        POP BC
        DJNZ POSITIC  ;повторяем
POSI_OK POP AF
        LD (TRACK),A ;новое значение
        RET

TRACK   DB 0 ;текущая дорожка

PAUSE   PUSH BC
        PUSH HL
        LD BC,400  ;задержка
POS1    DEC BC
        LD A,B
        OR C
        JR NZ,POS1
        POP HL
        POP BC
        RET

DOS_DE  PUSH DE  ;прыгаем в ПЗУ ДОС
        JP #3D2F ;через точку


    Сверхбыстрая остановка дисковода
    
  Эта   процедурка   тоже   выдрана   из
MultiColor  Studio  v2.0, (c)  OHG.  Она
также  основана на мухлевании с командой
позиционирования  и  оригинальном чтении
порта  #1F. Для чтения используется про-
цедура по адресу #3EF3:

#3EF3 IN H,(C)    ;чтение порта
#3EF5 IN A,(255)  ;ожидание
      AND 192     ;какого-нибудь сигнала
      JR Z,#3EF5
      EI          ;на случай возврата
      RET M       ;если поступил INTRQ
                  ;то возврат
      DI          ;запрет прерываний
      IN A,(127)  ;чтение байта
      JR #3EF5    ;повтор

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

STOPDSK PUSH AF
        PUSH HL
        LD A,#40 ;шаг вперед без
        ;инкремента регистра дорожки
        LD DE,#2FC3
        CALL DOS_DE
        LD A,#D8    ;прерывание
        LD DE,#2FC3
        CALL DOS_DE
        LD C,#1F
        LD DE,#3EF3
        CALL DOS_DE
        POP HL
        POP AF
        EI
        RET

                 * * *



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

От редактора - DWT отчитывает Павла Павлова за отзыв о газете.

Обзор почты - письма читателей: Виталий Петренко (SLY), Вадим Чумаченко , Nuts, Xmus.

Обзор новья - пресса: Adventurer #13, Lamergy #5-#9, Body #33-#36, Heresy #8, Target #10, DonNews#16. Софт: ACEdit 0.60, Pro Tracker 3.53. Игры: Magic Music Toy 1.02, Открывашка, 3D-Roost, Citadel demo.

Новости и старости - продолжается конкурс <Твоя Игра>, Nuts прекратил работу над коммандером TRouble, Dizzy Game Editor почти готов, Демо версия <Угадай Мелодию> уже готова и т.д.

Мнение - Мысли о системном софте на Спектруме.

Мнение - lzb/j77: "Я и тут молчать не буду!"

Мнение - Абзац: новая печатная газета для Спректрума.

Кодерам - частные моменты в работе с TR-DOS (TR-DOS на уровне портов).

Железяки - схемка: привязка видеосигнала Спектрума к уровню чёрного.

PC и Spectrum - Unreal vs ZX Mak: сравнение двух популярных эмуляторов ZX Spectrum.

PC и Spectrum - обзор PC программ для копирования и конвертации спектрумовских файлов.

О всем про все - "Путь перед рассветом".

И смех, и грех - Письмо в Военно-исторический форум.

Реклама - рекалама и обьявления.


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

Похожие статьи:
Oбмен опытом - Несколько полезных советов и рекомендаций по подключению FDD 3.5 (трехдюймового дисковода).
Система - Описание программ : ZX-ASM3.0, Universal XAS Converter v2.1, Format Utility v2.01, Commander DOS v1.9, Super Catalog v1.12, Text Designer v1.0, The Dizzy Editor v1.0, Digital Studio for Covox, Alfasoft Music Crasher v2.13. Драйвер печати шрифтов , созданных в Mach v2.4.
Софт - Встрял: Starcontrol.
Вступление - Активность ZX-Hаpода pастет, но очень медленно.
Металлолом - Многие задавались вопросом как подключить hayes-модем к спеку - отвечаем...

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