Приветствую Вас, дорогие читатели и редак- торы журнала "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