| Code: ; Хамелеон-ДОС, версия 7.7 ; (c) Алексей Мамонтов, 1994
.Z80 aseg ORG 100H
MCONIN EQU 0F803H MF806 EQU 0F806H ; ввод байта MCOUT EQU 0F809H YFCA6 EQU 0FCA6H ; ???
YE043 EQU 0E043H ; ROM бейсика (похоже это вход в ROM-бейсик) YE14A EQU 0E14AH ; ROM бейсика TRANS EQU 0E11FH ; ROM бейсика (блок (DE) -> (HL) длиной BC) FILL_E EQU 0E12AH ; ROM бейсика (FILL блока длиной BC байтом из E) YE260 EQU 0E260H ; ROM бейсика (возможно это пауза) CMPDH EQU 0E425H ; ROM бейсика MSSG EQU 0E4A4H ; ROM бейсика PAUS_A EQU 0E5FBH ; ROM бейсика YE627 EQU 0E627H ; ROM бейсика YE6AA EQU 0E6AAH ; ROM бейсика YE6A3 EQU 0E6A3H ; ROM бейсика YEBD0 EQU 0EBD0H ; ROM бейсика YDD31 EQU 0DD31H ; ROM бейсика (запись файла на МГ-ленту) YDD94 EQU 0DD94H ; ROM бейсика (загрузка МГ-файла)
VG93 EQU 0E0H RG_UPR EQU 0E4H
RGCOM EQU VG93 ; регистр команд RGTRK EQU VG93+1 ; регистр дорожки RGSEC EQU VG93+2 ; регистр сектора RGDATA EQU VG93+3 ; регистр данных
CMDBUF EQU 0BE00H ; буфер ввода команд
NAME1 EQU 0BE8CH ; входное имя для МГ-файла (всего 6 букв) NAME2 EQU 0BE92H ; похоже, что это имя МГ-файла считанное с ленты BEGADR EQU 0BEA4H ; адрес начала МГ-файла (ROM-BIOS) ENDADR EQU 0BEA6H ; адрес конца МГ-файла (ROM-BIOS) YBEA9 EQU 0BEA9H ; адрес старта загруженного МГ-файла
D_PARM EQU 0BED0H ; область загрузки параметров всего диска ; далее следуют параметры диска:
DSKNAM EQU 0BED0H ; имя дискеты 10 символов (не 11) FR_SEC EQU 0BEDBH ; номер сектора первого свободного сектора на диске FR_TRK EQU 0BEDCH ; номер трека первого свободного сектора на диске CLOSED EQU 0BEDEH ; флаг зпрета DIR DISKRO EQU 0BEDFH ; флаг диск R/O
DIRBUF EQU 0BD00H ; буфер для работы с каталогом диска (256 байт)
YBE1E EQU 0BE1EH ; какой-то, похоже, неиспользуемый флаг RECORD EQU 0BE1FH ; сюда грузится каталоговая запись файла:
FNAME EQU 0BE1FH ; имя файла, 8 символов F_EXT EQU 0BE26H ; расширение, 3 символа F_ATTR EQU 0BE2AH ; атрибут файла: 0 - R/W, 1 - R/O, 2- SYS & R/O FF_SEC EQU 0BE2BH ; номер сектора на дорожке занимаемый первым сектором файла FF_TRK EQU 0BE2CH ; номер дорожки, где находится первый сектор файла F_BEGA EQU 0BE2DH ; начальный адрес файла в ОЗУ = адрес запуска F_NSEC EQU 0BE2FH ; длина файла в секторах
YB880 EQU 0B880H YBE38 EQU 0BE38H ; похоже флаг горячего старта YBE3A EQU 0BE3AH YBE40 EQU 0BE40H
STACK EQU 0BE80H
TRACK EQU 0BFB0H ; логический номер текущего трека (0...164) SECTOR EQU 0BFB1H ; номер текущего сектора (1-9) SIDE EQU 0BFB2H ; текущая сторона диска (0/1) FIZTRK EQU 0BFB3H ; физический номер дорожки для контроллера DISK EQU 0BFB4H ; номер текущего дисковода (1,2,3,4) EXEFLG EQU 0BFB5H ; если >0 запуск файлa, =0 нет запускa LENGTH EQU 0BFB6H ; число читаемых секторов (1-255) CURDSK EQU 0BFB7H ; используется при работе (диск к которому лезем) YBFB8 EQU 0BFB8H ; возможно это число секторов в треке (заготовка для DD)
JBFE8 EQU 0BFE8H ; здесь код C3 (команда JMP) YBFE9 EQU 0BFE9H ; здесь в ДОС адрес ABORT
JBFEB EQU 0BFEBH ; здесь код C3 (команда JMP) YBFEC EQU 0BFECH ; здесь AC6CD
JERROR EQU 0BEF0H ; здесь код C3 (сюда переход при ошибках дисковых операций) YBEF1 EQU 0BEF1H ; здесь в ДОС адрес ABORT
; ----------------------------------------------
.msg MACRO ADDR LD HL,ADDR CALL MSSG ENDM
; ----------------------------------------------
.msg_B MACRO SIZE LD B,SIZE CALL MSSG_B ENDM
; ----------------------------------------------
.emit MACRO SYM LD C,SYM CALL MCOUT ENDM
; ----------------------------------------------
.home MACRO ; процедура HOME XOR A ; она исп-ся 4 раза, лучше сделать п/п-му HOME LD (TRACK),A INC A LD (SECTOR),A ENDM
; ----------------------------------------------
INCLOC MACRO LOC LD A,(LOC) INC A LD (LOC),A ENDM
; ----------------------------------------------
.phase 0C000H
JP START
; ----------------------------------------------
SREAD: LD B,32 ; число попыток чтения сектора каталога AC005: DI PUSH HL CALL SREAD1 POP HL IN A,(RGCOM) AND 00011100B EI RET Z DEC B ; DJNZ JP NZ,AC005 JP ERROR
; ----------------------------------------------
SREAD1: LD A,(SECTOR) OUT (RGSEC),A JP SREAD2
; ----------------------------------------------
JP CMPDH ; для совместимости с прежними версиями
; ----------------------------------------------
SREAD2: LD C,0C0H LD A,(SIDE) OR A LD A,82H JP Z,JJJ_01 LD A,8AH JJJ_01: CALL EXEC JP RD_LOO ; && перенести сюда процедуру RD_LOO
; ----------------------------------------------
defb 255,255,255,255
; ----------------------------------------------
SWRITE: LD B,32 ; число попыток записи AC03C: DI PUSH HL CALL SWRIT1 POP HL IN A,(RGCOM) AND 01111100B EI RET Z JP AC105
; ----------------------------------------------
SWRIT1: LD A,(SECTOR) OUT (RGSEC),A
LD C,0C0H LD A,(SIDE) OR A LD A,0A2H JP Z,AC05D LD A,0AAH AC05D: ; физическая запись сектора CALL EXEC WR_LOO: IN A,(RG_UPR) AND C JP Z,WR_LOO LD A,(HL) OUT (RGDATA),A INC HL JP P,WR_LOO RET
; ----------------------------------------------
PODGOT: ; подготовка дисковых операций PUSH HL ; установка головки на требуемую дорожку PUSH BC ; в HL куда грузить LD C,10 LD HL,CURDSK LD A,(DISK) CP (HL) JP Z,AC080 LD (HL),A AC07D: CALL SELDSK AC080: LD A,(TRACK) OR A ; CY=0 RRA LD (FIZTRK),A LD A,0 RLA LD (SIDE),A OR A LD A,(HL) LD B,00001100B JP NZ,AC097 ; если сторона 1 LD B,00011100B ; бит стороны в контроллере инвертированный AC097: OR B LD B,A INC HL INC HL LD A,(HL) OR A JP Z,AC63D AC0A0: LD A,B XOR 01000000B CALL AC656 JP AC632 ; && перенести сюда процедуру AC632
; ----------------------------------------------
defb 0
; ----------------------------------------------
LDNSEC: CALL PODGOT ; загрузить LENGTH секторов на AC0AD: CALL SREAD LD A,(LENGTH) DEC A RET Z LD (LENGTH),A CALL AC0C1 JP C,AC0AD JP LDNSEC
; ----------------------------------------------
AC0C1: LD BC,100H ; Выход: CY ADD HL,BC PUSH HL LD HL,SECTOR LD A,(YBFB8) INC (HL) CP (HL) JP NC,AC0F7 LD (HL),1 ; первый сектор трека: SECTOR= 1 DEC HL ; теперь HL указывет на TRACK LD A,(HL) CP 164 ; превышен последний трек ? JP AC0F3 ; && перенести сюда процедуру AC0F3
; ----------------------------------------------
defb 255,255
; ----------------------------------------------
WRNSEC: CALL PODGOT AC0DF: CALL SWRITE LD A,(LENGTH) DEC A RET Z LD (LENGTH),A CALL AC0C1 JP C,AC0DF JP WRNSEC
; ----------------------------------------------
AC0F3: JP NC,ERROR INC (HL) AC0F7: CCF POP HL RET
; ----------------------------------------------
AC0FA: CALL EXEC CALL READY IN A,(RGCOM) AND 00011000B RET
; ----------------------------------------------
AC105: DEC B JP NZ,AC03C ; DJNZ JP ERROR
; ----------------------------------------------
defb 255,255
; ----------------------------------------------
RD_DIR: CALL PODGOT ; читаем сектор каталога AC111: PUSH HL LD HL,DIRBUF CALL SREAD POP HL RET
; ----------------------------------------------
WR_DIR: PUSH HL ; запись сектора каталога LD HL,DIRBUF CALL PODGOT CALL SWRITE POP HL RET
; ----------------------------------------------
FIND: ; поиск файла в каталоге .home ; если файл найден, то загрузка пар-ров файла в область RECORD FNLOO1: CALL RD_DIR LD HL,DIRBUF FNLOO2: PUSH HL PUSH DE CALL CMPSTR POP DE POP HL OR A RET Z CP 1 ; имена были равны? JP Z,AC17F ; если равны, на загрузку пар-ров файла в область RECORD
LD BC,17 ; шаг каталоговых записей ADD HL,BC ; к следующей каталоговой записи в DIR-буфере LD A,L CP 0FFH ; была последняя запись сектора ? (кстати, короче INC A) JP NZ,FNLOO2 INCLOC SECTOR ; на следующий сектор CP 10 ; был последний сектор трека ? JP C,FNLOO1 ; если был не последний сектор RET_A2: LD A,2 RET
; ----------------------------------------------
CMPSTR: LD A,(HL) ; Сравнение двух имён длиной 11 символов (всез значащие) OR A ; Выход: A=1, если строки сравнились O'KAY RET Z ; A=2, если строки неодинаковые LD C,11 CMPLOO: LD A,(DE) ; сравнение строк по (HL) и (DE) длиной из C CP (HL) JP NZ,RET_A2 INC HL INC DE DEC C JP RETZA1 ; && перенести сюда процедуру RETZA1
; ----------------------------------------------
defb 0
; ----------------------------------------------
LD A,E ; ?? бредятина CP 0FFH JP Z,65CH CP B JP C,0F065H JP 0F168H
; ----------------------------------------------
RETZA1: JP NZ,CMPLOO LD A,1 RET
; ----------------------------------------------
AC17F: EX DE,HL ; DE= откуда LD HL,RECORD ; куда LD BC,17 ; сколько (это длина каталоговой записи) CALL TRANS LD A,1 RET
; ----------------------------------------------
LOAD: LD DE,FNAME AC18F: CALL FIND CP 1 RET NZ ; если такого файла нет CALL PODG_W ; на выходе HL= адрес начала блока CALL LDNSEC LD HL,(F_BEGA) CALL CHKEXE ; проверить атрибут запуска файла RET Z POP AF JP (HL)
; ----------------------------------------------
PODG_W: LD A,(FF_SEC) ; подготовка к записи файла LD (SECTOR),A LD A,(FF_TRK) LD (TRACK),A LD A,(F_NSEC) LD (LENGTH),A LD HL,(F_BEGA) RET
; ----------------------------------------------
@C1BA: RDDPRM: ; считать параметры всего диска в область D_PARM .home CALL RD_DIR
LD HL,D_PARM ; куда LD DE,DIRBUF ; откуда LD BC,16 ; сколько JP TRANS
; ----------------------------------------------
SAVE: ; запись целого файла CALL RDDPRM ; читаем общие параметры диска в D_PARM LD A,(DISKRO) OR A RET NZ ; если диск R/O
LD DE,FNAME ; проверяем есть ли уже такой файл CALL FIND ; на выходе HL указывает на запись в DIRBUF OR A RET NZ ; если такой файл уже есть ; HL указывает на конец списка файлов в DIRBUF LD A,(FR_SEC) LD (FF_SEC),A ; пишем файл на DISK TOP
LD A,(FR_TRK) LD (FF_TRK),A
XOR A LD (F_ATTR),A ; атрибут файла R/W
; HL откуда, указывает на конец списка файлов в DIRBUF LD DE,FNAME ; куда LD BC,17 ; сколько (длина каталоговой записи) CALL TRANS ; копирует из FNAME в DIRBUF на место записи
CALL WR_DIR ; обновляем сектор каталога (куда добавлена нов.запись) CALL PODG_W CALL WRNSEC ; пишем сам файл
LD A,(SECTOR) INC A CP 10 ; был последний сектор ? JP Z,AC231 ; если ДА
LD (FR_SEC),A ; ставим новый DISK TOP
LD A,(TRACK) AC212: LD (FR_TRK),A ; ставим новый DISK TOP
.home ; читаем первый сектор и пишем его с новыми параметрами CALL RD_DIR
LD HL,DIRBUF ; куда LD DE,D_PARM ; откуда LD BC,16 ; сколько CALL TRANS
CALL WR_DIR ; пишем обновлённый первый сектор XOR A RET
; ----------------------------------------------
AC231: LD A,1 ; переход на следующий трек при записи LD (FR_SEC),A LD A,(TRACK) CP 164 ; последний трек ? CALL Z,WRFSEC ; если ДА, то на запись N сектора указателя DISK TOP и RET INC A JP AC212 ; на чтение первого сектора и запись его с новыми параметрами
; ----------------------------------------------
MSSG_B: .emit (HL) ; вывод Z-строки длиной в B-символов INC HL DEC B ; поменяв на JP NZ можно использовать DJNZ RET Z JP MSSG_B
; ----------------------------------------------
TDNAME: defb 'ИМЯ ДИСКА: ',0
; ----------------------------------------------
XDIR: ; вывод каталога диска CALL RDDPRM ; читаем общие параметры диска в D_PARM LD A,(CLOSED) OR A RET NZ
.msg TDNAME ; выводим текст 'ИМЯ ДИСКА: ' LD HL,DSKNAM ; выводим само имя дискеты .msg_B 10 CALL CR ; на начало следующей строки LD HL,DIRBUF +17 ; начало списка файлов в 1-м секторе (первые 17 байт - пар-ры диска) DIRLOO: LD A,(HL) OR A RET Z CALL AC2BF CP 0FFH CALL Z,AC2AE CP 10 RET Z LD A,E CP 1 JP Z,DIRLOO CALL SPACE .emit ':' CALL SPACE AC294: LD A,(HL) OR A RET Z CALL AC2BF CP 0FFH CALL Z,AC2AE CP 10 RET Z LD A,E CP 1 JP Z,AC294 CALL CR JP DIRLOO
; ----------------------------------------------
AC2AE: INCLOC SECTOR CP 10 ; был последний сектор трека ? RET Z CALL AC111 LD HL,DIRBUF RET
; ----------------------------------------------
AC2BF: LD A,(HL) CP 1 JP Z,AC2EA PUSH HL LD BC,11 ADD HL,BC LD A,(HL) POP HL CP 2 JP NC,AC2EA
PUSH HL .msg_B 8 .emit '.' .msg_B 3 POP HL
LD E,0 HLADD17: ; переходим к следующей записи в каталоге LD BC,17 ; шаг каталоговых записей ADD HL,BC LD A,L RET
; ----------------------------------------------
AC2EA: LD E,1 JP HLADD17
; ----------------------------------------------
SEL_A: XOR A LD (DISK),A LD (CURDSK),A SELDSK: XOR A ; установка диска CURDSK и проверка готовности OUT (RG_UPR),A LD A,(CURDSK) LD B,00011100B ; не понял, зачем грузить маску в рег.B OR B OUT (RG_UPR),A LD A,0D8H CALL EXEC AC306: IN A,(RGCOM) RRA JP C,AC306 LD A,8 CALL EXEC CALL READY CALL YE260 JP YE260
; ----------------------------------------------
READY: IN A,(RGCOM) ; ждём готовности RLA JP C,READY READY1: IN A,(RGCOM) RRA JP C,READY1 RET
; ----------------------------------------------
AC327: LD DE,TCMND LD A,D ; A= 0C3H LD (EXEFLG),A ; не 0, запуск файлa разрешён JP AC18F
; ----------------------------------------------
TCMND: defb 'COMMAND COM' ; имя автостартующего при старте DOS файла
TITR: defb 'CHAMELEON-DOS 7.7',13 defb '(C)MASKSOFT&144KБ',13,0
; ----------------------------------------------
AC361: XOR A LD (YBE38),A ; похоже флаг горячего старта CALL YEBD0 ; возможно инициализация чего-то CCP: ; вход в командный процессор DOS LD SP,STACK .msg TITR CALL SEL_A CALL V_INIT ; инициализация векторов ошибок CALL RDDPRM ; читаем общие параметры диска в D_PARM CALL AC327 ABORT: LD SP,STACK CALL V_INIT ; инициализация векторов ошибок CALL RDDPRM ; читаем общие параметры диска в D_PARM CALL CR ; на начало следующей строки LD A,(DISK) ADD A,'A'
.emit A .emit ':' .emit '>'
LD HL,CMDBUF ; буфер ввода команд PUSH HL LD BC,15 ; длина блока (здесь длина ком.строки) LD E,20H ; чем заполнять CALL FILL_E POP HL ; HL буфер ввода команд CALL MF806 ; первое слово можно ввести ключевой клавишей CP 7 ; клавиша <F0> JP Z,ZDIR CP 12H JP Z,ZSAVE CP 15H ; клавиша <F1> JP Z,BLOAD CP 16H ; клавиша <F3> JP Z,RENAME CP 14H ; клавиша <F4> JP Z,ERA CP 13H ; клавиша <F5> JP Z,TYPE CP 6 ; клавиша <П/Д> JP Z,RUNCPM CP 0BH JP Z,YE14A CP 0CH JP Z,CMD_0C LD (HL),A CALL COUTA INC HL AC3DE: CALL MCONIN CP 7FH JP Z,ZABOJ CP 13 JP Z,AC40A LD (HL),A CALL COUTA LD A,L CP 15 + low CMDBUF JP NC,AC3DE INC HL JP AC3DE
; ----------------------------------------------
ZABOJ: LD A,L OR A JP Z,AC3DE DEC HL .emit 7FH LD A,20H LD (HL),A JP AC3DE
; ----------------------------------------------
AC40A: DEC HL LD A,(HL) CP ':' JP NZ,AC420 DEC HL LD A,(HL) SUB 'A' CP 4 JP NC,ABORT LD (DISK),A JP ABORT
; ----------------------------------------------
AC420: LD HL,FNAME ; куда LD DE,CMDBUF ; откуда LD BC,8 ; сколько CALL TRANS
LD (HL),'C' ; короче на 5 байтов CALL MOVCOM INC HL LD (HL),'O' INC HL LD (HL),'M'
LD A,1 LD (EXEFLG),A
CALL LOAD JP NO_FND ; && перенести сюда процедуру NO_FND
; ----------------------------------------------
ZDIR: .msg TDIR CALL WAITWK ; ждём нажатия <ВК> CALL XDIR JP JBFE8
; ----------------------------------------------
WAITWK: CALL MCONIN CP 13 JP Z,CR ; если <ВК>, то на начало следующей строки JP WAITWK
; ----------------------------------------------
BLOAD: .msg TLOAD CALL WAITWK
LD HL,NAME1 LD BC,6 ; длина заполняемого блока LD E,20H ; чем заполнять CALL FILL_E
CALL YDD94 ; загрузка МГ-файла LD HL,(YBEA9) JP (HL)
; ----------------------------------------------
ASCHEX: SUB 30H ; из ASCII получить HEX-число CP 10H RET C SUB 7 RET
; ----------------------------------------------
IS_HEX: CP 30H JP C,RETCY1 CP 3AH JP C,RETCY0 CP 'A' JP C,RETCY1 CP 'G' JP NC,RETCY1 RETCY0: OR A RET
; ----------------------------------------------
RETCY1: SCF RET
; ----------------------------------------------
GETHEX: PUSH HL ; считывает из F806 и выводит HEX-число CALL MF806 CALL IS_HEX JP C,SYNTAX LD H,A CALL COUTA CALL MF806 CALL IS_HEX JP C,SYNTAX LD L,A CALL COUTA LD A,L CALL ASCHEX LD B,A LD A,H CALL ASCHEX RLCA RLCA RLCA RLCA OR B POP HL RET
; ----------------------------------------------
GET_HL: CALL GETHEX LD H,A CALL GETHEX LD L,A RET
; ----------------------------------------------
COUTA: LD C,A JP MCOUT
; ----------------------------------------------
GETNAM: LD HL,FNAME ; считывает имя файла из п/п-ммы F806 на FNAME AC4CF: CALL MF806 CP 13H JP Z,SYNTAX LD (HL),A CALL COUTA LD A,L CP (low FNAME) +7 ; 26H INC HL JP C,AC4CF ; если введено не более 8 символов .emit '.' AC4E7: CALL MF806 CP 13H JP Z,SYNTAX LD (HL),A CALL COUTA INC HL LD A,L CP (low FNAME) +11 ; 2AH RET NC ; если был последний 12-тый символ в имени JP AC4E7
; ----------------------------------------------
SPACE: LD C,20H JP MCOUT
; ----------------------------------------------
CR: LD C,13 ; на начало следующей строки JP MCOUT
; ----------------------------------------------
ZSAVE: .msg TSAVE CALL GETNAM ; считывает имя файла из п/п-ммы F806 CALL SPACE CALL GET_HL PUSH HL LD (F_BEGA),HL CALL SPACE CALL GET_HL EX DE,HL POP HL CALL GET_NS ; расчёт длины файла в секторах. Блок: HL...DE CALL WAITWK CALL SAVE OR A JP NZ,NOSAVE JP JBFE8
; ----------------------------------------------
ERROR: .msg TEROR JP JERROR
; ----------------------------------------------
NO_FND: LD HL,TNOFIL MSGEXI: CALL MSSG JP JBFE8
; ----------------------------------------------
NOSAVE: LD HL,TNOSAV JP MSGEXI
; ----------------------------------------------
SYNTAX: LD HL,TSNERR ; синтаксическая ошибка в команде JP MSGEXI
; ----------------------------------------------
TEROR: defb 13,'*ERORR I/O*',13,0 TDIR: defb 'DIR',0 TLOAD: defb 'LOAD ',0 TSAVE: defb 'SAVE ',0 TERA: defb 'ERA ',0 TREN: defb 'REN ',0 TNOFIL: defb 13,'*NO FILE*',0 TNOSAV: defb 13,'*NO SAVE*',0 TTYPE: defb 'TYPE ',0 TSNERR: defb 13,'*SN.ERROR*',0
; ----------------------------------------------
ERA: .msg TERA CALL GETNAM ; считывает имя файла из п/п-ммы F806 CALL WAITWK LD DE,FNAME CALL FIND CP 1 ; короче DEC A JP NZ,NO_FND EX DE,HL ; DE указывает на следующую запись файла в DIRBUF LD BC,17 ; шаг каталоговых записей CALL DSUB_B PUSH HL ; HL указывает на начало каталоговой записи LD BC,11 ; смещение в каталоговой записи до атрибута ADD HL,BC LD A,(HL) ; A= атрибут файла POP HL ; HL указывает на начало каталоговой записи CP 1 JP NC,NO_FND ; если файл R/O LD A,1 ; короче LD (HL),1 LD (HL),A ; удаляем файл, записав 1 первым символом имени CALL WR_DIR ; пишем обновлённый первый сектор JP JBFE8
; ----------------------------------------------
RENAME: .msg TREN CALL GETNAM ; считывает имя файла из п/п-ммы F806
LD HL,CMDBUF LD DE,FNAME LD BC,11 CALL TRANS .emit '=' CALL GETNAM ; считывает имя файла из п/п-ммы F806
LD DE,FNAME CALL FIND CP 1 JP NZ,NO_FND EX DE,HL LD BC,17 ; шаг каталоговых записей CALL DSUB_B ; вернём указатель HL на найденный файл в DIRBUF LD DE,CMDBUF ; откуда LD BC,11 ; сколько CALL TRANS ; скопируем новое имя в каталоговую запись в DIRBUF CALL WR_DIR ; обновляем сектор каталога JP JBFE8
; ----------------------------------------------
@C60F: DSUB_B: LD A,L ; вычитание HL минус BC SUB C LD L,A LD A,H SBC A,B LD H,A RET
; ----------------------------------------------
TYPE: .msg TTYPE LD (EXEFLG),A ; A=0 запуск файлa запрещён CALL GETNAM ; считывает имя файла из п/п-ммы F806 CALL WAITWK CALL LOAD DEC A JP NZ,NO_FND LD HL,(F_BEGA) JP MSGEXI
; ----------------------------------------------
AC632: LD (HL),1 JP NZ,AC64C DEC HL ; HL указывает на SECTOR LD (HL),9 POP BC POP HL ; в HL куда грузить RET
; ----------------------------------------------
AC63D: LD A,B CALL AC656 JP NZ,AC0A0 LD (HL),0 DEC HL LD (HL),10H POP BC POP HL RET
; ----------------------------------------------
AC64C: DEC (HL) DEC HL DEC HL DEC C JP NZ,AC07D JP ERROR
; ----------------------------------------------
AC656: OUT (RG_UPR),A CALL PAUS15 LD A,(FIZTRK) OUT (RGDATA),A ; ?? а не должно тут быть RGTRK LD A,1CH ; команда для ВГ93 JP AC0FA ; && перенести сюда процедуру AC0FA
; ----------------------------------------------
START: OUT (0),A LD SP,0BF99H ; начальный стек
LD A,88H OUT (0C3H),A
LD A,8AH OUT (0D3H),A
LD A,2 OUT (0C2H),A
LD A,8FH OUT (0C1H),A
LD A,0BFH OUT (0D0H),A
IN A,(0D1H) CP 0FBH JP NZ,AC696
LD HL,0000 AC688: LD A,(HL) CPL LD (HL),A CP (HL) JP NZ,YE043
INC HL LD A,H CP 0C0H JP NZ,AC688 AC696: CALL AC786
LD A,0DFH OUT (0D0H),A
IN A,(0D1H) CP 7FH JP Z,AC6AA
LD HL,AC6CD LD (YBFEC),HL
AC6AA: LD A,0C3H LD (JBFEB),A
LD HL,0B000H LD BC,0EEFH LD E,0 CALL FILL_E
LD HL,YB880 LD (YBE40),HL
LD A,1 LD (YBE3A),A
LD A,255 LD (YBE1E),A
JP 0E0F5H
; ----------------------------------------------
AC6CD: LD HL,DIRBUF ; откуда LD DE,80C0H ; куда LD BC,100H ; сколько PUSH HL PUSH DE PUSH BC CALL TRANS CALL AC777 POP BC POP HL POP DE CALL TRANS
JP AC361
; ----------------------------------------------
defb 0
; ----------------------------------------------
@C6E9: GET_NS: PUSH HL ; расчёт длины файла в секторах. Блок: HL...DE PUSH DE ; заносит рассчитанную длину в RECORD LD A,1 LD (F_NSEC),A ; начиная с одного сектора CALL GNSLOO ; здесь п/п-мма не нужна (теряем байт) POP DE POP HL RET
; ----------------------------------------------
GNSLOO: LD BC,256 ADD HL,BC CALL CMPDH ; сравнение HL и DE (CMPDH) RET NC ; если достигнут или превышен конечный адрес
LD A,(F_NSEC) INC A LD (F_NSEC),A
JP GNSLOO
; ----------------------------------------------
@C708: RUNCPM: .home LD A,31 ; длина файла в секторах LD (LENGTH),A LD HL,9000H ; куда грузим CALL LDNSEC JP 0A600H
; ----------------------------------------------
AC71E: ; формирование имени DOS-файла из имени МГ-файла LD DE,NAME1 ; откуда JP FNFORM
; ----------------------------------------------
LD DE,NAME2 ; откуда FNFORM: LD HL,FNAME ; куда LD BC,6 ; сколько CALL TRANS LD (HL),20H INC HL LD (HL),20H INC HL MOVCOM: LD (HL),'C' INC HL LD (HL),'O' INC HL LD (HL),'M' RET
; ----------------------------------------------
AC73F: CALL AC71E ; формирование имени DOS-файла из имени МГ-файла
LD HL,(ENDADR) EX DE,HL LD HL,(BEGADR) ; адреса начала и конца блока в HL,DE LD (F_BEGA),HL ; готовим каталоговую запись в RECORD CALL GET_NS ; расчёт длины файла в секторах. Блок: HL...DE JP SAVE ; && перенести сюда процедуру SAVE
; ----------------------------------------------
AC752: ; загрузка и запуск COM-файла CALL AC71E ; формирование имени DOS-файла из имени МГ-файла XOR A LD (EXEFLG),A ; =0 запуск файлa запрещён JP LOAD
; ----------------------------------------------
V_INIT: LD A,0C3H ; инициализация векторов ошибок LD (JBFE8),A LD (JERROR),A LD (JBFEB),A
LD HL,ABORT LD (YBEF1),HL LD (YBFE9),HL
LD HL,CCP LD (YBFEC),HL
RET
; ----------------------------------------------
AC777: LD HL,80C0H ; запуск LD DE,YFCA6 LD BC,0EAH ; 234 дес CALL TRANS
JP 80D4H
; ----------------------------------------------
AC786: CP 0F7H RET NZ
LD HL,YB880 LD (YBE40),HL
LD C,33H CALL YE6AA
LD C,17H CALL YE6A3
JP YE627
; ----------------------------------------------
defb 80H
; ----------------------------------------------
; Входы в функции ДОС @C79D: JP PODGOT ; подготовка @C7A0: JP SREAD ; читать сетор @C7A3: JP SWRITE ; запись сектора @C7A6: JP LDNSEC ; считать LENGTH секторов @C7A9: JP WRNSEC ; записать LENGTH секторов @C7AC: JP FIND ; поиск файла и чтение его каталоговой записи @C7AF: JP LOAD ; загрузка файла @C7B2: JP SAVE ; запись файла @C7B5: JP XDIR ; вывод каталога диска @C7B8: JP ERA ; удаление файла @C7BB: JP RENAME ; переименование файла @C7BE: JP TYPE ; вывод текстового файла на экран @C7C1: JP ZSAVE ; запись файла с вводом командной строки @C7C4: JP GETHEX ; считать однобайтовое HEX-число @C7C7: JP GETNAM ; считывает имя файла из п/п-ммы F806 @C7CA: JP GET_HL ; считать двухбайтовое HEX-число @C7CD: JP AC752 @C7D0: JP AC73F
; ----------------------------------------------
CMD_0C: LD A,165 LD (TRACK),A CALL PODGOT JP AC361 ; && перенести сюда процедуру AC361
; ----------------------------------------------
CHKEXE: LD A,(EXEFLG) ; проверить атрибут запуска файла OR A ; Выход: флаг Z=1, если запуск файлa запрещён LD A,1 RET Z RET
; ----------------------------------------------
RD_LOO: IN A,(RG_UPR) ; физическое чтение сектора AND C JP Z,RD_LOO IN A,(RGDATA) RET M LD (HL),A INC HL JP RD_LOO
; ----------------------------------------------
EXEC: OUT (RGCOM),A PAUS15: LD A,15 JP PAUS_A
; ----------------------------------------------
defb 0
; ----------------------------------------------
WRFSEC: LD (FR_SEC),A ; записать N сектора указателя DISK TOP RET
; ----------------------------------------------
.dephase
END
| |