mirror of https://github.com/wwarthen/RomWBW.git
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.
2131 lines
50 KiB
2131 lines
50 KiB
;
|
|
;==================================================================================================
|
|
; HBIOS
|
|
;==================================================================================================
|
|
;
|
|
; INCLUDE GENERIC STUFF
|
|
;
|
|
#INCLUDE "std.asm"
|
|
;
|
|
.ORG 0
|
|
;
|
|
;==================================================================================================
|
|
; NORMAL PAGE ZERO SETUP, RET/RETI/RETN AS APPROPRIATE
|
|
;==================================================================================================
|
|
;
|
|
.FILL (000H - $),0FFH ; RST 0
|
|
JP HB_START
|
|
.DW ROM_SIG
|
|
.FILL (008H - $),0FFH ; RST 8
|
|
JP HB_DISPATCH
|
|
.FILL (010H - $),0FFH ; RST 10
|
|
RET
|
|
.FILL (018H - $),0FFH ; RST 18
|
|
RET
|
|
.FILL (020H - $),0FFH ; RST 20
|
|
RET
|
|
.FILL (028H - $),0FFH ; RST 28
|
|
RET
|
|
.FILL (030H - $),0FFH ; RST 30
|
|
RET
|
|
.FILL (038H - $),0FFH ; INT
|
|
RETI
|
|
.FILL (066H - $),0FFH ; NMI
|
|
RETN
|
|
;
|
|
.FILL (070H - $),0FFH ; SIG STARTS AT $80
|
|
;
|
|
ROM_SIG:
|
|
.DB $76, $B5 ; 2 SIGNATURE BYTES
|
|
.DB 1 ; STRUCTURE VERSION NUMBER
|
|
.DB 7 ; ROM SIZE (IN MULTIPLES OF 4KB, MINUS ONE)
|
|
.DW NAME ; POINTER TO HUMAN-READABLE ROM NAME
|
|
.DW AUTH ; POINTER TO AUTHOR INITIALS
|
|
.DW DESC ; POINTER TO LONGER DESCRIPTION OF ROM
|
|
.DB 0, 0, 0, 0, 0, 0 ; RESERVED FOR FUTURE USE; MUST BE ZERO
|
|
;
|
|
NAME .DB "ROMWBW v", BIOSVER, ", ", TIMESTAMP, 0
|
|
AUTH .DB "WBW",0
|
|
DESC .DB "ROMWBW v", BIOSVER, ", Copyright 2015, Wayne Warthen, GNU GPL v3", 0
|
|
;
|
|
.FILL ($100 - $),$FF ; PAD REMAINDER OF PAGE ZERO
|
|
;
|
|
HCB .FILL $100,$FF ; RESERVED FOR HBIOS CONTROL BLOCK
|
|
;
|
|
;==================================================================================================
|
|
; HBIOS UPPER MEMORY PROXY (RELOCATED TO RUN IN TOP 2 PAGES OF CPU RAM)
|
|
;==================================================================================================
|
|
;
|
|
; THE FOLLOWING CODE IS RELOCATED TO THE TOP OF MEMORY TO HANDLE INVOCATION DISPATCHING
|
|
;
|
|
.FILL (HBX_IMG - $) ; FILL TO START OF PROXY IMAGE START
|
|
.ORG HBX_LOC ; ADJUST FOR RELOCATION
|
|
;
|
|
; MEMORY LAYOUT:
|
|
; HBIOS PROXY CODE $FE00 (256 BYTES)
|
|
; INTERRUPT VECTORS $FF00 (32 BYTES, 16 ENTRIES)
|
|
; HBIOS PROXY COPY BUFFER $FF20 (128 BYTES)
|
|
; HBIOS PROXY PRIVATE STACK $FFA0 (64 BYTES, 32 ENTRIES)
|
|
; HBIOS PROXY MGMT BLOCK $FFE0 (32 BYTES)
|
|
;
|
|
; DEFINITIONS
|
|
;
|
|
HBX_CODSIZ .EQU $100 ; 256 BYTE CODE SPACE
|
|
HBX_IVTSIZ .EQU $20 ; INT VECTOR TABLE SIZE (16 ENTRIES)
|
|
HBX_BUFSIZ .EQU $80 ; INTERBANK COPY BUFFER
|
|
HBX_STKSIZ .EQU $40 ; PRIVATE STACK SIZE
|
|
;
|
|
; HBIOS IDENTIFICATION DATA BLOCK
|
|
;
|
|
HBX_IDENT:
|
|
.DB 'W',~'W' ; MARKER
|
|
.DB RMJ << 4 | RMN ; FIRST BYTE OF VERSION INFO
|
|
.DB RUP << 4 | RTP ; SECOND BYTE OF VERSION INFO
|
|
;
|
|
;==================================================================================================
|
|
; HBIOS ENTRY FOR RST 08 PROCESSING
|
|
;==================================================================================================
|
|
;
|
|
HBX_INVOKE:
|
|
LD (HBX_STKSAV),SP ; SAVE ORIGINAL STACK FRAME
|
|
LD SP,HBX_STACK ; SETUP NEW STACK FRAME
|
|
|
|
LD A,(HB_CURBNK) ; GET CURRENT BANK
|
|
LD (HBX_INVBNK),A ; SETUP TO RESTORE AT EXIT
|
|
|
|
LD A,BID_BIOS ; HBIOS BANK
|
|
CALL HBX_BNKSEL ; SELECT IT
|
|
|
|
CALL HB_DISPATCH ; CALL HBIOS FUNCTION DISPATCHER
|
|
|
|
PUSH AF ; SAVE AF (FUNCTION RETURN)
|
|
LD A,$FF ; LOAD ORIGINAL BANK ($FF IS REPLACED AT ENTRY)
|
|
HBX_INVBNK .EQU $ - 1
|
|
CALL HBX_BNKSEL ; SELECT IT
|
|
POP AF ; RESTORE AF
|
|
|
|
LD SP,0 ; RESTORE ORIGINAL STACK FRAME
|
|
HBX_STKSAV .EQU $ - 2
|
|
|
|
RET ; RETURN TO CALLER
|
|
;
|
|
;;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
|
;; SETBNK - Switch Memory Bank to Bank in A.
|
|
;; Preserve all Registers including Flags.
|
|
;; Does NOT update current bank.
|
|
;;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
|
;
|
|
HBX_BNKSEL:
|
|
LD (HB_CURBNK),A ; RECORD NEW CURRENT BANK
|
|
;
|
|
#IF ((PLATFORM == PLT_SBC) | (PLATFORM == PLT_ZETA))
|
|
OUT (MPCL_ROM),A ; SET ROM PAGE SELECTOR
|
|
OUT (MPCL_RAM),A ; SET RAM PAGE SELECTOR
|
|
RET ; DONE
|
|
#ENDIF
|
|
#IF (PLATFORM == PLT_ZETA2)
|
|
BIT 7,A ; BIT 7 SET REQUESTS RAM PAGE
|
|
JR Z,HBX_ROM ; NOT SET, SELECT ROM PAGE
|
|
RES 7,A ; RAM PAGE REQUESTED: CLEAR ROM BIT
|
|
ADD A,16 ; ADD 16 x 32K - RAM STARTS FROM 512K
|
|
;
|
|
HBX_ROM:
|
|
RLCA ; TIMES 2 - GET 16K PAGE INSTEAD OF 32K
|
|
OUT (MPGSEL_0),A ; BANK_0: 0K - 16K
|
|
INC A ;
|
|
OUT (MPGSEL_1),A ; BANK_1: 16K - 32K
|
|
RET ; DONE
|
|
#ENDIF
|
|
#IF (PLATFORM == PLT_N8)
|
|
BIT 7,A ; TEST BIT 7 FOR RAM VS. ROM
|
|
JR Z,HBX_ROM ; IF NOT SET, SELECT ROM PAGE
|
|
;
|
|
HBX_RAM:
|
|
RES 7,A ; CLEAR BIT 7 FROM ABOVE
|
|
RLCA ; SCALE SELECTOR TO
|
|
RLCA ; ... GO FROM Z180 4K PAGE SIZE
|
|
RLCA ; ... TO DESIRED 32K PAGE SIZE
|
|
OUT0 (Z180_BBR),A ; WRITE TO BANK BASE
|
|
LD A,N8_DEFACR | 80H ; SELECT RAM BY SETTING BIT 7
|
|
OUT0 (N8_ACR),A ; ... IN N8 ACR REGISTER
|
|
RET ; DONE
|
|
;
|
|
HBX_ROM:
|
|
OUT0 (N8_RMAP),A ; BANK INDEX TO N8 RMAP REGISTER
|
|
XOR A ; ZERO ACCUM
|
|
OUT0 (Z180_BBR),A ; ZERO BANK BASE
|
|
LD A,N8_DEFACR ; SELECT ROM BY CLEARING BIT 7
|
|
OUT0 (N8_ACR),A ; ... IN N8 ACR REGISTER
|
|
RET ; DONE
|
|
;
|
|
#ENDIF
|
|
#IF (PLATFORM == PLT_MK4)
|
|
RLCA ; RAM FLAG TO CARRY FLAG AND BIT 0
|
|
JR NC,HBX_BNKSEL1 ; IF NC, WANT ROM PAGE, SKIP AHEAD
|
|
XOR %00100001 ; SET BIT FOR HI 512K, CLR BIT 0
|
|
HBX_BNKSEL1:
|
|
RLCA ; CONTINUE SHIFTING TO SCALE SELECTOR
|
|
RLCA ; FOR Z180 4K PAGE -> DESIRED 32K PAGE
|
|
OUT0 (Z180_BBR),A ; WRITE TO BANK BASE
|
|
RET ; DONE
|
|
#ENDIF
|
|
;
|
|
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
|
; Copy Data - Possibly between banks. This resembles CP/M 3, but
|
|
; usage of the HL and DE registers is reversed.
|
|
; Caller MUST ensure stack is already in high memory.
|
|
; Enter:
|
|
; HL = Source Address
|
|
; DE = Destination Address
|
|
; BC = Number of bytes to copy
|
|
; Exit : None
|
|
; Uses : AF,BC,DE,HL
|
|
;
|
|
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
|
;
|
|
HBX_BNKCPY:
|
|
; Save current bank to restore at end
|
|
LD A,(HB_CURBNK)
|
|
LD (HBX_CPYBNK),A
|
|
|
|
; Setup for copy loop
|
|
LD (HB_SRCADR),HL ; Init working source adr
|
|
LD (HB_DSTADR),DE ; Init working dest adr
|
|
LD H,B ; Move bytes to copy from BC
|
|
LD L,C ; ... to HL to use as byte counter
|
|
;
|
|
HBX_BNKCPY2:
|
|
; Copy loop
|
|
LD A,L ; Low byte of count to A
|
|
AND $7F ; Isolate bits relevant to 128 byte buf
|
|
LD BC,$80 ; Assume full buf copy
|
|
JR Z,HBX_BNKCPY3 ; If full buf copy, go do it
|
|
LD C,A ; Otherwise, BC := bytes to copy
|
|
;
|
|
HBX_BNKCPY3:
|
|
PUSH HL ; Save bytes left to copy
|
|
CALL HBX_BNKCPY4 ; Do it
|
|
POP HL ; Recover bytes left to copy
|
|
XOR A ; Clear CF
|
|
SBC HL,BC ; Reflect bytes copied in HL
|
|
JR NZ,HBX_BNKCPY2 ; If any left, then loop
|
|
LD A,$FF ; Load original bank ($FF is replaced at entry)
|
|
HBX_CPYBNK .EQU $ - 1
|
|
|
|
JR HBX_BNKSEL ; Select and return
|
|
;
|
|
HBX_BNKCPY4: ; Switch to source bank
|
|
LD A,(HB_SRCBNK) ; Get source bank
|
|
CALL HBX_BNKSEL ; Set source bank
|
|
;
|
|
; Copy BC bytes from HL -> BUF, allow HL to increment
|
|
PUSH BC ; Save copy length
|
|
LD HL,(HB_SRCADR) ; Point to source adr
|
|
LD DE,HBX_BUF ; Setup buffer as interim destination
|
|
LDIR ; Copy BC bytes: src -> buffer
|
|
LD (HB_SRCADR),HL ; Update source adr
|
|
POP BC ; Recover copy length
|
|
;
|
|
; Switch to dest bank
|
|
LD A,(HB_DSTBNK) ; Get destination bank
|
|
CALL HBX_BNKSEL ; Set destination bank
|
|
;
|
|
; Copy BC bytes from BUF -> HL, allow DE to increment
|
|
PUSH BC ; Save copy length
|
|
LD HL,HBX_BUF ; Use the buffer as source now
|
|
LD DE,(HB_DSTADR) ; Setup final destination for copy
|
|
LDIR ; Copy BC bytes: buffer -> dest
|
|
LD (HB_DSTADR),DE ; Update dest adr
|
|
POP BC ; Recover copy length
|
|
;
|
|
RET ; Done
|
|
;
|
|
; Call a routine in another bank saving and restoring the original bank.
|
|
; Caller MUST ensure stack is already in high memory.
|
|
; On input A=target bank, HL=target address
|
|
;
|
|
HBX_BNKCALL:
|
|
LD (HBX_TGTBNK),A ; stuff target bank to call into code below
|
|
LD (HBX_TGTADR),HL ; stuff address to call into code below
|
|
LD A,(HB_CURBNK) ; get current bank
|
|
PUSH AF ; save for return
|
|
HBX_TGTBNK .EQU $ + 1
|
|
LD A,$FF ; load bank to call ($FF overlaid at entry)
|
|
CALL HBX_BNKSEL ; activate the new bank
|
|
HBX_TGTADR .EQU $ + 1
|
|
CALL $FFFF ; call routine ($FFFF is overlaid above)
|
|
EX (SP),HL ; save hl and get bank to restore in hl
|
|
PUSH AF ; save af
|
|
LD A,H ; bank to restore to a
|
|
CALL HBX_BNKSEL ; restore it
|
|
POP AF ; recover af
|
|
POP HL ; recover hl
|
|
RET
|
|
;
|
|
; INTERRUPT HANDLER DISPATCHING
|
|
;
|
|
INT_TIMER: ; TIMER INTERRUPT HANDLER
|
|
PUSH HL ; SAVE HL
|
|
LD HL,HB_TIMINT ; HL := INT ADR IN BIOS
|
|
JR HBX_INT ; GO TO ROUTING CODE
|
|
;
|
|
INT_BAD: ; BAD INTERRUPT HANDLER
|
|
PUSH HL ; SAVE HL
|
|
LD HL,HB_BADINT
|
|
JR HBX_INT
|
|
;
|
|
; COMMON INTERRUPT DISPATCHING CODE
|
|
; SETUP AND CALL HANDLER IN BIOS BANK
|
|
;
|
|
HBX_INT: ; COMMON INTERRUPT ROUTING CODE
|
|
;
|
|
; SAVE STATE (ASSUMES HL SAVED PREVIOUSLY)
|
|
PUSH AF ; SAVE AF
|
|
PUSH BC ; SAVE BC
|
|
PUSH DE ; SAVE DE
|
|
|
|
; ACTIVATE BIOS BANK
|
|
#IF ((PLATFORM == PLT_SBC) | (PLATFORM == PLT_ZETA))
|
|
LD A,BID_BIOS ; BIOS PAGE INDEX TO ACCUM
|
|
OUT (MPCL_ROM),A ; SET ROM PAGE SELECTOR
|
|
OUT (MPCL_RAM),A ; SET RAM PAGE SELECTOR
|
|
#ENDIF
|
|
#IF (PLATFORM == PLT_ZETA2)
|
|
LD A,(BID_BIOS - $80 + $10) * 2 ; BIOS BID -> PAGE INDEX -> A
|
|
OUT (MPGSEL_0),A ; BANK_0: 0K - 16K
|
|
INC A ;
|
|
OUT (MPGSEL_1),A ; BANK_1: 16K - 32K
|
|
#ENDIF
|
|
#IF (PLATFORM == PLT_N8)
|
|
LD A,(BID_BIOS << 3) & $FF ; BIOS BID -> BBR VAL -> A
|
|
OUT0 (Z180_BBR),A ; WRITE TO Z180 BANK BASE REG
|
|
LD A,N8_DEFACR | $80 ; BIT 7 SET FOR RAM
|
|
OUT0 (N8_ACR),A ; WRITE TO N8 ACR
|
|
#ENDIF
|
|
#IF (PLATFORM == PLT_MK4)
|
|
LD A,(BID_BIOS << 3) & $FF | $80 ; BIOS BID -> PAGE INDEX -> A
|
|
OUT0 (Z180_BBR),A ; WRITE TO Z180 BANK BASE REG
|
|
#ENDIF
|
|
|
|
; SETUP INTERRUPT PROCESSING STACK IN HBIOS
|
|
LD (HB_INTSTKSAV),SP ; SAVE STACK POINTER
|
|
LD SP,HB_INTSTK ; SWITCH TO INTERRUPT STACK
|
|
|
|
; DO THE REAL WORK
|
|
CALL JPHL ; CALL INTERRUPT ROUTINE
|
|
|
|
; RESTORE STACK
|
|
LD SP,(HB_INTSTKSAV) ; RESTORE STACK
|
|
|
|
; RESTORE BANK
|
|
LD A,(HB_CURBNK) ; GET PRE-INT BANK
|
|
;
|
|
#IF ((PLATFORM == PLT_SBC) | (PLATFORM == PLT_ZETA))
|
|
OUT (MPCL_ROM),A ; SET ROM PAGE SELECTOR
|
|
OUT (MPCL_RAM),A ; SET RAM PAGE SELECTOR
|
|
#ENDIF
|
|
#IF (PLATFORM == PLT_ZETA2)
|
|
BIT 7,A ; BIT 7 SET REQUESTS RAM PAGE
|
|
JR Z,HBX_INT1 ; NOT SET, SELECT ROM PAGE
|
|
RES 7,A ; RAM PAGE REQUESTED: CLEAR ROM BIT
|
|
ADD A,16 ; ADD 16 x 32K - RAM STARTS FROM 512K
|
|
;
|
|
HBX_INT1:
|
|
RLCA ; TIMES 2 - GET 16K PAGE INSTEAD OF 32K
|
|
OUT (MPGSEL_0),A ; BANK_0: 0K - 16K
|
|
INC A ;
|
|
OUT (MPGSEL_1),A ; BANK_1: 16K - 32K
|
|
#ENDIF
|
|
#IF (PLATFORM == PLT_N8)
|
|
BIT 7,A ; TEST BIT 7 FOR RAM VS. ROM
|
|
JR Z,HBX_INT1 ; IF NOT SET, SELECT ROM PAGE
|
|
;
|
|
RES 7,A ; CLEAR BIT 7 FOR RAM VS. ROM
|
|
RLCA ; SCALE SELECTOR TO
|
|
RLCA ; ... GO FROM Z180 4K PAGE SIZE
|
|
RLCA ; ... TO DESIRED 32K PAGE SIZE
|
|
OUT0 (Z180_BBR),A ; WRITE TO BANK BASE
|
|
JR HBX_INT2 ; CONTINUE
|
|
;
|
|
HBX_INT1: ; SELECT ROM PAGE
|
|
XOR A ; ZERO ACCUM
|
|
OUT0 (Z180_BBR),A ; ZERO BANK BASE
|
|
LD A,N8_DEFACR ; SELECT ROM BY CLEARING BIT 7
|
|
OUT0 (N8_ACR),A ; ... IN N8 ACR REGISTER
|
|
;
|
|
HBX_INT2:
|
|
#ENDIF
|
|
#IF (PLATFORM == PLT_MK4)
|
|
RLCA ; RAM FLAG TO CARRY AND BIT 0
|
|
JR NC,HBX_INT1 ; IF NC, ROM, SKIP AHEAD
|
|
XOR %00100001 ; SET BIT FOR HI 512K, CLR BIT 0
|
|
HBX_INT1:
|
|
RLCA ; ROTATE
|
|
RLCA ; ... AGAIN
|
|
OUT0 (Z180_BBR),A ; WRITE TO BANK REGISTER
|
|
#ENDIF
|
|
;
|
|
; RESTORE STATE
|
|
POP DE ; RESTORE DE
|
|
POP BC ; RESTORE BC
|
|
POP AF ; RESTORE AF
|
|
POP HL ; RESTORE HL
|
|
|
|
; DONE
|
|
RETI ; IMPLICITLY REENABLES INTERRUPTS!
|
|
;
|
|
; FILLER FOR UNUSED HBIOS PROXY CODE SPACE
|
|
; PAD TO START OF INTERRUPT VECTOR TABLE
|
|
;
|
|
HBX_SLACK .EQU (HBX_LOC + HBX_CODSIZ - $)
|
|
.ECHO "HBIOS PROXY space remaining: "
|
|
.ECHO HBX_SLACK
|
|
.ECHO " bytes.\n"
|
|
.FILL HBX_SLACK,$FF
|
|
;
|
|
; HBIOS INTERRUPT VECTOR TABLE (16 ENTRIES)
|
|
;
|
|
HBX_IVT:
|
|
.DW INT_TIMER
|
|
.DW INT_BAD
|
|
.DW INT_BAD
|
|
.DW INT_BAD
|
|
.DW INT_BAD
|
|
.DW INT_BAD
|
|
.DW INT_BAD
|
|
.DW INT_BAD
|
|
.DW INT_BAD
|
|
.DW INT_BAD
|
|
.DW INT_BAD
|
|
.DW INT_BAD
|
|
.DW INT_BAD
|
|
.DW INT_BAD
|
|
.DW INT_BAD
|
|
.DW INT_BAD
|
|
;
|
|
; INTERBANK COPY BUFFER (128 BYTES)
|
|
;
|
|
HBX_BUF .FILL HBX_BUFSIZ,0
|
|
;
|
|
; PRIVATE STACK (64 BYTES, 32 ENTRIES)
|
|
;
|
|
.FILL HBX_STKSIZ,$FF
|
|
HBX_STACK .EQU $
|
|
;
|
|
; HBIOS PROXY MGMT BLOCK (TOP 32 BYTES)
|
|
;
|
|
.DB BID_BOOT ; CURRENTLY ACTIVE LOW MEMORY BANK ID
|
|
.DB $FF ; DEPRECATED!!!
|
|
.DW 0 ; BNKCPY SOURCE ADDRESS
|
|
.DB BID_USR ; BNKCPY SOURCE BANK ID
|
|
.DW 0 ; BNKCPY DESTINATION ADDRESS
|
|
.DB BID_USR ; BNKCPY DESTINATION BANK ID
|
|
.FILL 8,0 ; FILLER, RESERVED FOR FUTURE HBIOS USE
|
|
JP HBX_INVOKE ; FIXED ADR ENTRY FOR HBX_INVOKE (ALT FOR RST 08)
|
|
JP HBX_BNKSEL ; FIXED ADR ENTRY FOR HBX_BNKSEL
|
|
JP HBX_BNKCPY ; FIXED ADR ENTRY FOR HBX_BNKCPY
|
|
JP HBX_BNKCALL ; FIXED ADR ENTRY FOR HBX_BNKCALL
|
|
.DW HBX_IDENT ; ADDRESS OF HBIOS PROXY START
|
|
.DW HBX_IDENT ; ADDRESS OF HBIOS IDENT INFO DATA BLOCK
|
|
;
|
|
.FILL $MEMTOP - $ ; FILL TO END OF MEMORY (AS NEEDED)
|
|
.ORG HBX_IMG + HBX_SIZ ; RESET ORG
|
|
;
|
|
;==================================================================================================
|
|
; HBIOS CORE
|
|
;==================================================================================================
|
|
;
|
|
;
|
|
;==================================================================================================
|
|
; ENTRY VECTORS (JUMP TABLE)
|
|
;==================================================================================================
|
|
;
|
|
JP HB_START ; HBIOS INITIALIZATION
|
|
JP HB_DISPATCH ; VECTOR TO DISPATCHER
|
|
;
|
|
;==================================================================================================
|
|
; SYSTEM INITIALIZATION
|
|
;==================================================================================================
|
|
;
|
|
HB_START:
|
|
;
|
|
#IF ((PLATFORM == PLT_N8) | (PLATFORM == PLT_MK4))
|
|
; SET BASE FOR CPU IO REGISTERS
|
|
LD A,Z180_BASE
|
|
OUT0 (Z180_ICR),A
|
|
|
|
; DISABLE REFRESH
|
|
XOR A
|
|
OUT0 (Z180_RCR),A
|
|
|
|
; SET DEFAULT WAIT STATES TO ACCURATELY MEASURE CPU SPEED
|
|
LD A,$F0
|
|
OUT0 (Z180_DCNTL),A
|
|
|
|
#IF (Z180_CLKDIV >= 1)
|
|
; SET CLOCK DIVIDE TO 1 RESULTING IN FULL XTAL SPEED
|
|
LD A,$80
|
|
OUT0 (Z180_CCR),A
|
|
#ENDIF
|
|
|
|
#IF (Z180_CLKDIV >= 2)
|
|
; SET CPU MULTIPLIER TO 1 RESULTING IN XTAL * 2 SPEED
|
|
LD A,$80
|
|
OUT0 (Z180_CMR),A
|
|
#ENDIF
|
|
|
|
#ENDIF
|
|
;
|
|
CALL HB_CPUSPD ; CPU SPEED DETECTION
|
|
;
|
|
#IF ((PLATFORM == PLT_N8) | (PLATFORM == PLT_MK4))
|
|
;
|
|
; SET DESIRED WAIT STATES
|
|
LD A,0 + (Z180_MEMWAIT << 6) | (Z180_IOWAIT << 4)
|
|
OUT0 (Z180_DCNTL),A
|
|
;
|
|
#ENDIF
|
|
;
|
|
CALL DELAY_INIT ; INITIALIZE SPEED COMPENSATED DELAY FUNCTIONS
|
|
;
|
|
; ANNOUNCE HBIOS
|
|
;
|
|
;
|
|
; DISPLAY THE PRE-INITIALIZATION BANNER
|
|
;
|
|
CALL NEWLINE
|
|
CALL NEWLINE
|
|
PRTX(STR_BANNER)
|
|
CALL NEWLINE
|
|
CALL NEWLINE
|
|
PRTX(STR_PLATFORM)
|
|
PRTS(" @ $")
|
|
LD HL,(HCB + HCB_CPUKHZ)
|
|
CALL PRTD3M ; PRINT AS DECIMAL WITH 3 DIGIT MANTISSA
|
|
PRTS("MHz ROM=$")
|
|
LD HL,ROMSIZE
|
|
CALL PRTDEC
|
|
PRTS("KB RAM=$")
|
|
LD HL,RAMSIZE
|
|
CALL PRTDEC
|
|
PRTS("KB$")
|
|
;
|
|
; INITIALIZE HEAP STORAGE VARIABLES
|
|
;
|
|
LD DE,HB_END ; GET ADDRESS OF START OF HEAP
|
|
;
|
|
; HEAP STARTS AT END OF HBIOS
|
|
LD HL,HCB + HCB_HEAP ; POINT TO HEAP START ADDRESS VARIABLE
|
|
LD (HL),E ; SAVE LSB
|
|
INC HL ; BUMP
|
|
LD (HL),D ; SAVE MSB
|
|
;
|
|
; INIT HEAP TOP TO HEAP START
|
|
LD HL,HCB + HCB_HEAPTOP ; POINT TO HEAP TOP ADDRESS VARIABLE
|
|
LD (HL),E ; SAVE LSB
|
|
INC HL ; BUMP
|
|
LD (HL),D ; SAVE MSB
|
|
;
|
|
; CLEAR HEAP
|
|
LD HL,HB_END ; START OF HEAP
|
|
LD BC,BNKTOP - HB_END ; MAX SIZE OF HEAP
|
|
LD A,$FF ; FILL WITH $FF
|
|
CALL FILL ; DO IT
|
|
;
|
|
; PERFORM DEVICE INITIALIZATION
|
|
;
|
|
LD B,HB_INITTBLLEN
|
|
LD DE,HB_INITTBL
|
|
INITSYS1:
|
|
CALL NEWLINE
|
|
LD A,(DE)
|
|
LD L,A
|
|
INC DE
|
|
LD A,(DE)
|
|
LD H,A
|
|
INC DE
|
|
PUSH DE
|
|
PUSH BC
|
|
CALL JPHL
|
|
POP BC
|
|
POP DE
|
|
DJNZ INITSYS1
|
|
;
|
|
; PRIOR TO THIS POINT, CONSOLE I/O WAS DIRECTED TO HARDWARE (XIO.ASM).
|
|
; NOW THAT HBIOS IS READY, SET THE CONSOLE UNIT TO ACTIVATE CONSOLE I/O
|
|
; VIA HBIOS.
|
|
;
|
|
XOR A ; CONSOLE DEVICE IS UNIT #0 BY FIAT
|
|
LD (HCB + HCB_CONDEV),A ; SAVE IT, ACTIVATES CONSOLE ON HBIOS
|
|
;
|
|
; NOW SWITCH TO CRT CONSOLE IF CONFIGURED
|
|
;
|
|
#IF CRTACT
|
|
;
|
|
; IF PLATFORM HAS A CONFIG JUMPER, CHECK TO SEE IF IT IS JUMPERED.
|
|
; IF SO, BYPASS SWITCH TO CRT CONSOLE (FAILSAFE MODE)
|
|
;
|
|
#IF ((PLATFORM != PLT_N8) & (PLATFORM != PLT_MK4))
|
|
IN A,(RTC) ; RTC PORT, BIT 6 HAS STATE OF CONFIG JUMPER
|
|
BIT 6,A ; BIT 6 HAS CONFIG JUMPER STATE
|
|
JR Z,INITSYS2 ; Z=SHORTED, BYPASS CONSOLE SWITCH
|
|
#ENDIF
|
|
;
|
|
; NOTIFY USER OF CONSOLE SWITCH ON BOOT CONSOLE
|
|
CALL NEWLINE
|
|
CALL NEWLINE
|
|
PRTX(STR_SWITCH)
|
|
CALL NEWLINE
|
|
;
|
|
; SWITCH TO CRT CONSOLE
|
|
LD A,(HCB + HCB_CRTDEV) ; GET CRT DISPLAY DEVICE
|
|
LD (HCB + HCB_CONDEV),A ; SAVE IT AS ACTIVE CONSOLE DEVICE
|
|
;
|
|
; DISPLAY HBIOS BANNER ON NEW CONSOLE
|
|
CALL NEWLINE
|
|
CALL NEWLINE
|
|
PRTX(STR_BANNER)
|
|
CALL NEWLINE
|
|
#ENDIF
|
|
;
|
|
INITSYS2:
|
|
RET
|
|
;
|
|
;==================================================================================================
|
|
; TABLE OF INITIALIZATION ENTRY POINTS
|
|
;==================================================================================================
|
|
;
|
|
HB_INITTBL:
|
|
#IF (UARTENABLE)
|
|
.DW UART_INIT
|
|
#ENDIF
|
|
#IF (ASCIENABLE)
|
|
.DW ASCI_INIT
|
|
#ENDIF
|
|
#IF (SIMRTCENABLE)
|
|
.DW SIMRTC_INIT
|
|
#ENDIF
|
|
#IF (DSRTCENABLE)
|
|
.DW DSRTC_INIT
|
|
#ENDIF
|
|
#IF (VDUENABLE)
|
|
.DW VDU_INIT
|
|
#ENDIF
|
|
#IF (CVDUENABLE)
|
|
.DW CVDU_INIT
|
|
#ENDIF
|
|
#IF (UPD7220ENABLE)
|
|
.DW UPD7220_INIT
|
|
#ENDIF
|
|
#IF (SCGENABLE)
|
|
.DW SCG_INIT
|
|
#ENDIF
|
|
#IF (DSKYENABLE)
|
|
.DW DSKY_INIT
|
|
#ENDIF
|
|
#IF (MDENABLE)
|
|
.DW MD_INIT
|
|
#ENDIF
|
|
#IF (FDENABLE)
|
|
.DW FD_INIT
|
|
#ENDIF
|
|
#IF (RFENABLE)
|
|
.DW RF_INIT
|
|
#ENDIF
|
|
#IF (IDEENABLE)
|
|
.DW IDE_INIT
|
|
#ENDIF
|
|
#IF (PPIDEENABLE)
|
|
.DW PPIDE_INIT
|
|
#ENDIF
|
|
#IF (SDENABLE)
|
|
.DW SD_INIT
|
|
#ENDIF
|
|
#IF (HDSKENABLE)
|
|
.DW HDSK_INIT
|
|
#ENDIF
|
|
#IF (PRPENABLE)
|
|
.DW PRP_INIT
|
|
#ENDIF
|
|
#IF (PPPENABLE)
|
|
.DW PPP_INIT
|
|
#ENDIF
|
|
#IF (PPKENABLE)
|
|
.DW PPK_INIT
|
|
#ENDIF
|
|
#IF (KBDENABLE)
|
|
.DW KBD_INIT
|
|
#ENDIF
|
|
;
|
|
HB_INITTBLLEN .EQU (($ - HB_INITTBL) / 2)
|
|
;
|
|
;==================================================================================================
|
|
; IDLE
|
|
;==================================================================================================
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
;
|
|
IDLE:
|
|
PUSH AF
|
|
PUSH BC
|
|
PUSH DE
|
|
PUSH HL
|
|
#IF (FDENABLE)
|
|
CALL FD_IDLE
|
|
#ENDIF
|
|
POP HL
|
|
POP DE
|
|
POP BC
|
|
POP AF
|
|
RET
|
|
;
|
|
;==================================================================================================
|
|
; BIOS FUNCTION DISPATCHER
|
|
;==================================================================================================
|
|
;
|
|
; MAIN BIOS FUNCTION
|
|
; B: FUNCTION
|
|
;__________________________________________________________________________________________________
|
|
;
|
|
HB_DISPATCH:
|
|
;
|
|
#IF 1 ; *DEBUG* START
|
|
;
|
|
CALL HB_DISPCALL ; DO THE WORK
|
|
;
|
|
; CHECK STACK INTEGRITY
|
|
PUSH AF
|
|
LD A,(HBX_STACK - HBX_STKSIZ + $08)
|
|
CP $FF
|
|
CALL NZ,PANIC
|
|
POP AF
|
|
RET
|
|
HB_DISPCALL:
|
|
;
|
|
#ENDIF ; *DEBUG* END
|
|
;
|
|
LD A,B ; REQUESTED FUNCTION IS IN B
|
|
CP BF_CIO + $10 ; $00-$0F: CHARACTER I/O
|
|
JP C,CIO_DISPATCH
|
|
CP BF_DIO + $10 ; $10-$1F: DISK I/O
|
|
JP C,DIO_DISPATCH
|
|
CP BF_RTC + $10 ; $20-$2F: REAL TIME CLOCK (RTC)
|
|
JP C,RTC_DISPATCH
|
|
CP BF_EMU + $10 ; $30-$3F: EMULATION
|
|
CALL C,PANIC ; OBSOLETE!
|
|
CP BF_VDA + $10 ; $40-$4F: VIDEO DISPLAY ADAPTER
|
|
JP C,VDA_DISPATCH
|
|
|
|
CP BF_SYS ; SKIP TO BF_SYS VALUE AT $F0
|
|
CALL C,PANIC ; PANIC IF LESS THAN BF_SYS
|
|
JP SYS_DISPATCH ; OTHERWISE SYS CALL
|
|
CALL PANIC ; THIS SHOULD NEVER BE REACHED
|
|
;
|
|
;==================================================================================================
|
|
; CHARACTER I/O DEVICE DISPATCHER
|
|
;==================================================================================================
|
|
;
|
|
; ROUTE CALL TO SPECIFIED CHARACTER I/O DRIVER
|
|
; B: FUNCTION
|
|
; C: UNIT NUMBER
|
|
;
|
|
CIO_DISPATCH:
|
|
;
|
|
; ON ENTRY C IS HBIOS UNIT # (INDEX INTO CIO_TBL OF CHARACTER DEVICES)
|
|
; USE UNIT # IN C TO LOOKUP CIO_TBL ENTRY, THEN
|
|
; CONVERT C TO THE DEVICE/DRIVER SPECIFIC UNIT ID
|
|
; AND GET THE DEVICE TYPE TO A FOR DRIVER DISPATCHING
|
|
;
|
|
LD A,C ; INCOMING UNIT INDEX TO A
|
|
PUSH HL ; SAVE INCOMING HL
|
|
LD HL,CIO_CNT ; HL := ADDRESS OF TABLE ENTRY COUNT PREFIX
|
|
CP (HL) ; COMPARE TO INCOMING ENTRY INDEX
|
|
JR C,CIO_DISPATCH1 ; UNIT OK, PROCEED
|
|
CP CIODEV_CONSOLE ; CHECK FOR SPECIAL VALUE - CONSOLE OUTPUT
|
|
JR Z,CIO_DISPATCH_CON ; DO IT
|
|
;CP CIODEV_VDA ; CHECK FOR SPECIAL VALUE - VDA OUTPUT
|
|
;JR Z,CIO_DISPATCH_VDA ; DO IT
|
|
;
|
|
; NOT GOOD, INCOMING UNIT IS OUT OF RANGE
|
|
POP HL ; RESTORE HL/STACK
|
|
CALL PANIC ; PANIC
|
|
OR $FF ; SIGNAL ERROR
|
|
RET ; AND RETURN
|
|
;;
|
|
;CIO_DISPATCH_VDA:
|
|
; LD A,B ; FUNCTION NUMBER TO A
|
|
; ADD A,BF_EMU - BF_CIO ; TRANSLATE FUNCTION CIOXXX -> EMUXXX
|
|
; LD B,A ; PUT NEW FUNCTION NUMBER IN B
|
|
; POP HL ; RESTORE HL/STACK
|
|
; JP EMU_DISPATCH ; CHAIN TO EMULATOR DISPATCH
|
|
;
|
|
CIO_DISPATCH_CON:
|
|
LD A,(HCB + HCB_CONDEV) ; PUT CONSOLE UNIT NUMBER IN A
|
|
; FALL THRU
|
|
;
|
|
CIO_DISPATCH1:
|
|
;
|
|
INC HL ; BUMP PAST COUNT PREFIX TO START OF TABLE
|
|
RLCA ; MULTIPLY UNIT # BY 4 TO
|
|
RLCA ; ... TO CALC ENTRY OFFSET
|
|
CALL ADDHLA ; HL := ENTRY ADDRESS
|
|
LD A,(HL) ; GET DEVICE TYPE BYTE
|
|
INC HL ; BUMP TO DEVICE UNIT INDEX BYTE
|
|
LD C,(HL) ; DEVICE UNIT INDEX TO C
|
|
POP HL ; RECOVER INCOMING HL VALUE
|
|
;
|
|
; DISPATCH TO DRIVER BASED ON DEVICE TYPE IN A
|
|
;
|
|
#IF (UARTENABLE)
|
|
CP CIODEV_UART
|
|
JP Z,UART_DISPATCH
|
|
#ENDIF
|
|
#IF (ASCIENABLE)
|
|
CP CIODEV_ASCI
|
|
JP Z,ASCI_DISPATCH
|
|
#ENDIF
|
|
#IF (PRPENABLE & PRPCONENABLE)
|
|
CP CIODEV_PRPCON
|
|
JP Z,PRPCON_DISPATCH
|
|
#ENDIF
|
|
#IF (PPPENABLE & PPPCONENABLE)
|
|
CP CIODEV_PPPCON
|
|
JP Z,PPPCON_DISPATCH
|
|
#ENDIF
|
|
#IF (VDUENABLE)
|
|
CP CIODEV_VDU
|
|
JP Z,VDU_DISPCIO
|
|
#ENDIF
|
|
#IF (CVDUENABLE)
|
|
CP CIODEV_CVDU
|
|
JP Z,CVDU_DISPCIO
|
|
#ENDIF
|
|
#IF (UPD7220ENABLE)
|
|
CP CIODEV_UPD7220
|
|
JP Z,UPD7220_DISPCIO
|
|
#ENDIF
|
|
#IF (SCGENABLE)
|
|
CP CIODEV_SCG
|
|
JP Z,SCG_DISPCIO
|
|
#ENDIF
|
|
CALL PANIC
|
|
RET
|
|
;
|
|
; HBIOS CHARACTER DEVICE UNIT TABLE
|
|
;
|
|
; TABLE IS BUILT DYNAMICALLY BY EACH DRIVER DURING INITIALIZATION.
|
|
; THE TABLE IS PREFIXED BY TWO BYTES. TABLE - 1 CONTAINS THE CURRENT
|
|
; NUMBER OF ENTRIES. TABLE - 2 CONTAINS THE MAXIMUM NUMBER OF ENTRIES.
|
|
; EACH ENTRY IS DEFINED AS:
|
|
;
|
|
; BYTE DEVICE TYPE ID
|
|
; BYTE DEVICE/DRIVER UNIT NUMBER
|
|
; WORD UNIT DATA ADDRESS
|
|
;
|
|
CIO_MAX .EQU 16 ; UP TO 16 UNITS
|
|
CIO_SIZ .EQU CIO_MAX * 4 ; EACH ENTRY IS 4 BYTES
|
|
;
|
|
.DB CIO_MAX ; MAX ENTRY COUNT TABLE PREFIX
|
|
CIO_CNT .DB 0 ; ENTRY COUNT PREFIX
|
|
CIO_TBL .FILL CIO_SIZ,0 ; SPACE FOR ENTRIES
|
|
;
|
|
; ADD AN ENTRY TO THE CIO UNIT TABLE (SEE HB_ADDENT FOR DETAILS)
|
|
;
|
|
CIO_ADDENT:
|
|
LD HL,CIO_TBL ; POINT TO CIO TABLE
|
|
JP HB_ADDENT ; ... AND GO TO COMMON CODE
|
|
;
|
|
;==================================================================================================
|
|
; DISK I/O DEVICE DISPATCHER
|
|
;==================================================================================================
|
|
;
|
|
; ROUTE CALL TO SPECIFIED DISK I/O DRIVER
|
|
; B: FUNCTION
|
|
; C: UNIT NUMBER
|
|
;
|
|
|
|
;NDIO_NEWDISP:
|
|
; ; START OF THE ACTUAL DRIVER DISPATCHING LOGIC
|
|
; PUSH IY ; SAVE ORIGINAL IY
|
|
; PUSH HL ; SAVE HL
|
|
; LD HL,NDIO_RET ; GET RETURN VECTOR
|
|
; EX (SP),HL ; RECOVER HL & PUT RETURN VECTOR ON TOS
|
|
; PUSH HL ; SAVE HL
|
|
; LD HL,DIO_TBL ; POINT TO DISPATCH TABLE
|
|
; LD A,C ; GET REQUESTED UNIT FROM C
|
|
; RLCA ; MULTIPLY UNIT BY 4
|
|
; RLCA ; ... TO GET BYTE OFFSET OF ENTRY
|
|
; CALL ADDHLA ; HL -> ENTRY ADDRESS
|
|
; LD A,(HL) ; DRIVER ID TO A
|
|
; PUSH AF ; SAVE IT FOR NOW
|
|
; INC HL ; POINT TO UNIT
|
|
; LD C,(HL) ; PUT IT IN C FOR DRIVER
|
|
; INC HL ; POINT TO LSB OF UNIT DATA ADDRESS
|
|
; LD A,(HL) ; HL := UNIT DATA ADDRESS
|
|
; INC HL ; ...
|
|
; LD H,(HL) ; ...
|
|
; LD L,A ; ...
|
|
; POP AF ; RECOVER DRIVER ID
|
|
; EX (SP),HL ; RECOVER ORIG HL & PUT UNIT DATA ADDRESS TO TOS
|
|
; POP IY ; IY := UNIT DATA ADDRESS
|
|
; JP NDIO_DISPATCH2 ; USE LEGACY DISPATCHER
|
|
;;
|
|
;NDIO_RET:
|
|
; POP IY ; RECOVER IY
|
|
; OR A ; MAKE SURE FLAGS ARE SET
|
|
; RET ; AND RETURN
|
|
|
|
DIO_DISPATCH:
|
|
;
|
|
#IF 0 ; *DEBUG* START
|
|
;
|
|
; DUMP INCOMING CALL
|
|
CALL NEWLINE
|
|
PRTS("DIO>$")
|
|
CALL REGDMP ; DUMP REGS, NONE DESTROYED
|
|
;
|
|
; DO THE ACTUAL DISPATCH PROCESSING
|
|
CALL DIO_DISPCALL
|
|
;
|
|
; DUMP CALL RESULTS AND RETURN
|
|
CALL NEWLINE
|
|
PRTS("DIO<$")
|
|
CALL REGDMP ; DUMP REGS, NONE DESTROYED
|
|
RET
|
|
DIO_DISPCALL:
|
|
;
|
|
#ENDIF ; *DEBUG* END
|
|
;
|
|
; ON ENTRY C IS HBIOS UNIT # (INDEX INTO DIO_TBL OF DISK DEVICES)
|
|
; USE UNIT # IN C TO LOOKUP DIO_TBL ENTRY, THEN
|
|
; CONVERT C TO THE DEVICE/DRIVER SPECIFIC UNIT ID
|
|
; AND GET THE DEVICE TYPE TO A FOR DRIVER DISPATCHING
|
|
;
|
|
LD A,C ; INCOMING UNIT INDEX TO A
|
|
PUSH HL ; SAVE INCOMING HL
|
|
LD HL,DIO_CNT ; HL := ADDRESS OF TABLE ENTRY COUNT
|
|
CP (HL) ; COMPARE TO INCOMING ENTRY INDEX
|
|
JR C,DIO_DISPATCH1 ; UNIT OK, PROCEED
|
|
;
|
|
; NOT GOOD, INCOMING UNIT IS OUT OF RANGE
|
|
POP HL ; RESTORE HL/STACK
|
|
CALL PANIC ; PANIC
|
|
OR $FF ; SIGNAL ERROR
|
|
RET ; AND RETURN
|
|
;
|
|
DIO_DISPATCH1:
|
|
INC HL ; BUMP PAST COUNT PREFIX TO START OF TABLE
|
|
RLCA ; MULTIPLY BY 4 TO
|
|
RLCA ; ... TO CALC ENTRY OFFSET
|
|
CALL ADDHLA ; HL := ENTRY OFFSET
|
|
LD A,(HL) ; GET DEVICE TYPE BYTE
|
|
INC HL ; BUMP TO DEVICE UNIT INDEX BYTE
|
|
LD C,(HL) ; DEVICE UNIT INDEX TO C
|
|
POP HL ; RECOVER INCOMING HL VALUE
|
|
;
|
|
; DISPATCH TO DRIVER BASED ON DEVICE TYPE IN A
|
|
;
|
|
#IF (MDENABLE)
|
|
CP DIODEV_MD
|
|
JP Z,MD_DISPATCH
|
|
#ENDIF
|
|
#IF (FDENABLE)
|
|
CP DIODEV_FD
|
|
JP Z,FD_DISPATCH
|
|
#ENDIF
|
|
#IF (RFENABLE)
|
|
CP DIODEV_RF
|
|
JP Z,RF_DISPATCH
|
|
#ENDIF
|
|
#IF (IDEENABLE)
|
|
CP DIODEV_IDE
|
|
JP Z,IDE_DISPATCH
|
|
#ENDIF
|
|
#IF (PPIDEENABLE)
|
|
CP DIODEV_PPIDE
|
|
JP Z,PPIDE_DISPATCH
|
|
#ENDIF
|
|
#IF (SDENABLE)
|
|
CP DIODEV_SD
|
|
JP Z,SD_DISPATCH
|
|
#ENDIF
|
|
#IF (PRPENABLE & PRPSDENABLE)
|
|
CP DIODEV_PRPSD
|
|
JP Z,PRPSD_DISPATCH
|
|
#ENDIF
|
|
#IF (PPPENABLE & PPPSDENABLE)
|
|
CP DIODEV_PPPSD
|
|
JP Z,PPPSD_DISPATCH
|
|
#ENDIF
|
|
#IF (HDSKENABLE)
|
|
CP DIODEV_HDSK
|
|
JP Z,HDSK_DISPATCH
|
|
#ENDIF
|
|
CALL PANIC
|
|
RET
|
|
|
|
;
|
|
; CONVERT AN HBIOS STANDARD HARD DISK CHS ADDRESS TO
|
|
; AN LBA ADDRESS. A STANDARD HBIOS HARD DISK IS ASSUMED
|
|
; TO HAVE 16 SECTORS PER TRACK AND 16 HEADS PER CYLINDER.
|
|
;
|
|
; INPUT: HL=TRACK, D=HEAD, E=SECTOR
|
|
; OUTPUT: DE:HL=32 BIT LBA ADDRESS (D:7 IS NOT SET IN THE RESULT)
|
|
;
|
|
HB_CHS2LBA:
|
|
;
|
|
;; DEBUG: DUMP INCOMING TRACK:HEAD/SEC
|
|
;CALL NEWLINE
|
|
;PUSH BC
|
|
;PUSH HL
|
|
;POP BC
|
|
;CALL PRTHEXWORD
|
|
;CALL PC_COLON
|
|
;PUSH DE
|
|
;POP BC
|
|
;CALL PRTHEXWORD
|
|
;POP BC
|
|
;
|
|
; WE HAVE INCOMING HARDDISK CHS, CONVERT TO LBA
|
|
; HL=TRACK (0..N), D=HEAD (0..15), E=SECTOR (0..15)
|
|
; XLAT HL:DE (TT:HS) --> 32 BIT LBA (LBAHI:LBALO)
|
|
;
|
|
; D/E -> A (COMBINE HEAD/SEC AND SAVE IN A)
|
|
; 0 -> D
|
|
; H -> E
|
|
; L -> H
|
|
; A -> L
|
|
;
|
|
LD A,D ; HEAD TO A
|
|
RLCA ; LEFT SHIFT TO HIGH NIBBLE
|
|
RLCA ; ... DEPENDS ON HIGH
|
|
RLCA ; ... NIBBLE BEING 0 SINCE
|
|
RLCA ; ... IT ROTATES INTO LOW NIBBLE
|
|
OR E ; COMBINE WITH SECTOR (HIGH NIBBLE MUST BE ZERO)
|
|
LD D,0
|
|
LD E,H
|
|
LD H,L
|
|
LD L,A
|
|
;
|
|
;; DEBUG: DUMP RESULTING LBA (32 BIT)
|
|
;PRTS("-->$")
|
|
;PUSH BC
|
|
;PUSH DE
|
|
;POP BC
|
|
;CALL PRTHEXWORD
|
|
;PUSH HL
|
|
;POP BC
|
|
;CALL PRTHEXWORD
|
|
;POP BC
|
|
;
|
|
XOR A
|
|
RET
|
|
;
|
|
; HBIOS DISK DEVICE UNIT TABLE
|
|
;
|
|
; TABLE IS BUILT DYNAMICALLY BY EACH DRIVER DURING INITIALIZATION.
|
|
; THE TABLE IS PREFIXED BY TWO BYTES. TABLE - 1 CONTAINS THE CURRENT
|
|
; NUMBER OF ENTRIES. TABLE - 2 CONTAINS THE MAXIMUM NUMBER OF ENTRIES.
|
|
; EACH ENTRY IS DEFINED AS:
|
|
;
|
|
; BYTE DEVICE TYPE ID
|
|
; BYTE DEVICE/DRIVER UNIT NUMBER
|
|
; WORD UNIT DATA ADDRESS
|
|
;
|
|
DIO_MAX .EQU 16 ; UP TO 16 UNITS
|
|
DIO_SIZ .EQU DIO_MAX * 4 ; EACH ENTRY IS 4 BYTES
|
|
;
|
|
.DB DIO_MAX ; MAX ENTRY COUNT TABLE PREFIX
|
|
DIO_CNT .DB 0 ; ENTRY COUNT PREFIX
|
|
DIO_TBL .FILL DIO_SIZ,0 ; SPACE FOR ENTRIES
|
|
;
|
|
; ADD AN ENTRY TO THE DIO UNIT TABLE
|
|
;
|
|
DIO_ADDENT:
|
|
LD HL,DIO_TBL ; POINT TO DIO TABLE
|
|
JP HB_ADDENT ; ... AND GO TO COMMON CODE
|
|
;
|
|
;==================================================================================================
|
|
; REAL TIME CLOCK DEVICE DISPATCHER
|
|
;==================================================================================================
|
|
;
|
|
; ROUTE CALL TO REAL TIME CLOCK DRIVER
|
|
; B: FUNCTION
|
|
;
|
|
RTC_DISPATCH:
|
|
#IF (SIMRTCENABLE)
|
|
JP SIMRTC_DISPATCH
|
|
#ENDIF
|
|
#IF (DSRTCENABLE)
|
|
JP DSRTC_DISPATCH
|
|
#ENDIF
|
|
CALL PANIC
|
|
;
|
|
;==================================================================================================
|
|
; EMULATION INITIALIZATION DISPATCHER
|
|
;==================================================================================================
|
|
;
|
|
; EMULATOR MODULES ARE INITIALIZED BY THE VDA DRIVER THAT USES THEM.
|
|
; THE VDA DRIVER CALLS EMU_INIT TO DISPATCH THE INITIALIZATION REQUEST
|
|
; TO THE CORRRECT EMULATION MODULE.
|
|
;
|
|
; B: EMULATION TYPE ID (1=TTY, 2=ANSI, ETC.)
|
|
; C: VDA DRIVER'S CIO UNIT NUMBER
|
|
; DE: VDA DRIVER'S DISPATCH ADDRESS
|
|
;
|
|
;
|
|
EMU_INIT:
|
|
LD A,B ; GET REQUESTED EMULATION
|
|
;
|
|
DEC A ; 1 = TTY
|
|
#IF (TTYENABLE)
|
|
LD HL,TTY_INIT
|
|
JR Z,EMU_INIT1
|
|
#ENDIF
|
|
DEC A ; 2 = ANSI
|
|
#IF (ANSIENABLE)
|
|
LD HL,ANSI_INIT
|
|
JR Z,EMU_INIT1
|
|
#ENDIF
|
|
CALL PANIC ; INVALID
|
|
RET
|
|
;
|
|
EMU_INIT1:
|
|
JP (HL) ; DO THE EMULATOR INIT, DE := CIO DISPATCH ADR
|
|
;
|
|
;==================================================================================================
|
|
; VIDEO DISPLAY ADAPTER DEVICE DISPATCHER
|
|
;==================================================================================================
|
|
;
|
|
; ROUTE CALL TO SPECIFIED VDA DEVICE DRIVER
|
|
; B: FUNCTION
|
|
; C: UNIT NUMBER
|
|
;
|
|
VDA_DISPATCH:
|
|
LD A,C ; REQUESTED DEVICE/UNIT IS IN C
|
|
AND $F0 ; ISOLATE THE DEVICE PORTION
|
|
#IF (VDUENABLE)
|
|
CP VDADEV_VDU
|
|
JP Z,VDU_DISPATCH
|
|
#ENDIF
|
|
#IF (CVDUENABLE)
|
|
CP VDADEV_CVDU
|
|
JP Z,CVDU_DISPATCH
|
|
#ENDIF
|
|
#IF (UPD7220ENABLE)
|
|
CP VDADEV_7220
|
|
JP Z,UPD7220_DISPATCH
|
|
#ENDIF
|
|
#IF (SCGENABLE)
|
|
CP VDADEV_SCG
|
|
JP Z,SCG_DISPATCH
|
|
#ENDIF
|
|
CALL PANIC
|
|
;
|
|
;==================================================================================================
|
|
; SYSTEM FUNCTION DISPATCHER
|
|
;==================================================================================================
|
|
;
|
|
; B: FUNCTION
|
|
;
|
|
SYS_DISPATCH:
|
|
LD A,B ; GET REQUESTED FUNCTION
|
|
AND $0F ; ISOLATE SUB-FUNCTION
|
|
JP Z,SYS_SETBNK ; $F0
|
|
DEC A
|
|
JP Z,SYS_GETBNK ; $F1
|
|
DEC A
|
|
JP Z,SYS_COPY ; $F2
|
|
DEC A
|
|
JP Z,SYS_XCOPY ; $F3
|
|
DEC A
|
|
JP Z,SYS_ALLOC ; $F4
|
|
DEC A
|
|
JP Z,SYS_FREE ; $F5
|
|
DEC A
|
|
JP Z,SYS_VER ; $F6
|
|
DEC A
|
|
JP Z,SYS_GET ; $F7
|
|
DEC A
|
|
JP Z,SYS_SET ; $F8
|
|
DEC A
|
|
JP Z,SYS_PEEK ; $F9
|
|
DEC A
|
|
JP Z,SYS_POKE ; $FA
|
|
CALL PANIC ; INVALID
|
|
;
|
|
; SET ACTIVE MEMORY BANK AND RETURN PREVIOUSLY ACTIVE MEMORY BANK
|
|
; NOTE THAT IT GOES INTO EFFECT AS HBIOS IS EXITED
|
|
; HERE, WE JUST SET THE CURRENT BANK
|
|
; CALLER MUST EXTABLISH UPPER MEMORY STACK BEFORE INVOKING THIS FUNCTION!
|
|
;
|
|
SYS_SETBNK:
|
|
LD A,(HBX_INVBNK) ; GET THE PREVIOUS ACTIVE MEMORY BANK
|
|
PUSH AF ; SAVE IT
|
|
LD A,C ; LOAD THE NEW BANK REQUESTED
|
|
LD (HBX_INVBNK),A ; SET IT FOR ACTIVATION UPON HBIOS RETURN
|
|
POP AF ; GET PREVIOUS BANK INTO A
|
|
OR A
|
|
RET
|
|
;
|
|
; GET ACTIVE MEMORY BANK
|
|
;
|
|
SYS_GETBNK:
|
|
LD A,(HBX_INVBNK) ; GET THE ACTIVE MEMORY BANK
|
|
OR A
|
|
RET
|
|
;
|
|
; PERFORM MEMORY COPY POTENTIALLY ACROSS BANKS
|
|
;
|
|
SYS_COPY:
|
|
PUSH IX
|
|
POP BC
|
|
|
|
;; *DEBUG* START
|
|
;PUSH AF
|
|
;PUSH BC
|
|
;PUSH DE
|
|
;PUSH HL
|
|
;
|
|
;CALL NEWLINE
|
|
;
|
|
;LD A,(HB_SRCBNK)
|
|
;CALL PRTHEXBYTE
|
|
;CALL PC_COLON
|
|
;PUSH BC
|
|
;PUSH HL
|
|
;POP BC
|
|
;CALL PRTHEXWORD
|
|
;POP BC
|
|
;CALL PC_SPACE
|
|
|
|
;LD A,(HB_DSTBNK)
|
|
;CALL PRTHEXBYTE
|
|
;CALL PC_COLON
|
|
;PUSH BC
|
|
;PUSH DE
|
|
;POP BC
|
|
;CALL PRTHEXWORD
|
|
;POP BC
|
|
;CALL PC_SPACE
|
|
|
|
;CALL PRTHEXWORD
|
|
|
|
;POP HL
|
|
;POP DE
|
|
;POP BC
|
|
;POP AF
|
|
; *DEBUG* END
|
|
|
|
CALL BNKCPY
|
|
XOR A
|
|
RET
|
|
;
|
|
; SET BANKS FOR EXTENDED (INTERBANK) MEMORY COPY
|
|
;
|
|
SYS_XCOPY:
|
|
LD A,E
|
|
LD (HB_SRCBNK),A
|
|
LD A,D
|
|
LD (HB_DSTBNK),A
|
|
XOR A
|
|
RET
|
|
;
|
|
; ALLOCATE HL BYTES OF MEMORY FROM HBIOS HEAP
|
|
; RETURNS POINTER TO ALLOCATED MEMORY IN HL
|
|
; ON SUCCESS RETURN A == 0, AND Z SET
|
|
; ON FAILURE A <> 0 AND NZ SET AND HL TRASHED
|
|
; ALL OTHER REGISTERS PRESERVED
|
|
;
|
|
SYS_ALLOC:
|
|
JP HB_ALLOC
|
|
;
|
|
; FREE HEAP MEMORY BY SIMPLY RELEASING ALL
|
|
; MEMORY BEYOND POINTER IN HL.
|
|
; ON SUCCESS RETURN A == 0, AND Z SET
|
|
; ON FAILURE A <> 0 AND NZ SET AND HL TRASHED
|
|
; ALL OTHER REGISTERS PRESERVED
|
|
;
|
|
SYS_FREE:
|
|
CALL PANIC ; NOT YET IMPLEMENTED
|
|
OR $FF
|
|
RET
|
|
;
|
|
; GET THE CURRENT HBIOS VERSION
|
|
; ON INPUT, C=0
|
|
; RETURNS VERSION IN DE AS BCD
|
|
; D: MAJOR VERION IN TOP 4 BITS, MINOR VERSION IN LOW 4 BITS
|
|
; E: UPDATE VERION IN TOP 4 BITS, PATCH VERSION IN LOW 4 BITS
|
|
; L: PLATFORM ID
|
|
;
|
|
SYS_VER:
|
|
LD DE,0 | (RMJ << 12) | (RMN << 8) | (RUP << 4) | RTP
|
|
LD L,PLATFORM
|
|
XOR A
|
|
RET
|
|
;
|
|
; GET SYSTEM INFORMATION
|
|
; ITEM TO RETURN INDICATED IN C
|
|
;
|
|
SYS_GET:
|
|
LD A,C ; GET REQUESTED SUB-FUNCTION
|
|
CP BF_SYSGET_CIOCNT
|
|
JR Z,SYS_GETCIOCNT
|
|
CP BF_SYSGET_DIOCNT
|
|
JR Z,SYS_GETDIOCNT
|
|
CP BF_SYSGET_BOOTINFO
|
|
JR Z,SYS_GETBOOTINFO
|
|
CP BF_SYSGET_CPUINFO
|
|
JR Z,SYS_GETCPUINFO
|
|
CP BF_SYSGET_MEMINFO
|
|
JR Z,SYS_GETMEMINFO
|
|
CP BF_SYSGET_BNKINFO
|
|
JR Z,SYS_GETBNKINFO
|
|
OR $FF ; SIGNAL ERROR
|
|
RET
|
|
;
|
|
; GET BOOT INFORMATION
|
|
; RETURNS:
|
|
; L: BOOT BANK ID
|
|
; DE: BOOT DISK VOLUME (UNIT/SLICE)
|
|
;
|
|
SYS_GETBOOTINFO:
|
|
LD A,(HCB + HCB_BOOTBID)
|
|
LD L,A
|
|
LD DE,(HCB + HCB_BOOTVOL)
|
|
XOR A
|
|
RET
|
|
;
|
|
; GET CPU INFORMATION
|
|
; RETURNS:
|
|
; H: Z80 CPU VARIANT
|
|
; L: CPU SPEED IN MHZ
|
|
; DE: CPU SPEED IN KHZ
|
|
;
|
|
SYS_GETCPUINFO:
|
|
LD H,0 ; NOT YET DEFINED
|
|
LD A,(HCB + HCB_CPUMHZ)
|
|
LD L,A
|
|
LD DE,(HCB + HCB_CPUKHZ)
|
|
XOR A
|
|
RET
|
|
;
|
|
; GET MEMORY INFORMATION
|
|
; RETURNS:
|
|
; D: COUNT OF ROM BANKS
|
|
; E: COUNT OF RAM BANKS
|
|
;
|
|
SYS_GETMEMINFO:
|
|
LD D,ROMSIZE / 32
|
|
LD D,RAMSIZE / 32
|
|
XOR A
|
|
RET
|
|
;
|
|
; GET SERIAL UNIT COUNT
|
|
; RETURNS:
|
|
; D: HBIOS BANK ID
|
|
; E: USER BANK ID
|
|
;
|
|
SYS_GETBNKINFO:
|
|
LD A,(HCB + HCB_BIDBIOS)
|
|
LD D,A
|
|
LD A,(HCB + HCB_BIDUSR)
|
|
LD E,A
|
|
XOR A
|
|
RET
|
|
;
|
|
; GET SERIAL UNIT COUNT
|
|
;
|
|
SYS_GETCIOCNT:
|
|
LD A,(CIO_CNT) ; GET DEVICE COUNT (FIRST BYTE OF LIST)
|
|
LD E,A ; PUT IT IN E
|
|
XOR A ; SIGNALS SUCCESS
|
|
RET
|
|
;
|
|
; GET DISK UNIT COUNT
|
|
;
|
|
SYS_GETDIOCNT:
|
|
LD A,(DIO_CNT) ; GET DEVICE COUNT (FIRST BYTE OF LIST)
|
|
LD E,A ; PUT IT IN E
|
|
XOR A ; SIGNALS SUCCESS
|
|
RET
|
|
;
|
|
; SET SYSTEM PARAMETERS
|
|
; PARAMETER(S) TO SET INDICATED IN C
|
|
;
|
|
SYS_SET:
|
|
LD A,C ; GET REQUESTED SUB-FUNCTION
|
|
CP BF_SYSSET_BOOTINFO
|
|
JR Z,SYS_SETBOOTINFO
|
|
OR $FF ; SIGNAL ERROR
|
|
RET
|
|
;
|
|
; SET BOOT INFORMATION
|
|
; ON ENTRY:
|
|
; L: BOOT BANK ID
|
|
; DE: BOOT DISK VOLUME (UNIT/SLICE)
|
|
;
|
|
SYS_SETBOOTINFO:
|
|
LD A,L
|
|
LD (HCB + HCB_BOOTBID),A
|
|
LD (HCB + HCB_BOOTVOL),DE
|
|
XOR A
|
|
RET
|
|
;
|
|
; RETURN A BYTE OF MEMORY FROM HBIOS BANK
|
|
; ENTRY: HL=ADDRESS IN HBIOS BANK (0H-7FFFH)
|
|
; RETURN: C=BYTE VALUE
|
|
;
|
|
SYS_PEEK:
|
|
LD C,(HL)
|
|
XOR A
|
|
RET
|
|
;
|
|
; WRITE A BYTE OF MEMORY TO HBIOS BANK
|
|
; ENTRY: HL=ADDRESS IN HBIOS BANK (0H-7FFFH)
|
|
; RETURN: C=BYTE VALUE
|
|
;
|
|
SYS_POKE:
|
|
LD (HL),C
|
|
XOR A
|
|
RET
|
|
;;
|
|
;; GET HCB VALUE BYTE
|
|
;; C: HCB INDEX (OFFSET INTO HCB)
|
|
;; RETURN BYTE VALUE IN E
|
|
;;
|
|
;SYS_HCBGETB:
|
|
; CALL SYS_HCBPTR ; LOAD HL WITH PTR
|
|
; LD E,(HL) ; GET BYTE VALUE
|
|
; RET ; DONE
|
|
;;
|
|
;; PUT HCB VALUE BYTE
|
|
;; C: HCB INDEX (OFFSET INTO HCB)
|
|
;; E: VALUE TO WRITE
|
|
;;
|
|
;SYS_HCBPUTB:
|
|
; CALL SYS_HCBPTR ; LOAD HL WITH PTR
|
|
; LD (HL),E ; PUT BYTE VALUE
|
|
; RET
|
|
;;
|
|
;; GET HCB VALUE WORD
|
|
;; C: HCB INDEX (OFFSET INTO HCB)
|
|
;; RETURN WORD VALUE IN DE
|
|
;;
|
|
;SYS_HCBGETW:
|
|
; CALL SYS_HCBPTR ; LOAD HL WITH PTR
|
|
; LD E,(HL) ; GET BYTE VALUE
|
|
; INC HL
|
|
; LD D,(HL) ; GET BYTE VALUE
|
|
; RET ; DONE
|
|
;;
|
|
;; PUT HCB VALUE WORD
|
|
;; C: HCB INDEX (OFFSET INTO HCB)
|
|
;; DE: VALUE TO WRITE
|
|
;;
|
|
;SYS_HCBPUTW:
|
|
; CALL SYS_HCBPTR ; LOAD HL WITH PTR
|
|
; LD (HL),E ; PUT BYTE VALUE
|
|
; INC HL
|
|
; LD (HL),D ; PUT BYTE VALUE
|
|
; RET
|
|
;
|
|
;; CALCULATE REAL ADDRESS OF HCB VALUE FROM HCB OFFSET
|
|
;;
|
|
;SYS_HCBPTR:
|
|
; LD A,C ; LOAD INDEX (HCB OFFSET)
|
|
; LD HL,HCB ; GET HCB ADDRESS
|
|
; JP ADDHLA ; CALC REAL ADDRESS AND RET
|
|
;
|
|
;==================================================================================================
|
|
; GLOBAL HBIOS FUNCTIONS
|
|
;==================================================================================================
|
|
;
|
|
; COMMON ROUTINE THAT IS CALLED BY CHARACTER IO DRIVERS WHEN
|
|
; AN IDLE CONDITION IS DETECTED (WAIT FOR INPUT/OUTPUT)
|
|
;
|
|
CIO_IDLE:
|
|
PUSH AF ; PRESERVE AF
|
|
LD A,(IDLECOUNT) ; GET CURRENT IDLE COUNT
|
|
DEC A ; DECREMENT
|
|
LD (IDLECOUNT),A ; SAVE UPDATED VALUE
|
|
CALL Z,IDLE ; IF ZERO, DO IDLE PROCESSING
|
|
POP AF ; RECOVER AF
|
|
RET
|
|
;
|
|
; TIMER INTERRUPT
|
|
;
|
|
HB_TIMINT:
|
|
RET
|
|
;
|
|
; BAD INTERRUPT HANDLER
|
|
;
|
|
HB_BADINT:
|
|
RET
|
|
;
|
|
; WRAPPER FOR CALL TO HB_BNKCPY FOR USE BY INTERNAL HBIOS FUNCTIONS
|
|
;
|
|
BNKCPY .EQU HB_BNKCPY
|
|
;
|
|
; ADD AN ENTRY TO THE UNIT TABLE AT ADDRESS IN HL
|
|
; C: DEVICE TYPE ID
|
|
; B: UNIT INDEX
|
|
; DE: ADDRESS OF UNIT DATA
|
|
; RETURN
|
|
; A: UNIT NUMBER ASSIGNED
|
|
;
|
|
HB_ADDENT:
|
|
DEC HL ; POINT TO ENTRY COUNT
|
|
LD A,(HL) ; GET ENTRY COUNT
|
|
PUSH AF ; SAVE VALUE TO RETURN AS ENTRY NUM AT END
|
|
INC A ; INCREMENT TO ACCOUNT FOR NEW ENTRY
|
|
DEC HL ; POINT TO ENTRY MAX
|
|
CP (HL) ; COMPARE MAX TO CURRENT COUNT (COUNT - MAX)
|
|
CALL NC,PANIC ; OVERFLOW
|
|
INC HL ; POINT TO COUNT
|
|
LD (HL),A ; SAVE NEW COUNT
|
|
INC HL ; POINT TO START OF TABLE
|
|
DEC A ; CONVERT A FROM ENTRY COUNT TO ENTRY INDEX
|
|
RLCA ; MULTIPLY BY 4
|
|
RLCA ; ... TO GET BYTE OFFSET OF ENTRY
|
|
CALL ADDHLA ; MAKE HL POINT TO ACTUAL ENTRY ADDRESS
|
|
PUSH BC ; GET TABLE ENTRY ADDRESS TO BC
|
|
EX (SP),HL ; ... AND DISPATCH ADDRESS TO HL
|
|
POP BC ; ... SO THAT DE:HL HAS 32 BIT ENTRY
|
|
CALL ST32 ; LD (BC),DE:HL STORES THE ENTRY
|
|
POP AF ; RETURN ENTRY INDEX
|
|
RET
|
|
;
|
|
; ALLOCATE HL BYTES OF MEMORY ON THE HEAP
|
|
; RETURNS POINTER TO ALLOCATED SPACE IN HL
|
|
; ON SUCCESS RETURN A == 0, AND Z SET
|
|
; ON FAILURE A <> 0 AND NZ SET AND HL TRASHED
|
|
; ALL OTHER REGISTERS PRESERVED
|
|
;
|
|
; A 4 BYTE HEADER IS PLACED IN FRONT OF THE ALLOCATED MEMORY
|
|
; - DWORD: SIZE OF MEMROY ALLOCATED (DOES NOT INCLUDE 4 BYTE HEADER)
|
|
; - DWORD: ADDRESS WHERE ALLOC WAS CALLED (VALUE ON TOP OF STACK AT CALL)
|
|
;
|
|
HB_ALLOC:
|
|
; SAVE ALLOC SIZE AND REFERENCE ADR FOR SUBSEQUENT HEADER CONSTRUCTION
|
|
LD (HB_TMPSZ),HL ; SAVE INCOMING SIZE REQUESTED
|
|
; USE EX (SP),HL INSTEAD????
|
|
POP HL ; GET RETURN ADDRESS
|
|
LD (HB_TMPREF),HL ; SAVE AS REFERENCE
|
|
; USE EX (SP),HL INSTEAD????
|
|
PUSH HL ; PUT IT BACK ON STACK
|
|
LD HL,(HB_TMPSZ) ; RECOVER INCOMING MEM SIZE PARM
|
|
;
|
|
; CALC NEW HEAP TOP AND HANDLE OUT-OF-SPACE ERROR
|
|
PUSH DE ; SAVE INCOMING DE
|
|
LD DE,4 ; SIZE OF HEADER
|
|
ADD HL,DE ; ADD IT IN
|
|
JR C,HB_ALLOC1 ; ERROR ON OVERFLOW
|
|
LD DE,(HCB + HCB_HEAPTOP) ; CURRENT HEAP TOP
|
|
ADD HL,DE ; ADD IT IN, HL := NEW HEAP TOP
|
|
JR C,HB_ALLOC1 ; ERROR ON OVERFLOW
|
|
BIT 7,H ; TEST PAST END OF BANK (>= 32K)
|
|
JR NZ,HB_ALLOC1 ; ERROR IF PAST END
|
|
;
|
|
; SAVE NEW HEAP TOP
|
|
LD DE,(HCB + HCB_HEAPTOP) ; GET ORIGINAL HEAP TOP
|
|
LD (HCB + HCB_HEAPTOP),HL ; SAVE NEW HEAP TOP
|
|
;
|
|
; SET HEADER VALUES
|
|
EX DE,HL ; HEADER ADR TO HL
|
|
LD DE,(HB_TMPSZ) ; GET THE ORIG SIZE REQUESTED
|
|
LD (HL),E ; SAVE SIZE (LSB)
|
|
INC HL ; BUMP HEADER POINTER
|
|
LD (HL),D ; SAVE SIZE (MSB)
|
|
INC HL ; BUMP HEADER POINTER
|
|
LD DE,(HB_TMPREF) ; GET THE REFERENCE ADR
|
|
LD (HL),E ; SAVE REF ADR (LSB)
|
|
INC HL ; BUMP HEADER POINTER
|
|
LD (HL),D ; SAVE REF ADR (MSB)
|
|
INC HL ; BUMP HEADER POINTER
|
|
;
|
|
; RETURN SUCCESS, HL POINTS TO START OF ALLOCATED MEMORY (PAST HEADER)
|
|
POP DE ; RESTORE INCOMING DE
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET ; AND RETURN
|
|
;
|
|
HB_ALLOC1:
|
|
; ERROR RETURN
|
|
POP DE ; RESTORE INCOMING DE
|
|
OR $FF ; SIGNAL ERROR
|
|
RET ; AND RETURN
|
|
;
|
|
HB_TMPSZ .DW 0
|
|
HB_TMPREF .DW 0
|
|
;
|
|
;==================================================================================================
|
|
; DEVICE DRIVERS
|
|
;==================================================================================================
|
|
;
|
|
#IF (SIMRTCENABLE)
|
|
ORG_SIMRTC .EQU $
|
|
#INCLUDE "simrtc.asm"
|
|
SIZ_SIMRTC .EQU $ - ORG_SIMRTC
|
|
.ECHO "SIMRTC occupies "
|
|
.ECHO SIZ_SIMRTC
|
|
.ECHO " bytes.\n"
|
|
#ENDIF
|
|
;
|
|
#IF (DSRTCENABLE)
|
|
ORG_DSRTC .EQU $
|
|
#INCLUDE "dsrtc.asm"
|
|
SIZ_DSRTC .EQU $ - ORG_DSRTC
|
|
.ECHO "DSRTC occupies "
|
|
.ECHO SIZ_DSRTC
|
|
.ECHO " bytes.\n"
|
|
#ENDIF
|
|
;
|
|
#IF (UARTENABLE)
|
|
ORG_UART .EQU $
|
|
#INCLUDE "uart.asm"
|
|
SIZ_UART .EQU $ - ORG_UART
|
|
.ECHO "UART occupies "
|
|
.ECHO SIZ_UART
|
|
.ECHO " bytes.\n"
|
|
#ENDIF
|
|
;
|
|
#IF (ASCIENABLE)
|
|
ORG_ASCI .EQU $
|
|
#INCLUDE "asci.asm"
|
|
SIZ_ASCI .EQU $ - ORG_ASCI
|
|
.ECHO "ASCI occupies "
|
|
.ECHO SIZ_ASCI
|
|
.ECHO " bytes.\n"
|
|
#ENDIF
|
|
;
|
|
#IF (VDUENABLE)
|
|
ORG_VDU .EQU $
|
|
#INCLUDE "vdu.asm"
|
|
SIZ_VDU .EQU $ - ORG_VDU
|
|
.ECHO "VDU occupies "
|
|
.ECHO SIZ_VDU
|
|
.ECHO " bytes.\n"
|
|
#ENDIF
|
|
;
|
|
#IF (CVDUENABLE)
|
|
ORG_CVDU .EQU $
|
|
#INCLUDE "cvdu.asm"
|
|
SIZ_CVDU .EQU $ - ORG_CVDU
|
|
.ECHO "CVDU occupies "
|
|
.ECHO SIZ_CVDU
|
|
.ECHO " bytes.\n"
|
|
#ENDIF
|
|
;
|
|
#IF (UPD7220ENABLE)
|
|
ORG_UPD7220 .EQU $
|
|
#INCLUDE "upd7220.asm"
|
|
SIZ_UPD7220 .EQU $ - ORG_UPD7220
|
|
.ECHO "UPD7220 occupies "
|
|
.ECHO SIZ_UPD7220
|
|
.ECHO " bytes.\n"
|
|
#ENDIF
|
|
;
|
|
#IF (SCGENABLE)
|
|
ORG_SCG .EQU $
|
|
#INCLUDE "scg.asm"
|
|
SIZ_SCG .EQU $ - ORG_SCG
|
|
.ECHO "SCG occupies "
|
|
.ECHO SIZ_SCG
|
|
.ECHO " bytes.\n"
|
|
#ENDIF
|
|
;
|
|
#IF (PRPENABLE)
|
|
ORG_PRP .EQU $
|
|
#INCLUDE "prp.asm"
|
|
SIZ_PRP .EQU $ - ORG_PRP
|
|
.ECHO "PRP occupies "
|
|
.ECHO SIZ_PRP
|
|
.ECHO " bytes.\n"
|
|
#ENDIF
|
|
;
|
|
#IF (PPPENABLE)
|
|
ORG_PPP .EQU $
|
|
#INCLUDE "ppp.asm"
|
|
SIZ_PPP .EQU $ - ORG_PPP
|
|
.ECHO "PPP occupies "
|
|
.ECHO SIZ_PPP
|
|
.ECHO " bytes.\n"
|
|
#ENDIF
|
|
;
|
|
#IF (MDENABLE)
|
|
ORG_MD .EQU $
|
|
#INCLUDE "md.asm"
|
|
SIZ_MD .EQU $ - ORG_MD
|
|
.ECHO "MD occupies "
|
|
.ECHO SIZ_MD
|
|
.ECHO " bytes.\n"
|
|
#ENDIF
|
|
|
|
#IF (FDENABLE)
|
|
ORG_FD .EQU $
|
|
#INCLUDE "fd.asm"
|
|
SIZ_FD .EQU $ - ORG_FD
|
|
.ECHO "FD occupies "
|
|
.ECHO SIZ_FD
|
|
.ECHO " bytes.\n"
|
|
#ENDIF
|
|
|
|
#IF (RFENABLE)
|
|
ORG_RF .EQU $
|
|
#INCLUDE "rf.asm"
|
|
SIZ_RF .EQU $ - ORG_RF
|
|
.ECHO "RF occupies "
|
|
.ECHO SIZ_RF
|
|
.ECHO " bytes.\n"
|
|
#ENDIF
|
|
|
|
#IF (IDEENABLE)
|
|
ORG_IDE .EQU $
|
|
#INCLUDE "ide.asm"
|
|
SIZ_IDE .EQU $ - ORG_IDE
|
|
.ECHO "IDE occupies "
|
|
.ECHO SIZ_IDE
|
|
.ECHO " bytes.\n"
|
|
#ENDIF
|
|
|
|
#IF (PPIDEENABLE)
|
|
ORG_PPIDE .EQU $
|
|
#INCLUDE "ppide.asm"
|
|
SIZ_PPIDE .EQU $ - ORG_PPIDE
|
|
.ECHO "PPIDE occupies "
|
|
.ECHO SIZ_PPIDE
|
|
.ECHO " bytes.\n"
|
|
#ENDIF
|
|
|
|
#IF (SDENABLE)
|
|
ORG_SD .EQU $
|
|
#INCLUDE "sd.asm"
|
|
SIZ_SD .EQU $ - ORG_SD
|
|
.ECHO "SD occupies "
|
|
.ECHO SIZ_SD
|
|
.ECHO " bytes.\n"
|
|
#ENDIF
|
|
|
|
#IF (HDSKENABLE)
|
|
ORG_HDSK .EQU $
|
|
#INCLUDE "hdsk.asm"
|
|
SIZ_HDSK .EQU $ - ORG_HDSK
|
|
.ECHO "HDSK occupies "
|
|
.ECHO SIZ_HDSK
|
|
.ECHO " bytes.\n"
|
|
#ENDIF
|
|
|
|
#IF (PPKENABLE)
|
|
ORG_PPK .EQU $
|
|
#INCLUDE "ppk.asm"
|
|
SIZ_PPK .EQU $ - ORG_PPK
|
|
.ECHO "PPK occupies "
|
|
.ECHO SIZ_PPK
|
|
.ECHO " bytes.\n"
|
|
#ENDIF
|
|
|
|
#IF (KBDENABLE)
|
|
ORG_KBD .EQU $
|
|
#INCLUDE "kbd.asm"
|
|
SIZ_KBD .EQU $ - ORG_KBD
|
|
.ECHO "KBD occupies "
|
|
.ECHO SIZ_KBD
|
|
.ECHO " bytes.\n"
|
|
#ENDIF
|
|
|
|
#IF (TTYENABLE)
|
|
ORG_TTY .EQU $
|
|
#INCLUDE "tty.asm"
|
|
SIZ_TTY .EQU $ - ORG_TTY
|
|
.ECHO "TTY occupies "
|
|
.ECHO SIZ_TTY
|
|
.ECHO " bytes.\n"
|
|
#ENDIF
|
|
|
|
#IF (ANSIENABLE)
|
|
ORG_ANSI .EQU $
|
|
#INCLUDE "ansi.asm"
|
|
SIZ_ANSI .EQU $ - ORG_ANSI
|
|
.ECHO "ANSI occupies "
|
|
.ECHO SIZ_ANSI
|
|
.ECHO " bytes.\n"
|
|
#ENDIF
|
|
;
|
|
#DEFINE USEDELAY
|
|
#INCLUDE "util.asm"
|
|
#INCLUDE "time.asm"
|
|
#INCLUDE "bcd.asm"
|
|
#INCLUDE "xio.asm"
|
|
;
|
|
#IF (DSKYENABLE)
|
|
#DEFINE DSKY_KBD
|
|
#INCLUDE "dsky.asm"
|
|
#ENDIF
|
|
;
|
|
#IF ((PLATFORM == PLT_SBC) | (PLATFORM == PLT_ZETA) | (PLATFORM == PLT_ZETA2))
|
|
;
|
|
; DETECT Z80 CPU SPEED USING DS-1302 RTC
|
|
;
|
|
HB_CPUSPD:
|
|
;
|
|
#IF (DSRTCENABLE)
|
|
;
|
|
CALL DSRTC_TSTCLK ; IS CLOCK RUNNING?
|
|
JR Z,HB_CPUSPD1 ; YES, CONTINUE
|
|
; MAKE SURE CLOCK IS RUNNING
|
|
LD HL,DSRTC_TIMDEF
|
|
CALL DSRTC_TIM2CLK
|
|
LD HL,DSRTC_BUF
|
|
CALL DSRTC_WRCLK
|
|
CALL DSRTC_TSTCLK ; NOW IS CLOCK RUNNING?
|
|
RET NZ
|
|
;
|
|
HB_CPUSPD1:
|
|
; WATT FOR AN INITIAL TICK TO ALIGN, THEN WAIT
|
|
; FOR SECOND TICK AND TO GET A FULL ONE SECOND LOOP COUNT
|
|
CALL HB_WAITSECS ; WAIT FOR INITIAL SECS TICK
|
|
CALL HB_WAITSECS ; WAIT FOR SECS TICK AGAIN, COUNT INDE
|
|
;
|
|
LD A,H
|
|
OR L
|
|
RET Z ; FAILURE, USE DEFAULT CPU SPEED
|
|
;
|
|
; TIMES 4 (W/ ROUNDING) FOR CPU SPEED IN KHZ
|
|
INC HL
|
|
SRL H
|
|
RR L
|
|
SLA L
|
|
RL H
|
|
SLA L
|
|
RL H
|
|
SLA L
|
|
RL H
|
|
;
|
|
LD (HCB + HCB_CPUKHZ),HL
|
|
LD DE,1000
|
|
CALL DIV16
|
|
LD A,C
|
|
LD (HCB + HCB_CPUMHZ),A
|
|
;
|
|
RET
|
|
;
|
|
HB_WAITSECS:
|
|
; WAIT FOR SECONDS TICK
|
|
; RETURN SECS VALUE IN A, LOOP COUNT IN DE
|
|
; LOOP TARGET IS 250 T-STATES, SO CPU FREQ IN KHZ = LOOP COUNT * 4
|
|
LD HL,0 ; INIT LOOP COUNTER
|
|
CALL HB_RDSEC ; GET SECONDS
|
|
LD E,A ; SAVE IT
|
|
HB_WAITSECS1:
|
|
CALL DLY32
|
|
CALL DLY8
|
|
CALL DLY4
|
|
JP $ + 3 ; 10 TSTATES
|
|
; LD A,R ; 9 TSTATES
|
|
; INC BC ; 6 TSTATES
|
|
NOP ; 4 TSTATES
|
|
NOP ; 4 TSTATES
|
|
NOP ; 4 TSTATES
|
|
NOP ; 4 TSTATES
|
|
NOP ; 4 TSTATES
|
|
;
|
|
CALL HB_RDSEC ; GET SECONDS
|
|
INC HL ; BUMP COUNTER
|
|
CP E ; EQUAL?
|
|
RET NZ ; DONE IF TICK OCCURRED
|
|
LD A,H ; CHECK HL
|
|
OR L ; ... FOR OVERFLOW
|
|
RET Z ; TIMEOUT, SOMETHING IS WRONG
|
|
JR HB_WAITSECS1 ; LOOP
|
|
;
|
|
HB_RDSEC:
|
|
; READ SECONDS BYTE INTO A
|
|
LD C,$81 ; SECONDS REGISTER HAS CLOCK HALT FLAG
|
|
CALL DSRTC_CMD ; SEND THE COMMAND
|
|
CALL DSRTC_GET ; READ THE REGISTER
|
|
CALL DSRTC_END ; FINISH IT
|
|
RET
|
|
;
|
|
#ELSE
|
|
;
|
|
RET ; NO RTC, ABORT
|
|
;
|
|
#ENDIF
|
|
;
|
|
#ENDIF
|
|
;
|
|
;
|
|
#IF ((PLATFORM == PLT_N8) | (PLATFORM == PLT_MK4))
|
|
;
|
|
; DETECT Z180 CPU SPEED USING DS-1302 RTC
|
|
;
|
|
HB_CPUSPD:
|
|
;
|
|
#IF (DSRTCENABLE)
|
|
;
|
|
CALL DSRTC_TSTCLK ; IS CLOCK RUNNING?
|
|
JR Z,HB_CPUSPD1 ; YES, CONTINUE
|
|
; MAKE SURE CLOCK IS RUNNING
|
|
LD HL,DSRTC_TIMDEF
|
|
CALL DSRTC_TIM2CLK
|
|
LD HL,DSRTC_BUF
|
|
CALL DSRTC_WRCLK
|
|
CALL DSRTC_TSTCLK ; NOW IS CLOCK RUNNING?
|
|
RET NZ
|
|
;
|
|
HB_CPUSPD1:
|
|
; WATT FOR AN INITIAL TICK TO ALIGN, THEN WAIT
|
|
; FOR SECOND TICK AND TO GET A FULL ONE SECOND LOOP COUNT
|
|
CALL HB_WAITSECS ; WAIT FOR INITIAL SECS TICK
|
|
CALL HB_WAITSECS ; WAIT FOR SECS TICK AGAIN, COUNT INDE
|
|
;
|
|
LD A,H
|
|
OR L
|
|
RET Z ; FAILURE, USE DEFAULT CPU SPEED
|
|
;
|
|
; TIMES 8 FOR CPU SPEED IN KHZ
|
|
SLA L
|
|
RL H
|
|
SLA L
|
|
RL H
|
|
SLA L
|
|
RL H
|
|
;
|
|
LD (HCB + HCB_CPUKHZ),HL
|
|
LD DE,1000
|
|
CALL DIV16
|
|
LD A,C
|
|
LD (HCB + HCB_CPUMHZ),A
|
|
;
|
|
RET
|
|
;
|
|
HB_WAITSECS:
|
|
; WAIT FOR SECONDS TICK
|
|
; RETURN SECS VALUE IN A, LOOP COUNT IN DE
|
|
; LOOP TARGET IS 250 T-STATES, SO CPU FREQ IN KHZ = LOOP COUNT * 4
|
|
LD HL,0 ; INIT LOOP COUNTER
|
|
CALL HB_RDSEC ; GET SECONDS
|
|
LD E,A ; SAVE IT
|
|
HB_WAITSECS1:
|
|
CALL DLY64
|
|
OR A ; 7 TSTATES
|
|
;OR A ; 7 TSTATES
|
|
;OR A ; 7 TSTATES
|
|
;OR A ; 7 TSTATES
|
|
NOP ; 6 TSTATES
|
|
NOP ; 6 TSTATES
|
|
NOP ; 6 TSTATES
|
|
NOP ; 6 TSTATES
|
|
;NOP ; 6 TSTATES
|
|
;
|
|
CALL HB_RDSEC ; GET SECONDS
|
|
INC HL ; BUMP COUNTER
|
|
CP E ; EQUAL?
|
|
RET NZ ; DONE IF TICK OCCURRED
|
|
LD A,H ; CHECK HL
|
|
OR L ; ... FOR OVERFLOW
|
|
RET Z ; TIMEOUT, SOMETHING IS WRONG
|
|
JR HB_WAITSECS1 ; LOOP
|
|
;
|
|
HB_RDSEC:
|
|
; READ SECONDS BYTE INTO A
|
|
LD C,$81 ; SECONDS REGISTER HAS CLOCK HALT FLAG
|
|
CALL DSRTC_CMD ; SEND THE COMMAND
|
|
CALL DSRTC_GET ; READ THE REGISTER
|
|
CALL DSRTC_END ; FINISH IT
|
|
RET
|
|
;
|
|
#ELSE
|
|
;
|
|
RET ; NO RTC, ABORT
|
|
;
|
|
#ENDIF
|
|
;
|
|
#ENDIF
|
|
;
|
|
; PRINT VALUE OF HL AS THOUSANDTHS, IE. 0.000
|
|
;
|
|
PRTD3M:
|
|
PUSH BC
|
|
PUSH DE
|
|
PUSH HL
|
|
LD E,'0'
|
|
LD BC,-10000
|
|
CALL PRTD3M1
|
|
LD E,0
|
|
LD BC,-1000
|
|
CALL PRTD3M1
|
|
CALL PC_PERIOD
|
|
LD BC,-100
|
|
CALL PRTD3M1
|
|
LD C,-10
|
|
CALL PRTD3M1
|
|
LD C,-1
|
|
CALL PRTD3M1
|
|
POP HL
|
|
POP DE
|
|
POP BC
|
|
RET
|
|
PRTD3M1:
|
|
LD A,'0' - 1
|
|
PRTD3M2:
|
|
INC A
|
|
ADD HL,BC
|
|
JR C,PRTD3M2
|
|
SBC HL,BC
|
|
CP E
|
|
JR Z,PRTD3M3
|
|
LD E,0
|
|
CALL COUT
|
|
PRTD3M3:
|
|
RET
|
|
;
|
|
;==================================================================================================
|
|
; CONSOLE CHARACTER I/O HELPER ROUTINES (REGISTERS PRESERVED)
|
|
;==================================================================================================
|
|
;
|
|
; OUTPUT CHARACTER FROM A
|
|
;
|
|
COUT:
|
|
; SAVE ALL INCOMING REGISTERS
|
|
PUSH AF
|
|
PUSH BC
|
|
PUSH DE
|
|
PUSH HL
|
|
;
|
|
; GET CURRENT CONSOLE UNIT
|
|
LD E,A ; OUTPUT CHAR TO E
|
|
LD A,(HCB + HCB_CONDEV) ; GET CONSOLE UNIT BYTE
|
|
CP $FF ; TEST FOR $FF (HBIOS NOT READY)
|
|
JR Z,COUT1 ; IF NOT READY, USE XIO
|
|
;
|
|
; USE HBIOS
|
|
LD C,A ; CONSOLE UNIT TO C
|
|
LD B,BF_CIOOUT ; HBIOS FUNC: OUTPUT CHAR
|
|
CALL CIO_DISPATCH ; CALL CIO DISPATCHER DIRECTLY
|
|
JR COUT2 ; CONTINUE
|
|
;
|
|
COUT1:
|
|
; USE XIO
|
|
LD A,E ; GET OUTPUT CHAR BACK TO ACCUM
|
|
CALL XIO_OUTC ; OUTPUT VIA XIO
|
|
;
|
|
COUT2:
|
|
; 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
|
|
;
|
|
LD A,(HCB + HCB_CONDEV) ; GET CONSOLE UNIT BYTE
|
|
CP $FF ; TEST FOR $FF (HBIOS NOT READY)
|
|
JR Z,CIN1 ; IF NOT READY, USE XIO
|
|
;
|
|
; USE HBIOS
|
|
LD C,A ; CONSOLE UNIT TO C
|
|
LD B,BF_CIOIN ; HBIOS FUNC: INPUT CHAR
|
|
CALL CIO_DISPATCH ; CALL CIO DISPATCHER DIRECTLY
|
|
LD A,E ; RESULTANT CHAR TO A
|
|
JR CIN2 ; CONTINUE
|
|
;
|
|
CIN1:
|
|
; USE XIO
|
|
CALL PANIC ; NOT YET SUPPORTED
|
|
;
|
|
CIN2:
|
|
;
|
|
; 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
|
|
;
|
|
LD A,(HCB + HCB_CONDEV) ; GET CONSOLE UNIT BYTE
|
|
CP $FF ; TEST FOR $FF (HBIOS NOT READY)
|
|
JR Z,CST1 ; IF NOT READY, USE XIO
|
|
;
|
|
; USE HBIOS
|
|
LD C,A ; CONSOLE UNIT TO C
|
|
LD B,BF_CIOIST ; HBIOS FUNC: INPUT STATUS
|
|
CALL CIO_DISPATCH ; CALL CIO DISPATCHER DIRECTLY
|
|
JR CST2 ; CONTINUE
|
|
;
|
|
CST1:
|
|
; USE XIO
|
|
CALL PANIC ; NOT YET SUPPORTED
|
|
;
|
|
CST2:
|
|
; RESTORE REGISTERS (AF IS OUTPUT)
|
|
POP HL
|
|
POP DE
|
|
POP BC
|
|
RET
|
|
;
|
|
;==================================================================================================
|
|
; HBIOS GLOBAL DATA
|
|
;==================================================================================================
|
|
;
|
|
IDLECOUNT .DB 0
|
|
;
|
|
; THE HOST (HST) VALUES BELOW INDICATE THE DISK AND BLOCK CURRENTLY
|
|
; ADDRESSED FOR READ/WRITE OPERATIONS.
|
|
; THE 32-BIT BLOCK ADDRESS CAN BE TREADED AS EITHER CHS OR LBA, HIGH ORDER BIT ON SIGNIFIES LBA
|
|
; CHS:
|
|
; .DW 0 ; TRACK (0-65535)
|
|
; .DB 0 ; SECTOR (0-255)
|
|
; .DB 0 ; HEAD (0-127)
|
|
;
|
|
; LBA:
|
|
; .DW 0 ; LBA LOW WORD
|
|
; .DW 0 ; LBA HIGH WORD
|
|
;
|
|
; DISK DEVICE/UNIT ID
|
|
;HSTDSK .DB 0 ; DISK DEVICE/UNIT ID
|
|
; FULL 32 BIT LBA
|
|
HSTLBA .EQU $ ; REFERS TO START OF 32-BIT LBA
|
|
; LBA LOW WORD -OR- TRACK
|
|
HSTLBALO .EQU $ ; BLOCK ADDRESS LBA LOW WORD
|
|
HSTTRK .DW 0 ; CYLINDER (0-65535)
|
|
; LBA HIGH WORD -OR- HEAD/SECTOR
|
|
HSTLBAHI .EQU $ ; BLOCK ADDRESS LBA HIGH WORD
|
|
HSTSEC .DB 0 ; SECTOR (0-255)
|
|
HSTHEAD .DB 0 ; HEAD (0-255)
|
|
;
|
|
DIOBUF .DW 0 ; PTR TO CURRENT DISK XFR BUFFER
|
|
;DIOBUFDEF .DW 0 ; PTR TO DEFAULT PREALLOCATED DISK XFR BUFFER
|
|
;
|
|
HB_INTSTKSAV .DW 0 ; SAVED STACK POINTER DURING INT PROCESSING
|
|
.FILL $40,$FF ; 32 ENTRY STACK FOR INTERRUPT PROCESSING
|
|
HB_INTSTK .EQU $ ; TOP OF INTERRUPT PROCESSING STACK
|
|
;
|
|
STR_BANNER .DB "SBC HBIOS v", BIOSVER, ", ", TIMESTAMP, "$"
|
|
STR_PLATFORM .DB PLATFORM_NAME, "$"
|
|
STR_SWITCH .DB "*** Activating CRT Console ***$"
|
|
;
|
|
HB_TMPBUF .FILL 512,0 ; INTERNAL DISK BUFFER
|
|
;
|
|
HB_END .EXPORT HB_END ; EXPORT ENDING ADDRESS
|
|
;
|
|
SLACK .EQU BNKTOP - $
|
|
.ECHO "HBIOS space remaining: "
|
|
.ECHO SLACK
|
|
.ECHO " bytes.\n"
|
|
;
|
|
.END
|
|
|