From ee29a4c7b0e09b639eb93a8427aa09cb15025a36 Mon Sep 17 00:00:00 2001 From: Tolik <85737314+Tolik-Trek@users.noreply.github.com> Date: Fri, 3 Apr 2026 22:40:08 +1000 Subject: [PATCH] ... --- format/data.z80 | 129 ++++++ format/format.asm | 927 +----------------------------------------- format/math.asm | 194 +++++++++ format/new_format.asm | 655 +++++++++++++++++++++++++++++ 4 files changed, 982 insertions(+), 923 deletions(-) create mode 100644 format/data.z80 create mode 100644 format/math.asm create mode 100644 format/new_format.asm diff --git a/format/data.z80 b/format/data.z80 new file mode 100644 index 0000000..9b087f1 --- /dev/null +++ b/format/data.z80 @@ -0,0 +1,129 @@ +;███████████████████████████████████████████████████████████████████████ +;████████████████████████████████ DATA █████████████████████████████████ +;███████████████████████████████████████████████████████████████████████ + +;----------------------------------------------------------------------- + MACRO FAT_TYPES_LINE vol_size, clu_size, fat_type + WORD vol_size, clu_size + BYTE fat_type + ENDM + + MODULE TABLES +FAT12 EQU 3 +FAT16 EQU 2 +FAT32 EQU 4 +; VOL SIZE CLUSTER SIZE FAT TYPE +FAT_TYPES: FAT_TYPES_LINE #0800, 32768, FAT32 ; > 32768 + FAT_TYPES_LINE #0400, 16384, FAT32 ; 16384..32768 Mb + FAT_TYPES_LINE #0200, 8192, FAT32 ; 8192..16384 Mb + FAT_TYPES_LINE #0100, 4096, FAT32 ; 4096..8192 Mb + FAT_TYPES_LINE #0080, 32768, FAT16 ; 2048..4096 Mb + FAT_TYPES_LINE #0040, 16384, FAT16 ; 1023..2048 Mb + FAT_TYPES_LINE #0020, 8192, FAT16 ; 511..1023 Mb + FAT_TYPES_LINE #0010, 4096, FAT16 ; 256..511 Mb + FAT_TYPES_LINE #0008, 2048, FAT16 ; 128..256 Mb + FAT_TYPES_LINE #0004, 1024, FAT16 ; 64..128 Mb + FAT_TYPES_LINE #0002, 512, FAT16 ; 32..64 Mb + ; если меньше, то FAT12 +.LineSize EQU 5 +.Records EQU ($ - FAT_TYPES)/.LineSize + ENDMODULE +;----------------------------------------------------------------------- + + +;----------------------------------------------------------------------- +VARIABLES EQU $ +.FAT_TYPE BYTE TABLES.FAT12 ; [x] +.CurrentDrive DB 0 +.VOLUME_SIZE_BYTES BLOCK 5,0 +.FatFDD_ReservedSectors WORD 1 +.FatHDD_ReservedSectors WORD 8 +.Fat32_ReservedSectors WORD 32 +.RootDirSectors WORD 0 +.NotUsedSpace BYTE 0 ; in sectors +.total_clusters_L: WORD 0 +.total_clusters_H: WORD 0 +.FAT32_RootDirClusters WORD 1 +.FAT.LABEL BYTE 'NO_LABEL ' +.DriveExtendedParameters BYTE 0 +;----------------------------------------------------------------------- + + +;----------------------------------------------------------------------- +; Ключ выставлен : Дефолтное значение +KEYS_PARAMETERS EQU $ +.ONLY_HELP BYTE 0 : BYTE 0 ; [ ] /? ; вывод справки +.FAT_TYPE BYTE 0 : BYTE TABLES.FAT12 ; [ ] /t ; +.BytesPerSector BYTE 0 : WORD #200 ; [ ] /s ; +.SectorsPerCluster: BYTE 0 : BYTE 0 ; [ ] /c ; +.Number_of_FATs: BYTE 0 : BYTE 2 ; [ ] /n ; +.FilesInRootDIR: BYTE 0 : WORD 0 ; [ ] /d ; +.RESERVED_SECTORS: BYTE 0 : WORD 0 ; [ ] /r ; +.LOW_FORMAT BYTE 0 : BYTE 0 ; [ ] /l ; для дискет +;----------------------------------------------------------------------- + + +;----------------------------------------------------------------------- +; root_dir_sectors = ((root_dir_entries * 32) + (bytes_per_sector - 1)) / bytes_per_sector +FAT_PARAMETERS: +.PART1 EQU $ +; +.JMP: BYTE #EB,#FE,#00 ; [x] opcode jmp $ +.ID_NAME BYTE "DDF " ; DSS Drive Formatter +.ID_NAME_VER BYTE "0." +.ID_NAME_MOD BYTE "00" +.BytesPerSector: WORD #200 ; predefined ; [x] +.SectorsPerCluster: BYTE 0 ; [x] +.RESERVED_SECTORS: WORD 0 ; [x] +.Number_of_FATs: BYTE 2 ; predefined ; [x] +.FilesInRootDIR: WORD 0 ; FAT32 constant ; [ ] FAT ; [x] FAT32 +.SectorsPerDrive: WORD 0 ; FAT32 constant ; [x] +- +.DRIVE_TYPE: BYTE 0 ; ; [x] +- +.SectorsPerFAT16: WORD 0 ; FAT32 constant ; [x] +.SectorsPerTrack WORD 9 ; BPB_SecPerTrk ; [x] +.HEADS WORD 2 ; [x] +.HIDDEN DWORD 0 ; от начала MBR, extMBR ; [x] +.BPB_BIG_TOTAL_SECTORS_L WORD 0 ; [x] +- +.BPB_BIG_TOTAL_SECTORS_H WORD 0 ; [x] +- +.PART1_SIZE EQU $ - .PART1 +; FAT 12, FAT 16 +.PART2_FAT12_16 EQU $ +; +.BPB_PHISICAL_DRIVE_NUMBER BYTE #80 ; [x] +.reserved_1 BYTE 0 ; predefined ; +; .FAT.EXT_BOOT_REC_SIGNATURE BYTE #29 ; constant ; +; .FAT.SERIAL_NUMBER DWORD 0 ; +; .FAT.LABEL DB 'NO_LABEL ' ; +; .ID_FAT DB 'FAT16 ' ; +.PART2_FAT12_16_END EQU $ + +; FAT32 +.PART2_FAT32 EQU $ +; +.SectorsPerFAT32 DWORD 0 ; [x] ;!TODO error если старший байт !=0 +.MainFATnumber WORD 0 ; BPB_ExtFlags ; +.Version WORD 0 ; constant ; +.RootDirStartCluster DWORD 2 ; FIXED! используется в формуле +.FSINFO_Sector WORD 1 ; constant ; +.CopyBootSector WORD 6 ; constant ; +.reserved_block: BLOCK 12 ; constant ; +.FDD_Number BYTE 0 ; [x] +.reserved_2: BYTE 0 ; constant ; +; .FAT32.EXT_BOOT_REC_SIGNATURE BYTE #29 ; constant ; +; .FAT32.SERIAL_NUMBER DWORD 0 ; +; .FAT32.LABEL DB 'NO_LABEL ' ; +; .ID_FAT32 DB 'FAT32 ' ; +.PART2_FAT32_SIZE EQU $ - .PART2_FAT32 +; SHARED +.PART3_SHARED EQU $ +; +.FAT.EXT_BOOT_REC_SIGNATURE BYTE #29 ; constant ; +.FAT.SERIAL_NUMBER DWORD 0 ; [ ] +.FAT.LABEL DB 'NO_LABEL ' ; [ ] ;!TODO дополнительно писать в корневую директорию +.ID_FAT DB 'FAT32 ' ; +.PART3_SHARED_SIZE EQU $ - .PART3_SHARED +;----------------------------------------------------------------------- + + +;----------------------------------------------------------------------- +;----------------------------------------------------------------------- \ No newline at end of file diff --git a/format/format.asm b/format/format.asm index f72bcae..62e93cb 100755 --- a/format/format.asm +++ b/format/format.asm @@ -801,931 +801,12 @@ buff EQU ( high $ + ((low $)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 -;;;;;;;;;;;;;;;;; -*/ - -;!TODO: -; Dss.DRV.Open -; Dss.DRV.Close - - -; DSS Drive Formatter -FAT32_FORMAT: +//////////////////////////////////////////////////////////////////////// + include 'new_format.asm' //////////////////////////////////////////////////////////////////////// -MAKE_AUTO: LD (STOP_ERROR.Save_SP),SP - ;!FIXIT - LD A,(FMTDISK) - LD (VARIABLES.CurrentDrive),A - ; - CALL CALCULATE_FAT - CALL FORMAT_DRIVE - ;!FIXIT - ;CALL MAKE_ROOT_DIR_LABEL ; первая запись в root dir - метка, потом нули - RET - -;----------------------------------------------------------------------- -CALCULATE_FAT: ;LD (STOP_ERROR.Save_SP),SP - ; Определение параметров носителя и выбор FAT -.STEP1: ; эта должна быть общей для заполнения геометрии диска - - LD A,(VARIABLES.CurrentDrive) - LD BC,Dss.DRV.GenIOCTL.GetMoreParams - RST ToDSS.DRV - JR NC,.set_hidden - ; - CP BIOS.Error.InvalidSubFunction - JR Z,.GetParams ; если нет такой подфункции в драйвере, то смещение = 0 - SCF - JP STOP_ERROR - ; -.set_hidden: LD (CALCULATED_FAT_PARAMETERS.HIDDEN),DE - LD (CALCULATED_FAT_PARAMETERS.HIDDEN + 2),HL -.GetParams: LD A,(VARIABLES.CurrentDrive) - LD BC,Dss.DRV.GenIOCTL.GetParams - RST ToDSS.DRV - JP C,STOP_ERROR - ;!TODO CHECK ERROR неподходящий диск - ; - EX AF,AF' - AND #F0 - LD (CALCULATED_FAT_PARAMETERS.BPB_PHISICAL_DRIVE_NUMBER),A - LD (CALCULATED_FAT_PARAMETERS.FDD_Number),A - ; !FIXIT вариант для винта - LD A,H - OR L - JR NZ,.BPB_BIG_TOTAL_SECTORS - ; - LD (CALCULATED_FAT_PARAMETERS.SectorsPerDrive),DE - ;!TODO установить флаг, что мелкий диск не для FAT32 при Автомате - JR .STEP1_2 - ; -.BPB_BIG_TOTAL_SECTORS: - LD (CALCULATED_FAT_PARAMETERS.BPB_BIG_TOTAL_SECTORS_L),DE - LD (CALCULATED_FAT_PARAMETERS.BPB_BIG_TOTAL_SECTORS_H),HL -.STEP1_2: ; размер сектора - XOR A - SRL B - RRA - LD C,A - LD (CALCULATED_FAT_PARAMETERS.BytesPerSector),BC - ; размер диска в байтах - CALL MUL32_POWER2 - LD (VARIABLES.VOLUME_SIZE_BYTES),DE - LD (VARIABLES.VOLUME_SIZE_BYTES + 2),HL - LD (VARIABLES.VOLUME_SIZE_BYTES + 4),A - LD E,H - LD D,A - CALL AUTO_CHOOSE_FAT_PARAMS - JR C,STOP_ERROR - ; - LD A,C - LD (CALCULATED_FAT_PARAMETERS.FAT_TYPE),A - CP TABLES.FAT32 - LD HL,RESERVED_SECTORS.FAT32 - JR Z,.set_reserved_s - ; - ;!FIXIT проверка FDD/HDD - LD HL,RESERVED_SECTORS.FAT_HDD - ; -.set_reserved_s: - LD (CALCULATED_FAT_PARAMETERS.RESERVED_SECTORS),HL - LD HL,(CALCULATED_FAT_PARAMETERS.BytesPerSector) - DEC HL - SBC HL,DE - LD HL,(CALCULATED_FAT_PARAMETERS.BytesPerSector) - EX DE,HL - JR C,.BPS_OK - ; на случай, если табличный кластер меньше сектора - LD A,1 -.BPS_OK: CALL C,DIV16_POWER2 - JR C,STOP_ERROR - ; - LD (CALCULATED_FAT_PARAMETERS.SectorsPerCluster),A - ; - CALL GET_DRIVE_TYPE - JR C,STOP_ERROR - ; - LD A,B - LD (CALCULATED_FAT_PARAMETERS.DRIVE_TYPE),A - LD HL,(CALCULATED_FAT_PARAMETERS.SectorsPerDrive) - LD A,H - OR L - JR NZ,.total_sectors - ; - LD HL,(CALCULATED_FAT_PARAMETERS.BPB_BIG_TOTAL_SECTORS_H) - LD (CALC_TOTAL_CLUSTERS.t_sec_h),HL - LD HL,(CALCULATED_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,(CALCULATED_FAT_PARAMETERS.FilesInRootDIR) - AND A - JR Z,.it_is_fat32 - ; - LD (CALCULATED_FAT_PARAMETERS.SectorsPerFAT16),HL - RET - ; -.it_is_fat32: LD (CALCULATED_FAT_PARAMETERS.SectorsPerFAT32),HL - LD HL,(CALC_TOTAL_CLUSTERS.fat_size_h) - LD (CALCULATED_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 -CALC_TOTAL_CLUSTERS: -.t_sec_h+1: LD DE,0 -.t_sec_l+1: LD HL,0 - ; data_sectors - AND A - ; total_sectors - reserved_sectors - LD BC,(CALCULATED_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 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,(CALCULATED_FAT_PARAMETERS.Number_of_FATs) - CALL DEBCxA - ; - LD B,H - LD C,L - PUSH IX - POP DE - ;num_fats * fat_sz32 = BCDE - ; - LD HL,(CALCULATED_FAT_PARAMETERS.RootDirSectors) ; !FIXIT написать процедуру вычисления RootDirSectors до вызова этой - ADD HL,DE - JR NC,.skip_inc - ; - AND A - INC BC -.skip_inc: EX DE,HL - ;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 - ; - ; total_clusters - LD A,(CALCULATED_FAT_PARAMETERS.SectorsPerCluster) - CALL HLDE_Div_A - LD (CALCULATED_FAT_PARAMETERS.NotUsedSpace),A - ; total_clusters = HL:DE - ; - LD (CALCULATED_FAT_PARAMETERS.total_clusters),DE - LD (CALCULATED_FAT_PARAMETERS.total_clusters + 2),HL - ; fat_size - LD B,D - LD C,E - EX DE,HL - ; total_clusters = DE:BC - ; - LD A,(CALCULATED_FAT_PARAMETERS.FAT_TYPE) -.call_calc: CALL DEBCxA - ;DE:BC * A = HL:IX - ; - LD BC,(CALCULATED_FAT_PARAMETERS.BytesPerSector) - LD A,(CALCULATED_FAT_PARAMETERS.FAT_TYPE) - CP TABLES.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 -;----------------------------------------------------------------------- - - -;----------------------------------------------------------------------; - IFUSED DIV_by_Shifts -; HL:DE / A => DE:BC, H=0, L - остаток -DIV_by_Shifts: LD C,A - DEC A - JR Z,.exit - ; - AND E - LD B,A ; остаток - LD A,C - RRCA -.loop: SRL H - RR L - RR D - RR E - RRCA - JP NC,.loop - ; - LD A,B -.exit: LD B,D - LD C,E - EX DE,HL - LD H,0 - LD L,A - RET - ENDIF -;----------------------------------------------------------------------; - - -;----------------------------------------------------------------------- -; IN: -; DEBC, A -; OUT: -; HLIX = DEBC*A -DEBCxA: LD HL,0 - LD IX,0 - AND A - RET Z - ; -.loop: ADD IX,BC - ADC HL,DE - JP C,STOP_ERROR ; дохера - ; - DEC A - JR NZ,.loop - RET -;----------------------------------------------------------------------- - - -/* -total_sectors DWORD 0x10000000 -reserved_sectors WORD -data_sectors DWORD -total_clusters 3 bytes 0x400000 - -total_clusters * 4 4 bytes -fat_sz32 max 3 bytes Размер таблицы в секторах - -data_sectors = total_sectors - reserved_sectors - (num_fats * fat_sz32) -total_clusters = data_sectors / sectors_per_cluster -fat_sz32 = (total_clusters * 4 + (bytes_per_sector - 1)) / bytes_per_sector -*/ - - -;----------------------------------------------------------------------- -;HLIX/BC -> HLIX remainder DE -HLIX_div_BC: EX DE,HL - ; Negate BC to allow add instead of sbc - XOR A - ; Need to set HL to 0 anyways, so save 2cc and a byte - LD H,A - LD L,A - SUB C - LD C,A - SBC A,A - SUB B - LD B,A - LD A,D - CALL .sub8 - RLA - LD D,A - LD A,E - CALL .sub8 - RLA - LD E,A - LD A,XH - CALL .sub8 - RLA - LD XH,A - LD A,XL - CALL .sub8 - RLA - LD XL,A - EX DE,HL - RET - ; -.sub8: CALL .iter1 -.iter1: CALL .iter2 -.iter2: CALL .sub -.sub: RLA - ADC HL,HL - JR C,.skip - ; - ADD HL,BC - RET C - ; - SBC HL,BC - RET - ; -.skip: ADD HL,BC - SCF - RET -;----------------------------------------------------------------------- - - -;----------------------------------------------------------------------- -FORMAT_DRIVE: CALL CLEAN_SECTOR_BUFFER - ; - LD HL,CALCULATED_FAT_PARAMETERS.PART1 - LD DE,SECTOR_BUFFER - LD BC,CALCULATED_FAT_PARAMETERS.PART1_SIZE - LDIR - ; - LD A,(CALCULATED_FAT_PARAMETERS.FAT_TYPE) - CP TABLES.FAT32 - ;!FIXIT - JP NZ,STOP_ERROR - ; - CALL MAKE_SYS_SECTORS - CALL CLEAN_SECTOR_BUFFER - ; clean all fat tables at drive - LD A,(CALCULATED_FAT_PARAMETERS.FAT_TYPE) - CP TABLES.FAT32 - LD BC,(CALCULATED_FAT_PARAMETERS.SectorsPerFAT32) - LD DE,(CALCULATED_FAT_PARAMETERS.SectorsPerFAT32 + 2) - JR Z,.its_fat32 - ; - LD BC,(CALCULATED_FAT_PARAMETERS.SectorsPerFAT16) - LD DE,0 -.its_fat32: LD (.add_l),BC - LD (.add_h),DE - LD A,(CALCULATED_FAT_PARAMETERS.Number_of_FATs) - CALL DEBCxA - ; HL:IX - всего секторов для записи - PUSH HL - PUSH IX - EXX - POP DE - POP HL - EXX - ; HL':DE' - всего секторов для записи - ; - LD IX,(CALCULATED_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 - ; make fat table - LD HL,(CALCULATED_FAT_PARAMETERS.DRIVE_TYPE) - LD H,#FF - LD (SECTOR_BUFFER),HL - LD L,H - LD (SECTOR_BUFFER + 2),HL - LD A,(CALCULATED_FAT_PARAMETERS.FAT_TYPE) - CP TABLES.FAT12 - JR NZ,.not_fat12 - ; fat12 - XOR A - LD (SECTOR_BUFFER + 3),A - JR .write_fat - ; -.not_fat12 CP TABLES.FAT16 - JR Z,.write_fat - ;fat32 - ; - LD HL,.Fat32Data - LD DE,SECTOR_BUFFER + 3 - LD BC,.Fat32Data.Size - LDIR - ; -.write_fat: LD A,(CALCULATED_FAT_PARAMETERS.Number_of_FATs) - LD HL,0 - LD D,H - LD E,L - PUSH HL - POP IX - LD BC,(CALCULATED_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,CALCULATED_FAT_PARAMETERS.PART2_FAT32 - LD BC,CALCULATED_FAT_PARAMETERS.PART2_FAT32_SIZE + CALCULATED_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,(CALCULATED_FAT_PARAMETERS.CopyBootSector) - CALL WRITE_SECTOR_BUFFER - ; - LD A,(CALCULATED_FAT_PARAMETERS.FAT_TYPE) - CP TABLES.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,(CALCULATED_FAT_PARAMETERS.FAT32_RootDirClusters) - LD DE,(CALCULATED_FAT_PARAMETERS.RootDirStartCluster) ; FIXED! - ADD HL,DE - LD DE,(CALCULATED_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,(CALCULATED_FAT_PARAMETERS.total_clusters) - LD IX,(CALCULATED_FAT_PARAMETERS.total_clusters + 2) - 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,(CALCULATED_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,(CALCULATED_FAT_PARAMETERS.CopyBootSector) - LD DE,(CALCULATED_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,(CALCULATED_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 -;----------------------------------------------------------------------- - - - - //////////////////////////////////////////////////////////////////////// - - -;----------------------------------------------------------------------- -;!TODO доделать для дискет -GET_DRIVE_TYPE: LD A,(CALCULATED_FAT_PARAMETERS.BPB_PHISICAL_DRIVE_NUMBER) - CP DRIVE_CODES.SPRINTER.ATA - LD B,BOOT_SECTOR.Hard_Drive - RET Z - ; дискеты и когда-нибудь ATAPI - SCF - RET -;----------------------------------------------------------------------- - - -;----------------------------------------------------------------------- -; -> DE - 4 и 5 байты размера раздела. -; должно быть установлено значение VOLUME_SIZE_BYTES. -; <- DE - CLUSTER SIZE. -; C - FAT TYPE. -AUTO_CHOOSE_FAT_PARAMS: - 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) - 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 -;----------------------------------------------------------------------- - - -;----------------------------------------------------------------------- -; -> HLDE * BC. BC = степень двойки -; <- AHLDE -; CF=1 - error -MUL32_POWER2: SRL B - RR C - LD A,B - OR C - RET Z - ; - XOR A -.loop: EX DE,HL - ADD HL,HL - EX DE,HL - ADC HL,HL - ADC A,0 - RET C - ; - SRL B - RR C - JR NC,.loop - ; - ;EX DE,HL - AND A - RET -;----------------------------------------------------------------------- - - -;----------------------------------------------------------------------- -; -> HL / DE. DE = степень двойки -; <- A = HL / DE -; CF=1 - error -DIV16_POWER2: XOR A -.loop: INC A - SBC HL,DE - JR NC,.loop - DEC A - RET Z ; error: делимое < делителя - CCF - RET -;----------------------------------------------------------------------- - - - -;----------------------------------------------------------------------- - MACRO DIV_RL - RL H - RLA - ADD A,C - JR C,.exit - SUB C -.exit: - ENDM -; -;Input: HLDE is numerator, A<129 is the divisor. -;Output: HLDE is quotient, A is remainder, C is negated -HLDE_Div_A: NEG - LD C,A - XOR A - CALL .div - LD B,H - LD H,L - CALL .div - LD L,H - LD H,D - CALL .div - LD D,H - LD H,E - CALL .div - LD E,H - LD H,B - RL E - RL D - ADC HL,HL - RET - ; -.div: DIV_RL - DIV_RL - DIV_RL - DIV_RL - DIV_RL - DIV_RL - DIV_RL - RL H - RLA - ADD A,C - RET C - SUB C - RET -;----------------------------------------------------------------------- - - - - - MACRO FAT_TYPES_LINE vol_size, clu_size, fat_type - WORD vol_size, clu_size - BYTE fat_type - ENDM - - MODULE TABLES -FAT12 EQU 3 -FAT16 EQU 2 -FAT32 EQU 4 -; VOL SIZE CLUSTER SIZE FAT TYPE -FAT_TYPES: FAT_TYPES_LINE #0800, 32768, FAT32 ; > 32768 - FAT_TYPES_LINE #0400, 16384, FAT32 ; 16384..32768 Mb - FAT_TYPES_LINE #0200, 8192, FAT32 ; 8192..16384 Mb - FAT_TYPES_LINE #0100, 4096, FAT32 ; 4096..8192 Mb - FAT_TYPES_LINE #0080, 32768, FAT16 ; 2048..4096 Mb - FAT_TYPES_LINE #0040, 16384, FAT16 ; 1023..2048 Mb - FAT_TYPES_LINE #0020, 8192, FAT16 ; 511..1023 Mb - FAT_TYPES_LINE #0010, 4096, FAT16 ; 256..511 Mb - FAT_TYPES_LINE #0008, 2048, FAT16 ; 128..256 Mb - FAT_TYPES_LINE #0004, 1024, FAT16 ; 64..128 Mb - FAT_TYPES_LINE #0002, 512, FAT16 ; 32..64 Mb - ; если меньше, то FAT12 -.LineSize EQU 5 -.Records EQU ($ - FAT_TYPES)/.LineSize - ENDMODULE -; - - -; -RESERVED_SECTORS: ;predefined (пока) -.FAT_FDD EQU 1 -.FAT_HDD EQU 8 -.FAT32 EQU #2032 ;32 -; - - -; -VARIABLES EQU $ -.CurrentDrive DB 0 -.VOLUME_SIZE_BYTES BLOCK 5,0 -; - -; root_dir_sectors = ((root_dir_entries * 32) + (bytes_per_sector - 1)) / bytes_per_sector -CALCULATED_FAT_PARAMETERS: -.FAT_TYPE BYTE TABLES.FAT12 ; [x] -.RootDirSectors WORD 0 -.NotUsedSpace BYTE 0 ; in sectors -.total_clusters: DWORD 0 -.FAT32_RootDirClusters WORD 1 -.PART1 EQU $ -; -.JMP: BYTE #EB,#FE,#00 ; [x] opcode jmp $ -.ID_NAME BYTE "DDF " ; DSS Drive Formatter -.ID_NAME_VER BYTE "0." -.ID_NAME_MOD BYTE "00" -.BytesPerSector: WORD #200 ; predefined ; [x] -.SectorsPerCluster: BYTE 0 ; [x] -.RESERVED_SECTORS: WORD 0 ; [x] -.Number_of_FATs: BYTE 2 ; predefined ; [ ] -.FilesInRootDIR: WORD 0 ; FAT32 constant ; [ ] FAT ; [x] FAT32 -.SectorsPerDrive: WORD 0 ; FAT32 constant ; [x] +- -.DRIVE_TYPE: BYTE 0 ; ; [x] +- -.SectorsPerFAT16: WORD 0 ; FAT32 constant ; [x] -.SectorsPerTrack WORD 9 ; BPB_SecPerTrk ; [ ] Размер дорожки в секторах -.HEADS WORD 2 ; [ ] -.HIDDEN DWORD 0 ; от начала MBR, extMBR ; [x] -.BPB_BIG_TOTAL_SECTORS_L WORD 0 ; [x] +- -.BPB_BIG_TOTAL_SECTORS_H WORD 0 ; [x] +- -.PART1_SIZE EQU $ - .PART1 -; FAT 12, FAT 16 -.PART2_FAT12_16 EQU $ -; -.BPB_PHISICAL_DRIVE_NUMBER BYTE #80 ; [x] -.reserved_1 BYTE 0 ; predefined ; -; .FAT.EXT_BOOT_REC_SIGNATURE BYTE #29 ; constant ; -; .FAT.SERIAL_NUMBER DWORD 0 ; -; .FAT.LABEL DB 'NO_LABEL ' ; -; .ID_FAT DB 'FAT16 ' ; -.PART2_FAT12_16_END EQU $ - -; FAT32 -.PART2_FAT32 EQU $ -; -.SectorsPerFAT32 DWORD 0 ; [x] ;!TODO error если старший байт !=0 -.MainFATnumber WORD 0 ; BPB_ExtFlags ; -.Version WORD 0 ; constant ; -.RootDirStartCluster DWORD 2 ; FIXED! используется в формуле -.FSINFO_Sector WORD 1 ; constant ; -.CopyBootSector WORD 6 ; constant ; -.reserved_block: BLOCK 12 ; constant ; -.FDD_Number BYTE 0 ; [x] -.reserved_2: BYTE 0 ; constant ; -; .FAT32.EXT_BOOT_REC_SIGNATURE BYTE #29 ; constant ; -; .FAT32.SERIAL_NUMBER DWORD 0 ; -; .FAT32.LABEL DB 'NO_LABEL ' ; -; .ID_FAT32 DB 'FAT32 ' ; -.PART2_FAT32_SIZE EQU $ - .PART2_FAT32 -; SHARED -.PART3_SHARED EQU $ -; -.FAT.EXT_BOOT_REC_SIGNATURE BYTE #29 ; constant ; -.FAT.SERIAL_NUMBER DWORD 0 ; [ ] -.FAT.LABEL DB 'NO_LABEL ' ; [ ] ;!TODO дополнительно писать в корневую директорию -.ID_FAT DB 'FAT32 ' ; -.PART3_SHARED_SIZE EQU $ - .PART3_SHARED -; - - -; -SECTOR_BUFFER EQU $ -; - - - ENDIF - - - - - DISPLAY "programm size: ",$-EXEHeader Loader_End: - DISPLAY "last address: ",$ \ No newline at end of file + DISPLAY "last address: ",$ +//////////////////////////////////////////////////////////////////////// diff --git a/format/math.asm b/format/math.asm new file mode 100644 index 0000000..4aed939 --- /dev/null +++ b/format/math.asm @@ -0,0 +1,194 @@ +;███████████████████████████████████████████████████████████████████████ +;████████████████████████████████ MATH █████████████████████████████████ +;███████████████████████████████████████████████████████████████████████ + + +;----------------------------------------------------------------------; + IFUSED DIV_by_Shifts +; HL:DE / A => DE:BC, H=0, L - остаток +DIV_by_Shifts: LD C,A + DEC A + JR Z,.exit + ; + AND E + LD B,A ; остаток + LD A,C + RRCA +.loop: SRL H + RR L + RR D + RR E + RRCA + JP NC,.loop + ; + LD A,B +.exit: LD B,D + LD C,E + EX DE,HL + LD H,0 + LD L,A + RET + ENDIF +;----------------------------------------------------------------------; + + +;----------------------------------------------------------------------- +; IN: +; DEBC, A +; OUT: +; HLIX = DEBC*A +DEBCxA: LD HL,0 + LD IX,0 + AND A + RET Z + ; +.loop: ADD IX,BC + ADC HL,DE + JP C,STOP_ERROR ; дохера + ; + DEC A + JR NZ,.loop + RET +;----------------------------------------------------------------------- + + +;----------------------------------------------------------------------- +;HLIX/BC -> HLIX remainder DE +HLIX_div_BC: EX DE,HL + ; Negate BC to allow add instead of sbc + XOR A + ; Need to set HL to 0 anyways, so save 2cc and a byte + LD H,A + LD L,A + SUB C + LD C,A + SBC A,A + SUB B + LD B,A + LD A,D + CALL .sub8 + RLA + LD D,A + LD A,E + CALL .sub8 + RLA + LD E,A + LD A,XH + CALL .sub8 + RLA + LD XH,A + LD A,XL + CALL .sub8 + RLA + LD XL,A + EX DE,HL + RET + ; +.sub8: CALL .iter1 +.iter1: CALL .iter2 +.iter2: CALL .sub +.sub: RLA + ADC HL,HL + JR C,.skip + ; + ADD HL,BC + RET C + ; + SBC HL,BC + RET + ; +.skip: ADD HL,BC + SCF + RET +;----------------------------------------------------------------------- + + +;----------------------------------------------------------------------- +; -> HLDE * BC. BC = степень двойки +; <- AHLDE +; CF=1 - error +MUL32_POWER2: SRL B + RR C + LD A,B + OR C + RET Z + ; + XOR A +.loop: EX DE,HL + ADD HL,HL + EX DE,HL + ADC HL,HL + ADC A,0 + JP C,STOP_ERROR + ; + SRL B + RR C + JR NC,.loop + ; + ;EX DE,HL + AND A + RET +;----------------------------------------------------------------------- + + +;----------------------------------------------------------------------- +; -> HL / DE. DE = степень двойки +; <- A = HL / DE +; CF=1 - error +DIV16_POWER2: XOR A +.loop: INC A + SBC HL,DE + JR NC,.loop + DEC A + RET Z ; error: делимое < делителя + CCF + RET +;----------------------------------------------------------------------- + + +;----------------------------------------------------------------------- + MACRO DIV_RL + RL H + RLA + ADD A,C + JR C,.exit + SUB C +.exit: + ENDM +; +;Input: HLDE is numerator, A<129 is the divisor. +;Output: HLDE is quotient, A is remainder, C is negated +HLDE_Div_A: NEG + LD C,A + XOR A + CALL .div + LD B,H + LD H,L + CALL .div + LD L,H + LD H,D + CALL .div + LD D,H + LD H,E + CALL .div + LD E,H + LD H,B + RL E + RL D + ADC HL,HL + RET + ; +.div: DIV_RL + DIV_RL + DIV_RL + DIV_RL + DIV_RL + DIV_RL + DIV_RL + RL H + RLA + ADD A,C + RET C + SUB C + RET +;----------------------------------------------------------------------- \ No newline at end of file diff --git a/format/new_format.asm b/format/new_format.asm new file mode 100644 index 0000000..5afe282 --- /dev/null +++ b/format/new_format.asm @@ -0,0 +1,655 @@ +;!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 Размер сектора в байтах +.SectorsPerCluster ;!TODO EQU #0D ; BYTE 2 BPB_SecPerClus Размер кластера в секторах +.RESERVED_SECTORS !RESERVED_SECTORS EQU #0E ; WORD 1 BPB_ResvdSecCnt Размер системной области (включая этот сектор) 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 Размер одной FAT в секторах (0 в FAT32) +.SectorsPerTrack GenIOCTL.GetParams EQU #18 ; WORD 9 BPB_SecPerTrk Размер дорожки в секторах +.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 Размер одной FAT в секторах +.MainFATnumber 0 EQU #28 ; WORD 0 BPB_ExtFlags Номер главной таблицы FAT +.Version 0 EQU #2A ; WORD 0 BPB_FSVer Версия FAT32 (обычно 0) +.RootDirStartCluster 2 EQU #2C ; DWORD 2 BPB_RootClus Первый кластер корневого каталога (обычно 2) +.FSINFO_Sector 1 EQU #30 ; WORD 1 BPB_FSInfo Номер сектора структуры FSINFO (обычно 1) +.CopyBootSector 6 EQU #32 ; WORD 6 BPB_BkBootSec Номер сектора - копии загрузочного (обычно 6) +.reserved_block: 0 EQU #34 ; BLOCK 12 BPB_Reserved Зарезервировано +.FDD_Number GenIOCTL.GetParams&#F0 EQU #40 ; BYTE 0 BS_DrvNum Номер дисковода для функций 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 +FAT32_FORMAT: +//////////////////////////////////////////////////////////////////////// + +MAKE_AUTO: LD (STOP_ERROR.Save_SP),SP + ;!FIXIT + LD A,(FMTDISK) + LD (VARIABLES.CurrentDrive),A + ; + CALL CALCULATE_FAT + CALL FORMAT_DRIVE + ;!FIXIT + ;CALL MAKE_ROOT_DIR_LABEL ; первая запись в root dir - метка, потом нули + RET + +;----------------------------------------------------------------------- +; Определение параметров носителя и выбор FAT +CALCULATE_FAT: CALL .STEP1 ; эта должна быть общей для заполнения геометрии диска + ; Автоматический выбор FAT_TYPE, RESERVED_SECTORS, SectorsPerCluster + CALL .STEP2 + ; дальше устанавливаем геометрию. Уже должен быть выбран тип FAT + CALL .STEP3 + 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 + LD (VARIABLES.VOLUME_SIZE_BYTES + 2),HL + LD (VARIABLES.VOLUME_SIZE_BYTES + 4),A + RET +;--------------; + + +;--------------; +; Автоматический выбор FAT_TYPE, RESERVED_SECTORS, SectorsPerCluster +.STEP2: CALL AUTO_CHOOSE_FAT_PARAMS + JR C,STOP_ERROR + ; + LD A,C + LD (VARIABLES.FAT_TYPE),A + CP TABLES.FAT32 + LD HL,(VARIABLES.Fat32_ReservedSectors) + JR Z,.set_reserved_s + ; + ;!FIXIT проверка FDD/HDD + LD HL,(VARIABLES.FatHDD_ReservedSectors) + ; +.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 +.STEP3: CALL GET_DRIVE_TYPE + JR C,STOP_ERROR + ; + LD A,B + LD (FAT_PARAMETERS.DRIVE_TYPE),A + 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 TABLES.FAT32 + 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: +.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 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) ; !FIXIT написать процедуру вычисления RootDirSectors до вызова этой + ADD HL,DE + JR NC,.skip_inc + ; + AND A + INC BC +.skip_inc: EX DE,HL + ;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 + ; + ; 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 TABLES.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 +;----------------------------------------------------------------------- + + +;----------------------------------------------------------------------- +;!TODO доделать для дискет +GET_DRIVE_TYPE: LD A,(FAT_PARAMETERS.BPB_PHISICAL_DRIVE_NUMBER) + CP DRIVE_CODES.SPRINTER.ATA + LD B,BOOT_SECTOR.Hard_Drive + RET Z + ; дискеты и когда-нибудь ATAPI + SCF + 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 +;----------------------------------------------------------------------- + + +;----------------------------------------------------------------------- +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 TABLES.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 TABLES.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 + ; make fat table + 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 NZ,.not_fat12 + ; fat12 + XOR A + LD (SECTOR_BUFFER + 3),A + JR .write_fat + ; +.not_fat12 CP TABLES.FAT16 + JR Z,.write_fat + ;fat32 + ; + LD HL,.Fat32Data + LD DE,SECTOR_BUFFER + 3 + 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 TABLES.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 +;----------------------------------------------------------------------- + + +//////////////////////////////////////////////////////////////////////// + include 'math.asm' +//////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////// + include 'data.z80' +//////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////// +SECTOR_BUFFER EQU $ +.SIZE EQU 4096 + ASSERT SECTOR_BUFFER + SECTOR_BUFFER.SIZE < #C000, "ERROR: SECTOR_BUFFER" +////////////////////////////////////////////////////////////////////////