You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1091 lines
27 KiB

;
;==================================================================================================
; LOADER
;==================================================================================================
;
; INCLUDE GENERIC STUFF
;
#INCLUDE "std.asm"
;
; osimg.bin
;
;LDRIMG .EQU $0000 ;SIZE 0A00 > 0000-0A00
MONIMG .EQU $0A00 ;SIZE 1000 > 0A00-1A00
CPMIMG .EQU $1A00 ;SIZE 3000 > 1A00-4A00
ZSYSIMG .EQU $4A00 ;SIZE 3000 > 4A00-7A00
EGGIMG .EQU $7A00 ;SIZE 0200 > 7A00-7C00
;
; osimg1.bin
;
BASIMG .EQU $0000 ;SIZE 2000 > 0000-2000
TBCIMG .EQU $2000 ;SIZE 0900 > 2000-2900
;
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
CALL PRTALL
CALL PC_COLON
#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 'B' ; NASCOM BASIC
JP Z,GOBASIC
CP 'C' ; CP/M BOOT FROM ROM
JP Z,GOCPM
CP 'E' ; CP/M BOOT FROM ROM
JP Z,GOEASTA
CP 'M' ; MONITOR
JP Z,GOMONSER
; CP 'L' ; LIST DRIVES
; JP Z,GOLIST
CP 'T' ; TASTY BASIC
JP Z,GOTBAS
CP 'Z' ; ZSYSTEM BOOT FROM ROM
JP Z,GOZSYS
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 'B' ; NASCOM BASIC
JP Z,GOBASIC
CP 'C' ; CP/M BOOT FROM ROM
JP Z,GOCPM
CP 'E' ; CP/M BOOT FROM ROM
JP Z,GOEASTA
CP 'M' ; MONITOR
JP Z,GOMONSER
; CP 'L' ; LIST DRIVES
; JP Z,GOLIST
CP 'T' ; TASTY BASIC
JP Z,GOTBAS
CP 'Z' ; ZSYSTEM BOOT FROM ROM
JP Z,GOZSYS
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
;
GOBASIC:
LD DE,STR_BOOTBAS ; DE POINTS TO MESSAGE
CALL WRITESTR ; WRITE IT TO CONSOLE
; COPY BASIC FROM BASIC FROM OSIMG0 IN ROM BANK TO THIS RAM BANKS
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
LD HL,BAS_SIZ ; HL = COPY LEN = 1 PAGE = 256 BYTES
RST 08 ; DO IT
LD DE,STR_LOADING
CALL WRITESTR ; WRITE IT TO CONSOLE
LD B,BF_SYSBNKCPY ; HBIOS FUNC: PERFORM BANK COPY
LD HL,BASIMG ; COPY FROM
LD DE,BAS_LOC ; COPY TO
RST 08 ; DO IT
LD DE,STR_LAUNCH
CALL WRITESTR
LD HL,BAS_LOC
JP CHAIN
; LD HL,BAS_LOC ; FIRST BANK CODE
; PUSH HL
; LD DE,STR_BOOTBAS ; DE POINTS TO MESSAGE
; CALL WRITESTR ; WRITE IT TO CONSOLE
; ; COPY IMAGE TO EXEC ADDRESS
; LD HL,BASIMG ; HL := BASIC IMAGE ADDRESS
; LD DE,BAS_LOC ; DE := BASIC EXEC ADDRESS
; LD BC,BAS_SIZ ; BC := BASIC SIZE
; LDIR ; COPY BASIC CODE TO EXEC ADDRESS
; POP HL ; RECOVER ENTRY ADDRESS
; JR CHAIN ; AND CHAIN TO IT
GOEASTA:
LD HL,EGG_LOC
PUSH HL
LD DE,STR_LAUNCH ; DE POINTS TO MESSAGE
CALL WRITESTR ; WRITE IT TO CONSOLE
; COPY IMAGE TO EXEC ADDRESS
LD HL,EGGIMG ; HL := BASIC IMAGE ADDRESS
LD DE,EGG_LOC ; DE := BASIC EXEC ADDRESS
LD BC,EGG_SIZ ; BC := BASIC SIZE
LDIR ; COPY BASIC CODE TO EXEC ADDRESS
POP HL ; RECOVER ENTRY ADDRESS
JR CHAIN ; AND CHAIN TO IT
GOTBAS:
LD DE,STR_BOOTTBC ; DE POINTS TO MESSAGE
CALL WRITESTR ; WRITE IT TO CONSOLE
; COPY BASIC FROM BASIC FROM OSIMG0 IN ROM BANK TO THIS RAM BANKS
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
LD HL,TBC_SIZ ; HL = COPY LEN = 1 PAGE = 256 BYTES
RST 08 ; DO IT
LD DE,STR_LOADING
CALL WRITESTR ; WRITE IT TO CONSOLE
LD B,BF_SYSBNKCPY ; HBIOS FUNC: PERFORM BANK COPY
LD HL,TBCIMG ; COPY FROM
LD DE,TBC_LOC ; COPY TO
RST 08 ; DO IT
LD DE,STR_LAUNCH
CALL WRITESTR
LD HL,TBC_LOC
JP CHAIN
; LD HL,TBC_LOC ; FIRST BANK CODE
; PUSH HL
; LD DE,STR_BOOTTBC ; DE POINTS TO MESSAGE
; CALL WRITESTR ; WRITE IT TO CONSOLE
; ; COPY IMAGE TO EXEC ADDRESS
; LD HL,TBCIMG ; HL := BASIC IMAGE ADDRESS
; LD DE,TBC_LOC ; DE := BASIC EXEC ADDRESS
; LD BC,TBC_SIZ ; BC := BASIC SIZE
; LDIR ; COPY BASIC CODE TO EXEC ADDRESS
; POP HL ; RECOVER ENTRY ADDRESS
; JR CHAIN ; AND CHAIN TO IT
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 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_BOOTMON .DB "START MONITOR FROM ROM\r\n$"
STR_BOOTBAS .DB "START BASIC FROM ROM\r\n$"
STR_BOOTTBC .DB "START TASTYBASIC FROM ROM\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 "($"
;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_ITSRAM .DB "\r\n\RAM$"
STR_LAUNCH .DB "\r\nLaunching ...$"
;
STR_BANNER .DB "\r\n", PLATFORM_NAME, " Boot Loader$"
STR_BOOTMENU .DB "\r\n"
.DB "\r\nROM Boot: (B)ASIC, (C)PM, (M)onitor, (T)ASTYBASIC, (Z)System.\r\n"
.DB "Disk Boot: $"
;
.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