;--------------------------------------------------------------- ;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 JP 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 JP GOOD_DRIVE //////////////////////////////////////////////////////////////////////// FAIL: CALL MESSAGE .NULL: LD HL,MESSAGES.FAILURE CALL MESSAGE DI HALT JR $ ; ; ; DOSMESS: CALL FMESAGE ; LD C,Dss.PChars ; RST ToDSS ; RET ; ; ; FMESAGE: LD HL,MSG0 ; LD BC,MSGE-MSG0 ; INC A ; EX AF,AF' ; XOR A ; EX AF,AF' ; .NEXTMSG: EX AF,AF' ; CPIR ; RET PO ; RET NZ ; EX AF,AF' ; DEC A ; JR NZ,.NEXTMSG ; RET ; ; MESSAGE: ;CALL FMESAGE ;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 ; FAILURE EQU 0 ; INCORR EQU 1 ; ERRPART EQU 2 ; ERRIBPB EQU 3 ; NO_SYS EQU 4 ; NOSHELL EQU 5 ; STARTDO EQU 6 ;a BIOS version that is incompatible with this version of DOS 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\nUnsupported BIOS version! Update BIOS to run this version of DSS.\r\n",0 .ERRPART: DB "\r\nUnknown partition table.",0 .ERRIBPB: DB "\r\nInvalid BOOT sector.",0 .NO_SYS: DB "\r\nCan't open file SYSTEM.DOS...",0 .NOSHELL: DB "\r\nCan't open file 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 FATMSG: DB "FAT" //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// ASSERT $<#8200, "Error!!! BIOS LOADING ONLY FIRST #200 BYTES" //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// 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 C,FAIL.NULL ; ; 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 (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 (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 (BANKDOS),A LD A,SUBLOAD_SIZE LD (LOAD_CORE.max_sectors),A LD (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 ; ; LD A,(BANKDOS) ; OUT (SLOT0),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 ; .NoShell: LD HL,MESSAGES.NOSHELL ; JP C,FAIL ; LD HL,MESSAGES.FAILURE ; JP FAIL ; XFAIL: CALL DOSMESS ; .fail: LD HL,MESSAGES.FAILURE ; CALL DOSMESS ; DI ; HALT ; .halt: JR .halt ; ; 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 ; для баланса ;EXX PUSH HL ; для баланса ;EXX JP LOAD_CORE.subload ; CALL .set_stack ; JP RUN_CORE ; .set_stack: PUSH HL ; JP LOAD_CORE.subload ; ; PART_TB: PUSH BC LD HL,(BOOT_BUFFER + BOOT_SECTOR.MBR_SIGNATURE) LD DE,#AA55 ;AND A ; CF = 0 SBC HL,DE SCF RET NZ LD IX,BOOT_BUFFER + BOOT_SECTOR.PARTITION_TABLE LD B, +(_sMBR_PARTITION_TABLE / _sMBR_PARTITION_RECORD) ; .part_loop: LD A,(IX + _sMBR_PARTITION_RECORD.FS_ID) ; ЕСЛИ добавится поддержка ещё одного типа ФС, то поменять 1 на 2 ; 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 ; ; 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 E,(IX + _sMBR_PARTITION_RECORD.Start_LBA + 0) LD D,(IX + _sMBR_PARTITION_RECORD.Start_LBA + 1) LD L,(IX + _sMBR_PARTITION_RECORD.Start_LBA + 2) LD H,(IX + _sMBR_PARTITION_RECORD.Start_LBA + 3) PUSH DE POP IX LD (PARTITION_START_L),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 ;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 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 ; ;RD_BPB: ; CALL READ_BPB ; JP C,DOS_X_Error.Not_ready ; ; ; LD DE,#AA55 ; сигнатура ;R05 ; LD HL,(BOOT_BUFFER + BOOT_SECTOR.MBR_SIGNATURE) ;R08 ;R07 ; ;R05 ; AND A ; SBC HL,DE ; JP NZ,DOS_X_Error.UnknownBPB ; ; ;R08 ; [x] fat32 ; LD HL,BOOT_BUFFER ; LD DE,BootSector ; LD BC,_sBOOT_SECTOR_PARAMS_FAT32 ; size ; LDIR ; LD A,(BOOT_BUFFER + BOOT_SECTOR.DRIVE_TYPE) CP #F0 RET C ; LD HL,(BOOT_BUFFER + BOOT_SECTOR.BytesPerSector) LD (FatBuffer.BytesPerSector),HL 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 (FatBuffer.FAT2_SEC_L),HL ; low word first sector FAT #2 ; fat32 XOR A LD B,A LD C,A LD (FatBuffer.FAT1_SEC_H),BC ; high word first sector FAT #1 ; fat32 LD (FatBuffer.FAT2_SEC_H),BC ; high word first sector FAT #1 ; fat32 LD (FatBuffer.RootDirFirstSector_H),BC LD (FatBuffer.SectorsPerFAT_H),A ; fat32 ; ; 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 LD (FatBuffer.Number_Of_FATs),A CP 1 JR Z,.one_FAT DEC A ADD HL,DE LD (FatBuffer.FAT2_SEC_L),HL JR NC,.no_inc_BC INC BC .no_inc_BC: LD (FatBuffer.FAT2_SEC_H),BC .one_FAT: ;C_DATA1 .loop1: ADD HL,DE JR NC,.loop1_1 INC BC .loop1_1: DEC A JR NZ,.loop1 ; LD (FatBuffer.RootDirFirstSector_L),HL ; first sector DIR LD (FatBuffer.FirstDataSector_H),BC LD BC,(FatBuffer.BytesPerSector) LD A,B AND A ; RL C RLA RL C RLA RL C RLA ; LD C,A LD B,0 ; BC - File handels in sectors ;;;; IF COMPILE_UNUSED_CODE LD (FatBuffer.FilesPerSector),A ENDIF ; 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,(FatBuffer.BytesPerSector) ;LD HL,(BOOT_BUFFER + BOOT_SECTOR.BytesPerSector) LD A,(FatBuffer.SectorsPerCluster) ;LD A,(BOOT_BUFFER + BOOT_SECTOR.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 ; fat32 LD HL,(BOOT_BUFFER + BOOT_SECTOR.SectorsPerDrive) LD DE,(FatBuffer.FirstDataSector_L) 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) PUSH BC ; Total Sectors high PUSH HL ; Total Sectors low AND A SBC HL,DE JP NC,.HDDBIG DEC BC JP .HDDBIG ; .HDDSMAL: ; CF = 0 LD BC,0 PUSH BC ; Total Sectors high PUSH HL ; Total Sectors low SBC HL,DE ; .HDDBIG: CALL SectorToCluster INC HL LD (FatBuffer.MaxClusterLow),HL LD A,L OR H JR NZ,.no_inc_bc INC BC .no_inc_bc: LD (FatBuffer.MaxClusterHigh),BC ; XOR A LD H,A LD L,A LD (FatBuffer.CacheBlock),HL LD (FatBuffer.CacheUpdated),A ; A = 0 LD HL,(FatBuffer.SectorsPerFAT_H) LD H,A EX DE,HL 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) ;LD A,(BOOT_BUFFER + BOOT_SECTOR.SectorsPerCluster) ; HL:DE / A => DE:BC, H=0, L - остаток CALL DIV_for_SPC ; выясняем разрядность FAT LD A,D OR E JR NZ,.its_FAT32 ; LD HL,4084 SBC HL,BC JR NC,.its_FAT12 ; LD HL,65525 SBC HL,BC JR C,.its_FAT32 ; ; It's FAT16 LD HL,#FFFF LD A,FAT_TYPE.x16 .set_vars: EXX LD HL,0 LD (FatBuffer.END_CHAIN_CLUSTER_H),HL LD (FatBuffer.RootDirStartCluster_L),HL LD (FatBuffer.RootDirStartCluster_H),HL LD HL,BOOT_BUFFER + BOOT_SECTOR.FAT.LABEL EXX LD DE,(BOOT_BUFFER + BOOT_SECTOR.FAT.SERIAL_NUMBER) LD BC,(BOOT_BUFFER + BOOT_SECTOR.FAT.SERIAL_NUMBER+2) JR .SET_VARS ; .its_FAT12: LD HL,#0FFF LD A,FAT_TYPE.x12 JR .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 LD (FatBuffer.FAT2_SEC_L),HL EXX LD (FatBuffer.FAT1_SEC_H),HL LD (FatBuffer.FAT2_SEC_H),HL ; .mirrored_FATs: ; LD HL,BOOT_BUFFER + BOOT_SECTOR.FAT32.LABEL ; EXX LD HL,(BOOT_BUFFER + BOOT_SECTOR.RootDirStartCluster) LD (FatBuffer.RootDirStartCluster_L),HL LD DE,(BOOT_BUFFER + BOOT_SECTOR.RootDirStartCluster+2) LD (FatBuffer.RootDirStartCluster_H),DE ; CALL CLUSTER_TO_SECTOR.no_prepare LD (FatBuffer.RootDirFirstSector_L),IX LD (FatBuffer.RootDirFirstSector_H),HL ; LD HL,(BOOT_BUFFER + BOOT_SECTOR.FSINFO_Sector) LD (FatBuffer.FSINFO_Sector),HL ; LD A,FAT_TYPE.x32 LD HL,#0FFF LD (FatBuffer.END_CHAIN_CLUSTER_H),HL LD H,L LD DE,(BOOT_BUFFER + BOOT_SECTOR.FAT32.SERIAL_NUMBER) LD BC,(BOOT_BUFFER + BOOT_SECTOR.FAT32.SERIAL_NUMBER+2) ; .SET_VARS: LD (FatBuffer.FAT_TYPE),A LD (FatBuffer.END_CHAIN_CLUSTER_L),HL LD (FatBuffer.BPB_SERIAL_NUMBER),DE LD (FatBuffer.BPB_SERIAL_NUMBER+2),BC EXX LD DE,FatBuffer.BPB_LABEL LD BC,11 ;!HARDCODE LDIR LD DE,0 CALL READ_FAT_TABLE AND A RET ; ;;;;;;;; ; --> BC:HL - Sector ; <-- BC:HL - Cluster SectorToCluster: LD A,B AND #0F LD B,A LD A,(FatBuffer.SectorsPerCluster) ;LD A,(BOOT_BUFFER + BOOT_SECTOR.SectorsPerCluster) SCF .loop: RRA RET C RR B RR C RR H RR L JP .loop ; ; HL:DE / A => DE:BC, H=0, L - остаток DIV_for_SPC: 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 ; ;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 JP NC,.loop ; .skip: EX DE,HL LD XL,E LD XH,D 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 ADC HL,DE ;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 ADD IX,DE DEC C RET Z ; LD A,(IX+FAT_DIRECTORY_RECORD.NAME) OR A SCF RET Z ; CP #E5 JR Z,.SKIPNAM ; LD A,(IX+FAT_DIRECTORY_RECORD.ATTRIBUT) AND FAT_ATTR.DIRECTORY JR NZ,.SKIPNAM ; 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,(BANKDOS) EX AF,AF' LD A,(DRIVE) RST ToBIOS_18 EXX POP HL EXX POP HL ;AND A RET ; .SMALL_CLUSTER: LD B,A LD C,BIOS.DRV_READ_LONG LD A,(BANKDOS) 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 байтов LD A,(BIG_CORE) 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 */ ;------------------------------------------------------------------------------------------------ ; Прочитать из кеша FAT-а номер след. кластера ; вход: hl - номер кластера (младшее слово) ; hl' - номер кластера (старшее слово. только для FAT32) ; выход: hl - номер кластера (младшее слово) ; hl' - номер кластера (старшее слово) ; de - номер след. кластера (младшее слово) ; de' - номер след. кластера (старшее слово) ; если DE':DE = 0, то кластер HL':HL свободен ; CF - конец цепочки ;------------------------------------------------------------------------------------------------ READ_FROM_FAT: CALL CHECK_CLUSTER_IS_SMALLER RET C 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. Раньше номер блока в рег. A передавался ; LD BC,(FatBuffer.CacheBlock) ; BC - BLOCK FAT IN CASH ; CP C 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 #0F 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. Раньше номер блока в рег. A передавался ; LD BC,(FatBuffer.CacheBlock) ; BC - BLOCK FAT IN CASH ; CP C 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 ; ; [x] fat32 ;!TEST ; вход: hl = младшее слово номера кластера для сравнения с FAT_Max_Cluster ; hl' = старшее слово номера кластера для сравнения с FAT_Max_Cluster (только для fat32) CHECK_CLUSTER_IS_SMALLER: LD A,(FatBuffer.FAT_TYPE) XOR FAT_TYPE.x32 JR NZ,.low ; Z=0 проверяем младшее слово номера кластера ; проверяем старшее слово номера кластера EXX EX DE,HL LD HL,(FatBuffer.MaxClusterHigh) ; CF = 0 SBC HL,DE EX DE,HL EXX LD A,DSS_Error.sys.DISK_FULL RET C RET NZ ; проверяем младшее слово номера кластера .low: EX DE,HL LD HL,(FatBuffer.MaxClusterLow) SBC HL,DE EX DE,HL LD A,DSS_Error.sys.DISK_FULL 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 ; Прочитать в кеш ХХ секторов 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 LD HL,(FatBuffer.FAT1_SEC_H) ; JR NC,.no_inc ; INC HL .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 ; FTIME EQU HANDBUF + FAT_DIRECTORY_RECORD.TIME ; FDATE EQU HANDBUF + FAT_DIRECTORY_RECORD.DATE 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 BANKDOS EQU BIG_CORE+1 ;SHEL_FM EQU VALUE+54 ; EQU VALUE+56 ;----------------- ; BLOCK #8600-$-3,0 ; DB 'SPT' ; BIGA EQU (($/256)+1)*256 ; BIGA2 EQU BIGA-$-2 ; DS BIGA2 ; DB "dp" ; E______ ;STACK EQU (($/256)+2)*256 DISPLAY "BOOT_BUFFER ",/H,BOOT_BUFFER DISPLAY "DIR_BUFFER ",/H,DIR_BUFFER DISPLAY "FatBuffer ",/H,FatBuffer ENT ENDMODULE OUTEND ;[]-----------------------------------------------------------[]