TR-DOS для тех кто о нем ничего не знает. .BIG BRAIN WARL0CK 15.02.97 Я ни разу не писал статей в HACKER и, чтобы исправить сие недоразумение я решил написать серию статей о TR-DOSe. Начну я с самых азов, т.е. с того как его вызвать из BASIC и из машинных кодов и др. ---------------------------------------------------------------- КОДЫ ОШИБОК ПРИ ВЫЗОВЕ ИЗ BASICa. Коды ошибок можно получить из переменной TR-DOS (23823) или через переменную BASICa следующим образом: LET err=USR 15б19:REM:команда DOS или RAND0MIZE USR 15б19:REM:команда DOS LET err=РЕЕК 23823 а теперь значения кодов ошибок: 0 - нет ошибок 1 - нет файла 3 - файл с таким именем на диске уже есть 4 - каталог переполнен (кол-во файлов больше 128) 5 - переполнение номера записи б - нет диска 7 - ошибка на диске 8 - ошибка синтаксиса 9 - я не нашел нигде данных на эту ошибку 10 - канал уже открыт 11 - диск не форматирован 12 - канал не открыт ---------------------------------------------------------------- СТРУКТУРА ЗАГОЛОВКА ФАЙЛА 0...7 8 9 В D E F ХХХХХ Х ХХ ХХ Х Х Х │ │ │ │ │ │ └ 1 байт -номер начальной дорожки │ │ │ │ │ └── 1 байт -номер начального сектора │ │ │ │ └──── 1 байт -длина файла в секторах │ │ │ └──────── 2 байта-длина файла для C0DE и програм- │ │ │ ной части для BASICa,в байтах │ │ └──────────── 2 байта-начальный адрес для C0DE или │ │ полная длина файла для BASICa │ └────────────── 1 байт -тип файла └──────────────────── 8 байт -имя файла ---------------------------------------------------------------- СТРУКТУРА СИСТЕМНОГО CEKT0PA ╔══════════╤════════════════════════════════════════════╗ ║СМЕЩЕНИЕ │ НАЗНАЧЕНИЕ ║█ ╠══════════╪════════════════════════════════════════════╣█ ║ 225 │ Байт. Номер следующего свободного сектора. ║█ ║ │ После форматирования равен нулю. ║█ ║──────────┼────────────────────────────────────────────╢█ ║ 22б │ Байт. Номер следующей свободной дорожки. ║█ ║ │ После форматирования равен единице. ║█ ║──────────┼────────────────────────────────────────────╢█ ║ 227 │ Байт. Тип дискеты: ║█ ║ │ 22 - 80 дорожек,2 стороны ║█ ║ │ 23 - 40 дорожек,2 стороны ║█ ║ │ 24 - 80 дорожек,1 сторона ║█ ║ │ 25 - 40 дорожек,1 сторона ║█ ║──────────┼────────────────────────────────────────────╢█ ║ 228 │ Байт. Кол-во файлов на диске, в том числе ║█ ║ │ и удаленные.После форматирования равен 0. ║█ ║──────────┼────────────────────────────────────────────╢█ ║ 229,230 │ Слово. Кол-во свободных секторов. ║█ ║ │ После форматирования: ║█ ║ │ ║█ ║ │ 2544 - для 80 дорожечного двухстороннего ║█ ║ │ 12б4 - для 80 дорожечного одностороннего ║█ ║ │ и 40 дорожечхого двухстороннего ║█ ║ │ б24 - для 40 дорожечного одностороннего ║█ ║──────────┼────────────────────────────────────────────╢█ ║ 231 │ Байт. Кол-во секторов на дорожке. ║█ ║ │ Если не равен 1б то выдается сообщение: ║█ ║ │ Disk еггог и 23823=11 ║█ ║──────────┼────────────────────────────────────────────╢█ ║ 232,233 │ Два байта нулей. Только вот зачем, я не ║█ ║ │ знаю. ║█ ║──────────┼────────────────────────────────────────────╢█ ║ 234...242│ Девять байт пробелов (код 32). ║█ ║──────────┼────────────────────────────────────────────╢█ ║ 243 │ Один байт равный нулю. ║█ ║──────────┼────────────────────────────────────────────╢█ ║ 244 │ Байт. Кол-во удаленных файлов. После фор- ║█ ║ │ матирования равен нулю. ║█ ║──────────┼────────────────────────────────────────────╢█ ║ 245...252│ 8 байт. Имя диска ║█ ║──────────┼────────────────────────────────────────────╢█ ║ 253...255│ 3 байта нулей. ║█ ╚══════════╧════════════════════════════════════════════╝█ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ---------------------------------------------------------------- ВХОДНЫЕ ТОЧКИ TR-DOS 0 входных точках TR-DOS написано не мало но я решусь повториться, т.к. возможно у кого-то этой информации нет. #3D00 - вход в DOS из BASICa. #3D03 - вызов команды TD-DOS из BASICa. #ЗDOб - канал связи с дисковым файлом-программа ввода. #ЗDOE - канал связи с дисковым файлом-программа вывода. #3D13 - выполнение команды заданноы в регистре С процессора. #3D2F - переход на любой адрес DOS. По адресу #3D2F стоят две комманды :NOP и RET.С помощью этой точки входа можно попасть по любому адресу ПЗУ TR-DOS. LD HL,LAB ; адрес возврата PUSH HL ; заносим его на стек LD HL,адрес ; адрес в ПЗУ TR-DOS PUSH HL ; заносим его на стек JP #3D2F ; переход на точку входа LAB ..... ; продолжение программы или LD HL,адрес ; адрес ПЗУ TR-DOS CALL DOS ; заносим на стек адрес возврата ..... ; продолжение программы DOS PUSH HL ; заносим на стек адрес в ПЗУ TR-DOS JP #3D2F ; переход на точку входа Наиболее важной точкой входа является #3D13.Теперь разберем команды, которые можно использовать через эту точку входа. Чтобы вызвать команду нужно задать необходимые данные в регистрах и воспользоваться данной конструкцией: LD С,номер ;номер команды CALL #3D13 ;переход на точку входа ..... ;продолжение программы ══════════╤═════════════════════════════════════════════════════ Значение │Краткое описание команды регистра С│ ══════════╪═════════════════════════════════════════════════════ #00 │ Восстановление ВГ-93: головка отводится на нулевую │ дорожку и ожидает сигнала INTRQ. Ожидание можно │ прервать нажав BREAK. ──────────┼───────────────────────────────────────────────────── #01 │ Инициализация дисковода, заданного в регистре А: │ 00-А │ 01-В │ 02-С │ 03-D ──────────┼───────────────────────────────────────────────────── #02 │ Установка головки на дорожку номер, которой задан в │ регистре А (0...179). ──────────┼───────────────────────────────────────────────────── #03 │ Установка номера сектора, номер которого задан в │ регистре А (1..1б). ──────────┼───────────────────────────────────────────────────── #04 │ Установка адреса буффера, заданного в регистровой │ паре HL. Помещается в системную переменную #5D00. ──────────┼───────────────────────────────────────────────────── #05 │ Чтение блока секторов. По адресу HL считывается В │ секторов с доржки D,первый из которых имеет номер E. ──────────┼───────────────────────────────────────────────────── #0б │ Запись блока секторов. Параметры те же, что и в ко- │ манде #05. ──────────┼───────────────────────────────────────────────────── #07 │ Вывод каталога диска в канал с номером А. ──────────┼───────────────────────────────────────────────────── #08 │ Чтение заголовка (дискриптора) файла в область сис- │ темных переменных. Номер файла в регистре А (0..127 │ в том числе и удаленные). ──────────┼───────────────────────────────────────────────────── #09 │ Запись заголовка файла на диск. Номер файла в А. ──────────┼───────────────────────────────────────────────────── #0А │ Поиск файла в каталоге по имени и типу, которые за- │ даны в системных переменных #5CDD...#5CE5; кол-во │ проверяемых байтов заносится в переменную 23814, │ обычно 9. Если файл был найден, то его номер в ре- │ гистре С и ячеыках 23838, 23823; если не найден то │ регистр С=255, 23823=255, 23838 не изменяется. ──────────┼───────────────────────────────────────────────────── #0В │ Запись на диск файла типа C0DE с адреса HL и длиной │ DE; имя и тип файла должны находиться в системных │ переменны. Проверка на наличие одноименного файла не │ проводитяся, так что можно создать несколько файлов │ с одинаковым именем и типом. ──────────┼───────────────────────────────────────────────────── #0С │ Запись BASIC программы. Имя задается в системных пе- │ ременных. Проверка на наличие одноименного файла не │ производится. В переменной #5CD1 задается номер │ строки автостарта. Если тип не В, то файл запишеться │ под именем "boot". ──────────┼───────────────────────────────────────────────────── #0E │ Загрузка или VERIFY файлов; тип и заголовок в сис- │ темных переменных.При 23801=0 производится загрузка, │ а при 255 проверка. Для загрузки BASIC программы │ 23824 должна быть равна 0, если 255 то старая прог- │ памма стирается, а новая не загружается. Данные, в │ зависимости от содержимого А, задаются по разному: │ │ А=0 ;адрес и длина берутся из каталога │ А=3 ;адрес в HL, длина DE │ А=255 ;адрес в HL, длина из каталога ──────────┼───────────────────────────────────────────────────── #12 │ Стирается файл, имя и тип которого заданны в сис- │ темных переменных, стерты будут все файлы с такими │ именем и типом, их кол-во в переменной 23815. ──────────┼───────────────────────────────────────────────────── #13 │ Перенос информации о файле (дискриптора,1б байт) с │ адреса HL в системные переменные #5CDD...#5CE5. ──────────┼───────────────────────────────────────────────────── #14 │ Перенос дискриптора файла из системных переменных │ в адрес HL. ──────────┼───────────────────────────────────────────────────── #15 │ Проверка дорожки, номер которой задан в регистре D. │ Если на дорожке будут найдены битые сектора, то в │ системных переменных будут данные: │ #5DOF код ошибки 7 │ #SСDб кол-во битых секторов ──────────┼───────────────────────────────────────────────────── #1б │ Устанавливает текущую сторону диска 0. ──────────┼───────────────────────────────────────────────────── #17 │ Устанавливает текущую сторону диска 1. ──────────┼───────────────────────────────────────────────────── #18 │ Производит настройку переменных на тип дискеты. ══════════╧═════════════════════════════════════════════════════ Приведу несколько примеров использования точки входа #3D13: Загрузчик моноблок : ; в BASIC строке за REM расположена примерно такая процедура: LD HL,#9С40 ;адрес загрузки картинки LD ВС,#1В05 ;кол-во секторов и код команды 5 LD DE,(#5CF4) ;номер следующих дорожки и сектора CALL 15б35 ;вызов процедуры загрузки LD DE,#4000 ;адрес экранной области LD HL,#9С40 ;адрес куда загрузили картинку LD ВС,#1В00 ;длина картинки LDIR ;переброска картинки в экран LD HL,#7530 ;адрес загрузки основного блока LD ВС,#б205 ;кол-во секторов и код команды 5 LD DE,(#5CF4) ;номер следующих дорожки и сектора CALL 15б35 ;вызов процедуры загрузки JP #7530 ;запуск загруженной программы Пофайловый загрузчик: ; так же в строке после REM небольшая процедура: LD HL,BL0CK1 ;адрес имени и типа первого блока LD С,#13 ;перенос дискриптора CALL 15б35 ;вызов процедуры переноса дискриптора LD С,#0А ;поиск фаила на диске CALL 15б35 ;вызов процедуры поиска LD А,С ;сохраняем номер файла в аккумуляторе INC С ;если файла нет, JP Z,LABEL ; то переход на вывод сообщения LD С,8 ;чтение дискриптора файла CALL 15б35 ;переход на точку входа X0R А ;загрузка LD (23801),А ; файла LD А,255 ;длина из каталога адрес из HL LD HL,#9С40 ;адрес загрузки PUSH HL ;запоминаем его LD С,#0E ;загружаем первый блок CALL 15б35 ;вызов процедуры загрузки POP HL ;восстанавливаем адрес LD DE,#4000 ;переброска LD ВС,#1В00 ; картинки LDIR ; в экран LD HL,BL0CK2 ;адрес имени второго блока LD С,#13 ;перенос дискриптора файла CALL 15б35 ;вызов процедуры переноса LD С,#0А ;поиск файла на диске CALL 15б35 ;вызов процедуры поиска LD А,С ;сохраняем номер фаила в аккумуляторе INC С ;если файл не найден JP Z,LABEL ; то переход на печать сообщения LD С,#08 ;загрузка дискриптора файла CALL 15б35 ;переход в TR-DOS X0R А ;загрузка LD (23801),А ; блока LD А,255 ;адрес в HL, длина из каталога LD HL,#7530 ;адрес загрузки LD С,#0E ;загрузка файла CALL 15б35 ;вызов процедуры загрузки JP #7530 ;запуск основного блока LABEL CALL 3435 ;очистка экрана LD А,2 ;номер канала вывода CALL #1б01 ;вызов процедуры открытия канала LD DE,ТЕХТ ;DE начало сообщения LD ВС,BL0CK1-ТЕХТ ;ВС длина сообщения CALL 8252 ;печать сообщения LD А,2 ;красный цвет 0UT (254),А ; бордюра DI ;запрещаем прерывания HALT ;вешаем комп ТЕХТ DEFB 22,0,0 ;координаты печати DEFM "FILE N0T FOUND!" BL0CK1 DEFM "FILE1 С" BL0CK1 DEFM "FILE2 С" Раз уж разговор зашел о точках входа то я дам несколько адресов процедур TR-DOS с адресами для версии ПЗУ 5.04Т. ══════════════╦═════════════════════════════════════════════════ адрес (НЕХ) ║ назначение ══════════════╬═════════════════════════════════════════════════ 0000 ║ Полный рестарт системы ──────────────╫───────────────────────────────────────────────── 0008 ║ RST #08, инициализация, в DE вершина памяти. ──────────────╫───────────────────────────────────────────────── 0010 ║ RST #10,вывод символа из аккумулятора. ──────────────╫───────────────────────────────────────────────── 0018 ║ RST #18, строки символов начиная с (HL), кончая ║ нулем или символом больше 127. ──────────────╫───────────────────────────────────────────────── 0020 ║ RST #20, вызов процедуры из ПЗУ, адрес сразу за ║ RST #20, например: ║ ║ RST #20 ║ DEFW #ODбВ ──────────────╫───────────────────────────────────────────────── 0028 ║ RST #28, возвращает в HL адрес текущего канала ║ с учетом сдвига в С. ──────────────╫───────────────────────────────────────────────── OOбб ║ Обработчик MAGIC кнопки. ──────────────╫───────────────────────────────────────────────── 01D3 ║ Выход из DOS после выполнения команд #0D-#11 ║ точки входа 15б35. Это команды для дальнейшего ║ расширения TR-DOS. ──────────────╫───────────────────────────────────────────────── 03б0 ║ Название версии TR-DOS. ──────────────╫───────────────────────────────────────────────── 0405 ║ Процедура выполнения команды #18. ──────────────╫───────────────────────────────────────────────── 0800 ║ Свободная память (#FF). ──────────────╫───────────────────────────────────────────────── 1003 ║ Текст "Подсоединен интерфейс 1". ──────────────╫───────────────────────────────────────────────── 10А5 ║ Текст системной информации для LIST. ──────────────╫───────────────────────────────────────────────── 115D ║ Печать листа (HL) в десятичной форме. ──────────────╫───────────────────────────────────────────────── 1бSС ║ Выполнение команды #08. ──────────────╫───────────────────────────────────────────────── 1ббЧ ║ Выполнение команды #09. ──────────────╫───────────────────────────────────────────────── 1CF0 ║ Выполнение командв #0А. ──────────────╫───────────────────────────────────────────────── 1EЗD ║ Выполнение команды #05. ──────────────╫───────────────────────────────────────────────── 1EЧD ║ Выполнение команды #0б. ──────────────╫───────────────────────────────────────────────── 1FFD ║ Форматирование дорожки ║ в E номер дорожки ║ в системной переменной #SСEб адрес таблицы ║ в системной переменной #5CE8 адрес таблицы +1 ║ в системной переменной #5CD7 флаг проверки ║ секторов #1FB9 - 0rdinary, #325А - TURB0. ──────────────╫───────────────────────────────────────────────── 1FEB ║ Выполнение команды #1б. ──────────────╫───────────────────────────────────────────────── 1FFб ║ Выполнение команды #17. ──────────────╫───────────────────────────────────────────────── 2739 ║ Выполнение команды #15. ──────────────╫───────────────────────────────────────────────── 27бб ║ Тексты сообщений TR-DOS. ──────────────╫───────────────────────────────────────────────── 283С ║ Сюда переходит управление с 15б35, определение ║ команды. ──────────────╫───────────────────────────────────────────────── 288С ║ Таблица адресов команд адресуемых регистром С. ──────────────╫───────────────────────────────────────────────── 28D8 ║ Выполнение команды #07. ──────────────╫───────────────────────────────────────────────── 28E0 ║ Выполнение команды #13. ──────────────╫───────────────────────────────────────────────── 28E3 ║ Выполнение команды #14. ──────────────╫───────────────────────────────────────────────── 28E5 ║ Перенос дискриптора файла ║ при А=0 из HL в системные переменные ║ при А<>0 наоборот. ──────────────╫───────────────────────────────────────────────── 28F2 ║ Выполнение команды #0С. ──────────────╫───────────────────────────────────────────────── 28FB ║ Выплонение команды #0В. ──────────────╫───────────────────────────────────────────────── 290F ║ Выполнение команды #0E. ──────────────╫───────────────────────────────────────────────── 292б ║ Выполнение команды #12. ──────────────╫───────────────────────────────────────────────── 29В1 ║ Тексты сообшений TR-DOS. ──────────────╫───────────────────────────────────────────────── 2А53 ║ Вывод А в порт ВС. ──────────────╫───────────────────────────────────────────────── 2АSб ║ Сюда TR-DOS переходит после нажатия MAGIC. ──────────────╫───────────────────────────────────────────────── ЗOFD ║ Ключевые слова TR-DOS. ──────────────╫───────────────────────────────────────────────── 2FFЗ ║ Таблица адресов ключевых слов. ──────────────╫───────────────────────────────────────────────── 3D00 ║ Точка входа. См. начало статьи. ──────────────╫───────────────────────────────────────────────── 3D03 ║ Точка входа. ──────────────╫───────────────────────────────────────────────── ЗDOб ║ Точка входа. ──────────────╫───────────────────────────────────────────────── ЗDOE ║ Точка входа. ──────────────╫───────────────────────────────────────────────── 3D13 ║ Точка входа. ──────────────╫───────────────────────────────────────────────── 3D24 ║ Точка входа. ──────────────╫───────────────────────────────────────────────── 3D2F ║ Точка входа. ──────────────╫───────────────────────────────────────────────── 3D98 ║ Выполнение команды #00. ──────────────╫───────────────────────────────────────────────── 3DCB ║ Выполнение команды #01. ──────────────╫───────────────────────────────────────────────── 3E44 ║ Выполнение команды ВГ93 из В, данные в А. ──────────────╫───────────────────────────────────────────────── ЗEбЗ ║ Выполнение команды #02. ──────────────╫───────────────────────────────────────────────── 3F02 ║ Выполнение команды #03. ──────────────╫───────────────────────────────────────────────── ЗFOб ║ Выполнение команды #04. ──────────────╫───────────────────────────────────────────────── ЗEF5 ║ Ожидание выполнения последней команды ВГ93. ─────────────╫───────────────────────────────────────────────── ЗFE5 ║ Здесь находится процедура приема группы байт ║ от ВГ93 (INI). ─────────────╫───────────────────────────────────────────────── 3FCA ║ Здесь находится процедура блочной записи (0UTI). ══════════════╩═════════════════════════════════════════════════ Самый простой и надежный способ определения версии ПЗУ TR-DOS это через команду #13: LD HL,#03б0 ;в HL помещаем адрес версии TR-DOS ; (для 5.04Т) LD С,#13 ;перенос из HL в системные переменные ; 1б байт CALL 15б35 ;переход в TR-DOS ..... ;процедура сравнения стрингов Я думаю, что для первой статьи в HACKER этого хватит. Ну чтож я заканчиваю. Большинство информации я взял из книжки "TR-DOS для это через команду #13: LD HL,#03б0 ;в HL помещаем адрес версии TR-DOS ; (для 5.04Т) LD С,#13 ;перенос из HL в системные переменные ; 1б байт CALL 15б35 ;переход в TR-DOS ..... ;процедура сравнения стрингов Я думаю, что для первой статьи в HACKER этого хватит. Ну чтож я заканчиваю. Большинство информации я взял из книжки "TR-DOS для професионалов и любителей" Ю. Поморцева. А здесь наверняка будет комментарий CRAZY ALEXa. **************************************************************** Хе-хе... А вот комментария то и не будет... Хотя, это уже комментарий?! ****************************************************************