From e8cf44ae6ba5fb4f889913152b8706a83b4134ba Mon Sep 17 00:00:00 2001 From: Tolik <85737314+Tolik-Trek@users.noreply.github.com> Date: Mon, 12 Jan 2026 20:46:33 +1000 Subject: [PATCH] =?UTF-8?q?FINDDIR=20=D0=B2=D1=80=D0=BE=D0=B4=D0=B5=20OK?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DSS/API/Find.asm | 4 +- DSS/API/Open.asm | 2 +- DSS/API/Rename.asm | 22 ++++- DSS/API/Write.asm | 12 ++- DSS/DOS_FS.ASM | 3 + DSS/FS/FAT.asm | 222 +++++++++++++++++++-------------------------- DSS/ToDo.txt | 8 +- 7 files changed, 133 insertions(+), 140 deletions(-) diff --git a/DSS/API/Find.asm b/DSS/API/Find.asm index 93ab841..7988c5d 100644 --- a/DSS/API/Find.asm +++ b/DSS/API/Find.asm @@ -140,7 +140,9 @@ F_NEXT: EXX ; .CURHND+2: LD IX,0 ; адрес следующей записи в кэше директории - JP SEARCH.next_record + LD DE,SEARCH.for_F_NEXT + PUSH DE ; выход в SEARCH из SEARCH_RECORD_IN_DIR_CACHE + JP SEARCH_RECORD_IN_DIR_CACHE.next_record ; /* Любые изменения в директории убьют её. diff --git a/DSS/API/Open.asm b/DSS/API/Open.asm index 03444a4..09c4a7c 100644 --- a/DSS/API/Open.asm +++ b/DSS/API/Open.asm @@ -53,7 +53,7 @@ OPEN_FN: ; Current Dir 15/10/23 LDIR .TMP+1: LD A,0 LD (IY+_sFM.ACCESS_MODE),A - ; оптимизнул тут + ; !FIXIT оптимизнул тут ;LD A,(TASK) ;LD (IY+_sFM.TASK_NUM),A ;XOR A diff --git a/DSS/API/Rename.asm b/DSS/API/Rename.asm index 748eceb..a78b847 100644 --- a/DSS/API/Rename.asm +++ b/DSS/API/Rename.asm @@ -40,29 +40,41 @@ RENAME: ; Current Dir 15/10/23 ; LD A,FAT_ATTR.NoSYSnoVolID CALL SEARCH.Custom ; поиск записи "old_name.ext" в списке диска + ; DE - record index POP HL RET C - ;LD DE,MASKARE + ; + LD (.recordAddr),IX + ; на случай переключения страницы кэша после SEARCH.Custom "new_name.ext" + LD A,(CORE_BUFFERS.FS_Buffer.DirBlock) + LD (.DirBlock),A + LD (.recordIndex),DE + ; CALL MASK.name RET C ; CALL CHECK_NAME RET Z ; - PUSH IX + ;PUSH IX LD A,FAT_ATTR.NoSYSnoVolID CALL SEARCH.Custom ; поиск записи "new_name.ext" в списке диска - POP IX + ;POP IX LD A,DSS_Error.sys.FILE_EXISTS CCF RET C ; SET_PAGE_X DIRPAGE EX AF,AF' + ; на случай переключения страницы кэша после SEARCH.Custom "new_name.ext" + LD A,(CORE_BUFFERS.FS_Buffer.DirBlock) +.DirBlock+1: CP 0 +.recordIndex+1: LD DE,0 + SCF ; не пересчитывать размер директории + CALL NZ,LOADDIR.next ; LD HL,CORE_BUFFERS.MASKARE - LD D,XH - LD E,XL +.recordAddr+1: LD DE,0 LD BC,11 LDIR ; diff --git a/DSS/API/Write.asm b/DSS/API/Write.asm index f28fbde..3d1592f 100644 --- a/DSS/API/Write.asm +++ b/DSS/API/Write.asm @@ -29,13 +29,15 @@ WRITE: ;!TEST ;!TODO 5/12/23 ; [ ] PUSH DE CALL SET_FM JR C,.ERR1 + ; LD A,(IY+_sFM.ACCESS_MODE) AND Dss.Open.R JR NZ,.RD_ONLY + ; SET 7,(IY + _sFM.ACCESS_MODE) SET 5,(IY + _sFM.FS_REC.ATTRIBUT) LD A,(IY + _sFM.DRIVE) - CALL OPENDSK + CALL OPENDSK ;!FIXIT для сохранения директории используется. Может ли случиться, что диск сменится? JR C,.ERR1 ; [x] 26/06/2024 {64 kb cluster} CALL CHECK_64kb_CLUSTER @@ -49,6 +51,7 @@ WRITE: ;!TEST ;!TODO 5/12/23 ; [ ] PUSH BC SRL B JR Z,.WOV2 + ; PUSH HL PUSH DE PUSH BC @@ -56,6 +59,7 @@ WRITE: ;!TEST ;!TODO 5/12/23 ; [ ] CALL BLOCK_WRITE POP BC JR C,.ERR3 + ; LD C,B LD HL,(.R_POINT) LD DE,#0200 ;!HARDCODE sector size @@ -76,6 +80,7 @@ WRITE: ;!TEST ;!TODO 5/12/23 ; [ ] LD B,A OR C JR Z,.WOV6 + ; PUSH HL PUSH DE PUSH BC @@ -93,6 +98,7 @@ WRITE: ;!TEST ;!TODO 5/12/23 ; [ ] LD HL,(.R_POINT) POP BC JP C,.ERR2 + ; LDIR LD (.R_POINT),HL POP DE @@ -108,6 +114,7 @@ WRITE: ;!TEST ;!TODO 5/12/23 ; [ ] LD C,SLOT3 OUT (C),B RET C + ; .WOV6: LD HL,(.R_POINT) .S_POINT+1: LD DE,0 ; CF=0 @@ -152,6 +159,7 @@ WRITE: ;!TEST ;!TODO 5/12/23 ; [ ] EXX POP DE JP C,.ERR1 + ; LD HL,512 ;!HARDCODE ;!FIXIT ; [ ] sector size AND A SBC HL,DE @@ -161,6 +169,7 @@ WRITE: ;!TEST ;!TODO 5/12/23 ; [ ] AND A SBC HL,BC JR NC,.WOV3 + ; ADD HL,BC LD B,H LD C,L @@ -187,6 +196,7 @@ WRITE: ;!TEST ;!TODO 5/12/23 ; [ ] OUT (C),B POP HL JP C,.ERR2 + ; LD BC,1 ADD HL,BC EX DE,HL diff --git a/DSS/DOS_FS.ASM b/DSS/DOS_FS.ASM index a3a0717..9cd5da2 100644 --- a/DSS/DOS_FS.ASM +++ b/DSS/DOS_FS.ASM @@ -114,12 +114,15 @@ OPENDSK: ;!TEST DRV.Open 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 diff --git a/DSS/FS/FAT.asm b/DSS/FS/FAT.asm index c45ae5b..f13f11a 100644 --- a/DSS/FS/FAT.asm +++ b/DSS/FS/FAT.asm @@ -2116,12 +2116,14 @@ DELETE_LFN_RECORDS: ;----------------------------------------------------------------------; - +; [ ] big dir грузить тут начальную страницу в dir cache или перед вызовом? +; [ ] big dir всегда ли при вызове у нас правильные (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_L и H) для LOADDIR? ;----------------------------------------------------------------------; ; Поиск записи каталога в списке каталога -; вход: a = атрибут записи (.Custom) +; вход: A = атрибут записи (.Custom) ; (CORE_BUFFERS.MASKARE) - маска для поиска -; выход: de = индекс записи в списке каталога +; выход: DE - индекс записи в списке каталога +; IX - адрес найденой записи в SLOT3 ; (HANDBUF) = file's directory record ; CF - каталог не найден SEARCH: @@ -2141,8 +2143,34 @@ SEARCH: SET_PAGE_X DIRPAGE PUSH AF EX AF,AF' + CPL + CALL SEARCH_RECORD_IN_DIR_CACHE +.for_F_NEXT: JR C,.error ; - CPL + LD D,XH + LD E,XL + LD HL,CORE_BUFFERS.HANDBUF + EX DE,HL + LD BC,CORE_BUFFERS.HANDBUF.SIZE + LDIR + POP AF + OUT (SLOT3),A + AND A + EXX ; record index + RET + ; +.error: POP AF + OUT (SLOT3),A + LD A,DSS_Error.sys.FILE_NOT_FOUND + SCF + RET +;----------------------------------------------------------------------; + + + +;----------------------------------------------------------------------; +SEARCH_RECORD_IN_DIR_CACHE: + ;CPL LD C,A ;!TEST 9/11/23 record index EXX @@ -2152,13 +2180,16 @@ SEARCH: .loop_big: LD IX,DIRPAGE.buffer .loop: LD A,(IX + FAT_DIRECTORY_RECORD.NAME) OR A - JR Z,.error_file_not_found + SCF + RET Z ; not found + ; CP #E5 ;!HARDCODE #E5 - запись в директории свободна, так как файл/директория были удалены JR Z,.next_record + ; LD A,(IX + FAT_DIRECTORY_RECORD.ATTRIBUT) LD D,A AND C - JR NZ,.next_record +.type+0: JR NZ,.next_record ; LD A,C INC A @@ -2170,55 +2201,27 @@ SEARCH: .found_attr: LD HL,CORE_BUFFERS.MASKARE LD D,XH LD E,XL - LD B,11 + LD B,11 ;!HARDCODE dos name not LFN 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 - ; - LD D,XH - LD E,XL - ;!TEST 9/11/23 record index - ; EXX - ; PUSH DE ; record index - ; EXX - ;PUSH IX - ; - LD HL,CORE_BUFFERS.HANDBUF - EX DE,HL - LD BC,CORE_BUFFERS.HANDBUF.SIZE - LDIR - ; record index - ;POP DE - POP AF - ;EX AF,AF' - OUT (SLOT3),A - ;EX AF,AF' - AND A - EXX ; record index - RET + ;JR NZ,.next_record + JR Z,.next_char ; .next_record: ;!TEST 9/11/23 record index EXX INC DE EXX ; -.inc_rec_num: LD DE,FAT_DIRECTORY_RECORD + LD DE,FAT_DIRECTORY_RECORD ADD IX,DE JR NC,.loop ; - ; [ ] big dir - ; LD A,(F_FIRST.FNDMODE) ;!FIXIT big dir - неправильно использовать это, надо новую переменную - ; RLA - ; JR NC,.error_too_many_files - ; -; CF=1 + ; CF=1 ; !FIXIT root dir in LOADDIR ; !FIXIT если в кэш были изменения? .readDirNext: PUSH BC @@ -2229,59 +2232,40 @@ SEARCH: POP DE EXX POP BC - JR NC,.loop_big ; !FIXIT там нет CF на выходе + JR NC,.loop_big ; !FIXIT может быть ошибка чтения или при ZF - конец директории ; -.error_file_not_found: - POP AF - OUT (SLOT3),A - LD A,DSS_Error.sys.FILE_NOT_FOUND - SCF RET ; -; .error_too_many_files: -; POP AF -; OUT (SLOT3),A -; LD A,DSS_Error.sys.TOO_MANY_FILES_IN_DIR -; SCF -; RET - ; - +.next_char: INC HL + INC DE + DJNZ .loop_compare + ; CF=0 + RET ;----------------------------------------------------------------------; -;----------------------------------------------------------------------; +;----------------------------------------------------------------------; 20 28 ; FIND "MASKAREA" IN DIRECTORY ; выход: IY:DE - cluster number +; [ ] big dir всегда ли при вызове у нас правильные (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_L и H) для LOADDIR? FINDDIR: SET_PAGE_X DIRPAGE ; PUSH AF - LD IX,DIRPAGE.buffer -.big_loop: LD A,(IX + FAT_DIRECTORY_RECORD.NAME) - OR A - JR Z,.error + ;[ ] big dir ; !FIXIT заменить на цикличный перебор директории по страницам, чтоб не делать лишних загрузок + LD A,(CORE_BUFFERS.FS_Buffer.DirBlock) + AND A + CALL NZ,LOADDIR ; - CP #E5 - JR Z,.next_step - ; - LD A,(IX + FAT_DIRECTORY_RECORD.ATTRIBUT) - AND FAT_ATTR.DIRECTORY - JR Z,.next_step - ; - LD HL,CORE_BUFFERS.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,#28 ; JR Z,... + LD (SEARCH_RECORD_IN_DIR_CACHE.type),A ; search directory + LD A,FAT_ATTR.DIRECTORY + CALL SEARCH_RECORD_IN_DIR_CACHE + EX AF,AF + LD A,#20 ; JR NZ,... + LD (SEARCH_RECORD_IN_DIR_CACHE.type),A ; search + EX AF,AF + JR C,.error ; LD A,(IX + FAT_DIRECTORY_RECORD.NAME) CP "." @@ -2315,10 +2299,6 @@ FINDDIR: SET_PAGE_X DIRPAGE .MM3: LD (HL),0 JP .ITs_DIR ; -.next_step: LD BC,FAT_DIRECTORY_RECORD - ADD IX,BC - JR NC,.big_loop - ; .error: POP AF OUT (SLOT3),A LD A,DSS_Error.sys.PATH_NOT_FOUND @@ -2344,36 +2324,6 @@ FINDDIR: SET_PAGE_X DIRPAGE 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 - ; .ITs_DIR: ; fat32 LD E,(IX + FAT_DIRECTORY_RECORD.FIRST_CLUSTER_H) LD D,(IX + FAT_DIRECTORY_RECORD.FIRST_CLUSTER_H+1) @@ -2488,8 +2438,8 @@ OPENDIR: ; init JR NZ,.SUBDIR2 ; fat32 ; !TEST 04/01/2026 - ;EX DE,HL - CALL CHECK_ROOT_CLUSTER + EX DE,HL + CALL CHECK_ROOT_CLUSTER ;CALL CHECK_FIRST_CLUSTER EX DE,HL ; @@ -2524,21 +2474,29 @@ OPENDIR: ; init RET C ; EX DE,HL - LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_L),HL ; fat32 - LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_H),IY ; fat32 + LD A,(CORE_BUFFERS.FS_Buffer.FAT_TYPE) + CP FAT_TYPE.x32 + JR NZ,.setCluster ; [ ] big dir - ; ... + LD A,H + OR L + OR YH + OR YL + JR NZ,.setCluster + ; set root dir for fat32 + LD HL,(CORE_BUFFERS.FS_Buffer.RootDirStartCluster_L) + LD IY,(CORE_BUFFERS.FS_Buffer.RootDirStartCluster_H) +.setCluster: LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_L),HL + LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_H),IY ; fat32 ; - ;LD HL,#4000 ;!HARDCODE - ;LD (CORE_BUFFERS.FM_BUF.FS_REC.F_SIZE),HL -;-------------; EX DE,HL -; JP LOADDIR +;-------------; JP LOADDIR ;----------------------------------------------------------------------; ; Прочитать список каталога ; вход (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_L), (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_H) LOADDIR: ;!TODO optimize + ;!FIXIT если HL выйдет за размеры директории и DirBlock будет некорректным? LD HL,0 ; ID записи, который должен попасть в КЭШ -.Custom: AND A ; в LOAD_SAVE_DIR_PREPARE посчитается размер каталога директории +.Custom: AND A ; в LOAD_SAVE_DIR_PREPARE посчитается размер каталога директории .next: CALL LOAD_SAVE_DIR_PREPARE PUSH AF EX AF,AF' @@ -2546,7 +2504,7 @@ LOADDIR: ;!TODO optimize ; root dir ;LD A,(CORE_BUFFERS.FS_Buffer.FAT_TYPE) ;CP FAT_TYPE.x32 - JR Z,.LoadRootDir + JR Z,.LoadRootDirFAT12_16 ;CALL LOAD_SAVE_DIR_PREPARE.CalcDirSize ; fat32 ; LD HL,(CORE_BUFFERS.FS_Buffer.RootDirStartCluster_L) @@ -2575,10 +2533,17 @@ LOADDIR: ;!TODO optimize RET NZ ; читаем с начала CALL LOADDIR +.no_more: XOR A ;!FIXIT научить этому вызывающие процедуры ; 0 - нет ошибок. признак конца каталога SCF RET ; -.LoadRootDir: LD HL,(CORE_BUFFERS.FS_Buffer.RootDirFirstSector_H);!TODO возможно, хватит LD HL,0 +.LoadRootDirFAT12_16: + ; [ ] big dir + LD A,(CORE_BUFFERS.FS_Buffer.DirBlock) + AND A + JR NZ,.no_more + ; + LD HL,(CORE_BUFFERS.FS_Buffer.RootDirFirstSector_H);!TODO возможно, хватит LD HL,0 LD IX,(CORE_BUFFERS.FS_Buffer.RootDirFirstSector_L); номер лог. сектора LD A,(CORE_BUFFERS.FS_Buffer.DirSizeInSectors) LD B,32 ; !HARDCODE sector size 512. 16384/(sector 512). размер root-каталога ; [ ] sector size 512 @@ -2780,6 +2745,7 @@ LOAD_SAVE_DIR_PREPARE: ; вход: iy=структура дескриптора ; [ ] big dir получать откуда и сколько байтов изменилось в кэш, чтоб не писать на диск лишнего SAVEDIR: ;!TODO optimize + SCF ; не считать размер директории CALL LOAD_SAVE_DIR_PREPARE PUSH AF EX AF,AF' @@ -2800,7 +2766,7 @@ SAVEDIR: ;!TODO optimize ;!FIXIT если она нужна, то проверить на баги (например, размер дирректории меньше при открытии и больше после правок) ; когда будет чтение кусками каталога в кэш, тут ещё счётчик прикрутить .DirBlkSize+1: LD DE,0 - XOR A + XOR A ; FM CALL WRITE POP AF OUT (SLOT3),A diff --git a/DSS/ToDo.txt b/DSS/ToDo.txt index 74211e0..13cebd4 100644 --- a/DSS/ToDo.txt +++ b/DSS/ToDo.txt @@ -1,6 +1,6 @@ По полным директориям. ;[x] LOADDIR после READ выходить с CF, если прочитано 0 -;[ ] FINDDIR - пока работает только с тем, что было загружено в кэш и мало что находит, если страниц больше 1. +;[x] FINDDIR - пока работает только с тем, что было загружено в кэш и мало что находит, если страниц больше 1. ;[ ] Переделать WRITE_DIR_HANDLE для работы с любой записью в каталоге (сейчас ищет первую пустую, чтоб записать в неё) ;[ ] Все изменения в записях каталога делать в буфере CORE_BUFFERS.HANDBUF и сохранять через WRITE_DIR_HANDLE ;[x] Переменная DirBlock показывающая какой блок директории в кэш. @@ -12,9 +12,9 @@ Перелопатить -;[ ] FINDDIR -;[ ] LOAD_SAVE_DIR_PREPARE -;[ ] LOADDIR +;[x] FINDDIR +;[x] LOAD_SAVE_DIR_PREPARE +;[x] LOADDIR ;[ ] SAVEDIR ;[ ] RENAME ;[ ] CLOSE_FN