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

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

<b>TR-DOS для начинающих</b> - Продолжение.
┌─────────────────────────────┐
│                             │
│    TR DOS ДЛЯ НАЧИНАЮЩИХ    │
│                             │
└─────────────────────────────┘

(c) В.Сироткин

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

  ПРОГРАММИРОВАНИЕ КОНТРОЛЛЕРА

   А теперь  разберем  несколько
конкретных примеров.

   !!! Необходимое  напоминание:
не забудьте, что для разных вер-
сий ТРДОС необходимо  выставлять
свои адреса подпрограмм !!!

   Перед тем, как загрузчик нач-
нет  работать, программа  должна
определить версию ТРДОС и  скор-
ректировать   адреса    вызовов.
Определять версию и  настраивать
загрузчик удобнее всего функцией
ТРДОС C = #13.  Мы пропустим эту
часть программы, так как в главе
'ФУНКЦИИ ТРДОС'  подробно описа-
но, как это сделать.

   Пример 1. Загрузчик файлов
140.
;базовые адреса ПЗУ даны для версии 5.01 *
;в угловых скобках будут указаны адреса для 5.03 *

; головная часть загрузчика

       ORG  ADRESS   ; начальный адрес загрузчика
       DI            ; запретим прерывания
       LD HL,#5800   ; закрасим экран черными атри-
                     ; бутами
                     ; на экране у нас будет буфер
       LD DE,#5801   ; для считывания последнего
                     ; сектора файла, чтобы в ОЗУ
                     ; перенести нужное количество
                     ; байтов,
                     ; а также буфер для считы-
                     ; вания каталога диска
       LD BC,#01FF
       LD (HL),L
       LDIR
;------------------

       CALL  LOAD_CAT ; найти на диске нужный файл
;  и  его атрибуты (подпрограмма возвращает в ре-
;гистре  'D'- номер  Дорожки, в 'E' - номер Секто-
;ра, в 'HL' адрес загрузки в ОЗУ, ; в 'BC'- длину)
;------------------
       PUSH  BC       ; спрятать длину файла
       DEC   B        ; уменьшить длину на 1 сектор
;-------------------

       CALL  LOAD_SEK ; файл  без последних
                      ; 2-х секторов (если 'C'=0,
                      ; то без 1-го последнего)
                      ; загрузить с адреса из 'HL'
;-------------------
       PUSH  HL       ; спрятать последующий адрес
                      ; ОЗУ для оставшихся 2-х,
                      ; (1-го) сектора
       LD HL,#4800    ; адрес буфера для сектора

       LD B,2         ; ДВА сектора
       CALL  LOAD_SEK ; загрузить в адрес #4800 два
                      ; последних сектора
       POP  DE        ; достать адрес ОЗУ для остав-
                      ; шихся секторов/сектора
       POP  BC        ; достать длину всего файла
       LD   B,1       ; один сектор наверняка, и
                      ; остаток длины из 'C'
       LD   HL,#4800  ; перенести из экрана
       LDIR           ; в адрес по 'DE'
       EI             ;
       RET            ; вернуться в программу

;---------------------------
;  подпрограмма считывание каталога и определение
;  атрибутов файла

LOAD_CAT LD DE,0000     ; ноль Дорожка и Сектор
LOAD     PUSH DE        ; спрятать
         LD HL,#4800    ; адрес буфера в ОЗУ для
                        ; сектора
         PUSH HL        ; спрятать
         LD B,1         ; Один сектор
         CALL LOAD_SEK  ; считать сектор номером
                        ; из 'E'
                        ; с НОЛЬ дорожки ; т.е.
                        ; из области КАТАЛОГА диска
         POP HL         ; начало адреса буфера
         LD B,#10       ; счетчик  заголовков (на
                        ; секторе их 16)
CIKL     PUSH HL        ; спрятать адрес начала
         LD DE,FILENAME ; адрес в ОЗУ, где ИМЯ
                        ; файла,
                        ; который  нужно загрузить
         LD C,08        ; счетчик букв имени файла
NAME_F   INC HL         ; пропустим первую букву в
                        ; имени
                        ; файла в считанном ката-
                        ; логе
         LD A,(DE)      ; буква НУЖНОГО имени
         CP (HL)        ; сравним с буквой из ИМЕНИ
                        ; файла считанного с диска
         JR NZ,ZAGOLOW  ; не совпало - переход
         INC DE         ; совпало - следующая буква
                        ; имени
         DEC C          ; уменьшить счетчик букв
                        ; имени
         JR NZ,NAME_F   ; все буквы? - нет - возврат
                        ; на цикл проверки
         POP DE         ; Да, имя и тип файла
                        ; совпали !
         POP DE         ; указатель стека вернем в
                        ; исходное состояние
         INC HL         ; переходим на атрибуты
                        ; файла
         LD  E,(HL)     ; мл.бит АДРЕСА загрузки
                        ; файла
         INC HL
         LD D,(HL)      ; ст.бит АДРЕСА загрузки
         INC HL
         LD C,(HL)      ; мл.бит ДЛИНЫ
         INC HL
         LD B,(HL)      ; ст.бит ДЛИНЫ
         INC HL         ; пропустим байт объем в
                        ; секторах
         INC HL         ;
         LD  A,(HL)     ; Номер первого Сектора
                        ; файла
         INC HL
         LD  H,(HL)     ; Номер Дорожки
         LD  L,A
         EX  DE,HL      ; в HL-адрес загрузки в ОЗУ
                        ; в DE - дорожка / сектор
                        ; в BC - длина згружаемого
                        ; блока
         RET            ; вернемся

;---------------------------
; счетчик заголовков и секторов каталога

ZAGOLOW POP HL          ; вернем адрес текущего
                        ; заголовка
        LD  DE,#0010    ; длина заголовка
        ADD HL,DE       ; перейдем на следующий
                        ; заголовок
        DJNZ CIKL       ; если не весь сектор -
                        ; повторить
        POP DE          ; вернуть и увеличить номер
        INC DE          ; сектора
        BIT 3,E         ; все 7 секторов каталога
        JR Z,LOAD       ; нет - повторить
        JP ERROR        ; да, каталог весь,
                        ; но файлы не обнаружены:
                        ; Переход на обработку
                        ; ошибочной ситуации

;---------------------------
; имя файла для поиска в каталоге

FILENAME  DEFM 'FNAME_0' ; имя файла без 1-й
                         ; буквы
          DEFM 'C'       ; файл тип CODE
;----------------------------

;подпрограмма загрузки с диска

LOAD_SEK  LD IX,#2F1B < #2F65 > ; адрес подпрограм-
                                ; мы в ПЗУ
;'ВОСТАНОВЛЕНИЕ, т.е. переход  на дорожку 0
; адрес является входом в середину процедуры
; #2EF0 < #2F3A > (смотри приложение)

          CALL TRDOS     ; исполнить подпрограмму
                         ; в ПЗУ

TREK      PUSH BC        ; спрячем длину блока
          PUSH           ; и номер дорожки с
                         ; сектором
          LD A,D         ; номер дорожки
          OR A           ; преобразуем в номер
                         ; ЦИЛИНДРА
          RRA            ; и  в СТОРОНУ диска
          LD C,A         ; скопируем номер цилиндра
                         ; в 'C' для работы в ПЗУ
          JR NC,UP_TREK  ; был 'перенос'?,номер был
                         ; четный ?
          LD A,#2C       ; если нечетный -
                         ; готовность 'НИЗ'
          JR FIND_TRK    ; перейти на 'ПОИСК НУЖНОГО
                         ; ТРЕКА'

UP_TREK   LD A,#3C       ; номер четный -
                         ; готовность 'ВЕРХ'

FIND_TRK LD IX,#2F03 < #2F4D > ; адрес в ПЗУ;
                               ; "ПОИСК"

; этот адрес является входом в середину процедуры
; #2EF0 < #2F3A > (смотри приложение к главе)

         CALL TRDOS     ; найти нужный цилиндр и
                        ; прижать к нужной стороне
                        ; диска
          POP DE        ; извлечь номер дорожки,
                        ; сектора
          POP BC        ; и длину блока

N_SECTOR  PUSH BC       ; спрятать
                        ; (здесь уже в процессе
          PUSH DE       ; загрузки будут текущие
                        ; номера
                        ; дорожек и секторов)

          LD IX,#2ED1 < #2F1B > ; загрузить сектор
                                ; с номером
                         ; из 'E', в адрес по 'HL'

          CALL TRDOS     ; исполнить

          POP DE         ; извлечь номер ДОРОЖКИ
                         ; и СЕКТОРА
                         ; уже загруженного
          INC H          ; увеличим адрес буфера
                         ; ОЗУ на 1 сектор,
                         ; т.е. поднимем на 256
          INC E         ; увеличим номер сектора
          BIT 4,E       ; все сектора на дорожке ?

          JR Z, ALL_SEC ; НЕТ- продолжаем загрузку

          LD E,00        ; ДА - обнулим номер
                         ; сектора
          INC D          ; увеличим номер ДОРОЖКИ
          POP BC         ; посмотрим оставшуюся
                         ; длину
          DJNZ TREK      ; уменьшим ее на 256
                         ; (на 1 сектор)
                         ; вернемся, если не все
                         ; загружено

          RET            ; загрузили все что нужно
                         ; выход
;---------------------
ALL_SEK   POP BC         ; посмотрим оставшуюся
                         ; длину
          DJNZ  N_SECTOR ; уменьшим ее на 256
                         ; (на 1 сектор)
                         ; згружаем с дорожки
                         ; дальше, если еще не все

          RET            ; загрузили все что нужно -
                         ; выходим

;---------------------
TRDOS     PUSH IX       ; адрес на исполнение
                        ; процедуры ПЗУ ТРДОС
          JP #3D2F      ; вызвать процедуру косвенно
                        ; по адресу из стека
;----------------------------------------------------
2
   Данная программа не  нуждает-
ся ни в каких системных перемен-
ных и может работать даже в  эк-
ранной области.  Ею можно загру-
жать как головную часть програм-
мы, так и подгружать последующие
уровни. Единственный  недостаток
такого  загрузчика - это то, что
все файлы на диске, в  каталоге,
должны иметь свою РЕАЛЬНУЮ длину
и  адрес  загрузки. Если вам это
почему-то не подходит (например,
вы хотите защитить свои програм-
мы), то, добавив в программу еще
несколько команд и применив  ме-
тод  шифрования  длины  и адреса
файла во время их создания, мож-
но решить и эту проблему. Но это
разговор для отдельной главы.
   Как  мы  видим, большую часть
места в программе занимает поиск
файла на диске и определение его
атрибутов (длины, старта, номера
дорожки и номера сектора).
   Программу  можно  существенно
сократить, если все это  опреде-
лять изначально, когда идет пер-
воначальная загрузка из БЕЙСИКа.
Пока  память  свободна и область
системных  переменных  ТРДОС  не
перекрыта  кодами.  Это  удобнее
сделать  Функциями ДОС, а данные
о файлах передать потом в основ-
ную  программу, сохранив  их  до
поры до времени в свободном мес-
те памяти.

           Пример 2

   Рассмотрим  как раз  тот слу-
чай, когда данные о файле (кото-
рый должен подгружаться как пос-
ледующий уровень  игры  или  как
состояние этой игры)  переданы в
программу во время ее загрузки.
140.
; * загрузчик  *  используем подпрограмму
; ТРДОС #3F00 < #3F0A >
; програма стартует с метки START
; данные о файле лежат в адресах ОЗУ
; Номер сектора и номер дорожки - по адресу
;                                  'ATRIBUT'
; длина файла по адресу  'DLINN'
; адрес загрузки по адресу 'ADR_LO'
;-----------------

ATRIBUT        NOP   ; сюда передать Номер Сектора
               NOP   ; сюда передать Номер Дорожки
DLIN           NOP   ; сюда передать Длину загрузки
               NOP
ADR_LO         NOP   ; сюда передать адрес загрузки
               NOP

;-------подпрограмма вызова процедуры ДОС----------
TRDOS          PUSH IX      ; вызвать подпрограмму
                            ; ТРДОС
               JP #3D2F     ; адресом из 'IX'
;--------------------------------------------------

;............... СТАРТ..............................

START  LD BC,(ATRIBUT)  ; возьмем номера дорожки и
                        ; сектора
       LD HL,(#5CFE)    ; сохраним изменяемые ячейки
       PUSH HL          ; ОЗУ в системной области
       LD HL,(#5D00)
       PUSH HL
       LD HL,(#5C00)
       PUSH HL
       LD A,0           ; в (#5C00) должен быть 0
       LD (#5C00),0
       LD A,C           ; Номер сектора
       LD C,B
       LD (#5CFF),A     ; занести N. сектора
       PUSH BC          ; сохраним N. дорожки

       LD IX,#2EF0 < #2F3A > ; найдем дорожку на
       CALL TRDOS            ; диске

       LD BC,00         ; задержимся
WAIT   DJNZ WAIT        ; и
       DEC C            ; подождем
       JR NZ,WAIT

       POP BC           ; извлечем N. дорожки

       LD IX,#2EF0 < #2F3A > ; так как головка у нас
                     ; вышла на соответствующее место
       CALL TRDOS    ; то дав 'ПОИСК' этой же дорожки
                     ; мы просто прижмем головку к
                     ; диску и раскрутим диск
       LD IX,#3F00 < #3F0A > ; диск крутится, головка
                      ; прижата, теперь -
                      ; команда чтение Сектора
       LD HL,(ADR_LO) ; взять адрес Загрузки и
       LD (#5D00),HL  ; поместить для работы

       CALL TRDOS     ; считать Один Сектор с диска
                      ; в адрес ОЗУ
               ............
               и т. д. ; далее идут коды пересчета
                       ; сколько осталось загружать,
                       ; какие сектора и дорожки.
;-------------------------------------------------
2
   Я  думаю,  продолжение   этой
программы  вы  сможете  дописать
сами (алгоритм  можно  взять  из
предыдущего примера). Не забудь-
те только вернуть при выходе  из
программы со стека все сохранен-
ные значения в область системных
переменных.

   А  теперь  несколько  слов  о
ЗАПИСИ на диск.  Если в вышепри-
веденных примерах вызов  'ЧТЕНИЕ
СЕКТОРА'  заменить на  'ЗАПИСЬ В
СЕКТОР' и  чуть-чуть  переделать
программу, то  у  вас  получится
готовая  подпрограмма  ЗАПИСИ  в
фиксированный файл. (Смотри гла-
ву Функции ТРДОС, пример  сохра-
нения состояния игры 'ЭЛИТА').
   Вы из БЕЙСИКа  создаете  файл
нужной величины для  последующей
записи в него информации из  ра-
ботающей  программы.   Передаете
атрибуты этого  файла  во  время
загрузки в тело программы, где у
вас расположена ваша подпрограм-
ма 'ЗАПИСИ'- и все.
   Это самый легкий способ реше-
ния проблемы. Если же вы  хотите
написать    полную     программу
'СОХРАНЕНИЕ', то правила  записи
файла  на  диск  остаются такими
же, как в главе 'ФУНКЦИИ ТРДОС'.
А той информации, что вы уже по-
черпнули - вполне хватит,  чтобы
сделать  это  вполне  профессио-
нально.

   Теперь, когда мы  узнали, как
записывать - считывать с диска и
как написать подпрограмму, кото-
рая это делает, поговорим о том,
где эту подпрограмму помещать  в
переделываемой программе.
   Немного об этом было  сказано
в главе 'ФУНКЦИИ ТРДОС', но  так
как  мы  уже  вышли  на  уровень
программирования контроллера, то
у нас и  возможностей  появилось
больше.
   Как    встроить     приличный
ПОЛНОЦЕННЫЙ  'загрузчик/сохрани-
тель' в программу,  которая  ис-
пользует ВСЮ ПАМЯТЬ  компьютера,
если к тому  же  не  хочется  из
этой  программы  ничего  выкиды-
вать, а также  не  хочется  пор-
тить экран ??? Выход есть!
   Этот медод может  иметь  мно-
жество различных  вариантов,  но
суть  одна:  в    переделываемой
программе  встраивают  лишь  ма-
ленькую   подпрограмму-загрузчик
(всего лишь несколько байт), ко-
торая  предназначена   сохранять
часть ОЗУ с адреса #5C00 до  ад-
реса, к примеру, #5FFF  (4  сек-
тора  нам,  надеюсь,  хватит)  в
фиксированный  файл,  а  на  это
место загружать из другого  фик-
сированного файла  копию - образ
области  СИСТЕМНЫХ переменных  и
ОСНОВНОЙ  загрузчик,  который  и
будет  выполнять  главную работу
по ЧТЕНИЮ/ЗАПИСИ.
   После окончания работы основ-
ной  загрузчик  должен  передать
управление на ту маленькую  под-
программу,  которая   востановит
сохраненную область ОЗУ из  пер-
вого файла на свое место.
   Это  называется    ОВЕРЛЕЙНОЙ
ЗАГРУЗКОЙ или 'вытаскиванием са-
мого себя за  волосы'.  Вы  рас-
сматриваете  дисковое  простран-
ство как область  дополнительной
памяти с жестко заданными  адре-
сами и перекачиваете в  нее  или
из нее то, что нужно вам на дан-
ный момент.  Поэтапно  это может
выглядеть приблизительно так:

   Создаем командами БЕЙСИКА два
файла типа CODE.

> RANDOMIZE USR 15619:REM:SAVE
  "BUFFER"CODE любой адрес,1024

   Это файл для  сохранения  об-
ласти ОЗУ из  тела  переделывае-
мой программы в процессе ее  ра-
боты.

> RANDOMIZE USR 15619:REM:
  SAVE"SYSBOOT"CODE 23552,1024

   Это файл с образом  системных
переменных и с основной подпрог-
раммой работы с диском.

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

   В файле 'SYSBOOT' после копии
всей области системных  перемен-
ных  и  области буфера вписываем
нашу основную подпрограмму рабо-
ты с диском.

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

 - номер первого сектора файла
   "BUFFER",
 - номер первой дорожки этого
   файла,
 - номер первого сектора файла
   "SYSBOOT",
 - номер первой дорожки этого
   файла.

   Длину передавать не надо, так
как она известна изначально.

   Во время работы  переделывае-
мой программы, если она  выходит
на процесс загрузки или сохране-
ния, запустится  вспомогательный
загрузчик, который сначала  сох-
ранит область ОЗУ с адреса #5C00
по #5FFF в файле "BUFFER", а за-
тем на это место в ОЗУ  загрузит
из файла "SYSBOOT" копию  облас-
ти  системных    переменных    и
ОСНОВНУЮ подпрограмму  работы  с
диском и передаст ей управление.

   Так как все  системные  пере-
менные и ТРДОС и SOS востановят-
ся, основная подпрограмма  может
работать с  диском  через  любые
ФУНКЦИИ ТРДОС. А это значит, что
у  вас  отпали  все  проблемы  с
поиском нужного файла на диске и
с пересчетом номеров  дорожек  и
секторов - при считывании с дис-
ка, а при записи - проблема  за-
писи информации о файле в  ката-
лог и в 8-й системный сектор!

   Не забудьте, в регистре IY  у
вас должено быть значение #5C3A,
и установлено  прерывание  1.  А
также - переустановите стек, ес-
ли он был  настроен  на  ту  об-
ласть,  которая  сохраняется  на
диске.
   После завершения своей  рабо-
ты основная подпрограмма  должна
передать  управление  опять   во
вспомогательный загрузчик, кото-
рый востановит из файла "BUFFER"
всю область программы, сохранен-
ную на диске, на старое место  в
ОЗУ.
   Единственное неудобство в та-
ком методе -  это  необходимость
иметь  ко  всем  прочим   файлам
программы еще и 2 наших файла.
   Можно отказаться и от файлов,
если поместить буфер  сохранения
и основную подпрограмму работы с
диском в конкретные сектора,  на
конкретной дорожке диска. Напри-
мер, можно использовать  пустую-
щие сектора на НУЛЕВОЙ  дорожке.
Вспомним, что каталог у  нас  на
первых семи секторах,  системный
сектор -  восьмой,  а  остальные
сектора свободны и  системой  не
используются (их использует под-
программа  ПЗУ  ТРДОС  во  время
сохранения МАГИК-файла).
   Если поступить таким образом,
то вы получите программу,  кото-
рая  будет  работать  только  на
этом диске. С одной стороны, это
создаст проблемы  при  копирова-
нии вами этой программы на  дру-
гой диск. Необходимо будет копи-
ровать не толко файлы программы,
но и  сектора  НУЛЕВОЙ  дорожки,
где у вас будет записана  основ-
ная подпрограмма работы  с  дис-
ком.
   А с  другой  стороны,  модуль
работы с  диском, записанный  на
этих секторах,  может  использо-
вать сразу несколько программ, а
сами программы будут защищены от
несанкционированного   копирова-
ния с вашего диска, так как заг-
рузочный модуль на  НУЛЕВОЙ  до-
рожке при попытке 'сдуть' у  вас
программу  останется  нескопиро-
ванным.
   Такой диск можно будет скопи-
ровать только  целиком  ТРЕКОВЫМ
КОПИРОВЩИКОМ.
   А если пойти дальше и  распо-
ложить сектора с нашей  подпрог-
раммой на  специально  размечен-
ной дорожке с номером,  например
161,  о  которой  системе  будет
просто неизвестно, то  полноцен-
но скопировать этот диск не смо-
жет никакой копировщик. Но о за-
щите дисков мы поговорим  немно-
го позднее.

   А сейчас рассмотрим те аспек-
ты программирования контроллера,
которые до сих  пор  упоминались
лишь вскользь.

         ФОРМАТИРОВАНИЕ

   Процесс  форматирования - это
запись  некоторой    специальной
последовательности кодов на выб-
ранный ЦИЛИНДР и сторону  диска.
Наибольшее  число  цилиндров  на
диске зависит  прежде  всего  от
дисковода, так как у одних  дис-
ководов ограничитель хода  голо-
вок стоит на 80, а у  других  он
может стоять на 86 (ограничитель
чисто механический).
   ТРДОС форматирует диск на  80
цилиндров, записывая в  8-м сек-
торе 0 дорожки информацию-сигна-
нализатор - какой  это  диск   и
сколько  свободных  секторов  на
диске.
   Процедура для  форматирования
одной дорожки находится в ПЗУ по
адресу #1FC1 <#1FFD>. Перед этим
головки должны быть выведены  на
нужный цилиндр и прижаты к  вер-
хней (четной) или нижней (нечет-
ной) стороне  диска.  Затем  по-
дается команда 'ЗАПИСЬ ДОРОЖКИ'-
#F4.

   Форматирование     происходит
следующей    последовательностью
байтов  (эти  байты  подаются  в
порт #7F в подпрограмме по адре-
су #2075 <#20B1>).
   Для наглядности приводим таб-
лицу - что подается  для  записи
на диск и  что  записывается  на
диске, так как некоторые байты в
команде 'ЗАПИСЬ ДОРОЖКИ ' интер-

претируются  микросхемой   ВГ93,
как вложенные субкоманды.

               ТАБЛИЦА МАССИВА ДЛЯ ОДНОГО СЕКТОРА

     ┌────────────────────────────────┬───────────────────┐
     │ ЧТО ПОДАЕТСЯ В ПОРТ ДЛЯ ЗАПИСИ │  ЧТО ЗАПИСЫВАЕТСЯ │
     ├────────────────────────────────┴───────────────────┤
     │           10 байтов #4E ( нач. пробел )            │
     ├────────────────────────────────────────────────────┤
     │                  12 байтов  НОЛЕЙ                  │
     ├────────────────────────────────┬───────────────────┤
     │ 3 раза код #F5 (инициализация  │   код #A1, метка  │
     │    счетчика контр.суммы)       │   начало I.A.M    │
     ├────────────────────────────────┴───────────────────┤
     │        код #FE   (адресная индексная метка)        │
     ├────────────────────────────────────────────────────┤
     │                Байт  НОМЕР ДОРОЖКИ                 │
     │ (ВНИМАНИЕ!!!  НОМЕР ДОРОЖКИ на диске ТРДОС записы- │
     │ вает и на ВЕРХНЕЙ и на НИЖНЕЙ стороне диска с ОДИ- │
     │ НАКОВЫМ  номером  - НОМЕРОМ ЦИЛИНДРА. Определение, │
     │ какая  дорожка  из  160  где находится, происходит │
     │ чисто программным путем).                          │
     ├────────────────────────────────────────────────────┤
     │                Байт СТОРОНЫ диска                  │
     │  (ВНИМАНИЕ!!!   ТРДОС  и  верхнюю и нижнюю сторону │
     │ диска метит  байтом  0, определение, какая сторона │
     │ диска принадлежит какой из 160 дорожек, происходит │
     │ чисто программным путем).                          │
     ├────────────────────────────────────────────────────┤
     │       Байт НОМЕР СЕКТОРА ( отсчет с 1 до 16)       │
     ├────────────────────────────────────────────────────┤
     │ Байт РАЗМЕР СЕКТОРА ( в ТРДОС = 1 ,т.е. 256 байт)  │
     ├────────────────────────────────┬───────────────────┤
     │ Байт #F7   (субкоманда -       │    Два байта      │
     │ записать подсчитанную к.сумму) │ конрольной суммы  │
     ├────────────────────────────────┴───────────────────┤
     │        22 байта #4E ( пробел перед данными)        │
     ├────────────────────────────────────────────────────┤
     │                     12 байтов  НОЛЕЙ               │
     ├────────────────────────────────┬───────────────────┤
     │ 3 раза код #F5 (инициализация  │  код #A1, начало  │
     │    счетчика контр.суммы)       │  метки данных     │
     ├────────────────────────────────┴───────────────────┤
     │         код #FB   (адресная метка данных)          │
     ├────────────────────────────────────────────────────┤
     │                       256  НОЛЕЙ                   │
     │                   (это поле данных)                │
     ├────────────────────────────────┬───────────────────┤
     │      Байт #F7   (субкоманда -  │    Два байта      │
     │  записать подсчитанную к.сумму │ контрольной суммы │
     ├────────────────────────────────┴───────────────────┤
     │        50 байтов  #4E ( остаточный пробел)         │
     └────────────────────────────────────────────────────┘

   После того, как все 16 секто-
ров на дорожке размечены, остав-
шееся место дорожки  заполняется
кодом #4E.
   Этот  массив   форматирования
предназначен   для    дисководов
двойной плотности. Для  дисково-
дов одинарной плотности  он  бу-
дет другой.
   Для дисководов двойной  плот-
ности  (режим   Модифицированной
Частотной модуляции ) в  процес-
се  выполнения  команды  "ЗАПИСЬ
ДОРОЖКИ"  микросхема   восприни-
мает и рассматривает как  субко-
манды следующие байты:

байт #F5 - запись кода #A1 и за-
           пуск   счетчика  кон-
           трольной суммы;
байт #F6 - запись кода C2;
байт #F7 - запись   подсчитанной
           контрольной суммы  на
           диск.

   В процессе программирования у
вас может возникнуть желание от-
форматировать отдельные  дорожки
на диске по-другому. Например, в
процессе  создания    защищенных
дисков или для скрытого  загруз-
чика. Нет проблем!
   Вы  можете   отформатировать,
например, 163-ю дорожку на своем
диске  всего  с  одним  сектором
длиною в 1024 байта и с  систем-
ным номером 223, и об  этом  бу-
дет знать только ваша программа,
работающая с этой дорожкой, и вы
сами.
   При попытке кого-либо  друго-
го прочитать вашу секретную  до-
рожку и  сектор,  скорее  всего,
его постигнет неудача,  так  как
этот кто-то не будет знать  сис-
темного  номера  этого  сектора.
Микросхема ВГ93  его  просто  не
найдет на дорожке, не говоря  уж
о попытке прочитать его содержи-
мое.
   (Когда вы прочтете эту  книгу
до конца и затратите  определен-
ные усилия, вы сможете без  тру-
да  копировать  любые   подобные
диски   с    любой    ЛОГИЧЕСКОЙ
ЗАЩИТОЙ).

   Форматирование дорожки  можно
выполнить и  через  другую  под-
программу ТРДОС, а именно  #3FC0
<#3FCA> (см.выше). Сформировав в
области ОЗУ весь массив дорожки,
каким он должен быть  на  диске,
можно одним махом  записать  ин-
формацию из ОЗУ в диск на дорож-
ку, и таким образом отформатиро-
вать ее.
   Посчитаем из таблицы, сколько
байтов в ОЗУ займет у  нас  весь
массив:
   376  байт  -  это  на   одном
секторе и 376*16= 6016  байт  на
всей  дорожке  (плюс    довесок,
приблизительно в 200 байт).
   При  форматировании   дорожки
своими форматами  вы должны учи-
тывать это, и длина всего масси-
ва вашего формата не должна пре-
вышать эту цифру.  Лишняя инфор-
мация просто не запишется на до-
рожку.

   ОПРЕДЕЛЕНИЕ РАЗМЕТКИ ДИСКА

   В некоторых случаях  вам  мо-
жет  потребоваться   определить,
как размечен тот или  иной  диск
(например, для  'вскрытия' защи-
щенных дисков или дисков, разме-
ченных нестандартно).  В системе
команд ВГ93 есть команда:  'ЧТЕ-
НИЕ АДРЕСА', но она предназначе-
на   для  нормально  размеченных
дисков, т.е. без всяких выкрута-
сов.
   С ее помощью можно читать ин-
дексную адресную метку и  ТРДОС-
овских, и MSDOS-овских дисков, и
CP/M дисков, но если вы попытае-
тесь прочитать индексно-адресную
метку на диске, где на одной до-
рожке существуют сектора с  раз-
ной длиной и с номерами, взятыми
с  потолка  - то  вы  прочитаете
метку одного сектора, но узнать,
какие сектора, сколько их и  ка-
кие  у  них  номера, вы  вряд ли
сможете.  Для  этого  существует
'хитрый' способ.
   Вспомним.  У  нас  в  резерве
осталась  команда  ВГ93  'ЧТЕНИЕ
ДОРОЖКИ ЦЕЛИКОМ'. При  этой  ко-
манде микросхема читает с дорож-
ки все: и  метки, и  синхронизи-
рующие  байты, и  данные - в об-
щем, все, все, все. Единственный
недостаток этой  команды  -  это
то, что при чтении информации  с
диска  читаемые байты не строби-
руются. Но это нам не  помешает.
Итак!  Представим, к  вам  попал
диск с подозрительной разметкой.
Выводите  головки  дисковода  на
какую-нибудь дорожку (обычно  на
нулевую ), прижимаете головки  к
поверхности, даете команду 'ЧТЕ-
НИЕ ДОРОЖКИ' и выходите  на под-
программу ТРДОС  #3FDB <#3FE5> -
чтение массива из порта Данных в 
адрес M (HL) (естественно, перед
этим вы  должны  зарезервировать
буфер  для  считываемых  данных,
размером   приблизительно   6300
байта, можно даже на экране).
   Повторите эту процедуру  чте-
ния раза 2-3  подряд  для  более
надежного считывания, т.к.  бай-
ты не сопровождаются  синхросиг-
налом. И вот у вас в буфере ока-
жется массив данных целой дорож-
ки со всеми служебными  метками.
А дальше совсем просто.
   Вспомним, с каких байтов  на-
чинается  I.A.M.  - индексно-ад-
ресная метка. Правильно - с бай-
тов #A1 и #FE (кто не вспомнил -
смотри предыдущую таблицу масси-
ва форматирования).  (Для дисков
с ОДИНАРНОЙ плотностью байт  пе-
ред кодом #FE будет другой  (мо-
жет быть и  00, и #C9, и #FF - в
зависимости от изначального мас-
сива форматирования).
   Находим эти байты в буфере, а
после них, пожалуйста, все  дан-
ные одного сектора: номер дорож-
ки, сторона, номер и длина  сек-
тора. Запомним эти данные в  ка-
ких-нибудь  ячейках  ОЗУ.   Ищем
следующие два байта #A1 и #FE; и
так, пока весь буфер не  кончит-
ся. После этого у  нас  окажутся
на руках все козыри, какой бы ни
был хитроумный формат на  дорож-
ке. Просканировав весь  диск, мы
получим карту формата всех доро-
жек и секторов.  Но  обычно  бы-
вает  достаточно  просканировать
2-4 дорожки.

       Продолжение следует




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

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".


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

Похожие статьи:
Demoscene - Deja Vu #02: Нoвoстu демoсцены.
Фан-клуб - Сегодня, 21 июня 1999 года исполнилось бы 38 лет лидеру группы "КИНО" Виктору Цою...
Новости - Hippiman/Conscience выпустил новогоднюю игру Dizzy Rescues Santa, Польский культуролог Пётр Марецки прислал большой опросник для будущей книги, Сергей Смирнов (Gogin) возродил свой проект по портированию игры Super Mario для Спектрума.
От редакции - второй номер журнала "ТНЕ SТАR".
Конструкции Хаоса'2000 - Информация о фестивале.

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