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.
****************************************************************
Хе-хе... А вот комментария то и не будет...
Хотя, это уже комментарий?!
****************************************************************
Other articles: