From 7d98613cb53f6809407f1caed3defeb216308bd6 Mon Sep 17 00:00:00 2001 From: Tolik <85737314+Tolik-Trek@users.noreply.github.com> Date: Mon, 17 Nov 2025 19:30:36 +1000 Subject: [PATCH] ... --- DSS/API/Close.asm | 1 + DSS/API/Create.asm | 2 +- DSS/API/MkDir.asm | 2 +- DSS/API/Rename.asm | 1 + DSS/FS/FAT.asm | 145 ++++++++++++++++++++++++++++++++++++++++++++- DSS/Structures.inc | 6 +- DSS/ToDo.txt | 6 ++ 7 files changed, 156 insertions(+), 7 deletions(-) create mode 100644 DSS/ToDo.txt diff --git a/DSS/API/Close.asm b/DSS/API/Close.asm index 33db8a2..e084673 100644 --- a/DSS/API/Close.asm +++ b/DSS/API/Close.asm @@ -82,6 +82,7 @@ CLOSE_FN: LD (.TMP),A LDIR EX AF,AF' OUT (SLOT3),A + ; [ ] big dir передавать откуда и сколько байтов изменилось в кэш, чтоб не писать на диск лишнего CALL SAVEDIR .NOTMODF: LD A,(.TMP) JP RES_FM diff --git a/DSS/API/Create.asm b/DSS/API/Create.asm index 7378abd..7804fc6 100644 --- a/DSS/API/Create.asm +++ b/DSS/API/Create.asm @@ -79,7 +79,7 @@ CREATE: ;!TEST Current Dir ;[x] 15/10/23 ;CREATE_FN: .loop2: LD (HL),C INC HL DJNZ .loop2 - ; + ; [ ] big dir передавать откуда и сколько байтов изменилось в кэш, чтоб не писать на диск лишнего CALL WRT_HND RET C ;CALL SAVEDIR diff --git a/DSS/API/MkDir.asm b/DSS/API/MkDir.asm index 6959be3..81ef781 100644 --- a/DSS/API/MkDir.asm +++ b/DSS/API/MkDir.asm @@ -100,7 +100,7 @@ MKDIR: .loop2: LD (HL),C INC HL DJNZ .loop2 - ; + ; [ ] big dir передавать откуда и сколько байтов изменилось в кэш, чтоб не писать на диск лишнего CALL WRT_HND ; скопир. новую запись в список диска (каталога) ;CALL SAVEDIR ; и сбросить кеш каталога на диск ; diff --git a/DSS/API/Rename.asm b/DSS/API/Rename.asm index 30597b6..7bb24ba 100644 --- a/DSS/API/Rename.asm +++ b/DSS/API/Rename.asm @@ -81,5 +81,6 @@ RENAME: ;!TEST Current Dir ;[x] 15/10/23 ; EX AF,AF' OUT (SLOT3),A + ; [ ] big dir передавать откуда и сколько байтов изменилось в кэш, чтоб не писать на диск лишнего JP SAVEDIR ; ; ; \ No newline at end of file diff --git a/DSS/FS/FAT.asm b/DSS/FS/FAT.asm index ef169ec..15837ff 100644 --- a/DSS/FS/FAT.asm +++ b/DSS/FS/FAT.asm @@ -596,7 +596,7 @@ LOADDIR: ;!TODO optimize ;!TODO FAT procedures ;----------------------------------------------------------------------; - +/* LOAD_SAVE_DIR_PREPARE: ;!TODO optimize XOR A ; FILE MANIPULATOR = 0 @@ -659,11 +659,19 @@ LOAD_SAVE_DIR_PREPARE: EX DE,HL EXX JR NC,.loop - ; DE - размер директории в кластерах ; + ; 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 - размер сектора в байтах @@ -702,6 +710,133 @@ LOAD_SAVE_DIR_PREPARE: JR NC,.loop2 ; <-- DE*BC*A = DE':DE RET +*/ +; Вход: +; 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 чтоб получить номер блока +*/ + ;----------------------------------------------------------------------; ; скопировать запись в список диска (каталога) de ix iy @@ -760,12 +895,14 @@ WRT_HND: .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 @@ -1368,6 +1505,7 @@ DELETE_REC_FAT: SET_PAGE_X DIRPAGE EX AF,AF' OUT (SLOT3),A EX AF,AF' + ; [ ] big dir передавать откуда и сколько байтов изменилось в кэш, чтоб не писать на диск лишнего JP Z,SAVEDIR ; сбросить кеш каталога на диск ; если размер файла не ноль .loop: ;EX DE,HL ; hl=номер кластера @@ -1395,6 +1533,7 @@ DELETE_REC_FAT: SET_PAGE_X DIRPAGE ;EX DE,HL JP NC,.loop CALL WRITE_FAT_TABLE + ; [ ] big dir передавать откуда и сколько байтов изменилось в кэш, чтоб не писать на диск лишнего JP SAVEDIR ; сбросить кеш каталога на диск ; Установить первым известным кластером для поиска свободного. diff --git a/DSS/Structures.inc b/DSS/Structures.inc index 51a6aa8..27228f8 100644 --- a/DSS/Structures.inc +++ b/DSS/Structures.inc @@ -80,7 +80,7 @@ ; STRUCT _sFS_Buffer .DRIVE: BYTE #FF -.FAT_TYPE: BYTE #00 ; TYPE FAT (12 - 12bit, 16 - 16bit, 32 - 32bit) ; fat32 +.FAT_TYPE: BYTE #00 ; TYPE FAT (12 - 12bit, 16 - 16bit, 32 - 32bit) .CacheBlock: WORD #0000 .CacheUpdated: BYTE #00 ;.SectorsPerBank: BYTE #00 @@ -106,11 +106,13 @@ .BytesPerSector: WORD #0000 .SectorsPerCluster: BYTE #00 .FSINFO_Sector: WORD #01 -.BPB_SERIAL_NUMBER: DWORD 0 +.BPB_SERIAL_NUMBER: DWORD #00000000 .BPB_LABEL: BLOCK 11,' ' ; 11 для FAT, 31 для CDFS .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 изменились до сохранения ;.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 new file mode 100644 index 0000000..3bc3011 --- /dev/null +++ b/DSS/ToDo.txt @@ -0,0 +1,6 @@ +По полным директориям. +;[ ] Переменная DIR_BLOCK показывающая какой блок директории в кэш. +;[ ] Переменная DIR_BLOCK_CHANGED показывающая какой из кусков в блоке кэш изменился до сохранения. Как в FAT. +;[ ] Процедуры меняющие данные в кэш директории должны менять DIR_BLOCK_CHANGED. +;[ ] Передавать в LOADDIR нужный блок для загрузки в кэш (или номер нужной записи каталога). +;[ ] LOAD_SAVE_DIR_PREPARE походу, переделать к херам вместе с LOADDIR и SAVEDIR \ No newline at end of file