Eldorado #02
19 января 1996

Система - обращении непосредственно к ПЗУ DOS и о прямом программировании ВГ 93.

<b>Система</b> - обращении непосредственно к ПЗУ DOS и о
прямом программировании ВГ 93.
Приветствую Вас, дорогие читатели и редак-
торы  журнала "Eldorado"! Как здорово, что
у нас в Ярославле наконец-то появился свой
электронный  журнал.  Конечно  ребятам еще
надо  поработать над собой, но первые шаги
были  явно  на уровне. Особенно порадовала
музыка. Ну вот, спасибо сказал, а теперь о
маленькой  ошибочке,  которая  закралась в
первую статью "Система":                  
                                          
                                          
Есть:                                     
                                          
zag       LD     С,5                      
          LD     DE,(23796)               
          RET                             
                                          
Должно быть:                              
                                          
zag       LD     С,5                      
          LD     DE,(23796)               
          JP     #3D13                    
                                          
                                          
Так же хотелось бы отметить, что приведен-
ная  в  первом  номере  "Eldorado"  статья
"Система"  предназначалась  явно для начи-
нающих.  А это значит, что необходимо было
толком рассказать, КАК запихать полученный
загрузчик в первую БЕЙСИК-стоку, если TASM
держит  там  свой  резидент!  Поработайте.
Лично  я  эмулирую  при помощи DEFB и DEFW
БЕЙСИК-операторы. Могу поделиться.        
                                          
                                          
Теперь  по  делу.  Я, собственно, хотел бы
продолжить  тему загрузчиков, и поговорить
об обращении непосредственно к ПЗУ DOS и о
прямом программировании ВГ 93.            
                                          
                                          
Вообще  говоря  о программировании ВГ 93 и
работе  с диском без использования систем-
ных  переменных  DOS говорилось и писалось
немало. Наиболее подробная, на мой взгляд,
информация публиковалась в третьем издании
книги "ZXSpectrum для пользователей и про-
граммистов" (ZXSpectrum & TR-DOS) Н.Родио-
нова и А.Ларченко. Но изложение информации
в этом, и ему подобных, изданиях несколько
суховато. А листинги подпрограмм ДОС'а или
не даются вообще или не комментируются.   
                                          
Короче, далее я попытаюсь наиболее доступ-
но и ясно рассказать о ВГ 93 и опираясь на
изложенную информацию рассказать о некото-
рых подпрограммах ДОС'а.                  
                                          
Здесь  и далее: ВГ93 - м-ма КР1818ВГ93;   
ОС - операционная система (Бейсик и т.п.);
ДОС - дисковая операционная система;      
                                          
                                          
Начнем  с  того, что ВГ-шка для вас (и для
процессора) - всего лишь несколько портов.
Послал  в  один  порт число, в другой порт
другое число, в третий порт послал код ко-
манды; глядишь - а на дисководе и лампочка
загорелась,  и  уже  диск крутится, а если
что  нибудь  из четвертого порта почитать,
то может даже что-нибудь да и прочитается.
                                          
                                          
Следует  отметить  несколько крайне важных
вещей:                                    
                                          
1.  ПЗУ  ДОС, а вместе с ним и регистры ВГ
(порты) включаются только тогда, когда вы-
полняется  какая-либо  команда  по  адресу
#3D00  -  #ЗDFF  (15616 - 15871). В ПЗУ ОС
там  находится знакогенератор и передавать
ему управление просто так еще никто (слава
Богу) не додумался. Отключается же ПЗУ ДОС
(а вместе с ним и порты ВГ9З) при выполне-
нии  любой команды по адресу, большему чем
#ЗFFF (16383), то есть в ОЗУ.             
                                          
2.  Из пункта 1. следует, что управлять ВГ
можно только подпрограммами ДОС'а, а чтобы
это сделать необходимо его хорошо изучить.
                                          
3.  Из  пунктов 1. и 2. следует, что обра-
щаться  к необходимым нам частям ДОС нужно
каким-то  особым,  извратным  способом. Об
этом мы поговорим несколько позже.        
                                          
А вот те самые регистры-порты ВГ93:       
                                          
╔═════════╦═══════════════════╦══════════╗
║ Адрес   ║ Название регистра ║  Доступ  ║
╠═════════╬═══════════════════╬══════════╣
║#1F (31) ║ Рег. команд       ║ Запись   ║
║#1F (31) ║ Рег. состояний    ║ Чтение   ║
║#3F (63) ║ Рег. дорожки      ║ Чт./зап. ║
║#5F (95) ║ Рег. сектора      ║ Чт./зап. ║
║#7F (127)║ Рег. данных       ║ Чт./зап. ║
╚═════════╩═══════════════════╩══════════╝
                                          
А это (^) не совсем регистр ВГ, но нам это
без разницы.                              
                                          
╔═════════╦═══════════════════╦══════════╗
║#FF (255)║ Системный регистр ║ Чт./зап. ║
╚═════════╩═══════════════════╩══════════╝
                                          
Адрес - номер порта.                      
                                          
Доступ  - это что с ним можно делать (чт./
зап. это чтение и запись соответственно). 
                                          
Напомню,  что  для  нас, в принципе, слова
"порт" и "регистр" являются синонимами.   
                                          
Регистр  команд  - в него записывается ко-
манда,  понятная  ВГ. Принятая команда не-
медленно выполняется. Можно только записы-
вать.                                     
                                          
Регистр состояний  -  отдельные биты этого
регистра  указывают на корректность приня-
той  команды и т.п. (что-то вроде регистра
F в Z-80). Только чтение.                 
                                          
Регистры  дорожки и сектора - указывают на
положение    головки  дисковода.  Являются
входными  параметрами для некоторых команд
ВГ.    Чтение   и  запись.  Для  тех,  кто
путается, напомню:                        
                                          
                                          
                                          
                                          
                                          
                                          
                                          
Регистр данных - через него передаются или
принимаются  записываемые  или считываемые
данные  (иногда - вспомогательные). Чтение
и запись.                                 
                                          
                                          
Системный  регистр  -  при  чтении из него
указывает  на готовность дисковода принять
или  выдать  очередной  байт,  а  также на
окончание операции. При записи - системную
информацию  (номер дисковода, метод записи
FM/MFM, сторона и т.п.). Подробнее:       
                                          
                                          
При чтении из порта #FF:                  
╔═════╦══════════════════════════════════╗
║ Бит ║            Назначение            ║
╠═════╬══════════════════════════════════╣
║ 0-5 ║     Не представляют интереса     ║
║  6  ║          Запрос данных           ║
║  7  ║          Конец операции          ║
╚═════╩══════════════════════════════════╝
                                          
При записи:                               
╔═════╦══════════════════════════════════╗
║ Бит ║            Назначение            ║
╠═════╬══════════════════════════════════╣
║ 0-1 ║  Выбор дисковода (00,01,10,11    ║
║     ║                    A, В, С, D)   ║
║  2  ║Сброс микроконтроллера (практичес-║
║     ║ки не требуется)                  ║
║  3  ║ Блокировка сигнала HLT ВГ. Для   ║
║     ║ нормальной работы должна быть 1. ║
║  4  ║ Выбор головки: 0 - 1-ая, нижняя; ║
║     ║                1 - 2-ая, верхняя.║
║  5  ║Метод записи:                     ║
║     ║0 - FM частотная модуляция        ║
║     ║1 - MFM модифицированная частотная║
║     ║модуляция. Обычно пользуются MFM. ║
║ 6-7 ║         Не используются          ║
╚═════╩══════════════════════════════════╝
------------------------------------------
Практический  интерес  для  нас  на данном
этапе  представляет  чтение  из системного
регистра (порта):                         
                                          
                                          
Запрос  данных  -  до тех пор, пока в этом
разряде  записан 0, дисковод не готов при-
нять  (выдать) очередной байт данных. Ведь
процессор  действует  намного быстрее, чем
ВГ93  и  оба  они  передают данные гораздо
быстрее,  чем  дисковод  (собачка-то бежит
быстрее человека! Ха-ха).                 
                                          
Конец  операции - ну, тут все понятно: 0 в
этом  разряде означает, что текущая опера-
ция  не завершена. Только следует отметить
один  очень  интересный момент: при чтении
сектора контроллер САМ определяет, сколько
байт  будет  считано (не зависимо от того,
хотите  вы  этого  или нет). То же самое и
при записи сектора(ов). Подумайте над этим
моментом, мы еще вернемся к нему.         
                                          
                                          
Поскольку  мы  с  Вами  говорим о чтении с
диска при помощи прямого управления ВГ, то
не имеет смысла (пока) рассказывать о всех
командах управления ВГ.                   
                                          
Рассмотрим самые необходимые:             
                                          
(здесь  следует сказать, что у команд ВГ93
нет  мнемоник,  как  у ассемблера, поэтому
просто  пишут название команды (группы ко-
манд) и битовую раскладку)                
                                          
                                          
Поиск - 0001hvxx. Эта команда устанавлива-
ет  магн.  головку на дорожку, номер кото-
рой задан в регистре ДАННЫХ. Предполагает-
ся, что в регистре ДОРОЖКИ находится номер
дорожки,  на  котором стоит головка. Жела-
тельно  (но  необязательно)  выполнять при
параметре v=1.                            
                                          
     h = 0 - во время выполнения команды  
     головка будет поднята над диском и не
     будет выдан сигнал на включение дви- 
     гателя дисковода;                    
     h = 1 - головка будет опущена в рабо-
     чее положение и сигнал на включение  
     будет выдан.                         
                                          
     v - имеет смысл, только при h=1. При 
     v = 1 значение регистра дорожки срав-
     нивается со значением, считанным с   
     диска.                               
                                          
     хх - скорость выполнения операции:   
     00 - максимальная, 01,10 - промежу-  
     точные, 11 - минимальная.            
                                          
Чтение  сектора(ов)  -  1OOmsecO. Название
говорит  само за себя. Номер сектора зада-
ется в регистре СЕКТОРА.                  
                                          
     m = 0 - прочитать только один сектор.
     m = 1 - все сектора до конца дорожки.
                                          
     s - сторона дискеты (0-ниж., 1-верх.)
     Практического значения не имеет, т.к.
     стороной диска занимается СИСТЕМНЫЙ  
     регистр, но может пригодиться (см.^).
                                          
     e - если этот бит установлен, то меж-
     ду выдачей сигнала на установку голо-
     вок в рабочее положение и началом    
     операции делается задержка в 15 мс.  
                                          
     c - проверять (1) или нет (0) сторо- 
     ну дискеты при операции (см. параметр
     s). Дело в том, что сторона дискеты  
     записываеся при форматировании, но об
     этом мы поговорим в следующий раз.   
                                          
Это  две  простейшие операции, опираясь на
которые мы с Вами рассмотрим чтение с дис-
ка.                                       
Вот  упрощенный драйвер дисковых операций,
приведенный  в ZX-РЕВЮ 4'95 (зачем изобре-
тать велосипед?):                         
                                          
       © ALANSOFT'95                      
     SMALL DISK-DRIVER                    
Слегка переделал Nicolas Viper.           
                                          
На входе должны быть заданы:              
   HL = адрес загрузки;                   
   DE = дорожка,сектор;                   
    В = число секторов.                   
                                          
       ORG   50000                        
DRIVER                                    
       DI                                 
       LD    IX,#2F65 ;(12133) Подпрогамма
       CALL  DOS      ;инициализации.     
L1     PUSH  DE       ;Сохраняем DE и ВС. 
       PUSH  ВС       ;                   
       OR    A        ;Переводим из логи- 
       LD    A,D      ;ческого номера до- 
       RRA            ;рожки в физический.
       LD    С,A      ;(обсудим позже)    
       LD    A,#3С    ;#3С=%00111100      
       JR    NC,L2    ;#2С=%00101100      
       LD    A,#2С    ;        ^сторона.  
                      ;                   
L2     LD    IX,#2FЧD ;Подпрограмма уста- 
       CALL  DOS      ;новки на дорожку.  
                      ;(12109)            
       POP   ВС       ;Восстанавливаем    
       POP   DE       ;  ВС и DE.         
М2     PUSH  HL       ;Сохраняем          
       PUSH  DE       ;    регистры.      
       PUSH  ВС       ;                   
       LD    IX,#2F1В ;{12059) Собственно 
       CALL  DOS      ;чтение.            
       POP   ВС       ;Восстанавливаем    
       POP   DE       ;    регистры.      
       POP   HL       ;                   
       INC   Н        ;Поскольку считаем, 
                      ;что длина сектора  
                      ;256 байт.          
       INC   E        ;Следующий сектор.  
       LD    A,15     ;15=%00001111       
       AND   E        ;Если E=16, то E=0, 
       LD    E,A      ;флаг Z=1 и переход 
       JR    Z,L5     ;на следующую дорож-
       DJNZ  М2       ;ку, иначе просто   
                      ;следующий сектор.  
       JR    EXIT     ;На выход.          
L5     INC   D        ;Следующая дорожка. 
       DJNZ  L1       ;                   
EXIT   EI             ;                   
       RET            ;Выход.             
                      ;                   
DOS                   ;На стеке - адрес   
                      ;возврата.          
       PUSH  IX       ;На стеке - адрес   
                      ;вызываемой процеду-
                      ;ры.                
       JP    #3D2F    ;(1566З) Подключает-
                      ;ся ПЗУ ДОС, а там  
находится:                                
                                          
#3D2F  NOP                                
#3D30  RET.    По RET управление передает-
               ся нужной  Вам подпрограмме
ПЗУ ДОС, а  она вернется  в  точку, откуда
вызывали процедуру "DOS".                 
                                          
Перед  тем, как разбирать вызываемые нашим
драйвером  процедуры  ДОС'а,  напомню, что
существует два способа нумерации дорожек и
секторов:                                 
                                          
1.  Логический. К нему мы с Вами привыкли.
Дорожки  нумеруются  от  нуля  и  до  159.
Сектора нумеруются: 0..15                 
                                          
2.  Физический. Дорожки нумеруются: 0..79,
но на каждой стороне. Нулевая логическая -
это нулевая верхняя физическая, первая ло-
гич. это нулевая  верхняя и т.д..  Сектора
нумеруются:  1..16.  Такой способ наиболее
понятен ВГ и Вашему флоппи-диск-кранчеру  
(шутка).                                  
                                          
                                          
А вот и процедурки ДОС'а:                 
                                          
#2F65  Сброс (восстановление) контроллера.
Обязательно  обращаться  в  начале работы!
Ничего  интересного.  Если  захотите, то я
расскажу о ней в следующих публикациях.   
                                          
                                          
#2FЧD Установка на дорожку:               
Входные параметры в регистрах :           
                                          
 A - Системная информация. Обычно #3С или 
#2С, что соответствует:                   
#3С - А,?,разрешен HLT,верхняя головка,MFM
#2С - то же, но с нижней головкой. Подроб-
нее смотрите в описании системного р-ра.  
 С - Физический номер дорожки.            
 В регистре дорожки - номер дорожки, на   
которой стоит головка.                    
#2FЧD  OUT   (#FF),A  ;установка системной
                      ;информации. Исполь-
                      ;зуется для установ-
                      ;ки стороны диска.  
       LD    A,С      ;В рег. данных номер
       OUT   (#7F),A  ;нужной дорожки.    
       CALL  #ЗDFD    ;Задержка           
       LD    A,#18    ;#18=%00011000 Ко-  
       OUT   (#1F),A  ;манда "Поиск".     
М1     IN    A,(#FF)  ;Ждем, пока команда 
       AND   #80      ;исполняется.       
       JR    Z,М1     ;#80=%10000000      
       PUSH  ВС       ;                   
       CALL  #ЗDFD    ;Еще одна задержка. 
       POP   ВС       ;                   
       RET            ;Возврат            
------------------------------------------
#ЗDFD  LD    A,#50    ;Подпрограмма       
W1     LD    С,#FF    ;задержки.          
W2     DEC   С        ;                   
       JR    NZ,W2    ;                   
       DEC   A        ;                   
       JR    NZ,W1    ;                   
       RET            ;Возврат            
#2F1В Чтение дорожки.                     
                                          
Входные параметры:                        
                                          
 E - логический номер сектора.            
 HL - адрес загрузки.                     
Предполагается, что головка установлена на
ту дорожку, с которой необходимо читать.  
                                          
#2F1В  LD    A,E      ;Был логический -   
       INC   A        ;стал физический.   
       OUT   (#5F),A  ;Посылаем в регистр 
                      ;сектора            
       PUSH  HL       ;                   
       LD    D,#14    ;#14=20 Сколько раз 
                      ;повторять, в случае
       PUSH  DE       ;ошибки.Сохраняем.  
L1     DI             ;Запрет прерываний! 
       LD    С,#7F    ;Адрес р-ра данных. 
       LD    A,#80    ;#80=%10000000 Ко-  
       OUT   (#1F),A  ;манда "чтение".    
       CALL  #ЗFE5    ;Собственно чтение. 
       POP   DE       ;Восстанавливаем ре-
       POP   HL       ;гистры.            
       IN    A,(#1F)  ;Проверка на ошибку.
       AND   #7F      ;#7F=%01111111      
       RET   Z        ;Возврат, если окей.
       DEC   D        ;Уменьшаем счетчик. 
       PUSH  HL       ;                   
       PUSH  DE       ;                   
       JR    NZ,L1    ;Повтор, если D<>0. 
#2F39  HALT           ;Повись!            
#2FЗA  ...            ;                   
                      ;                   
       ...            ;                   
                      ;                   
#ЗFE5  IN    A,(#FF)  ;Ожидаем разрешения.
       AND   #С0      ;#С0=%11000000      
       JR    Z,#ЗFE5  ;                   
       RET   М        ;Возврат, если конец
                      ;См. таблицу по Сис-
                      ;темному р-ру. Флаг 
                      ;S дублирует старший
                      ;разряд р-ра.       
       INI            ;Читаем.            
                      ;INI=IN  (HL),(С)   
                      ;    INC HL         
       JR    #ЗFE5    ;Зацикливание.      
Вот и все. Надеюсь вы поняли большую часть
изложенного материала. Если хотите продол-
жения, то сообщите об этом в редакцию "El-
dorado"  или  Condor soft'у лично.  А я бы
вам рассказал о записи (без исп. сист. пе-
ременных ДОС'а), о том, как сделать музыку
во  время  загрузки  (см. "BATLE СOMMAND",
"BLINKY'S", "INSULT") и еще о чем-нибудь. 
                                          
В статье использовался материал книги     
А.Ларченко и Н.Родионова                  
"ZX  Specrtum & TR DOS для пользователей и
программистов" издательства "ПИТЕР" 1994г.
Это  издание - лучшая настольная книга для
программиста и пользователя.              
                                          
И на последок: большое человеческое спаси-
бо сэру Клайву Синклеру за машину, которая
научила нас радости программирования.     
                                          
                                          
                                          
                                          
                      © 1995 Nicolas Viper



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

Вступление - Возможно скоро в продаже появится мышь для Спектрума. Мы с Никодимом над этим проектом ведем работу.

Экспертиза - прохождение игры Mercenary.

Дебют - игра Deep Strike.

Классика - поговорим о тетрисе.

Система - обращении непосредственно к ПЗУ DOS и о прямом программировании ВГ 93.

Кроссворд - ответы на головоломку.

Реклама - Самый широкий выбор программного обеспечения для "ZХ-Sрectrum"!

Письма - "Привет! Я - Дмитриев Иван, мне 1З лет и я большой поклонник компьютера "Спектрум - 128"!


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

Похожие статьи:
Обзор системок - Обзор системных программ : ZX-Turbo Assembler v3.10, Srite Maker, Storm v1.1, Burst Eyes v1.1, STS v6.2, Direct Commander v3.04, Turbo Disk Utility v1.0.
От авторов - BODY снова в сети минской ZX-NET.
Our News - ZX-будни города Перми.
Там... - Обратный билет, Мусорщик, Князь Тьмы, Лабаканах.
Что нового - О новинках в Минске. Пароли к игре The Last Courier.

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