;--------------------------------------------------------------- ;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 + ; +------------------------------+ DEFINE ORIGINAL_DSS 0 DEFINE UNIVERSAL_BOOT 1 DISP #8000 OUTPUT 'build/DSSloader.bin' ;ADRIVE EQU #00 ;CDRIVE EQU #02 DRIVE: _mSYSID DI 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 A,INCORR ;JR C,FAIL RET C LD A,(DRIVE) BIT 7,A JR Z,GOOD_DRIVE EX DE,HL LD DE,2*256 + 21 ;!HARDCODE если версия ниже 2.21, то ошибка SBC HL,DE LD A,INCORR ;JR C,FAIL RET C GOOD_DRIVE: LD DE,#8200 ;!HARDCODE LD HL,0 LD IX,2 LD BC,2*256 + BIOS.DRV_READ LD A,(DRIVE) RST ToBIOS_18 JP C,FAIL.NULL ; ; CONTINUE ;!TEST 26/03/2024 ;LD SP,#C000 ; LD HL,0 LD (DISKL),HL LD (DISKH),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 A,ERRIBPB ;JP C,FAIL RET C CALL GETROOT LD A,NO_SYS ;JP C,FAIL RET C ; [ ] загрузка system.dos больше #4000 байтов LD HL,(FSIZE1) LD A,H OR L JR NZ,.set_size LD DE,(FSIZE0) LD HL,#4000 SBC HL,DE RLA .set_size: LD (BIG_SHELL),A ; LD HL,(FCLUSTR) LD DE,#C000 CALL FLOAD ; загрузка 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,XFAIL.fail ; LD A,STARTDO CALL DOSMESS ; 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,XFAIL.fail LD C,Dss.BootDSK ENDIF ; LD A,STARTDO CALL DOSMESS 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,PSHELL LD BC,Dss.Exec RST ToDSS .NoShell: LD A,NOSHELL ;JP XFAIL XFAIL: CALL DOSMESS .fail: LD A,FAILURE CALL DOSMESS DI HALT .halt: JR .halt ; ; PART_TB: PUSH BC LD HL,(BOOT+510) LD DE,#AA55 AND A SBC HL,DE JR NZ,.ERRP LD IX,BOOT+#01BE LD B,4 ;!HARDCODE счетчик записей партиций в MBR .DOSAGA: LD A,(IX+4) 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 .next: LD DE,#10 ADD IX,DE DJNZ .DOSAGA .ERRP: LD A,ERRPART JP FAIL ; ; YEPDOS: ;[ ] 17.12.2023 загрузка с активного раздела, а не с первого LD A,#80 CP (IX+0) JR NZ,PART_TB.next LD A,4 ;!HARDCODE счетчик записей партиций в MBR SUB B PUSH AF ; номер загрузочного раздела ; LD E,(IX+08) LD D,(IX+09) LD L,(IX+10) LD H,(IX+11) LD XH,D LD XL,E LD (DISKL),IX LD (DISKH),HL LD A,(DRIVE) LD DE,BOOT 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 ; ; SET_PRM: PUSH BC LD A,B LD C,BIOS.DRV_GET_PAR RST ToBIOS_18 LD A,(BOOT.SectorsPerTrack) LD L,A POP AF PUSH AF LD C,BIOS.DRV_SET_PAR RST ToBIOS_18 POP BC LD A,C RET ; ; GET_BPB: LD IX,#0000 LD HL,#0000 LD DE,BOOT 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 CALL SET_PRM ;FDD .NX2: LD HL,(BOOT+510) LD DE,#AA55 AND A SBC HL,DE SCF RET NZ LD IY,BOOT ;Analysing Block Parametr BIOS LD A,(IY+_sBOOT_SECTOR_PARAMS.DRIVE_TYPE) CP #F0 RET C LD HL,0 ;calc. first sector FAT LD (DIR_FRH),HL ; LD E,(IY+_sBOOT_SECTOR_PARAMS.RESERVED_SECTORS) ;Reserve sec LD D,(IY+_sBOOT_SECTOR_PARAMS.RESERVED_SECTORS+1) ADD HL,DE LD (FAT_FRM),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.Number_of_FATs) ;amount FATs .C_DATA1: ADD HL,DE DEC A JR NZ,.C_DATA1 LD (DIR_FRM),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 (DIR_S_S),A ;Sectors per dir LD L,A LD H,0 ADD HL,DE LD (DAT_FRM),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.SectorsPerCluster) .NEXTAD3: ADD HL,BC ;calc. cluster size DEC A JR NZ,.NEXTAD3 LD (CLU_LEN),HL LD HL,BOOT.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 (FAT_TYP),A LD (ENDCLUS),HL ; LD IX,(DISKL) LD HL,(DISKH) LD DE,(FAT_FRM) LD BC,#0000 ADD IX,DE ADC HL,BC ;HL:IX LD DE,FAT LD BC,3*256 + BIOS.DRV_READ LD A,(DRIVE) RST ToBIOS_18 RET C LD HL,0 LD (FatCache),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 ; ; поиск system.dos GETROOT: LD HL,(DIR_FRH) LD IX,(DIR_FRL) LD BC,(DISKL) LD DE,(DISKH) LD A,(DIR_S_S) .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 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 - FAT_DIRECTORY_RECORD .SKIPNAM: LD DE,FAT_DIRECTORY_RECORD ADD IX,DE DEC C RET Z LD A,(IX+00) OR A SCF RET Z CP #E5 JR Z,.SKIPNAM LD A,(IX+11) AND #10 JR NZ,.SKIPNAM LD HL,MASKARE LD D,XH LD E,XL LD B,11 .SEARCH2: LD A,(DE) CP (HL) JR NZ,.SKIPNAM INC HL INC DE DJNZ .SEARCH2 LD D,XH LD E,XL LD HL,HANDBUF EX DE,HL LD BC,FAT_DIRECTORY_RECORD LDIR XOR A INC A RET ; ; 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.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 C,BIOS.DRV_READ_LONG ; 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 ; AND A ; RET ; 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.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.SectorsPerCluster) SUB SUBLOAD_SIZE + 1 CCF RET NC LD A,SUBLOAD_SIZE LD (BOOT.SectorsPerCluster),A AND A RET ; ; --> HL - CLUSTER ; <-- HL:IX - SECTOR NSECTOR: LD DE,0 DEC HL DEC HL LD A,(BOOT.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,(DAT_FRM) ;first data sector XOR A ADD IX,DE LD D,A LD E,A ADC HL,DE ; LD DE,(DISKL) ADD IX,DE LD DE,(DISKH) ADC HL,DE RET ;----------------- ;!TODO сделать это макросами или инклюдами универсальными. повторяются в досе и ещё где-то ; HL - CLUSTER ; DE - (CLUSTER) R_F_FAT: PUSH HL LD A,(FAT_TYP) 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 SBC HL,DE JP NC,.R_F_00H ADD HL,DE ADD HL,HL ; HL - FAT OFFSET (FROM CASH) DEC A LD BC,(FatCache) ; A - ELEMENT OF CASH CP C CALL NZ,RE_FAT LD DE,FAT ADD HL,DE LD E,(HL) INC HL LD D,(HL) LD HL,#FFEF 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.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,(FatCache) CP C CALL NZ,RE_FAT LD DE,FAT 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 JP .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 XOR A SBC HL,DE POP HL RET ; ; RE_FAT: PUSH HL LD L,A LD H,0 LD (FatCache),HL LD E,L LD D,H ADD HL,HL ADD HL,DE LD IX,0 LD DE,(FAT_FRM) ADD HL,DE EX DE,HL JR NC,.NOINX INC IX .NOINX: LD HL,(DISKL) ADD HL,DE EX DE,HL LD BC,(DISKH) JR NC,.NOINX2 INC IX .NOINX2: ADD IX,BC PUSH IX PUSH DE POP IX POP HL LD DE,FAT LD BC,3*256 + BIOS.DRV_READ LD A,(DRIVE) RST ToBIOS_18 POP HL RET ; //////////////////////////////////////////////////////////////////////// FAIL: CALL MESSAGE .NULL: LD A,FAILURE CALL MESSAGE DI HALT JR $ ; ; DOSMESS: CALL FMESAGE LD C,Dss.PChars JP ToDSS ; ; 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 PRINTZ: LD A,(HL) ;R01 INC HL OR A RET Z CALL PRINTX JR PRINTZ ; ; PRINTX: CP #0D JR Z,.CR_ CP #0A 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,#84 JP 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 JP 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 ; 0 10 20 30 40 50 60 70 80 MSG0: DB 0 DB 13,10,"The system has been halted. Press RESET to restart your computer.",13,10,0 DB 13,10,"You started your computer with a BIOS version that is incompatible with this",13,10 DB "version of DSS. Please update BIOS to run this version of DSS.",13,10,0 DB "Invalid partition table.",13,10,0 DB "Invalid BOOT sector.",13,10,0 DB "Can't open file SYSTEM.DOS...",13,10,0 DB 13,10,"Starting DSS... ",13,10,13,10,0 MSGE: DB 0 ; PSHELL: DB '\SYSTEM.EXE /P',0 ROOT: DB 'X:\',0 MASKARE: DB "SYSTEM DOS" FATMSG: DB "FAT" //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// ; Area for boot sector [512Bytes] BOOT _sBOOT_SECTOR_PARAMS = $ ; BOOT EQU $ ; ID_NAME EQU BOOT+#03 ; +03 DOS NAME ; ; Block Parameters BIOS ; B_P_S EQU BOOT+#0B ; +0B BYTE PER SECTOR ; S_P_C EQU BOOT+#0D ; +0D SECTORS PER CLUSTER ; RESERVE EQU BOOT+#0E ; +0E RESERVE SECTORS ; FAT_NUM EQU BOOT+#10 ; +10 AMOUNT FATS ; F_P_DIR EQU BOOT+#11 ; +11 FILES IN DIRECTORY ; S_P_D EQU BOOT+#13 ; +13 ALL SECTORS ON DISK ; ID_FORM EQU BOOT+#15 ; +15 ID FORMAT ; S_P_F EQU BOOT+#16 ; +16 SIZE FAT IN SECTORS ; S_P_T EQU BOOT+#18 ; +18 SECTOR PER TRACK ; HEADS EQU BOOT+#1A ; +1A AMOUNT SIDES ; HIDDEN EQU BOOT+#1C ; +1C HIDDEN SECTORS ; ID_FAT EQU BOOT+#36 ; +36 FAT ID ; ; end boot sector DIR EQU BOOT+512 FAT EQU DIR+512 VALUE EQU 3*512+FAT FatCache EQU VALUE+0 FAT_FRM EQU VALUE+2 ; MSD_FAT_SEC first sector FAT DIR_FRH EQU VALUE+4 ; MSD_CAT_SEC first sector DIR DIR_FRL EQU VALUE+6 ; MSD_CAT_SEC first sector DIR DIR_FRM EQU VALUE+6 DIR_S_S EQU VALUE+8 ; DIR_SEC_SIZE DAT_FRM EQU VALUE+9 ; MSD_DAT_SEC FAT_TYP EQU VALUE+11; TYPE FAT (#32 - 12bit, #36 - 16bit) CLU_LEN EQU VALUE+12; CLASTER_LEN ENDCLUS EQU VALUE+14 HANDBUF EQU VALUE+16 FTIME EQU VALUE+16+22 FDATE EQU VALUE+16+24 FCLUSTR EQU VALUE+16+26 FSIZE0 EQU VALUE+16+28 FSIZE1 EQU VALUE+16+30 DISKH EQU VALUE+48 DISKL EQU VALUE+50 READMEM EQU VALUE+52 ;SHEL_FM EQU VALUE+54 BIG_SHELL EQU VALUE+54 BANKDOS EQU VALUE+55 ; 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 ENT OUTEND ;[]-----------------------------------------------------------[]