Estex-DSS/DSS/FS/FAT/FAT.asm
2024-06-29 02:44:01 +10:00

1170 lines
27 KiB
NASM
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;[BEGIN]
;//MODULE: FAT
;//CREATE: 19-05-1998 AUTHOR: Denis Parinov
;//UPDATE: 24-10-1999 DNS Restore module
;---------------------------------------------------------------
;Rev Date Name Description
;---------------------------------------------------------------
;R08 14-11-2002 DNS IMPROVE BPB-FUNCTION
;R07 17-12-1999 DNS BUG FIX SIGNATURE #55AA AT 510 OFFSET
;---------------------------------------------------------------
;----------------------------------------------------------------------;
SET_FSInfo: LD A,(CORE_BUFFERS.FatBuffer.FAT_TYPE)
CP FAT_TYPE.x32
RET NZ
;
LD A,(CORE_BUFFERS.FatBuffer.UPD_FSINFO)
OR A
RET Z
;
; „¥« ¥¬ FSInfo ᥪâ®à
; ç¨á⨬ ᥪâ®à
LD HL,CORE_BUFFERS.SECTOR_BUFFER
LD DE,CORE_BUFFERS.SECTOR_BUFFER+1
LD (HL),0
LD BC,512 - 1 ;!HARDCODE à §¬¥à ᥪâ®à 
LDIR
; LEAD_SIGNATURE
LD HL,#5252
LD (CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.LEAD_SIGNATURE),HL
LD HL,#4161
LD (CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.LEAD_SIGNATURE + 2),HL
; DATA_SIGNATURE
LD HL,#7272
LD (CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.DATA_SIGNATURE),HL
LD HL,#6141
LD (CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.DATA_SIGNATURE + 2),HL
; SECTOR_SIGNATURE
LD HL,#AA55
LD (CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.SECTOR_SIGNATURE),HL
; FREE_CLUSTERS_COUNT
LD HL,(CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_L)
LD (CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.FREE_CLUSTERS_COUNT),HL
LD HL,(CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_H)
LD (CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.FREE_CLUSTERS_COUNT+2),HL
; FIRST_FREE_CLUSTER
LD HL,(G_CLUST.low)
LD (CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.FIRST_FREE_CLUSTER),HL
LD HL,(G_CLUST.high)
LD (CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.FIRST_FREE_CLUSTER+2),HL
; <20>¨è¥¬ ¥£® ­  ¢¨­â
XOR A
LD (CORE_BUFFERS.FatBuffer.UPD_FSINFO),A
JR WRITE_FSinfo
; ;
; <20>à®ç¨â âì BPB ¢ SECTOR_BUFFER
READ_BPB: LD C,Dss.DRV.GetBPB
JR RW_SECTOR
; ‡ ¯¨á âì FSinfo ¨§ SECTOR_BUFFER
WRITE_FSinfo: LD IX,(CORE_BUFFERS.FatBuffer.FSINFO_Sector)
LD HL,0
;JR WRITE_SECTOR
; ‡ ¯¨á âì ᥪâ®à ¨§ SECTOR_BUFFER
; ‚室: HL:IX = Logical Block (sector)
WRITE_SECTOR: LD BC,1*256 + Dss.DRV.Write
JR RW_SECTOR
; <20>à®ç¨â âì FSinfo ¢ SECTOR_BUFFER
READ_FSinfo: LD IX,(CORE_BUFFERS.FatBuffer.FSINFO_Sector)
LD HL,0
; <20>à®ç¨â âì ᥪâ®à ¢ SECTOR_BUFFER
; ‚室: HL:IX = Logical Block (sector)
READ_SECTOR: LD BC,1*256 + Dss.DRV.Read
;
RW_SECTOR: IN A,(SLOT3)
PUSH AF
IN A,(SLOT0)
OUT (SLOT3),A
;
LD A,(CORE_BUFFERS.FatBuffer.DRIVE)
LD DE,CORE_BUFFERS.SECTOR_BUFFER+#C000
RST ToDSS.DRV
EX AF,AF'
;
POP AF
OUT (SLOT3),A
EX AF,AF'
RET
;
; [ ] 㤠«¥­¨¥ § ¯¨á¨ LFN
;
; ¢å®¤: IX = ⥪ãé ï § ¯¨áì ¢ áâà ­¨æ¥ á ª â «®£®¬ FAT ¤«ï ª®â®à®©
; ­ ¤® 㤠«¨âì § ¯¨á¨ LFS
DELETE_LFN_RECORDS:
PUSH IX
LD A,XH
AND #C0
SUB 1
LD C,A
; ॣ¨áâॠC ¬ áª  ¤«ï ®¯à¥¤¥«¥­¨ï ¢ë室  §  ¯à¥¤¥«ë áâà ­¨æë
;
.find_LFN: LD DE, -(FAT_DIRECTORY_RECORD)
LD A,FAT_ATTR.LFS_Entry
;
.loop: ADD IX,DE
LD A,XH
CP C
JR Z,.beyond_boundaries
;
LD A,FAT_ATTR.LFS_Entry
CP (IX+FAT_DIRECTORY_RECORD.ATTRIBUT)
JR NZ,.exit
LD (IX+FAT_DIRECTORY_RECORD.NAME),#E5
JR .loop
;
.exit: AND A
.beyond_boundaries: ; !TODO ¯®¤£à㧪  ¤à㣮© ç á⨠ª â «®£ . ¯®ª  § £«ã誠
POP IX
RET
;----------------------------------------------------------------------;
; <20>®¨áª § ¯¨á¨ ª â «®£  ¢ ᯨ᪥ ª â «®£ 
;
; ¢å®¤: a =  âਡãâ § ¯¨á¨
; ¢ë室: de = ¨­¤¥ªá § ¯¨á¨ ¢ ᯨ᪥ ª â «®£ 
; (HANDBUF) = file's direcory record
; CF - ª â «®£ ­¥ ­ ©¤¥­
SEARCH:
.Dir: ;LD A,FAT_ATTR.DIRECTORY
LD A,FAT_ATTR.HiddenSysDir
CALL .Custom
RET NC
CP DSS_Error.sys.PATH_NOT_FOUND + 1
RET C
;
SCF
LD A,DSS_Error.sys.TOO_MANY_FILES_IN_DIR
RET
;
.File: LD A,FAT_ATTR.NoDIRnoVolID
.Custom: EX AF,AF' ; A = 76ADLSHR
SET_PAGE_X DIRPAGE
;PUSH AF
EX AF,AF'
;
CPL
LD C,A
LD IX,DIRPAGE.buffer
;!TEST 9/11/23 record index
; ®¯â¨¬¨§ æ¨ï ¤«ï ¨­¤¥ªá  § ¯¨á¨ ¢ ᯨ᪥ ª â «®£ .
; <09>®­ ¤®¡¨âáï ¢¥à­ãâì ¤«ï ¯¥à¥¡®à  ª â «®£  > #4000 ¡ ©â
; EXX
; LD DE,0
; EXX
;
.loop: LD A,(IX+FAT_DIRECTORY_RECORD.NAME)
OR A
JR Z,.error_file_not_found
CP #E5 ;!HARDCODE #E5 - § ¯¨áì ¢ ¤¨à¥ªâ®à¨¨ ᢮¡®¤­ , â ª ª ª ä ©«/¤¨à¥ªâ®à¨ï ¡ë«¨ 㤠«¥­ë
JR Z,.next_record
LD A,(IX+FAT_DIRECTORY_RECORD.ATTRIBUT)
AND C
JR NZ,.next_record
LD HL,MASKARE
LD D,XH
LD E,XL
LD B,11
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
; EXX
PUSH IX
;
LD HL,HANDBUF
EX DE,HL
LD BC,HANDBUF.SIZE
LDIR
;!TEST 9/11/23 record index
POP DE
;
EX AF,AF'
OUT (SLOT3),A
EX AF,AF'
AND A
RET
.next_record:
LD DE,FAT_DIRECTORY_RECORD
;!TEST 9/11/23 record index
; EXX
; INC DE
; EXX
;
ADD IX,DE
JR NC,.loop
.error_too_many_files:
EX AF,AF'
OUT (SLOT3),A
LD A,DSS_Error.sys.TOO_MANY_FILES_IN_DIR
SCF
RET
;
.error_file_not_found:
EX AF,AF'
OUT (SLOT3),A
LD A,DSS_Error.sys.FILE_NOT_FOUND
SCF
RET
;----------------------------------------------------------------------;
;
;!TODO ?
;GHANDLE:
; PUSH DE
; PUSH HL
; PUSH IX
; CALL TESTDSK
; JP C,G_HAND1
; CALL LOADDIR
; POP DE
; LD HL,DIR
; LD BC,FAT_DIRECTORY_RECORD
;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
;
;----------------------------------------------------------------------;
; FIND "MASKAREA" IN DIRECTORY
; [x] fat32 ;!TEST
; ¢ë室: IY:DE - cluster number
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
CP #E5
JR Z,.next_step
LD A,(IX + FAT_DIRECTORY_RECORD.ATTRIBUT)
AND FAT_ATTR.DIRECTORY
JR Z,.next_step
LD HL,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,(IX + FAT_DIRECTORY_RECORD.NAME)
CP "."
JP NZ,.ADDSPEC
LD A,(IX + FAT_DIRECTORY_RECORD.NAME + 1)
CP "."
JP NZ,.IT_DIR
LD HL,CORE_BUFFERS.WorkDirectory
LD D,H
LD E,L
INC HL
LD BC,CORE_BUFFERS.WorkDirectory.DEPTH
XOR A
CPIR
JP PO,.error ;[x] 20/11/23 ¯à®¢¥àª  ­  ¢ë室 §  £à ­¨æë
DEC HL ;R009
DEC HL
LD BC,CORE_BUFFERS.WorkDirectory.DEPTH
LD A,'\'
CPDR
INC HL
EX DE,HL
; CF = 0
SBC HL,DE
EX DE,HL
JR NZ,.MM3
INC HL
.MM3: LD (HL),0
JP .IT_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
SCF
RET
;
.ADDSPEC:
LD HL,CORE_BUFFERS.WorkDirectory+1
LD BC,CORE_BUFFERS.WorkDirectory.DEPTH-1
CALL .CHECK_SLASH
JR C,.error
;R011
LD A,B
AND A
JR NZ,.nxt
LD A,C
CP 8+1+3 ;!HARDCODE ¨¬ï ª â «®£  + â®çª  + à áè¨à¥­¨¥
JR C,.error
.nxt: ;
LD E,XL
LD D,XH
; [x] ®¯â¨¬¨§ æ¨ï ¯® à §¬¥àã
EX DE,HL
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
;
.IT_DIR:; fat32
LD E,(IX + FAT_DIRECTORY_RECORD.FIRST_CLUSTER_H)
LD D,(IX + FAT_DIRECTORY_RECORD.FIRST_CLUSTER_H+1)
LD YH,D
LD YL,E
LD E,(IX + FAT_DIRECTORY_RECORD.FIRST_CLUSTER_L)
LD D,(IX + FAT_DIRECTORY_RECORD.FIRST_CLUSTER_L+1)
POP AF
OUT (SLOT3),A
AND A
RET
.CHECK_SLASH:
XOR A
CPIR
;[x] 20/11/23 ¯à®¢¥àª  ­  ¢ë室 §  £à ­¨æë
SCF
RET PO
;
DEC HL
DEC HL
LD A,'\' ; #5C
CP (HL)
INC HL
RET Z
LD (HL),A
INC HL
LD (HL),0
;INC HL
RET
;----------------------------------------------------------------------;
CHECK_ROOT_CLUSTER:
EX DE,HL
LD HL,(CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_L) ;R005
LD A,L
OR H
LD HL,(CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_H)
OR L
OR H
EX DE,HL
RET
;----------------------------------------------------------------------;
; ¢å®¤: HL - ¨¬ï ¤¨à¥ªâ®à¨¨
; [x] fat32 ;!TEST
OPENDIR: LD IY,CORE_BUFFERS.FM_BUF
LD A,(HL)
OR A
JR NZ,.SUBDIR
;
.REROOT: LD DE,0
LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_L),DE
LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_H),DE
CALL LOADDIR
; CF=0
LD HL,CORE_BUFFERS.WorkDirectory
LD (HL),'\'
INC HL
LD (HL),#00
;AND A
RET
;
.SUBDIR: CP "."
JR NZ,.SUBDIR2
; fat32
CALL CHECK_ROOT_CLUSTER
JR NZ,.no_root ;R005
; "cd ." or "cd .."
;R005
INC HL
LD A,(HL)
OR A
DEC HL
JR Z,.REROOT
;
.no_root: EXX
LD HL,MASKARE
LD DE,MASKARE+1
LD BC,10 ;!HARDCODE
LD (HL),' '
LDIR
EXX
LD DE,MASKARE
.loop: LDI
LD A,(HL)
OR A
JR NZ,.loop
JR .SUBDIR3
;
.SUBDIR2: CALL MASK.name
RET C
; 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
LD HL,#4000 ;!HARDCODE
LD (CORE_BUFFERS.FM_BUF.FS_REC.F_SIZE),HL
;-------------; EX DE,HL
; JP LOADDIR
; <20>à®ç¨â âì ᯨ᮪ ª â «®£ 
; [x] fat32 ;!TEST
LOADDIR: ;!TODO optimize
CALL LOAD_SAVE_DIR_PREPARE
PUSH AF
EX AF,AF'
JR NZ,.read_dir
LD A,(CORE_BUFFERS.FatBuffer.FAT_TYPE)
CP FAT_TYPE.x32
JR NZ,.LoadRootDir
; fat32
LD HL,(CORE_BUFFERS.FatBuffer.RootDirStartCluster_L)
LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_L),HL
LD HL,(CORE_BUFFERS.FatBuffer.RootDirStartCluster_H)
LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_H),HL
;LD HL,(CORE_BUFFERS.FatBuffer.BytesPerCluster) ; !FIXIT ¢ëç¨â뢠âì ¯®«­®áâìî ª â «®£
LD HL,#4000 ; à §¬¥à ¤¨à¥ªâ®à¨¨
LD (CORE_BUFFERS.FM_BUF.FS_REC.F_SIZE),HL
;
.read_dir: LD HL,DIRPAGE.buffer ; ªã¤ 
LD DE,#4000 ; ᪮«ìª®
XOR A ; ¤¥áªà¨¯â®à
CALL READ ; ç⥭¨¥ ¨§ ä ©« 
LD (SAVEDIR.DIRSIZE),DE ; ç¨á«® ¯à®ç¨â. ¡ ©â®¢
POP AF
OUT (SLOT3),A
RET
;
.LoadRootDir: LD HL,(CORE_BUFFERS.FatBuffer.RootDirFirstSector_H) ;!TODO ¢®§¬®¦­®, 墠â¨â LD HL,0
LD IX,(CORE_BUFFERS.FatBuffer.RootDirFirstSector_L) ; ­®¬¥à «®£. ᥪâ®à 
LD A,(CORE_BUFFERS.FatBuffer.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.FatBuffer.DRIVE) ; ­®¬¥à ¤¨áª 
LD DE,DIRPAGE.buffer ; ¡ãä¥à
LD C,Dss.DRV.Read ; ç⥭¨¥ ᥪâ®à®¢
RST ToDSS.DRV
POP AF
OUT (SLOT3),A
RET
;----------------------------------------------------------------------;
;!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
EX AF,AF'
;
LD A,(CORE_BUFFERS.FatBuffer.DRIVE)
LD (IY+_sFM.DRIVE),A
;!FIXIT ¯¥à¥¤¥« âì ­  à ¡®âã ¡¥§ IY
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)
;
EX AF,AF'
RET
;----------------------------------------------------------------------;
; ᪮¯¨à®¢ âì § ¯¨áì ¢ ᯨ᮪ ¤¨áª  (ª â «®£ ) de ix iy
; ¨ á¡à®á¨âì ª¥è ª â «®£  ­  ¤¨áª
; ¢å®¤: (HANDBUF) - § ¯¨áì ª â «®£ 
WRT_HND:
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,HANDBUF
LD BC,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.FatBuffer.BytesPerCluster)
ADD HL,BC
LD (SAVEDIR.DIRSIZE),HL
AND A
;JP SAVEDIR
;----------------------------------------------------------------------;
; ‘¡à®á¨âì ª¥è ª â «®£  ­  ¤¨áª.
; ¢å®¤: iy=áâàãªâãà  ¤¥áªà¨¯â®à 
; [x] fat32 ;!TEST
SAVEDIR: ;!TODO optimize
CALL LOAD_SAVE_DIR_PREPARE
PUSH AF
EX AF,AF'
JR NZ,.save_dir
;
LD A,(CORE_BUFFERS.FatBuffer.FAT_TYPE)
CP FAT_TYPE.x32
JR NZ,.SaveRootDir
; fat32
LD HL,(CORE_BUFFERS.FatBuffer.RootDirStartCluster_L)
LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_L),HL
LD HL,(CORE_BUFFERS.FatBuffer.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.FatBuffer.RootDirFirstSector_H) ;!TODO ¢®§¬®¦­®, 墠â¨â LD HL,0
LD IX,(CORE_BUFFERS.FatBuffer.RootDirFirstSector_L)
LD A,(CORE_BUFFERS.FatBuffer.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.FatBuffer.DRIVE)
LD DE,DIRPAGE.buffer
LD C,Dss.DRV.Write
RST ToDSS.DRV
POP AF
OUT (SLOT3),A
RET
;----------------------------------------------------------------------;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
; [x] fat32 ;!TEST
RD_BPB: ; LD C,SLOT3
; IN B,(C)
; PUSH BC
; IN A,(SLOT0)
; OUT (SLOT3),A
; LD A,(CORE_BUFFERS.FatBuffer.DRIVE)
; LD DE,CORE_BUFFERS.SECTOR_BUFFER+#C000 ;R08
; LD C,Dss.DRV.GetBPB
; RST ToDSS.DRV
; POP BC
; OUT (C),B
CALL READ_BPB
JP C,DOS_X_Error.Not_ready
;
LD DE,#AA55 ; ᨣ­ âãà  ;R05
LD HL,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.MBR_SIGNATURE) ;R08 ;R07
;R05
AND A
SBC HL,DE
JP NZ,DOS_X_Error.UnknownBPB
;
; ;R08 ; [x] fat32
; LD HL,CORE_BUFFERS.SECTOR_BUFFER
; LD DE,CORE_BUFFERS.BootSector
; LD BC,_sBOOT_SECTOR_PARAMS_FAT32 ; size
; LDIR
;
LD A,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.DRIVE_TYPE)
CP #F0
JP C,DOS_X_Error.UnknownBPB
;
LD HL,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.BytesPerSector)
LD (CORE_BUFFERS.FatBuffer.BytesPerSector),HL
LD A,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.SectorsPerCluster)
LD (CORE_BUFFERS.FatBuffer.SectorsPerCluster),A
; calc. first sector FAT
LD HL,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.RESERVED_SECTORS)
LD (CORE_BUFFERS.FatBuffer.FAT1_SEC_L),HL ; low word first sector FAT #1
LD (CORE_BUFFERS.FatBuffer.FAT2_SEC_L),HL ; low word first sector FAT #2
;[ ] fat32
XOR A
LD B,A
LD C,A
LD (CORE_BUFFERS.FatBuffer.FAT1_SEC_H),BC ; high word first sector FAT #1 ; [ ] fat32
LD (CORE_BUFFERS.FatBuffer.FAT2_SEC_H),BC ; high word first sector FAT #1 ; [ ] fat32
LD (CORE_BUFFERS.FatBuffer.RootDirFirstSector_H),BC
LD (CORE_BUFFERS.FatBuffer.SectorsPerFAT_H),A ; [ ] fat32
;LD (CORE_BUFFERS.FatBuffer.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 BC,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.SectorsPerFAT32 + 2)
LD A,C
LD (CORE_BUFFERS.FatBuffer.SectorsPerFAT_H),A
LD DE,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.SectorsPerFAT32)
.skip_high: LD (CORE_BUFFERS.FatBuffer.SectorsPerFAT_L),DE
LD A,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.Number_of_FATs) ; amount FATs
LD (CORE_BUFFERS.FatBuffer.Number_Of_FATs),A
CP 1
JR Z,.one_FAT
DEC A
ADD HL,DE
LD (CORE_BUFFERS.FatBuffer.FAT2_SEC_L),HL
JR NC,.no_inc_BC
INC BC
.no_inc_BC: LD (CORE_BUFFERS.FatBuffer.FAT2_SEC_H),BC
.one_FAT: ;C_DATA1
.loop1: ADD HL,DE
JR NC,.loop1_1
INC BC
.loop1_1: DEC A
JR NZ,.loop1
;
LD (CORE_BUFFERS.FatBuffer.RootDirFirstSector_L),HL ; first sector DIR
LD (CORE_BUFFERS.FatBuffer.FirstDataSector_H),BC
;
LD BC,(CORE_BUFFERS.FatBuffer.BytesPerSector)
LD A,B
AND A
;
RL C
RLA
RL C
RLA
RL C
RLA
;
LD C,A
LD B,0 ; BC - File handels in sectors
;;;;
IF COMPILE_UNUSED_CODE
LD (CORE_BUFFERS.FatBuffer.FilesPerSector),A
ENDIF
;
EX DE,HL
LD HL,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.FilesInRootDIR) ; 0 for fat32
; [ ]fat32 ;!TEST
LD A,H
OR L
JR Z,.skip_loop2
;
DEC HL
XOR A
;NEXTAD2
.loop2: INC A
JP Z,DOS_X_Error.UnknownBPB
SBC HL,BC
JR NC,.loop2
;
.skip_loop2: EX DE,HL
LD C,A ; A - sectors in DIR
LD B,0
LD (CORE_BUFFERS.FatBuffer.DirSizeInSectors),A
ADD HL,BC ; Start DATA area
LD (CORE_BUFFERS.FatBuffer.FirstDataSector_L),HL
; B = 0
;
LD HL,(CORE_BUFFERS.FatBuffer.BytesPerSector)
LD A,(CORE_BUFFERS.FatBuffer.SectorsPerCluster)
;!TODO FATcacheSize
; calc. cluster size
XOR 1
JR Z,.loop3.end
RRA
.loop3: ADD HL,HL
RRA
JP NC,.loop3
.loop3.end: ;
LD (CORE_BUFFERS.FatBuffer.BytesPerCluster),HL
;LD DE,#8001 ; ¯à®¢¥àª  ­  à §¬¥à ª« áâ¥à  ¡®«ìè¥ 32 ª¡ - ­¥ ¯®¤¤¥à¦¨¢ ¥âáï ; !TODO
;AND A
;SBC HL,DE
;JP NC,DOS_X_Error.UnknownBPB ; [ ] fixed bug, thanks to @Romychs (Roman Boykov)
////////////////////////////////////////////////////////////////////////
;!TODO ­¥ ¨á¯®«ì§ã¥âáï §­ ç¥­¨ï ¢ëç¨á«ï¥¬ë¥ ¨ á®åà ­ï¥¬ë¥ ¢ FatBuffer
; EX DE,HL
; LD HL,#3FFF ;!HARDCODE ;!TODO FATcacheSize
; XOR A
; ;NEXTAD4 ;!FIXIT ®¯â¨¬¨§¨à®¢ âì ª®£¤  ¯®­ ¤®¡¨âáï
;.loop4: INC A
; JP Z,DOS_X_Error.UnknownBPB
; SBC HL,DE
; JR NC,.loop4
; LD (CORE_BUFFERS.FatBuffer.ClustersPerBank),A ; A - Clusters per bank (16k)
;
; LD HL,0
; LD BC,(CORE_BUFFERS.SECTOR_BUFFER + _sBOOT_SECTOR_PARAMS.SectorsPerTrack) ; Sector per track
; LD A,(CORE_BUFFERS.SECTOR_BUFFER + _sBOOT_SECTOR_PARAMS.HEADS)
;.BPB_L1: ; calc. sector per cylinder
; ADD HL,BC
; DEC A
; JR NZ,.BPB_L1
; LD (CORE_BUFFERS.FatBuffer.S_X_H),HL
////////////////////////////////////////////////////////////////////////
; [ ] fat32
LD HL,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.SectorsPerDrive)
LD DE,(CORE_BUFFERS.FatBuffer.FirstDataSector_L)
LD A,H
OR L
JP NZ,.HDDSMAL
;
LD HL,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.BPB_BIG_TOTAL_SECTORS_L)
LD BC,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.BPB_BIG_TOTAL_SECTORS_H)
PUSH BC ; Total Sectors high
PUSH HL ; Total Sectors low
AND A
SBC HL,DE
JP NC,.HDDBIG
DEC BC
JP .HDDBIG
;
.HDDSMAL: ; CF = 0
LD BC,0
PUSH BC ; Total Sectors high
PUSH HL ; Total Sectors low
SBC HL,DE
;
.HDDBIG: CALL SectorToCluster
; LD A,(CORE_BUFFERS.FatBuffer.SectorsPerCluster)
; SCF
; .loop7: RRA
; JR C,.loop7_exit
; RR B
; RR C
; RR H
; RR L
; JP .loop7
;
.loop7_exit: INC HL
LD (CORE_BUFFERS.FatBuffer.MaxClusterLow),HL
LD A,L
OR H
JR NZ,.no_inc_bc
INC BC
.no_inc_bc: LD (CORE_BUFFERS.FatBuffer.MaxClusterHigh),BC
;
XOR A
LD H,A
LD L,A
LD (CORE_BUFFERS.FatBuffer.CacheBlock),HL
LD (CORE_BUFFERS.FatBuffer.CacheUpdated),A
; A = 0
LD HL,(CORE_BUFFERS.FatBuffer.SectorsPerFAT_H)
LD H,A
EX DE,HL
LD HL,(CORE_BUFFERS.FatBuffer.SectorsPerFAT_L)
; DE:HL = SectorsPerFAT
;
LD A,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.Number_of_FATs)
LD B,A
DEC A
JR Z,.loop_mul_end
; .Number_of_FATs * .SectorsPerFAT
.loop_mul: ADD HL,HL
EX DE,HL
ADC HL,HL
EX DE,HL
DJNZ .loop_mul
.loop_mul_end: ; .DirSizeInSectors + .Number_of_FATs * .SectorsPerFAT
LD B,0
LD A,(CORE_BUFFERS.FatBuffer.DirSizeInSectors)
LD C,A
ADD HL,BC
JR NC,.no_inc_DE
INC DE
.no_inc_DE: ; .RESERVED_SECTORS + .DirSizeInSectors + .Number_of_FATs * .SectorsPerFAT
LD BC,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.RESERVED_SECTORS)
ADD HL,BC
JR NC,.no_inc_de
INC DE
.no_inc_de: ; Total_Sectors - (.RESERVED_SECTORS + .DirSizeInSectors + .Number_of_FATs * .SectorsPerFAT)
AND A
LD B,D
LD C,E
POP DE ; Total Sectors low
EX DE,HL
SBC HL,DE
EX (SP),HL ; Total Sectors high
SBC HL,BC
POP DE ; Total Sectors low
; HL:DE = DataSec
;
LD A,(CORE_BUFFERS.FatBuffer.SectorsPerCluster)
; HL:DE / A => DE:BC, H=0, L - ®áâ â®ª
CALL DIV_by_Shifts
; ¢ëïá­ï¥¬ à §à來®áâì FAT
LD A,D
OR E
JR NZ,.its_FAT32
;
LD HL,4084
SBC HL,BC
JR NC,.its_FAT12
;
LD HL,65524
SBC HL,BC
JR C,.its_FAT32
;
; It's FAT16
LD HL,#FFFF
LD A,FAT_TYPE.x16
.set_vars: EXX
LD HL,0
LD (CORE_BUFFERS.FatBuffer.END_CHAIN_CLUSTER_H),HL
LD (CORE_BUFFERS.FatBuffer.RootDirStartCluster_L),HL
LD (CORE_BUFFERS.FatBuffer.RootDirStartCluster_H),HL
LD HL,CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.FAT.LABEL
EXX
LD DE,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.FAT.SERIAL_NUMBER)
LD BC,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.FAT.SERIAL_NUMBER+2)
JR .SET_VARS
;
.its_FAT12: LD HL,#0FFF
LD A,FAT_TYPE.x12
JR .set_vars
;
.its_FAT32: LD A,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.MainFATnumber)
CP #80
JR C,.mirrored_FATs ;¥á«¨ ¢á¥ ª®¯¨¨ FAT ¨á¯®«ì§ãîâáï
; ¨á¯®«ì§ã¥âáï ⮫쪮 ®¤­  ª®¯¨ï FAT
LD HL,(CORE_BUFFERS.FatBuffer.FAT1_SEC_H)
LD DE,(CORE_BUFFERS.FatBuffer.SectorsPerFAT_H)
LD D,0
EXX
LD HL,(CORE_BUFFERS.FatBuffer.FAT1_SEC_L)
LD DE,(CORE_BUFFERS.FatBuffer.SectorsPerFAT_L)
AND #0F
JR Z,.first_FAT_active
LD B,A
;
.fat_calc_loop: ADD HL,DE
EXX
ADC HL,DE
EXX
DJNZ .fat_calc_loop
;
.first_FAT_active:
LD (CORE_BUFFERS.FatBuffer.FAT1_SEC_L),HL
LD (CORE_BUFFERS.FatBuffer.FAT2_SEC_L),HL
EXX
LD (CORE_BUFFERS.FatBuffer.FAT1_SEC_H),HL
LD (CORE_BUFFERS.FatBuffer.FAT2_SEC_H),HL
;
.mirrored_FATs: LD HL,CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.FAT32.LABEL
;
EXX
LD HL,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.RootDirStartCluster)
LD (CORE_BUFFERS.FatBuffer.RootDirStartCluster_L),HL
LD DE,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.RootDirStartCluster+2)
LD (CORE_BUFFERS.FatBuffer.RootDirStartCluster_H),DE
;
CALL CLUSTER_TO_SECTOR.no_prepare
LD (CORE_BUFFERS.FatBuffer.RootDirFirstSector_L),IX
LD (CORE_BUFFERS.FatBuffer.RootDirFirstSector_H),HL
;
LD HL,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.FSINFO_Sector)
LD (CORE_BUFFERS.FatBuffer.FSINFO_Sector),HL
;
LD A,FAT_TYPE.x32
LD HL,#0FFF
LD (CORE_BUFFERS.FatBuffer.END_CHAIN_CLUSTER_H),HL
LD H,L
LD DE,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.FAT32.SERIAL_NUMBER)
LD BC,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.FAT32.SERIAL_NUMBER+2)
;
.SET_VARS: LD (CORE_BUFFERS.FatBuffer.FAT_TYPE),A
LD (CORE_BUFFERS.FatBuffer.END_CHAIN_CLUSTER_L),HL
LD (CORE_BUFFERS.FatBuffer.BPB_SERIAL_NUMBER),DE
LD (CORE_BUFFERS.FatBuffer.BPB_SERIAL_NUMBER+2),BC
EXX
LD DE,CORE_BUFFERS.FatBuffer.BPB_LABEL
LD BC,11 ;!HARDCODE
LDIR
;
SET_PAGE_X FATPAGE
PUSH AF
LD DE,0
CALL READ_FAT_TABLE
POP AF
OUT (SLOT3),A
;
; “áâ ­®¢¨âì ­ ç «ì­ë© ª« áâ¥à ¤«ï ç⥭¨ï
LD A,(CORE_BUFFERS.FatBuffer.FAT_TYPE)
CP FAT_TYPE.x32
JR Z,.set_FSinfo
;
LD HL,#0001
LD (G_CLUST.low),HL
DEC L
LD (G_CLUST.high),HL
;
DEC HL
LD (CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_L),HL
LD (CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_H),HL
XOR A
RET
;
.set_FSinfo: CALL READ_FSinfo
; !FIXIT ¯à®¢¥àª  ­  ®è¨¡ªã
;
; ¯à®¢¥àª  ®¤­®© ¨§ á®â­¨ áà ­ëå ᨣ­ âãà
LD HL,(CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.DATA_SIGNATURE)
LD DE,(CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.DATA_SIGNATURE + 2)
LD BC,#7272
SBC HL,BC
JR NZ,.error
EX DE,HL
LD DE,#6141
SBC HL,DE
JR NZ,.error
; FREE_CLUSTERS_COUNT
LD BC,(CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.FREE_CLUSTERS_COUNT)
LD DE,(CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.FREE_CLUSTERS_COUNT+2)
; CF = 0
CALL .check_cluster
JR NC,.skip_FFFF
;
LD B,#FF
LD C,B
LD D,B
LD E,B
;
.skip_FFFF: LD (CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_L),BC
LD (CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_H),DE
;
; FIRST_FREE_CLUSTER
LD BC,(CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.FIRST_FREE_CLUSTER)
LD DE,(CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.FIRST_FREE_CLUSTER+2)
; CF = 0
CALL .check_cluster
JR C,.error
;
LD (G_CLUST.high),DE
LD (G_CLUST.low),BC
XOR A
.error: LD (CORE_BUFFERS.FatBuffer.UPD_FSINFO),A
RET Z
;!TODO FREE_CLUSTERS_COUNT
;LD HL,#FFFF
;LD (CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_L),HL
;LD (CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_H),HL
;
XOR A
LD H,A
LD L,2
LD (G_CLUST.low),HL
LD L,H
LD (G_CLUST.high),HL
RET
;
;!TODO MaxCluster - ¬ ªá¨¬ «ì­® ¤®¯ãáâ¨¬ë© ¨«¨ ­  1 ¡®«ìè¥ ¬ ªá¨¬ «ì­® ¤®¯ãá⨬®£®?
.check_cluster: LD HL,(CORE_BUFFERS.FatBuffer.MaxClusterLow)
SBC HL,BC
LD HL,(CORE_BUFFERS.FatBuffer.MaxClusterHigh)
SBC HL,DE
RET
;;;;;;;;
; --> BC:HL - Sector
; <-- BC:HL - Cluster
SectorToCluster:
LD A,B
AND #0F
LD B,A
LD A,(CORE_BUFFERS.FatBuffer.SectorsPerCluster)
SCF
.loop: RRA
RET C
RR B
RR C
RR H
RR L
JP .loop
;
DOS_X_Error:
.UnknownBPB: LD A,DSS_Error.sys.UNKNOWN_FORMAT
SCF
RET
;
.Not_ready: LD A,DSS_Error.sys.NOT_READY
; CF = 1
RET
;
;
;!TODO ª ¡ãä¥à ¬!
/*
FatBuffer:
;.MSG: DB 'FAT'
.DRIVE: DB #FF
.FAT_TYPE: DB #00 ; TYPE FAT (12 - 12bit, 16 - 16bit, 32 - 32bit) ; [x] fat32
.CacheBlock: DW #00
.CacheUpdated: DB #00
;.SectorsPerBank: DB #00
.RootDirStartCluster_L: DW #0000
.RootDirStartCluster_H: DW #0000 ; [ ] fat32
.FAT1_SEC_L: DW #0000 ; MSD_FAT_SEC first sector FAT (FAT_FRM)
.FAT1_SEC_H: DW #0000 ; [ ] fat32
.FAT2_SEC_L: DW #0000
.FAT2_SEC_H: DW #0000 ; [ ] fat32
.SectorsPerFAT_L DW #0000
.SectorsPerFAT_H DB #00
.RootDirFirstSector_L: DW #0000 ; MSD_CAT_SEC first sector DIR
.RootDirFirstSector_H: DW #0000 ; MSD_CAT_SEC first sector DIR ; !TODO ®£à ­¨ç¥­¨¥ ¢ 32 ƒ¨£  ;!FIXIT ­¥ ¨á¯®«ì§ã¥âáï
.DirSizeInSectors: DB #00 ; DIR_SEC_SIZE
.FirstDataSector_L: DW #0000 ; MSD_DAT_SEC low
.FirstDataSector_H: DW #0000 ; MSD_DAT_SEC high ; [ ] fat32 ¡ë«® ®£à ­¨ç¥­¨¥ ¢ 32 ƒ¨£ 
.BytesPerCluster: DW #0000 ; CLUSTER_LEN
.END_CHAIN_CLUSTER_L: DW #FFFF
.END_CHAIN_CLUSTER_H: DW #0FFF ; [ ] fat3
.MaxClusterLow: DW #0000 ; ¬ ªá. ç¨á«® ª« áâ¥à®¢ (¡¥§ á«ã¦.)
.MaxClusterHigh: DW #0000 ; ¬ ªá. ç¨á«® ª« áâ¥à®¢ (¡¥§ á«ã¦.)
;
.BytesPerSector DW #0000
.SectorsPerCluster DB #00
.BPB_SERIAL_NUMBER DW 0,0
.BPB_LABEL BLOCK 11,' ' ; 11 ¤«ï FAT, 31 ¤«ï CDFS
IF COMPILE_UNUSED_CODE
.FilesPerSector: DB #00 ; ç¨á«® ä ©«®¢ëå § ¯¨á¥© ¢ ᥪâ®à¥
.ClustersPerBank: DB #00 ; A - Clusters per bank (16k) (ç¨á«® ª« áâ¥à®¢ ­  ¡«®ª އ“) ; ????? íâ® ¨á¯®«ì§ã¥âáï?
ENDIF
;.READ_PG: DB #00 ;!TODO ­¥ ¨á¯®«ì§ãîâáï ­¥ª®â®àë¥ §­ ç¥­¨ï, ­® § ¤ã¬ª  ­¥¯«®å ï)))
;.S_X_H: DW #0000 ; ª®«¨ç¥á⢮ ᥪâ®à®¢ ­  樫¨­¤à¥ ; ????? íâ® ¨á¯®«ì§ã¥âáï?
;
*/
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////