From 082c101845d65d884e7adea84bfc214273783a0a Mon Sep 17 00:00:00 2001 From: b1ackmai1er <39449559+b1ackmai1er@users.noreply.github.com> Date: Sat, 10 Nov 2018 01:10:48 +0800 Subject: [PATCH] Tidy up Romldr --- romldr.asm | 937 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 937 insertions(+) create mode 100644 romldr.asm diff --git a/romldr.asm b/romldr.asm new file mode 100644 index 00000000..ae71101b --- /dev/null +++ b/romldr.asm @@ -0,0 +1,937 @@ +; +;================================================================================================== +; LOADER +;================================================================================================== +; +; INCLUDE GENERIC STUFF +; +#INCLUDE "std.asm" +; +INT_IM1 .EQU $FF00 +; + .ORG 0 +; +;================================================================================================== +; NORMAL PAGE ZERO SETUP, RET/RETI/RETN AS APPROPRIATE +;================================================================================================== +; + JP $100 ; RST 0: JUMP TO BOOT CODE + .FILL (008H - $),0FFH +#IF (PLATFORM == PLT_UNA) + JP $FFFD ; RST 8: INVOKE UBIOS FUNCTION +#ELSE + JP HB_INVOKE ; RST 8: INVOKE HBIOS FUNCTION +#ENDIF + .FILL (010H - $),0FFH + RET ; RST 10 + .FILL (018H - $),0FFH + RET ; RST 18 + .FILL (020H - $),0FFH + RET ; RST 20 + .FILL (028H - $),0FFH + RET ; RST 28 + .FILL (030H - $),0FFH + RET ; RST 30 + .FILL (038H - $),0FFH +#IF (PLATFORM == PLT_UNA) + RETI ; RETURN W/ INTS DISABLED +#ELSE + #IF (INTMODE == 1) + JP INT_IM1 ; JP TO INTERRUPT HANDLER IN HI MEM + #ELSE + RETI ; RETURN W/ INTS DISABLED + #ENDIF +#ENDIF + .FILL (066H - $),0FFH + RETN ; NMI +; + .FILL (100H - $),0FFH ; PAD REMAINDER OF PAGE ZERO +; +; +;================================================================================================== +; LOADER +;================================================================================================== +; + DI ; NO INTERRUPTS + LD SP,BL_STACK ; SETUP STACK + +; +#IF (PLATFORM != PLT_UNA) + CALL DELAY_INIT ; INIT DELAY FUNCTIONS +#ENDIF +; +#IF (PLATFORM == PLT_UNA) +; ; COPY UNA BIOS PAGE ZERO TO USER BANK, LEAVE USER BANK ACTIVE +; LD BC,$01FB ; UNA FUNC = SET BANK +; LD DE,BID_BIOS ; UBIOS_PAGE (SEE PAGES.INC) +; CALL $FFFD ; DO IT (RST 08 NOT YET INSTALLED) +; PUSH DE ; SAVE PREVIOUS BANK +;; +; LD HL,0 ; FROM ADDRESS 0 (PAGE ZERO) +; LD DE,$9000 ; USE $9000 AS BOUNCE BUFFER +; LD BC,256 ; ONE PAGE IS 256 BYTES +; LDIR ; DO IT +;; +; LD BC,$01FB ; UNA FUNC = SET BANK +; ;POP DE ; RECOVER OPERATING BANK +; LD DE,BID_USR ; TO USER BANK +; CALL $FFFD ; DO IT (RST 08 NOT YET INSTALLED) +;; +; LD HL,$9000 ; USE $9000 AS BOUNCE BUFFER +; LD DE,0 ; TO PAGE ZERO OF OPERATING BANK +; LD BC,256 ; ONE PAGE IS 256 BYTES +; LDIR ; DO IT +;; +;; ; INSTALL UNA INVOCATION VECTOR FOR RST 08 +;; ; *** IS THIS REDUNDANT? *** +;; LD A,$C3 ; JP INSTRUCTION +;; LD (8),A ; STORE AT 0x0008 +;; LD HL,($FFFE) ; UNA ENTRY VECTOR +;; LD (9),HL ; STORE AT 0x0009 +;; +; LD BC,$01FB ; UNA FUNC = SET BANK +; POP DE ; RECOVER OPERATING BANK +; CALL $FFFD ; DO IT (RST 08 NOT YET INSTALLED) +#ELSE + ; PREP THE USER BANK (SETUP PAGE ZERO) + LD B,BF_SYSSETCPY ; HBIOS FUNC: SETUP BANK COPY + LD D,BID_USR ; D = DEST BANK = USER BANK + LD E,BID_BIOS ; E = SRC BANK = BIOS BANK + LD HL,256 ; HL = COPY LEN = 1 PAGE = 256 BYTES + RST 08 ; DO IT + LD B,BF_SYSBNKCPY ; HBIOS FUNC: PERFORM BANK COPY + LD HL,0 ; COPY FROM BIOS ADDRESS 0 + LD DE,0 ; TO USER ADDRESS 0 + RST 08 ; DO IT +#ENDIF + EI +; +; RUN THE BOOT LOADER MENU +; + LD DE,STR_BANNER ; DISPLAY BOOT BANNER + +DOBOOTMENU: + CALL WRITESTR ; DISPLAY MESSAGE OR ERROR + CALL NEWLINE +; +#IF (DSKYENABLE) + LD HL,BOOT ; POINT TO BOOT MESSAGE + CALL DSKY_SHOWRAW ; DISPLAY MESSAGE +#ENDIF +; +#IF (BOOTTYPE == BT_AUTO) + LD BC,100 * BOOT_TIMEOUT + LD (BL_TIMEOUT),BC +#ENDIF +; + LD B,MENU_N ; DISPLAY ALL ROM MENU ENTRIES + LD HL,MENU_S ; DE POINTS TO START RECORD + +MENU_L: PUSH HL ; SAVE CURRENT RECORD POSITION + + PUSH HL ; PUT CURRENT ROM RECORD IN HL + POP DE + + PUSH BC ; POINT HL TO THE MENU KEY + LD BC,MENU_O + ADD HL,BC + POP BC + +WRITEM1:LD A,(DE) ; DE STEPS THROUGH THE MENU NAMES + CP '$' ; TEST FOR STRING TERMINATOR + JR Z,WRITEM2 + + CP (HL) ; DO WE HAVE A MATCH WITH MENU + JR NZ,WRITEM3 + + LD A,'(' + CALL COUT + LD A,(DE) + CALL COUT + LD A,')' +WRITEM3:CALL COUT + INC DE + JR WRITEM1 +WRITEM2:POP HL ; RECALL THE PREVIOUS RECORD + LD DE,MENU_V ; SAVED AT MENU_L + ADD HL,DE ; MOVE TO NEXT RECORD + + LD A,' ' + CALL COUT + + DJNZ MENU_L ; NEXT MENU ITEM + + CALL NEWLINE ; DISPLAY AVAILABLE DRIVES + CALL PRTALL + CALL PC_COLON + +DB_BOOTLOOP: + + CALL CST ; CHECK CONSOLE INPUT + OR A + JR NZ,GOTK1 + +#IF (DSKYENABLE) + CALL KY_STAT ; CHECK DSKY INPUR + OR A + JR Z,GOTNK + + CALL KY_GET + JR MENU_A +#ENDIF + +GOTNK: ; CHECK AUTOBOOT TIMEOUT + +#IF (BOOTTYPE == BT_AUTO) + LD DE,625 ; DELAY FOR 10MS TO MAKE TIMEOUT CALC EASY + CALL VDELAY ; 16US * 625 = 10MS + LD BC,(BL_TIMEOUT) ; CHECK/INCREMENT TIMEOUT + DEC BC + LD (BL_TIMEOUT),BC + LD A,B + OR C + JP NZ,DB_BOOTLOOP + + LD A,BOOT_DEFAULT ; TIMEOUT EXPIRED, + JR MENU_A ; PERFORM DEFAULT BOOT ACTION +#ENDIF + JR DB_BOOTLOOP + +GOTK1: CALL CINUC + +MENU_A: LD B,MENU_N + LD DE,MENU_S+10-MENU_V + LD HL,MENU_V +MENU_C: EX DE,HL + ADD HL,DE + CP (HL) + EX DE,HL + JR Z,MENU_X + DJNZ MENU_C ; FALL THRU IF IT DOES NOT MATCH ROM MENU + +; CHECK FOR DRIVE EXECUTION + + CP '0' ; 0-9, DISK DEVICE + JR C,DB_INVALID + CP '9' + 1 + JR NC,DB_INVALID + SUB '0' + JP GOBOOTDISK + +MENU_X: CALL NEWLINE + + ; DE CONTAIN POINTER TO MENU RECORD + + EX DE,HL + INC HL ; WE HAVE A VALID ROM MENU OPTION + LD E,(HL) + INC HL + LD D,(HL) + EX DE,HL + + JP (HL) ; JUMP TO THE ROUTINE TO EXECUTE IT + +DB_INVALID: + LD DE,STR_INVALID + JP DOBOOTMENU + +#DEFINE MENU_L(M1,M2,M3,M4,M5,M6,M7,M8,M9,M10) \ +#DEFCONT \ .DB M1 +#DEFCONT \ .DB M2 +#DEFCONT \ .DW M3 +#DEFCONT \ .DW M4 +#DEFCONT \ .DW M5 +#DEFCONT \ .DW M6 +#DEFCONT \ .DW M7 +#DEFCONT \ .DB M8 +#DEFCONT \ .DB M9 +#DEFCONT \ .DB M10 +; +; name menu exec dest-exec source dest-addr img-size source-bank dest desc +; DB DB DW DB DW DW DW DW DB DB +MENU_S: MENU_L("MONITOR$ $", "M", GOROM, MON_SERIAL, 1000h, MON_LOC, MON_SIZ, BID_BIOSIMG, BID_USR, "Monitor$12345") +MENU_1: MENU_L("CP/M$ $", "C", GOROM, CPM_ENT, 2000h, CPM_LOC, CPM_SIZ, BID_BIOSIMG, BID_USR, "CP/M 80 2.2$ ") + MENU_L("Z-SYSTEM$$", "Z", GOROM, CPM_ENT, 5000h, CPM_LOC, CPM_SIZ, BID_BIOSIMG, BID_USR, "ZSDOS V1.1$ ") + MENU_L("$ $", "E", GOROM, EGG_LOC, 0E00h, EGG_LOC, EGG_SIZ, BID_BIOSIMG, BID_USR, "Easter Egg$ ") + MENU_L("FORTH$ $", "F", GOROM, FTH_LOC, 0000h, FTH_LOC, FTH_SIZ, BID_OSIMG, BID_USR, "Camel Forth$ ") + MENU_L("BASIC$ $", "B", GOROM, BAS_LOC, 1700h, BAS_LOC, BAS_SIZ, BID_OSIMG, BID_USR, "Nascom BASIC$") + MENU_L("T-BASIC$ $", "T", GOROM, TBC_LOC, 3700h, TBC_LOC, TBC_SIZ, BID_OSIMG, BID_USR, "Tasty BASIC$ ") + +#IF (DSKYENABLE) + MENU_L("DSKY-MON $", "D", GOROM, MON_DSKY, 1000h, MON_LOC, MON_SIZ, BID_BIOSIMG, BID_USR, "DSKY Monitor$") +#ENDIF + + .DB "REBOOT$ ", "R" + .DW REBOOT + +MENU_E: +MENU_V .EQU MENU_1-MENU_S ; LENGTH OF EACH MENU RECORD +MENU_N .EQU ((MENU_E-MENU_S)/MENU_V)+1 ; NUMBER OF MENU ITEMS +MENU_O .EQU 10 ; OFFSET TO MENU KEY FROM NAME +; +; BOOT OPTION PROCESSING +; +GOROM: EX DE,HL + LD B,5 ; PUT NEXT FIVE ADDRESSES ON STACK +GOROMB1:INC HL + LD E,(HL) ; EXEC + INC HL ; SOURCE + LD D,(HL) ; DEST + PUSH DE ; SIZE + DJNZ GOROMB1 ; BANKS + + POP DE ; BANKS + POP HL ; SIZE + LD B,BF_SYSSETCPY ; HBIOS FUNC: SETUP BANK COPY + RST 08 ; DO IT + + POP DE ; DEST + POP HL ; SOURCE + LD B,BF_SYSBNKCPY ; HBIOS FUNC: PERFORM BANK COPY + RST 08 ; DO IT +; + ; EXEC ADDRESS ON TOP OF STACK +; +#IF (PLATFORM == PLT_UNA) + LD BC,$00FB ; GET LOWER PAGE ID + RST 08 ; DE := LOWER PAGE ID == BOOT ROM PAGE + LD L,1 ; BOOT DISK UNIT IS ROM (UNIT ID = 1) + LD BC,$01FC ; UNA FUNC: SET BOOTSTRAP HISTORY + RST 08 ; CALL UNA + + ; HL IS ALREADY ON STACK AS REQUIRED BY UNA EXEC CHAIN CALL + + LD DE,BID_USR ; TARGET BANK ID + PUSH DE ; ... ON STACK + DI ; ENTER WITH INTS DISABLED + JP $FFF7 ; UNA INTER-PAGE EXEC CHAIN +#ELSE + LD A,(HB_CURBNK) ; GET CURRENT BANK ID FROM PROXY DATA + LD B,BF_SYSSET ; HB FUNC: SET HBIOS PARAMETER + LD C,BF_SYSSET_BOOTINFO ; HB SUBFUNC: SET BOOT INFO + LD L,A ; ... AND SAVE AS BOOT BANK + LD DE,$0100 ; BOOT VOLUME (UNIT, SLICE) + RST 08 +; + LD A,BID_USR ; ACTIVATE USER BANK + POP HL ; RECOVER ENTRY ADDRESS + DI ; ENTER WITH INTS DISABLED + CALL HB_BNKCALL ; AND GO + HALT ; WE SHOULD NEVER RETURN!!! +#ENDIF +; +; REBOOT ROMLDR +; +REBOOT: LD A,BID_BOOT ; BOOT BANK + LD HL,0 ; ADDRESS ZERO + CALL HB_BNKCALL ; DOES NOT RETURN + +GOBOOTDISK: + LD (BL_BOOTID),A + LD DE,STR_BOOTDISK + CALL WRITESTR +; +; BOOT FROM DISK DRIVE +; +BOOTDISK: + LD DE,STR_BOOTDISK1 ; DISK BOOT MESSAGE + CALL WRITESTR ; PRINT IT + +#IF (PLATFORM == PLT_UNA) +; +; BOOT FROM UNA DISK DRIVE +; + LD A,(BL_BOOTID) ; GET BOOT DEVICE ID + LD B,A ; MOVE TO B + + ; LOAD SECTOR 2 (BOOT INFO) + LD C,$41 ; UNA FUNC: SET LBA + LD DE,0 ; HI WORD OF LBA IS ALWAYS ZERO + LD HL,2 ; LOAD STARTING INFO SECTOR 2 + RST 08 ; SET LBA + JP NZ,DB_ERR ; HANDLE ERROR +; + LD C,$42 ; UNA FUNC: READ SECTORS + LD DE,BL_INFOSEC ; DEST OF CPM IMAGE + LD L,1 ; SECTORS TO READ + RST 08 ; DO READ + JP NZ,DB_ERR ; HANDLE ERROR +; +#ELSE + ; CHECK FOR VALID DRIVE LETTER + LD A,(BL_BOOTID) ; BOOT DEVICE TO A + PUSH AF ; SAVE BOOT DEVICE + LD B,BF_SYSGET + LD C,BF_SYSGET_DIOCNT + RST 08 ; E := DISK UNIT COUNT + POP AF ; RESTORE BOOT DEVICE + CP E ; CHECK MAX (INDEX - COUNT) + JP NC,DB_NODISK ; HANDLE INVALID SELECTION + + ; SET THE BOOT UNIT AND SLICE + LD A,(BL_BOOTID) ; GET BOOTID + LD (BL_DEVICE),A ; STORE IT + XOR A ; LU ALWAYS ZERO + LD (BL_LU),A ; STORE IT + + ; SENSE MEDIA + LD A,(BL_DEVICE) ; GET DEVICE/UNIT + LD C,A ; STORE IN C + LD B,BF_DIOMEDIA ; DRIVER FUNCTION = DISK MEDIA + LD E,1 ; ENABLE MEDIA CHECK/DISCOVERY + RST 08 ; CALL HBIOS + JP NZ,DB_ERR ; HANDLE ERROR + + ; SEEK TO SECTOR 2 OF LU + LD A,(BL_LU) ; GET LU SPECIFIED + LD E,A ; LU INDEX + LD H,65 ; 65 TRACKS PER LU + CALL MULT8 ; HL := H * E + LD DE,$02 ; HEAD 0, SECTOR 2 + LD B,BF_DIOSEEK ; SETUP FOR NEW SEEK CALL + LD A,(BL_DEVICE) ; GET BOOT DISK UNIT + LD C,A ; PUT IN C + RST 08 ; DO IT + JP NZ,DB_ERR ; HANDLE ERROR + + ; READ + LD B,BF_DIOREAD ; FUNCTION IN B + LD A,(BL_DEVICE) ; GET BOOT DISK UNIT + LD C,A ; PUT IN C + LD HL,BL_INFOSEC ; READ INTO INFO SEC BUFFER + LD DE,1 ; TRANSFER ONE SECTOR + RST 08 ; DO IT + JP NZ,DB_ERR ; HANDLE ERROR +; +#ENDIF +; + ; CHECK SIGNATURE + CALL NEWLINE ; FORMATTING + LD DE,(BB_SIG) ; GET THE SIGNATURE + LD A,$A5 ; FIRST BYTE SHOULD BE $A5 + CP D ; COMPARE + JP NZ,DB_NOBOOT ; ERROR IF NOT EQUAL + LD A,$5A ; SECOND BYTE SHOULD BE $5A + CP E ; COMPARE + JP NZ,DB_NOBOOT ; ERROR IS NOT EQUAL + + ; PRINT CPMLOC VALUE + CALL NEWLINE + LD DE,STR_CPMLOC + CALL WRITESTR + LD BC,(BB_CPMLOC) + CALL PRTHEXWORD + + ; PRINT CPMEND VALUE + CALL PC_SPACE + LD DE,STR_CPMEND + CALL WRITESTR + LD BC,(BB_CPMEND) + CALL PRTHEXWORD + + ; PRINT CPMENT VALUE + CALL PC_SPACE + LD DE,STR_CPMENT + CALL WRITESTR + LD BC,(BB_CPMENT) + CALL PRTHEXWORD + CALL PC_SPACE + + ; PRINT DISK LABEL + LD DE,STR_LABEL + CALL WRITESTR + LD DE,BB_LABEL ; if it is there, then a printable + LD A,(BB_TERM) ; Display Disk Label if Present + CP '$' ; (dwg 2/7/2012) + CALL Z,WRITESTR ; label is there as well even if spaces. +; + LD DE,STR_LOADING ; LOADING MESSAGE + CALL WRITESTR ; PRINT IT +; + ; COMPUTE NUMBER OF SECTORS TO LOAD + LD HL,(BB_CPMEND) ; HL := END + LD DE,(BB_CPMLOC) ; DE := START + OR A ; CLEAR CARRY + SBC HL,DE ; HL := LENGTH TO LOAD + LD A,H ; DETERMINE 512 BYTE SECTOR COUNT + RRCA ; ... BY DIVIDING MSB BY TWO + LD (BL_COUNT),A ; ... AND SAVE IT +; +#IF (PLATFORM == PLT_UNA) +; + ; READ OS IMAGE INTO MEMORY + LD C,$42 ; UNA FUNC: READ SECTORS + LD A,(BL_BOOTID) ; GET BOOT DEVICE ID + LD B,A ; MOVE TO B + LD DE,(BB_CPMLOC) ; DEST OF CPM IMAGE + LD A,(BL_COUNT) ; GET SECTORS TO READ + LD L,A ; SECTORS TO READ + RST 08 ; DO READ + JP NZ,DB_ERR ; HANDLE ERROR +; + ; PASS BOOT DEVICE/UNIT/LU TO CBIOS COLD BOOT + LD DE,-1 ; BOOT ROM PAGE, -1 FOR N/A + LD A,(BL_BOOTID) ; GET BOOT DISK UNIT ID + LD L,A ; PUT IN L + LD BC,$01FC ; UNA FUNC: SET BOOTSTRAP HISTORY + RST 08 ; CALL UNA + JP NZ,DB_ERR ; HANDLE ERROR +; + ; JUMP TO COLD BOOT ENTRY + LD HL,(BB_CPMENT) ; GET THE ENTRY POINT + PUSH HL ; PUT ON STACK FOR UNA CHAIN FUNC + LD DE,BID_USR ; TARGET BANK ID IS USER BANK + PUSH DE ; PUT ON STACK FOR UNA CHAIN FUNC + DI ; ENTER WITH INTS DISABLED + JP $FFF7 ; UNA INTER-PAGE EXEC CHAIN +; +#ELSE +; + ; READ OS IMAGE INTO MEMORY + LD B,BF_DIOREAD ; FUNCTION IN B + LD A,(BL_DEVICE) ; GET BOOT DISK UNIT + LD C,A ; PUT IN C + LD HL,(BB_CPMLOC) ; LOAD ADDRESS + LD D,0 + LD A,(BL_COUNT) ; GET SECTORS TO READ + LD E,A ; NUMBER OF SECTORS TO LOAD + RST 08 + JP NZ,DB_ERR ; HANDLE ERRORS + + ; PASS BOOT DEVICE/UNIT/LU TO CBIOS COLD BOOT + LD B,BF_SYSSET ; HB FUNC: SET HBIOS PARAMETER + LD C,BF_SYSSET_BOOTINFO ; HB SUBFUNC: SET BOOT INFO + LD A,(HB_CURBNK) ; GET CURRENT BANK ID FROM PROXY DATA + LD L,A ; ... AND SAVE AS BOOT BANK + LD A,(BL_DEVICE) ; LOAD BOOT DEVICE/UNIT + LD D,A ; SAVE IN D + LD A,(BL_LU) ; LOAD BOOT LU + LD E,A ; SAVE IN E + RST 08 + JP NZ,DB_ERR ; HANDLE ERRORS + + ; JUMP TO COLD BOOT ENTRY + LD A,BID_USR ; ACTIVATE USER BANK + LD HL,(BB_CPMENT) ; OS ENTRY ADDRESS + DI ; ENTER WITH INTS DISABLED + CALL HB_BNKCALL ; AND GO + HALT ; WE SHOULD NEVER RETURN!!! +; +#ENDIF +; +DB_NODISK: + ; SELDSK DID NOT LIKE DRIVE SELECTION + LD DE,STR_NODISK + JP DOBOOTMENU + +DB_NOBOOT: + ; DISK IS NOT BOOTABLE + LD DE,STR_NOBOOT + JP DOBOOTMENU + +DB_ERR: + ; I/O ERROR DURING BOOT ATTEMPT + LD DE,STR_BOOTERR + JP DOBOOTMENU +; +#IF (PLATFORM == PLT_UNA) +; +; +; PRINT LIST OF ALL DRIVES UNDER UNA +; +PRTALL: + LD B,0 ; START WITH UNIT 0 +; +PRTALL1: ; LOOP THRU ALL UNITS AVAILABLE + LD C,$48 ; UNA FUNC: GET DISK TYPE + LD L,0 ; PRESET UNIT COUNT TO ZERO + RST 08 ; CALL UNA, B IS ASSUMED TO BE UNTOUCHED!!! + LD A,L ; UNIT COUNT TO A + OR A ; PAST END? + RET Z ; WE ARE DONE + PUSH BC ; SAVE UNIT + CALL PRTDRV ; PROCESS THE UNIT + POP BC ; RESTORE UNIT + INC B ; NEXT UNIT + JR PRTALL1 ; LOOP +; +; PRINT THE UNA UNIT INFO +; ON INPUT B HAS UNIT +; +PRTDRV: + PUSH BC ; SAVE UNIT + PUSH DE ; SAVE DISK TYPE + LD A,'(' ; NEWLINE AND SPACING + CALL COUT ; PRINT IT + LD A,B ; DRIVE LETTER TO A + ADD A,'0' ; MAKE IT DISPLAY NUMERIC + CALL COUT ; PRINT IT + LD A,')' ; DRIVE LETTER COLON + CALL COUT ; PRINT IT + POP DE ; RECOVER DISK TYPE + LD A,D ; DISK TYPE TO A + CP $40 ; RAM/ROM? + JR Z,PRTDRV1 ; HANDLE RAM/ROM + LD DE,DEVIDE ; ASSUME IDE + CP $41 ; IDE? + JR Z,PRTDRV2 ; PRINT IT + LD DE,DEVPPIDE ; ASSUME PPIDE + CP $42 ; PPIDE? + JR Z,PRTDRV2 ; PRINT IT + LD DE,DEVSD ; ASSUME SD + CP $43 ; SD? + JR Z,PRTDRV2 ; PRINT IT + LD DE,DEVDSD ; ASSUME DSD + CP $44 ; DSD? + JR Z,PRTDRV2 ; PRINT IT + LD DE,DEVUNK ; OTHERWISE UNKNOWN + JR PRTDRV2 +; +PRTDRV1: ; HANDLE RAM/ROM + LD C,$45 ; UNA FUNC: GET DISK INFO + LD DE,BL_INFOSEC ; 512 BYTE BUFFER + RST 08 ; CALL UNA + BIT 7,B ; TEST RAM DRIVE BIT + LD DE,DEVROM ; ASSUME ROM + JR Z,PRTDRV2 ; IF SO, PRINT IT + LD DE,DEVRAM ; OTHERWISE RAM + JR PRTDRV2 ; PRINT IT +; +PRTDRV2: ; PRINT DEVICE + POP BC ; RECOVER UNIT + CALL WRITESTR ; PRINT DEVICE NAME + LD A,B ; UNIT TO A + ADD A,'0' ; MAKE IT PRINTABLE NUMERIC + CALL COUT ; PRINT IT + LD A,',' ; DEVICE NAME SEPARATOR + CALL COUT ; PRINT IT + RET ; DONE +; +DEVRAM .DB "RAM$" +DEVROM .DB "ROM$" +DEVIDE .DB "IDE$" +DEVPPIDE .DB "PPIDE$" +DEVSD .DB "SD$" +DEVDSD .DB "DSD$" +DEVUNK .DB "UNK$" +; +#ELSE +; +; PRINT LIST OF ALL DRIVES +; +PRTALL: +; + LD B,BF_SYSGET + LD C,BF_SYSGET_DIOCNT + RST 08 ; E := DISK UNIT COUNT + LD B,E ; COUNT TO B + LD A,B ; COUNT TO A + OR A ; SET FLAGS + RET Z ; BAIL OUT IF ZERO + LD C,0 ; INIT DEVICE INDEX +; +PRTALL1: + LD A,'(' ; FORMATTING + CALL COUT ; PRINT IT + LD A,C ; INDEX TO A + ADD A,'0' ; MAKE NUMERIC CHAR + CALL COUT ; PRINT IT + LD A,')' ; FORMATTING + CALL COUT ; PRINT IT + PUSH BC ; SAVE LOOP CONTROL + LD B,BF_DIODEVICE ; HBIOS FUNC: REPORT DEVICE INFO + RST 08 ; CALL HBIOS + CALL PRTDRV ; PRINT IT + POP BC ; RESTORE LOOP CONTROL + INC C ; BUMP INDEX + DJNZ PRTALL1 ; LOOP AS NEEDED + RET ; DONE +; +; PRINT THE DRIVER DEVICE/UNIT INFO +; ON INPUT D HAS DRIVER ID, E HAS DRIVER MODE/UNIT +; DESTROY NO REGISTERS OTHER THAN A +; +PRTDRV: + PUSH DE ; PRESERVE DE + PUSH HL ; PRESERVE HL + LD A,D ; LOAD DEVICE/UNIT + RRCA ; ROTATE DEVICE + RRCA ; ... BITS + RRCA ; ... INTO + RRCA ; ... LOWEST 4 BITS + AND $0F ; ISOLATE DEVICE BITS + ADD A,A ; MULTIPLE BY TWO FOR WORD TABLE + LD HL,DEVTBL ; POINT TO START OF DEVICE NAME TABLE + CALL ADDHLA ; ADD A TO HL TO POINT TO TABLE ENTRY + LD A,(HL) ; DEREFERENCE HL TO LOC OF DEVICE NAME STRING + INC HL ; ... + LD D,(HL) ; ... + LD E,A ; ... + CALL WRITESTR ; PRINT THE DEVICE NMEMONIC + POP HL ; RECOVER HL + POP DE ; RECOVER DE + LD A,E ; LOAD DRIVER MODE/UNIT + AND $0F ; ISOLATE UNIT + CALL PRTDECB ; PRINT IT + CALL PC_SPACE ; FORMATTING + ;LD A,E ; LOAD LU + ;CALL PRTDECB ; PRINT IT + RET +; +DEVTBL: ; DEVICE TABLE + .DW DEV00, DEV01, DEV02, DEV03 + .DW DEV04, DEV05, DEV06, DEV07 + .DW DEV08, DEV09, DEV10, DEV11 + .DW DEV12, DEV13, DEV14, DEV15 +; +DEVUNK .DB "???$" +DEV00 .DB "MD$" +DEV01 .DB "FD$" +DEV02 .DB "RAMF$" +DEV03 .DB "IDE$" +DEV04 .DB "ATAPI$" +DEV05 .DB "PPIDE$" +DEV06 .DB "SD$" +DEV07 .DB "PRPSD$" +DEV08 .DB "PPPSD$" +DEV09 .DB "HDSK$" +DEV10 .EQU DEVUNK +DEV11 .EQU DEVUNK +DEV12 .EQU DEVUNK +DEV13 .EQU DEVUNK +DEV14 .EQU DEVUNK +DEV15 .EQU DEVUNK +; +#ENDIF +; +;__TEXT_STRINGS_________________________________________________________________________________________________________________ +; +; STRINGS +;_____________________________________________________________________________________________________________________________ +; +STR_BOOTDISK .DB "BOOT FROM DISK\r\n$" +STR_BOOTDISK1 .DB "\r\nReading disk information...$" +STR_INVALID .DB "INVALID SELECTION\r\n$" +STR_SETUP .DB "SYSTEM SETUP\r\n$" +STR_SIG .DB "SIGNATURE=$" +STR_CPMLOC .DB "LOC=$" +STR_CPMEND .DB "END=$" +STR_CPMENT .DB "ENT=$" +STR_LABEL .DB "LABEL=$" +STR_LOADING .DB "\r\nLoading...$" +STR_NODISK .DB "\r\nNo disk!$" +STR_NOBOOT .DB "\r\nDisk not bootable!$" +STR_BOOTERR .DB "\r\nBoot failure!$" +STR_BANNER .DB "\r\n", PLATFORM_NAME, " Boot Loader\r\n$" +; +#IF (DSKYENABLE) + ; b o o t . . +BOOT .DB $9F,$9D,$9D,$94,$80,$80,$00,$00 +#ENDIF +; +#DEFINE USEDELAY +#INCLUDE "util.asm" +; +#IF (DSKYENABLE) +#DEFINE DSKY_KBD +#INCLUDE "dsky.asm" +#ENDIF +; +;================================================================================================== +; CONSOLE CHARACTER I/O HELPER ROUTINES (REGISTERS PRESERVED) +;================================================================================================== +; +#IF (PLATFORM != PLT_UNA) +; +; OUTPUT CHARACTER FROM A +; +COUT: + ; SAVE ALL INCOMING REGISTERS + PUSH AF + PUSH BC + PUSH DE + PUSH HL +; + ; OUTPUT CHARACTER TO CONSOLE VIA HBIOS + LD E,A ; OUTPUT CHAR TO E + LD C,CIODEV_CONSOLE ; CONSOLE UNIT TO C + LD B,BF_CIOOUT ; HBIOS FUNC: OUTPUT CHAR + RST 08 ; HBIOS OUTPUTS CHARACTDR +; + ; RESTORE ALL REGISTERS + POP HL + POP DE + POP BC + POP AF + RET +; +; INPUT CHARACTER TO A +; +CIN: + ; SAVE INCOMING REGISTERS (AF IS OUTPUT) + PUSH BC + PUSH DE + PUSH HL +; + ; INPUT CHARACTER FROM CONSOLE VIA HBIOS + LD C,CIODEV_CONSOLE ; CONSOLE UNIT TO C + LD B,BF_CIOIN ; HBIOS FUNC: INPUT CHAR + RST 08 ; HBIOS READS CHARACTDR + LD A,E ; MOVE CHARACTER TO A FOR RETURN +; + ; RESTORE REGISTERS (AF IS OUTPUT) + POP HL + POP DE + POP BC + RET +; +; RETURN INPUT STATUS IN A (0 = NO CHAR, !=0 CHAR WAITING) +; +CST: + ; SAVE INCOMING REGISTERS (AF IS OUTPUT) + PUSH BC + PUSH DE + PUSH HL +; + ; GET CONSOLE INPUT STATUS VIA HBIOS + LD C,CIODEV_CONSOLE ; CONSOLE UNIT TO C + LD B,BF_CIOIST ; HBIOS FUNC: INPUT STATUS + RST 08 ; HBIOS RETURNS STATUS IN A +; + ; RESTORE REGISTERS (AF IS OUTPUT) + POP HL + POP DE + POP BC + RET +; +#ENDIF +; +#IF (PLATFORM == PLT_UNA) +; +; OUTPUT CHARACTER FROM A +; +COUT: + ; SAVE ALL INCOMING REGISTERS + PUSH AF + PUSH BC + PUSH DE + PUSH HL +; + ; OUTPUT CHARACTER TO CONSOLE VIA UBIOS + LD E,A + LD BC,$12 + RST 08 +; + ; RESTORE ALL REGISTERS + POP HL + POP DE + POP BC + POP AF + RET +; +; INPUT CHARACTER TO A +; +CIN: + ; SAVE INCOMING REGISTERS (AF IS OUTPUT) + PUSH BC + PUSH DE + PUSH HL +; + ; INPUT CHARACTER FROM CONSOLE VIA UBIOS + LD BC,$11 + RST 08 + LD A,E +; + ; RESTORE REGISTERS (AF IS OUTPUT) + POP HL + POP DE + POP BC + RET +; +; RETURN INPUT STATUS IN A (0 = NO CHAR, !=0 CHAR WAITING) +; +CST: + ; SAVE INCOMING REGISTERS (AF IS OUTPUT) + PUSH BC + PUSH DE + PUSH HL +; + ; GET CONSOLE INPUT STATUS VIA UBIOS + LD BC,$13 + RST 08 + LD A,E +; + ; RESTORE REGISTERS (AF IS OUTPUT) + POP HL + POP DE + POP BC + RET +; +#ENDIF +; +; READ A CONSOLE CHARACTER AND CONVERT TO UPPER CASE +; +CINUC: + CALL CIN + AND 7FH ; STRIP HI BIT + CP 'A' ; KEEP NUMBERS, CONTROLS + RET C ; AND UPPER CASE + CP 7BH ; SEE IF NOT LOWER CASE + RET NC + AND 5FH ; MAKE UPPER CASE + RET +; +;================================================================================================== +; FILL REMAINDER OF BANK +;================================================================================================== +; +SLACK: .EQU ($LDR_SIZ - $) + .FILL SLACK +; + .ECHO "LOADER space remaining: " + .ECHO SLACK + .ECHO " bytes.\n" +; +;================================================================================================== +; WORKING DATA STORAGE +;================================================================================================== +; + .ORG $8000 +; + .DS 64 ; 32 LEVEL STACK +BL_STACK .EQU $ ; ... TOP IS HERE +; +BL_COUNT .DS 1 ; LOAD COUNTER +BL_TIMEOUT .DS 2 ; AUTOBOOT TIMEOUT COUNTDOWN COUNTER +BL_BOOTID .DS 1 ; BOOT DEVICE ID CHOSEN BY USER +BL_DEVICE .DS 1 ; DEVICE TO LOAD FROM +BL_LU .DS 1 ; LU TO LOAD FROM +; +; BOOT INFO SECTOR IS READ INTO AREA BELOW +; THE THIRD SECTOR OF A DISK DEVICE IS RESERVED FOR BOOT INFO +; +BL_INFOSEC .EQU $ + .DS (512 - 128) +BB_METABUF .EQU $ +BB_SIG .DS 2 ; SIGNATURE (WILL BE 0A55AH IF SET) +BB_PLATFORM .DS 1 ; FORMATTING PLATFORM +BB_DEVICE .DS 1 ; FORMATTING DEVICE +BB_FORMATTER .DS 8 ; FORMATTING PROGRAM +BB_DRIVE .DS 1 ; PHYSICAL DISK DRIVE # +BB_LU .DS 1 ; LOGICAL UNIT (LU) + .DS 1 ; MSB OF LU, NOW DEPRECATED + .DS (BB_METABUF + 128) - $ - 32 +BB_PROTECT .DS 1 ; WRITE PROTECT BOOLEAN +BB_UPDATES .DS 2 ; UPDATE COUNTER +BB_RMJ .DS 1 ; RMJ MAJOR VERSION NUMBER +BB_RMN .DS 1 ; RMN MINOR VERSION NUMBER +BB_RUP .DS 1 ; RUP UPDATE NUMBER +BB_RTP .DS 1 ; RTP PATCH LEVEL +BB_LABEL .DS 16 ; 16 CHARACTER DRIVE LABEL +BB_TERM .DS 1 ; LABEL TERMINATOR ('$') +BB_BILOC .DS 2 ; LOC TO PATCH BOOT DRIVE INFO TO (IF NOT ZERO) +BB_CPMLOC .DS 2 ; FINAL RAM DESTINATION FOR CPM/CBIOS +BB_CPMEND .DS 2 ; END ADDRESS FOR LOAD +BB_CPMENT .DS 2 ; CP/M ENTRY POINT (CBIOS COLD BOOT) +; + .END