Estex-DSS/BOOT/DSSBOOT.ASM
2024-06-08 05:23:00 +10:00

1645 lines
35 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.

;---------------------------------------------------------------
;Rev Date Name Decription
;---------------------------------------------------------------
;R04 25-03-2023 BAO ; !FIXIT
;R03 23-01-2000 DNS OPTIMIZE NEW BOOTING PROCEDURE
;R02 08-01-2000 DNS NEW BOOTING PROCEDURE
;R01 25-05-1998 DNS Console printing
;R00 09-11-1998 DNS Color printing start message
; Install CGA palette
; +------------------------------+
; + System Bootstrap +
; + Initial revision 09 Nov 1998 +
; +------------------------------+
MODULE DSS_Boot_Loader
; BIOS 3.06 § £à㦠¥â ®¤¨­ ᥪâ®à § £àã§ç¨ª  ¨ ¯¥à¥¤ ñâ ¥¬ã ã¯à ¢«¥­¨¥.
DEFINE ORIGINAL_DSS 0
DEFINE UNIVERSAL_BOOT 1
LOAD_SECTORS EQU SECTORS_OF_LOADER-1
DISP #8000
OUTPUT 'build/DSSloader.bin'
;ADRIVE EQU #00
;CDRIVE EQU #02
DRIVE: _mSYSID
DI
; ;!TEST 26/03/2024
; LD SP,#C000
; ;
LD (DRIVE),A
;[ ] 17.12.2023 § £à㧪  á  ªâ¨¢­®£® à §¤¥« ,   ­¥ á ¯¥à¢®£®
XOR A
LD (DRIVE+1),A
;
LD C,BIOS.DRV_VERSION
RST ToBIOS_18
;
LD HL,FAIL
PUSH HL
;
LD HL,MESSAGES.INCORR
RET C ; goto FAIL
LD A,(DRIVE)
BIT 7,A
JR Z,GOOD_DRIVE
EX DE,HL
LD DE,2*256 + 21 ;!HARDCODE ¥á«¨ ¢¥àá¨ï ­¨¦¥ 2.21, â® ®è¨¡ª 
SBC HL,DE
LD HL,MESSAGES.INCORR
RET C ; goto FAIL
;
GOOD_DRIVE: LD DE,#8200 ;!HARDCODE
LD HL,0
LD IX,2
LD BC,LOAD_SECTORS*256 + BIOS.DRV_READ ; ¤®§ £à㧪  ᥪâ®à®¢ § £àã§ç¨ª 
LD A,(DRIVE)
RST ToBIOS_18
JP NC,CONTINUE
JR FAIL.NULL
////////////////////////////////////////////////////////////////////////
FAIL: CALL MESSAGE
.NULL: LD HL,MESSAGES.FAILURE
CALL MESSAGE
JR $
;
MESSAGE: ;R01 Start
XOR A
OUT (SYS_PORT.ON),A
.loop: LD A,(HL) ;R01
INC HL
OR A
RET Z
CALL PRINTX
JR .loop
;
PRINTX: CP "\r" ;
JR Z,.CR_
CP "\n" ;
JR Z,.LF_
LD BC,1*256 + BIOS.LP_PRINT_SYM
RST ToBIOS_18
RET
;
.CR_: LD C,BIOS.LP_GET_PLACE
RST ToBIOS_18
LD E,0
LD C,BIOS.LP_SET_PLACE
RST ToBIOS_18
RET
;
.LF_: LD C,BIOS.LP_GET_PLACE
RST ToBIOS_18
LD A,#1F
CP D
JR NZ,.LF2
PUSH DE
PUSH HL
LD DE,#0020
LD BC,1*256 + BIOS.LP_SCROLL_UD
RST ToBIOS_18
;
LD DE,#1F00
LD C,BIOS.LP_SET_PLACE
RST ToBIOS_18
;
LD A," "
LD BC,#50 + BIOS.LP_PRINT_SYM
RST ToBIOS_18
POP HL
POP DE
DEC D
.LF2: INC D
LD C,BIOS.LP_SET_PLACE
RST ToBIOS_18
RET ;R01
;R01 End
MESSAGES:; 0 10 20 30 40 50 60 70 80
.FAILURE: DB "\r\nFatal error! Press RESET to restart.\r\n",0
.INCORR: DB "\r\nOld BIOS version.\r\n",0
.ERRPART: DB "\r\nUnknown partition table.",0
.ERRIBPB: DB "\r\nInvalid BOOT sector.",0
.NO_SYS: DB "\r\nCan't open SYSTEM.DOS...",0
.NOSHELL: DB "\r\nCan't open SYSTEM.EXE...",0
.STARTDO: DB "\r\nStarting DSS... \r\n\n",0
;
SHELL_NAME: DB '\SYSTEM.EXE /P',0
ROOT: DB 'X:\',0
CORE_NAME: DB "SYSTEM DOS"
.Size EQU $-CORE_NAME
////////////////////////////////////////////////////////////////////////
ASSERT $<#8200, "Error!!! BIOS LOADING ONLY FIRST #200 BYTES"
////////////////////////////////////////////////////////////////////////
CONTINUE: LD HL,0
LD (PARTITION_START_L),HL
LD (PARTITION_START_H),HL
;
LD BC,1*256 + BIOS.GetMem
RST ToBIOS_18 ;GET PAGE FOR DOS
LD (LOAD_CORE.BANKDOS),A
;
OUT (SLOT0),A
;
CALL GET_BPB ;READ BPB
LD HL,MESSAGES.ERRIBPB
RET C ; goto FAIL
CALL GETROOT
;
LD HL,MESSAGES.NO_SYS
RET C ; goto FAIL
; [ ] § £à㧪  system.dos ¡®«ìè¥ #4000 ¡ ©â®¢
LD HL,(FSIZE1)
LD A,H
OR L
JR NZ,.set_size
LD DE,(FSIZE0)
LD HL,#4000
SBC HL,DE
JR NC,.set_no_size
.set_size: LD A,#FF
.set_no_size: LD (LOAD_CORE.BIG_CORE),A
OR A
PUSH AF
; § £à㧪 
EXX
LD HL,(FCLUSTER_H)
EXX
LD HL,(FCLUSTR_L)
LD DE,#C000
CALL LOAD_CORE
; [ ] § £à㧪  system.dos ¡®«ìè¥ #4000 ¡ ©â®¢
EX AF,AF'
POP AF
JR Z,.no_big_core
EX AF,AF'
JR C,.no_big_core
;
IN A,(SLOT1)
LD (LOAD_CORE.BANKDOS),A
LD A,SUBLOAD_SIZE
LD (LOAD_CORE.max_sectors),A
LD (LOAD_CORE.BIG_CORE),A ; ⥯¥àì íâ® áçñâ稪 ®áâ ¢è¨åáï ᥪâ®à®¢
;
LD A,(BOOT_BUFFER + BOOT_SECTOR.SectorsPerCluster)
CP #20 + 1 ; !HARDCODE ª®«-¢® § £à㦠¥¬ëå ᥪâ®à®¢
JP NC,INC_SECTOR_NUM
;CALL R_F_FAT ; next cluster in chain
CALL READ_FROM_FAT ; next cluster in chain
EX DE,HL
EXX
EX DE,HL
EXX
LD DE,#C000
CALL NC,LOAD_CORE
.no_big_core: ;
RUN_CORE: DI
XOR A
OUT (SYS_PORT.OFF),A
;
LD A,#10
LD BC,#7FFD
OUT (C),A
;
LD A,1
LD B,#1F ;1FFD
OUT (C),A
;
;DOS LOADED
;IF UNIVERSAL_BOOT
;[ ] 17.12.2023 § £à㧪  á  ªâ¨¢­®£® à §¤¥« ,   ­¥ á ¯¥à¢®£®
LD A,(DRIVE+1) ; ­®¬¥à à §¤¥« 
LD L,A
;
LD A,(DRIVE) ; ­®¬¥à ãáâனá⢠
LD C,Dss.Version
RST ToDSS
JP C,FAIL.NULL
;
LD HL,MESSAGES.STARTDO
CALL MESSAGE
;
XOR A
OUT (SYS_PORT.OFF),A
;
LD A,(DRIVE)
LD BC,Dss.BootDSK.Set
RST ToDSS
;
LD BC,Dss.BootDSK.Get
;ELSE
; IF ORIGINAL_DSS
; LD C,Dss.Version
; RST ToDSS
; ELSE
; LD A,(DRIVE)
; LD C,Dss.Version
; RST ToDSS
; JP C,FAIL.NULL
; LD C,Dss.BootDSK
; ENDIF ;
; LD HL,MESSAGES.STARTDO
; CALL MESSAGE
; IF ORIGINAL_DSS
; LD A,(DRIVE)
; LD BC,Dss.BootDSK.Set
; RST ToDSS
; LD B,Dss.BootDSK.Get
; ENDIF
;ENDIF
;
RST ToDSS
;
ADD A,"A"
;
LD HL,ROOT
LD (HL),A
LD C,Dss.ChDir
RST ToDSS
;
LD HL,SHELL_NAME
LD BC,Dss.Exec
RST ToDSS
.NoShell: JP NC,FAIL.NULL
LD HL,MESSAGES.NOSHELL
CP DSS_Error.sys.UNEXPECTED_APP_TRMN
JP NZ,FAIL
JP FAIL.NULL
;
INC_SECTOR_NUM: PUSH DE
CALL CLUSTER_TO_SECTOR
LD DE,#20 ;!HARDCODE ª®«¨ç¥á⢮ ¯à®ç¨â ­­ëå ᥪâ®à®¢
ADD IX,DE
JR NC,.no_inc
INC HL
.no_inc: ;
POP DE
LD BC,RUN_CORE
PUSH BC
PUSH HL ; ¤«ï ¡ « ­á 
PUSH HL ; ¤«ï ¡ « ­á 
JP LOAD_CORE.subload
;
;
PART_TB: PUSH BC
LD HL,(BOOT_BUFFER + BOOT_SECTOR.MBR_SIGNATURE)
LD DE,#AA55
; CF = 0
SBC HL,DE
SCF
RET NZ
LD IX,BOOT_BUFFER + BOOT_SECTOR.PARTITION_TABLE
LD B, +(_sMBR_PARTITION_TABLE / _sMBR_PARTITION_RECORD)
;
LD HL,YEPDOS
PUSH HL
.part_loop: LD A,(IX + _sMBR_PARTITION_RECORD.FS_ID)
; …‘‹ˆ ¤®¡ ¢¨âáï ¯®¤¤¥à¦ª  ¥éñ ®¤­®£® ⨯  ”‘, â® ¯®¬¥­ïâì 1 ­  2
; 1
CP PartitionSysTypes.FAT16_LBA
RET Z ;JR Z,YEPDOS
CP PartitionSysTypes.FAT16
RET Z ;JR Z,YEPDOS
CP PartitionSysTypes.FAT16_32Mb
RET Z ;JR Z,YEPDOS
CP PartitionSysTypes.FAT12
RET Z ;JR Z,YEPDOS
CP PartitionSysTypes.FAT32
RET Z ;JR Z,YEPDOS
CP PartitionSysTypes.FAT32_LBA
RET Z ;JR Z,YEPDOS
;
; 2
;EXX
;LD HL,SUPPORTED_PARTITIONS
;LD BC,SUPPORTED_PARTITIONS.Size
;CPIR
;EXX
;JR Z,YEPDOS
;
.next: LD DE,_sMBR_PARTITION_RECORD
ADD IX,DE
DJNZ .part_loop
;
LD HL,MESSAGES.ERRPART
JP FAIL
; 2
; SUPPORTED_PARTITIONS:
; ;.Empty DB #00
; .FAT12 DB #01
; .FAT16_32Mb DB #04
; ;.Extended DB #05
; .FAT16 DB #06
; ;.HPFS_NTFS DB #07
; .FAT32 DB #0B
; .FAT32_LBA DB #0C
; .FAT16_LBA DB #0E
; ;.Win_Ext_LBA DB #0F
; ;.Linux_swap DB #82
; ;.Linux DB #83
; ;.Linux_extended DB #85
; .Size EQU $-SUPPORTED_PARTITIONS
;
;
YEPDOS: ;[ ] 17.12.2023 § £à㧪  á  ªâ¨¢­®£® à §¤¥« ,   ­¥ á ¯¥à¢®£®
LD A,#80
CP (IX + _sMBR_PARTITION_RECORD.isActive)
JR NZ,PART_TB.next
LD A,4 ;!HARDCODE áç¥â稪 § ¯¨á¥© ¯ àâ¨æ¨© ¢ MBR
SUB B
PUSH AF ; ­®¬¥à § £à㧮筮£® à §¤¥« 
;
LD L,(IX + _sMBR_PARTITION_RECORD.Start_LBA + 0)
LD H,(IX + _sMBR_PARTITION_RECORD.Start_LBA + 1)
PUSH HL
LD (PARTITION_START_L),HL
LD L,(IX + _sMBR_PARTITION_RECORD.Start_LBA + 2)
LD H,(IX + _sMBR_PARTITION_RECORD.Start_LBA + 3)
POP IX
LD (PARTITION_START_H),HL
LD A,(DRIVE)
LD DE,BOOT_BUFFER
LD BC,1*256 + BIOS.DRV_READ
RST ToBIOS_18
;[ ] 17.12.2023 § £à㧪  á  ªâ¨¢­®£® à §¤¥« ,   ­¥ á ¯¥à¢®£®
POP AF
POP BC
LD L,A ; ­®¬¥à § £à㧮筮£® à §¤¥« 
LD A,C
;
RET
;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*
GET_BPB: LD IX,#0000
LD HL,#0000
LD DE,BOOT_BUFFER
LD BC,1*256 + BIOS.DRV_READ
LD A,(DRIVE)
RST ToBIOS_18
RET C
LD A,(DRIVE)
LD B,A
AND #F0
LD C,A
CP #80
JR NZ,.NX1
CALL PART_TB ;HDD
RET C
;[ ] 17.12.2023 § £à㧪  á  ªâ¨¢­®£® à §¤¥« ,   ­¥ á ¯¥à¢®£®
LD (DRIVE+1),HL
;
.NX1: CP #00
JR NZ,.NX2
;
; SET_PRM if FDD
PUSH BC
LD A,B
LD C,BIOS.DRV_GET_PAR
RST ToBIOS_18
LD A,(BOOT_BUFFER + BOOT_SECTOR.SectorsPerTrack)
LD L,A
POP AF
;PUSH AF
LD C,BIOS.DRV_SET_PAR
RST ToBIOS_18
;POP BC
;LD A,C ; ­ å¥à ?
;RET
.NX2: LD HL,(BOOT_BUFFER + BOOT_SECTOR.MBR_SIGNATURE)
LD DE,#AA55
AND A
SBC HL,DE
SCF
RET NZ
;
LD IY,BOOT_BUFFER ;Analysing Block Parametr BIOS
LD A,(IY+_sBOOT_SECTOR_PARAMS.DRIVE_TYPE)
CP #F0
RET C
LD HL,0 ;calc. first sector FAT
LD (FatBuffer.RootDirFirstSector_H),HL
;
LD E,(IY+_sBOOT_SECTOR_PARAMS.RESERVED_SECTORS) ;Reserve sec
LD D,(IY+_sBOOT_SECTOR_PARAMS.RESERVED_SECTORS+1)
ADD HL,DE
LD (FatBuffer.FAT1_SEC_L),HL ;first sector FAT
LD E,(IY+_sBOOT_SECTOR_PARAMS.SectorsPerFAT16) ;sectors in FAT
LD D,(IY+_sBOOT_SECTOR_PARAMS.SectorsPerFAT16+1)
LD A,(BOOT_BUFFER + BOOT_SECTOR.Number_of_FATs) ;amount FATs
.C_DATA1: ADD HL,DE
DEC A
JR NZ,.C_DATA1
LD (FatBuffer.RootDirFirstSector_L),HL ;first sector DIR
EX DE,HL
LD L,(IY+_sBOOT_SECTOR_PARAMS.FilesInRootDIR) ;Number file handel
LD H,(IY+_sBOOT_SECTOR_PARAMS.FilesInRootDIR+1)
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
LD A,H
SRL A
LD (FatBuffer.DirSizeInSectors),A ;Sectors per dir
LD L,A
LD H,0
ADD HL,DE
LD (FatBuffer.FirstDataSector_L),HL ;First sector data
;
LD C,(IY+_sBOOT_SECTOR_PARAMS.BytesPerSector) ;Size sector
LD B,(IY+_sBOOT_SECTOR_PARAMS.BytesPerSector+1)
LD HL,0
LD A,(BOOT_BUFFER + BOOT_SECTOR.SectorsPerCluster)
.NEXTAD3: ADD HL,BC ;calc. cluster size
DEC A
JR NZ,.NEXTAD3
LD (FatBuffer.BytesPerCluster),HL
LD HL,BOOT_BUFFER + BOOT_SECTOR.ID_FAT
LD DE,FATMSG
LD B,3
.R_BPBL1: LD A,(DE)
CP (HL)
JP NZ,.IBMDOS_
INC HL
INC DE
DJNZ .R_BPBL1
.FID: LD A,(HL)
INC HL
CP " "
JR Z,.FID
CP "1"
SCF
RET NZ
LD A,(HL)
CP "6" ; FAT16
;LD HL,#FFFF
JR Z,.BPB_FAT
CP "2" ; FAT12
SCF
RET NZ
;LD HL,#0FFF
.BPB_FAT: LD (FatBuffer.FAT_TYPE),A
;LD (FatBuffer.END_CHAIN_CLUSTER_L),HL
;
LD IX,(PARTITION_START_L)
LD HL,(PARTITION_START_H)
LD DE,(FatBuffer.FAT1_SEC_L)
LD BC,#0000
ADD IX,DE
ADC HL,BC
;HL:IX
LD DE,FAT_SECTORS_BUFFER
LD BC,3*256 + BIOS.DRV_READ
LD A,(DRIVE)
RST ToBIOS_18
RET C
LD HL,0
LD (FatBuffer.CacheBlock),HL
XOR A
RET
;
.IBMDOS_ LD A,(IY+_sBOOT_SECTOR_PARAMS.DRIVE_TYPE)
CP #F0
RET C
CP #F8
LD A,"6"
LD HL,#FFFF
JR Z,.BPB_FAT
LD A,"2"
LD HL,#0FFF
JR .BPB_FAT
;*/
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
;/*
GET_BPB: LD HL,#0000
;
LD (FatBuffer.FAT1_SEC_H),HL ; high word first sector FAT #1 ; fat32
LD (FatBuffer.RootDirFirstSector_H),HL
;LD (FatBuffer.CacheBlock),HL
XOR A
LD (FatBuffer.SectorsPerFAT_H),A ; fat32
;
PUSH HL
POP IX
; LD IX,#0000
; LD HL,#0000
LD DE,BOOT_BUFFER
LD BC,1*256 + BIOS.DRV_READ
LD A,(DRIVE)
RST ToBIOS_18
RET C
LD A,(DRIVE)
LD B,A
AND #F0
LD C,A
CP #80
JR NZ,.NX1
CALL PART_TB ;HDD
RET C
;[ ] 17.12.2023 § £à㧪  á  ªâ¨¢­®£® à §¤¥« ,   ­¥ á ¯¥à¢®£®
LD (DRIVE+1),HL
;
.NX1: CP #00
JR NZ,.NX2
;
; SET_PRM if FDD
PUSH BC
LD A,B
LD C,BIOS.DRV_GET_PAR
RST ToBIOS_18
LD A,(BOOT_BUFFER + BOOT_SECTOR.SectorsPerTrack)
LD L,A
POP AF
LD C,BIOS.DRV_SET_PAR
RST ToBIOS_18
;
.NX2: LD HL,(BOOT_BUFFER + BOOT_SECTOR.MBR_SIGNATURE)
LD DE,#AA55
;AND A
SBC HL,DE
SCF
RET NZ
;
LD A,(BOOT_BUFFER + BOOT_SECTOR.DRIVE_TYPE)
CP #F0
RET C
;
LD HL,(BOOT_BUFFER + BOOT_SECTOR.BytesPerSector)
LD A,(BOOT_BUFFER + BOOT_SECTOR.SectorsPerCluster)
LD (FatBuffer.SectorsPerCluster),A
; calc. first sector FAT
LD HL,(BOOT_BUFFER + BOOT_SECTOR.RESERVED_SECTORS)
LD (FatBuffer.FAT1_SEC_L),HL ; low word first sector FAT #1
;
LD BC,0
LD DE,(BOOT_BUFFER + BOOT_SECTOR.SectorsPerFAT16)
LD A,E
OR D
JR NZ,.skip_high
;
LD BC,(BOOT_BUFFER + BOOT_SECTOR.SectorsPerFAT32 + 2)
LD A,C
LD (FatBuffer.SectorsPerFAT_H),A
LD DE,(BOOT_BUFFER + BOOT_SECTOR.SectorsPerFAT32)
.skip_high: LD (FatBuffer.SectorsPerFAT_L),DE
LD A,(BOOT_BUFFER + BOOT_SECTOR.Number_of_FATs) ; amount FATs
CP 1
JR Z,.one_FAT
DEC A
ADD HL,DE
JR NC,.no_inc_BC
INC BC
.no_inc_BC: ;
.one_FAT: ;
.loop1: ADD HL,DE
JR NC,.loop1_1
INC BC
.loop1_1: DEC A
JR NZ,.loop1
;
LD (FatBuffer.RootDirFirstSector_L),HL ; first sector DIR
LD (FatBuffer.FirstDataSector_H),BC
LD BC,(BOOT_BUFFER + BOOT_SECTOR.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
;
EX DE,HL
LD HL,(BOOT_BUFFER + BOOT_SECTOR.FilesInRootDIR) ; 0 for fat32
; fat32
LD A,H
OR L
JR Z,.skip_loop2
;
DEC HL
XOR A
;NEXTAD2
.loop2: INC A
RET C
SBC HL,BC
JR NC,.loop2
;
.skip_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,(BOOT_BUFFER + BOOT_SECTOR.BytesPerSector)
LD A,(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 (FatBuffer.BytesPerCluster),HL
LD HL,(BOOT_BUFFER + BOOT_SECTOR.SectorsPerDrive)
LD BC,0
LD A,H
OR L
JP NZ,.HDDSMAL
;
LD HL,(BOOT_BUFFER + BOOT_SECTOR.BPB_BIG_TOTAL_SECTORS_L)
LD BC,(BOOT_BUFFER + BOOT_SECTOR.BPB_BIG_TOTAL_SECTORS_H)
.HDDSMAL: ;
PUSH BC ; Total Sectors high
PUSH HL ; Total Sectors low
XOR A
;LD H,A
;LD L,A
;LD (FatBuffer.CacheBlock),HL
; A = 0
LD DE,(FatBuffer.SectorsPerFAT_H)
LD D,A
LD HL,(FatBuffer.SectorsPerFAT_L)
; DE:HL = SectorsPerFAT
;
LD A,(BOOT_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,(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,(BOOT_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,(FatBuffer.SectorsPerCluster)
; HL:DE / A => DE:BC, H=0, L - ®áâ â®ª
;CALL DIV_for_SPC
LD C,A
DEC A
JR Z,.DIV_exit
;
AND E
LD B,A ; ®áâ â®ª
LD A,C
RRCA
;
.DIV_loop: SRL H
RR L
RR D
RR E
RRCA
JP NC,.DIV_loop
LD A,B
.DIV_exit: LD B,D
LD C,E
EX DE,HL
LD H,0
LD L,A
;
; ¢ëïá­ï¥¬ à §à來®áâì FAT
LD A,D
OR E
JR NZ,.its_FAT32
;
LD HL,4084
SBC HL,BC
LD A,FAT_TYPE.x12
JR NC,.SET_VARS
;
LD HL,65525
SBC HL,BC
LD A,FAT_TYPE.x16
JR NC,.SET_VARS
;
.its_FAT32: LD A,(BOOT_BUFFER + BOOT_SECTOR.MainFATnumber)
CP #80
JR C,.mirrored_FATs ;¥á«¨ ¢á¥ ª®¯¨¨ FAT ¨á¯®«ì§ãîâáï
; ¨á¯®«ì§ã¥âáï ⮫쪮 ®¤­  ª®¯¨ï FAT
LD HL,(FatBuffer.FAT1_SEC_H)
LD DE,(FatBuffer.SectorsPerFAT_H)
LD D,0
EXX
LD HL,(FatBuffer.FAT1_SEC_L)
LD DE,(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 (FatBuffer.FAT1_SEC_L),HL
EXX
LD (FatBuffer.FAT1_SEC_H),HL
.mirrored_FATs: ;
LD HL,(BOOT_BUFFER + BOOT_SECTOR.RootDirStartCluster)
LD DE,(BOOT_BUFFER + BOOT_SECTOR.RootDirStartCluster+2)
CALL CLUSTER_TO_SECTOR.no_prepare
LD (FatBuffer.RootDirFirstSector_L),IX
LD (FatBuffer.RootDirFirstSector_H),HL
LD A,FAT_TYPE.x32
;
.SET_VARS: LD (FatBuffer.FAT_TYPE),A
LD DE,0
CALL READ_FAT_TABLE
AND A
RET
;
;;;;;;;;
;
; HL:DE / A => DE:BC, H=0, L - ®áâ â®ª
; DIV_for_SPC:
; LD C,A
; DEC A
; JR Z,.DIV_exit
; ;
; AND E
; LD B,A ; ®áâ â®ª
; LD A,C
; RRCA
; ;
; .DIV_loop: SRL H
; RR L
; RR D
; RR E
; RRCA
; JP NC,.DIV_loop
; LD A,B
; .DIV_exit: LD B,D
; LD C,E
; EX DE,HL
; LD H,0
; LD L,A
; RET
;
;NSECTOR:
; in: HL':HL - CLUSTER
; out: HL:IX - SECTOR
CLUSTER_TO_SECTOR:
EXX
PUSH HL
EXX
POP DE
; DE:HL - cluster
;
.no_prepare: PUSH BC
LD BC,-2
ADD HL,BC
JR C,.no_dec_de
DEC DE
.no_dec_de: ; cluster = cluster - 2
;
LD A,(FatBuffer.SectorsPerCluster)
XOR 1
JR Z,.skip
;
RRA
.loop: ADD HL,HL
RL E
RL D
;
RRA
JR NC,.loop
;
.skip: EX DE,HL
PUSH DE
POP IX
LD DE,(FatBuffer.FirstDataSector_L)
ADD IX,DE
LD DE,(FatBuffer.FirstDataSector_H)
ADC HL,DE
;
POP BC
RET
;
;*/
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
; ¯®¨áª system.dos
GETROOT: LD HL,(FatBuffer.RootDirFirstSector_H)
LD IX,(FatBuffer.RootDirFirstSector_L)
LD BC,(PARTITION_START_L)
LD DE,(PARTITION_START_H)
LD A,(FatBuffer.FAT_TYPE)
CP FAT_TYPE.x32
LD A,(FatBuffer.DirSizeInSectors)
JR NZ,.NEXTSEC
;
LD A,(FatBuffer.SectorsPerCluster);!FIXIT ¯à®çâñâ ⮫쪮 ¯¥à¢ë© ª« áâ¥à ä ©«®¢ ­  FAT32
.NEXTSEC: PUSH AF
ADD IX,BC
JR NC,.skip_inc
INC HL
;ADC HL,DE
.skip_inc: ;HL:IX
PUSH IX
PUSH HL
LD BC,1*256 + BIOS.DRV_READ
LD DE,DIR_BUFFER
LD A,(DRIVE)
RST ToBIOS_18
CALL SEARCH
POP HL
POP IX
POP BC
RET C
RET NZ
LD A,B
;LD DE,0
LD BC,1
DEC A
JR NZ,.NEXTSEC
SCF
RET
;
SEARCH: LD C,17 ;HANDELS PER SECTOR 512/32 + 1
LD IX, DIR_BUFFER - FAT_DIRECTORY_RECORD
.SKIPNAM: LD DE,FAT_DIRECTORY_RECORD
.SKIPNAM_DE: ADD IX,DE
DEC C
RET Z
;
LD A,(IX+FAT_DIRECTORY_RECORD.NAME)
OR A
SCF
RET Z
;
CP #E5
JR Z,.SKIPNAM_DE
;
LD A,(IX+FAT_DIRECTORY_RECORD.ATTRIBUT)
AND FAT_ATTR.DIRECTORY
JR NZ,.SKIPNAM_DE
;
LD DE,CORE_NAME
PUSH IX
POP HL
LD B,CORE_NAME.Size
;
.loop: LD A,(DE)
CP (HL)
JR NZ,.SKIPNAM
INC HL
INC DE
DJNZ .loop
;
PUSH IX
POP HL
LD DE,HANDBUF
LD BC,FAT_DIRECTORY_RECORD
LDIR
; ZF = 1, CF = 0, A != 0
AND A ; ­  ¢ë室¥ ZF = CF = 0
RET
; HL - CLUSTER
; DE - ADDRESS
; !TODO ᤥ« âì âãâ ®¯à¥¤¥«¥­¨¥ à §¬¥à  SYSTEM.DOS
; [ ] ¨ ¢®§¬®¦­®áâì § £à㧨âì ¡®«ìè¥ 1 áâà ­¨æë
LOAD_CORE: LD (READMEM),DE
.loop: PUSH HL
EXX
PUSH HL
EXX
;
CALL CLUSTER_TO_SECTOR
;
;LD A,(FatBuffer.FAT_TYPE)
; CP FAT_TYPE.x32
; JR NZ,.skip_it
;
LD DE,(PARTITION_START_L)
ADD IX,DE
LD DE,(PARTITION_START_H)
ADC HL,DE
;.skip_it: ;
LD DE,(READMEM)
LD A,(BOOT_BUFFER + BOOT_SECTOR.SectorsPerCluster)
.max_sectors+1: CP #20
JR C,.SMALL_CLUSTER
;
.subload: LD A,(.max_sectors)
LD B,A
LD C,BIOS.DRV_READ_LONG
LD A,(LOAD_CORE.BANKDOS)
EX AF,AF'
LD A,(DRIVE)
RST ToBIOS_18
EXX
POP HL
EXX
POP HL
RET
;
.SMALL_CLUSTER: LD B,A
LD C,BIOS.DRV_READ_LONG
.BANKDOS+1: LD A,0
EX AF,AF'
LD A,(DRIVE)
RST ToBIOS_18
;
LD HL,(READMEM)
LD DE,(FatBuffer.BytesPerCluster)
ADD HL,DE
LD (READMEM),HL
EXX
POP HL
EXX
POP HL
CCF
RET NC
; [ ] § £à㧪  system.dos ¡®«ìè¥ #4000 ¡ ©â®¢
.BIG_CORE+1: LD A,0
DEC A
LD (.BIG_CORE),A
RET Z
;
CALL READ_FROM_FAT
;CALL R_F_FAT
RET C
EXX
EX DE,HL
EXX
EX DE,HL
JP .loop
; HL - CLUSTER
; DE - ADDRESS
;!TODO ᤥ« âì âãâ ®¯à¥¤¥«¥­¨¥ à §¬¥à  SYSTEM.DOS ¨ ¢®§¬®¦­®áâì § £à㧨âì ¡®«ìè¥ 1 áâà ­¨æë
; FLOAD: LD (READMEM),DE
; .LD_FILE: PUSH HL ; system.dos first cluster
; CALL NSECTOR ; Cluster to Sector
; LD DE,(READMEM)
; LD A,(BOOT_BUFFER + BOOT_SECTOR.SectorsPerCluster)
; CP #20 + 1 ; !HARDCODE ª®«-¢® § £à㦠¥¬ëå ᥪâ®à®¢
; LD C,BIOS.DRV_READ_LONG
; JR C,.SMALL_CLUSTER
; LD A,(BANKDOS)
; EX AF,AF'
; ;LD BC,#20*256 + BIOS.DRV_READ_LONG
; LD B,#20 ; !HARDCODE ª®«-¢® § £à㦠¥¬ëå ᥪâ®à®¢
; .set_drv: LD A,(DRIVE)
; RST ToBIOS_18
; JP C,GOOD_DRIVE.NoShell
; POP HL
; ; [ ] § £à㧪  system.dos ¡®«ìè¥ #4000 ¡ ©â®¢
; ;AND A
; ;RET
; LD A,(BIG_SHELL)
; OR A
; RET Z
; ;
; XOR A
; LD (BIG_SHELL),A
; PUSH HL
; CALL NSECTOR
; LD DE,#20 ; !HARDCODE ª®«-¢® ¯à®ç¨â ­­ëå ᥪâ®à®¢
; AND A
; ADD IX,DE
; JR NC,.no_inc_hl
; INC HL
; .no_inc_hl: LD BC,SUBLOAD_SIZE*256 + BIOS.DRV_READ ; !HARDCODE ª®«-¢® „ާ £à㦠¥¬ëå ᥪâ®à®¢
; LD DE,#4000
; JR .set_drv
; ;
; .SMALL_CLUSTER: LD B,A
; LD A,(BANKDOS)
; EX AF,AF'
; LD A,(DRIVE)
; RST ToBIOS_18
; JP C,GOOD_DRIVE.NoShell
; ;
; LD HL,(READMEM)
; LD DE,(CLU_LEN)
; ADD HL,DE
; LD (READMEM),HL
; ; [ ] § £à㧪  system.dos ¡®«ìè¥ #4000 ¡ ©â®¢
; ;POP HL
; ;RET C
; CALL C,.more_than_1
; POP HL
; RET C
; ;
; CALL R_F_FAT ; next cluster in chain
; RET C
; EX DE,HL
; JP .LD_FILE
; ; [ ] § £à㧪  system.dos ¡®«ìè¥ #4000 ¡ ©â®¢
; .more_than_1: LD A,(BIG_SHELL)
; OR A
; SCF
; RET Z
; IN A,(SLOT1)
; LD HL,BANKDOS
; CP (HL)
; CCF
; RET Z
; LD (BANKDOS),A
; LD HL,#C000
; LD (READMEM),HL
; LD A,(BOOT_BUFFER + BOOT_SECTOR.SectorsPerCluster)
; SUB SUBLOAD_SIZE + 1
; CCF
; RET NC
; LD A,SUBLOAD_SIZE
; LD (BOOT_BUFFER + BOOT_SECTOR.SectorsPerCluster),A
; AND A
; RET
;
/*
; --> HL - CLUSTER
; <-- HL:IX - SECTOR
NSECTOR: LD DE,0
DEC HL
DEC HL
LD A,(BOOT_BUFFER + BOOT_SECTOR.SectorsPerCluster)
XOR 1
JR Z,.skip
;
RRA
.loop: ADD HL,HL
RL E
RL D
RRA
JP NC,.loop
;
.skip: EX DE,HL
PUSH DE
POP IX
LD DE,(FatBuffer.FirstDataSector_L) ;first data sector
XOR A
ADD IX,DE
LD D,A
LD E,A
ADC HL,DE
;
LD DE,(PARTITION_START_L)
ADD IX,DE
LD DE,(PARTITION_START_H)
ADC HL,DE
RET
*/
;------------------------------------------------------------------------------------------------
; <20>à®ç¨â âì ¨§ ª¥è  FAT-  ­®¬¥à á«¥¤. ª« áâ¥à 
; ¢å®¤: hl - ­®¬¥à ª« áâ¥à  (¬« ¤è¥¥ á«®¢®)
; hl' - ­®¬¥à ª« áâ¥à  (áâ à襥 á«®¢®. ⮫쪮 ¤«ï FAT32)
; ¢ë室: hl - ­®¬¥à ª« áâ¥à  (¬« ¤è¥¥ á«®¢®)
; hl' - ­®¬¥à ª« áâ¥à  (áâ à襥 á«®¢®)
; de - ­®¬¥à á«¥¤. ª« áâ¥à  (¬« ¤è¥¥ á«®¢®)
; de' - ­®¬¥à á«¥¤. ª« áâ¥à  (áâ à襥 á«®¢®)
; ¥á«¨ DE':DE = 0, â® ª« áâ¥à HL':HL ᢮¡®¤¥­
; CF - ª®­¥æ 楯®çª¨
;------------------------------------------------------------------------------------------------
READ_FROM_FAT: PUSH HL
;
IN A,(SLOT3)
PUSH AF
LD A,SHARED_PAGE
OUT (SLOT3),A
;
LD A,(FatBuffer.FAT_TYPE)
CP FAT_TYPE.x16
JR C,.FAT12
JR NZ,.FAT32
; fat16, ¯à®áâ® ç¨â âì á«¥¤. ­®¬¥à
.FAT16: CALL GET_FAT16_CELL
LD E,(HL) ; ¯à®ç¨â âì ­®¬¥à ª« áâ¥à 
INC HL
LD D,(HL)
;
LD HL,SERVICE_SECTORS.FAT16
.exit: POP AF
OUT (SLOT3),A
; ®¡­ã«ï¥¬ CF ¨ ãáâ ­ ¢«¨¢ ¥¬ ª®¤ ®è¨¡ª¨ = DssErr.sys.NO_ERROR
XOR A
; ¯à®¢¥àª  ­  á«ã¦. ª« áâ¥àë
SBC HL,DE
POP HL
;!FIXIT fat32 ¯¥à¥áâà å®¢ª 
EXX
LD H,A
LD L,A
LD D,A
LD E,A
EXX
RET
;
;
.FAT12: CALL GET_FAT12_CELL
LD E,(HL)
INC HL
LD D,(HL)
LD HL,SERVICE_SECTORS.FAT12
JR NC,.Correct_2
.Correct_1: LD A,E
AND #F0
DUP 4 ; ¢¯à ¢® ­  4 ¡¨âa
RR D
RRA
EDUP
LD E,A
JR .exit
;
.Correct_2: LD A,D
AND #0F
LD D,A
JR .exit
;
.FAT32: EXX
PUSH HL
EXX
;
CALL GET_FAT32_CELL
; ¯à®ç¨â âì ¬« ¤è¥¥ á«®¢® ­®¬¥à  ª« áâ¥à 
LD E,(HL)
INC HL
LD D,(HL)
INC HL
; ¯à®ç¨â âì áâ à襥 á«®¢® ­®¬¥à  ª« áâ¥à 
LD A,(HL)
INC HL
EX AF,AF'
LD A,(HL)
EXX
AND #0F
LD D,A
EX AF,AF'
LD E,A
EXX
; ®¡­ã«ï¥¬ CF ¨ ãáâ ­ ¢«¨¢ ¥¬ ª®¤ ®è¨¡ª¨ = DssErr.sys.NO_ERROR
XOR A
; ¯à®¢¥àª  ­  á«ã¦. ª« áâ¥àë ¬« ¤è¥£® á«®¢  ª« áâ¥à 
LD HL,SERVICE_SECTORS.FAT32.Low
SBC HL,DE
; ¯à®¢¥àª  ­  á«ã¦. ª« áâ¥àë áâ à襣® á«®¢  ª« áâ¥à 
EXX
LD HL,SERVICE_SECTORS.FAT32.High
SBC HL,DE
POP HL
EXX
POP BC
LD A,B
OUT (SLOT3),A
POP HL
LD A,0
RET
;
;¢å®¤: HL - ­®¬¥à ª« áâ¥à 
;¢ë室: HL -  ¤à¥á ­ã¦­®© ï祩ª¨ ¢ áâà ­¨æ¥ FATPAGE
; CF - çñâ­ë©/­¥çñâ­ë©  ¤à¥á ª« áâ¥à 
GET_FAT12_CELL: LD D,H
LD E,L
SRL H
RR L ; ᤢ¨£ ¢¯à ¢® ç¥à¥§ CF
PUSH AF ; á®åà. ä« £
ADD HL,DE ; CLUSTER * 1.5
;
IF FAT_CACHE.Size_12 < #1800
;!FIXIT ®¯â¨¬¨§¨à®¢ âì
LD A,H
LD B,H
;
AND #1F
;AND FAT_CACHE.Size_Mask_16
;
LD H,A
LD A,B
;
RLCA
RLCA
RLCA
;DUP FAT_CACHE.Degree_16
; RRCA
;EDUP
AND #07
;AND FAT_CACHE.Part_Mask_16
;
; [ ] ¯®¬¥­ï«áï ¢å®¤ ¢ ¯à®æ¥¤ãàã READ_FAT_TABLE. <20> ­ìè¥ ­®¬¥à ¡«®ª  ¢ ॣ. A ¯¥à¥¤ ¢ «áï
LD DE,(FatBuffer.CacheBlock) ; BC - BLOCK FAT IN CASH
CP E
LD E,A
;
CALL NZ,READ_FAT_TABLE ; ¯à®ç¨â âì ¢ ª¥è 16 ᥪâ®à®¢ FAT- 
ENDIF
;
LD DE,FATPAGE.cache
ADD HL,DE
POP AF
RET
;
;¢å®¤: HL - ­®¬¥à ª« áâ¥à 
;¢ë室: HL -  ¤à¥á ­ã¦­®© ï祩ª¨ ¢ áâà ­¨æ¥ FATPAGE
GET_FAT16_CELL: LD A,H
LD B,H
AND FAT_CACHE.Size_Mask_16
LD H,A
LD A,B
; A=A/16 ; A - BLOCK FAT (1 BLOCK = 8192 BYTES)
DUP FAT_CACHE.Degree_16
RRCA
EDUP
;AND #0F
AND FAT_CACHE.Part_Mask_16
;
ADD HL,HL ; HL - FAT OFFSET (FROM CASH)
; [x] fat32 ¯®¬¥­ï«áï ¢å®¤ ¢ ¯à®æ¥¤ãàã READ_FAT_TABLE. <20> ­ìè¥ ­®¬¥à ¡«®ª  ¢ ॣ. A ¯¥à¥¤ ¢ «áï
LD DE,(FatBuffer.CacheBlock) ; BC - BLOCK FAT IN CASH
CP E
LD E,A
;
CALL NZ,READ_FAT_TABLE ; A != C - READ NEW BLOCK FAT
LD DE,FATPAGE.cache ; ­ ç «® ª¥è  FAT- 
ADD HL,DE ; ­  ï祩ªã FAT
RET
;
;¢å®¤: HL':HL - ­®¬¥à ª« áâ¥à 
;¢ë室: HL -  ¤à¥á ­ã¦­®© ï祩ª¨ ¢ áâà ­¨æ¥ FATPAGE
GET_FAT32_CELL: ; ¤¢¨£ ¥¬ ¢«¥¢® HL':H
LD A,H
EXX
LD C,A
LD A,H
AND FAT_CACHE.Size_Mask_32 ; #0F
LD H,A
LD A,C
;
LD B,FAT_CACHE.Degree ; 4 ᤢ¨£ 
.loop_block: RLCA ; << H
RL L ; << L'
RL H ; << H'
DJNZ .loop_block
EXX
; ¨â®£¥ âãâ ¢ HL' ­®¬¥à ¡«®ª  FAT
;
; HL - FAT32 OFFSET (FROM CASH)
LD A,H
AND FAT_CACHE.Size_Mask_32 ; #0F
LD H,A
ADD HL,HL
ADD HL,HL
PUSH HL ; [ç] fat32 á®å࠭塞 ­  á«ãç ©, ¥á«¨ READ_FAT_TABLE ¨á¯®àâ¨â
AND A
;
EXX
EX DE,HL
LD HL,(FatBuffer.CacheBlock) ; BC - BLOCK FAT IN CASH
SBC HL,DE
CALL NZ,READ_FAT_TABLE ; A != C - READ NEW BLOCK FAT
POP HL
LD DE,FATPAGE.cache ; ­ ç «® ª¥è  FAT- 
ADD HL,DE ; ­  ï祩ªã FAT
RET
;
/*
;-----------------
; HL - CLUSTER
; DE - (CLUSTER)
R_F_FAT: PUSH HL
LD A,(FatBuffer.FAT_TYPE)
CP "2"
JP Z,.R_F_F12
;
.R_F_F16: LD DE,768 ; DE - CLUSTERS IN CASH
XOR A
.R_F_00H: INC A ; HL - CLUSTER ; [ ] fat32 âãâ áçñâ稪 ¢ 32 ¡¨â  ­ã¦¥­ ¨«¨ 16, ¥á«¨ áâà ­¨æã FF ¨á¯®«ì§®¢ âì
SBC HL,DE
JP NC,.R_F_00H
ADD HL,DE
ADD HL,HL ; HL - FAT OFFSET (FROM CASH)
DEC A
LD BC,(FatBuffer.CacheBlock) ; A - ELEMENT OF CASH
CP C
CALL NZ,RE_FAT
LD DE,FAT_SECTORS_BUFFER
ADD HL,DE
LD E,(HL)
INC HL
LD D,(HL)
LD HL,#FFEF
;
.exit: XOR A
SBC HL,DE
POP HL
RET
;
.R_F_F12 LD D,H
LD E,L
ADD HL,HL
ADD HL,DE
RR H
RR L
PUSH AF
EX DE,HL
LD HL,(BOOT_BUFFER + BOOT_SECTOR.BytesPerSector)
LD B,H
LD C,L
ADD HL,HL
ADD HL,BC
EX DE,HL
XOR A ; DE - SIZE SECTOR * 3
.R_F_00: INC A ; HL - FAT OFFSET
SBC HL,DE
JP NC,.R_F_00
ADD HL,DE
DEC A
LD BC,(FatBuffer.CacheBlock)
CP C
CALL NZ,RE_FAT
LD DE,FAT_SECTORS_BUFFER
ADD HL,DE
POP AF
LD E,(HL)
INC HL
LD D,(HL)
JP C,.R_F_F01
LD A,D
AND #0F
LD D,A
JR .R_F_F02
;
.R_F_F01: LD A,E
AND #F0
RR D ; ¢¯à ¢® ­  4 ¡¨âa
RRA
RR D
RRA
RR D
RRA
RR D
RRA
LD E,A
;
.R_F_F02: LD HL,#0FEF
JR .exit
; XOR A
; SBC HL,DE
; POP HL
; RET
;
*/
;
;
/*
RE_FAT: PUSH HL
LD L,A
LD H,0
LD (FatBuffer.CacheBlock),HL
LD E,L
LD D,H
ADD HL,HL
ADD HL,DE
LD IX,0
LD DE,(FatBuffer.FAT1_SEC_L)
ADD HL,DE
EX DE,HL
JR NC,.NOINX
INC IX
.NOINX: LD HL,(PARTITION_START_L)
ADD HL,DE
EX DE,HL
LD BC,(PARTITION_START_H)
JR NC,.NOINX2
INC IX
.NOINX2: ADD IX,BC
PUSH IX
PUSH DE
POP IX
POP HL
LD DE,FAT_SECTORS_BUFFER
LD BC,3*256 + BIOS.DRV_READ
LD A,(DRIVE)
RST ToBIOS_18
POP HL
RET
*/
;
;RE_FAT:
;RX01
; <20>à®ç¨â âì ¢ ª¥è •• ᥪâ®à®¢ FAT- 
; DE - NEW FAT BLOCK
READ_FAT_TABLE: PUSH HL
;
EX DE,HL
LD (FatBuffer.CacheBlock),HL
;
CALL GET_SECTOR_OF_FAT
;
; BC:HL - ­®¬¥à «®£.ᥪâ®à 
LD DE,(FatBuffer.FAT1_SEC_L)
ADD HL,DE
;
; EX DE,HL
; LD XH,D
; LD XL,E
PUSH HL
POP IX
;
LD HL,(FatBuffer.FAT1_SEC_H)
.no_inc: ADC HL,BC
; HL:IX - SECTOR FAT FOR READING
;
LD DE,(PARTITION_START_L)
ADD IX,DE
LD DE,(PARTITION_START_H)
ADC HL,DE
LD DE,FAT_SECTORS_BUFFER
;
IN A,(SLOT3)
PUSH AF
LD A,SHARED_PAGE
OUT (SLOT3),A
;
LD A,(FatBuffer.FAT_TYPE)
XOR FAT_TYPE.x32
LD BC,FAT_CACHE.Sectors_16*256 + BIOS.DRV_READ
JR NZ,.next
LD B,FAT_CACHE.Sectors_32
.next: LD A,(DRIVE)
RST ToBIOS_18
;
POP AF
OUT (SLOT3),A
POP HL
RET
;
;FAT_BLOCK * Sectors_in_Block = SECTOR_OF_FAT
; in: HL - Cache block
; out: C:HL - logical number
; B = 0
GET_SECTOR_OF_FAT:
LD A,(FatBuffer.FAT_TYPE)
LD B,FAT_CACHE.Degree_32 ;!FIXIT ᤥ« âì ç¥à¥§ ¯¥à¥¬¥­­ãî
XOR FAT_TYPE.x32
JR Z,.next
LD B,FAT_CACHE.Degree ;!FIXIT ᤥ« âì ç¥à¥§ ¯¥à¥¬¥­­ãî
XOR A
.next: LD C,A
;
.loop: ADD HL,HL ;x2
ADC A,C
DJNZ .loop
;
LD C,A
RET
////////////////////////////////////////////////////////////////////////
; Area for boot sector [512Bytes]
;BOOT _sBOOT_SECTOR_PARAMS = $
BOOT_BUFFER EQU $
DIR_BUFFER EQU BOOT_BUFFER+512
;
;FAT_SECTORS_BUFFER EQU DIR_BUFFER+512
;VALUE EQU 3*512+FAT_SECTORS_BUFFER
FAT_SECTORS_BUFFER EQU #C000
VALUE EQU DIR_BUFFER+512
FatBuffer _sysFatBuffer = VALUE
/*
.DRIVE: BYTE #FF
.FAT_TYPE: BYTE #00 ; TYPE FAT (12 - 12bit, 16 - 16bit, 32 - 32bit) ; fat32
.CacheBlock: WORD #0000
.CacheUpdated: BYTE #00
.RootDirStartCluster_L: WORD #0000
.RootDirStartCluster_H: WORD #0000 ; fat32
.FAT1_SEC_L: WORD #0000 ; MSD_FAT_SEC first sector FAT (FAT_FRM)
.FAT1_SEC_H: WORD #0000 ; fat32
.FAT2_SEC_L: WORD #0000
.FAT2_SEC_H: WORD #0000 ; fat32
.Number_Of_FATs BYTE #02
.SectorsPerFAT_L WORD #0000
.SectorsPerFAT_H BYTE #00
.RootDirFirstSector_L: WORD #0000 ; MSD_CAT_SEC first sector DIR
.RootDirFirstSector_H: WORD #0000 ; MSD_CAT_SEC first sector DIR
.DirSizeInSectors: BYTE #00 ; DIR_SEC_SIZE
.FirstDataSector_L: WORD #0000 ; MSD_DAT_SEC low
.FirstDataSector_H: WORD #0000 ; MSD_DAT_SEC high
.BytesPerCluster: WORD #0000 ; CLUSTER_LEN
.END_CHAIN_CLUSTER_L: WORD #FFFF
.END_CHAIN_CLUSTER_H: WORD #0FFF
.MaxClusterLow: WORD #0000 ; ¬ ªá. ç¨á«® ª« áâ¥à®¢ (¡¥§ á«ã¦.)
.MaxClusterHigh: WORD #0000 ; ¬ ªá. ç¨á«® ª« áâ¥à®¢ (¡¥§ á«ã¦.)
.BytesPerSector: WORD #0000
.SectorsPerCluster: BYTE #00
.FSINFO_Sector: WORD #01
.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
;.FilesPerSector: BYTE #00 ; ç¨á«® ä ©«®¢ëå § ¯¨á¥© ¢ ᥪâ®à¥
;.ClustersPerBank: BYTE #00 ; A - Clusters per bank (16k) (ç¨á«® ª« áâ¥à®¢ ­  ¡«®ª އ“)
;.READ_PG: BYTE #00 ;!TODO ­¥ ¨á¯®«ì§ãîâáï ­¥ª®â®àë¥ §­ ç¥­¨ï, ­® § ¤ã¬ª  ­¥¯«®å ï)))
;.S_X_H: DWORD #0000 ; ª®«¨ç¥á⢮ ᥪâ®à®¢ ­  樫¨­¤à¥
FatBuffer EQU VALUE
.CacheBlock EQU FatBuffer+0 ; FatCache
.FAT1_SEC_L EQU FatBuffer+2 ; FAT_FRM MSD_FAT_SEC first sector FAT
.RootDirFirstSector_H EQU FatBuffer+4 ; DIR_FRH MSD_CAT_SEC first sector DIR
.RootDirFirstSector_L EQU FatBuffer+6 ; DIR_FRL MSD_CAT_SEC first sector DIR
.DirSizeInSectors EQU FatBuffer+8 ; DIR_S_S DIR_SEC_SIZE
.FirstDataSector_L EQU FatBuffer+9 ; DAT_FRM MSD_DAT_SEC
.FAT_TYPE EQU FatBuffer+11; FAT_TYP ; !FIXIT TYPE FAT (#32 - 12bit, #36 - 16bit)
.BytesPerCluster EQU FatBuffer+12; CLU_LEN
.FAT1_SEC_H EQU FatBuffer+14 ;
.SectorsPerFAT_L EQU FatBuffer+16
.SectorsPerFAT_H EQU FatBuffer+18
.FAT2_SEC_L EQU FatBuffer+20
.FAT2_SEC_H EQU FatBuffer+22
;.END_CHAIN_CLUSTER_L EQU FatBuffer+14; ENDCLUS
*/
; FatCache EQU VALUE+0 ; .CacheBlock
; FAT_FRM EQU FatCache+2 ; .FAT1_SEC_L MSD_FAT_SEC first sector FAT
; DIR_FRH EQU FatCache+4 ; .RootDirFirstSector_H MSD_CAT_SEC first sector DIR
; DIR_FRL EQU FatCache+6 ; .RootDirFirstSector_L MSD_CAT_SEC first sector DIR
; DIR_S_S EQU FatCache+8 ; .DirSizeInSectors DIR_SEC_SIZE
; DAT_FRM EQU FatCache+9 ; .FirstDataSector_L MSD_DAT_SEC
; FAT_TYP EQU FatCache+11; .FAT_TYPE ; !FIXIT TYPE FAT (#32 - 12bit, #36 - 16bit)
; CLU_LEN EQU FatCache+12; .BytesPerCluster
; ENDCLUS EQU FatCache+14; .END_CHAIN_CLUSTER_L
HANDBUF EQU VALUE + _sysFatBuffer
FCLUSTER_H EQU HANDBUF + FAT_DIRECTORY_RECORD.FIRST_CLUSTER_H
FCLUSTR_L EQU HANDBUF + FAT_DIRECTORY_RECORD.FIRST_CLUSTER_L
FSIZE0 EQU HANDBUF + FAT_DIRECTORY_RECORD.F_SIZE
FSIZE1 EQU HANDBUF + FAT_DIRECTORY_RECORD.F_SIZE + 2
PARTITION_START_H EQU FSIZE1+2
PARTITION_START_L EQU PARTITION_START_H+2
READMEM EQU PARTITION_START_L+2
;BIG_CORE EQU READMEM+2
DISPLAY "BOOT_BUFFER ",/H,BOOT_BUFFER
DISPLAY "DIR_BUFFER ",/H,DIR_BUFFER
DISPLAY "FatBuffer ",/H,FatBuffer
ENT
ENDMODULE
OUTEND
;[]-----------------------------------------------------------[]