FORMAT/format/new_format.asm
2026-04-06 01:46:22 +10:00

883 lines
22 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.

;!TODO:
; [ ] Dss.DRV.Open
; [ ] Dss.DRV.Close
; [ ] .SectorsPerFAT32 DWORD 0 error ¥á«¨ áâ à訩 ¡ ©â !=0
; [ ] .FAT.LABEL DB 'NO_LABEL ' ¤®¯®«­¨â¥«ì­® ¯¨á âì ¢ ª®à­¥¢ãî ¤¨à¥ªâ®à¨î
/*
BOOT_SECTOR EQU #00
.JMP EQU #00 ; BLOCK 3,0 BS_jmpBoot Jump to bootstrap (E.g. eb 3c 90; on i86: JMP 003E NOP. One finds either eb xx 90, or e9 xx xx.
.ID_NAME EQU #03 ; TEXT 8 BS_OEMName DOS NAME - DB "DSS_1.70"
; Block Parameters BIOS
.BytesPerSector GenIOCTL.GetParams EQU #0B ; WORD #200 BPB_BytsPerSec <09> §¬¥à ᥪâ®à  ¢ ¡ ©â å
.SectorsPerCluster ;!TODO EQU #0D ; BYTE 2 BPB_SecPerClus <09> §¬¥à ª« áâ¥à  ¢ ᥪâ®à å
.RESERVED_SECTORS !RESERVED_SECTORS EQU #0E ; WORD 1 BPB_ResvdSecCnt <09> §¬¥à á¨á⥬­®© ®¡« á⨠(¢ª«îç ï íâ®â ᥪâ®à) RESERVE SECTORS
.Number_of_FATs 2 EQU #10 ; BYTE 2 BPB_NumFATs Š®«¨ç¥á⢮ â ¡«¨æ FAT
.FilesInRootDIR 0 EQU #11 ; WORD 112 BPB_RootEntCnt —¨á«® ®¯¨á â¥«¥© ä ©«®¢ ¢ ª®à­¥¢®¬ ª â «®£¥ (¢ FAT32 - 0)
.SectorsPerDrive 0 EQU #13 ; WORD 1440 BPB_TotSec16 ޡ饥 ç¨á«® ᥪâ®à®¢ ­  ¤¨áª¥ (¥á«¨ 0, â® à §¬¥à - ¢ .BPB_BIG_TOTAL_SECTORS)
.DRIVE_TYPE !DRV_TYPE EQU #15 ; BYTE #F0 BPB_Media ’¨¯ ãáâனá⢠
.SectorsPerFAT16 0 EQU #16 ; WORD 2 BPB_FATSz16 <09> §¬¥à ®¤­®© FAT ¢ ᥪâ®à å (0 ¢ FAT32)
.SectorsPerTrack GenIOCTL.GetParams EQU #18 ; WORD 9 BPB_SecPerTrk <09> §¬¥à ¤®à®¦ª¨ ¢ ᥪâ®à å
.HEADS GenIOCTL.GetParams EQU #1A ; WORD 2 BPB_NumHeads ª®«¨ç¥á⢮ £®«®¢®ª
.HIDDEN EQU #1C ; DWORD 0 BPB_HiddSec ª®«¨ç¥á⢮ áªàëâëå ᥪâ®à®¢
.BPB_BIG_TOTAL_SECTORS_L EQU #20 ; WORD 0 BPB_TotSec32 BIG TOTAL SECTOR Low word
.BPB_BIG_TOTAL_SECTORS_H EQU #22 ; WORD 0 BPB_TotSec32 BIG TOTAL SECTOR High word
; FAT 32
.SectorsPerFAT32 EQU #24 ; DWORD 4 BPB_FATSz32 <09> §¬¥à ®¤­®© FAT ¢ ᥪâ®à å
.MainFATnumber 0 EQU #28 ; WORD 0 BPB_ExtFlags <09>®¬¥à £« ¢­®© â ¡«¨æë FAT
.Version 0 EQU #2A ; WORD 0 BPB_FSVer ‚¥àá¨ï FAT32 (®¡ëç­® 0)
.RootDirStartCluster 2 EQU #2C ; DWORD 2 BPB_RootClus <09>¥à¢ë© ª« áâ¥à ª®à­¥¢®£® ª â «®£  (®¡ëç­® 2)
.FSINFO_Sector 1 EQU #30 ; WORD 1 BPB_FSInfo <09>®¬¥à ᥪâ®à  áâàãªâãàë FSINFO (®¡ëç­® 1)
.CopyBootSector 6 EQU #32 ; WORD 6 BPB_BkBootSec <09>®¬¥à ᥪâ®à  - ª®¯¨¨ § £à㧮筮£® (®¡ëç­® 6)
.reserved_block: 0 EQU #34 ; BLOCK 12 BPB_Reserved ‡ à¥§¥à¢¨à®¢ ­®
.FDD_Number GenIOCTL.GetParams&#F0 EQU #40 ; BYTE 0 BS_DrvNum <09>®¬¥à ¤¨áª®¢®¤  ¤«ï ä㭪権 BIOS
.reserved_2: 0 EQU #41 ; BYTE 0 BS_Reserved1 ‡ à¥§¥à¢¨à®¢ ­®
.FAT32.EXT_BOOT_REC_SIGNATURE EQU #42 ; BYTE #29 BS_BootSig ‘¨£­ âãà  - #29
.FAT32.SERIAL_NUMBER EQU #43 ; DWORD 0 BS_VolID VOLUME SERIAL NUMBER
.FAT32.LABEL EQU #47 ; TEXT 11 BS_VolLab Œ¥âª  ¤¨áª 
.ID_FAT32 EQU #52 ; TEXT 8 BS_FilSysType €¡¡à¥¢¨ âãà  ä ©«®¢®© á¨á⥬ë
.BOOT_CODE_FAT32 EQU #5A
------------------------------------------------------------------------
!DRV_TYPE: GenIOCTL.GetParams - 䨧¨ç¥áª¨© ­®¬¥à
0,1 - BIOS.DRV_GET_PAR - ⨯ ä«®¯ àï
#8x - Hard Drive
®áâ «ì­®¥ ¯®¤ã¬ âì
;;;;;;;;;;;;;;;;;
¤«ï ᬥ饭¨ï FAT ¤® ªà â­®£® 4096 §­ ç¥­¨ï:
1) tmp1 = ((.HIDDEN + min_last_sector) & #0F)>0 ) * #10
2) tmp2 = (.HIDDEN + min_last_sector) & #FFFF'FFF0
3) tmp3 = tmp2 + tmp1
4) error = (tmp3 >= #1000'0000) ; LBA28
reserved_sectors = ( ((.HIDDEN + min_last_sector) & #0F)>0 ) * #10) - .HIDDEN
;;;;;;;;;;;;;;;;;
*/
; DSS Drive Formatter
////////////////////////////////////////////////////////////////////////
;-----------------------------------------------------------------------
DSS_DRIVE_FORMAT:
;-----------------------------------------------------------------------
LD A,(KEYS_PARAMETERS.FAT_TYPE + KEYS_PARAMETERS.Status)
LD C,A
; ¯à®¢¥àª  ­  § âã¯
LD A,(KEYS_PARAMETERS.FilesInRootDIR + KEYS_PARAMETERS.Status)
AND A
JR Z,.no_zatup
;
LD A,C
OR A
JR Z,.no_zatup
;
LD A,(KEYS_PARAMETERS.FAT_TYPE + KEYS_PARAMETERS.Data)
CP CONSTANTS.FAT32
JR NZ,.no_zatup
;
LD A,KEYS_PARAMETERS.Status.Ignored
LD (KEYS_PARAMETERS.FilesInRootDIR + KEYS_PARAMETERS.Status),A
.no_zatup: ; ¯à®¢¥àª  ­   ¢â®-à áçñâ
LD A,(KEYS_PARAMETERS.SectorsPerCluster + KEYS_PARAMETERS.Status)
OR C
JR Z,MAKE_AUTO
;
; !TODO
;
MAKE_AUTO: LD (STOP_ERROR.Save_SP),SP
;!FIXIT
LD A,(FMTDISK)
LD (VARIABLES.CurrentDrive),A
;
CALL CALCULATE_FAT
CALL FORMAT_DRIVE
CALL MAKE_LABEL_IN_DIR
;!FIXIT
;CALL MAKE_ROOT_DIR_LABEL ; ¯¥à¢ ï § ¯¨áì ¢ root dir - ¬¥âª , ¯®â®¬ ­ã«¨
RET
;-----------------------------------------------------------------------
; €¢â®¬ â¨ç¥áª®¥ ¯à¥¤¥«¥­¨¥ ¯ à ¬¥â஢ ­®á¨â¥«ï ¨ ¢ë¡®à FAT
CALCULATE_FAT: CALL .STEP1 ; íâ  ¤®«¦­  ¡ëâì ®¡é¥© ¤«ï § ¯®«­¥­¨ï £¥®¬¥âਨ ¤¨áª 
; €¢â®¬ â¨ç¥áª¨© ¢ë¡®à FAT_TYPE, RESERVED_SECTORS, SectorsPerCluster
CALL .STEP2
; RESERVED_SECTORS, RootDir, ¤ «ìè¥ ãáâ ­ ¢«¨¢ ¥¬ £¥®¬¥âà¨î. “¦¥ ¤®«¦¥­ ¡ëâì ¢ë¡à ­ ⨯ FAT
CALL .STEP3
CALL MAKE_SERIAL
RET
;--------------;
;--------------;
.STEP1: LD A,(VARIABLES.CurrentDrive)
LD BC,Dss.DRV.GenIOCTL.GetMoreParams
RST ToDSS.DRV
JR NC,.set_hidden
;
CP BIOS.Error.InvalidSubFunction
JP NZ,STOP_ERROR
; ¥á«¨ ­¥â â ª®© ¯®¤ä㭪樨 ¢ ¤à ©¢¥à¥, ⮠ᬥ饭¨¥ = 0
LD HL,0
LD D,H
LD E,L
;
.set_hidden: LD (FAT_PARAMETERS.HIDDEN),DE
LD (FAT_PARAMETERS.HIDDEN + 2),HL
LD A,(VARIABLES.CurrentDrive)
LD BC,Dss.DRV.GenIOCTL.GetParams
RST ToDSS.DRV
JP C,STOP_ERROR
;!TODO CHECK ERROR ­¥¯®¤å®¤ï騩 ¤¨áª
;
LD (VARIABLES.DriveExtendedParameters),A
EX AF,AF'
AND #F0
LD (FAT_PARAMETERS.BPB_PHISICAL_DRIVE_NUMBER),A
LD (FAT_PARAMETERS.FDD_Number),A
EXX
LD (FAT_PARAMETERS.SectorsPerTrack),BC
LD (FAT_PARAMETERS.HEADS),DE
EXX
; !FIXIT ¢ à¨ ­â ¤«ï ¢¨­â 
LD A,H
OR L
JR NZ,.BPB_BIG_TOTAL_SECTORS
;
LD (FAT_PARAMETERS.SectorsPerDrive),DE
;!TODO ãáâ ­®¢¨âì ä« £, çâ® ¬¥«ª¨© ¤¨áª ­¥ ¤«ï FAT32 ¯à¨ €¢â®¬ â¥
JR .STEP1_2
;
.BPB_BIG_TOTAL_SECTORS:
LD (FAT_PARAMETERS.BPB_BIG_TOTAL_SECTORS_L),DE
LD (FAT_PARAMETERS.BPB_BIG_TOTAL_SECTORS_H),HL
.STEP1_2: ; à §¬¥à ᥪâ®à 
XOR A
SRL B
RRA
LD C,A
LD (FAT_PARAMETERS.BytesPerSector),BC
; à §¬¥à ¤¨áª  ¢ ¡ ©â å EDLHA
CALL MUL32_POWER2
LD (VARIABLES.VOLUME_SIZE_BYTES),DE ; !FIXIT ¡ ©â ¨§ E ­¥ ¨á¯®«ì§ã¥âáï
LD (VARIABLES.VOLUME_SIZE_BYTES + 2),HL
LD (VARIABLES.VOLUME_SIZE_BYTES + 4),A
RET
;--------------;
;--------------;
; €¢â®¬ â¨ç¥áª¨© ¢ë¡®à FAT_TYPE, SectorsPerCluster
.STEP2: CALL AUTO_CHOOSE_FAT_PARAMS
JR C,STOP_ERROR
;
LD A,C
LD (VARIABLES.FAT_TYPE),A
;CP CONSTANTS.FAT32
;LD HL,CONSTANTS.FAT_ReservedSectors.FAT32
;JR Z,.set_reserved_s
;
;!FIXIT ¯à®¢¥àª  FDD/HDD
;LD HL,CONSTANTS.FAT_ReservedSectors.HDD
;
.set_reserved_s:
;LD (FAT_PARAMETERS.RESERVED_SECTORS),HL
LD HL,(FAT_PARAMETERS.BytesPerSector)
DEC HL
SBC HL,DE
LD HL,(FAT_PARAMETERS.BytesPerSector)
EX DE,HL
JR C,.BPS_OK
; ­  á«ãç ©, ¥á«¨ â ¡«¨ç­ë© ª« áâ¥à ¬¥­ìè¥ á¥ªâ®à 
LD A,1
.BPS_OK: CALL C,DIV16_POWER2
JR C,STOP_ERROR
;
LD (FAT_PARAMETERS.SectorsPerCluster),A
RET
;--------------;
;--------------;
; ¤ «ìè¥ ãáâ ­ ¢«¨¢ ¥¬ £¥®¬¥âà¨î. “¦¥ ¤®«¦¥­ ¡ëâì ¢ë¡à ­ ⨯ FAT
;IN:
; FAT_PARAMETERS.BPB_PHISICAL_DRIVE_NUMBER
; FAT_PARAMETERS.SectorsPerDrive
; FAT_PARAMETERS.BPB_BIG_TOTAL_SECTORS_L
; FAT_PARAMETERS.BPB_BIG_TOTAL_SECTORS_H
;OUT:
; VARIABLES.NotUsedSpace
; VARIABLES.total_clusters_L
; VARIABLES.total_clusters_H
; CALC_TOTAL_CLUSTERS.fat_size_l
; CALC_TOTAL_CLUSTERS.fat_size_h
; FAT_PARAMETERS.DRIVE_TYPE
; FAT_PARAMETERS.SectorsPerFAT16
; FAT_PARAMETERS.SectorsPerFAT32
; FAT_PARAMETERS.RESERVED_SECTORS
; FAT_PARAMETERS.FilesInRootDIR
.STEP3: CALL GET_DRIVE_TYPE
JR C,STOP_ERROR
;
LD A,B
LD (FAT_PARAMETERS.DRIVE_TYPE),A
;
CALL SET_RESERVED_AND_ROOTDIR
;
LD HL,(FAT_PARAMETERS.SectorsPerDrive)
LD A,H
OR L
JR NZ,.total_sectors
;
LD HL,(FAT_PARAMETERS.BPB_BIG_TOTAL_SECTORS_H)
LD (CALC_TOTAL_CLUSTERS.t_sec_h),HL
LD HL,(FAT_PARAMETERS.BPB_BIG_TOTAL_SECTORS_L)
.total_sectors: LD (CALC_TOTAL_CLUSTERS.t_sec_l),HL
CALL CALC_TOTAL_CLUSTERS
LD HL,(CALC_TOTAL_CLUSTERS.fat_size_l)
LD A,(VARIABLES.FAT_TYPE)
CP CONSTANTS.FAT32
LD DE,"32"
JR Z,.it_is_fat32
;
LD (FAT_PARAMETERS.SectorsPerFAT16),HL
RET
;
.it_is_fat32: LD (FAT_PARAMETERS.SectorsPerFAT32),HL
LD HL,(CALC_TOTAL_CLUSTERS.fat_size_h)
LD (FAT_PARAMETERS.SectorsPerFAT32 + 2),HL
RET
;--------------;
;-----------------------------------------------------------------------
;-----------------------------------------------------------------------
STOP_ERROR:
.Save_SP+1: LD SP,0
;!TODO
SCF
;
RET
;-----------------------------------------------------------------------
;-----------------------------------------------------------------------
; data_sectors = total_sectors - reserved_sectors - root_dir_sectors - (num_fats * fat_sz)
; IN: DE:HL = total_sectors
; OUT: (VARIABLES.NotUsedSpace)
; (VARIABLES.total_clusters_L)
; (VARIABLES.total_clusters_H)
; (CALC_TOTAL_CLUSTERS.fat_size_l)
; (CALC_TOTAL_CLUSTERS.fat_size_h)
CALC_TOTAL_CLUSTERS:
LD A,(VARIABLES.FAT_TYPE)
SUB CONSTANTS.FAT32
JR Z,.no_root_dir
; calc rootdir sectors
LD HL,(FAT_PARAMETERS.FilesInRootDIR)
XOR A
LD B,5 ; AHL<<5 = AHL*32
CALL AHL_RL_B
; B=0
PUSH HL
POP IX
LD H,B
LD L,A
LD BC,(FAT_PARAMETERS.BytesPerSector)
;HLIX/BC -> HLIX remainder DE
CALL HLIX_div_BC
LD A,D
OR E
JR Z,.no_plus_one
;
LD BC,1
ADD IX,BC
DEC C
ADC HL,BC
.no_plus_one: ; HL:IX - rootdir sectors
LD (VARIABLES.RootDirSectors),IX
LD A,L
LD (VARIABLES.RootDirSectors + 2),A
; ª®à४â¨à㥬 §­ ç¥­¨¥ FilesInRootDIR
LD BC,(FAT_PARAMETERS.BytesPerSector)
LD DE,(VARIABLES.RootDirSectors)
CALL MUL32_POWER2
LD A,L
EX DE,HL
LD B,5 ; AHL>>5 = AHL/32
CALL AHL_RR_B
LD (FAT_PARAMETERS.FilesInRootDIR),HL
.no_root_dir: ;
.t_sec_h+1: LD DE,0
.t_sec_l+1: LD HL,0
; data_sectors
AND A
; total_sectors - reserved_sectors
LD BC,(FAT_PARAMETERS.RESERVED_SECTORS)
SBC HL,BC
JR NC,.skip_dec_DE
;
AND A
DEC DE
.skip_dec_DE: ; DE:HL = total_sectors - reserved_sectors
.push_regs: PUSH DE
PUSH HL
;num_fats * fat_sz32; fat_sz32 ¢ ª« áâ¥à å
.fat_size_l+1: LD BC,0
.fat_size_h+1: LD DE,0
LD A,(FAT_PARAMETERS.Number_of_FATs)
CALL DEBCxA
;
LD B,H
LD C,L
PUSH IX
POP DE
;num_fats * fat_sz32 = BCDE
;
LD HL,(VARIABLES.RootDirSectors)
ADD HL,DE
EX DE,HL
LD HL,(VARIABLES.RootDirSectors + 2)
LD H,0
ADC HL,BC
LD B,H
LD C,L
;num_fats * fat_sz32 + root_dir_sectors = BC:DE
;
POP HL
SBC HL,DE
EX DE,HL
POP HL
SBC HL,BC
JR C,STOP_ERROR
; data_sectors = HL:DE
LD (VARIABLES.DataSectors_L),DE
LD (VARIABLES.DataSectors_H),HL
; total_clusters
LD A,(FAT_PARAMETERS.SectorsPerCluster)
CALL HLDE_Div_A
LD (VARIABLES.NotUsedSpace),A
; total_clusters = HL:DE
;
LD (VARIABLES.total_clusters_L),DE
LD (VARIABLES.total_clusters_H),HL
; fat_size
LD B,D
LD C,E
EX DE,HL
; total_clusters = DE:BC
;
LD A,(VARIABLES.FAT_TYPE)
.call_calc: CALL DEBCxA
;DE:BC * A = HL:IX
;
LD BC,(FAT_PARAMETERS.BytesPerSector)
LD A,(VARIABLES.FAT_TYPE)
CP CONSTANTS.FAT12
JR NZ,.no_sla
;
SLA C
RL B
.no_sla: DEC BC
ADD IX,BC
JR NC,.skip_inc_HL
;
INC HL
.skip_inc_HL: INC BC
CALL HLIX_div_BC
; ®ªà㣫¥­¨¥ ¢¯¥àñ¤
LD A,D
OR E
JR Z,.set_new_size
;
LD BC,1
ADD IX,BC
DEC C
ADC HL,BC
; fat_size = HLIX
.set_new_size: LD DE,(.fat_size_l)
LD BC,(.fat_size_h)
LD (.fat_size_l),IX
LD (.fat_size_h),HL
AND A
SBC HL,BC
JR NZ,.next_loop
;
PUSH IX
POP HL
SBC HL,DE
RET Z
.next_loop: ;
.counter+1: LD A,32 ; loop counter
DEC A
LD (.counter),A
JP NZ,CALC_TOTAL_CLUSTERS
JP STOP_ERROR
;-----------------------------------------------------------------------
;-----------------------------------------------------------------------
SET_RESERVED_AND_ROOTDIR:
LD A,(VARIABLES.FAT_TYPE)
CP CONSTANTS.FAT32
JR Z,.for_fat32
; FAT12_16
; ‘â ¢¨¬ ¤¥ä®«â­ë¥ §­ ç¥­¨ï
LD A,(FAT_PARAMETERS.DRIVE_TYPE)
CP BOOT_SECTOR.Hard_Drive
LD HL,CONSTANTS.FAT_ReservedSectors.HDD
LD DE,CONSTANTS.FilesInRootDIR.HDD
JR Z,.set_vars
; #F0
CP BOOT_SECTOR.Floppy_3x5_1x44
LD HL,CONSTANTS.FAT_ReservedSectors.FDD
LD DE,CONSTANTS.FilesInRootDIR.FDD_HD
JR Z,.set_vars
; #F9
LD A,(VARIABLES.DriveExtendedParameters)
RLA
JR C,.set_vars ; 5.25 / 1200
; 720
LD DE,CONSTANTS.FilesInRootDIR.FDD_DD
.set_vars: CALL .ChooseReserved
EX DE,HL
CALL .ChooseFilesInRootDIR
RET
;
.for_fat32: LD A,(KEYS_PARAMETERS.FilesInRootDIR + KEYS_PARAMETERS.Status)
DEC A
JR NZ,.set_for_fat32
;
LD A,KEYS_PARAMETERS.Status.Ignored
LD (KEYS_PARAMETERS.FilesInRootDIR + KEYS_PARAMETERS.Status),A
.set_for_fat32: LD HL,CONSTANTS.FAT_ReservedSectors.FAT32
LD DE,CONSTANTS.FilesInRootDIR.HDD
JR .set_vars
;
;
.ChooseFilesInRootDIR:
LD A,(KEYS_PARAMETERS.FilesInRootDIR + KEYS_PARAMETERS.Status)
DEC A
JR NZ,.noChangeRootDir
;
LD HL,(KEYS_PARAMETERS.FilesInRootDIR + KEYS_PARAMETERS.Data)
.noChangeRootDir:
LD (FAT_PARAMETERS.FilesInRootDIR),HL
RET
;
;
.ChooseReserved:
LD A,(KEYS_PARAMETERS.RESERVED_SECTORS + KEYS_PARAMETERS.Status)
DEC A
JR NZ,.noChangeReserved
;
LD HL,(KEYS_PARAMETERS.RESERVED_SECTORS + KEYS_PARAMETERS.Data)
.noChangeReserved:
LD (FAT_PARAMETERS.RESERVED_SECTORS),HL
RET
;-----------------------------------------------------------------------
;-----------------------------------------------------------------------
GET_DRIVE_TYPE: LD A,(FAT_PARAMETERS.BPB_PHISICAL_DRIVE_NUMBER)
AND A ; DRIVE_CODES.SPRINTER.FDD
LD B,BOOT_SECTOR.Hard_Drive
RET NZ
; FDD
LD A,(VARIABLES.DriveExtendedParameters)
RLA
LD B,BOOT_SECTOR.Floppy_3x5_720
RET NC
;
AND %0000'1000
LD B,BOOT_SECTOR.Floppy_3x5_1x44
RET Z
;
LD B,BOOT_SECTOR.Floppy_8_1x20
RET
;-----------------------------------------------------------------------
;-----------------------------------------------------------------------
; -> ¤®«¦­® ¡ëâì ãáâ ­®¢«¥­® §­ ç¥­¨¥ VOLUME_SIZE_BYTES.
; <- DE - CLUSTER SIZE.
; C - FAT TYPE.
AUTO_CHOOSE_FAT_PARAMS:
LD DE,(VARIABLES.VOLUME_SIZE_BYTES + 3)
LD IX,TABLES.FAT_TYPES
LD A,TABLES.FAT_TYPES.Records
LD BC,TABLES.FAT_TYPES.LineSize
.loop: LD L,(IX)
LD H,(IX+1)
AND A
SBC HL,DE
JR C,.found
JR Z,.found
;
ADD IX,BC
DEC A
JR NZ,.loop
; ã ­ á FAT12 c ª« áâ¥à®¬ ¢ 512
; ­ ¤® ¯à®¢¥à¨âì à §¤¥« ­  ¬¨­¨¬ «ì­ë© à §¬¥à ¤«ï FAT
; sec_bpb + sec_fat + sec_root_dir + sec_for_data
LD A,D
OR E
JR NZ,.found
;
LD HL,(VARIABLES.VOLUME_SIZE_BYTES + 1)
LD DE,8
SBC HL,DE
RET C ; à §¤¥« ᫨誮¬ ¬ « ¤«ï FAT12 (<2048)
.found: ; ¤®áâ ñ¬ ¯ à ¬¥âàë ¨§ â ¡«¨æë
DI
LD (.restore_SP),SP
LD SP,IX
POP HL ; 宫®á⮥
POP DE ; CLUSTER SIZE
POP BC ; C - FAT TYPE
LD A,C
.restore_SP+1: LD SP,0
EI
AND A
RET
;-----------------------------------------------------------------------
;-----------------------------------------------------------------------
MAKE_SERIAL: LD C,Dss.SysTime
RST ToDSS
;
EX DE,HL
ADD IX,DE
LD (FAT_PARAMETERS.SERIAL_NUMBER_2),IX
;
LD A,D
LD D,B
XOR C
.loop: RRA
DJNZ .loop
;
LD E,H
LD H,L
LD L,E
;
LD E,A
ADD HL,DE
LD (FAT_PARAMETERS.SERIAL_NUMBER_1),HL
RET
;-----------------------------------------------------------------------
;-----------------------------------------------------------------------
FORMAT_DRIVE: CALL CLEAN_SECTOR_BUFFER
;
LD HL,FAT_PARAMETERS.PART1
LD DE,SECTOR_BUFFER
LD BC,FAT_PARAMETERS.PART1_SIZE
LDIR
;
LD A,(VARIABLES.FAT_TYPE)
CP CONSTANTS.FAT32
;!FIXIT
JP NZ,STOP_ERROR
;
CALL MAKE_SYS_SECTORS
CALL CLEAN_SECTOR_BUFFER
; clean all fat tables at drive
LD A,(VARIABLES.FAT_TYPE)
CP CONSTANTS.FAT32
LD BC,(FAT_PARAMETERS.SectorsPerFAT32)
LD DE,(FAT_PARAMETERS.SectorsPerFAT32 + 2)
JR Z,.its_fat32
;
LD BC,(FAT_PARAMETERS.SectorsPerFAT16)
LD DE,0
.its_fat32: LD (.add_l),BC
LD (.add_h),DE
LD A,(FAT_PARAMETERS.Number_of_FATs)
CALL DEBCxA
; HL:IX - ¢á¥£® ᥪâ®à®¢ ¤«ï § ¯¨á¨
PUSH HL
PUSH IX
EXX
POP DE
POP HL
EXX
; HL':DE' - ¢á¥£® ᥪâ®à®¢ ¤«ï § ¯¨á¨
;
LD IX,(FAT_PARAMETERS.RESERVED_SECTORS)
LD HL,0
EXX
.write_loop: PUSH HL
PUSH DE
EXX
PUSH HL
PUSH IX
; HL:IX - ⥪ã騩 ᥪâ®à FAT
CALL WRITE_SECTOR_BUFFER
;
POP IX
POP HL
LD BC,1
ADD IX,BC
DEC C
ADC HL,BC
EXX
LD BC,1
POP HL
SBC HL,BC
POP DE
EX DE,HL
DEC C
SBC HL,BC
JR NZ,.write_loop
;
LD A,D
OR E
JR NZ,.write_loop
EXX
; HL:IX - rootdir's first sector
;
LD (VARIABLES.RootDirFirstSector_L),IX
LD (VARIABLES.RootDirFirstSector_H),HL
;
; make fat table
LD HL,SECTOR_BUFFER
LD A,(FAT_PARAMETERS.DRIVE_TYPE)
LD (HL),A
INC HL
LD (HL),#FF
INC HL
LD (HL),#FF
LD A,(VARIABLES.FAT_TYPE)
CP CONSTANTS.FAT12
JR Z,.write_fat ; fat12
;
INC HL
LD (HL),#FF
JR C,.write_fat ; fat16
;
; LD HL,(FAT_PARAMETERS.DRIVE_TYPE)
; LD H,#FF
; LD (SECTOR_BUFFER),HL
; LD L,H
; LD (SECTOR_BUFFER + 2),HL
; LD A,(VARIABLES.FAT_TYPE)
; CP TABLES.FAT12
; JR C,.write_fat ; fat16
; JR NZ,.fat32
; ; fat12
; XOR A
; LD (SECTOR_BUFFER + 3),A
; JR .write_fat
;
.fat32: ; fat32
LD DE,#0FFF
LD B,7
LD (HL),D
.loop32: INC HL
LD (HL),E
DJNZ .loop32
INC HL
LD (HL),D
; EX DE,HL
; ;LD DE,SECTOR_BUFFER + 3
; LD HL,.Fat32Data
; LD BC,.Fat32Data.Size
; LDIR
;
.write_fat: LD A,(FAT_PARAMETERS.Number_of_FATs)
LD HL,0
LD D,H
LD E,L
PUSH HL
POP IX
LD BC,(FAT_PARAMETERS.RESERVED_SECTORS)
;
.write_tbl_fat: ADD IX,BC
ADC HL,DE
PUSH AF
PUSH HL
PUSH IX
; HL:IX - ⥪ã騩 ᥪâ®à FAT
;
CALL WRITE_SECTOR_BUFFER
;
.add_l+1: LD BC,0
.add_h+1: LD DE,0
POP IX
POP HL
POP AF
DEC A
JR NZ,.write_tbl_fat
RET
;
;.Fat32Data: DB #0F,#FF,#FF,#FF,#FF,#FF,#FF,#FF,#0F
;.Fat32Data.Size EQU $-.Fat32Data
;-----------------------------------------------------------------------
;-----------------------------------------------------------------------
MAKE_SYS_SECTORS:
LD HL,FAT_PARAMETERS.PART2_FAT32
LD BC,FAT_PARAMETERS.PART2_FAT32_SIZE + FAT_PARAMETERS.PART3_SHARED_SIZE
LDIR
;
LD HL,#AA55
LD (SECTOR_BUFFER + BOOT_SECTOR.MBR_SIGNATURE),HL
;
LD HL,0
LD IX,0
CALL WRITE_SECTOR_BUFFER
LD HL,0
LD IX,(FAT_PARAMETERS.CopyBootSector)
CALL WRITE_SECTOR_BUFFER
;
LD A,(VARIABLES.FAT_TYPE)
CP CONSTANTS.FAT32
RET NZ
;
CALL CLEAN_SECTOR_BUFFER
LD HL,#AA55
LD (SECTOR_BUFFER + _sFSinfo.SECTOR_SIGNATURE),HL
;
LD HL,#5252
LD (SECTOR_BUFFER + _sFSinfo.LEAD_SIGNATURE),HL
LD HL,#4161
LD (SECTOR_BUFFER + _sFSinfo.LEAD_SIGNATURE + 2),HL
;
LD HL,#7272
LD (SECTOR_BUFFER + _sFSinfo.DATA_SIGNATURE),HL
LD HL,#6141
LD (SECTOR_BUFFER + _sFSinfo.DATA_SIGNATURE + 2),HL
;
LD HL,(VARIABLES.FAT32_RootDirClusters)
LD DE,(FAT_PARAMETERS.RootDirStartCluster) ; FIXED!
ADD HL,DE
LD DE,(FAT_PARAMETERS.RootDirStartCluster + 2)
JR NC,.no_inc_de
;
INC DE
.no_inc_de: LD (SECTOR_BUFFER + _sFSinfo.FIRST_FREE_CLUSTER),HL
LD (SECTOR_BUFFER + _sFSinfo.FIRST_FREE_CLUSTER + 2),DE
;
LD B,H
LD C,L
LD HL,(VARIABLES.total_clusters_L)
LD IX,(VARIABLES.total_clusters_H)
SBC HL,BC
LD (SECTOR_BUFFER + _sFSinfo.FREE_CLUSTERS_COUNT),HL
PUSH IX
POP HL
SBC HL,DE
LD (SECTOR_BUFFER + _sFSinfo.FREE_CLUSTERS_COUNT + 2),HL
;
LD IX,(FAT_PARAMETERS.FSINFO_Sector)
LD HL,0
CALL WRITE_SECTOR_BUFFER
;
LD HL,#FFFF
LD (SECTOR_BUFFER + _sFSinfo.FIRST_FREE_CLUSTER),HL
LD (SECTOR_BUFFER + _sFSinfo.FIRST_FREE_CLUSTER + 2),HL
LD (SECTOR_BUFFER + _sFSinfo.FREE_CLUSTERS_COUNT),HL
LD (SECTOR_BUFFER + _sFSinfo.FREE_CLUSTERS_COUNT + 2),HL
INC HL
LD IX,(FAT_PARAMETERS.CopyBootSector)
LD DE,(FAT_PARAMETERS.FSINFO_Sector)
ADD IX,DE
PUSH IX
CALL WRITE_SECTOR_BUFFER
;
CALL CLEAN_SECTOR_BUFFER
LD HL,#AA55
LD (SECTOR_BUFFER + _sFSinfo.SECTOR_SIGNATURE),HL
LD HL,0
LD IX,(FAT_PARAMETERS.FSINFO_Sector)
INC IX
CALL WRITE_SECTOR_BUFFER
POP IX
INC IX
LD HL,0
CALL WRITE_SECTOR_BUFFER
RET
;-----------------------------------------------------------------------
;-----------------------------------------------------------------------
CLEAN_SECTOR_BUFFER:
LD HL,SECTOR_BUFFER
LD DE,SECTOR_BUFFER + 1
LD BC,4096 - 1 ; ­  ¡ã¤ã饥, ¤«ï ᥪâ®à®¢ ¡®«ìè¥ 512
LD (HL),0
LDIR
RET
;-----------------------------------------------------------------------
;-----------------------------------------------------------------------
;!FIXIT check error
WRITE_SECTOR_BUFFER:
LD A,(VARIABLES.CurrentDrive)
.sectors+2: LD BC,256*1 + Dss.DRV.Write
LD DE,SECTOR_BUFFER
JP ToDSS.DRV
;-----------------------------------------------------------------------
;-----------------------------------------------------------------------
; IN: HL:IX - rootdir's first sector
MAKE_LABEL_IN_DIR:
CALL CLEAN_SECTOR_BUFFER ;!FIXIT ᪮॥ ¢á¥£®, ­¥ ­ã¦­® ç¨áâ¨âì
; make directory record
LD HL,FAT_PARAMETERS.LABEL
LD DE,SECTOR_BUFFER
LD BC,FAT_PARAMETERS.LABEL.Size
LDIR
;
EX DE,HL
LD (HL),#08
LD HL,#0233
LD (SECTOR_BUFFER+22),HL
LD HL,#5C85
LD (SECTOR_BUFFER+24),HL
; LD HL,.RootLabel
; LD BC,.RootLabel.Size
; LDIR
; write sector
LD HL,(VARIABLES.RootDirFirstSector_H)
LD IX,(VARIABLES.RootDirFirstSector_L)
JR WRITE_SECTOR_BUFFER
;
; root dir entry for label and 0 for "end of catalog" without label
; .RootLabel: ;BYTE 'NO_LABEL '
; BYTE #08,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00
; BYTE #33,#02,#85,#5C,#00,#00,#00,#00,#00,#00,#00
; .RootLabel.Size EQU $-.RootLabel
;-----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
include 'math.asm'
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
include 'data.z80'
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
SECTOR_BUFFER EQU $
.SIZE EQU 4096
ASSERT SECTOR_BUFFER + SECTOR_BUFFER.SIZE < #C000, "ERROR: SECTOR_BUFFER"
////////////////////////////////////////////////////////////////////////