From cfb3543373f36951d22a072a0388d9cbb6bcac46 Mon Sep 17 00:00:00 2001 From: Tolik <85737314+Tolik-Trek@users.noreply.github.com> Date: Thu, 11 Dec 2025 21:24:10 +1000 Subject: [PATCH] ... --- DSS/API/Close.asm | 7 +- DSS/API/Create.asm | 4 +- DSS/API/Delete.asm | 5 +- DSS/API/MkDir.asm | 4 +- DSS/API/Rename.asm | 10 +- DSS/API/RmDir.asm | 14 +- DSS/API/Write.asm | 2 +- DSS/FS/FAT.asm | 214 +++++----------- DSS/Structures.inc | 4 +- DSS/ToDo.txt | 17 +- DSS/defines.inc | 1 + DSS/drivers/media/ATAPI/Cd_dos.asm | 2 +- TMP_CODE.ASM | 377 +++++++++++++++++++++++++++++ 13 files changed, 484 insertions(+), 177 deletions(-) create mode 100644 TMP_CODE.ASM diff --git a/DSS/API/Close.asm b/DSS/API/Close.asm index e084673..3b0cb03 100644 --- a/DSS/API/Close.asm +++ b/DSS/API/Close.asm @@ -10,11 +10,13 @@ CLOSE_FN: 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 ; @@ -47,7 +49,7 @@ CLOSE_FN: LD (.TMP),A LD (IY+_sFM.FS_REC.FIRST_CLUSTER_L),E LD (IY+_sFM.FS_REC.FIRST_CLUSTER_L+1),D ; - CALL LOADDIR + CALL LOADDIR ; [ ] big dir ; [ ] big dir ;!TODO отмотать кэш до нужного record index? ; @@ -75,9 +77,6 @@ CLOSE_FN: LD (.TMP),A LD D,YH LD E,YL EX DE,HL - ;PUSH HL - ;SET_PAGE_X DIRPAGE - ;POP HL LD BC,FAT_DIRECTORY_RECORD LDIR EX AF,AF' diff --git a/DSS/API/Create.asm b/DSS/API/Create.asm index 7804fc6..38fc7d4 100644 --- a/DSS/API/Create.asm +++ b/DSS/API/Create.asm @@ -80,7 +80,7 @@ CREATE: ;!TEST Current Dir ;[x] 15/10/23 ;CREATE_FN: INC HL DJNZ .loop2 ; [ ] big dir передавать откуда и сколько байтов изменилось в кэш, чтоб не писать на диск лишнего - CALL WRT_HND + CALL WRITE_DIR_HANDLE RET C ;CALL SAVEDIR .PATH0+1: LD HL,0 @@ -97,7 +97,7 @@ CREATE: ;!TEST Current Dir ;[x] 15/10/23 ;CREATE_FN: LD (.PATH0),HL CALL SetPath_GetName RET C - ; [ ] 26/06/2024 + ; [x] 26/06/2024 {64 kb cluster} CALL CHECK_64kb_CLUSTER RET C ; diff --git a/DSS/API/Delete.asm b/DSS/API/Delete.asm index e5e92f0..d9fa466 100644 --- a/DSS/API/Delete.asm +++ b/DSS/API/Delete.asm @@ -10,7 +10,7 @@ DEL_FN: ;Current Dir ;[x] 15/10/23 ; CALL SetPath_GetName ; тест на допуст. имя и настр. на диск RET C - ; [ ] 26/06/2024 + ; [x] 26/06/2024 {64 kb cluster} CALL CHECK_64kb_CLUSTER RET C ; @@ -27,7 +27,8 @@ DEL_FN: ;Current Dir ;[x] 15/10/23 CALL CHECK_NAME ; RET Z - CALL LOADDIR + ; + CALL LOADDIR ; [ ] big dir CALL SEARCH.File RET C JP DELETE_REC_FAT ; пометить запись как "удаленная" diff --git a/DSS/API/MkDir.asm b/DSS/API/MkDir.asm index 81ef781..62d503e 100644 --- a/DSS/API/MkDir.asm +++ b/DSS/API/MkDir.asm @@ -28,7 +28,7 @@ MKDIR: ; .START: CALL SetPath_GetName ; тест на допуст. имя и настр. на диск RET C - ; [ ] 26/06/2024 + ; [x] 26/06/2024 {64 kb cluster} CALL CHECK_64kb_CLUSTER RET C ; @@ -101,7 +101,7 @@ MKDIR: INC HL DJNZ .loop2 ; [ ] big dir передавать откуда и сколько байтов изменилось в кэш, чтоб не писать на диск лишнего - CALL WRT_HND ; скопир. новую запись в список диска (каталога) + CALL WRITE_DIR_HANDLE ; скопир. новую запись в список диска (каталога) ;CALL SAVEDIR ; и сбросить кеш каталога на диск ; ; создаём служебные каталоги "." и ".." в созданном каталоге diff --git a/DSS/API/Rename.asm b/DSS/API/Rename.asm index 7bb24ba..344b400 100644 --- a/DSS/API/Rename.asm +++ b/DSS/API/Rename.asm @@ -19,7 +19,7 @@ RENAME: ;!TEST Current Dir ;[x] 15/10/23 ; ; !TODO воткнуть тут SetPath_GetName, чтоб можно было удалять по относительным путям? ; - ; [ ] 26/06/2024 + ; [x] 26/06/2024 {64 kb cluster} PUSH HL CALL CHECK_64kb_CLUSTER POP HL @@ -41,10 +41,10 @@ RENAME: ;!TEST Current Dir ;[x] 15/10/23 ; RET Z PUSH DE - CALL LOADDIR ; прочитать список каталога + CALL LOADDIR ; [ ] big dir ; прочитать список каталога ;LD A,#33 LD A,FAT_ATTR.NoSYSnoVolID - CALL SEARCH.Custom ; поиск записи в списке диска + CALL SEARCH.Custom ; поиск записи "old_name.ext" в списке диска POP HL RET C ;LD DE,MASKARE @@ -62,7 +62,7 @@ RENAME: ;!TEST Current Dir ;[x] 15/10/23 RET Z PUSH IX LD A,FAT_ATTR.NoSYSnoVolID - CALL SEARCH.Custom ; поиск записи в списке диска + CALL SEARCH.Custom ; поиск записи "new_name.ext" в списке диска POP IX LD A,DSS_Error.sys.FILE_EXISTS CCF @@ -77,7 +77,7 @@ RENAME: ;!TEST Current Dir ;[x] 15/10/23 LD BC,11 LDIR ; - CALL DELETE_LFN_RECORDS ; [ ] удаление записи LFN + CALL DELETE_LFN_RECORDS ; [ ] удаление записи LFN ; EX AF,AF' OUT (SLOT3),A diff --git a/DSS/API/RmDir.asm b/DSS/API/RmDir.asm index 1bc9517..c1bba29 100644 --- a/DSS/API/RmDir.asm +++ b/DSS/API/RmDir.asm @@ -23,23 +23,17 @@ RMDIR: ;!TEST Current Dir ;[x] 15/10/23 ; .START: CALL SetPath_GetName RET C - ; [ ] 26/06/2024 + ; [x] 26/06/2024 {64 kb cluster} CALL CHECK_64kb_CLUSTER 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 ; + CALL CHECK_NAME RET Z - CALL LOADDIR + ; + CALL LOADDIR ; [ ] big dir CALL SEARCH.Dir RET C ; fat32 ; [ ] CDFS diff --git a/DSS/API/Write.asm b/DSS/API/Write.asm index 90474ae..f28fbde 100644 --- a/DSS/API/Write.asm +++ b/DSS/API/Write.asm @@ -37,7 +37,7 @@ WRITE: ;!TEST ;!TODO 5/12/23 ; [ ] LD A,(IY + _sFM.DRIVE) CALL OPENDSK JR C,.ERR1 - ; [ ] 26/06/2024 + ; [x] 26/06/2024 {64 kb cluster} CALL CHECK_64kb_CLUSTER RET C ; diff --git a/DSS/FS/FAT.asm b/DSS/FS/FAT.asm index 15837ff..827dbc9 100644 --- a/DSS/FS/FAT.asm +++ b/DSS/FS/FAT.asm @@ -85,13 +85,15 @@ RW_SECTOR: IN A,(SLOT3) ; [ ] удаление записи LFN ; -; вход: IX = текущая запись в странице с каталогом FAT для которой +; вход: IX = указатель на текущую запись в странице с каталогом FAT для которой ; надо удалить записи LFS +; [ ] big dir DELETE_LFN_RECORDS: PUSH IX LD A,XH AND #C0 - SUB 1 + DEC A + ;SUB 1 LD C,A ; В регистре C маска для определения выхода за пределы страницы ; @@ -101,7 +103,7 @@ DELETE_LFN_RECORDS: .loop: ADD IX,DE LD A,XH CP C - JR Z,.beyond_boundaries + JR Z,.beyond_boundaries ; [ ] big dir тут надо подгружать предыдущий DIR_BLOCK ; LD A,FAT_ATTR.LFS_Entry CP (IX+FAT_DIRECTORY_RECORD.ATTRIBUT) @@ -488,7 +490,7 @@ OPENDIR: LD IY,CORE_BUFFERS.FM_BUF .REROOT: LD DE,0 ; !FIXIT ; [ ] CDFS - брать первый кластер из переменной LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_L),DE LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_H),DE - CALL LOADDIR + CALL LOADDIR ; [ ] big dir ; CF=0 LD HL,CORE_BUFFERS.WorkDirectory LD (HL),'\' @@ -529,16 +531,20 @@ OPENDIR: LD IY,CORE_BUFFERS.FM_BUF ; fat32 .SUBDIR3: CALL FINDDIR 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 + ; [ ] big dir + ; ... + ; ;LD HL,#4000 ;!HARDCODE ;LD (CORE_BUFFERS.FM_BUF.FS_REC.F_SIZE),HL ;-------------; EX DE,HL ; JP LOADDIR ; Прочитать список каталога -; [x] fat32 ;!TEST +; вход (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_L), (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_H) LOADDIR: ;!TODO optimize CALL LOAD_SAVE_DIR_PREPARE .next: PUSH AF @@ -553,31 +559,31 @@ LOADDIR: ;!TODO optimize LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_L),HL LD HL,(CORE_BUFFERS.FS_Buffer.RootDirStartCluster_H) LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_H),HL - - ;LD HL,(CORE_BUFFERS.FS_Buffer.BytesPerCluster) ; !FIXIT вычитывать полностью каталог - LD HL,#4000 ; размер директории ;!HARDCODE + ;LD HL,(CORE_BUFFERS.FS_Buffer.BytesPerCluster) ; !FIXIT вычитывать полностью каталог + LD HL,DIRPAGE.size ; размер директории ;!HARDCODE LD (CORE_BUFFERS.FM_BUF.FS_REC.F_SIZE),HL ; -.read_dir: LD HL,DIRPAGE.buffer ; куда - LD DE,#4000 ; сколько - XOR A ; дескриптор - CALL READ ; чтение из файла +.read_dir: LD HL,DIRPAGE.buffer ; куда + LD DE,DIRPAGE.size ; сколько + XOR A ; дескриптор + CALL READ ; чтение из файла EX AF,AF' - LD (SAVEDIR.DIRSIZE),DE ; число прочит. байтов + LD (SAVEDIR.DIRSIZE),DE ; число прочит. байтов POP AF OUT (SLOT3),A EX AF,AF' RET ; -.LoadRootDir: LD HL,(CORE_BUFFERS.FS_Buffer.RootDirFirstSector_H) ;!TODO возможно, хватит LD HL,0 - LD IX,(CORE_BUFFERS.FS_Buffer.RootDirFirstSector_L) ; номер лог. сектора +.LoadRootDir: 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-каталога CP B JR NC,.RTD1 ; LD B,A ; число секторов -.RTD1: LD A,(CORE_BUFFERS.FS_Buffer.DRIVE) ; номер диска +.RTD1: LD A,(CORE_BUFFERS.FS_Buffer.DRIVE) ; ном +ер диска LD DE,DIRPAGE.buffer ; буфер LD C,Dss.DRV.Read ; чтение секторов RST ToDSS.DRV @@ -594,133 +600,46 @@ LOADDIR: ;!TODO optimize ;----------------------------------------------------------------------; + + ld + ; доделать передачу ID записи директории и загрузки по ней нужного куска в кэш ;!TODO FAT procedures ;----------------------------------------------------------------------; -/* -LOAD_SAVE_DIR_PREPARE: - ;!TODO optimize - XOR A ; FILE MANIPULATOR = 0 - LD H,A - LD L,A - LD IX,0 - LD B,A ; от начала файла - CALL MOVE_FP - - SET_PAGE_X DIRPAGE - AND A - PUSH AF - ; - LD A,(CORE_BUFFERS.FS_Buffer.DRIVE) - LD (CORE_BUFFERS.FM_BUF.DRIVE),A - ;;;;;;;; - ;LD A,(IY+_sFM.FS_REC.FIRST_CLUSTER_L) - ;OR (IY+_sFM.FS_REC.FIRST_CLUSTER_L+1) - ;OR (IY+_sFM.FS_REC.FIRST_CLUSTER_H) - ;OR (IY+_sFM.FS_REC.FIRST_CLUSTER_H+1) - ; - XOR A - LD D,#40 - LD E,A - LD HL,(CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_L) - EXX - LD D,A - LD E,A - LD HL,(CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_H) - OR H - OR L - EXX - OR H - OR L - ;;;;;;;; - PUSH AF - CALL NZ,.CalcDirSize - ; - LD (CORE_BUFFERS.FM_BUF.FS_REC.F_SIZE),DE - EXX - LD (CORE_BUFFERS.FM_BUF.FS_REC.F_SIZE + 2),DE - POP AF - EX AF,AF' - POP AF - RET - ; -.CalcDirSize: ; calc dir size in clusters - LD DE,0 - ;LD HL,(CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_L) - ;EXX - ; LD HL,(CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_H) -.loop: ; ; - ;EXX - INC DE ; Надеемся тут на то, что спецификация выполняется и переполнения не будет - PUSH DE - CALL READ_FROM_FAT - EX DE,HL - POP DE - EXX - EX DE,HL - EXX - JR NC,.loop - ; - ; DE - размер директории в кластерах - ;!FIXIT можно оптимизнуть кол-во сдвигов - ;0001 0000 0000 0000 max кол-во кластеров - ; пример - ;0000 0000 0000 0111 Clusters - ; 0100 0000 SectorsPerCluster - ;0000 0010 0000 0000 BytesPerSector - ; D' E' D E - ;0000 0000 0000 0011 1000 0000 0000 0000 - ; - LD A,(CORE_BUFFERS.FS_Buffer.SectorsPerCluster) - LD BC,(CORE_BUFFERS.FS_Buffer.BytesPerSector) - ; DE':DE - кол-во кластеров - ; A - размер кластера в секторах - ; BC - размер сектора в байтах - ; --> DE*BC*A = DE':DE для ответа хватит, походу, 4х регистров - EXX - LD DE,0 - EXX - SRL B - RR C - RRCA - JR C,.loop2 - ; -.loop1: ; - SLA E - RL D - EXX - RL E - RL D - ;RL C - EXX - ; - RRCA - JR NC,.loop1 - ; -.loop2: ; - SLA E - RL D - EXX - RL E - RL D - ;RL C - EXX - ; - SRL B - RR C - JR NC,.loop2 - ; <-- DE*BC*A = DE':DE - RET -*/ ; Вход: -; ID записи, который должен попасть в КЭШ +; HL - ID записи, который должен попасть в КЭШ LOAD_SAVE_DIR_PREPARE: - ;!TODO optimize - XOR A ; FILE MANIPULATOR = 0 - LD H,A + ; [ ] Вход: HL - ID записи, который должен попасть в КЭШ + ; [ ] Выход: HLIX - смещение в файле каталога на нужный блок по #4000 байтов + ; HLIX = (HL*32) & #1FC000 смещение на нужный блок по #4000 байтов + XOR A + LD XL,A LD L,A - LD IX,0 - LD B,A ; от начала файла - CALL MOVE_FP + LD A,H + AND #0E + RRA + RR L + RRA + RR L + RRA + RR L + LD E,L + LD XH,E + LD L,A + ; ; + ; + ; A = номер блока кэш директории + RL E + RLA + RL E + RLA + LD (CORE_BUFFERS.FS_Buffer.DIR_BLOCK),A + ; + XOR A ; FILE MANIPULATOR = 0 + ;LD H,A + ;LD L,A + ;LD IX,0 + LD B,A ; от начала файла + CALL MOVE_FP SET_PAGE_X DIRPAGE AND A @@ -839,11 +758,12 @@ LOAD_SAVE_DIR_PREPARE: ;----------------------------------------------------------------------; +; [ ] big dir ; скопировать запись в список диска (каталога) de ix iy ; и сбросить кеш каталога на диск ; вход: (HANDBUF) - запись каталога ; выход: DE - record index -WRT_HND: +WRITE_DIR_HANDLE: SET_PAGE_X DIRPAGE EX AF,AF' LD HL,DIRPAGE.buffer @@ -1047,13 +967,13 @@ FAT_BPB: LD A,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.DRIVE_TYPE) LD BC,(CORE_BUFFERS.FS_Buffer.BytesPerSector) LD A,B AND A - ; - RL C - RLA - RL C - RLA - RL C - RLA + ; BytesPerSector/FAT_DIRECTORY_RECORD (32) + RL C + RLA + RL C + RLA + RL C + RLA ; LD C,A LD B,0 ; BC - File handels per sector @@ -3019,7 +2939,7 @@ GET_OFFSET_IN_SECTORS: ;----------------------------------------------------------------------; -; [x] 26/06/2024& read only 64kb cluster ; !TODO cluster 64kb +; [x] 26/06/2024 {64 kb cluster} read only 64kb cluster ; !TODO cluster 64kb CHECK_64kb_CLUSTER: LD HL,(CORE_BUFFERS.FS_Buffer.BytesPerCluster) ; CF=0 diff --git a/DSS/Structures.inc b/DSS/Structures.inc index 27228f8..ddb0211 100644 --- a/DSS/Structures.inc +++ b/DSS/Structures.inc @@ -111,8 +111,8 @@ .UPD_FSINFO: BYTE 0 .FREE_CLUSTERS_COUNT_L: WORD #FFFF .FREE_CLUSTERS_COUNT_H: WORD #FFFF -.DIR_BLOCK BYTE #00 ; какой блок директории загружен в кэш директорий DIRPAGE -.DIR_BLOCK_CHANGES DWORD #00000000 ; какие из кусков в блоке кэш DIRPAGE изменились до сохранения +.DIR_BLOCK BYTE #00 ; [ ] big dir. какой блок директории загружен в кэш директорий DIRPAGE +.DIR_BLOCK_CHANGES DWORD #00000000 ; [ ] big dir. какие из кусков в блоке кэш DIRPAGE изменились до сохранения ;.FilesPerSector: BYTE #00 ; число файловых записей в секторе ;.ClustersPerBank: BYTE #00 ; A - Clusters per bank (16k) (число кластеров на блок ОЗУ) ;.READ_PG: BYTE #00 ;!TODO не используются некоторые значения, но задумка неплохая))) diff --git a/DSS/ToDo.txt b/DSS/ToDo.txt index 3bc3011..0145585 100644 --- a/DSS/ToDo.txt +++ b/DSS/ToDo.txt @@ -1,6 +1,21 @@ По полным директориям. +;[ ] Переделать WRITE_DIR_HANDLE для работы с любой записью в каталоге (сейчас ищет первую пустую, чтоб записать в неё) +;[ ] Все изменения в записях каталога делать в буфере CORE_BUFFERS.HANDBUF и сохранять через WRITE_DIR_HANDLE ;[ ] Переменная DIR_BLOCK показывающая какой блок директории в кэш. ;[ ] Переменная DIR_BLOCK_CHANGED показывающая какой из кусков в блоке кэш изменился до сохранения. Как в FAT. ;[ ] Процедуры меняющие данные в кэш директории должны менять DIR_BLOCK_CHANGED. ;[ ] Передавать в LOADDIR нужный блок для загрузки в кэш (или номер нужной записи каталога). -;[ ] LOAD_SAVE_DIR_PREPARE походу, переделать к херам вместе с LOADDIR и SAVEDIR \ No newline at end of file +;[ ] Передавать в SAVEDIR нужный блок для записи из кэш (или номер нужной записи каталога). +;[ ] LOAD_SAVE_DIR_PREPARE походу, переделать к херам вместе с LOADDIR и SAVEDIR + + +Перелопатить +;[ ] LOAD_SAVE_DIR_PREPARE +;[ ] LOADDIR +;[ ] SAVEDIR +;[ ] RENAME +;[ ] CLOSE_FN +;[ ] DEL_FN +;[ ] RMDIR +;[ ] OPENDIR +;[ ] DELETE_LFN_RECORDS \ No newline at end of file diff --git a/DSS/defines.inc b/DSS/defines.inc index 802ea96..24f0747 100644 --- a/DSS/defines.inc +++ b/DSS/defines.inc @@ -73,6 +73,7 @@ MINIMUM_BIOS_VERSION EQU 3*256 + 06 ; version 3.06 ; кэш списка каталога DIRPAGE EQU 0 + (low BANKTBL) .buffer EQU #C000 +.size EQU #4000 FATPAGE EQU 1 + (low BANKTBL) .cache EQU #C000 TXTPAGE EQU 2 + (low BANKTBL) diff --git a/DSS/drivers/media/ATAPI/Cd_dos.asm b/DSS/drivers/media/ATAPI/Cd_dos.asm index 2a16b23..8cc17b7 100644 --- a/DSS/drivers/media/ATAPI/Cd_dos.asm +++ b/DSS/drivers/media/ATAPI/Cd_dos.asm @@ -291,7 +291,7 @@ ACCESS DEFB #00 HANDBUF DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - +;WRITE_DIR_HANDLE WRT_HND LD A,DIRPAGE CALL BANK PUSH AF diff --git a/TMP_CODE.ASM b/TMP_CODE.ASM new file mode 100644 index 0000000..4cfc29a --- /dev/null +++ b/TMP_CODE.ASM @@ -0,0 +1,377 @@ +FAT_BPB: LD A,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.DRIVE_TYPE) + CP #F0 + JP C,RD_BPB.UnknownBPB + ; PREPARE + XOR A + LD (.UsesVarsFAT32),A + ; + ;EXX + LD H,A + LD L,A + LD D,A + LD E,A + EXX + ;[ ] fat32 + LD B,A + LD C,A + LD (CORE_BUFFERS.FS_Buffer.SectorsPerFAT_H),A ; [ ] fat32 + ; + LD HL,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.BytesPerSector) + LD (CORE_BUFFERS.FS_Buffer.BytesPerSector),HL + LD A,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.SectorsPerCluster) + LD (CORE_BUFFERS.FS_Buffer.SectorsPerCluster),A + ; calc. first sector FAT + LD HL,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.RESERVED_SECTORS) + LD (CORE_BUFFERS.FS_Buffer.FAT1_SEC_L),HL ; low word first sector FAT #1 + LD (CORE_BUFFERS.FS_Buffer.FAT2_SEC_L),HL ; low word first sector FAT #2 + ;[ ] fat32 + LD (CORE_BUFFERS.FS_Buffer.FAT1_SEC_H),BC ; high word first sector FAT #1 ; [ ] fat32 + LD (CORE_BUFFERS.FS_Buffer.FAT2_SEC_H),BC ; high word first sector FAT #1 ; [ ] fat32 + LD (CORE_BUFFERS.FS_Buffer.RootDirFirstSector_H),BC + ;LD (CORE_BUFFERS.FS_Buffer.END_CHAIN_CLUSTER_H),BC ; [ ] fat32 reset variables + ; + ; + LD DE,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.SectorsPerFAT16) + LD A,E + OR D + JR NZ,.skip_high + ; + LD (.UsesVarsFAT32),A + +/* + 0001 0000 0000 0000 max кол-во кластеров + 0000 0000 0000 0111 Clusters + 0100 0000 SectorsPerCluster + 0000 0010 0000 0000 BytesPerSector + D' E' D E + 0000 0000 0000 0011 1000 0000 0000 0000 + + + #FFFF<<5 = #1FFFE0 = 0000 0000 0001 1111 1111 1111 1110 0000 + + #FFFF номер записи + #1FFFE0 смещение на запись в файле директории + #1FFFE0 & #1FC000 смещение на нужный блок по #4000 байтов + #1FFFE0 & #3FFF Адрес нужной позиции в кэш + (#1FFFE0 & #1FC000)<<2 двигаем байт 2 и 3 чтоб получить номер блока + + H L + 0000 1011 1101 0001 3025 + 0001 0111 1010 0010 0000 3025*32 + 0001 0100 0000 0000 0000 and #1FC000 + 0011 1010 0010 0000 addr in page + + H L + 1111 1111 1111 1111 65535 + 0001 1111 1111 1111 1110 0000 65535*32 + L Xh Xl + 0001 1111 1100 0000 0000 0000 and #1FC000 + 0011 1010 0010 0000 addr in page + + 1 0111 1010 001 + 0000 0001 0111 1010 0010 0000 + + + +*/ + + + + + + + + +; Прочитать список каталога +; [x] fat32 ;!TEST +LOADDIR: ;!TODO optimize + CALL LOAD_SAVE_DIR_PREPARE +.next: PUSH AF + EX AF,AF' + JR NZ,.read_dir ; root dir or not + ; root dir + LD A,(CORE_BUFFERS.FS_Buffer.FAT_TYPE) + CP FAT_TYPE.x32 + JR NZ,.LoadRootDir + ; fat32 + LD HL,(CORE_BUFFERS.FS_Buffer.RootDirStartCluster_L) + LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_L),HL + LD HL,(CORE_BUFFERS.FS_Buffer.RootDirStartCluster_H) + LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_H),HL + ;LD HL,(CORE_BUFFERS.FS_Buffer.BytesPerCluster) ; !FIXIT вычитывать полностью каталог + LD HL,DIRPAGE.size + LD (CORE_BUFFERS.FM_BUF.FS_REC.F_SIZE),HL + ; +.read_dir: LD HL,DIRPAGE.buffer ; куда + LD DE,DIRPAGE.size ; сколько + XOR A ; дескриптор + CALL READ ; чтение из файла + EX AF,AF' + LD (SAVEDIR.DIRSIZE),DE ; число прочит. байтов + POP AF + OUT (SLOT3),A + EX AF,AF' + RET + ; +.LoadRootDir: 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-каталога + CP B + JR NC,.RTD1 + ; + LD B,A ; число секторов +.RTD1: LD A,(CORE_BUFFERS.FS_Buffer.DRIVE) ; номер диска + LD DE,DIRPAGE.buffer ; буфер + LD C,Dss.DRV.Read ; чтение секторов + RST ToDSS.DRV + ; !FIXIT нет проверки на ошибку + ; 21/04/2025 fix мусор в странице каталога, если каталог меньше страницы + BIT 7,D + JR Z,.exit + XOR A + LD (DE),A + ; +.exit: POP AF + OUT (SLOT3),A + RET + + +; Прочитать список каталога +; Вход: +; (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_L), (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_H) +; [ ] ID записи, который должен попасть в КЭШ +LOAD_SAVE_DIR_PREPARE: + ;!TODO optimize + XOR A ; FILE MANIPULATOR = 0 + LD H,A + LD L,A + LD IX,0 + LD B,A ; от начала файла + CALL MOVE_FP + ; + SET_PAGE_X DIRPAGE + AND A + PUSH AF + ; + LD A,(CORE_BUFFERS.FS_Buffer.DRIVE) + LD (CORE_BUFFERS.FM_BUF.DRIVE),A + ;;;;;;;; + ;LD A,(IY+_sFM.FS_REC.FIRST_CLUSTER_L) + ;OR (IY+_sFM.FS_REC.FIRST_CLUSTER_L+1) + ;OR (IY+_sFM.FS_REC.FIRST_CLUSTER_H) + ;OR (IY+_sFM.FS_REC.FIRST_CLUSTER_H+1) + ; + XOR A + LD D,#40 + LD E,A + LD HL,(CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_L) + EXX + LD D,A + LD E,A + LD HL,(CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_H) + OR H + OR L + EXX + OR H + OR L + ;;;;;;;; + PUSH AF + CALL NZ,.CalcDirSize + ; + LD (CORE_BUFFERS.FM_BUF.FS_REC.F_SIZE),DE + EXX + LD (CORE_BUFFERS.FM_BUF.FS_REC.F_SIZE + 2),DE + POP AF + EX AF,AF' + POP AF + RET + ; +.CalcDirSize: ; calc dir size in clusters + LD DE,0 + ;LD HL,(CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_L) + ;EXX + ; LD HL,(CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_H) +.loop: ; ; + ;EXX + INC DE ; Надеемся тут на то, что спецификация выполняется и переполнения не будет + PUSH DE + CALL READ_FROM_FAT + EX DE,HL + POP DE + EXX + EX DE,HL + EXX + JR NC,.loop + ; + ; DE - размер директории в кластерах + ;!FIXIT можно оптимизнуть кол-во сдвигов + ;0001 0000 0000 0000 max кол-во кластеров + ; пример + ;0000 0000 0000 0111 Clusters + ; 0100 0000 SectorsPerCluster + ;0000 0010 0000 0000 BytesPerSector + ; D' E' D E + ;0000 0000 0000 0011 1000 0000 0000 0000 + ; + LD A,(CORE_BUFFERS.FS_Buffer.SectorsPerCluster) + LD BC,(CORE_BUFFERS.FS_Buffer.BytesPerSector) + ; DE':DE - кол-во кластеров + ; A - размер кластера в секторах + ; BC - размер сектора в байтах + ; --> DE*BC*A = DE':DE для ответа хватит, походу, 4х регистров + EXX + LD DE,0 + EXX + SRL B + RR C + RRCA + JR C,.loop2 + ; +.loop1: ; + SLA E + RL D + EXX + RL E + RL D + ;RL C + EXX + ; + RRCA + JR NC,.loop1 + ; +.loop2: ; + SLA E + RL D + EXX + RL E + RL D + ;RL C + EXX + ; + SRL B + RR C + JR NC,.loop2 + ; <-- DE*BC*A = DE':DE + RET + +/* 4 3 2 1 + #FFFF<<5 = #1FFFE0 = 0000 0000 0001 1111 1111 1111 1110 0000 + + #FFFF номер записи + #1FFFE0 смещение на запись в файле директории + #1FFFE0 & #1FC000 смещение на нужный блок по #4000 байтов + #1FFFE0 & #3FFF Адрес нужной позиции в кэш + (#1FFFE0 & #1FC000)<<2 двигаем байт 2 и 3 чтоб получить номер блока +*/ + +;----------------------------------------------------------------------; + +; [ ] big dir +; скопировать запись в список диска (каталога) de ix iy +; и сбросить кеш каталога на диск +; вход: (HANDBUF) - запись каталога +; выход: DE - record index +WRITE_DIR_HANDLE: + SET_PAGE_X DIRPAGE + EX AF,AF' + LD HL,DIRPAGE.buffer + ;!TEST 9/11/23 record index + EXX + LD DE,0 + EXX + ; + LD BC,FAT_DIRECTORY_RECORD +.loop: ;LD A,(IX+00) + LD A,(HL) + OR A + JR Z,.WRT_HN2 + CP #E5 + JR Z,.WRT_HN2 + ;ADD IX,BC + ADD HL,BC + JR NC,.loop ;!FIXIT количество записей каталога = страница + ; + EX AF,AF' + OUT (SLOT3),A + LD A,DSS_Error.sys.ROOT_OVERFLOW + SCF + RET + ; +.WRT_HN2: ;LD D,XH + ;LD E,XL + EX DE,HL + LD HL,CORE_BUFFERS.HANDBUF + LD BC,CORE_BUFFERS.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,(CORE_BUFFERS.FS_Buffer.BytesPerCluster) + ADD HL,BC + LD (SAVEDIR.DIRSIZE),HL + AND A +.SAVEDIR: EXX + PUSH DE + EXX + ; [ ] big dir передавать откуда и сколько байтов изменилось в кэш, чтоб не писать на диск лишнего + CALL SAVEDIR + POP DE + RET +;----------------------------------------------------------------------; +; Сбросить кеш каталога на диск. +; вход: iy=структура дескриптора +; [ ] big dir получать откуда и сколько байтов изменилось в кэш, чтоб не писать на диск лишнего +SAVEDIR: ;!TODO optimize + CALL LOAD_SAVE_DIR_PREPARE + PUSH AF + EX AF,AF' + JR NZ,.save_dir + ; + LD A,(CORE_BUFFERS.FS_Buffer.FAT_TYPE) + CP FAT_TYPE.x32 + JR NZ,.SaveRootDir + ; fat32 + LD HL,(CORE_BUFFERS.FS_Buffer.RootDirStartCluster_L) + LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_L),HL + LD HL,(CORE_BUFFERS.FS_Buffer.RootDirStartCluster_H) + LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_H),HL + ; +.save_dir: LD HL,DIRPAGE.buffer + ; размер списка каталога size_cash_directory + ;!FIXIT если она нужна, то проверить на баги (например, размер дирректории меньше при открытии и больше после правок) + ; когда будет чтение кусками каталога в кэш, тут ещё счётчик прикрутить +.DIRSIZE+1: LD DE,0 + XOR A + CALL WRITE + POP AF + OUT (SLOT3),A + RET + ; +.SaveRootDir: 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, Root Dir max size in sectors + SUB B + JR NC,.RTD1S + ADD A,B + LD B,A +.RTD1S: LD A,(CORE_BUFFERS.FS_Buffer.DRIVE) + LD DE,DIRPAGE.buffer + LD C,Dss.DRV.Write + RST ToDSS.DRV + POP AF + OUT (SLOT3),A + RET + +