Estex-DSS/BOOT/DSSBOOT.ASM
Anatoliy Belyanskiy 51c118ee62 bugfixes
2024-06-10 01:29:44 +10:00

1227 lines
25 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 § £à㦠¥â ®¤¨­ ᥪâ®à § £àã§ç¨ª  ¨ ¯¥à¥¤ ñâ ¥¬ã ã¯à ¢«¥­¨¥.
; 0 - ®à¨£¨­ «ì­ë© ¢ à¨ ­â § ¯ã᪠ DSS, 1 - ¢ à¨ ­â ‘ ©¬ ­ 
DEFINE ORIGINAL_DSS 0
; 1 - ¡ã¤¥â £à㧨âì ¢¥àá¨î ‘ ©¬ ­  ¨ ®á­®¢­ãî. 0 - ⮫쪮 ®á­®¢­ãî.
DEFINE UNIVERSAL_BOOT 1
;------------------------------------------------------------------------------
ORG_ADDRESS EQU #8000
LOAD_SECTORS EQU SECTORS_OF_LOADER.AFTER_BPB
LOADER_IN_BPB:
.MAX_SIZE EQU _sBOOT_SECTOR.PARTITION_TABLE - _sBOOT_SECTOR_PARAMS_FAT32
;------------------------------------------------------------------------------
DISP ORG_ADDRESS
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: LD HL,(BOOT_BUFFER + BOOT_SECTOR.MBR_SIGNATURE)
LD DE,#AA55
; CF = 0
SBC HL,DE
SCF
RET NZ
;
PUSH BC
LD IX,BOOT_BUFFER + BOOT_SECTOR.PARTITION_TABLE
LD B, +(_sMBR_PARTITION_TABLE / _sMBR_PARTITION_RECORD)
;
LD HL,YEPDOS
;
.part_loop: LD A,(IX + _sMBR_PARTITION_RECORD.FS_ID)
; …‘‹ˆ ¤®¡ ¢¨âáï ¯®¤¤¥à¦ª  ¥éñ ­¥áª®«ìª¨å ⨯®¢ ”‘, â® ¯®¬¥­ïâì 1fs ­  2fs
; 1
CP PartitionSysTypes.FAT16_LBA
JR Z,YEPDOS
CP PartitionSysTypes.FAT16
JR Z,YEPDOS
CP PartitionSysTypes.FAT16_32Mb
JR Z,YEPDOS
CP PartitionSysTypes.FAT12
JR Z,YEPDOS
CP PartitionSysTypes.FAT32
JR Z,YEPDOS
CP PartitionSysTypes.FAT32_LBA
JR Z,YEPDOS
;
; 2fs
; EXX
; LD HL,SUPPORTED_PARTITIONS
; LD BC,SUPPORTED_PARTITIONS.Size
; CPIR
; EXX
; RET Z ;JR Z,YEPDOS
;
.next: LD DE,_sMBR_PARTITION_RECORD
ADD IX,DE
DJNZ .part_loop
;
LD HL,MESSAGES.ERRPART
JP FAIL
; 2fs
; 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 HL,#0000
;
LD (FatBuffer.FAT1_SEC_H),HL ; high word first sector FAT #1
LD (FatBuffer.RootDirFirstSector_H),HL
;LD (FatBuffer.CacheBlock),HL
XOR A
LD (FatBuffer.SectorsPerFAT_H),A
;
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
; ¯¥à¥ª¨¤ë¢ ­¨¥ ç á⨠§ £àã§ç¨ª  ¨§ 0 ᥪâ®à 
LD HL,BOOT_BUFFER + (_sBOOT_SECTOR.PARTITION_TABLE - ZERO_SECTOR_OF_BPB.Size)
LD DE,ZERO_SECTOR_OF_BPB
LD BC,ZERO_SECTOR_OF_BPB.Size
LDIR
;
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
LD A,H
OR L
JR Z,.skip_loop2
;
DEC HL
XOR A
.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
;
;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: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
//// //// //// //// //// //// //// //// ////
//// //// //// //// //// //// //// //// ////
DISPLAY "SECTORS 1..3 DATA ENDS:\t",/H,$,". Size: ",/D,$-ORG_ADDRESS," b. Free: ",/D,512*3-($-ORG_ADDRESS)," b."
ZERO_SECTOR_OF_BPB:
.physical EQU $$$
//// //// //// //// //// //// //// //// ////
//// //// //// //// //// //// //// //// ////
;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
;
;¢å®¤: 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)
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
;
;
;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
;¢å®¤: 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
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
;
;------------------------------------------------------------------------------------------------
; <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
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
;
//// //// //// //// //// //// //// //// ////
//// //// //// //// //// //// //// //// ////
DISPLAY "SECTORS 0 DATA ENDS:\t\t",/H,$,". Size: ",/D,$-ZERO_SECTOR_OF_BPB," b. Free: ",/D,LOADER_IN_BPB.MAX_SIZE-($-ZERO_SECTOR_OF_BPB)," b."
ZERO_SECTOR_OF_BPB_END:
ZERO_SECTOR_OF_BPB.Size EQU ZERO_SECTOR_OF_BPB_END - ZERO_SECTOR_OF_BPB
//// //// //// //// //// //// //// //// ////
//// //// //// //// //// //// //// //// ////
;
;
////////////////////////////////////////////////////////////////////////
; 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
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
;[]-----------------------------------------------------------[]