; ;================================================================================================== ; LOADER ;================================================================================================== ; ; INCLUDE GENERIC STUFF ; #INCLUDE "std.asm" ; MONIMG .EQU $1000 CPMIMG .EQU $2000 ZSYSIMG .EQU $5000 ; 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 LD DE,STR_BOOTMENU CALL WRITESTR #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 DB_BOOTLOOP: ; ; CHECK FOR CONSOLE BOOT KEYPRESS ; CALL CST OR A JP Z,DB_CONEND CALL CINUC CP 'M' ; MONITOR JP Z,GOMONSER CP 'C' ; CP/M BOOT FROM ROM JP Z,GOCPM CP 'Z' ; ZSYSTEM BOOT FROM ROM JP Z,GOZSYS CP 'L' ; LIST DRIVES JP Z,GOLIST CP '0' ; 0-9, DISK DEVICE JP C,DB_INVALID CP '9' + 1 JP NC,DB_INVALID SUB '0' JP GOBOOTDISK DB_CONEND: ; ; CHECK FOR DSKY BOOT KEYPRESS ; #IF (DSKYENABLE) CALL KY_STAT ; GET KEY FROM KB INTO A OR A JP Z,DB_DSKYEND CALL KY_GET CP KY_GO ; GO = MONITOR JP Z,GOMONDSKY CP KY_BO ; BO = BOOT ROM JP Z,GOCPM ; CP 0AH ; A-F, DISK BOOT ; JP C,DB_INVALID CP 0FH + 1 ; 0-F, DISK BOOT ; JP NC,DB_INVALID ; SUB 0AH JP GOBOOTDISK ; LD HL,BOOT ; POINT TO BOOT MESSAGE ; LD A,00H ; BLANK OUT SELECTION,IT WAS INVALID ; LD (HL),A ; STORE IT IN DISPLAY BUFFER ; CALL SEGDISPLAY ; DISPLAY THE BUFFER DB_DSKYEND: #ENDIF ; ; IF CONFIGURED, CHECK FOR AUTOBOOT TIMEOUT ; #IF (BOOTTYPE == BT_AUTO) ; DELAY FOR 10MS TO MAKE TIMEOUT CALC EASY LD DE,625 ; 16US * 625 = 10MS CALL VDELAY ; CHECK/INCREMENT TIMEOUT LD BC,(BL_TIMEOUT) DEC BC LD (BL_TIMEOUT),BC LD A,B OR C JP NZ,DB_BOOTLOOP ; TIMEOUT EXPIRED, PERFORM DEFAULT BOOT ACTION LD A,BOOT_DEFAULT CP 'M' ; MONITOR JP Z,GOMON CP 'C' ; CP/M BOOT FROM ROM JP Z,GOCPM CP 'Z' ; ZSYSTEM BOOT FROM ROM JP Z,GOZSYS CP 'L' ; LIST DRIVES JP Z,GOLIST CP '0' ; 0-9, DISK DEVICE JP C,DB_INVALID CP '9' + 1 JP NC,DB_INVALID SUB '0' JP GOBOOTDISK #ENDIF JP DB_BOOTLOOP ; ; BOOT OPTION PROCESSING ; DB_INVALID: LD DE,STR_INVALID CALL WRITESTR JP DOBOOTMENU ; GOMONSER: LD HL,MON_SERIAL ; MONITOR SERIAL INTERFACE ENTRY ADDRESS TO HL JR GOMON ; LOAD AND RUN MONITOR ; GOMONDSKY: LD HL,MON_DSKY ; MONITOR DSKY INTERFACE ENTRY ADDRESS TO HL JR GOMON ; LOAD AND RUN MONITOR ; GOMON: LD DE,STR_BOOTMON ; DE POINTS TO MESSAGE CALL WRITESTR ; WRITE IT TO CONSOLE ; PUSH HL ; SAVE DESIRED MONITOR ENTRY ADDRESS ; ; COPY MONITOR IMAGE TO EXEC ADDRESS LD HL,MONIMG ; HL := MONITOR IMAGE ADDRESS LD DE,MON_LOC ; DE := MONITOR EXEC ADDRESS LD BC,MON_SIZ ; BC := MONITOR SIZE LDIR ; COPY MONITOR CODE TO EXEC ADDRESS ; POP HL ; RECOVER ENTRY ADDRESS JR CHAIN ; AND CHAIN TO IT ; GOCPM: LD DE,STR_BOOTCPM ; DE POINTS TO MESSAGE CALL WRITESTR ; WRITE IT TO CONSOLE LD HL,CPMIMG ; SET HL TO CPM IMAGE ADDRESS JR GOOS ; LOAD AND RUN OS ; GOZSYS: LD DE,STR_BOOTZSYS ; DE POINTS TO MESSAGE CALL WRITESTR ; WRITE IT TO CONSOLE LD HL,ZSYSIMG ; SET HL TO ZSYS IMAGE ADDRESS JR GOOS ; LOAD AND RUN OS ; GOOS: ; COPY OS IMAGE TO EXEC ADDRESS LD DE,CPM_LOC ; DE := MONITOR EXEC ADDRESS LD BC,CPM_SIZ ; BC := MONITOR SIZE LDIR ; COPY MONITOR CODE TO EXEC ADDRESS ; LD HL,CPM_ENT ;JR CHAIN ; CHAIN TO ENTRY ADDRESS IN USER BANK ; CHAIN: PUSH HL ; SAVE ENTRY ADDRESS ; #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 ; GOLIST: LD DE,STR_LIST CALL WRITESTR LD DE,STR_DRVLIST CALL WRITESTR CALL PRTALL JP DOBOOTMENU ; 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 COLON 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_COLON ; 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_BOOTMON .DB "START MONITOR\r\n$" STR_BOOTCPM .DB "BOOT CPM FROM ROM\r\n$" STR_BOOTZSYS .DB "BOOT ZSYSTEM FROM ROM\r\n$" 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 "\r\n $" 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$" STR_BOOTMENU .DB "\r\n" .DB "Boot: (C)PM, (Z)System, (M)onitor,\r\n" .DB " (L)ist disks, or Disk Unit # ===> $" ; .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 ($1000 - $) .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