Адрес 10300. Вызов подпрограмм TR-DOS из машинного кода. Вход:
в регистре C код команды, остальное согласно описанию. На выходе
в регистре BC код ошибки.
10300 PUSH AF ;сохранение регистров
PUSH BC
LD (23812),DE
LD (23810),HL
CALL 8433 ;если нужно, то изменение памяти
LD A,255
LD (23829),A ;сообщения не печатать
LD (23839),A ;команда поступила из машинного кода
POP BC ;восстановление BC и AF
POP AF
LD HL,513 ;по возврату пойдем в подпрограмму возврата в
LD (23834),HL;бейсик
LD HL,0 ;сохранение SP
ADD HL,SP
LD (23836),HL
DEC HL ;резервирование места для адреса возврата по
DEC HL ;ошибке из подпрограмм бейсика
LD SP,HL
PUSH AF ;сохранение AF
CALL 541 ;установка адреса возврата по ошибке из бейсика
LD HL,10380 ;берем адрес начала таблицы команд
10345 LD A,(HL) ;берем код команды
CP C ;он совпал с требуемым ?
JR NZ,10367 ;если нет, то берем код следующей команды
POP AF ;восстановление AF
INC HL ;берем адрес, по которому находится адрес подпрограммы
LD E,(HL) ;берем адрес подпрограммы
INC HL
LD D,(HL)
LD HL,467 ;берем адрес подпрограммы завершения
PUSH HL ;кладем его на стек
PUSH DE ;кладем на стек адрес подпрограммы
LD HL,(23810);восстановление HL и DE
LD DE,(23812)
RET ;переход к подпрограмме
10367 CP 255 ;достигнут конец таблицы ?
JR NZ,10375 ;если нет, то берем адрес номера следующей подпрограммы
POP AF ;снятие AF со стека (этого можно было не делать)
JP 467 ;переход на подпрограмму завершения
10375 INC HL ;пропуск двух байтов адреса подпрограммы
INC HL
INC HL
JR 10345 ;повтор
10380 DEFB 0 ;таблица номеров и адресов подпрограмм
DEFW 15768
DEFB 1
DEFW 15819
DEFB 2
DEFW 15971
DEFB 3
DEFW 16130
DEFB 4
DEFW 16134
DEFB 5
DEFW 7741
DEFB 6
DEFW 7757
DEFB 7
DEFW 10456
DEFB 8
DEFW 5724
DEFB 9
DEFW 5732
DEFB 10
DEFW 7408
DEFB 11
DEFW 10491
DEFB 12
DEFW 10482
DEFB 13
DEFW 467
DEFB 14
DEFW 10511
DEFB 15
DEFW 467
DEFB 16
DEFW 467
DEFB 17
DEFW 467
DEFB 18
DEFW 10534
DEFB 19
DEFW 10464
DEFB 20
DEFW 10467
DEFB 21
DEFW 10041
DEFB 22
DEFW 8171
DEFB 23
DEFW 8182
DEFB 24
DEFW 1029
DEFB 255 ;признак конца таблицы
────────────────────────────────────────────────────────────────
Адрес 10456. Выдача каталога диска с настройкой. На входе в A
задайте номер потока, в который будете выводить каталог.
10456 PUSH AF ;сохранение номера потока
CALL 1029;настройка на диск
POP AF ;восстановление номера потока
JP 1145 ;вывод каталога
────────────────────────────────────────────────────────────────
Адрес 10464. Перемещение описателя файла из памяти в 23773. В HL
задайте адрес описателя файла в памяти.
10464 XOR A ;перемещаем из (HL) в 23773
JP 10469;перемещение описателя
────────────────────────────────────────────────────────────────
Адрес 10467. Перемещение описателя файла из 23773 в память по
адресу, установленному в HL. Используется также с адреса 10469
(перемещение описателя файла, в HL - адрес описателя в памяти, в
A - направление перемещения: 0 - из памяти, иначе - в память).
10467 LD A,255 ;перемещаем в память
10469 LD DE,23773;установка второго адреса для LDIR
LD BC,16 ;установка длины описателя
OR A ;установка направления перемещения
JR Z,10479
EX DE,HL
10479 LDIR ;перемещение описателя файла
RET ;возврат
────────────────────────────────────────────────────────────────
Адрес 10482. Запись программы на бейсике. Установите 23761,
23773 и 23781.
10482 CALL 1029;настройка на диск
CALL 6852;проверка свободного места в каталоге
JP 6951 ;запись программы
────────────────────────────────────────────────────────────────
Адрес 10491. Запись файла. Имя с расширением поместите в 23773,
длину в DE, начало в HL.
10491 LD (23767),HL;установка начала
LD (23769),DE;установка действительной длины файла
LD (23771),DE;установка длины файла для каталога
CALL 1029 ;настройка на диск
CALL 6852 ;проверка наличия свободного места в каталоге
JP 6995 ;запись файла
────────────────────────────────────────────────────────────────
Адрес 10511. Загрузка / верификация файла а также чтение / за-
пись сектора файла. Установите 23773, 23781, 23767 (только для
чтения / записи сектора) и 23801; в A поместите флаг загрузки согласно
описанию команды #0E в HL и DE - старт и длину (в зависимости от
аккумулятора).
10511 OR A
LD (23766),A ;установка флага загрузки
LD (23769),HL;установка адреса загрузки
LD (23771),DE;установка длины загрузки
CALL 7347 ;поиск файла
CALL 6308 ;если файл найден, то чтение его описателя
CALL 6315 ;обработка параметров загрузки
JP 6433 ;загрузка файла
────────────────────────────────────────────────────────────────
Адрес 10534. Стирание файла. Установите 23773 и 23781. На выходе
будут установлены 23815 и 23816.
10534 CALL 1029;настройка на диск
CALL 7347;поиск файла
JP 1952 ;стирание его
────────────────────────────────────────────────────────────────
Адрес 10543. Проверка наличия файла. Имя поместите на стек каль-
кулятора и установите 23814. Если файл найден, то в рег. C и в
23838 и будет включен флаг Z, иначе флаг Z будет сброшен, а в
C будет 255.
10543 CALL 7255;установка имени файла
CALL 1029;настройка на диск
JP 7347 ;поиск файла и возврат
────────────────────────────────────────────────────────────────
Адрес 10552. Печать имени файла с расширением. В HL установите
адрес имени с расширением.
10552 PUSH BC ;сохранение BC
LD B,8 ;в имени файла 8 символов
10555 LD A,(HL) ;берем символ из имени файла
RST 16 ;печать его
INC HL ;адрес следующего символа
DJNZ 10555;повтор до конца
LD A,"<" ;печать "<"
RST 16
LD A,(HL) ;печать расширения
RST 16
LD A,">" ;печать ">"
RST 16
POP BC ;восстановление BC
RET ;возврат
────────────────────────────────────────────────────────────────
Адрес 10570. Создание буфера, если его нет. Установите 23820.
10570 PUSH HL ;сохранение регистров
PUSH DE
PUSH BC
PUSH AF
LD HL,23820 ;буфер есть ?
LD A,(HL)
OR A
JR Z,10642 ;если да, то восстановление регистров и возврат
PUSH HL ;сохранение адреса флага наличия буфера
LD BC,257 ;длина буфера
PUSH BC ;сохранение ее
CALL 6653 ;проверка возможности выделения буфера
POP BC ;восстановление длины буфера
POP HL ;восстановление адреса его флага
LD (HL),0 ;буфер есть
LD HL,23845 ;начало буфера
CALL 7730 ;выделение буфера
LD HL,(23825);командная строка переместилась на 257 байтов
LD BC,257
ADD HL,BC
JR 10639 ;установка нового адреса командной строки и возврат
────────────────────────────────────────────────────────────────
Адрес 10608. Удаление буфера, если он есть. Установите 23820.
Используется также с адресов 10639 и 10642 подпрограммой 10570.
10608 PUSH HL ;сохранение регистров
PUSH DE
PUSH BC
PUSH AF
LD HL,23820 ;буфера нет ?
LD A,(HL)
OR A
JR NZ,10642 ;если да, то возврат
LD (HL),255 ;буфера нет
LD HL,23845 ;начало буфера
LD BC,257 ;его длина
CALL 7726 ;удаление области памяти
OR A ;командная строка переместилась на 257 байтов
LD BC,257 ;надо поменять ее адрес
LD HL,(23825)
SBC HL,BC
10639 LD (23825),HL
10642 POP AF ;восстановление регистров
POP BC
POP DE
POP HL
RET ;возврат
────────────────────────────────────────────────────────────────
Адрес 10647. Выполнение команды 40. Установите 23825 и 23611.
Используется также с адреса 10648 (выполнение команды установки
типа дисковода; установите все для 10647 плюс в A тип дисково-
да).
10647 XOR A ;дисковод 40-дорожечный односторонний
Ошибка!!! Во-первых, почему односторонний ?; во-вторых, надо
проверять возможность использования дисковода в требуемом режи-
ме.
10648 LD (23767),A;сохранение типа дисковода
CALL 7541 ;если идет проверка на синтаксис, то возврат
CALL 1067 ;проверка второго символа строки
JP Z,7450 ;если это ENTER, то *ERROR*
CALL 15889 ;берем адрес ячейки с типом дисковода
LD A,(23767);установка типа дисковода
LD (HL),A
JP 993 ;сообщение O.K.
────────────────────────────────────────────────────────────────
Адрес 10670. Выполнение команды "80". Установите 23825 и 23611.
10670 LD A,128;дисковод 80-дорожечный односторонний
Ошибка!!! Во-первых, почему односторонний ?; во-вторых, надо
проверять возможность использования дисковода в требуемом режи-
ме.
JP 10648;выполнение команды
────────────────────────────────────────────────────────────────
Адрес 10674. Тексты сообщений TR-DOS.
10674 DEFB 13
DEFM "*ERROR*"
DEFB 141
10683 DEFB 13
DEFM "No space"
DEFB 141
10693 DEFB 13
DEFM "File exists"
DEFB 141
10706 DEFM " Free"
DEFB 141
10712 DEFB 13
DEFM "Read onl"
DEFB 249
10722 DEFB 13
DEFM "Disc erro"
DEFB 242
10733 DEFB 13
DEFM "Rec. O/"
DEFB 198
10743 DEFM "Title:"
DEFB 160
10750 DEFB 13
DEFM "Retry,Abort,Ignore?"
DEFB 0
10771 DEFB 13
DEFM "Trk"
DEFB 160
10776 DEFM " Sec"
DEFB 160
10781 DEFM " Del. File"
DEFB 141
10792 DEFB 13
DEFM "No"
10795 DEFM " File(S)
DEFB 141
────────────────────────────────────────────────────────────────
Адрес 10805. Перенос подпрограммы определение текущего ПЗУ по
адресу 16512.
10805 LD HL,10817;адрес подпрограммы определение текущего ПЗУ
LD DE,16512;ее адрес в ОЗУ
LD BC,32 ;ее длина - 32 байта
LDIR ;перенос подпрограммы
RET ;возврат
────────────────────────────────────────────────────────────────
Адрес 10817. Подпрограмма определения текущего ПЗУ. Устанавлива-
ет 23553 и подключает ПЗУ 48-го бейсика. Для работы подпрограмма
должна быть перемещена в любое место ОЗУ. Можно использовать
также с адреса 10835 для прямого вывода в любой порт.
10817 LD A,(949) ;берем байт из ПЗУ
CP 243 ;это 243 ?
LD A,16 ;если да, то это ПЗУ 48-го бейсика
JR Z,10827
XOR A ;иначе это ПЗУ 128-го бейсика
10827 LD (23553),A;установка номера ПЗУ
LD BC,32765 ;адрес порта конфигурации системы
LD A,16 ;ПЗУ 48-го бейсика
10835 OUT (C),A ;установка ПЗУ
RET ;возврат
────────────────────────────────────────────────────────────────
Адрес 10838. Запись памяти на диск.
10838 PUSH AF ;сохранение регистров
PUSH BC
PUSH DE
PUSH HL
PUSH IX
PUSH IY
EXX
PUSH BC
PUSH DE
PUSH HL
EX AF,AF'
PUSH AF
LD A,I
PUSH AF
LD A,R
PUSH AF
LD HL,0
ADD HL,SP ;сохранение SP
PUSH HL
LD A,60 ;выбор дисковода A и верхней стороны диска
OUT (255),A
LD A,63 ;установка регистра I
LD I,A
IN A,(31) ;берем состояние контроллера
AND 128
RRCA
RRCA
RRCA
LD (23553),A ;сохранение его
Ошибка!!! Нельзя портить память.
CALL 12133 ;восстановление
CALL 16032 ;задержка в 2168937 тактов
CALL 16032 ;еще раз
LD DE,10 ;сектор 10
LD HL,16384 ;записывать с адреса 16384
PUSH HL ;сохранение числа 16384
CALL 11635 ;запись сектора
LD HL,16640 ;записывать с адреса 16640
LD DE,11 ;сектор 11
CALL 11635 ;запись сектора
POP HL ;восстановление числа 16384
PUSH HL ;и снова сохранение
LD DE,8 ;сектор 8
CALL 12059 ;загрузка сектора
LD HL,16611 ;берем тип диска
LD A,(HL)
LD (23552),A ;сохраняем его
Ошибка!!! Опять порча памяти.
INC HL ;берем количество файлов на диске
LD A,(HL)
INC (HL) ;записали еще 1 файл
Внимание!!! Не проверяется наличие свободного места в каталоге
диска.
INC HL ;берем количество свободного места на диске
LD E,(HL)
INC HL
LD D,(HL)
OR A ;сброс флага C
EX DE,HL
LD DE,192 ;уменьшим количество места на диске на 192
SBC HL,DE ;сектора
LD (16613),HL;установка нового количества свободного места на диске
LD HL,16384 ;записывать с адреса 16384
LD DE,8 ;сектор 8
CALL 11635 ;запись сектора
POP HL ;восстановление адреса 16384
LD DE,(16609);берем адрес свободного места на диске
PUSH DE ;сохраняем его
LD DE,10 ;сектор 10
CALL 12059 ;загрузка сектора
POP DE ;восстановление адреса свободного места на диске
CALL 11596 ;запись секторов
PUSH DE ;сохранение нового адреса свободного места на диске
LD A,60 ;выбор дисковода A и верхней стороны диска
OUT (255),A
CALL 12133 ;восстановление
LD HL,16384 ;грузить с адреса 16384
LD DE,8 ;сектор 8
LD B,1
CALL 12059 ;загрузка сектора
POP DE ;восстановление нового адреса свободного места на диске
LD HL,(16609);берем старый адрес свободного места на диске
LD (16609),DE;установка нового адреса
PUSH HL ;сохранение старого адреса
LD HL,16384 ;записывать с адреса 16384
LD DE,8 ;сектор 8
LD B,1
CALL 11635 ;запись сектора
LD A,(16612) ;берем номер записанного файла
DEC A
CALL 11493 ;загрузка сектора с его описателем
LD (HL),"@" ;имя файла - "@"
INC HL
LD B,7 ;7 пробелов
11017 LD (HL)," "
INC HL
DJNZ 11017
LD (HL),"C" ;расширение файла - "C"
POP DE ;восстановление старого адреса свободного места на диске
POP BC ;и значения SP после сохранения регистров
INC HL ;установка значения SP после сохранения
LD (HL),C ;в поле адреса загрузки файла
INC HL
LD (HL),B
INC HL ;поле длины файла пропускаем
INC HL
INC HL
LD (HL),192 ;длина файла - 192 сектора
INC HL
LD (HL),E ;установка адреса файла на диске
INC HL
LD (HL),D
LD HL,16384 ;записывать с адреса 16384
LD DE,0
IN A,(95) ;берем номер сектора, в котором находится
DEC A ;описатель файла
LD E,A
LD B,1
CALL 11635 ;запись сектора
LD HL,0 ;сохранение SP
ADD HL,SP
LD (16704),SP
LD SP,16895 ;перенос стека в экран
CALL 10805 ;перенос в экран подпрограммы определения текущего ПЗУ
LD HL,49152 ;адрес страниц ОЗУ
XOR A ;начало вычисления контрольной суммы страницы
11071 ADD A,(HL) ;прибавление к сумме очередного байта
INC HL ;адрес следующего байта
LD B,A ;сохранение контрольной суммы
LD A,H ;берем старший байт текущего адреса в странице
OR A ;это 0 ?
LD A,B ;восстановление контрольной суммы
JR NZ,11071 ;если нет, то повтор
LD HL,16640 ;сохранение контрольной суммы текущей
LD (HL),A ;страницы
PUSH HL ;сохранение ее адреса
LD HL,11096 ;адрес возврата - 11096
PUSH HL ;помещение его на стек
LD HL,15663 ;адрес переключателя ПЗУ на TR-DOS
PUSH HL ;помещение его на стек
DI ;запрет прерываний
JP 16512 ;определение текущего ПЗУ
11096 POP HL ;восстановление адреса контрольной суммы текущей страницы
LD BC,32765 ;адрес порта конфигурации системы
LD A,170 ;контрольный байт
LD (16688),A ;помещение его в экран
LD D,5 ;банк ОЗУ 5
LD A,(23553) ;выбор ПЗУ
OR D
LD D,A
OUT (C),A ;выбор банка памяти
LD A,(49456) ;берем адрес контрольного байта
CP 170 ;это 170 ?
JP NZ,11291 ;если нет, то выход
LD A,D ;ОЗУ 0
AND 248
LD D,A
INC HL ;адрес переменной с кодом текущего банка памяти
LD B,8 ;всего 8 страниц
LD (HL),D ;установка банка
OUT (C),D ;выбор банка
XOR A ;начало вычисления контрольной суммы страницы
LD HL,49152 ;адрес страниц ОЗУ
11136 ADD A,(HL) ;прибавление к сумме очередного байта
INC HL ;адрес следующего байта
LD E,A ;сохранение контрольной суммы
LD A,H ;берем старший байт текущего адреса в странице
OR A ;это 0 ?
LD A,E ;восстановление контрольной суммы
JR NZ,11136 ;если нет, то повтор
LD HL,16640 ;адрес переменной с контрольной суммой текущей страницы
CP (HL) ;суммы совпадают ?
INC HL ;адрес переменной с кодом текущего банка памяти
JR Z,11155 ;если да, то все
INC D ;следующая страница ОЗУ
DJNZ 11129 ;повтор до конца
DEC D ;берем код текущего банка памяти
11155 LD B,8 ;всего 8 страниц
11157 PUSH BC ;сохранение числа страниц
CALL 11319 ;запись страницы
POP BC ;восстановление числа страниц
DJNZ 11157 ;повтор до конца
LD C,0 ;дорожка 0
CALL 12090 ;позиционирование
CALL 11562 ;загрузка сектора 8 по адресу 16384
LD A,(16612) ;берем количество файлов на диске
LD (16642),A ;сохраняем его
INC A ;записали еще 1 файл
LD (16612),A ;установка нового количества файлов
LD HL,(16613);берем количество свободного места на диске
LD DE,1 ;уменьшаем его на 1 сектор
SBC HL,DE
LD (16613),HL;установка нового количества свободного места на диске
RET C ;если места на диске нет, то возврат
Внимание!!! Куда возврат ? Ведь на вершине стека находится сох-
раненные регистры R и F.
LD HL,(16609);берем адрес свободного места на диске
LD (16670),HL;сохраняем его
CALL 11550 ;установка имени файла
LD A,"8" ;восьмой файл
LD (11657),A
LD A,1 ;его длина - 1 сектор
LD (16669),A
LD HL,16640 ;адрес загрузки - 16640
LD (16665),HL
LD HL,256 ;длина - 256 байтов
LD (16667),HL
LD DE,(16609);берем адрес свободного места на диске
CALL 12133 ;восстановление
LD C,D ;берем номер дорожки
CALL 12090 ;позиционирование
LD HL,16640 ;записывать с адреса 16640
LD B,1 ;1 сектор
CALL 11608 ;запись сектора
LD (16609),DE;установка нового адреса свободного места на диске
LD C,0 ;дорожка 0
CALL 12090 ;позиционирование
CALL 11572 ;запись сектора 8 с адреса 16384
LD A,(16642) ;берем номер записанного файла
CALL 11493 ;загрузка сектора с его описателем
LD DE,16656 ;замена описателя файла
LD BC,16
EX DE,HL
LDIR
IN A,(95) ;берем номер загруженного сектора
DEC A
LD E,A
LD D,0
LD HL,16384 ;записывать с адреса 16384
CALL 11635 ;запись сектора
LD BC,32765 ;адрес порта конфигурации системы
LD A,(16641) ;берем код текущего банка памяти
OUT (C),A ;установка его
11291 LD HL,(16704);восстановление SP
LD SP,HL
LD HL,16384 ;загружать с адреса 16384
LD DE,10 ;сектор 10
CALL 12059 ;загрузка сектора
LD HL,16640 ;загружать с адреса 16640
LD DE,11 ;сектор 11
CALL 12059 ;загрузка сектора
LD A,60 ;помещение на стек числа 60
PUSH AF
JP 11964 ;восстановление регистров и возврат
────────────────────────────────────────────────────────────────
Адрес 11319. Запись страницы ОЗУ, если она не пустая. Поместите
в B номер страницы плюс 1 и установите 23552 и 16641.
11319 LD A,B ;берем номер страницы
DEC A
LD (16643),A;установка его
LD B,A ;сохранение его
LD A,(16641);берем номер текущей страницы
AND 7
CP B ;записываем ее ?
RET Z ;если да, то возврат
LD A,2 ;записываем страницу 2 ?
CP B
RET Z ;если да, то возврат
LD A,(16641);берем код текущего банка памяти
AND 8 ;текущий экран 0 ?
JR Z,11349 ;если да, то не записываем страницу 5
LD A,B ;записываем страницу 7 ?
CP 7
RET Z ;если да, то возврат
JR 11353 ;запись страницы
11349 LD A,B ;записываем страницу 5 ?
CP 5
RET Z ;если да, то возврат
11353 CALL 11357 ;запись страницы
RET ;возврат
────────────────────────────────────────────────────────────────
Адрес 11357. Запись страницы ОЗУ, если она не пустая. Поместите
в B номер страницы и установите 23552 и 16641.
11357 LD HL,16641;берем код текущего банка памяти
LD A,(HL)
AND 248 ;оставляем экран и ПЗУ
LD C,A
LD A,B ;вычисление байта для порта конфигурации
OR C ;системы
PUSH BC ;сохранение кода текущего банка памяти
LD BC,23765;адрес порта конфигурации
OUT (C),A ;установка банка памяти
POP BC ;восстановление кода текущего банка
LD HL,49152;адрес страницы
11376 LD A,(HL) ;берем байт из страницы
OR A ;это 0 ?
JR NZ,11386;если нет, то запись страницы
INC HL ;следующий байт
LD A,H ;конец страницы ?
OR A
JR NZ,11376;если нет, то повтор
RET ;возврат
11386 CALL 11390 ;запись страницы
RET ;возврат