;[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 ;!FIXIT пока в виде заплатки полунеработающей ;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: XOR A CALL .OPENATR ;R02 RET C LD B,(IY+_sFM.ATTRIBUT) PUSH BC CALL CLOSE POP BC RET C LD A,B ;AND A RET .WATTRIB: PUSH AF XOR A CALL .OPENATR ;R02 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 POP BC RET C LD A,B ;AND A RET ;R02 .OPENATR: LD (F_FIRST.ACCESS),A ; раб. ячейка (здесь атрибут записи) CALL GETWORD ; тест на допуст. имя и настр. на диск RET C LD HL,TMPNAME LD DE,MASKARE CALL MASK RET C LD A,FAT_ATTR.NoVolID CALL SEARCH.ASEARCH ; JR NC,OPENAT ; на поиск своб. дескриптора ; ; запись не найдена ; RET 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 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 LD A,DSS_Error.sys.FILE_EXISTS CCF RET C ; .DO: LD HL,MASKARE LD DE,HANDBUF LD BC,11 LDIR EX DE,HL LD A,(F_FIRST.ACCESS) 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 CALL SAVEDIR .PATH0+1: LD HL,0 XOR A JP OPEN ;R08 .Prepare: AND #E7 ;R04 %76A00SHR = !FAT_ATTR LD (F_FIRST.ACCESS),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 LD HL,TMPNAME LD DE,MASKARE CALL MASK RET C ; ; LD DE,MASKARE ; CALL MASK ; RET C LD HL,MASKARE LD BC,11 LD A,"?" CPIR LD A,DSS_Error.sys.INVALID_NAME SCF RET Z CALL LOADDIR CALL SEARCH 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 PUSH HL PUSH DE CALL DIR_PATH_CHECK.forceCheck POP DE POP HL RET C ; PUSH DE LD DE,MASKARE CALL MASK POP DE RET C LD HL,MASKARE LD BC,11 LD A,"?" CPIR LD A,DSS_Error.sys.INVALID_NAME SCF RET Z PUSH DE CALL LOADDIR ; прочитать список каталога ;LD A,#33 LD A,FAT_ATTR.NoSYSnoVolID CALL SEARCH.ASEARCH ; поиск записи в списке диска POP HL RET C LD DE,MASKARE CALL MASK RET C LD HL,MASKARE LD BC,11 LD A,"?" CPIR LD A,DSS_Error.sys.INVALID_NAME SCF RET Z PUSH IX LD A,FAT_ATTR.NoSYSnoVolID CALL SEARCH.ASEARCH ; поиск записи в списке диска 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 запись ; выход: A - дескриптор файла, если CF=0 ; код ошибки, если CF=1 //////////////////////////////////////////////////////////////////////// OPEN_FN:;!Test Current Dir ;[x] 15/10/23 LD C,A PUSH HL PUSH BC CALL DIR_PATH_CHECK.forceCheck POP BC POP HL RET C LD A,C ; ;R08 OPEN: LD (F_FIRST.ACCESS),A CALL GETWORD RET C LD HL,TMPNAME LD DE,MASKARE CALL MASK RET C .FILE: CALL SEARCH RET C ;R02 .FM: CALL GET_FM 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 LD A,(F_FIRST.ACCESS) LD (IY+_sFM.ACCESS_MODE),A LD A,(TASK) LD (IY+_sFM.TASK_NUM),A XOR 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 (F_FIRST.ACCESS),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 D,(IY+_sFM.DIR_CLUSTER) LD E,(IY+_sFM.DIR_CLUSTER+1) PUSH DE XOR A CALL SET_FM POP DE LD (IY+_sFM.DIR_CLUSTER),D LD (IY+_sFM.DIR_CLUSTER+1),E CALL LOADDIR LD A,(F_FIRST.ACCESS) CALL SET_FM 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 D,YH LD E,YL EX DE,HL PUSH HL SET_PAGE_X DIRPAGE POP HL LD BC,#0020 LDIR OUT (SLOT3),A CALL SAVEDIR .NOTMODF: LD A,(F_FIRST.ACCESS) CALL RES_FM RET //////////////////////////////////////////////////////////////////////// ;Входные значения: ; C - #19 ; HL - указатель на файловую спецификацию ; DE - рабочий буфер 44 байта, если B=0, иначе 256 байт ; A - атрибуты, используемые при поиске ; B = 0 - имя найденного файла в формате 11 байт "FilenameExt" ; B = 1 - имя найденного файла в формате DOS "filename.ext",0 ;Выходные значения: ; A - код ошибки, если CF=1 //////////////////////////////////////////////////////////////////////// F_FIRST: ;!Test Current Dir 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 (.ACCESS),A LD (.DTABUF),DE LD A,B LD (.FNDMODE),A PUSH HL CALL LOADDIR POP HL CALL GETWORD RET C LD HL,TMPNAME LD DE,MASKARE CALL MASK RET C .ACCESS+1: LD A,0 CALL SEARCH.ASEARCH RET C LD HL,MASKARE .DTABUF+1: LD DE,0 LD BC,11 ;!HARDCODE LDIR LD A,(.ACCESS) 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 EXX LD DE,0 EXX .CURHND+2: LD IX,0 LD A,XH OR XL JP Z,SEARCH.error JP SEARCH.SEARCH1 //////////////////////////////////////////////////////////////////////// ; ; //////////////////////////////////////////////////////////////////////// CHNDISK_FN: CALL CHNDISK RET C PUSH AF CALL DIR_PATH_CHANGE.FullCurrent POP AF RET CHNDISK: ;!TEST CALL OPENDSK ;CALL OPENDSK.force ; ;????? R10 RET C LD HL,WorkDirectory LD (HL),0 PUSH AF CALL OPENDIR POP BC RET C LD A,B ; RET C ; PUSH AF ; CALL LOADDIR ; POP AF RET //////////////////////////////////////////////////////////////////////// ; Функция #1E. Информация о текущем каталоге. ; ; вход: HL - буфер в памяти 256 байт ; выход: A - код ошибки, если CF=1 ; !FIXIT может выйти за пределы буфера? //////////////////////////////////////////////////////////////////////// CURRDIR: LD DE,WorkDirectory JR CURRDIR_FN.skip CURRDIR_FN: LD DE,CurrentDirectory .skip: EX DE,HL XOR A .loop: CP (HL) LDI JR NZ,.loop 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 JP DIR_PATH_CHANGE.FullCurrent ; 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 LD C,A PUSH HL PUSH BC CALL DIR_PATH_CHECK POP BC POP HL RET C LD A,C ; CALL GETWORD ; тест на допуст. имя и настр. на диск RET C LD HL,TMPNAME ; 8.3 имя LD DE,MASKARE ; буфер имени 11 симв. формата CALL MASK ; преобр. имя 8.3 -> 11 формат RET C CALL LOADDIR ; прочитать список каталога CALL DSEARCH ; поиск записи каталога в списке диска 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 ; IF OLD_SET_BANK ; PUSH HL ; ENDIF SET_PAGE_X DIRPAGE ; IF OLD_SET_BANK ; POP HL ; ENDIF PUSH AF LD A,(DIR) CP "." 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 ; ячейка атрибутов файла .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 LDIR ;!FIXIT нужно ли так много грохать? 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 ;!FIXIT нужно ли так много грохать? 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 LD C,A PUSH HL PUSH BC CALL DIR_PATH_CHECK POP BC POP HL RET C LD A,C ; CALL GETWORD RET C LD HL,TMPNAME LD DE,MASKARE CALL MASK RET C LD HL,MASKARE LD BC,11 LD A,"?" CPIR LD A,DSS_Error.sys.INVALID_NAME SCF RET Z CALL LOADDIR CALL DSEARCH 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 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 ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; ; скопировать запись в список диска (каталога) WRT_HND: SET_PAGE_X DIRPAGE PUSH AF LD IX,DIR 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 ; POP 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 POP AF OUT (SLOT3),A LD HL,DIR LD BC,(SAVEDIR.DIRSIZE) DEC BC ADD HL,BC AND A SBC HL,DE RET NC LD HL,(SAVEDIR.DIRSIZE) LD BC,(FatBuffer.B_P_C) ADD HL,BC LD (SAVEDIR.DIRSIZE),HL 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 ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; ; Поиск записи каталога в списке каталога ; ; вход: a=атрибут записи ; выход: de'=индекс записи в списке каталога ; CF - каталог не найден DSEARCH: LD A,FAT_ATTR.DIRECTORY CALL SEARCH.ASEARCH RET NC LD A,DSS_Error.sys.PATH_NOT_FOUND RET ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; SEARCH: LD A,FAT_ATTR.NoDIRnoVolID .ASEARCH: EX AF,AF' ; 76ADLSHR SET_PAGE_X DIRPAGE PUSH AF EX AF,AF' CPL LD C,A LD IX,DIR EXX LD DE,0 EXX .SEARCH1: LD A,(IX+00) OR A JR Z,.SEARCH4 CP #E5 ;!HARDCODE #E5 - запись в директории свободна, так как файл/директория были удалены JR Z,.SEARCH3 LD A,(IX+11) AND C JR NZ,.SEARCH3 LD HL,MASKARE LD D,XH LD E,XL LD B,11 EX DE,HL .SEARCH2: LD A,(DE) CP '?' JR Z,.SEARCH5 CP (HL) JR NZ,.SEARCH3 .SEARCH5: INC HL INC DE DJNZ .SEARCH2 LD D,XH LD E,XL LD HL,HANDBUF EX DE,HL LD BC,HANDBUF.SIZE LDIR POP AF OUT (SLOT3),A AND A RET .SEARCH3: EXX INC DE EXX LD DE,#0020 ;!HARDCODE ADD IX,DE JR NC,SEARCH.SEARCH1 .error: POP AF OUT (SLOT3),A LD A,DSS_Error.sys.TOO_MANY_FILES_IN_DIR SCF RET .SEARCH4: POP AF OUT (SLOT3),A LD A,DSS_Error.sys.FILE_NOT_FOUND SCF RET ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; ; Тест на допустимое имя и настроиться на диск. ; вход: hl=строка имени 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 ;!TEST CHNDISK OPENDSK ;CALL OPENDSK CALL CHNDISK ; POP HL RET C ; .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 к буферам ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; ;????? R10 OPENDSK: ;!TEST DRV.Open обход 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: XOR A CALL SET_FM LD A,(HL) OR A JR NZ,.SUBDIR .REROOT1: LD DE,0 LD (IY+_sFM.ST_CLUSTER),E LD (IY+_sFM.ST_CLUSTER+1),D CALL LOADDIR ;LD HL,CurrentDirectory .dir+1: LD HL,WorkDirectory LD (HL),'\' INC HL LD (HL),#00 AND A RET .SUBDIR: CP "." JR NZ,.SUBDIR2 LD A,(IY+_sFM.ST_CLUSTER) ;R05 ;!FIXIT можно переделать на прямые ссылки без IY OR (IY+_sFM.ST_CLUSTER+1) ;R05 ;!FIXIT можно переделать на прямые ссылки без IY 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 .SUBDIR0: LDI LD A,(HL) OR A JR NZ,.SUBDIR0 JR .SUBDIR3 .SUBDIR2: LD DE,MASKARE CALL MASK RET C .SUBDIR3: CALL FINDDIR RET C LD (IY+_sFM.ST_CLUSTER),E LD (IY+_sFM.ST_CLUSTER+1),D LD DE,#4000 LD (IY+_sFM.F_SIZE),E LD (IY+_sFM.F_SIZE+1),D CALL LOADDIR AND A RET ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; ; FIND "MASKAREA" IN DIRECTORY FINDDIR: SET_PAGE_X DIRPAGE ; PUSH AF LD IX,DIR .F_01: LD A,(IX+00) OR A JR Z,.error CP #E5 JR Z,.F_03 LD A,(IX+11) AND #10 JR Z,.F_03 LD HL,MASKARE LD D,XH LD E,XL EX DE,HL LD B,11 .loop: LD A,(DE) CP "?" JR Z,.F_05 CP (HL) JR NZ,.F_03 .F_05: INC HL INC DE DJNZ .loop LD A,(IX+0) CP "." JP NZ,.ADDSPEC LD A,(IX+1) CP "." JP NZ,.IT_DIR ;LD HL,CurrentDirectory LD HL,WorkDirectory LD D,H LD E,L INC HL ;LD BC,CurrentDirectory.DEPTH LD BC,WorkDirectory.DEPTH XOR A CPIR ;!FIXIT нет проверки на завершение по BC=0 DEC HL ;R09 ;[x] исправлен баг с парсингом буфера каталога DEC HL ;LD BC,CurrentDirectory.DEPTH LD BC,WorkDirectory.DEPTH LD A,'\' CPDR INC HL ;AND A ; CF = 0 EX DE,HL SBC HL,DE EX DE,HL JR NZ,.MM3 JP .MM2_5 .F_03: LD BC,#0020 ADD IX,BC JR NC,.F_01 .error: POP AF OUT (SLOT3),A LD A,DSS_Error.sys.PATH_NOT_FOUND SCF RET .ADDSPEC: LD E,XL LD D,XH ;LD HL,CurrentDirectory+1 ;LD BC,CurrentDirectory.DEPTH-1 LD HL,WorkDirectory+1 LD BC,WorkDirectory.DEPTH-1 ; XOR A ; CPIR ;!FIXIT нет проверки на завершение по BC=0 ; DEC HL ; DEC HL ; LD A,'\' ; #5C ; CP (HL) ; INC HL ; JR Z,.ADDSPE0 ; LD (HL),A ; INC HL ; .ADDSPE0: CALL .CHECK_SLASH ;R11 LD A,B AND A JR NZ,.MM1 LD A,C CP 8 JR C,FINDDIR.error ;R11 LD BC,#0820 .MM1: LD A,(DE) INC DE CP C JR Z,.MM2 LD (HL),A ;!FIXIT вот тут может вылезать за пределы буфера при длинном пути и грохать код и данные. R11 времено лечит костылём INC HL .MM2 DJNZ .MM1 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 ;!FIXIT нет проверки на завершение по BC=0 DEC HL DEC HL LD A,'\' ; #5C CP (HL) INC HL RET Z LD (HL),A INC HL RET ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; ; Преобразовать имя 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 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,DIR ; куда LD DE,#4000 ; сколько XOR A ; дескриптор CALL READ ; чтение из файла 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) 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 ; чтение секторов RST ToDSS.DRV POP AF OUT (SLOT3),A AND A RET ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; ; Сбросить кеш каталога на диск. ; вход: 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,DIR ; размер списка каталога 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,DIR LD C,Dss.DRV.Write RST ToDSS.DRV POP AF OUT (SLOT3),A AND A RET ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; DIR_PATH_CHANGE: .FullCurrent: LD A,(FatBuffer.DRIVE) ADD 'A' LD (CurrentPath),A ; .Current: LD HL,WorkDirectory LD DE,CurrentDirectory LD BC,DIRECTORY_PATH_LENGTH LDIR RET ; .FullWork: LD A,(CurrentPath) SUB 'A' LD (FatBuffer.DRIVE),A ; .Work: LD HL,CurrentDirectory LD DE,WorkDirectory LD BC,DIRECTORY_PATH_LENGTH LDIR RET 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 ; JR .ReDir .end: CP (HL) RET Z .ReDir: LD HL,CurrentPath JR .gotoPath ; .checkDrive: LD HL,CurrentPath LD A,(FatBuffer.DRIVE) ADD 'A' CP (HL) RET .gotoPath: CALL FINDDIR.CHECK_SLASH JP GETWORD ;----------------------------------------------------------------------; ;!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 ; ;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 ;