│ 16 │ Функция FPOS │
├───────────┼─────────────────────────┤
│ 18 │ Символ поддержки │
└───────────└─────────────────────────┘
Табл.21.1. Запросы к устройству
TEXT - это указатель на текст программы на языке BASIC, если
эта BASIC-программа в картридже должна автоматически запускаться
при перезагрузке. В противном случае там хранится ноль. Размер
программы должен быть не более 16 К, по адресам с 8000h по BFFFh.
Интерпретатор языка BASIC проверяет содержимое поля TEXT
заголовка картриджа после инициализации (INIT) и после того как
стартует система. Если там не ноль, то по указателю TEXT
запускается BASIC-программа. Она должна храниться в промежуточном
коде и ее начало обозначается кодом ноль.
п.2. Создание CALL-подпрограмм пользователем
Приведем пример программы создания следующих подпрограмм
пользователя, вызываемых из MSX-BASIC оператором CALL:
CALL RUSON - включение русских букв;
CALL RUSOFF - выключение русских букв;
CALL CAPSON - включение прописных букв;
CALL CAPSOFF - выключение прописных букв.
Эти операторы формируются в псевдо-ROM по адресу 4000h. Для
правильной трансляции ссылок используются директивы. PHASE и
.DEPHASE, которые описаны ниже.
Перед записью значений в ячейку управления вторичными слотами
(FFFFh) они должны инвертироваться. Это нужно помнить и при
запоминании текущего состояния слотов.
Хотя для трансляции мы воспользовались ассемблером M80 и
сборщиком L80, полученный файл реально имеет тип OBJ. Это
обеспечивают первые 7 байт текста программы.
┌──────────────────────────────
MSX. M-80 1.00 01-Apr-85
.Z80
9000 Load EQU 9000h ; адрес загрузки
4000 CallROM EQU 4000h ; адрес переписывания
FD02 RAMCF EQU 0FD02h ; страница 1 слот 3-2
FD89 IdCall EQU 0FD89h ; сюда BASIC записывает
; имя оператора CALL
0F1F RUSSWCH EQU 0F1Fh ; вкл/выкл. RUS
FCAB CAPST EQU 0FCABh ; статус CAPS
FCAC KANAST EQU 0FCACh ; статус RUS
0004 CallNmb EQU 4 ; количество наших CALL
0000' ASEG
0000 FE DB 0FEh ; Obj-файл
0001 9000 DW Load ; адрес загрузки
0003 90F2 DW Load+Length ; конечный адрес
0005 9000 DW Start ; стартовый адрес
; ========================================
.PHASE Load
9000 F3 Start: DI
; === Установка вторичного слота
9001 3A FFFF LD A,(0FFFFh) ; текущее полож. слотов
9004 2F CPL ; инверсия
9005 F5 PUSH AF ; запись в стек
9006 CB DF SET 3,A ; страница 1, втор. сл. 2
9008 CB 97 RES 2,A
900A 32 FFFF LD (0FFFFh),A
; === Установка первичного слота
900D DB A8 IN A,(0A8h) ; первичный слот
900F F5 PUSH AF
9010 F6 0C OR 00001100b ; стр. 1, слот 3
9012 D3 A8 OUT (0A8h),A
; === Заполняем псевдо-ROM
9014 21 902E LD HL, PrgEnd ; откуда
9017 11 4000 LD DE, CallROM ; куда
901A 01 00C4 LD BC, Length-(PrgEnd-Load) ; сколько
901D ED B0 LDIR ; пересылка
; === Восстановление конфигурации BASIC
901F F1 POP AF
9020 D3 A8 OUT (0A8h),A
9022 F1 POP AF
9023 32 FFFF LD (0FFFFh),A
9026 FB EI
; === Заполнение буфера SLTATR - FD02h, т. е.
; === Разрешение CALL для слота 3-2, первая страница (4000h)
9027 3E 20 LD A,32
9029 32 FD02 LD (RAMCF),A
902C 3F CCF
902D C9 RET ; возврат в BASIC
902E PrgEnd EQU $
.DEPHASE
; === Заголовок псевдо-ROM
.PHASE CallROM
4000 41 42 DB 'AB' ; ID картриджа
4002 0000 DW 0 ; адрес инициализации ROM
4004 4011 DW CallBeg ; адрес обработки CALL
4006 0000 DW 0 ; адрес обработки нестанд. I/O
4008 0000 DW 0 ; адрес текста BASIC в ROM
400A DS 7,0 ; резерв
; === Начало обработки оператора CALL
4011 CallBeg:
4011 37 SCF ; флаг "Syntax error"
4012 E5 PUSH HL ; сохраним HL
4013 06 04 LD B, CallNmb ; цикл сравнений
4015 21 4053 LD HL, IdBlock
4018 NewComp:
4018 E5 PUSH HL
4019 CD 4028 CALL CompBlock ; сравниваем имена
401C E1 POP HL
401D 30 1C JR NC, AddrBlock ; если нашли имя, переход
401F 11 0010 LD DE,010h ; на следующее имя, +16 байт
4022 19 ADD HL, DE ; увеличиваем адрес
4023 10 F3 DJNZ NewComp ; повторяем поиск
4025 E1 POP HL ; возврат, имени CALL нет
4026 37 SCF ; "Syntax error"
4027 C9 RET
; === Сравнение имен
4028 CompBlock:
4028 11 FD89 LD DE, IdCall ; адрес имени CALL
402B 1A NextS: LD A,(DE)
402C A7 AND A ; ноль?
402D 28 07 JR Z, EndNm
402F BE CP (HL) ; сравнить с псевдоROM
4030 37 SCF
4031 C0 RET NZ ; выход, не равны
4032 23 INC HL ; сравнить следующие символы
4033 13 INC DE
4034 18 F5 JR NextS
4036 BE EndNm: CP (HL) ; тоже ноль?
4037 37 SCF
4038 C0 RET NZ ; выход, если длиннее
4039 3F CCF ; имена совпали !
403A C9 RET
; === Выбираем адрес нашего CALL и переходим
403B AddrBlock:
403B 3E 04 LD A, CallNmb
403D 90 SUB B ; номер имени CALL
403E 21 404B LD HL, AddrCall
4041 87 ADD A, A ; смещение в табл. адресов
4042 16 00 LD D,0
4044 5F LD E, A
4045 19 ADD HL, DE ; адрес в таблице - в HL
4046 5E LD E,(HL) ; адрес подпр. CALL - в DE
4047 23 INC HL
4048 56 LD D,(HL)
4049 EB EX DE, HL ; адрес - в HL
404A E9 JP (HL) ; переход на наш CALL!
; === Таблица адресов подпрограмм CALL
404B AddrCall:
404B 4093 DW RUSON
404D 409D DW RUSOFF
404F 40A8 DW CAPSON
4051 40B7 DW CAPSOFF
; === Таблица имен операторов CALL, по 16 байт на имя
4053 IdBlock:
4053 52 55 53 4F DEFM 'RUSON'
4057 4E
4058 DEFS 11,0
4063 52 55 53 4F DEFM 'RUSOFF'
4067 46 46
4069 DEFS 10,0
4073 43 41 50 53 DEFM 'CAPSON'
4077 4F 4E
4079 DEFS 10,0
4083 43 41 50 53 DEFM 'CAPSOFF'
4087 4F 46 46
408A DEFS 9,0
; === Включить RUS
4093 AF RUSON: XOR A
4094 32 FCAC LD (KANAST),A
4097 F7 RST 30h
4098 00 DEFB 0
4099 0F1F DEFW RUSSWCH
409B E1 POP HL
409C C9 RET
; === Выключить RUS
RUSOFF:
409D 3E FF LD A,0FFh
409F 32 FCAC LD (KANAST),A
40A2 F7 RST 30h
40A3 00 DEFB 0
40A4 0F1F DEFW RUSSWCH
40A6 E1 POP HL
40A7 C9 RET
; === Включить CAPS
CAPSON:
40A8 3E FF LD A,0FFh
40AA 32 FCAB LD (CAPST),A
40AD F3 DI
40AE DB AA IN A,(0AAh)
40B0 E6 BF AND 0BFh
40B2 D3 AA OUT (0AAh),A
40B4 FB EI
40B5 E1 POP HL
40B6 C9 RET
; === Выключить CAPS
CAPSOFF:
40B7 AF XOR A
40B8 32 FCAB LD (CAPST),A
40BB F3 DI
40BC DB AA IN A,(0AAh)
40BE F6 40 OR 40h
40C0 D3 AA OUT (0AAh),A
40C2 FB EI
40C3 E1 POP HL
40C4 C9 RET
.DEPHASE
00F2 Length EQU $-1-7
END
└──────────────────────────────
22. Работа с файлами
При работе с внешними устройствами в традиционном
программировании используются два понятия: набор данных и файл.
Набором данных называют логически связанную совокупность
информации, размещаемую на внешних запоминающих устройствах и
устройствах ввода/вывода. Таким образом, набор данных имеет
физический смысл - информация, хранимая на ленте, диске, бумаге и
т. п.
Файл - это абстракция (структура, описание) набора данных в
программе на некотором языке программирования. Программист
описывает файл и выполняет операции ввода/вывода над файлом,
возможно, не зная точно, какой конкретно набор данных будет
сопоставлен файлу. Связь файла с набором данных обычно
осуществляет оператор открытия файла.
В последнее время понятие "файл" часто используется вместо
понятия "набор данных". Файл становится и логическим, и физическим
понятием.
С файлами (наборами данных) можно работать на двух уровнях -
"низком" и "высоком". В первой главе была описана организация
хранения информации на диске. Хорошо разобравшись в структуре
директория, DPB, FAT, FCB, можно написать программу, которая ищет
файл в директории, затем в FAT, читает или пишет информацию в
соответствующие сектора диска и затем обновляет директорий и FAT.
Это и есть "низкий" уровень, требующий очень кропотливой и
аккуратной работы.
На "высоком" уровне программист берет на себя минимум забот -
задает FCB и буфер ввода/вывода, а всю остальную работу выполняют
системные функции BDOS MSX-DOS. Такая работа более надежна, но
предоставляет меньше возможностей.
п.1. Абсолютное чтение/запись
Под абсолютным чтением/записью здесь понимается чтение/запись
логических секторов диска, в том числе BOOT-сектора, секторов
директория, таблиц FAT, секторов данных.
Для выполнения таких действий можно использовать системные
функции BDOS 1Ah ( установка адреса буфера), 1Bh ( получение
информации о драйвере), 2Fh ( абсолютное чтение секторов), 30h
( абсолютная запись секторов диска) и другие.
В качестве примера приведем программу восстановления
директория, если были случайно уничтожены несколько файлов. Как Вы
помните, при этом в первом байте соответствующей записи директория
появляется код E5h.
Программа находит такие записи в директории и ждет ввода
программистом первой литеры стертого файла. В конце работы
восстановленный директорий записывается назад на диск. Обратите
внимение, что программа не востанавливает FAT, записи которого при
уничтожении файла обнуляются.
┌──────────────
MSX. M-80 1.00 01-Apr-85 PAGE 1
.Z80
0005 BDOS EQU 5
0001 CONS_INP EQU 1
0002 CONS_OUT EQU 2
|
Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |


