;[BEGIN] ;//MODULE: DOS5 ;//CREATE: 19-05-1998 AUTHOR: Denis Parinov ;//UPDATE: 24-10-1999 DNS Restore module ;------------------------------------------------------------- ;Rev Date Name Description ;------------------------------------------------------------- ;R11 17-04-2023 BAO Временный костыль для недопускания переполнения буфера пути каталога ;R10 15-04-2023 BAO FIXED BUG WITH CHANGE DISK WITHOUT CHANGE PATH ;R09 13-04-2023 BAO FIX BUG WITH PARSING DIRECTORY BUFFER ;R08 15-04-2003 DNS SAVE AND RESTORE CUR-PATH MACROS ;R07 06-02-2003 DNS FIX BUG IN MASK ROUTINE, IT ALLOW NAMES WHICH BEGAN ; FROM "." ".NAM" ;R06 29-01-2003 DNS FIX BUG WITH SET FILE DATE AND TIME ;R05 26-11-2002 DNS FIX ERROR IN CHDIR, DON'T ALLOWED "." FOR ROOT ;R04 19-11-2002 DNS DON'T ALLOW DIR & LABEL ATTR FOR FILES ;R03 19-11-2002 DNS ADD RESET OF VOLUME LABEL ATTRIBUT ;R02 19-11-2002 DNS FIX GET/SET ATTRIBUTES ;R01 16-12-1999 DNS Y2K fix ;------------------------------------------------------------- //////////////////////////////////////////////////////////////////////// ; INPUT: HL - "C:\DIR1\DIR2\filename.ext",#00 ; A - ATTRIB ; B - MODE ; B = 0 GET ATTRIB ; B = 1 SET ATTRIB ; OUTPUT: A - ATTRIB //////////////////////////////////////////////////////////////////////// ATTRIB: ;!TEST Current Dir ;[x] 15/10/23 LD C,A PUSH HL PUSH BC CALL DIR_PATH_CHECK POP BC POP HL RET C LD A,C ; ; INC B DEC B JP Z,.RATTRIB DEC B JP Z,.WATTRIB LD A,DSS_Error.sys.INVALID_FUNCTION SCF RET .RATTRIB: ;!TEST ;[x] 16/11/23 optimize get attribute ;XOR A ; CALL .OPENATR ;R02 RET C ;!TEST ;[x] 16/11/23 optimize get attribute LD A,(HANDBUF+_sFM.ATTRIBUT) ;LD B,(IY+_sFM.ATTRIBUT) ;PUSH BC ;CALL CLOSE ;POP BC ;RET C ;LD A,B ; RET .WATTRIB: PUSH AF XOR A ;!TEST ;[x] 16/11/23 optimize get attribute LD (OPEN.TMP),A ; CALL .OPENATR ;R02 ;!TEST ;[x] 16/11/23 optimize get attribute CALL NC,OPEN.FM ; POP BC RET C SET 7,(IY+_sFM.ACCESS_MODE) RES 3,B ;CLEAR LABEL ATTR ;R03 ;!HARDCODE attribute bit LD (IY+_sFM.ATTRIBUT),B PUSH BC CALL CLOSE .error: POP BC RET C LD A,B RET ;R02 .OPENATR: ;!TEST ;[x] 16/11/23 optimize get attribute ;LD (OPEN.TMP),A ; раб. ячейка (здесь атрибут записи) ; CALL GETWORD ; тест на допуст. имя и настр. на диск RET C CALL MASK RET C LD A,FAT_ATTR.NoVolID ;!TEST ;[x] 16/11/23 optimize get attribute JP SEARCH.Custom ;CALL SEARCH.Custom ;RET C ; запись не найдена ;JP OPEN.FM ; на поиск своб. дескриптора ; ; ;R02 //////////////////////////////////////////////////////////////////////// ; INPUT: HL - "C:\DIR1\DIR2\filename.ext",#00 ; OUTPUT: A - FM //////////////////////////////////////////////////////////////////////// CREATE: ;!TEST Current Dir ;[x] 15/10/23 PUSH HL CALL DIR_PATH_CHECK POP HL RET C ; CALL .Prepare RET C CALL SEARCH.File CALL NC,DELETE ;FILE EXIST RECREAT JR .DO ; ; INPUT: HL - "C:\DIR1\DIR2\filename.ext",#00 ; OUTPUT: A - FM .NEW: ;!TEST Current Dir ;[x] 15/10/23 PUSH HL CALL DIR_PATH_CHECK POP HL RET C ; CALL .Prepare RET C CALL SEARCH.File LD A,DSS_Error.sys.FILE_EXISTS CCF RET C ; .DO: LD HL,MASKARE LD DE,HANDBUF LD BC,11 LDIR EX DE,HL .TMP+1: LD A,0 LD (HL),A INC HL LD BC,#0A00 ;!HARDCODE ; .loop1: LD (HL),C INC HL DJNZ .loop1 ; PUSH HL CALL SYSTIME CALL MK_TIME POP HL LD (HL),E INC HL LD (HL),D INC HL LD (HL),C INC HL LD (HL),B INC HL LD BC,#0600 ; .loop2: LD (HL),C INC HL DJNZ .loop2 ; CALL WRT_HND RET C ;CALL SAVEDIR .PATH0+1: LD HL,0 XOR A LD (OPEN.TMP),A JP OPEN.FILE ;R08 .Prepare: AND #E7 ;R04 %76A00SHR = !FAT_ATTR ;!HARDCODE LD (.TMP),A LD (.PATH0),HL CALL GETWORD RET C ; LD HL,TMPNAME ; LD DE,MASKARE JP MASK CREAT_N EQU CREATE.NEW //////////////////////////////////////////////////////////////////////// ; INPUT: HL - "c:\dir\filename.ext",#00 without simbols * ? //////////////////////////////////////////////////////////////////////// DEL_FN: ;!TEST ;!TEST Current Dir ;[x] 15/10/23 PUSH HL CALL DIR_PATH_CHECK POP HL RET C ; CALL GETWORD ; тест на допуст. имя и настр. на диск RET C CALL MASK RET C ; ;!TEST optimization ;LD HL,MASKARE ;LD BC,11 ;LD A,"?" ;CPIR ;LD A,DSS_Error.sys.INVALID_NAME ;SCF CALL CHECK_NAME ; RET Z CALL LOADDIR CALL SEARCH.File RET C ;JP DELETE ; пометить запись как "удаленная" DELETE: SET_PAGE_X DIRPAGE 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 JP Z,SAVEDIR ; сбросить кеш каталога на диск .loop: EX DE,HL ; hl=номер кластера CALL R_F_FAT ; прочитать из кеша FAT-а номер след. кластера PUSH DE ; номер след. кластера PUSH AF LD DE,#0000 ; номер кластера CALL W_T_FAT ; записать в кеш FAT-а номер кластера POP AF POP DE JP NC,.loop CALL WR_FAT JP SAVEDIR ; сбросить кеш каталога на диск //////////////////////////////////////////////////////////////////////// ; Функция #10. Переименование файла. ; Глобальные символы * и ? в именах файлов не допускаются. ; ; вход: HL - указатель на старое имя файла ; DE - указатель на новое имя файла ; выход: A - код ошибки, если CF=1 ; ; INPUT: HL - "old_name.ext",#00 without simbols * ? ; DE - "new_name.ext",#00 without simbols * ? //////////////////////////////////////////////////////////////////////// RENAME: ;!TEST Current Dir ;[x] 15/10/23 PUSH HL PUSH DE CALL DIR_PATH_CHECK.forceCheck POP DE POP HL RET C ; PUSH DE ;LD DE,MASKARE CALL MASK.name POP DE RET C ;!TEST optimization ;LD HL,MASKARE ;LD BC,11 ;LD A,"?" ;CPIR ;LD A,DSS_Error.sys.INVALID_NAME ;SCF CALL CHECK_NAME ; RET Z PUSH DE CALL LOADDIR ; прочитать список каталога ;LD A,#33 LD A,FAT_ATTR.NoSYSnoVolID CALL SEARCH.Custom ; поиск записи в списке диска POP HL RET C ;LD DE,MASKARE CALL MASK.name RET C ;!TEST optimization ;LD HL,MASKARE ;LD BC,11 ;LD A,"?" ;CPIR ;LD A,DSS_Error.sys.INVALID_NAME ;SCF CALL CHECK_NAME ; RET Z PUSH IX LD A,FAT_ATTR.NoSYSnoVolID CALL SEARCH.Custom ; поиск записи в списке диска POP IX LD A,DSS_Error.sys.FILE_EXISTS CCF RET C SET_PAGE_X DIRPAGE LD HL,MASKARE LD D,XH LD E,XL LD BC,11 LDIR OUT (SLOT3),A JP SAVEDIR //////////////////////////////////////////////////////////////////////// ; Функция #11. Открытие файла. ; ; вход: HL - указатель на имя файла ; A - режим доступа: ; A=0 чтение/запись ; A=1 чтение ; A=2 запись ; выход: CF=0, A - дескриптор файла. ; CF=1, A - код ошибки. //////////////////////////////////////////////////////////////////////// OPEN_FN:;!TEST Current Dir ;[x] 15/10/23 LD (OPEN.TMP),A PUSH HL CALL DIR_PATH_CHECK.forceCheck POP HL RET C JR OPEN.start ;!FIXIT сделать как в mkdir или rmdir? ; ;R08 OPEN: LD (.TMP),A ; enter point from CREATE .start: CALL GETWORD RET C CALL MASK ; enter point from OPEN_FN RET C .FILE: CALL SEARCH.File ; enter point from EXEC RET C ;R02 .FM: CALL GET_FM ; enter point from ATTRIB RET C LD A,C EX AF,AF' EXX LD (IY+_sFM.HANDLE),E LD (IY+_sFM.HANDLE+1),D EXX LD D,YH LD E,YL LD HL,HANDBUF LD BC,HANDBUF.SIZE LDIR .TMP+1: LD A,0 LD (IY+_sFM.ACCESS_MODE),A LD A,(TASK) LD (IY+_sFM.TASK_NUM),A XOR A ; LD (IY+_sFM.KnownCluster_L),A LD (IY+_sFM.KnownCluster_H),A LD (IY+_sFM.KnownOffset_L),A LD (IY+_sFM.KnownOffset_H),A ; LD (IY+_sFM.F_POSITION),A LD (IY+_sFM.F_POSITION+1),A LD (IY+_sFM.F_POSITION+2),A LD (IY+_sFM.F_POSITION+3),A LD A,(FatBuffer.DRIVE) LD (IY+_sFM.DRIVE),A LD HL,CORE_BUFFERS.FM_BUF+_sFM.ST_CLUSTER LD E,(HL) INC HL LD D,(HL) LD (IY+_sFM.DIR_CLUSTER),E LD (IY+_sFM.DIR_CLUSTER+1),D EX AF,AF' AND A RET //////////////////////////////////////////////////////////////////////// ;Входные значения: ; C - #12 ; A - файловый манипулятор ;Выходные значения: ; A - код ошибки, если CF=1 //////////////////////////////////////////////////////////////////////// CLOSE_FN: ;R08 CLOSE: LD (.TMP),A CALL SET_FM RET C LD A,(TASK) CP (IY+_sFM.TASK_NUM) LD A,DSS_Error.sys.ACCESS_DENIED SCF RET NZ BIT 7,(IY+_sFM.ACCESS_MODE) JR Z,.NOTMODF LD E,(IY+_sFM.DIR_CLUSTER) LD D,(IY+_sFM.DIR_CLUSTER+1) PUSH DE ; [x] 15/11/2023 -bug with bad clusters ;!TEST LD A,(IY+_sFM.DRIVE) CALL OPENDSK ; XOR A CALL SET_FM POP DE LD (IY+_sFM.DIR_CLUSTER),E LD (IY+_sFM.DIR_CLUSTER+1),D ; [x] 15/11/2023 -bug with bad clusters ;!TEST LD (IY+_sFM.ST_CLUSTER),E LD (IY+_sFM.ST_CLUSTER+1),D ; CALL LOADDIR .TMP+1: LD A,0 CALL SET_FM ; SET_PAGE_X DIRPAGE ; ;TEST 9/11/23 ; LD HL,DIR ; LD DE,#0020 ; LD C,(IY+_sFM.HANDLE) ; LD B,(IY+_sFM.HANDLE+1) ; JR .CLOSE2 ; .CLOSE1: ; ADD HL,DE ; DEC BC ; .CLOSE2: ; LD A,B ; OR C ; JR NZ,.CLOSE1 LD L,(IY+_sFM.HANDLE) LD H,(IY+_sFM.HANDLE+1) ; LD D,YH LD E,YL EX DE,HL ;PUSH HL ;SET_PAGE_X DIRPAGE ;POP HL LD BC,#0020 ;!HARDCODE LDIR OUT (SLOT3),A CALL SAVEDIR .NOTMODF: LD A,(.TMP) CALL RES_FM RET //////////////////////////////////////////////////////////////////////// ;Входные значения: ; C - #19 ; HL - указатель на файловую спецификацию ; DE - рабочий буфер 44 байта, если B=0, иначе 256 байт ; ;!!!!! на самом деле сейчас если B=1, рабочий буфер 46 байт ; A - атрибуты, используемые при поиске ; B = 0 - имя найденного файла в формате 11 байт "FilenameExt" ; B = 1 - имя найденного файла в формате DOS "filename.ext",0 ;Выходные значения: ; A - код ошибки, если CF=1 //////////////////////////////////////////////////////////////////////// F_FIRST: ; Current Dir [x] 15/10/23 ; LD C,A ; PUSH HL ; PUSH DE ; PUSH BC ; CALL DIR_PATH_CHECK ; POP BC ; POP DE ; POP HL ; RET C ; LD A,C ; ; LD (.TMP),A LD (.DTABUF),DE LD A,B LD (.FNDMODE),A PUSH HL ;!TEST Current Dir ;[x] 15/10/23 CALL DIR_PATH_CHECK RET C ; CALL LOADDIR POP HL CALL GETWORD RET C CALL MASK RET C LD A,(.TMP) CALL SEARCH.Custom RET C LD HL,MASKARE .DTABUF+1: LD DE,0 LD BC,11 ;!HARDCODE LDIR .TMP+1: LD A,0 LD (DE),A .FIND_S: INC DE LD BC,#0020 ADD IX,BC LD (F_NEXT.CURHND),IX LD HL,HANDBUF+12 ;!HARDCODE LD BC,HANDBUF.SIZE-12 ;????? метку вместо числа? LDIR LD A,(HANDBUF+11) LD (DE),A INC DE LD HL,HANDBUF .FNDMODE+1: LD A,0 OR A JR NZ,.FIND_M2 LD BC,11 ;!HARDCODE LDIR LD A,F_NEXT.NO_NEXT.NO LD (F_NEXT.NO_NEXT),A XOR A RET .FIND_M2: CALL GETNAME LD A,F_NEXT.NO_NEXT.NO LD (F_NEXT.NO_NEXT),A XOR A RET //////////////////////////////////////////////////////////////////////// ; ; //////////////////////////////////////////////////////////////////////// F_NEXT: .NO_NEXT.YES EQU 0 .NO_NEXT.NO EQU #FF .NO_NEXT+1: LD A,0 OR A LD A,DSS_Error.sys.INVALID_ACCESS SCF RET Z LD (F_FIRST.DTABUF),DE EX DE,HL LD DE,MASKARE LD BC,11 ;!HARDCODE LDIR XOR A ; F_NEXT.NO_NEXT.YES LD (F_NEXT.NO_NEXT),A LD A,(HL) PUSH HL CALL .NSEARCH POP DE RET C JP F_FIRST.FIND_S .NSEARCH: EX AF,AF' SET_PAGE_X DIRPAGE ;PUSH AF EX AF,AF' CPL LD C,A ;TEST 9/11/23 ; EXX ; LD DE,0 ; EXX ; .CURHND+2: LD IX,0 LD A,XH OR XL JP Z,SEARCH.error_too_many_files JP SEARCH.loop //////////////////////////////////////////////////////////////////////// ; ; //////////////////////////////////////////////////////////////////////// CHNDISK_FN: CALL CHNDISK RET C PUSH AF CALL DIR_PATH_CHANGE.FullCurrent POP AF RET CHNDISK:;[x] более корректная смена диска CALL OPENDSK ; ;R10 RET C LD HL,WorkDirectory LD (HL),0 PUSH AF CALL OPENDIR POP BC RET C LD A,B RET //////////////////////////////////////////////////////////////////////// ; Функция #1E. Информация о текущем каталоге. ; ; вход: HL - буфер в памяти 256 байт ; выход: A - код ошибки, если CF=1 //////////////////////////////////////////////////////////////////////// CURRDIR: LD DE,WorkDirectory JR CURRDIR_FN.skip CURRDIR_FN: LD DE,CurrentDirectory .skip: EX DE,HL LD BC,DIRECTORY_PATH_LENGTH ;[x] 15/11/2023 могло выйти за пределы буфера XOR A .loop: CP (HL) LDI JP PO,.error ;[x] 15/11/2023 могло выйти за пределы буфера JR NZ,.loop RET ;[x] 15/11/2023 могло выйти за пределы буфера .error: LD A,DSS_Error.sys.TOO_DEEP_DIR_DEPTH SCF RET ; //////////////////////////////////////////////////////////////////////// ; Функция #21. Текущая дата и время. ; ; вход: нет ; выход: D - день ; E - месяц ; IX - год ; H - час ; L - минуты ; B - секунды ; C - день недели //////////////////////////////////////////////////////////////////////// SYSTIME: LD C,BIOS.CMOS_TEST RST ToBIOS JP C,.NOCMOS LD D,7 ;DAY CALL RCMOS PUSH AF LD D,8 ;MONTH CALL RCMOS POP DE LD E,A PUSH DE LD D,4 ;HOUR CALL RCMOS PUSH AF LD D,2 ;MINUTE CALL RCMOS POP DE LD E,A PUSH DE LD D,0 ;SECOND CALL RCMOS PUSH AF LD D,6 ;WEEK DAY LD C,BIOS.CMOS_RD RST ToBIOS POP DE LD E,A PUSH DE LD D,9 ;YEAR CALL RCMOS ;READ AND CONVERT TO DECIMAL PUSH AF LD D,#32 ;CENTURY LD C,BIOS.CMOS_RD RST ToBIOS LD XH,A POP AF CP 80 ;R01, TEST DECIMAL FIX PUSH AF JR C,.XXIAGE LD A,#19 CP XH JR Z,.GOODAGE JR .BADAGE .XXIAGE: LD A,#20 CP XH JR Z,.GOODAGE .BADAGE: PUSH AF LD D,#32 ;CENTURY LD C,BIOS.CMOS_WR RST ToBIOS POP AF LD XH,A .GOODAGE: POP AF LD XL,A LD A,XH CALL BCD2HEX LD L,A LD H,0 LD C,L LD B,H LD XH,B ADD HL,HL ADD HL,HL ADD HL,BC ADD HL,HL ;*10 LD B,H LD C,L ADD HL,HL ADD HL,HL ADD HL,BC ADD HL,HL ;*10(100) EX DE,HL ADD IX,DE POP BC POP HL POP DE AND A RET .NOCMOS: .NC_DAY+1: LD DE,DAY*256+MONTH ;DAY/MONTH .NC_HOUR+1: LD HL,0 ;HOUR/MINUTE .NC_SEC+1: LD BC,1 ;SECOND/WEEKDAY .NC_YEAR+2: LD IX,YEAR ;YEAR AND A RET //////////////////////////////////////////////////////////////////////// ; Функция #22. Установить текущую дату и время. ; ; вход: D - день ; E - месяц ; IX - год ; H - час ; L - минуты ; B - секунды ; выход: A - код ошибки, если CF=1 //////////////////////////////////////////////////////////////////////// SETTIME: PUSH IX PUSH BC PUSH HL PUSH DE LD C,BIOS.CMOS_TEST RST ToBIOS JP C,.NOCMOS2 POP AF PUSH AF LD D,7 ;DAY CALL WCMOS POP BC LD A,C LD D,8 ;MONTH CALL WCMOS POP AF PUSH AF LD D,4 ;HOUR CALL WCMOS POP BC LD A,C LD D,2 ;MINUTE CALL WCMOS POP AF PUSH AF LD D,0 ;SECOND CALL WCMOS POP BC LD A,C LD D,6 ;WEEK DAY LD C,BIOS.CMOS_WR RST ToBIOS ; POP HL XOR A LD DE,100 .YR: INC A SBC HL,DE JR NC,.YR ADD HL,DE DEC A PUSH HL LD D,#32 ;CENTURY CALL WCMOS POP BC LD A,C LD D,9 ;YEAR CALL WCMOS AND A RET ; !FIXIT новый биос выставляет время, если с ним что-то не так. .NOCMOS2: LD C,0 LD (SYSTIME.NC_DAY),DE ;DAY/MONTH LD (SYSTIME.NC_HOUR),HL ;HOUR/MINUTE LD (SYSTIME.NC_SEC),BC ;SECOND/WEEKDAY LD (SYSTIME.NC_YEAR),IX ;YEAR AND A 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 ; раскодировать время/дату AND A RET //////////////////////////////////////////////////////////////////////// ; Функция #18. Изменение даты и времени файла. ; ; вход: A - дескриптор файла ; D - день ; E - месяц ; IX - год ; H - час ; L - минуты ; B - секунды ; выход: A - код ошибки, если CF=1 //////////////////////////////////////////////////////////////////////// PUT_D_T: PUSH AF CALL MK_TIME ; закодировать время/дату POP AF ; дескриптор PUSH DE PUSH BC CALL SET_FM POP BC POP DE RET C LD (IY+_sFM.TIME),E LD (IY+_sFM.TIME+1),D LD (IY+_sFM.DATE),C LD (IY+_sFM.DATE+1),B SET 7,(IY+_sFM.ACCESS_MODE) ;R06 ; уст. признак изменения файла AND A RET //////////////////////////////////////////////////////////////////////// ; Функция #1D. Смена текущего каталога. ; Меняет текущий каталог и текущий диск, если он указан в файловой ; спецификации. Если путь начинается с "\" - это означает путь от ; корневого каталога, иначе от текущего. ; ; вход: HL - указатель на имя каталога ; выход: нет ; ; INPUT: HL - "C:\DIR\DIR\DIR_NAME[\]",0 //////////////////////////////////////////////////////////////////////// CHDIR_FN: ;!TEST Current Dir ;[x] 15/10/23 PUSH HL CALL DIR_PATH_CHECK POP HL RET C CALL CHDIR ; если удачно, то копируем WorkDirectory в CurrentDirectory JP NC,DIR_PATH_CHANGE.FullCurrent ; если неудачно, то возвращаемся туда откуда пришли PUSH AF LD HL,CurrentDirectory CALL CHDIR POP AF RET ; CHDIR: CALL GETWORD ; тест на допуст. имя и настр. на диск RET C LD HL,TMPNAME LD A,(HL) OR A CALL NZ,OPENDIR RET //////////////////////////////////////////////////////////////////////// ; Функция #1B. Создание каталога. ; ; вход: HL - указатель на имя каталога ; выход: A - код ошибки, если CF=1 ; ; INPUT: HL - "C:\DIR\DIR\DIR_NAME",0 //////////////////////////////////////////////////////////////////////// MKDIR: ;!TEST Current Dir ;[x] 15/10/23 PUSH HL CALL DIR_PATH_CHECK POP HL RET C CALL .START PUSH AF LD HL,CurrentDirectory CALL CHDIR POP AF RET ; .START: CALL GETWORD ; тест на допуст. имя и настр. на диск RET C ;LD HL,TMPNAME ; 8.3 имя ;LD DE,MASKARE ; буфер имени 11 симв. формата CALL MASK ; преобр. имя 8.3 -> 11 формат RET C ;!TEST optimization ранее GETWORD уже загрузил директорию ;CALL LOADDIR ; прочитать список каталога ; CALL SEARCH.Dir ; поиск записи каталога в списке диска LD A,DSS_Error.sys.DIR_EXISTS CCF RET C ; каталог найден ; CALL G_CLUST RET C PUSH HL 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 (HL),A INC HL LD BC,#0A00 ; b=счетчик ; .loop1: LD (HL),C INC HL DJNZ .loop1 ; PUSH HL CALL SYSTIME ; узнать тек. дату и время CALL MK_TIME ; закодировать время/дату POP HL LD (HL),E ; de=время INC HL LD (HL),D INC HL LD (HL),C ; день INC HL LD (HL),B ; месяц INC HL POP DE PUSH DE LD (HL),E INC HL LD (HL),D INC HL LD BC,#0400 ; b=счетчик ; .loop2: LD (HL),C INC HL DJNZ .loop2 ; CALL WRT_HND ; скопир. новую запись в список диска (каталога) ;CALL SAVEDIR ; и сбросить кеш каталога на диск LD HL,CORE_BUFFERS.SECBUF ; буфер LD (HL),"." ; запись тек. каталога LD BC,10*256 + ' ' ; b=счетчик, c=пробел ; .loop3: INC HL LD (HL),C DJNZ .loop3 ; INC HL LD DE,HANDBUF+11 ; ячейка атрибутов файла EX DE,HL LD BC,21 LDIR EX DE,HL LD (HL),"." ; запись родит. каталога INC HL LD (HL),"." LD BC,9*256 + ' ' ; b=счетчик, c=пробел .MKD03: INC HL LD (HL),C DJNZ .MKD03 ; INC HL SET_PAGE_X DIRPAGE PUSH AF ; LD A,(DIRPAGE.buffer) CP "." LD DE,DIRPAGE.buffer+11 ; атрибуты записи ;!HARDCODE 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 ; ячейка атрибутов файла .MKD04: EX DE,HL LD BC,HANDBUF.SIZE-11 LDIR POP AF OUT (SLOT3),A ; EX DE,HL LD D,H LD E,L INC DE LD (HL),0 LD BC,512-65 ;!HARDCODE LDIR ; POP HL CALL NSECTOR LD A,(CORE_BUFFERS.BootSector.S_P_C) ; секторов на кластер .MKD12: PUSH AF PUSH HL ; ст. разряд PUSH IX ; номер лог. сектора IN A,(SLOT3) PUSH AF IN A,(SLOT0) OUT (SLOT3),A ; LD A,(FatBuffer.DRIVE) LD DE,CORE_BUFFERS.SECBUF+#C000 LD BC,1*256 + Dss.DRV.Write RST ToDSS.DRV ; POP AF OUT (SLOT3),A ; LD HL,CORE_BUFFERS.SECBUF LD DE,CORE_BUFFERS.SECBUF+1 LD BC,511 LD (HL),0 LDIR ; POP IX POP HL INC IX LD A,XH OR XL JR NZ,.MKD11 INC HL .MKD11 POP AF DEC A JR NZ,.MKD12 AND A RET //////////////////////////////////////////////////////////////////////// ; Функция #1C. Удаление каталога. ; Можно удалить только пустой каталог. ; ; вход: HL - указатель на имя каталога ; выход: A - код ошибки, если CF=1 ; ; INPUT: HL - "C:\DIR\DIR\DIR_NAME",0 //////////////////////////////////////////////////////////////////////// RMDIR: ;!TEST Current Dir ;[x] 15/10/23 PUSH HL CALL DIR_PATH_CHECK POP HL RET C CALL .START PUSH AF LD HL,CurrentDirectory CALL CHDIR CALL DIR_PATH_CHANGE.Current POP AF RET ; .START: CALL GETWORD RET C CALL MASK RET C ;!TEST optimization ;LD HL,MASKARE ;LD BC,11 ;LD A,"?" ;CPIR ;LD A,DSS_Error.sys.INVALID_NAME ;SCF CALL CHECK_NAME ; RET Z CALL LOADDIR CALL SEARCH.Dir RET C LD HL,(HANDBUF+_sFM.ST_CLUSTER) PUSH IX .RMD17: PUSH HL CALL NSECTOR LD A,(CORE_BUFFERS.BootSector.S_P_C) .RMD12: PUSH AF PUSH HL PUSH IX IN A,(SLOT3) PUSH AF IN A,(SLOT0) OUT (SLOT3),A LD DE,CORE_BUFFERS.SECBUF+#C000 LD BC,1*256 + Dss.DRV.Read LD A,(FatBuffer.DRIVE) RST ToDSS.DRV POP AF OUT (SLOT3),A LD B,16 ;!HARDCODE 16 * 32 = 512; 32 - размер записи, 512 - размер считанного сектора LD HL,CORE_BUFFERS.SECBUF .RMD10: LD A,(HL) OR A JP Z,.RMD15 ;DIR EMPTY CP "." JR Z,.RMD14 CP #E5 ;!HARDCODE байт удаления файла JR Z,.RMD14 LD DE,11 ;!HARDCODE смещ. до байта атрибутов ADD HL,DE LD A,(HL) SBC HL,DE ;BIT 3,A AND %0000'1000 JP Z,.error ;DIR NOT EMPTY .RMD14: LD DE,#0020 ADD HL,DE DJNZ .RMD10 POP IX POP HL INC IX LD A,XH OR XL JR NZ,.RMD11 INC HL .RMD11: POP AF DEC A JR NZ,.RMD12 POP HL ; номер кластера CALL R_F_FAT ; прочитать из кеша FAT-а номер след. кластера EX DE,HL ; hl=номер след. кластера JR NC,.RMD17 ; не конец цепочки .RMD18: POP IX JP DELETE ; пометить запись как "удаленная" .RMD15: POP IX POP HL POP AF POP HL JR .RMD18 .error: POP IX POP HL POP AF POP HL POP IX LD A,DSS_Error.sys.DIR_NOT_EMPTY SCF RET //////////////////////////////////////////////////////////////////////// ;Входные значения: ; C - #44 ; B = 0, преобразовать из 11 символьного формата в формат ДОС ; HL - 11 символов имени файла ; DE - буфер для имени в формате ДОС ; B = 1, преобразовать из формата ДОС в 11 символьный формат ; HL - имя файла в формате ДОС ; DE - 11 символов имени файла ;Выходные значения: ; A - код ошибки, если CF=1 //////////////////////////////////////////////////////////////////////// DOSNAME: INC B DEC B JP Z,GETNAME DEC B JP Z,MASK.custom LD A,DSS_Error.sys.INVALID_FUNCTION SCF RET //////////////////////////////////////////////////////////////////////// ;----------------------------------------------------------------------; ; Чтение регистров CMOS ; вход: d=номер регистра RCMOS: LD C,BIOS.CMOS_RD RST ToBIOS ;JP BCD2HEX ; INPUT : A - BCD ; OUTPUT: A - HEX BCD2HEX: LD E,A RRCA RRCA RRCA RRCA AND #0F LD D,A ADD A,A ADD A,A ADD A,D ADD A,A LD D,A LD A,E AND #0F ADD A,D RET ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; ;!FIXIT переделать по доке на Даллас и заись в ячейки часов ; Запись регистров CMOS ; вход: d=номер регистра WCMOS: CALL HEX2BCD LD C,BIOS.CMOS_WR JP ToBIOS ; INPUT : A - HEX ; OUTPUT: A - BCD HEX2BCD: LD BC,#0AFF .loop: INC C SUB B JR NC,.loop ADD A,B LD B,A LD A,C RLCA RLCA RLCA RLCA AND #F0 OR B RET ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; ; Закодировать время/дату ; вход: de - день/месяц ; hl - часы/минуты ; b - секунды ; ix - год ; выход: de - время ; bc - месяц/день ; ix - год ; ;INPUT: D - DAY; E - MONTH ; H - HOUR; L - MINUTE ; B - SECOND (0...59) ; IX- YEAR (0...65535) ;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 SLA A RL H SLA A RL H SLA A RL H SRL B OR B LD L,A LD BC,#F844 ;(-1980) ADD IX,BC LD A,E RLCA RLCA RLCA RLCA AND #F0 LD B,XL SLA A RL B OR D LD C,A EX DE,HL 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) ;OUTPUT: D - DAY; E - MONTH ; H - HOUR; L - MINUTE ; B - SECOND (0...59) ; IX- YEAR (0...65535) RMKTIME: EX DE,HL LD A,C AND #1F LD D,A SRL B RR C LD A,C RRCA RRCA RRCA RRCA AND #0F LD E,A LD C,B LD B,0 LD IX,1980 ADD IX,BC LD A,L AND #1F ADD A,A LD B,A SRL H RR L SRL H RR L SRL H RR L SRL L SRL L AND A RET ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; ; HL - 11 bytes filename "FILENAMEEXT" ; DE - DOS filename "FILENAME.EXT",0 ; GETNAME: ; LD BC,#08FF ; .GETN1: LD A,(HL) ; CP " " ; JR NZ,.GETN3 ; .GETN2: INC HL ; DJNZ .GETN2 ; JR .GETN4 ; .GETN3: LDI ; DJNZ .GETN1 ; ; ; .GETN4: LD A,(HL) ; CP " " ; LD A,"." ; JR NZ,.GETN5 ; LD A,#00 ; .GETN5: LD (DE),A ; INC DE ; RET Z ; LD B,#03 ; .GETN6: LD A,(HL) ; CP " " ; RET Z ; LDI ; XOR A ; LD (DE),A ; DJNZ .GETN6 ; RET ;---------------;---------------;--------------- GETNAME: LD BC,#08FF LD A,' ' .loop: CP (HL) JR Z,.skip LDI DJNZ .loop ;;;; JP .extension ;;;; .skip: LD C,B LD B,0 ; CF=0 ADC HL,BC ;;;; .extension: CP (HL) LD A,"." JR NZ,.copy_extension XOR A .copy_extension: LD (DE),A INC DE RET Z ;no copy extension ; copy extension LD BC,#03FF ;!HARDCODE длина расширения + счётчик LD A,' ' .loop2: CP (HL) JR Z,.exit LDI DJNZ .loop2 .exit: XOR A LD (DE),A RET ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; ; Поиск записи каталога в списке каталога ; ; вход: a=атрибут записи ; выход: de'=индекс записи в списке каталога ; (HANDBUF) = file's direcory record ; CF - каталог не найден SEARCH: .Dir: LD A,FAT_ATTR.DIRECTORY CALL SEARCH.Custom RET NC CP DSS_Error.sys.PATH_NOT_FOUND + 1 RET C ; SCF LD A,DSS_Error.sys.TOO_MANY_FILES_IN_DIR RET ; .File: LD A,FAT_ATTR.NoDIRnoVolID .Custom: EX AF,AF' ; A = 76ADLSHR SET_PAGE_X DIRPAGE ;PUSH AF EX AF,AF' ; CPL LD C,A LD IX,DIRPAGE.buffer ;!TEST 9/11/23 ; EXX ; LD DE,0 ; EXX ; .loop: LD A,(IX+00) OR A JR Z,.error_file_not_found CP #E5 ;!HARDCODE #E5 - запись в директории свободна, так как файл/директория были удалены JR Z,.next_record LD A,(IX+11) AND C JR NZ,.next_record LD HL,MASKARE LD D,XH LD E,XL LD B,11 EX DE,HL .loop_compare: LD A,(DE) CP '?' JR Z,.next_char CP (HL) JR NZ,.next_record .next_char: INC HL INC DE DJNZ .loop_compare ;!TEST 9/11/23 ;[x] some optimize ; LD D,XH ; LD E,XL LD D,XH LD E,XL EXX LD D,XH LD E,XL EXX ; LD HL,HANDBUF EX DE,HL LD BC,HANDBUF.SIZE LDIR ;POP AF EX AF,AF' OUT (SLOT3),A EX AF,AF' AND A RET .next_record: ;!TEST 9/11/23 ;[x] some optimize ; EXX ; INC DE ; EXX ; LD DE,#0020 ;!HARDCODE ADD IX,DE JR NC,.loop .error_too_many_files: ;POP AF EX AF,AF' OUT (SLOT3),A LD A,DSS_Error.sys.TOO_MANY_FILES_IN_DIR SCF RET ; .error_file_not_found: ;POP AF EX AF,AF' OUT (SLOT3),A LD A,DSS_Error.sys.FILE_NOT_FOUND SCF RET ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; ; Тест на допустимое имя и настроиться на диск. ; вход: hl=строка имени ; выход: (TMPNAME) GETWORD: ; !TEST INC HL LD A,(HL) DEC HL CP ':' JR NZ,.dir_loop LD A,(HL) CP 'a' JR C,.next CP '{' JR NC,.next SUB #20 .next: SUB 'A' INC HL INC HL PUSH HL CALL CHNDISK ;CALL OPENDSK POP HL RET C LD A,(HL) OR A RET Z CP ' ' ; RET Z CP '\' ; SCF LD A,DSS_Error.sys.PATH_NOT_FOUND RET NZ INC HL ; .dir_loop: LD DE,TMPNAME LD BC,#0DFF ; .loop: LD A,(HL) INC HL CP '\' ; JR Z,.DIR_NAME ; AND A ; JR Z,.DIR_NAME ;CP ':' ;JR Z,.DRV_NAME LD (DE),A INC DE CP ' '+1 CCF RET NC DJNZ .loop LD A,DSS_Error.sys.INVALID_NAME SCF RET ; .DIR_NAME: XOR A LD (DE),A PUSH HL LD HL,TMPNAME CALL OPENDIR POP HL RET C JR .dir_loop ; .DRV_NAME: ; LD A,(TMPNAME) ; CP 'a' ; JR C,.next ; CP '{' ; JR NC,.next ; SUB #20 ; .next: SUB 'A' ; PUSH HL ; ;!TEST CHNDISK OPENDSK ; ;CALL OPENDSK ; CALL CHNDISK ; ; ; POP HL ; RET C ; JR .loop ; ; Буфер имени 8.3 формата TMPNAME: DZ ' ' ; 12 пробелов и 0 ;!FIXIT к буферам ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; ; IN: A - drive number ; OPENDSK: ;!TEST DRV.Open обход R10 LD C,A LD A,(FatBuffer.DRIVE) CP C JR Z,.exit LD A,C ; .force: PUSH AF LD C,Dss.DRV.Open RST ToDSS.DRV POP BC JP C,.error LD A,B LD (FatBuffer.DRIVE),A CALL RD_BPB RET C .exit: LD A,(LDRIVE) AND A RET .error: CP DSS_Error.sys.INVALID_DRIVE SCF RET Z LD A,DSS_Error.sys.NOT_READY RET ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; OPENDIR:;!TEST ;[x] some optimize ;XOR A ;CALL SET_FM LD IY,CORE_BUFFERS.FM_BUF ; LD A,(HL) OR A JR NZ,.SUBDIR .REROOT1: LD DE,0 ;!TEST ;[x] some optimize ;LD (IY+_sFM.ST_CLUSTER),E ;LD (IY+_sFM.ST_CLUSTER+1),D EX DE,HL LD (CORE_BUFFERS.FM_BUF + _sFM.ST_CLUSTER),HL EX DE,HL ; CALL LOADDIR LD HL,WorkDirectory LD (HL),'\' INC HL LD (HL),#00 ; CF=0 ;AND A RET .SUBDIR: CP "." JR NZ,.SUBDIR2 ;!TEST ;[x] some optimize ;LD A,(IY+_sFM.ST_CLUSTER) ;R05 LD A,(CORE_BUFFERS.FM_BUF + _sFM.ST_CLUSTER) ;R05 ; OR (IY+_sFM.ST_CLUSTER+1) ;R05 JR NZ,.SUDI1 ;R05 INC HL ;R05 LD A,(HL) ;R05 OR A ;R05 DEC HL ;R05 JR Z,.REROOT1 ;R05 .SUDI1: EXX LD HL,MASKARE LD DE,MASKARE+1 LD BC,10 ;!HARDCODE LD (HL),' ' LDIR EXX LD DE,MASKARE .loop: LDI LD A,(HL) OR A JR NZ,.loop JR .SUBDIR3 .SUBDIR2: CALL MASK.name RET C .SUBDIR3: CALL FINDDIR RET C ;!TEST ;[x] some optimize ;LD (IY+_sFM.ST_CLUSTER),E ;LD (IY+_sFM.ST_CLUSTER+1),D ;LD DE,#4000 ;!HARDCODE ;LD (IY+_sFM.F_SIZE),E ;LD (IY+_sFM.F_SIZE+1),D EX DE,HL LD (CORE_BUFFERS.FM_BUF + _sFM.ST_CLUSTER),HL LD HL,#4000 ;!HARDCODE LD (CORE_BUFFERS.FM_BUF + _sFM.F_SIZE),HL EX DE,HL ; CALL LOADDIR ; CF=0 ;AND A RET ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; ; FIND "MASKAREA" IN DIRECTORY FINDDIR: SET_PAGE_X DIRPAGE ; PUSH AF LD IX,DIRPAGE.buffer .big_loop: LD A,(IX+00) OR A JR Z,.error CP #E5 JR Z,.next_step LD A,(IX+11) ;!HARDCODE AND #10 ;!HARDCODE JR Z,.next_step LD HL,MASKARE LD D,XH LD E,XL EX DE,HL LD B,11 ;!HARDCODE .loop: LD A,(DE) CP "?" JR Z,.compared CP (HL) JR NZ,.next_step .compared: INC HL INC DE DJNZ .loop ; LD A,(IX+0) CP "." JP NZ,.ADDSPEC LD A,(IX+1) ;!HARDCODE CP "." JP NZ,.IT_DIR LD HL,WorkDirectory LD D,H LD E,L INC HL LD BC,WorkDirectory.DEPTH XOR A CPIR JP PO,.error ;[x] 20/11/23 проверка на выход за границы DEC HL ;R09 DEC HL LD BC,WorkDirectory.DEPTH LD A,'\' CPDR INC HL EX DE,HL ; CF = 0 SBC HL,DE EX DE,HL JR NZ,.MM3 INC HL .MM3: LD (HL),0 JP .IT_DIR ; .next_step: LD BC,#0020 ;!HARDCODE ADD IX,BC JR NC,.big_loop ; .error: POP AF OUT (SLOT3),A LD A,DSS_Error.sys.PATH_NOT_FOUND SCF RET .ADDSPEC: LD HL,WorkDirectory+1 LD BC,WorkDirectory.DEPTH-1 CALL .CHECK_SLASH JR C,.error ;R11 LD A,B AND A JR NZ,.nxt LD A,C CP 8+1+3 ;!HARDCODE имя каталога + точка + расширение JR C,.error .nxt: ; LD E,XL LD D,XH ; [x] оптимизация по размеру EX DE,HL CALL GETNAME EX DE,HL ; ; LD BC,256*8 + ' ' ;!HARDCODE ; .MM1: LD A,(DE) ; INC DE ; CP C ; JR Z,.MM2 ; LD (HL),A ; INC HL ; .MM2 DJNZ .MM1 ;x42-40 50-55 ; LD A,(DE) ; INC DE ; CP C ; JR Z,.MM3 ; LD (HL),"." ; INC HL ; LD (HL),A ; INC HL ; LD A,(DE) ; INC DE ; CP C ; JR Z,.MM3 ; LD (HL),A ; INC HL ; LD A,(DE) ; CP C ; JR Z,.MM3 ; LD (HL),A ; .MM2_5: INC HL ; .MM3: LD (HL),0 ; ; JP IT_DIR .IT_DIR: LD E,(IX+_sFM.ST_CLUSTER) LD D,(IX+_sFM.ST_CLUSTER+1) POP AF OUT (SLOT3),A AND A RET .CHECK_SLASH: XOR A CPIR ;[x] 20/11/23 проверка на выход за границы SCF RET PO ; DEC HL DEC HL LD A,'\' ; #5C CP (HL) INC HL RET Z LD (HL),A INC HL RET ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; ; .custom: ; Преобразовать имя 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: LD HL,TMPNAME .name: LD DE,MASKARE .custom: PUSH HL PUSH DE LD H,D LD L,E INC DE LD (HL),' ' LD BC,10 ;!HARDCODE = size (FileName + Extension - 1) LDIR POP DE POP HL LD A,(HL) CP '.' ;R07 SCF ;R07 JR Z,.MASKB ;R07 CP ' '+1 .MASKB: LD A,DSS_Error.sys.INVALID_NAME RET C LD BC,#0902 ; B - счетчик .MASK1: LD A,(HL) CP ' '+1 CCF RET NC CP '"' JR Z,.MASK_ERR CP '*' JR Z,.MASK3 CP '+' JR Z,.MASK_ERR CP ',' JR Z,.MASK_ERR CP '.' JR Z,.MASK5 CP '/' JR Z,.MASK_ERR CP ':' JR Z,.MASK_ERR CP ';' JR Z,.MASK_ERR CP '<' JR Z,.MASK_ERR CP '=' JR Z,.MASK_ERR CP '>' JR Z,.MASK_ERR CP '[' JR Z,.MASK_ERR CP '\' JR Z,.MASK_ERR CP ']' JR Z,.MASK_ERR CP '|' JR Z,.MASK_ERR ; CP 'a' ;????? ; JR C,.MASK2 ; CP 'z' + 1 ; JR NC,.MASK2 ; SUB #20 CALL UPPER ; a..z -> A..Z .MASK2: LD (DE),A INC HL INC DE DJNZ .MASK1 .MASK_ERR: LD A,DSS_Error.sys.INVALID_NAME SCF RET .MASK3: LD A,'?' INC HL DJNZ .MASK6 LD A,DSS_Error.sys.INVALID_NAME SCF RET .MASK6: LD (DE),A INC DE DJNZ .MASK6 LD B,1 JR .MASK1 .MASK5: LD A,' ' INC HL DJNZ .MASK4 LD B,4 DEC C JP NZ,.MASK1 LD A,DSS_Error.sys.INVALID_NAME SCF RET .MASK4: LD (DE),A INC DE DJNZ .MASK4 LD B,4 DEC C JP NZ,.MASK1 LD A,DSS_Error.sys.INVALID_NAME SCF RET ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; ; a..z -> A..Z UPPER: CP 'a' RET C CP 'z' + 1 JR NC,.MDUPPER SUB #20 .NOUPPER: RET .MDUPPER: CP 'а' ; русская буква а, код #A0 JR C,.NOUPPER CP 'п' ; русская буква п, код #B0 JR NC,.BGUPPER SUB #20 RET .BGUPPER: CP 'р' ; русская буква р, код #E0 JR C,.NOUPPER CP 'Ё' ; русская буква Ё, код #F0 JR NC,.HGUPPER SUB #50 RET .HGUPPER: CP 'ё' ; русская буква ё, код #F1 RET NZ DEC A RET ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; ; Прочитать список каталога LOADDIR: XOR A LD H,A LD L,A LD IX,0 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) ; de=номер первого кластера LD E,(IY+_sFM.ST_CLUSTER+1) LD A,D OR E JP Z,.LROTDIR ; root ?? LD HL,DIRPAGE.buffer ; куда LD DE,#4000 ; сколько XOR A ; дескриптор CALL READ ; чтение из файла ;!FIXIT проверка на ошибку LD (SAVEDIR.DIRSIZE),DE ; число прочит. байтов POP AF OUT (SLOT3),A AND A RET .LROTDIR: LD HL,(FatBuffer.DIR_FRH) ; ст. разряд LD IX,(FatBuffer.DIR_FRL) ; номер лог. сектора LD A,(FatBuffer.DIR_S_S) ;!TEST LD B,32 ; !HARDCODE 16384/(sector 512). размер root-каталога CP B JR NC,.RTD1 LD B,A ; число секторов ;LD B,32 ; !HARDCODE 16384/(sector 512). размер root-каталога ;SUB B ;JR NC,.RTD1 ;ADD A,B ;LD B,A ; число секторов ; .RTD1: LD A,(FatBuffer.DRIVE) ; номер диска LD DE,DIRPAGE.buffer ; буфер LD C,Dss.DRV.Read ; чтение секторов RST ToDSS.DRV POP AF OUT (SLOT3),A AND A RET ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; ; скопировать запись в список диска (каталога) ; и сбросить кеш каталога на диск WRT_HND: SET_PAGE_X DIRPAGE EX AF,AF' ; LD IX,DIRPAGE.buffer ;TEST 9/11/23 ; EXX ; LD DE,0 ; EXX ; .loop: LD A,(IX+00) OR A JR Z,.WRT_HN2 CP #E5 JR Z,.WRT_HN2 LD BC,#0020 ADD IX,BC JR NC,.loop ; EX AF,AF' OUT (SLOT3),A LD A,DSS_Error.sys.ROOT_OVERFLOW SCF RET .WRT_HN2: LD D,XH LD E,XL LD HL,HANDBUF LD BC,HANDBUF.SIZE LDIR EX AF,AF' OUT (SLOT3),A LD HL,DIRPAGE.buffer LD BC,(SAVEDIR.DIRSIZE) DEC BC ADD HL,BC AND A SBC HL,DE JR NC,SAVEDIR LD HL,(SAVEDIR.DIRSIZE) LD BC,(FatBuffer.B_P_C) ADD HL,BC LD (SAVEDIR.DIRSIZE),HL AND A JP SAVEDIR ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; ; Сбросить кеш каталога на диск. ; вход: iy=структура дескриптора SAVEDIR: XOR A LD HL,0 LD IX,0 LD B,0 CALL MOVE_FP ; SET_PAGE_X DIRPAGE PUSH AF ; LD A,(FatBuffer.DRIVE) LD (IY+_sFM.DRIVE),A LD D,(IY+_sFM.ST_CLUSTER) LD E,(IY+_sFM.ST_CLUSTER+1) LD A,D OR E JP Z,.SROTDIR LD HL,DIRPAGE.buffer ; размер списка каталога size_cash_directory .DIRSIZE+1: LD DE,0 XOR A CALL WRITE POP AF OUT (SLOT3),A AND A RET .SROTDIR: LD HL,(FatBuffer.DIR_FRH) LD IX,(FatBuffer.DIR_FRL) LD A,(FatBuffer.DIR_S_S) LD B,32 SUB B JR NC,.RTD1S ADD A,B LD B,A .RTD1S: LD A,(FatBuffer.DRIVE) LD DE,DIRPAGE.buffer LD C,Dss.DRV.Write RST ToDSS.DRV POP AF OUT (SLOT3),A AND A RET ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; ;!TEST Current Dir ;[x] 15/10/23 DIR_PATH_CHANGE: .FullCurrent: LD A,(FatBuffer.DRIVE) ADD 'A' LD (CurrentPath),A ; .Current: LD HL,CurrentDirectory JP CURRDIR ; .FullWork: LD A,(CurrentPath) SUB 'A' LD (FatBuffer.DRIVE),A ; .Work: LD HL,WorkDirectory JP CURRDIR_FN ; ; DIR_PATH_CHECK: LD A,(HL) CP '\' JR NZ,.notRootDir ; CALL .checkDrive RET Z LD A,(CurrentPath) SUB 'A' JP OPENDSK ; .notRootDir: INC HL LD A,(HL) CP ':' RET Z ; .forceCheck: LD HL,CurrentDirectory+1 LD BC,CurrentDirectory.DEPTH-1 CALL .checkDrive JR Z,.checkDir ; LD HL,CurrentPath LD A,(FatBuffer.DRIVE) ADD 'A' CP (HL) JR NZ,.gotoPath ; .checkDir: LD HL,CurrentDirectory+1 LD DE,WorkDirectory+1 ; .loop: LD A,(DE) AND A JR Z,.end CP (HL) INC HL INC DE JR Z,.loop JP .gotoPath ; .end: CP (HL) RET Z JR .gotoPath ; .checkDrive: LD HL,CurrentPath LD A,(FatBuffer.DRIVE) ADD 'A' CP (HL) RET .gotoPath: CALL FINDDIR.CHECK_SLASH LD A,DSS_Error.sys.PATH_NOT_FOUND RET C LD HL,CurrentPath JP GETWORD ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; CHECK_NAME: LD HL,MASKARE .custom: LD BC,11 ;!HARDCODE LD A,"?" CPIR LD A,DSS_Error.sys.INVALID_NAME SCF RET ;----------------------------------------------------------------------; ;!FIXIT к буферам ; Массив лог. номеров банок расширения DSS BANKTBL: BLOCK USING_MEMPAGES+1,#FF ; +1 для COREPAGE ; HANDBUF: BLOCK HANDBUF.SIZE,0 ; MASKARE: BLOCK 8,0 ; имя файла BLOCK 3,0 ; расш. BLOCK 21,0 ; 11+21=32 ;TMP_BYTE: DB 0 ; ACCESS: ; ;PATH0: DW #0000 ;ACCESS: DB #00 ;DTABUF: DW #0000 ;CURHND: DW #0000 ;NO_NEXT: DB #00 ;.YES EQU 0 ;.NO EQU #FF ;FNDMODE: DB #00 ;//MODULE: DOS5 ;[END] ;DIRSIZE: WORD 0 ; размер списка каталога size_cash_directory ;!TODO ? GHANDLE: ; PUSH DE ; PUSH HL ; PUSH IX ; CALL TESTDSK ; JP C,G_HAND1 ; CALL LOADDIR ; POP DE ; LD HL,DIR ; LD BC,#0020 ;G_HAND2: ; LD A,D ; OR E ; JP Z,G_HAND3 ; ADD HL,BC ; DEC DE ; JP G_HAND2 ;G_HAND3: ; EXX ; POP DE ; EXX ;G_HAND4: ; EX DE,HL ; LD A,DIRPAGE ; CALL BANK ; EX DE,HL ; LD DE,HANDTA ; ; DUP 32 ; LDI ; EDUP ; ; EXX ; OUT (SLOT3),A ; LD HL,HANDTA ; ; DUP 32 ; LDI ; EDUP ; ; EXX ; POP BC ; DEC BC ; LD A,B ; OR C ; RET Z ; PUSH BC ; JP G_HAND4 ;G_HAND1 POP IX ; POP HL ; POP DE ; RET ;HANDTA BLOCK 32,0 ;----------------------------------------------------------------------; ; ;!TEST ; SAVE_CURRENT_PATH: ; SET_PAGE_X ENVPAGE ; PUSH AF ; CALL CURRDSK ; ADD A,"A" ; LD HL,TMP_CURDIR ; LD (HL),A ; INC HL ; LD A,":" ; LD (HL),A ; INC HL ; CALL CURRDIR ; POP AF ; OUT (SLOT3),A ; RET ; BACK_CURRENT_PATH: ; SET_PAGE_X ENVPAGE ; PUSH AF ; LD HL,TMP_CURDIR ; CALL CHDIR ; POP AF ; OUT (SLOT3),A ; RET ; ; ;----------------------------------------------------------------------; ;!TEST ;BANK: ; LD C,A ; LD B,0 ; LD HL,BANKTBL ; ADD HL,BC ; IN A,(SLOT3) ; LD C,SLOT3 ; OUTI ; RET ;