; ;================================================================================================== ; 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 ; ; BANNER LD DE,STR_BANNER CALL WRITESTR ; #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 JP DOBOOTMENU ; ;__DOBOOT________________________________________________________________________________________________________________________ ; ; PERFORM BOOT FRONT PANEL ACTION ;________________________________________________________________________________________________________________________________ ; DOBOOTMENU: CALL NEWLINE ; #IF (DSKYENABLE) LD HL,BOOT ; POINT TO BOOT MESSAGE CALL SEGDISPLAY ; 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 DE,MENU_S LD HL,MENU_V MENU_L: PUSH DE WRITE_M:PUSH BC PUSH HL PUSH DE POP HL LD BC,10 ADD HL,BC ; HL POINTS TO MENU KEY WRITEM1:LD A,(DE) CP '$' ; TEST FOR STRING TERMINATOR JP Z,WRITEM2 CP (HL) JR NZ,WRITEM3 LD A,'(' CALL COUT LD A,(DE) CALL COUT LD A,')' WRITEM3:CALL COUT INC DE JR WRITEM1 WRITEM2:POP HL POP BC POP DE EX DE,HL ADD HL,DE EX DE,HL 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 JP C,DB_INVALID CP '9' + 1 JP NC,DB_INVALID SUB '0' JP GOBOOTDISK MENU_X: CALL NEWLINE EX DE,HL ; WE HAVE A VALID ROM MENU OPTION INC HL LD E,(HL) INC HL LD D,(HL) EX DE,HL JP (HL) ; JUMP TO THE ROUTINE TO EXECUTE IT #DEFINE MENU_L(M1,M2,M3,M4,M5,M6,M7,M8,M9,M10) \ #DEFCONT \ .DB M1 #DEFCONT \ .DB M2 #DEFCONT \ .DW M3 #DEFCONT \ .DB M4 #DEFCONT \ .DW M5 #DEFCONT \ .DW M6 #DEFCONT \ .DW M7 #DEFCONT \ .DW M8 #DEFCONT \ .DB M9 #DEFCONT \ .DB M10 ; ; name menu exec source-bank dest-exec source-addr dest-addr img-size dest-bank desc ; DB DB DW DB DW DW DW DW DB DB MENU_S: MENU_L("MONITOR $$", "M", GOROM, BID_BIOSIMG, MON_SERIAL, 0A00h, MON_LOC, MON_SIZ, BID_USR, "Monitor$12345") MENU_1: MENU_L("CP/M $ $", "C", GOROM, BID_BIOSIMG, CPM_ENT, 1A00h, CPM_LOC, CPM_SIZ, BID_USR, "CP/M 80 2.2$ ") MENU_L("Z-SYSTEM $", "Z", GOROM, BID_BIOSIMG, CPM_ENT, 4A00h, CPM_LOC, CPM_SIZ, BID_USR, "ZSDOS V1.1 $ ") MENU_L("$ $", "E", GOROM, BID_BIOSIMG, EGG_LOC, 7A00h, EGG_LOC, EGG_SIZ, BID_USR, "Easter Egg $ ") MENU_L("FORTH $ $", "R", GOROMB, BID_OSIMG, FTH_LOC, 0000h, FTH_LOC, FTH_SIZ, BID_USR, "Camel Forth$ ") MENU_L("BASIC $ $", "B", GOROMB, BID_OSIMG, BAS_LOC, 1700h, BAS_LOC, BAS_SIZ, BID_USR, "Nascom BASIC$") MENU_L("T-BASIC $$", "T", GOROMB, BID_OSIMG, TBC_LOC, 3700h, TBC_LOC, TBC_SIZ, BID_USR, "Tasty BASIC$ ") #IF (DSKYENABLE) MENU_L("DSKY-MON $", "D", GOROM, BID_BIOSIMG, MON_DSKY, 0A00h, MON_LOC, MON_SIZ, BID_USR, DSKY Monitor$") #ENDIF MENU_E: MENU_V .EQU MENU_1-MENU_S ; LENGTH OF EACH MENU RECORD MENU_N .EQU (MENU_E-MENU_S)/MENU_V ; NUMBER OF MENU ITEMS ; ; BOOT OPTION PROCESSING ; DB_INVALID: LD DE,STR_INVALID CALL WRITESTR JP DOBOOTMENU ; GOROM: EX DE,HL INC HL ; HL POINTS TO source-bank ; LD A,(HL) ; CP BID_BIOSIMG ; JP Z,DOBOOTMENU; ONLY CURRENT BANK SUPPORTED LD B,4 ; GOROM_1:INC HL LD E,(HL) INC HL LD D,(HL) PUSH DE DJNZ GOROM_1 POP BC ; SIZE POP DE ; DEST POP HL ; SOURCE LDIR JR CHAIN GOROMB: EX DE,HL INC HL ; HL POINTS TO source-bank ; LD A,(HL) ; CP BID_BIOSIMG ; JP Z,DOBOOTMENU; ONLY CURRENT BANK SUPPORTED LD B,4 GOROMB1:INC HL LD E,(HL) INC HL LD D,(HL) PUSH DE DJNZ GOROMB1 POP HL ; SIZE LD B,BF_SYSSETCPY ; HBIOS FUNC: SETUP BANK COPY LD D,BID_USR ; D = DEST BANK = USER BANK LD E,BID_OSIMG ; E = SRC BANK = BIOS BANK RST 08 POP DE ; DEST POP HL ; SOURCE LD B,BF_SYSBNKCPY ; HBIOS FUNC: PERFORM BANK COPY RST 08 ; DO IT CHAIN: ; EXPECT 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 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 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 ; GOBOOTDISK: LD (BL_BOOTID),A LD DE,STR_BOOTDISK CALL WRITESTR ; JP BOOTDISK ; ; 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 CALL WRITESTR JP DOBOOTMENU DB_NOBOOT: ; DISK IS NOT BOOTABLE LD DE,STR_NOBOOT CALL WRITESTR JP DOBOOTMENU DB_ERR: ; I/O ERROR DURING BOOT ATTEMPT LD DE,STR_BOOTERR CALL WRITESTR JP DOBOOTMENU ; #IF (DSKYENABLE) ; ; ;__SEGDISPLAY________________________________________________________________________________________ ; ; DISPLAY CONTENTS OF DISPLAYBUF IN DECODED HEX BITS 0-3 ARE DISPLAYED DIG, BIT 7 IS DP ;____________________________________________________________________________________________________ ; SEGDISPLAY: PUSH AF ; STORE AF PUSH BC ; STORE BC PUSH HL ; STORE HL LD BC,0007H ADD HL,BC LD B,08H ; SET DIGIT COUNT LD A,40H | 30H ; SET CONTROL PORT 7218 TO OFF OUT (PPIC),A ; OUTPUT CALL DLY2 ; WAIT LD A,0F0H ; SET CONTROL TO 1111 (DATA COMING, HEX DECODE,NO DECODE, NORMAL) SEGDISPLAY1: ; OUT (PPIA),A ; OUTPUT TO PORT LD A,80H | 30H ; STROBE WRITE PULSE WITH CONTROL=1 OUT (PPIC),A ; OUTPUT TO PORT CALL DLY2 ; WAIT LD A,40H | 30H ; SET CONTROL PORT 7218 TO OFF OUT (PPIC),A ; OUTPUT SEGDISPLAY_LP: LD A,(HL) ; GET DISPLAY DIGIT OUT (PPIA),A ; OUT TO PPIA LD A,00H | 30H ; SET WRITE STROBE OUT (PPIC),A ; OUT TO PPIC CALL DLY2 ; DELAY LD A,40H | 30H ; SET CONTROL PORT OFF OUT (PPIC),A ; OUT TO PPIC CALL DLY2 ; WAIT DEC HL ; INC POINTER DJNZ SEGDISPLAY_LP ; LOOP FOR NEXT DIGIT POP HL ; RESTORE HL POP BC ; RESTORE BC POP AF ; RESTORE AF RET #ENDIF #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 DE,STR_PREFIX ; NEWLINE AND SPACING CALL WRITESTR ; 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 ; CALL PC_SPACE 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 DE,STR_PREFIX ; FORMATTING CALL WRITESTR ; 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 ; CALL PC_SPACE ; SPACING 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_LIST .DB "LIST DEVICES\r\n$" 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_DRVLIST .DB "\r\nDisk Devices:\r\n$" STR_PREFIX .DB "($" 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_LAUNCH .DB "\r\nLaunching ...$" STR_BANNER .DB "\r\n", PLATFORM_NAME, " Boot Loader" STR_NL .DB "\r\n$" ; .IF DSKYENABLE BOOT: ; . . t o o b .DB 00H, 00H, 80H, 80H, 094H, 09DH, 09DH, 09FH .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