Служебные функции
Задание дескриптора файла. #13
Эта функция копирует из памяти 16 байтов, адресуемых регистровой
парой HL, в область дескриптора файла в системных переменных TR-DOS.
LD HL,Descript допирование дескриптора файла из области
;памяти, адресуемой меткой Descript, в
;область дескриптора файла
LD С,#13
CALL 15635
Копирование дескриптора файла. #14
Функция позволяет создать в памяти копию дескриптора файла.
Копируются 16 байтов из области дескриптора в память, адресуемую реги-
стровой парой HL.
LD HL,Descript
LD С,#14
CALL 15635
Позиционирование. #02
Эта функция используется командным процессором для позициони-
рования магнитной головки дисковода на заданную логическую дорожку.
Номер дорожки задается в аккумуляторе. Практического значения не имеет
потому, что остальные функции и так автоматически вызывают ее в начале
своей работы.
LD А,5 позиционирование к 5 логической дорожке,
; при двухсторонней дискете физическая
; дорожка — 2
LD С,2
CALL 15635
Выбрать нижнюю сторону дискеты. #17
Функция служит для выбора нижней стороны дискеты и используется
при тестировании дорожки совместно с функцией #15. Номер стороны
устанавливается в системном регистре интерфейса Beta Disk.
LD С,#17
CALL 15635
Тестирование дорожки. #15
Функция используется командным процессором после форматирова-
ния очередной дорожки для проверки записи. Работает с физическими
дорожками. Номер дорожки задается в регистре D, а номер стороны опреде-
ляется предыдущей операцией. Обратите внимание, что в отличие от других
функций интерпретатора номер дорожки задается не в логическом, а в
физическом виде. Для установки номера стороны можно воспользоваться
функций #02 или #17. Системная переменная 23766 (#5CD6) служит
счетчиком сбойных секторов для заданной дорожки. Если три попытки
прочитать сектор окончились неудачей, то переменная увеличивается на
единицу.
Установка номера сектора. #03
Номер сектора, заданный в аккумуляторе, помещается по адресу
23807. Практического значения функция не имеет.
LD A,Sec_num
LD Cf3
CALL 15635
Установка адреса буфера. #04
Содержимое регистровой пары HL помещается этой функцией в
системную переменную TR-DOS с адресом 23808. При работе интерпрета-
тора эта переменная хранит адрес пользовательского буфера для функций
#05 и #06. Практического значения не имеет.
LD HL.AdcLbuf
LD С,4
CALL 15635
Отсутствующие функции. #0D, #0F, #10, #11
Обращение к этим функциям интерпретатора не вызывает никаких
действий.
Работа с прерываниями
Работа с прерываниями в рамках ОС TR-DOS реализована недоста-
точно удачно, точнее она просто не реализована. Авторы TR-DOS, видимо,
не принимали в расчет возможность работы компьютера в отличном от
стандартного режиме обработки прерываний. Так если установлен второй
режим, то выполнение любых обращений к системе обычно приводит к
печальным результатам, не поддающимся какой-либо систематизации. Для
предотвращения этого можно порекомендовать простой и надежно работаю-
щий метод, суть которого заключается в следующем: перед тем, как исполь-
зовать TR-DOS, прерывания должны быть запрещены, а по окончании
операции вновь разрешены:
LD А,! ;эта команда запишет в бит P/V регистра фпа-
; гов состояние флага разрешения прерываний
PUSH AF
DI
CALL TR_DOS «-выполнение обращения к TR-DOS
POP AF ; восстановлен не значения флага разрешения
; прерываний
JP РО,$+4
EI
Приведенный выше способ не лишен недостатков. Так некоторые
подпрограммы системы сами разрешают прерывания, поэтому может ока-
заться полезным перед обращением к TR-DOS установить первый режим
обработки прерываний, а затем восстановить второй. Подобные методы,
однако, «лечат» не причину, а следствие. Попробуем точно установить
диагноз болезни, и выясним почему TR-DOS не работает при установленном
втором режиме прерываний. Для этого подробно рассмотрим, что происходит
при возникновении прерывания.
После прихода импульса прерывания микропроцессор считывает с
шины данных байт — вектор прерывания. Затем из памяти по адресу,
образуемому вектором прерывания и содержимым регистра I, будут выбра-
ны два байта — адрес подпрограммы обработки прерывания*. Но если
прерывание пришло в тот момент, когда работает TR-DOS, то передача
управления в область ОЗУ автоматически вернет на свое место стандартное
ПЗУ ZX Spectrum. По окончании выполнения подпрограммы произойдет
возврат в основную программу. Однако о «подмене» ПЗУ микропроцессор
не узнает, и вместо продолжения работы ОС TR-DOS будет выполняться
«нечто» из ОС ZX Spectrum.
Итак, для того, чтобы работать со вторым режимом прерываний нужно
каким-то образом установить, какое из двух ПЗУ (TR-DOS или ZX Spectrum)
было подключено до прихода прерывания. На первый взгляд задача невы-
полнима, так как переключения ПЗУ происходят аппарата о. Однако можно
воспользоваться отличиями информации в ПЗУ и задать различные адреса
подпрограмм обработки прерывания. Для этого необходимо задать в регистре
I микропроцессора число от 0 до #3F, тогда адрес будет выбран из области
ПЗУ. Наиболее удачным представляется число 9. В этом случае адрес
процедуры для ПЗУ ZX Spectrum будет 65129, для ПЗУ TR-DOS — 65535 (и
для версии 5.01, и для версии 5.03).
*) Более подробно о механизме работы прерываний микропроцессора Z80
рассказано в главе «Архитектура ZX Spectrum».
Хотя на процедуру обработки прерывания из ПЗУ TR-DOS остался
всего один байт, этого вполне достаточно, так как туда можно записать код
команды JR (#18). Смещение для нее микропроцессор прочитает уже из ПЗУ
ZX Spectrum, это будет код команды DI (#F3). Таким образом, получится
команда JR 65524. В «отвоеванных» 11 байтах можно разместить команду
JP 15664, сразу возвращающую управление в TR-DOS (однако при этом
прерывание окажется «потерянным»), а можно расположить небольшую
программу, выполняющую обработку прерывания, а затем возвращающую
управление.
В качестве примера приведем листинг программы часов, которые
будут «ходить» независимо от конфигурации компьютера. Для их «запуска»
необходимо выполнить подпрограмму, расположенную по адресу 50000.
10 ORG 50000
20 LD А,#18 ;код команды JR
30 LD (65535),А
40 Di ;запрещение прерываний на время установки
; режима
50 LD А,9
60 LD i.A
70 IM 2
80 EI
90 RET
Подпрограмма обработки прерывания. Сюда будет передаваться управ-
ление, когда подключено ПЗУ ZX Spectrum.
100 ORG 65129
110 PUSH AF ^сохранение используемых в подпрограмме
; регистров
120 PUSH HL
130 PUSH DE
140 PUSH ВС
150 CALL CLOCK ;выполнение программы часов
160 POP ВС ;восстановление регистров
170 POP DE
180 POP HL
190 POP AF
200 JP #38
Выполнение стандартной программы обработки прерывания
210 CLOCK LD HLf#5818
Установка атрибутов «циферблата» часов
220 LD DE,#5819
230 LD ВС.7
240 LD (HL)f#57
250 LDIR
260 LD HLJICK
Коррекция и проверка «тиков», один «тик» равен 1/50 секунды
270 DEC (HL)
280 JR NZ.TiME
290 LD (HL)t50
300 LD A,59
310 DEC HL
320 INC (HL)
Коррекция и проверка секунд
330 CP (HL)
340 JR NC.TIME
350 LD (HL).O
360 DEC HL
370 INC (HL)
Коррекция и проверка минут
380 CP (HL)
390 JR NC.TIME
400 LD ; (HL)f0
410 DEC HL
420 LD A(23
430 INC (HL)
Коррекция и проверка часов
440 CP (HL)
450 JR NCJIME
460 LD (HL)f0
470 TIME LD DEf#4018
Индикация текущего времени
480 LD A,(HOURS)
Вывод значения часов
490 CALL DECJPR
500 LD A.":"
510 CALL PRINT
520 LD At(MIN)
Вывод значения минут
530 CALL DECJPR
540 LD A.":"
550 CALL PRINT
560 LD A, (SEC)
Вывод значения секунд
570 DECJPR LD B,"0"-1
Вывод двух цифр — десятичного эквивалента содержимого аккумулятора
580 LOOP 10 INC В
590 SUB 10
600 JR NC.LOOPIO
610 ADD А."0"+10
620 PUSH AF
630 LD A(B
640 CALL PRINT
650 POP AF
660 PRINT LD L,A ;в аккумуляторе код знака
670 LD Н.О
Вычисление адреса символа в знакогенераторе
680 ADD HL.HL
690 ADD HL.HL
700 ADD HL,HL
710 LD A.H
720 ADD Af#3C ;адрес знакогенератора в ПЗУ—256 #3CP0
730 LD Н.А
740 LD В,8
750 LD C,D
760 P_LOOP LD A,(HL) ;вывод символа на жран
770 LD (DE)(A
780 INC HL
790 INC D
800 DJNZ P_LOOP
810 LD D(C
820 INC E
830 RET
840 HOURS DEFB 0 ;значение часов
850 MIN DEFB 0 ;значение минут
860 SEC DEFB 0 /значение секунд
870 TICK DEFB 0 /значение «тиков»
Подпрограмма обработки прерывания. Сюда будет передаваться управ-
ление после выполнения команды JR 65524 когда подключено ПЗУ
TR-DOS.
880 ORG 65524
890 PUSH HL /сохранение в стеке содержимого регистровой
; пары HL.
900 LD HL. 15664 /адрес возврата в TR-DOS
910 EX (SP)(HL /восстановление значения регистровой пары HL.
; В стеке - адрес возврата в ПЗУ TR-DOS
920 JP 65129 /выполнение подпрограммы обслуживания
; прерывания