From b6c902f4f714d663a8149304fde596c0faa2fa29 Mon Sep 17 00:00:00 2001 From: Anatoliy Belyanskiy Date: Wed, 19 Jul 2023 01:18:08 +1000 Subject: [PATCH] refactoring --- DSS/DOS5.ASM | 413 ++++++++++++++++++++++++++++++++++-------------- DSS/DOS_FM.ASM | 5 +- DSS/build.txt | 2 +- DSS/defines.inc | 2 +- 4 files changed, 297 insertions(+), 125 deletions(-) diff --git a/DSS/DOS5.ASM b/DSS/DOS5.ASM index e2f6980..d62542b 100644 --- a/DSS/DOS5.ASM +++ b/DSS/DOS5.ASM @@ -150,33 +150,41 @@ DELETE: LD DE,MASKARE CALL LOADDIR CALL SEARCH RET C +; пометить запись как "удаленная" DELFILE: SET_PAGE_X DIRPAGE - LD (IX+_sFM.NAME),#E5 - LD E,(IX+_sFM.ST_CLUSTER) + LD (IX+_sFM.NAME),#E5 ; признак удаления файла + LD E,(IX+_sFM.ST_CLUSTER) ; № первого кластера LD D,(IX+_sFM.ST_CLUSTER+1) OUT (SLOT3),A LD A,E OR D - JR Z,SMALDEL -DEL01 EX DE,HL - CALL R_F_FAT - PUSH DE + JP Z,SAVEDIR ; сбросить кеш каталога на диск +DEL01 EX DE,HL ; hl=номер кластера + CALL R_F_FAT ; прочитать из кеша FAT-а номер след. кластера + PUSH DE ; номер след. кластера PUSH AF - LD DE,#0000 - CALL W_T_FAT + LD DE,#0000 ; номер кластера + CALL W_T_FAT ; записать в кеш FAT-а номер кластера POP AF POP DE JP NC,DEL01 CALL WR_FAT -SMALDEL CALL SAVEDIR - AND A - RET + JP SAVEDIR ; сбросить кеш каталога на диск +;///////////////////////////////////////////////////////////////////// +; Функция #10. Переименование файла. +; Глобальные символы * и ? в именах файлов не допускаются. +; +; вход: HL - указатель на старое имя файла +; DE - указатель на новое имя файла +; выход: A - код ошибки, если CF=1 +; ; INPUT: HL - "old_name.ext",#00 without simbols * ? ; DE - "new_name.ext",#00 without simbols * ? +;///////////////////////////////////////////////////////////////////// RENAME PUSH DE LD DE,MASKARE CALL MASK @@ -190,10 +198,10 @@ RENAME PUSH DE SCF RET Z PUSH DE - CALL LOADDIR + CALL LOADDIR ; прочитать список каталога ;LD A,#33 LD A,FAT_ATTR.NoSYSnoVolID - CALL ASEARCH + CALL ASEARCH ; поиск записи в списке диска POP HL RET C LD DE,MASKARE @@ -208,7 +216,7 @@ RENAME PUSH DE RET Z PUSH IX LD A,FAT_ATTR.NoSYSnoVolID - CALL ASEARCH + CALL ASEARCH ; поиск записи в списке диска POP IX LD A,DSS_Error.sys.FILE_EXISTS CCF @@ -222,14 +230,12 @@ RENAME PUSH DE LD BC,11 LDIR OUT (SLOT3),A - CALL SAVEDIR - AND A - RET + JP SAVEDIR ;R02 OPENATR: - LD (ACCESS),A - CALL GETWORD + LD (ACCESS),A ; раб. ячейка (здесь атрибут записи) + CALL GETWORD ; тест на допуст. имя и настр. на диск RET C LD HL,TMPNAME LD DE,MASKARE @@ -237,10 +243,23 @@ OPENATR: RET C LD A,FAT_ATTR.NoVolID CALL ASEARCH - JR NC,OPENAT + JR NC,OPENAT ; на поиск своб. дескриптора + ; запись не найдена RET ;R02 + +;///////////////////////////////////////////////////////////////////// +; Функция #11. Открытие файла. +; +; вход: HL - указатель на имя файла +; A - режим доступа: +; A=0 чтение/запись +; A=1 чтение +; A=2 запись +; выход: A - дескриптор файла, если CF=0 +; код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// OPEN_FN: _mSavePath OPEN: ;R08 @@ -529,6 +548,13 @@ NSEARCH: JR Z,SEARCH3.error JP SEARCH1 +;------------------------------------------------- +; Поиск записи каталога в списке каталога +; +; вход: a=атрибут записи +; выход: de'=индекс записи в списке каталога +; CF - каталог не найден +;------------------------------------------------- DSEARCH: LD A,FAT_ATTR.DIRECTORY CALL ASEARCH @@ -604,6 +630,10 @@ SEARCH4: SCF RET +;------------------------------------------------- +; Тест на допустимое имя и настроиться на диск. +; вход: hl=строка имени +;------------------------------------------------- GETWORD: LD DE,TMPNAME LD BC,#0DFF @@ -649,8 +679,8 @@ GETWORD: POP HL JP NC,GETWORD RET - -TMPNAME: DB ' ',#00 ; 12 пробелов и 0 +; Буфер имени 8.3 формата +TMPNAME: DZ ' ' ; 12 пробелов и 0 ;!TODO сделать для каждого драйва запоминание текущей дирректории, пока тут заглушка ; RestoreDIR: @@ -901,6 +931,12 @@ IT_DIR: LD E,(IX+_sFM.ST_CLUSTER) RET +;///////////////////////////////////////////////////////////////////// +; Функция #1E. Информация о текущем каталоге. +; +; вход: HL - буфер в памяти 256 байт +; выход: A - код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// CURRDIR: EX DE,HL LD HL,DIRSPEC CURDIR1 LD A,(HL) @@ -909,58 +945,67 @@ CURDIR1 LD A,(HL) JR NZ,CURDIR1 RET + +;------------------------------------------------- +; Прочитать список каталога +;------------------------------------------------- LOADDIR: XOR A LD H,A LD L,A LD IX,0 - LD B,A + LD B,A ; от начала файла CALL MOVE_FP SET_PAGE_X DIRPAGE PUSH AF ;!TEST no ldir + ; очистить кеш каталога ;LD HL,#C000 ;LD DE,#C001 ;LD BC,#3FFF ;LD (HL),L ;LDIR ; - LD A,(FatBuffer.DRIVE) - LD (IY+_sFM.DRIVE),A - LD D,(IY+_sFM.ST_CLUSTER) + LD A,(FatBuffer.DRIVE) ; номер диска + LD (IY+_sFM.DRIVE),A ; сохр. в дескриптор + LD D,(IY+_sFM.ST_CLUSTER) ; de=номер первого кластера LD E,(IY+_sFM.ST_CLUSTER+1) LD A,D OR E - JP Z,LROTDIR - LD HL,DIR - LD DE,#4000 - XOR A - CALL READ - LD (DIRSIZE),DE + JP Z,LROTDIR ; root ?? + LD HL,DIR ; куда + LD DE,#4000 ; сколько + XOR A ; дескриптор + CALL READ ; чтение из файла + LD (DIRSIZE),DE ; число прочит. байтов POP AF OUT (SLOT3),A AND A RET -LROTDIR LD HL,(FatBuffer.DIR_FRH) - LD IX,(FatBuffer.DIR_FRL) +LROTDIR LD HL,(FatBuffer.DIR_FRH) ; ст. разряд + LD IX,(FatBuffer.DIR_FRL) ; номер лог. сектора LD A,(FatBuffer.DIR_S_S) - LD B,32 + LD B,32 ; !HARDCODE размер root-каталога SUB B JR NC,RTD1 ADD A,B - LD B,A -RTD1 LD A,(FatBuffer.DRIVE) - LD DE,DIR - LD C,Dss.DRV.Read + LD B,A ; число секторов +RTD1 LD A,(FatBuffer.DRIVE) ; номер диска + LD DE,DIR ; буфер + LD C,Dss.DRV.Read ; чтение секторов RST ToDSS.DRV POP AF OUT (SLOT3),A AND A RET +;------------------------------------------------- +; Сбросить кеш каталога на диск. +; вход: iy=структура дескриптора +;------------------------------------------------- SAVEDIR XOR A LD HL,0 LD IX,0 @@ -1003,7 +1048,7 @@ RTD1S LD A,(FatBuffer.DRIVE) AND A RET -DIRSIZE: WORD 0 +DIRSIZE: WORD 0 ; размер списка каталога size_cash_directory ;!TEST ;BANK: @@ -1017,6 +1062,8 @@ DIRSIZE: WORD 0 ; RET ; + +; Массив лог. номеров банок расширения ДОС BANKTBL: BLOCK USING_MEMPAGES+1,#FF ;!TODO @@ -1073,11 +1120,20 @@ BANKTBL: BLOCK USING_MEMPAGES+1,#FF ;HANDTA BLOCK 32,0 -MASKARE: BLOCK 32,0 ;!HARDCODE почему 32? +MASKARE: BLOCK 8,0 ; имя файла + BLOCK 3,0 ; расш. + BLOCK 21,0 ; 11+21=32 +;------------------------------------------------- +; Преобразовать имя 8.3 -> 11 формат +; вход: hl = 8.3 имя +; de = буфер имени 11 симв. формата +; при ошибке CF - недоп. имя +; ; HL - MASK "file*.t??" ; DE - 11 bytes filename ; RET: C=2 FILE WITHOUT EXTENTION ; C=1 FILE WITH EXTENTION +;------------------------------------------------- MASK PUSH HL PUSH DE LD H,D @@ -1095,52 +1151,53 @@ MASK PUSH HL CP '!' MASKB LD A,DSS_Error.sys.INVALID_NAME RET C - LD BC,#0902 + LD BC,#0902 ; B - счетчик MASK1 LD A,(HL) CP '!' CCF RET NC CP '"' - JR Z,MASK7 + JR Z,MASK_ERR CP '*' JR Z,MASK3 CP '+' - JR Z,MASK7 + JR Z,MASK_ERR CP ',' - JR Z,MASK7 + JR Z,MASK_ERR CP '.' JR Z,MASK5 CP '/' - JR Z,MASK7 + JR Z,MASK_ERR CP ':' - JR Z,MASK7 + JR Z,MASK_ERR CP ';' - JR Z,MASK7 + JR Z,MASK_ERR CP '<' - JR Z,MASK7 + JR Z,MASK_ERR CP '=' - JR Z,MASK7 + JR Z,MASK_ERR CP '>' - JR Z,MASK7 + JR Z,MASK_ERR CP '[' - JR Z,MASK7 + JR Z,MASK_ERR CP '\' - JR Z,MASK7 + JR Z,MASK_ERR CP ']' - JR Z,MASK7 + JR Z,MASK_ERR CP '|' - JR Z,MASK7 + JR Z,MASK_ERR ; CP 'a' ;????? ; JR C,MASK2 ; CP '{' ; JR NC,MASK2 ; SUB #20 - CALL UPPER + CALL UPPER ; a..z -> A..Z MASK2 LD (DE),A INC HL INC DE DJNZ MASK1 -MASK7 LD A,DSS_Error.sys.INVALID_NAME +MASK_ERR: + LD A,DSS_Error.sys.INVALID_NAME SCF RET @@ -1177,6 +1234,7 @@ MASK4 LD (DE),A SCF RET +; a..z -> A..Z UPPER CP 'a' RET C CP '{' @@ -1203,6 +1261,19 @@ HGUPPER CP ' DEC A RET + +;///////////////////////////////////////////////////////////////////// +; Функция #21. Текущая дата и время. +; +; вход: нет +; выход: D - день +; E - месяц +; IX - год +; H - час +; L - минуты +; B - секунды +; C - день недели +;///////////////////////////////////////////////////////////////////// SYSTIME LD C,BIOS.CMOS_TEST RST ToBIOS JP C,NOCMOS @@ -1284,6 +1355,9 @@ GOODAGE POP AF AND A RET +; Чтение регистров CMOS +; вход: d=номер регистра + RCMOS LD C,BIOS.CMOS_RD RST ToBIOS ; INPUT : A - BCD @@ -1322,6 +1396,17 @@ NOCMOS2 LD C,0 AND A RET +;///////////////////////////////////////////////////////////////////// +; Функция #22. Установить текущую дату и время. +; +; вход: D - день +; E - месяц +; IX - год +; H - час +; L - минуты +; B - секунды +; выход: A - код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// SETTIME PUSH IX PUSH BC PUSH HL @@ -1373,7 +1458,9 @@ YR INC A AND A RET - +;!FIXIT переделать по доке на Даллас и заись в ячейки часов +; Запись регистров CMOS +; вход: d=номер регистра WCMOS CALL HEX2BCD LD C,BIOS.CMOS_WR RST ToBIOS @@ -1397,26 +1484,53 @@ H2B INC C OR B RET +; Дата по-умолчанию NC_DAY DW DAY*256+MONTH ;DAY/MONTH NC_HOUR DW #0000 ;HOUR/MINUTE NC_SEC DW #0001 ;SECOND/WEEKDAY NC_YEAR DW YEAR ;YEAR + +;///////////////////////////////////////////////////////////////////// +; Функция #17. Информация о дате и времени файла. +; +; вход: A - дескриптор файла +; выход: D - день +; E - месяц +; IX - год +; H - час +; L - минуты +; B - секунды +; A - код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// GET_D_T CALL SET_FM RET C - LD E,(IY+_sFM.TIME) - LD D,(IY+_sFM.TIME+1) - LD C,(IY+_sFM.DATE) - LD B,(IY+_sFM.DATE+1) - CALL RMKTIME + ; время/дату из структуры дескр. + LD E,(IY+_sFM.TIME) ; время + LD D,(IY+_sFM.TIME+1) ; + LD C,(IY+_sFM.DATE) ; дата + LD B,(IY+_sFM.DATE+1) ; + CALL RMKTIME ; раскодировать время/дату AND A RET +;///////////////////////////////////////////////////////////////////// +; Функция #18. Изменение даты и времени файла. +; +; вход: A - дескриптор файла +; D - день +; E - месяц +; IX - год +; H - час +; L - минуты +; B - секунды +; выход: A - код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// PUT_D_T PUSH AF - CALL MK_TIME - POP AF + CALL MK_TIME ; закодировать время/дату + POP AF ; дескриптор PUSH DE PUSH BC CALL SET_FM @@ -1427,10 +1541,20 @@ PUT_D_T PUSH AF LD (IY+_sFM.TIME+1),D LD (IY+_sFM.DATE),C LD (IY+_sFM.DATE+1),B - SET 7,(IY+_sFM.ACCESS_MODE) ;R06 + SET 7,(IY+_sFM.ACCESS_MODE) ;R06 ; уст. признак изменения файла AND A RET +;------------------------------------------------- +; Закодировать время/дату +; вход: de - день/месяц +; hl - часы/минуты +; b - секунды +; ix - год +; выход: de - время +; bc - месяц/день +; ix - год +; ;INPUT: D - DAY; E - MONTH ; H - HOUR; L - MINUTE ; B - SECOND (0...59) @@ -1438,6 +1562,7 @@ PUT_D_T PUSH AF ;OUTPUT: DE - hhhhhmmmmmmsssss h - hour, m - min, s - sec/2 ; BC - yyyyyyymmmmddddd y - year, m - month, d - day ; (1980-2108) +;------------------------------------------------- MK_TIME LD A,L RLCA RLCA @@ -1468,6 +1593,16 @@ MK_TIME LD A,L AND A RET +;------------------------------------------------- +; Раскодировать время/дату +; вход: de - время +; bc - месяц/день +; ix - год +; выход: de - день/месяц +; hl - часы/минуты +; b - секунды +; ix - год +; ;INPUT: DE - hhhhhmmmmmmsssss h - hour, m - min, s - sec/2 ; BC - yyyyyyymmmmddddd y - year, m - month, d - day ; (1980-2108) @@ -1475,6 +1610,7 @@ MK_TIME LD A,L ; H - HOUR; L - MINUTE ; B - SECOND (0...59) ; IX- YEAR (0...65535) +;------------------------------------------------- RMKTIME EX DE,HL LD A,C AND #1F @@ -1507,8 +1643,19 @@ RMKTIME EX DE,HL AND A RET + +;///////////////////////////////////////////////////////////////////// +; Функция #1D. Смена текущего каталога. +; Меняет текущий каталог и текущий диск, если он указан в файловой +; спецификации. Если путь начинается с "\" - это означает путь от +; корневого каталога, иначе от текущего. +; +; вход: HL - указатель на имя каталога +; выход: нет +; ; INPUT: HL - "C:\DIR\DIR\DIR_NAME[\]",0 -CHDIR: CALL GETWORD +;///////////////////////////////////////////////////////////////////// +CHDIR: CALL GETWORD ; тест на допуст. имя и настр. на диск RET C LD HL,TMPNAME LD A,(HL) @@ -1516,51 +1663,59 @@ CHDIR: CALL GETWORD CALL NZ,OPENDIR RET - +;///////////////////////////////////////////////////////////////////// +; Функция #1B. Создание каталога. +; +; вход: HL - указатель на имя каталога +; выход: A - код ошибки, если CF=1 +; ; INPUT: HL - "C:\DIR\DIR\DIR_NAME",0 - +;///////////////////////////////////////////////////////////////////// MKDIR: _mSavePath - CALL GETWORD + CALL GETWORD ; тест на допуст. имя и настр. на диск RET C - LD HL,TMPNAME - LD DE,MASKARE - CALL MASK + LD HL,TMPNAME ; 8.3 имя + LD DE,MASKARE ; буфер имени 11 симв. формата + CALL MASK ; преобр. имя 8.3 -> 11 формат RET C - CALL LOADDIR - CALL DSEARCH + CALL LOADDIR ; прочитать список каталога + CALL DSEARCH ; поиск записи каталога в списке диска LD A,DSS_Error.sys.DIR_EXISTS CCF - RET C + RET C ; каталог найден + CALL G_CLUST RET C PUSH HL - LD DE,(FatBuffer.ENDCLUS) - CALL W_T_FAT - CALL WR_FAT + LD DE,(FatBuffer.ENDCLUS) ; номер кластера + CALL W_T_FAT ; записать в кеш FAT-а номер кластера + CALL WR_FAT ; подкл. банку кеша FAT и записать его на диск LD HL,MASKARE LD DE,HANDBUF LD BC,11 LDIR EX DE,HL - LD A,#10 + LD A,#10 ; атрибут записи каталога LD (HL),A INC HL - LD BC,#0A00 -FIHND0 LD (HL),C + LD BC,#0A00 ; b=счетчик + +.loop1: LD (HL),C INC HL - DJNZ FIHND0 + DJNZ .loop1 + PUSH HL - CALL SYSTIME - CALL MK_TIME + CALL SYSTIME ; узнать тек. дату и время + CALL MK_TIME ; закодировать время/дату POP HL - LD (HL),E + LD (HL),E ; de=время INC HL LD (HL),D INC HL - LD (HL),C + LD (HL),C ; день INC HL - LD (HL),B + LD (HL),B ; месяц INC HL POP DE PUSH DE @@ -1568,49 +1723,58 @@ FIHND0 LD (HL),C INC HL LD (HL),D INC HL - LD BC,#0400 -FIHND2 LD (HL),C + LD BC,#0400 ; b=счетчик + +.loop2: LD (HL),C INC HL - DJNZ FIHND2 - CALL WRT_HND - CALL SAVEDIR - LD HL,SECBUF - LD (HL),"." - LD B,10 -MKD02 INC HL - LD A,' ' - LD (HL),A - DJNZ MKD02 + DJNZ .loop2 + + CALL WRT_HND ; скопир. новую запись в список диска (каталога) + CALL SAVEDIR ; сбросить кеш каталога на диск + LD HL,SECBUF ; буфер + LD (HL),"." ; запись тек. каталога + LD BC,10*256 + ' ' ; b=счетчик, c=пробел + +.loop3: INC HL + LD (HL),C + DJNZ .loop3 + INC HL - LD DE,HANDBUF+11 + LD DE,HANDBUF+11 ; ячейка атрибутов файла EX DE,HL LD BC,21 LDIR EX DE,HL - LD (HL),"." + LD (HL),"." ; запись родит. каталога INC HL LD (HL),"." - LD B,9 + LD BC,9*256 + ' ' ; b=счетчик, c=пробел MKD03 INC HL - LD A,#20 - LD (HL),A + LD (HL),C DJNZ MKD03 + INC HL - PUSH HL + + IF OLD_SET_BANK + PUSH HL + ENDIF SET_PAGE_X DIRPAGE + + IF OLD_SET_BANK + POP HL + ENDIF - POP HL PUSH AF LD A,(DIR) CP "." - LD DE,DIR+11 + LD DE,DIR+11 ; атрибуты записи JP Z,MKD04 LD IX,HANDBUF XOR A LD (IX+_sFM.ST_CLUSTER),A LD (IX+_sFM.ST_CLUSTER+1),A - LD DE,HANDBUF+11 + LD DE,HANDBUF+11 ; ячейка атрибутов файла MKD04 EX DE,HL LD BC,HANDBUF.SIZE-11 LDIR @@ -1625,10 +1789,10 @@ MKD04 EX DE,HL LDIR ;!FIXIT нужно ли так много грохать? POP HL CALL NSECTOR - LD A,(BootSector.S_P_C) + LD A,(BootSector.S_P_C) ; секторов на кластер MKD12 PUSH AF - PUSH HL - PUSH IX + PUSH HL ; ст. разряд + PUSH IX ; номер лог. сектора IN A,(SLOT3) PUSH AF IN A,(SLOT0) @@ -1660,7 +1824,15 @@ MKD11 POP AF AND A RET +;///////////////////////////////////////////////////////////////////// +; Функция #1C. Удаление каталога. +; Можно удалить только пустой каталог. +; +; вход: HL - указатель на имя каталога +; выход: A - код ошибки, если CF=1 +; ; INPUT: HL - "C:\DIR\DIR\DIR_NAME",0 +;///////////////////////////////////////////////////////////////////// RMDIR: _mSavePath CALL GETWORD @@ -1707,13 +1879,14 @@ RMD10 LD A,(HL) JP Z,RMD15 ;DIR EMPTY CP "." JR Z,RMD14 - CP #E5 + CP #E5 ;!HARDCODE байт удаления файла JR Z,RMD14 - LD DE,11 + LD DE,11 ;!HARDCODE смещ. до байта атрибутов ADD HL,DE LD A,(HL) SBC HL,DE - BIT 3,A + ;BIT 3,A + AND %0000'1000 JP Z,RMD16 ;DIR NOT EMPTY RMD14 LD DE,#0020 ADD HL,DE @@ -1728,12 +1901,12 @@ RMD14 LD DE,#0020 RMD11 POP AF DEC A JR NZ,RMD12 - POP HL - CALL R_F_FAT - EX DE,HL - JR NC,RMD17 + POP HL ; номер кластера + CALL R_F_FAT ; прочитать из кеша FAT-а номер след. кластера + EX DE,HL ; hl=номер след. кластера + JR NC,RMD17 ; не конец цепочки RMD18 POP IX - JP DELFILE + JP DELFILE ; пометить запись как "удаленная" RMD15 POP IX POP HL diff --git a/DSS/DOS_FM.ASM b/DSS/DOS_FM.ASM index d6ec3db..bca1372 100644 --- a/DSS/DOS_FM.ASM +++ b/DSS/DOS_FM.ASM @@ -910,7 +910,7 @@ ADD_DE2: DJNZ ADD_DE1 ADC HL,DE RET -; HL:DE / BC => DE:IX HL-OSTATOK (DE:BC.HL) +; HL:DE / C => DE:IX HL-OSTATOK (DE:BC.HL). Легко переделать под HL:DE / A => HL:DE.A DIV32: LD A,C DEC A JR Z,.exit @@ -926,8 +926,7 @@ DIV32: LD A,C JR NC,.loop LD A,B ; -.exit: - LD XH,D +.exit: LD XH,D LD XL,E EX DE,HL LD H,0 diff --git a/DSS/build.txt b/DSS/build.txt index 25bf17f..dec2bf5 100644 --- a/DSS/build.txt +++ b/DSS/build.txt @@ -1 +1 @@ -18 \ No newline at end of file +19 \ No newline at end of file diff --git a/DSS/defines.inc b/DSS/defines.inc index 87f9b98..e0fcecc 100644 --- a/DSS/defines.inc +++ b/DSS/defines.inc @@ -17,7 +17,7 @@ DEFINE USING_MEMPAGES 4 DEFINE OLD_SET_BANK 0 -;!FIXIT сделать типа DIRPAGE EQU 0 + BANKTBL и упростить BANK +; кэш списка каталога DIRPAGE EQU 0 FATPAGE EQU 1 TXTPAGE EQU 2