Estex-DSS/DSS/FS/FAT/FAT.asm
Anatoliy Belyanskiy 6330028b93 88%
2024-04-15 02:16:33 +10:00

1032 lines
23 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
;---------------------------------------------------------------
;R08 14-11-2002 DNS IMPROVE BPB-FUNCTION
;R07 17-12-1999 DNS BUG FIX SIGNATURE #55AA AT 510 OFFSET
;---------------------------------------------------------------
;----------------------------------------------------------------------;
; <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_ROOT_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
; !FIXIT «®¢¨âáï ¤¢®©­®¥ ®¡à é¥­¨¥ ¯à¨ ®âªàë⨨ ª®à­ï ¤¨áª , ­ ¯à¨¬¥à
OPENDIR: LD IY,CORE_BUFFERS.FM_BUF
LD A,(HL)
OR A
JR NZ,.SUBDIR
.REROOT: ; fat32
; EX DE,HL
; LD HL,(CORE_BUFFERS.FatBuffer.RootDirStartCluster_L)
; LD (CORE_BUFFERS.FM_BUF + _sFM.FS_REC.FIRST_CLUSTER_L),HL
; LD HL,(CORE_BUFFERS.FatBuffer.RootDirStartCluster_H)
; LD (CORE_BUFFERS.FM_BUF + _sFM.FS_REC.FIRST_CLUSTER_H),HL
; EX DE,HL
LD DE,0
LD (CORE_BUFFERS.FM_BUF + _sFM.FS_REC.FIRST_CLUSTER_L),DE
LD (CORE_BUFFERS.FM_BUF + _sFM.FS_REC.FIRST_CLUSTER_H),DE
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_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 + _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
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 + _sFM.FS_REC.FIRST_CLUSTER_L),HL
LD HL,(CORE_BUFFERS.FatBuffer.RootDirStartCluster_H)
LD (CORE_BUFFERS.FM_BUF + _sFM.FS_REC.FIRST_CLUSTER_H),HL
; CALL .read_dir
; LD HL,0
; LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_L),HL
; LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_H),HL
; RET
;
.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) ; áâ. à §àï¤
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
;----------------------------------------------------------------------;
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
;!TODO FAT procedures
;----------------------------------------------------------------------;
; ‘¡à®á¨âì ª¥è ª â «®£  ­  ¤¨áª.
; ¢å®¤: 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 + _sFM.FS_REC.FIRST_CLUSTER_L),HL
LD HL,(CORE_BUFFERS.FatBuffer.RootDirStartCluster_H)
LD (CORE_BUFFERS.FM_BUF + _sFM.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)
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
;----------------------------------------------------------------------;
;----------------------------------------------------------------------;
; ᪮¯¨à®¢ âì § ¯¨áì ¢ ᯨ᮪ ¤¨áª  (ª â «®£ ) 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
JP NC,SAVEDIR
LD HL,(SAVEDIR.DIRSIZE)
LD BC,(CORE_BUFFERS.FatBuffer.BytesPerCluster)
ADD HL,BC
LD (SAVEDIR.DIRSIZE),HL
AND A
JP SAVEDIR
;----------------------------------------------------------------------;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
; ­¥ ¨á¯®«ì§ã¥âáï
; TESTDSK: ;????? ¢®§¬®¦­®, çâ® âãâ «®£¨ç­¥¥, 祬 ¢ ­ ç «¥ OPENDSK, ¥á«¨ ¡ã¤¥â à ¡®â âì Dss.DRV.Open
; LD A,(CORE_BUFFERS.FatBuffer.DRIVE)
; LD C,Dss.DRV.MediaCheck
; RST ToDSS.DRV
; OR A
; RET Z
; ॣ. A - ­®¬¥à ¤¨áª 
; [ ] fat32
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.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 + 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.SECBUF
; LD DE,CORE_BUFFERS.BootSector
; LD BC,_sBOOT_SECTOR_PARAMS_FAT32 ; size
; LDIR
;
LD A,(CORE_BUFFERS.SECBUF + BOOT_SECTOR.DRIVE_TYPE)
CP #F0
JP C,DOS_X_Error.UnknownBPB
;
;!TODO ¯à®¢¥à¨âì ¯® ¬¥âª¥ à §¤¥« , çâ® íâ® FAT, ¯®â®¬ ®¯à¥¤¥«ïâì ª ª®© FAT
;
LD HL,(CORE_BUFFERS.SECBUF + BOOT_SECTOR.BytesPerSector)
LD (CORE_BUFFERS.FatBuffer.BytesPerSector),HL
LD A,(CORE_BUFFERS.SECBUF + BOOT_SECTOR.SectorsPerCluster)
LD (CORE_BUFFERS.FatBuffer.SectorsPerCluster),A
; calc. first sector FAT
LD HL,(CORE_BUFFERS.SECBUF + BOOT_SECTOR.RESERVED_SECTORS)
;
; LD E,(IY+_sBOOT_SECTOR_PARAMS.HIDDEN) ;Hidden sec
; LD D,(IY+_sBOOT_SECTOR_PARAMS.HIDDEN+1)
; ADD HL,DE
;
;!FIXIT ¤«ï fat32 ¢â몠âì á ᥪâ®à   ªâ¨¢­®© â ¡«¨æë
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.END_CHAIN_CLUSTER_H),BC ; [ ] fat32 reset variables
;LD (CORE_BUFFERS.FatBuffer.MaxClusterHigh),BC ; [ ] fat32 reset variables
LD (CORE_BUFFERS.FatBuffer.SectorsPerFAT_H),A ; [ ] fat32
;
;
LD DE,(CORE_BUFFERS.SECBUF + BOOT_SECTOR.SectorsPerFAT16)
LD A,E
OR D
JR NZ,.skip_high
;
LD BC,(CORE_BUFFERS.SECBUF + BOOT_SECTOR.SectorsPerFAT32 + 2)
LD A,C
LD (CORE_BUFFERS.FatBuffer.SectorsPerFAT_H),A
LD DE,(CORE_BUFFERS.SECBUF + BOOT_SECTOR.SectorsPerFAT32)
.skip_high: LD (CORE_BUFFERS.FatBuffer.SectorsPerFAT_L),DE
;
LD A,(CORE_BUFFERS.SECBUF + BOOT_SECTOR.Number_of_FATs) ; amount FATs
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 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.SECBUF + 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
;
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 (CORE_BUFFERS.FatBuffer.ClustersPerBank),A ; A - Clusters per bank (16k)
ENDIF
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
; LD HL,CORE_BUFFERS.SECBUF + _sBOOT_SECTOR_PARAMS.ID_FAT ;!!!!!   ¥á«¨ IY ¨á¯®«ì§ã¥âáï ¤«ï ¯¥à¥¬¥­­®£® BootSector, â® ¡ã¤¥â ¡ £ 
; LD DE,FAT_STRING
; 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'
; JP Z,.fat1x
; CP '3'
; JP NZ,DOS_X_Error.UnknownBPB
; LD A,#52 ; #52-#20 = #32 fat type
; LD HL,#0FFF
; LD (CORE_BUFFERS.FatBuffer.END_CHAIN_CLUSTER_H),HL
; LD (CORE_BUFFERS.FatBuffer.MaxClusterHigh),HL ; [ ] fat32 ;!FIXIT
; 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 #20 ; A-#20 = fat type (#12, #16, #32)
; LD (CORE_BUFFERS.FatBuffer.FAT_TYPE),A
; LD (CORE_BUFFERS.FatBuffer.END_CHAIN_CLUSTER_L),HL
;!TODO ­¥ ¨á¯®«ì§ã¥âáï §­ ç¥­¨¥ ¢ëç¨á«ï¥¬®¥ ¨ á®å࠭塞®¥ ¢ FatBuffer
////////////////////////////////////////////////////////////////////////
; LD HL,0
; LD BC,(CORE_BUFFERS.SECBUF + _sBOOT_SECTOR_PARAMS.SectorsPerTrack) ; Sector per track
; LD A,(CORE_BUFFERS.SECBUF + _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.SECBUF + BOOT_SECTOR.SectorsPerDrive)
LD DE,(CORE_BUFFERS.FatBuffer.FirstDataSector_L)
LD A,H
OR L
JP NZ,.HDDSMAL
;
LD HL,(CORE_BUFFERS.SECBUF + BOOT_SECTOR.BPB_BIG_TOTAL_SECTORS_L)
LD BC,(CORE_BUFFERS.SECBUF + 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 ClusterToSector
; 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 (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.SECBUF + 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.SECBUF + 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_for_SPC
; ¢ëïá­ï¥¬ à §à來®áâì FAT
LD A,D
OR E
JR NZ,.its_FAT32
;
LD HL,4084
SBC HL,BC
JR NC,.its_FAT12
;
LD HL,65525
SBC HL,BC
JR C,.its_FAT32
;
; It's FAT16
LD HL,#FFFF
LD A,FAT_TYPE.x16
.Set_SN: EXX
LD HL,0
LD (CORE_BUFFERS.FatBuffer.END_CHAIN_CLUSTER_H),HL
LD (CORE_BUFFERS.FatBuffer.RootDirStartCluster_L),HL
LD HL,CORE_BUFFERS.SECBUF + BOOT_SECTOR.FAT.LABEL
EXX
LD DE,(CORE_BUFFERS.SECBUF + BOOT_SECTOR.FAT.SERIAL_NUMBER)
LD BC,(CORE_BUFFERS.SECBUF + BOOT_SECTOR.FAT.SERIAL_NUMBER+2)
JR .BPB_FAT
;
.its_FAT12: LD HL,#0FFF
LD A,FAT_TYPE.x12
JR .Set_SN
;
.its_FAT32: EXX
LD HL,CORE_BUFFERS.SECBUF + BOOT_SECTOR.FAT32.LABEL
EXX
;
LD HL,(CORE_BUFFERS.SECBUF + BOOT_SECTOR.RootDirStartCluster)
LD (CORE_BUFFERS.FatBuffer.RootDirStartCluster_L),HL
LD BC,(CORE_BUFFERS.SECBUF + BOOT_SECTOR.RootDirStartCluster+2)
LD (CORE_BUFFERS.FatBuffer.RootDirStartCluster_H),BC
CALL ClusterToSector
LD (CORE_BUFFERS.FatBuffer.RootDirFirstSector_L),HL
LD (CORE_BUFFERS.FatBuffer.RootDirFirstSector_H),BC
;
LD A,FAT_TYPE.x32
LD HL,#0FFF
LD (CORE_BUFFERS.FatBuffer.END_CHAIN_CLUSTER_H),HL
LD H,L
LD DE,(CORE_BUFFERS.SECBUF + BOOT_SECTOR.FAT32.SERIAL_NUMBER)
LD BC,(CORE_BUFFERS.SECBUF + BOOT_SECTOR.FAT32.SERIAL_NUMBER+2)
;
.BPB_FAT: 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
CALL R_CLUST
XOR A
RET
;!TODO detect fat type by clusters!
.IBM_DOS: LD A,(CORE_BUFFERS.SECBUF + BOOT_SECTOR.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
;
; --> BC:HL - Cluster
; <-- BC:HL - Sector
ClusterToSector:
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 ; ª®«¨ç¥á⢮ ᥪâ®à®¢ ­  樫¨­¤à¥ ; ????? íâ® ¨á¯®«ì§ã¥âáï?
;
*/
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////