Estex-DSS/DSS/FS/FAT/FAT.asm
Anatoliy Belyanskiy 8448dbef48 82%
2024-04-07 05:28:29 +10:00

905 lines
18 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.

;[BEGIN]
;//MODULE: FAT
;//CREATE: 19-05-1998 AUTHOR: Denis Parinov
;//UPDATE: 24-10-1999 DNS Restore module
;---------------------------------------------------------------
;Rev Date Name Description
;---------------------------------------------------------------
;RX01 10-02-1999 DNS UPGRADE FAT CASH
;---------------------------------------------------------------
;----------------------------------------------------------------------;
; <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+_sFAT_DIRECTORY_RECORD.NAME)
OR A
JR Z,.error_file_not_found
CP #E5 ;!HARDCODE #E5 - § ¯¨áì ¢ ¤¨à¥ªâ®à¨¨ ᢮¡®¤­ , â ª ª ª ä ©«/¤¨à¥ªâ®à¨ï ¡ë«¨ 㤠«¥­ë
JR Z,.next_record
LD A,(IX+_sFAT_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:
;!TEST 9/11/23 record index
; EXX
; INC DE
; EXX
;
LD DE,#0020 ;!HARDCODE
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,#0020
;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 + _sFAT_DIRECTORY_RECORD.NAME)
OR A
JR Z,.error
CP #E5
JR Z,.next_step
LD A,(IX + _sFAT_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 + _sFAT_DIRECTORY_RECORD.NAME)
CP "."
JP NZ,.ADDSPEC
LD A,(IX + _sFAT_DIRECTORY_RECORD.NAME + 1)
CP "."
JP NZ,.IT_DIR
LD HL,WorkDirectory
LD D,H
LD E,L
INC HL
LD BC,WorkDirectory.DEPTH
XOR A
CPIR
JP PO,.error ;[x] 20/11/23 ¯à®¢¥àª  ­  ¢ë室 §  £à ­¨æë
DEC HL ;R009
DEC HL
LD BC,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,#0020 ;!HARDCODE
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,WorkDirectory+1
LD BC,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 + _sFAT_DIRECTORY_RECORD.FIRST_CLUSTER_H)
LD D,(IX + _sFAT_DIRECTORY_RECORD.FIRST_CLUSTER_H+1)
LD YH,D
LD YL,E
LD E,(IX + _sFAT_DIRECTORY_RECORD.FIRST_CLUSTER_L)
LD D,(IX + _sFAT_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_ZERO_CLUSTER:
EX DE,HL
LD HL,(CORE_BUFFERS.FM_BUF + _sFM.FS_REC.FIRST_CLUSTER_L) ;R005
LD A,L
OR H
LD HL,(CORE_BUFFERS.FM_BUF + _sFM.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: ; fat32
EX DE,HL
LD HL,(FatBuffer.RootDirStartCluster_L)
LD (CORE_BUFFERS.FM_BUF + _sFM.FS_REC.FIRST_CLUSTER_L),HL
LD HL,(FatBuffer.RootDirStartCluster_H)
LD (CORE_BUFFERS.FM_BUF + _sFM.FS_REC.FIRST_CLUSTER_H),HL
EX DE,HL
CALL LOADDIR
; CF=0
LD HL,WorkDirectory
LD (HL),'\'
INC HL
LD (HL),#00
;AND A
RET
;
.SUBDIR: CP "."
JR NZ,.SUBDIR2
; fat32
CALL CHECK_ZERO_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 + _sFM.FS_REC.FIRST_CLUSTER_L),HL ; fat32
LD (CORE_BUFFERS.FM_BUF + _sFM.FS_REC.FIRST_CLUSTER_H),IY ; fat32
LD HL,#4000 ;!HARDCODE
LD (CORE_BUFFERS.FM_BUF + _sFM.FS_REC.F_SIZE),HL
;EX DE,HL
JP LOADDIR
;----------------------------------------------------------------------;
;----------------------------------------------------------------------;
; <20>à®ç¨â âì ᯨ᮪ ª â «®£ 
; [x] fat32 ;!TEST
LOADDIR: ;!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
; ;!TEST no ldir
; ; ®ç¨áâ¨âì ª¥è ª â «®£ 
; ; LD HL,#C000
; ; LD DE,#C001
; ; LD BC,#3FFF
; ; LD (HL),L
; ; LDIR
; ;
; LD A,(FatBuffer.DRIVE) ; ­®¬¥à ¤¨áª 
; LD (IY+_sFM.DRIVE),A ; á®åà. ¢ ¤¥áªà¨¯â®à
; ; ­®¬¥à ¯¥à¢®£® ª« áâ¥à 
; ; [x] fat32
; LD A,(FatBuffer.FAT_TYPE)
; XOR 32
; JR Z,.read_dir
; ;!FIXIT ¯¥à¥¤¥« âì ­  à ¡®âã ¡¥§ IY
; LD A,(IY+_sFM.FS_REC.FIRST_CLUSTER_L)
; OR (IY+_sFM.FS_REC.FIRST_CLUSTER_L+1)
CALL LOAD_SAVE_DIR_PREPARE
PUSH AF
EX AF,AF'
JR Z,.LoadRootDir
.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,(FatBuffer.RootDirFirstSector_H) ; áâ. à §àï¤
LD IX,(FatBuffer.RootDirFirstSector_L) ; ­®¬¥à «®£. ᥪâ®à 
LD A,(FatBuffer.DirSizeInSectors)
LD B,32 ; !HARDCODE sector size 512. 16384/(sector 512). à §¬¥à root-ª â «®£ 
CP B
JR NC,.RTD1
LD B,A ; ç¨á«® ᥪâ®à®¢
.RTD1: LD A,(FatBuffer.DRIVE) ; ­®¬¥à ¤¨áª 
LD DE,DIRPAGE.buffer ; ¡ãä¥à
LD C,Dss.DRV.Read ; ç⥭¨¥ ᥪâ®à®¢
RST ToDSS.DRV
POP AF
OUT (SLOT3),A
RET
;----------------------------------------------------------------------;
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,(FatBuffer.DRIVE)
LD (IY+_sFM.DRIVE),A
; [x] fat32
LD A,(FatBuffer.FAT_TYPE)
CP FAT_TYPE.x32 - 1
JR NC,.exit
;!FIXIT ¯¥à¥¤¥« âì ­  à ¡®âã ¡¥§ IY
LD A,(IY+_sFM.FS_REC.FIRST_CLUSTER_L)
OR (IY+_sFM.FS_REC.FIRST_CLUSTER_L+1)
.exit: EX AF,AF'
RET
;!TODO FAT procedures
;----------------------------------------------------------------------;
; ‘¡à®á¨âì ª¥è ª â «®£  ­  ¤¨áª.
; ¢å®¤: iy=áâàãªâãà  ¤¥áªà¨¯â®à 
; [x] fat32 ;!TEST
SAVEDIR: ;!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,(FatBuffer.DRIVE)
; LD (IY+_sFM.DRIVE),A
; ; [x] fat32
; LD A,(FatBuffer.FAT_TYPE)
; XOR 32
; JR Z,.save_dir
; ;!FIXIT ¯¥à¥¤¥« âì ­  à ¡®âã ¡¥§ IY
; LD A,(IY+_sFM.FS_REC.FIRST_CLUSTER_L)
; OR (IY+_sFM.FS_REC.FIRST_CLUSTER_L+1)
CALL LOAD_SAVE_DIR_PREPARE
PUSH AF
EX AF,AF'
JR Z,.SaveRootDir
.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,(FatBuffer.RootDirFirstSector_H)
LD IX,(FatBuffer.RootDirFirstSector_L)
LD A,(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,(FatBuffer.DRIVE)
LD DE,DIRPAGE.buffer
LD C,Dss.DRV.Write
RST ToDSS.DRV
POP AF
OUT (SLOT3),A
RET
;----------------------------------------------------------------------;
;----------------------------------------------------------------------;
; ᪮¯¨à®¢ âì § ¯¨áì ¢ ᯨ᮪ ¤¨áª  (ª â «®£ ) de ix iy
; ¨ á¡à®á¨âì ª¥è ª â «®£  ­  ¤¨áª
; ¢å®¤: (HANDBUF) - § ¯¨áì ª â «®£ 
WRT_HND: SET_PAGE_X DIRPAGE
EX AF,AF'
;
;LD IX,DIRPAGE.buffer
LD HL,DIRPAGE.buffer
;!TEST 9/11/23 record index
; EXX
; LD DE,0
; EXX
;
LD BC,#0020
.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,(FatBuffer.BytesPerCluster)
ADD HL,BC
LD (SAVEDIR.DIRSIZE),HL
AND A
JP SAVEDIR
;----------------------------------------------------------------------;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
; ­¥ ¨á¯®«ì§ã¥âáï
; TESTDSK: ;????? ¢®§¬®¦­®, çâ® âãâ «®£¨ç­¥¥, 祬 ¢ ­ ç «¥ OPENDSK, ¥á«¨ ¡ã¤¥â à ¡®â âì Dss.DRV.Open
; LD A,(FatBuffer.DRIVE)
; LD C,Dss.DRV.MediaCheck
; RST ToDSS.DRV
; OR A
; RET Z
; ॣ. D - ­®¬¥à ¤¨áª 
; [ ] fat32
RD_BPB: LD C,SLOT3
IN B,(C)
PUSH BC
IN A,(SLOT0)
OUT (SLOT3),A
LD A,(FatBuffer.DRIVE)
LD DE,CORE_BUFFERS.SECBUF+#C000 ;R08
LD C,Dss.DRV.GetBPB
RST ToDSS.DRV
POP BC
OUT (C),B
JP C,DOS_X_Error.Not_ready
LD DE,#AA55 ; ᨣ­ âãà  ;R05
LD HL,(CORE_BUFFERS.SECBUF+_sBOOT_SECTOR.MBR_SIGNATURE) ;R08 ;R07
;R05
AND A
SBC HL,DE
JP NZ,DOS_X_Error.UnknownBPB
;R08
LD HL,CORE_BUFFERS.SECBUF
LD DE,CORE_BUFFERS.BootSector
LD BC,_sBOOT_SECTOR_PARAMS ; size
LDIR
;
LD A,(CORE_BUFFERS.BootSector.DRIVE_TYPE)
CP #F0
JP C,DOS_X_Error.UnknownBPB
; calc. first sector FAT
LD HL,(CORE_BUFFERS.BootSector.RESERVED_SECTORS)
;
; LD E,(IY+_sBOOT_SECTOR_PARAMS.HIDDEN) ;Hidden sec
; LD D,(IY+_sBOOT_SECTOR_PARAMS.HIDDEN+1)
; ADD HL,DE
;
LD (FatBuffer.FAT1_SEC_L),HL ; low word first sector FAT #1
LD (FatBuffer.FAT2_SEC_L),HL ; low word first sector FAT #2
;[ ] fat32 ;!FIXIT
XOR A
LD D,A
LD E,A
LD (FatBuffer.FAT1_SEC_H),DE ; high word first sector FAT #1
LD (FatBuffer.FAT2_SEC_H),DE ; high word first sector FAT #1
LD (FatBuffer.RootDirStartCluster_L),DE
LD (FatBuffer.RootDirStartCluster_H),DE
LD (FatBuffer.SectorsPerFAT_H),A
;
;
LD DE,(CORE_BUFFERS.BootSector.SectorsPerFAT16)
LD (FatBuffer.SectorsPerFAT_L),DE
;
LD A,(CORE_BUFFERS.BootSector.Number_of_FATs) ; amount FATs
CP 1
JR Z,.loop1
DEC A
ADD HL,DE
LD (FatBuffer.FAT2_SEC_L),HL
;C_DATA1
.loop1: ADD HL,DE
DEC A
JR NZ,.loop1
;
LD (FatBuffer.RootDirFirstSector_L),HL ; first sector DIR
LD BC,(CORE_BUFFERS.BootSector.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 (FatBuffer.FilesPerSector),A
ENDIF
;
EX DE,HL
LD HL,(CORE_BUFFERS.BootSector.FilesInRootDIR) ; 0 for fat32
DEC HL ; [ ]fat32
XOR A
;NEXTAD2
.loop2: INC A
JP Z,DOS_X_Error.UnknownBPB
SBC HL,BC
JR NC,.loop2
;
EX DE,HL
LD C,A ; A - sectors in DIR
LD B,0
LD (FatBuffer.DirSizeInSectors),A
ADD HL,BC ; Start DATA area
LD (FatBuffer.FirstDataSector_L),HL
; B = 0
;
LD HL,(CORE_BUFFERS.BootSector.BytesPerSector)
LD A,(CORE_BUFFERS.BootSector.SectorsPerCluster)
;!TODO FATcacheSize
; calc. cluster size
XOR 1
JR Z,.loop3.end
RRA
.loop3: ADD HL,HL
RRA
JP NC,.loop3
.loop3.end:
;
LD (FatBuffer.BytesPerCluster),HL
IF COMPILE_UNUSED_CODE
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 (FatBuffer.ClustersPerBank),A ; A - Clusters per bank (16k)
ENDIF
;
;!TODO detect fat type by clusters!
;[ ] fat32 reset fat32 variables
LD HL,0
LD (FatBuffer.ENDCLUS_HIGH),HL
LD (FatBuffer.MaxClusterHigh),HL
;
LD HL,CORE_BUFFERS.BootSector.ID_FAT ;!!!!!   ¥á«¨ IY ¨á¯®«ì§ã¥âáï ¤«ï ¯¥à¥¬¥­­®£® BootSector, â® ¡ã¤¥â ¡ £ 
LD DE,FatBuffer.MSG
LD B,3
;R_BPBL1
.loop5: LD A,(DE)
CP (HL)
JP NZ,.IBM_DOS
INC HL
INC DE
DJNZ .loop5
;FID
.loop6: LD A,(HL)
INC HL
CP ' '
JR Z,.loop6
;
CP '1'
;[ ] fat32
JP Z,.fat1x
CP '3'
JP NZ,DOS_X_Error.UnknownBPB
LD A,#46 ; #46-#26 = 32 fat type
LD HL,#0FFF
LD (FatBuffer.ENDCLUS_HIGH),HL
LD (FatBuffer.MaxClusterHigh),HL
LD H,L
JR .BPB_FAT
;
.fat1x: LD A,(HL)
CP '2' ; FAT16
LD HL,#0FFF
JR Z,.BPB_FAT
CP '6' ; FAT12
JP NZ,DOS_X_Error.UnknownBPB
LD H,L
.BPB_FAT:
SUB #26 ; A-#26 = fat type (12, 16, 32)
LD (FatBuffer.FAT_TYPE),A
LD (FatBuffer.ENDCLUS_LOW),HL
;!TODO ­¥ ¨á¯®«ì§ã¥âáï §­ ç¥­¨¥ ¢ëç¨á«ï¥¬®¥ ¨ á®å࠭塞®¥ ¢ FatBuffer
////////////////////////////////////////////////////////////////////////
; LD HL,0
; LD BC,(CORE_BUFFERS.BootSector.SectorsPerTrack) ; Sector per track
; LD A,(CORE_BUFFERS.BootSector.HEADS)
; .BPB_L1:; calc. sector per cylinder
; ADD HL,BC
; DEC A
; JR NZ,.BPB_L1
; LD (FatBuffer.S_X_H),HL
////////////////////////////////////////////////////////////////////////
; [ ] fat32
LD HL,(CORE_BUFFERS.BootSector.SectorsPerDrive)
LD DE,(FatBuffer.FirstDataSector_L)
LD A,H
OR L
JP NZ,.HDDSMAL
;
LD HL,(CORE_BUFFERS.BootSector.BPB_BIG_TOTAL_SECTORS_L)
LD BC,(CORE_BUFFERS.BootSector.BPB_BIG_TOTAL_SECTORS_H)
AND A
SBC HL,DE
JP NC,.HDDBIG
DEC BC
JP .HDDBIG
;
.HDDSMAL:; CF = 0
SBC HL,DE
LD BC,0
.HDDBIG: LD A,(CORE_BUFFERS.BootSector.SectorsPerCluster)
SCF
.S4C01: RRA
JR C,.S4C02
RR B
RR C
RR H
RR L
JP .S4C01
.S4C02: INC HL
LD (FatBuffer.MaxClusterLow),HL
;
XOR A
LD H,A
LD L,A
LD (FatBuffer.CacheBlock),HL
LD (FatBuffer.CacheUpdated),A
SET_PAGE_X FATPAGE
PUSH AF
; [ ] fat32
; XOR A
; HL = 0
EX DE,HL
;
CALL READ_FAT_TABLE
POP AF
OUT (SLOT3),A
CALL R_CLUST
XOR A
RET
;!TODO detect fat type by clusters!
.IBM_DOS:
LD A,(CORE_BUFFERS.BootSector.DRIVE_TYPE)
CP #F0
JR C,DOS_X_Error.UnknownBPB
; ID ram-¤¨áª  - #FA
CP #F8 ; !FIXIT fat. ­¥ ®¡ï§ â¥«ì­® ¥á«¨ ¢¨­â, â® ­¥ FAT12
LD A,'2'
LD HL,#0FFF
JP NZ,.BPB_FAT
;
LD A,'6'
LD H,L
JP .BPB_FAT
;
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_H: DW #0000 ; MSD_CAT_SEC first sector DIR ; !TODO ®£à ­¨ç¥­¨¥ ¢ 32 ƒ¨£  ;!FIXIT ­¥ ¨á¯®«ì§ã¥âáï
.RootDirFirstSector_L: DW #0000 ; MSD_CAT_SEC first sector DIR
.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
.ENDCLUS_LOW: DW #FFFF
.ENDCLUS_HIGH: DW #0FFF ; [ ] fat3
.MaxClusterLow: DW #0000 ; ¬ ªá. ç¨á«® ª« áâ¥à®¢ (¡¥§ á«ã¦.)
.MaxClusterHigh: DW #0000 ; ¬ ªá. ç¨á«® ª« áâ¥à®¢ (¡¥§ á«ã¦.)
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 ; ª®«¨ç¥á⢮ ᥪâ®à®¢ ­  樫¨­¤à¥ ; ????? íâ® ¨á¯®«ì§ã¥âáï?
;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////