╔══════════════════════════════════════╗ ║Раздел: CPU для Вас; ║ ║Статья: Работаем с TR-DOS; ║ ║Музыка: Dreamer; ║ ║Текст : Ворожкин Александр. ║ ╚══════════════════════════════════════╝ Работа с TR-DOS на уровне машинных ко- дов.Вход в TR-DOS обеспечивается при чтении компьютером команды по адресам #3D00-#3DFF.При этом основное ПЗУ компь- ютера отключается, а на его место "подс- тавляется" ПЗУ TR-DOS. В нем по адресам #3D00-#3D2E (15610-15663) размещены точ- ки входа в подпрограммы TR-DOS. Наиболее важные из них приведены ниже. HEX DEC Выполняемое действие #3D00 15616 Выход в TR-DOS #3D03 15619 Выход в TR-DOS,выполне- ние команды TR-DOS и возврат в SOS #3D13 15635 Выполнение внутренних команд TR-DOS,в зависи- мости от содержимого регистра C микропроцес- сора #3D2F 15664 Выполнение подпрограмм TR-DOS,адресуемых через стек. Первые две точки входа общеизвестны и их использование не вызывает особых зат- руднений , две последние заслуживают от- дельного рассмотрения.После обращения по адресу #3D13 выполняется переход к под- программе #283C (10300), которая в зави- симости от кода, содержащегося в регист- ре C, выполняет переход на необходимую подпрограмму TR-DOS. 1.C = #01.Выбор дисковода.Его номер указывается в регистре A.При первом обращение к данному дисководу проис- ходит его инициализация (определяется количество дорожек, константа позици- рования) и изменяются соответствующие системные переменные. 2.C = #02.Головка устанавливается на трек,указанный регистром A.В случае двустороннего дисковода трекам 0 (нижний) и 1 (верхний) соответствует первый физический трек,трекам 2 и 3 - второй и т.д. Следует отметить,что на диске может быть не 80 физических треков (от 0 до 79),а 82 - 85 в зави- симости от конкретного дисковода, что используется некоторыми программами. Пример использования этой команды бу- дет дан ниже (пример.16). 3.C = #05.Чтение группы секторов. В ре- гистре B-количество считываемых сек- торов,D-номер начального трека, E-на- чального сектора , HL-адрес буфера, в который производится чтение. пример 6. LD C,#05 ;код команды LD B,#10 ;16 секторов LD D,#00 ;трек LD E,#00 ;сектор LD HL,#8000 ;адрес буфера CALL #3D13 RET Эта программа прочитает содержимое ну- левого трека в буфер по адресу 32678.На первый взгляд,две последние строчки про- граммы можно заменить одной командой JP #3D13 - ведь вызываемая подпрограмма заканчивается RET.Однако такая замена не всегда возможна из-за особенностей возв- рата после выполнения подпрограмм TR-DOS Отключение ПЗУ TR-DOS происходит при чтении процессором кода команды по адре- су, большему #3FFF.Если вы будете запус- кать предлагаемые примеры из BASIC'а ко- мандой RANDOMIZE USR adr , то возврат происходит через точку #2D2B(STACK-BC) в основном ПЗУ.Если вы сделаете предлагае- мую замену, то программа будет нормаль- но работать при вызове ее из другой про- граммы,находящейся в ОЗУ.Если вы вызове- те эту программу с помощью USR из BASIC, то при возврате не произойдет переключе- ние ПЗУ и результат будет таким, как не хотелось бы. 4.C = #06.Запись группы секторов.Пара- метры аналогичны операции чтения группы секторов. Пример 7. LD C,#06 ;код команды LD B,#10 ;16 секторов LD D,#9F ;трек LD E,#00 ;сектор LD HL,#8000 ;адрес буфера CALL #3D13 RET Эта программа ззпишет содержимое буфера по адресу 32768 на последний,159-й трек. Так можно, например,сохранить ранее счи- танный каталог на случай его порчи. Про- читав его затем из 159-го трека и запи- сав на 0-й,можно спасти ценные программы Следует заметить еще одну особенность команд #05 и #06 - они могут работать не только с секторами длиной 256 байт, но и с секторами другой длины (128,512,1024 байт).Используя особенность,несложно ор- ганизовать обмен информацией между ZX- SPECTRUM и другими компьтерами. так мож- но читать и писать на диски,используемые в компьютерах "СПЕЦИАЛИСТ" ,"ОРИОН-128", ДВК (с контроллером MY), а также IBM.од- хако в этих случаях нельзя сразу прочи- тать или записать группу секторов , так как секторы длиннее 256 байт будут нак- ладываться в памяти компьютера один на другой , неудача также постигнет вас при попытке считать с диска IBM сектор с но- нером 9 - таких там нет (при стандартном формате). Выход из этой ситуации прост - необходимо изучить структуру "чужого" диска и читать (или писать) информацию по одному сектору , каждый раз вычисляя номер следующего трека и сектора,а также адрес буфера. 5.C = #07. Вывод каталога диска.В реги- стре A - номер канала для вывода ката- лога. Предварительно должна быть выпол- нена команда #18. пример 8. LD C,#18 ;код команды CALL #3D13 ; LD A,#02 ;номер канала LD C,#07 ;код команды CALL #3D13 RET Эта программа равносильна директиве CAT TR-DOS.Если в регистр A перед вызовом команды занести #03 , то каталог будет выведен на принтер. 6.C = #08.Чтение информации о файле.В регистре A предварительно помещается по- рядковый номер файла (0-127).Из каталога диска 16 байт переносятся в область сис- темных переменных TR-DOS.Не имеет значе- ния,стерт ли этот файл или нет и сущест- вует ли он вообще.Адреса соответствующих системных переменных приведены ниже. HEX DEC Длина, назначение байт #5CDD 23733 8 Имя файла в ASCII ... ... #5CE4 23780 #5CE5 23781 1 Тип файла (A,B,C, D или #) , но , в принципе , может быть любой сим- вол,что открывает дополнительные возможности #5CE6 23782 2 Стартовый адрес кодового файла или длина BASIC программы #5CE8 23784 2 Длина файла #5CEA 23786 1 Объем файла в секторах #5CEB 23787 1 Номер первого сектора файла #5CEC 23788 1 Номер первого трека файла. 7.C = #09.Запись информации о файле в каталог.Из области системных переменных 16 байт переписываются в каталог на мес- то информации о файле,номер которого за- дан в A. Пример 9. LD A,#20 LD C,#80 CALL #3D13 LD HL,#5CDD LD (HL),#41 LD C,#09 CALL #3D13 RET Эта программа изменит первый символ в имени 32-го файла "A".Если этот файл был стертым, то он "восстановится" , но для этого необходимо дополнительно внести изменения также в 8-й сектор нулевого трека.Как это сделать , будет рассказано ниже. 8.C = #0A.Поиск файла по имени ,задан- ному в области системных переменных. Номер найденного файла возвращается в регистр C.Можно искать файлы по имени и типу (9 байт) или по любому количест- ву первых байтов имени (от 1 до 16),сле- дует лишь указать количество символов в системной переменной по адресу #5D06 (23814). 9.C = #0B.Запись на диск файла.Имя и тип файла - в области системных перемен- ных,длина - в DE,начальный адрес - в HL. Пример 10. LD HL,NAME ;адрес имени файла LD C,#13 ;код команды CALL #3D13 LD DE,#1B00 LD HL,#4000 LD C,#0B ;код команды CALL #3D13 RET NAME DEFM "SCR C" ;имя и тип фай- ла - 9 байт. Эта программа перенесет имя и тип файла "SCR" CODE (вообще-то переносится 16 , а не 9 байт , но последние 7 байт в данном случае не имеют значения) в области сис- темных переменных (адреса 23773-23781), затем запишет файл на диск. 10.C = #0C.Запись BASIC программы.Имя и тип файла (при типе,отличном от "B",файл записывается под именем "boot") - в об- ласти системных переменных. 11.C = #0E.Чтение / проверка файла.Имя и тип файла - в области системных пере- менных.Адрес загрузки файла берется с директории при A = #00 или из регистро- вой пары DE при A = #03. При A = #FF ко- ды загружаются с адреса HL, причем длина загружаемого файла берется из DE.Байт по адресу 23801 определяет тип операции: #00 - LOAD,#FF - VERIFY. Пример 11. Предположим,что на диске есть экранный файл с начальным адресом 16384 и длиной 6912 байт. LD HL,M1 LD C,#13 CALL #3D13 LD C,#0A CALL #3D13 LD A,C LD C,#08 CALL #3D13 LD A,#00 LD (#5CF9),A LD C,#0E CALL #3D13 RET M1 DEFM "SCR C" Эта программа перенесет имя и тип фай- ла "SCR" CODE (9 символов) в облать сис- темных переменных (адреса 23773-23781), затем отыщет этот файл в каталоге , про- читает информацию о нем из каталога дис- ка,а затем прочитает сам файл по данным, взятым из каталога. Пример 12. Добавьте к программе из примера 11 сле- дующие строки: LD A,#03 LD HL,#4800 LD DE,#0800 Эти строки следует вставлять между LD (#5CF9),A и LD C,#0E. Запустив теперь программу, вы увидите в центре экрана то,что раньше было в верх- ней его части. Пример 13. Если мофифицировать пример 11 следующим образом: LD A,#FF LD HL,#8000 То программа загрузит весь файл "SCR" CODE по адресу 32768. Примечание: пример 13 следует вставлять в пример 11 между строками: LD (#5CF9),A и LD C,#0E. 12. C = #12.Удаление файлов. Имя и тип файла - в области системных переменных. удаляются все файлы с такими данными. Пример 14. LD HL,M1 LD C,#12 CALL #3D13 LD C,#0A CALL #3D13 LD A,C LD C,#18 CALL #3D13 RET M1 DEFM "SCR C" Эта программа найдет на диске файл "SCR" CODE и сотрет его. 13. C = #13.По адресу 23773 переписыва- ются 16 байт информации из памяти,адресуемой регистро- вой парой HL. 14. C = #14.Переписываются 16 байт ин- формации из области систем- ных переменных по адресу 23773 в память по адресу, указанному в регистровой паре HL. 15. C = #15.Проверка дорожки. Регистр D должен содержать номер про- веряемого физического трека 16. C = #16.Загрузка системного регис- тра.Код - в регистре A.Пре- дварительно к нему прибав- ляется #3C. 17. C = #17.Выбрать нижнюю сторону. 18. C = #18.Настройка на диск. Проверя- ется тип диска (8-й сектор директории). Точка #3D2E открывает доступ к любой подпрограмме TR-DOS,однако ее использо- вание немного сложнее, чем #3D13.Для на- чала вспомним, как микропоцессор Z80 вы- полняет команды CALL_adr и RET. При вы- полнении команды CALL_adr в стек записы- ваются два байта - адрес команды,следую- щей за CALL_adr, затем выполняется пере- ход по адресу adr,При выполнении команды RET из стека считываются два байта - ад- рес, по которому происходит возврат из подпрограммы.Причем совсем не обязатель- но,чтобы эти два байта были записаны в стек при выполнении команды CALL_adr-они могут быть помещены туда, например, при выполнении команды PUSH_dd, где dd - лю- бая пара регистров микропроцессора.При обращении по адресу,соответствующему точке входа в DOS ( в данном случае #3D2E), как уже упоминалось,происходит подмена основного ПЗУ на ПЗУ TR-DOS.В последнем случае по адресу #3D2E записан код команды RET (#C9).Если предваритель- но поместить в стек адрес какой-либо подпрограммы TR-DOS, то будет выполнен переход на нее. В стек также необходимо перед этим поместить адрес возврата из подпрограммы. Пример 15. LD HL,RET1 ;адрес возврата PUSH HL ;помещаем в стек LD HL,ADRESS ;адрес подпрограм- мы TR-DOS PUSH HL ;помещаем в стек JP #3D2E ;переход RET1 RET ;точка для возврата Для использования точки входа #3D2E не- обходимо знать адреса подпрограмм TR-DOS К сожалению, TR-DOS написана очень запу- танно и дизассемблировать ее довольно сложно.Три приведенных ниже отрывка мож- но использовать при разработке приклад- ных программ,работающих с диском.Они со- ответствуют версии 5.03, в других верси- ях они тоже есть, но могут иметь другие адреса. #2A53 (10835): OUT (C),A RET #3FCA (16330): M1 IN A,(#FF) ;читаем системный регистр AND #C0 ;проверяем готов- ность данных JR Z,M1 ;еще раз,если не готово RET M ;возврат,если все записано OUTI ;вывести следующий байт в регистр JR M1 ;данных #3FE5 (16357): M2 IN A,(#FF) AND #C0 JR Z,M2 RET M ;возврат,если все прочитано INI ;прочитать следую- щий байт из ре- JR M2 ;гистра данных Первая из приведенных подпрограмм поз- воляет выводить необходимые данные в лю- бой из портов контроллера TR-DOS (это можно сделать только через обращение к ПЗУ TR-DOS).Таких портов пять.Первые че- тыре из них принадлежат микросхеме КР1818ВГ93 (табл.1). Таблица 1. Адрес Назначение #1F Регистр команд/состояния #3F Регистр дорожки #5F регистр сектора #7F регистр данных Назначение регистров и структура команд КР1818ВГ93 рассмотрены в работе [4]. Есть еще один порт, который имеет адрес #FF и обычно реализуется на К555ТМ9.Это системный регистр TR-DOS. При необходи- мости узнать содержимое этого регистра можно,воспользовавшись ячейкой 23830,ко- торая хранит копию этого регистра. Назначение разрядов управляющего слова следующее: D0 и D1 - номер НГМД (0-A,1-B,2-C,3-D); D2 - команда сброса контроллера; D3 - готовность головки (1 - готово); D4 - сторона диска (0 - низ,1 - верх); D6 - плотность записи (0 - двойная,1 - одинарная); При чтении из порта #FF считываются си- гналы DRQ (готовность данных для переда- чи, 38 вывод ВГ93, 6-й разряд порта) и INTRQ (выполнение команды,38 вывод ВГ93, 7-й разряд порта). Две последние подпрограммы предназна- чены для чтения массива данных в регистр данных.Их можно использовать так: Пример 16. LD A,#10 ;номер трека LD C,#02 ;код команды CALL #3D13 ;установить головку LD A,#50 ;данные для систем- ного регистра LD C,#FF ;адрес порта LD HL,RET0 ;адрес возврата PUSH HL ;в стек LD HL,#2A53 ;адрес подпрограммы PUSH HL ;в стек JP #3D2E RET0 LD C,#1F ;адрес порта регис- тра команд LD A,#E4 ;код команды чтения трека LD HL,RET1 ;адрес возврата PUSH HL ;в стек LD HL,#2A53 ;адрес подпрограммы PUSH HL ;в стек JP #3D2E RET1 LD C,#7F ;адрес порта регис- тра данных LD HL,RET2 ;адрес возврата PUSH HL ;в стек LD HL,#3FE5 ;адрес подпрограммы PUSH HL ;в стек LD HL,#A000 ;адрес буфера JP #3D2E RET2 RET Эта программа прочитает содержимое вер- хнего трека 16-го цилиндра диска со все- ми метками в буфер по адресу #A000. Если изменить две строки LD A,#F4 ;код команды записи трека LD HL,#3FCA ;адрес подпрограммы ( Эту программу необходимо поместить за место строк LD A,#E4 и LD HL,#3FE5 ), то получим программу записи трека со всеми метками (форматирование трека).Предвари- тельно в буфере необходимо подготовить массив для записи. Причем можно записы- вать треки с секторами любой длины (128,256,512,1024 байт) и с произвольной нумерацией - необходимо лишь правильно подготовить данные [4]. Можно предложить еще одно применение этой точки входа.В ПЗУ TR-DOS довольно много свободного места (около 4Кбайт). Туда можно помес- тить свои программы и запустить их, как предложено в примере 15. Таким образом, можно значительно расширить возможности TR-DOS, причем такое изменение не отра- зится на совместимости. Например, можно добавить программу "восстановления" или проверки диска,небольшую "boot"-програм- му или даже драйвер принтера,хотя в пос- леднем случае потребуются небольшие (не более 20 байт) изменения в основном ПЗУ. Конечно,неплохо было бы внести изменения в некоторые подпрограммы ПЗУ TR-DOS,хотя бы с целью исправления имеющихся ошибок, но это не всегда приемлемо.Любое измене- ние может привести к тому, что какая-ни- будь программа перестанет работать на таком компьютере. Особенно это касается основного ПЗУ компьютера. Там даже не- большое изменение (в том числе и запол- нение свободного пространства, изменение шрифта или даже надписи,которая выводит- ся при включении компьютера) может ухуд- шить совместимость с его "фирменным бра- том".Так что,решайте, какой компьютер вы хотите иметь: Sinclair - совместимый или Sinclair - подобный.