;----------------------------------------------------------------------; ; HL - 11 bytes filename "FILENAMEEXT" ; DE - DOS filename "FILENAME.EXT",0 ;!TODO LFN GetName: LD BC,#08FF ;!HARDCODE длина имени + счётчик LD A,' ' .loop: CP (HL) JR Z,.skip LDI DJNZ .loop JR .extension ; .skip: LD C,B LD B,0 ; CF=0 ADC HL,BC .extension: CP (HL) LD A,"." JR NZ,.copy_ext XOR A .copy_ext: 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 ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; ; old GETWORD ; Тест на допустимое имя и настроиться на диск. ; вход: hl=строка имени ; выход: (TMPNAME) SetPath_GetName: INC HL LD A,(HL) DEC HL CP ':' JR NZ,.dir_loop ; LD A,(HL) CP 'a' JR C,.next CP 'z'+1 JR NC,.next SUB %0010'0000 .next: SUB 'A' INC HL INC HL PUSH HL CALL CHDISK POP HL RET C LD A,(HL) OR A JR Z,.done CP ' ' JR Z,.done CP '\' ; SCF LD A,DSS_Error.sys.PATH_NOT_FOUND RET NZ INC HL ; .dir_loop: LD DE,CORE_BUFFERS.TMPNAME LD BC,256*CORE_BUFFERS.TMPNAME.Size + #FF .loop: LD A,(HL) INC HL CP '\' ; JR Z,.DIR_NAME ; LD (DE),A INC DE CP ' '+1 CCF RET NC DJNZ .loop LD A,DSS_Error.sys.INVALID_NAME SCF RET ; .done: XOR A LD (CORE_BUFFERS.TMPNAME),A RET ; .DIR_NAME: XOR A LD (DE),A PUSH HL LD HL,CORE_BUFFERS.TMPNAME CALL OPENDIR POP HL RET C JR .dir_loop ; ; Буфер имени 8.3 формата ;TMPNAME: DZ ' ' ; 12 пробелов и 0 ;!FIXIT к буферам ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; ; IN: A - drive number OPENDSK: ;!TEST DRV.Open обход R10 LD B,A LD A,(CORE_BUFFERS.FS_Buffer.DRIVE) CP B JR NZ,.open PUSH BC LD C,Dss.DRV.MediaCheck RST ToDSS.DRV POP BC JR Z,.exit JR C,.error JR .skip_open ;!FIXIT когда DRV.MediaCheck и DRV.Open будут отличаться ; .open: LD A,B ; .force: PUSH AF LD C,Dss.DRV.Open RST ToDSS.DRV POP BC JP C,.error ;[x] 29/02/2024 fix "open drive error" .skip_open: LD A,(CORE_BUFFERS.FS_Buffer.DRIVE) LD D,A PUSH DE ; LD A,B LD (CORE_BUFFERS.FS_Buffer.DRIVE),A ; CALL RD_BPB ; [ ] cdfs ;[x] 29/02/2024 fix "open drive error" POP DE JR C,.error_bpb ; RET C ; .exit: LD A,(LDRIVE) AND A RET ; !FIXIT костыль для Flex Navigator ; [ ] media change .error: CALL .error_convert LD A,C SCF RET ; .error_convert: CP DSS_Error.drv.INVALID_DRIVE LD C,DSS_Error.sys.INVALID_DRIVE RET Z ; CP DSS_Error.drv.ATAPI.UnitAttention LD C,DSS_Error.sys.MEDIA_CHANGED RET Z ; CP DSS_Error.drv.UNKNOWN_FORMAT LD C,DSS_Error.sys.UNKNOWN_FORMAT RET Z ; LD C,DSS_Error.sys.NOT_READY RET ; ;[x] 29/02/2024 fix "open drive error"; 20/06/2024 fixed .error_bpb: PUSH AF ; сохраняем номер ошибки LD A,(CORE_BUFFERS.FS_Buffer.DRIVE) CP D JR Z,.next_check ; LD A,D CP #FF SCF JR Z,.set_panic ; LD (CORE_BUFFERS.FS_Buffer.DRIVE),A CALL OPENDSK.force JR NC,.err_exit ; LD A,(BOOTDSK.NUM) LD (CORE_BUFFERS.FS_Buffer.DRIVE),A CALL OPENDSK.force ; .err_exit: LD A,(CORE_BUFFERS.FS_Buffer.DRIVE) ADD 'A' LD (CORE_BUFFERS.CurrentPath),A POP AF RET ; .next_check: LD A,(BOOTDSK.NUM) CP D SCF .reBPB: CALL NZ,OPENDSK.force ; проверка на ошибку .set_panic: LD HL,.NOT_READY LD E, +(80-.NOT_READY.size)/2 ; coord X LD BC,.NOT_READY.size JR NC,.err_exit JP KERNEL_PANIC ; .errorCycle: DB 0 .NOT_READY: DZ "Boot drive error..." .NOT_READY.size EQU $-.NOT_READY ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; ;!TEST Current Dir ;[x] 15/10/23 DIR_PATH_CHANGE: .FullCurrent: LD A,(CORE_BUFFERS.FS_Buffer.DRIVE) ADD 'A' LD (CORE_BUFFERS.CurrentPath),A ; .Current: LD HL,CORE_BUFFERS.CurrentDirectory JP CURRDIR ; .FullWork: LD A,(CORE_BUFFERS.CurrentPath) SUB 'A' LD (CORE_BUFFERS.FS_Buffer.DRIVE),A ; .Work: LD HL,CORE_BUFFERS.WorkDirectory JP CURRDIR_FN ; DIR_PATH_CHECK: LD A,(HL) CP '\' JR NZ,.notRootDir ; CALL .checkDrive RET Z LD A,(CORE_BUFFERS.CurrentPath) SUB 'A' JP OPENDSK ; .notRootDir: INC HL LD A,(HL) CP ':' RET Z ; .forceCheck: ;LD HL,CurrentDirectory+1 LD BC,CORE_BUFFERS.CurrentDirectory.DEPTH-1 CALL .checkDrive JR Z,.checkDir ; LD HL,CORE_BUFFERS.CurrentPath LD A,(CORE_BUFFERS.FS_Buffer.DRIVE) ADD 'A' CP (HL) JR NZ,.gotoPath ; .checkDir: LD HL,CORE_BUFFERS.CurrentDirectory+1 LD DE,CORE_BUFFERS.WorkDirectory+1 ; счётчик LD A,B LD B,C EX AF,AF' ; .loop: LD A,(DE) AND A JR Z,.end CP (HL) INC HL INC DE JR NZ,.gotoPath DJNZ .loop EX AF,AF' SUB 1 RET C EX AF,AF' DJNZ .loop ; .gotoPath: LD C,B EX AF,AF' LD B,A CALL FINDDIR.CHECK_SLASH LD A,DSS_Error.sys.PATH_NOT_FOUND RET C PUSH HL LD HL,CORE_BUFFERS.CurrentPath CALL SetPath_GetName POP HL RET C DEC HL LD (HL),0 RET ; .end: CP (HL) RET Z JR .gotoPath ; .checkDrive: LD HL,CORE_BUFFERS.CurrentPath LD A,(CORE_BUFFERS.FS_Buffer.DRIVE) ADD 'A' CP (HL) RET ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; CHECK_NAME: LD HL,CORE_BUFFERS.MASKARE .custom: LD BC,11 ;!HARDCODE LD A,"?" CPIR LD A,DSS_Error.sys.INVALID_NAME SCF RET ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; ;FMS DB FMCOUNT ;ACCESS MODE: ; 00 - READ/WRITE ; 01 - READ ; 02 - WRITE ;FM_BUF: ;File Manipulator (FM) ; BYTE '. ' ;+00 NAME ; BYTE ' ' ;+08 EXT ; BYTE #10 ;+11 ATTRIBUT ; BYTE 0 ;+12 RESERVED; !TODO следующий кластер для чтения ; BYTE 0 ;+13 RESERVED; !TODO следующий кластер для записи ; BLOCK 8,0 ;+14 RESERVED ; WORD #0000 ;+22 TIME ; WORD #0000 ;+24 DATE ; WORD #0000 ;+26 START CLUSTER ; DWORD #0000 ;+28 SIZE FILE ; DWORD #0000 ;+32 FILE POSITION (FP) ; WORD #0000 ;+36 DIRECTORY CLUSTER ; WORD #0000 ;+38 HANDLE NUMBER ; BYTE #00 ;+40 DRIVE OR CURRENT ; BYTE #00 ;+41 ACCESS MODE ; BYTE #00 ;+42 TASK ; BYTE #00 ;+43 EMPTY /* ;!TEST FM_BUF: _sFM .Size EQU _sFM BLOCK (FMCOUNT-1)*FM_BUF.Size, 0 */ //////////////////////////////////////////////////////////////////////// ; на выходе без ошибок IY указывает на файловый манипулятор FM_FIND: CP FMCOUNT+1 JR NC,.error ; PUSH DE LD IY,CORE_BUFFERS.FM_BUF LD DE,CORE_BUFFERS.FM_BUF.Size AND A JR Z,.endLoop .loop: ADD IY,DE DEC A JR NZ,.loop .endLoop: POP DE ; A=0 OR (IY) ;+00 NAME RET ; .error: XOR A LD A,DSS_Error.sys.INVALID_HANDLE RET SET_FM: CALL FM_FIND ; error ;LD A,DSS_Error.sys.INVALID_HANDLE ; CF = 1 SCF RET Z ; no error XOR A ;LD A,DSS_Error.sys.NO_ERROR ; CF = 0 RET RES_FM: CALL FM_FIND ; error ; LD A,DSS_Error.sys.INVALID_HANDLE SCF RET Z ; no error XOR A LD (IY + _sFM.FS_REC.NAME),A RET ; ;!TODO CHECK LOCKING GET_FM: LD B,FMCOUNT LD C,#FF LD IY,CORE_BUFFERS.FM_BUF - CORE_BUFFERS.FM_BUF.Size LD DE,CORE_BUFFERS.FM_BUF.Size .loop: ADD IY,DE INC C LD A,(IY + _sFM.FS_REC.NAME) OR A RET Z DJNZ .loop LD A,DSS_Error.sys.NO_HANDLES SCF RET ;FP COMPARE ; CY - FILE POINTER > SIZE ; NC - FILE POINTER < SIZE MOVE_CP: LD L,(IY + _sFM.FS_REC.F_SIZE) LD H,(IY + _sFM.FS_REC.F_SIZE+1) LD E,(IY + _sFM.F_POSITION) LD D,(IY + _sFM.F_POSITION+1) AND A SBC HL,DE LD L,(IY + _sFM.FS_REC.F_SIZE+2) LD H,(IY + _sFM.FS_REC.F_SIZE+3) LD E,(IY + _sFM.F_POSITION+2) LD D,(IY + _sFM.F_POSITION+3) SBC HL,DE RET ; ;----------------------------------------------------------------------; ; a..z -> A..Z UPPER: CP 'a' RET C CP 'z' + 1 JR NC,.CheckRUS .Dec: SUB #20 RET ; .CheckRUS: CP 'а' ; русская буква а, код #A0 RET C CP 'п'+1 ; русская буква п, код #AF + 1 JR C,.Dec ; .BGUPPER: CP 'р' ; русская буква р, код #E0 RET C CP 'Ё' ; русская буква Ё, код #F0 JR NC,.HGUPPER SUB #50 RET ; .HGUPPER: CP 'ё' ; русская буква ё, код #F1 RET NZ DEC A RET ;----------------------------------------------------------------------;