Адрес 8536. Прием числа. CH_ADD установите на символ перед
числом. Число, увеличенное на 1, будет помещено в 23767, а со-
держимое 23771 будет скопировано в 23769. Число не должно рав-
няться 0.
8536 CALL 7722 ;следующий символ
CALL 7564
CP "," ;это запятая ?
JP NZ,7450 ;если да, то ошибка
LD HL,(23771);сохранение 23771
LD (23769),HL
CALL 7691 ;помещение числа на стек калькулятора
CALL 7541 ;если идет проверка на синтаксис, то возврат
LD HL,(23771);число pавно 0 ?
LD A,
OR L
JP NZ,7450 ;если да, то ошибка
INC HL ;еще будет байт ENTER
LD (23767),HL;установка числа
LD HL,(23769);восстановление 23771
LD (23771),HL
RET ;возврат
────────────────────────────────────────────────────────────────
Адрес 8578. Выполнение команды OPEN#. Установите 23825 и 23611.
8578 LD HL,(23825);установка CH_ADD
LD (23645),HL
CALL 7691 ;принятие номера потока
CALL 7632 ;принятие имени файла на стек калькулятора
8590 CALL 7564 ;берем текущий символ
CP "A" ;он меньше "A" ?
JR NC,8602 ;если нет, то проверка режима файла
CALL 7722 ;следующий символ
JR 8590 ;повтор
8602 CP 165 ;это RND ?
PUSH AF ;сохранение символа и результата проверки
CALL Z,8536 ;если это RND, то обработка длины записи
POP AF ;восстановление символа и результата проверки
JR Z,8622 ;если это RND, то открытие потока
AND 223 ;буква заглавная
CP "R" ;это "R" ?
JR Z,8622 ;если да, то открытие потока
CP "W" ;это "W" ?
JP NZ,7450 ;если нет, то ошибка
8622 LD (23817),A ;сохранение буквы режима файла
CALL 7541 ;если идет проверка на синтаксис, то возврат
LD A,"#" ;расширение файла - "#"
LD (23781),A
LD A,0 ;поиск начинать с блока 0
LD (23782),A
CALL 8667 ;поиск последнего блока файла
PUSH AF ;сохранение флага результата поиска
CALL 8719 ;проверка потока
POP AF ;восстановление флага результата поиска
PUSH AF ;сохранение флага результата поиска
CALL NZ,8840 ;если файл не был найден, то создание блока 0
POP AF ;восстановление флага результата поиска
CALL 8770 ;открытие потока
LD HL,(23825);коррекция переменной с адресом командной строки
LD BC,292
ADD HL,BC
LD (23825),HL
JP 467 ;завершение
────────────────────────────────────────────────────────────────
Адрес 8667. Поиск блока файла данных. Вход: поместите имя файла
на стек калькулятора, установите 23773 и 23817 и поместите в
23782 номер первого блока файла. Выход: если файл найден, то бу-
дет считан описатель последнего или первого блока в зависимости
от 23817 и обнулен аккумулятор и установлен флаг Z; иначе флаг Z
будет сброшен, а в аккумуляторе будет байт из 23817.
8667 LD A,10 ;поиск файла ведем по 10 байтам
LD (23814),A
CALL 7344 ;установка имени файла и поиск файла
PUSH AF ;сохранение результата поиска
CALL 1029 ;настройка на диск
POP AF ;восстановление результата поиска
JR NZ,8710 ;если файл не найден, то проверка режима файла
LD A,(23817);открываем файл для чтения ?
CP "R"
JR Z,8705 ;если да, то выход
8689 LD HL,23782 ;следующий блок
INC (HL)
CALL 7347 ;поиск блока
JR Z,8689 ;если блок найден, то следующий блок
LD HL,23782
DEC (HL) ;последний существующий блок
CALL 7347 ;определение его номера в каталоге
8705 CALL 5725 ;чтение его описателя
XOR A ;обнуление аккумулятора и установка флага Z
RET ;возврат
8710 LD A,(23817);открываем файл для чтения ?
CP "R"
RET NZ ;если да, то возврат
JP 985 ;сообщение NO FILE
────────────────────────────────────────────────────────────────
Адрес 8719. Проверка занятости потока. Вход: установите 23771.
Выход: в HL будет адрес элемента таблицы STRMS, отвечающего за
данный поток. Используется также с адреса 8741 (то же, что и
7242).
8719 LD A,(23771);берем номер потока
RST 32 ;берем относительный адрес описателя потока, к
DEFW #1727 ;которому подключен канал
LD A,B ;поток занят ?
OR C
JP NZ,8731 ;если да, то ошибка
RET ;возврат
8731 LD A,25 ;код ошибки бейсика PARAMETER ERROR
Внимание!!! Лучше выдавать сообщение INVALID STREAM.
LD (23610),A
LD HL,10244 ;адрес сообщения STREAM OPENED
LD A,10 ;код ошибки TR-DOS - 10
8741 JP 7242 ;обработка ошибки
────────────────────────────────────────────────────────────────
Адрес 8744. Обработка ошибки NOT DISC FILE.
8744 LD A,11 ;код ошибки - 11
LD HL,10258;адрес сообщения NOT DISC FILE
JR 8741 ;обработка ошибки
────────────────────────────────────────────────────────────────
Адрес 8751. Инициализация признаков файла произвольного доступа.
Установите 23767 и откройте канал файла данных. Подпрограмма по-
мещает в A 127.
8751 PUSH HL ;сохранение HL
LD C,32 ;берем адрес 32-го байта описателя канала
RST 40
LD A,(23767);установка длины записи
LD (HL),A
INC HL
XOR A
LD (HL),A ;адресация от начала записи - 0
INC HL
LD (HL),A ;будет приниматься номер записи
INC HL
LD (HL),A ;сектор переписывать
LD A,127 ;загрузка аккумулятора
POP HL ;восстановление HL
RET ;возврат
────────────────────────────────────────────────────────────────
Адрес 8770. Создание описателя канала для файла данных и подклю-
чение к нему потока. Установите 23771.
8770 PUSH AF ;сохранение результата поиска файла
CALL 8719 ;берем адрес элемента таблицы STRMS, отвечающего за поток
EX DE,HL ;сохранение его
LD HL,(23635);вычисление относительного адреса нового
LD BC,(23631);описателя канала
SBC HL,BC
EX DE,HL ;восстановление адреса элемента таблицы STRMS
LD (HL),E ;установка относительного адреса описателя
INC HL ;канала
LD (HL),D
CALL 8822 ;создание описателя канала
LD A,(23817) ;берем способ открытия файла
CP 165 ;это RND ?
CALL Z,8751 ;если да, то инициализация признаков файла произвольного
;доступа
JR Z,8811 ;и установка признака способа открытия файла
LD A,(23817) ;берем способ открытия файла
CP "R" ;это R ?
LD A,255 ;если да, то признак способа открытия файла -
JR NZ,8811 ;255
XOR A ;иначе это 0
8811 LD (HL),A ;установка признака способа открытия файла
POP AF
JP 8816
8816 PUSH AF
LD BC,20 ;берем адрес фрагмента текста в описателе
ADD HL,BC ;канала минус 1
PUSH HL ;сохраняем его
CALL 9251 ;вычисление адреса текущего сектора файла на диске
POP HL ;восстановление адреса фрагмента текста минус 1
INC HL
LD B,1 ;загружать 1 сектоp
POP AF ;восстановление результата поиска файла
OR A ;был создан новый файл ?
PUSH AF ;сохранение результата проверки
CALL NZ,7757 ;если был создан новый файл, то запись сектора
POP AF ;сохранение результата проверки
CALL Z,7741 ;если файл существовал, то загрузка файла
RET ;возврат
────────────────────────────────────────────────────────────────
Адрес 8840. Создание нулевого блока файла данных.
8840 LD HL,(23767);сохранение 23767
PUSH HL
LD HL,8192 ;блок 0
LD (23767),HL
CALL 8858 ;создание блока
POP HL ;восстановление 23767
LD (23767),HL
RET ;возврат
────────────────────────────────────────────────────────────────
Адрес 8858. Создание блока файла данных. Установите 23767 и
23771, 23773 и 23781.
8858 LD HL,4096 ;длина блока - 4096 байтов
LD (23769),HL
CALL 6852 ;проверка наличия свободного места на диске
CAL 7001 ;запись файла
LD HL,0 ;заполнено 0 байтов
LD (23784),HL
CALL 5739 ;замена описателя блока
JP 7747 ;перезапись сектора с описателем и возврат
Внимание!!! После записи сектора надо снова открыть канал файла
данных, так как при ошибке открывается поток 0.
────────────────────────────────────────────────────────────────
Адрес 8882. Создание описателя канала и открытие потока.
8882 LD HL,(23635);открытие потока
DEC HL
LD (23633),HL
PUSH HL ;сохранение адреса описателя канала
LD BC,292 ;его длина - 292 байта
CALL 7730 ;создание области для описателя канала
LD A,0 ;заполнять область нулями
LD B,0 ;длина области - 256 байтов
8900 LD (DE),A ;очистка байта
DEC DE ;следующий адрес
DJNZ 8900 ;повтор до конца
POP HL ;восстановление адреса описателя канала
PUSH HL ;и снова сохранение
LD DE,15630 ;адрес подпрогpаммы вывода в канал
LD (HL),E
INC HL
LD (HL),D
INC HL
LD DE,15622 ;адрес подпрограммы ввода из канала
LD (HL),E
INC HL
LD (HL),D
INC HL
LD (HL),"D" ;имя канала - "D"
INC HL ;пропуск четырех байтов
INC HL
INC HL
INC HL
INC HL
LD (HL),36 ;байт 36
INC HL
LD (HL),1 ;байт 1
INC HL
LD A,(23798) ;номер дисковода
LD (HL),A
INC HL
LD A,(23838) ;номер последнего блока файла
LD (HL),A
INC HL
LD A,(23817) ;файл открывается для чтения ?
CP "R"
LD (HL),0 ;если да, то пройдено 0 байтов
JR Z,8956 ;иначе количество пройденных байтов берем из
LD A,(23784) ;поля длины записанной части файла
LD (HL),A
8956 INC HL
LD (HL),B
JR Z,8964
LD A,(23785)
LD (HL),A
8964 INC HL
EX DE,HL ;сохранение адреса 15-го байта описателя канала
POP HL ;восстановление адреса описателя канала
PUSH DE
LD DE,16 ;адрес 16-го байта описателя канала
ADD HL,DE
EX DE,HL
LD HL,23773 ;установка описателя файла
LD BC,16
LDIR
POP HL ;восстановление адреса 15-го байта описателя канала
RET ;возврат
────────────────────────────────────────────────────────────────
Адpес 8983. Вычисление адреса текущего символа файла данных в
описателе канала. Откройте поток, связанный с файлом данных. На
выходе адрес символа будет в HL.
8989 LD C,13 ;адрес 13-го байта описателя канала
RST 40
LD C,(HL);берем номер текущего символа в текущем секторе файла
RST 40 ;вычисление смещения до символа
LD BC,36 ;текст начинается с 36-го байта описателя канала
ADD HL,BC;вычисление адреса символа
RET ;возврат
────────────────────────────────────────────────────────────────
Адрес 8993. Вычисление адреса фрагмента текста в описателе кана-
ла. Откройте поток, связанный с файлом данных. Используется так-
же с адреса 8995 (вычисление адреса байта в описателе текущего
канала; откройте канал и поместите номер байта в C; на выходе в
HL будет адрес байта).
8993 LD C,36 ;текст начинается с 36-го байта
8995 LD B,0 ;перевод номера байта в 2-х байтный формат
LD HL,(23633);берем адрес описателя текущего канала
ADD HL,BC ;вычисление адреса байта
RET ;возврат
────────────────────────────────────────────────────────────────
Адрес 9002. Проверка достижения конца сектора в описателе кана-
ла. Откройте поток, связанный с файлом данных. При достижении
конца сектора будет загружен следующий. Если достигнут конец
блока, а следующий отсутствует, то он будет создан.
9002 LD C,13 ;адрес 13-го байта описателя канала
RST 40
INC (HL) ;следующий байт
RET NZ ;если не конец сектора, то возврат
PUSH HL ;сохранение адреса 13-го байта описателя канала
CALL 9283 ;установка дисковода
CALL 9212 ;запись текущего сектора
POP HL ;восстановление адреса 13-го байта описателя канала
INC HL ;14-ый байт
INC (HL) ;следующий сектор
PUSH HL ;сохранение адреса 14-го байта описателя канала
CALL 9240 ;загрузка сектора
POP HL ;восстановление адреса 14-го байта описателя канала
LD A,16 ;в блоке 16 секторов
CP (HL) ;конец блока ?
RET NZ ;если нет, то возврат
PUSH HL ;сохранение адреса 14-го байта описателя канала
LD C,15 ;15-ый байт
RST 40
LD A,(HL) ;файл прямого доступа ?
CP 127
POP HL ;восстановление адреса 14-го байта описателя канала
JR Z,9048 ;если файл прямого доступа, то проверка наличия следующего
;блока
LD HL,(23633);берем адрес описателя канала
CALL 9953 ;запись описателя блока
LD C,14 ;14-ый байт
RST 40
JP 9081 ;создание следующего блока файла
9048 CALL 9167 ;поиск следующего блока файла
PUSH AF ;сохранение результата поиска
CALL Z,9240 ;если блок найден, то загрузка сектора из блока
LD C,14 ;14-ый байт
RST 40
POP AF ;восстановление результата поиска блока
CALL NZ,9072 ;если блок не был найден, то создание его
RET ;возврат
────────────────────────────────────────────────────────────────
Адрес 9063. Помещение в D числа 32, в E - содержимого 25-го бай-
та описателя канала и обнуление байта по адресу, помещенному в
HL. Откройте нужный канал.
9063 LD (HL),0;обнуление байта
LD C,25 ;берем адрес 25-го байта описателя канала
RST 40
LD D,32 ;помещение в регистр D числа 32
LD E,(HL);помещение в E числа из 32-го байта описателя канала
RET ;возврат
────────────────────────────────────────────────────────────────
Адрес 9072. Создание блока файла данных. Откройте поток, связан-
ный с файлом данных.
9072 CALL 9063 ;берем номер создаваемого блока
LD (23767),DE;установка его
JR 9089 ;создание и возврат
────────────────────────────────────────────────────────────────
Адрес 9081. Cоздание блока файла данных. Откройте поток, связан-
ный с файлом данных, используется, также, с адреса 9089 (создание
блока файла данных; установите 23767 и 23771, 23773 и 23781).
9081 CALL 9063 ;берем номер текущего блока
INC E ;следующий блок
LD (23767),DE;установка номера блока
9089 CALL 8858 ;создание блока
CALL 10608 ;удаление буфера
Внимание!!! Если выполняется команда CAT# или LIST#, то буфеp
удалять нельзя.
LD C,16 ;берем адрес 16-го байта описателя канала
RST 40
EX DE,HL ;перенос его в DE
LD HL,23773 ;перенос описателя блока в описатель канала
LD BC,16
LDIR
LD C,12 ;12-ый байт
RST 40
LD A,(23838);установка номера блока в каталоге
LD (HL),A
RET ;возврат
────────────────────────────────────────────────────────────────
Адрес 9115. Проверка достижения конца сектора при чтении файла
данных. Откройте поток, связанный с файлом данных.
9115 LD C,13 ;адрес 16-го байта описателя канала
RST 40
INC (HL) ;следующий байт сектора
RET NZ ;если не конец сектора, то возврат
INC HL ;17-ый байт
INC (HL) ;следующий сектор
PUSH HL ;сохранение адреса 17-го байта описателя канала
CALL 9283 ;установка дисковода
LD C,35 ;35-ый байт
RST 40
LD A,(HL) ;это 0 ?
OR A
JR Z,9142 ;если да, то сектор не переписывать
POP HL ;восстановление адреса 17-го байта описателя канала
PUSH HL ;и снова сохранение его
DEC (HL) ;восстановление номера текущего сектора
CALL 9212 ;запись сектора
POP HL ;восстановление адреса 17-го байта описателя канала
PUSH HL ;и снова сохранение его
INC (HL) ;следующий сектор
9142 CALL 9240 ;загрузка сектора
POP HL ;восстановление адреса 17-го байта описателя канала
LD A,16 ;в блоке 16 секторов
CP (HL) ;конец блока ?
CALL NZ,9153;если да, то открытие следующего
RET ;возврат
────────────────────────────────────────────────────────────────
Адрес 9153. Открытие следующего блока файла данных. Откройте по-
ток, связанный с файлом данных, поместите в HL адрес 14-го байта
описателя канала и установите 23814.
9153 CALL 9167 ;поиск следующего блока файла данных
PUSH AF ;сохранение результата поиска
CALL 10608;удаление буфера
Внимание!!! Hадо проверять 23830, так как если выполняется ко-
манда CAT#, или LIST#, то буфер удалять нельзя.
POP AF ;восстановление результата поиска блока
JP NZ,9362;если блок не найден, то END OF FILE
JP 9240 ;загрузка сектора из блока
────────────────────────────────────────────────────────────────
Адрес 9167. Поиск следующего блока файла данных. Откройте поток,
связанный с файлом данных, поместите в HL адpес 14-го байта
описателя канала и установите 23814. Если блок найден, то флаг Z
будет включен, иначе выключен.
9167 LD (HL),0 ;номер текущего сектора - 0
LD C,25 ;25-ый байт описателя потока
RST 40
INC (HL) ;следующий блок
LD C,16 ;16-ый байт
RST 40
LD DE,23773 ;установка описателя блока
LD BC,16
LDIR
CALL 7347 ;поиск блока
Внимание!!! После поиска блока надо снова открывать поток, свя-
занный с файлом данных, так как при дисковых ошибках открывается
поток 0.
RET NZ ;если блок не найден, то возврат
CALL 5725 ;чтение описателя блока
LD C,16 ;перенос его в описатель канала
RST 40
EX DE,HL
LD HL,23773
LD BC,16
LDIR
LD C,12 ;12-ый байт
RST 40
LD A,(23838);установка номера блока в каталоге
LD (HL),A
XOR A ;установка флага Z
RET ;возврат
────────────────────────────────────────────────────────────────
Адрес 9188. Открытие блока. Номер блока в каталоге поместите в
A.
9188 CALL 5725 ;чтение описателя блока
Внимание!!! После чтения описателя надо снова открывать поток,
связанный с файлом данных, так как при дисковых ошибках открыва-
ется поток 0.
LD C,16 ;берем адрес 16-го байта описателя канала
RST 40
EX DE,HL ;переброска его в DE
LD HL,23773 ;перенос описателя блока в описатель канала
LD BC,16
LDIR
LD C,12 ;12-ый байт
RST 40
LD A,(23838);установка номера блока в каталоге
LD (HL),A
XOR A ;обнуление аккумулятора
RET ;возврат