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.
400 lines
9.5 KiB
400 lines
9.5 KiB
;:::::::::::::::::::::::::::::::::::::::*****************************
|
|
; HBIOS - HBios Interface Routines ***** Hardware-Specific *****
|
|
; *****************************
|
|
;
|
|
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
|
;
|
|
HB_DEFBNK EQU BID_USR ; Default bank number
|
|
;
|
|
; LOCATION OF DISPATCH ENTRY IN HBIOS BANK
|
|
;
|
|
HB_DISPATCH EQU 403H
|
|
HB_STACK EQU 500H
|
|
;
|
|
; PLATFORM SPECIFIC CONSTANTS
|
|
;
|
|
IF N8VEM OR ZETA OR ZETA2
|
|
SBC_BASE EQU 60H
|
|
ENDIF
|
|
|
|
IF N8VEM OR ZETA
|
|
MPCL_RAM EQU SBC_BASE + 18H ; BASE IO ADDRESS OF RAM MEMORY PAGER CONFIGURATION LATCH
|
|
MPCL_ROM EQU SBC_BASE + 1CH ; BASE IO ADDRESS OF ROM MEMORY PAGER CONFIGURATION LATCH
|
|
ENDIF
|
|
|
|
IF ZETA2
|
|
MPGSEL_0 EQU SBC_BASE + 18H
|
|
MPGSEL_1 EQU SBC_BASE + 19H
|
|
MPGSEL_2 EQU SBC_BASE + 1AH
|
|
MPGSEL_3 EQU SBC_BASE + 1BH
|
|
MPGENA EQU SBC_BASE + 1CH
|
|
ENDIF
|
|
|
|
IF N8
|
|
N8_BASE EQU 80H ; BASE I/O ADDRESS BOARD PERIPHERALS (NON-CPU)
|
|
ACR EQU N8_BASE + 14H ; AUXILLARY CONTROL REGISTER
|
|
DEFACR EQU 1BH ; DEFAULT VALUE FOR ACR
|
|
CPU_BBR EQU 40H + 39H
|
|
ENDIF
|
|
|
|
IF MK4
|
|
CPU_BBR EQU 40H + 39H
|
|
ENDIF
|
|
|
|
CSEG
|
|
|
|
IF INTPXY
|
|
|
|
DB 0 ; Prevents link error in BPBUILD
|
|
|
|
HB_XFC EQU 0FFE0H
|
|
HB_XFCIMG EQU $
|
|
|
|
.PHASE HB_XFC
|
|
HB_CURBNK DB 0
|
|
HB_INVBNK DB 0
|
|
HB_SRCADR DW 0
|
|
HB_SRCBNK DB 0
|
|
HB_DSTADR DW 0
|
|
HB_DSTBNK DB 0
|
|
HB_CPYLEN DW 0
|
|
DB 0,0,0,0,0,0
|
|
HB_INVOKE JP HBX_INVOKE
|
|
HB_BNKSEL JP HBX_BNKSEL
|
|
HB_BNKCPY JP HBX_BNKCPY
|
|
HB_BNKCALL JP 0 ; HBX_BNKCALL (NOT IMPLEMENTED)
|
|
DB 0,0 ; RESERVED
|
|
HB_IDENT DW 0 ; HBX_IDENT
|
|
.DEPHASE
|
|
|
|
HB_XFCSIZ EQU $ - HB_XFCIMG
|
|
|
|
ELSE
|
|
|
|
HBX_INVOKE EQU 0FFF0H
|
|
HBX_BNKSEL EQU 0FFF3H
|
|
HBX_BNKCPY EQU 0FFF6H
|
|
HBX_BNKCALL EQU 0FFF9H
|
|
|
|
HB_CURBNK EQU 0FFE0H
|
|
HB_INVBNK EQU 0FFE1H
|
|
HB_SRCADR EQU 0FFE2H
|
|
HB_SRCBNK EQU 0FFE4H
|
|
HB_DSTADR EQU 0FFE5H
|
|
HB_DSTBNK EQU 0FFE7H
|
|
HB_CPYLEN EQU 0FFE8H
|
|
|
|
ENDIF
|
|
|
|
;
|
|
;==================================================================================================
|
|
; HBIOS INTERFACE
|
|
;==================================================================================================
|
|
;
|
|
HBX_INIT:
|
|
|
|
IF INTPXY
|
|
|
|
; Copy HB_XFCIMG to target location
|
|
LD HL,HB_XFCIMG
|
|
LD DE,HB_XFC ; point to HBIOS comm block
|
|
LD BC,HB_XFCSIZ
|
|
LDIR
|
|
|
|
; Setup RST 08 vector
|
|
LD A,0C3H ; $C3 = JP
|
|
LD (08H),A
|
|
LD HL,HBX_INVOKE
|
|
LD (09H),HL
|
|
|
|
ENDIF
|
|
|
|
; Init HB data fields
|
|
LD A,BID_USR
|
|
LD (HB_CURBNK),A
|
|
LD (HB_SRCBNK),A
|
|
LD (HB_DSTBNK),A
|
|
|
|
IF BANKED
|
|
|
|
; Copy vectors from TPA page zero to SYS page zero
|
|
LD BC,(TPABNK) ; C := TPABNK, B := SYSBNK
|
|
CALL XMOVE ; Set source/dest banks for copy
|
|
LD HL,0 ; Source address is zero
|
|
LD DE,0 ; Destination address is zero
|
|
LD BC,40H ; Copy 40H bytes
|
|
CALL MOVE ; Do it
|
|
LD A,(TPABNK) ; Set all Bank regs to TPA
|
|
|
|
ENDIF
|
|
|
|
RET
|
|
|
|
HBX_XCOPY:
|
|
LD A,C
|
|
LD (HB_SRCBNK),A
|
|
LD A,B
|
|
LD (HB_DSTBNK),A
|
|
RET
|
|
|
|
HBX_COPY:
|
|
JP HBX_BNKCPY
|
|
|
|
IF INTPXY
|
|
|
|
;==================================================================================================
|
|
; SELECT MEMORY BANK FOR LOWER 32K
|
|
;==================================================================================================
|
|
|
|
HBX_BNKSEL:
|
|
LD (HB_CURBNK),A
|
|
|
|
IF N8VEM OR ZETA
|
|
OUT (MPCL_ROM),A
|
|
OUT (MPCL_RAM),A
|
|
RET
|
|
ENDIF
|
|
|
|
IF 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
|
|
ENDIF
|
|
|
|
IF N8
|
|
BIT 7,A
|
|
JR Z,HBX_ROM
|
|
;
|
|
HBX_RAM:
|
|
RES 7,A
|
|
RLCA
|
|
RLCA
|
|
RLCA
|
|
OUT0 (CPU_BBR),A
|
|
LD A,DEFACR | 80H
|
|
OUT0 (ACR),A
|
|
RET
|
|
;
|
|
HBX_ROM:
|
|
OUT0 (RMAP),A
|
|
XOR A
|
|
OUT0 (CPU_BBR),A
|
|
LD A,DEFACR
|
|
OUT0 (ACR),A
|
|
RET
|
|
ENDIF
|
|
|
|
IF MK4
|
|
RLCA
|
|
RLCA
|
|
RLCA
|
|
OUT0 (CPU_BBR),A
|
|
RET
|
|
|
|
ENDIF
|
|
|
|
;==================================================================================================
|
|
; INTERBANK MEMORY COPY
|
|
;==================================================================================================
|
|
|
|
HBX_BNKCPY:
|
|
HB_DI ; NOTE: ONLY REQUIRED WHEN USING IM 1
|
|
|
|
LD (HBX_STKSAV),SP
|
|
LD SP,HBX_TMPSTK
|
|
LD A,(HB_CURBNK) ; GET CURRENT BANK
|
|
PUSH AF ; AND SAVE TO RESTORE LATER
|
|
PUSH BC ; CUR LEN -> (SP)
|
|
;
|
|
HBX_BC_LOOP:
|
|
EX (SP),HL ; HL := CUR LEN, (SP) := CUR SRC
|
|
LD BC,HBX_BUFSIZ ; SET BC TO BOUNCE BUFFER SIZE
|
|
OR A ; CLEAR CARRY FLAG
|
|
SBC HL,BC ; CUR LEN := CUR LEN - BBUF SIZE
|
|
JR C,HBX_BC_LAST ; END GAME, LESS THAN BBUF BYTES LEFT
|
|
EX (SP),HL ; HL := CUR SRC, (SP) := REM LEN
|
|
CALL HBX_BC_ITER ; DO A FULL BBUF SIZE CHUNK
|
|
JR HBX_BC_LOOP ; AND REPEAT TILL DONE
|
|
;
|
|
HBX_BC_LAST:
|
|
; HL IS BETWEEN -(BBUF SIZE) AND -1, BC = BBUF SIZE
|
|
OR A ; CLEAR CARRY
|
|
ADC HL,BC ; HL := REM LEN (0 - 127)
|
|
EX (SP),HL ; HL := CUR SRC, (SP) := REM LEN
|
|
POP BC ; BC := REM LEN
|
|
CALL NZ,HBX_BC_ITER ; DO FINAL CHUNK, BUT ONLY IF NOT ZERO BYTES
|
|
POP AF ; RECOVER ORIGINAL BANK
|
|
CALL HBX_BNKSEL ; SWITCH TO CURRENT BANK AND EXIT
|
|
LD SP,(HBX_STKSAV)
|
|
|
|
HB_EI ; NOTE: ONLY REQUIRED WHEN USING IM 1
|
|
|
|
RET
|
|
;
|
|
HBX_BC_ITER:
|
|
; HL = SRC ADR, DE = DEST ADR, BC = LEN
|
|
PUSH BC ; SAVE COPY LEN
|
|
PUSH DE ; FINAL DEST ON STACK
|
|
LD DE,HBX_BUF ; SET DEST TO BUF
|
|
LD A,(HB_SRCBNK) ; GET SOURCE BANK
|
|
CALL HBX_BNKSEL ; SWITCH TO SOURCE BANK
|
|
LDIR ; HL -> BUF (DE), BC BYTES, HL UPDATED SRC ADR
|
|
POP DE ; DE := FINAL DEST
|
|
POP BC ; GET LEN BACK IN BC
|
|
PUSH HL ; SAVE UPDATED SRC ADR
|
|
LD HL,HBX_BUF ; SET SRC ADR TO BUF
|
|
LD A,(HB_DSTBNK) ; GET DEST BANK
|
|
CALL HBX_BNKSEL ; SWITCH TO DEST BANK
|
|
LDIR ; BUF (HL) -> DE, BC BYTES, DE UPDATED DEST ADR
|
|
POP HL ; RECOVER UPDATED SRC ADR
|
|
; HL = UPD SRC, DE = UPD DEST, BC = 0
|
|
RET
|
|
|
|
;==================================================================================================
|
|
; ENTRY POINT FOR BIOS FUNCTIONS (TARGET OF RST 08)
|
|
;==================================================================================================
|
|
|
|
HBX_INVOKE:
|
|
LD (HBX_INVSP),SP ; SAVE ORIGINAL STACK FRAME
|
|
LD A,(HB_CURBNK) ; GET CURRENT BANK
|
|
LD (HB_INVBNK),A ; SAVE INVOCATION BANK
|
|
|
|
; HB_DI
|
|
LD SP,HBX_TMPSTK ; USE SMALL TEMP STACK FRAME IN HI MEM FOR BANK SWITCH
|
|
LD A,BID_HB ; HBIOS BANK
|
|
CALL HBX_BNKSEL ; SELECT IT
|
|
LD SP,HB_STACK ; NOW USE FULL HBIOS STACK IN HBIOS BANK
|
|
; HB_EI
|
|
|
|
CALL HB_DISPATCH ; CALL HBIOS FUNCTION DISPATCHER
|
|
|
|
; HB_DI
|
|
LD SP,HBX_TMPSTK ; USE SMALL TEMP STACK FRAME IN HI MEM FOR BANK SWITCH
|
|
PUSH AF ; SAVE AF (FUNCTION RETURN)
|
|
LD A,(HB_INVBNK) ; LOAD ORIGINAL BANK
|
|
CALL HBX_BNKSEL ; SELECT IT
|
|
POP AF ; RESTORE AF
|
|
LD SP,0 ; RESTORE ORIGINAL STACK FRAME
|
|
HBX_INVSP EQU $ - 2
|
|
; HB_EI
|
|
|
|
RET ; RETURN TO CALLER
|
|
|
|
ENDIF
|
|
|
|
;==================================================================================================
|
|
; LD A,(C:HL)
|
|
;==================================================================================================
|
|
|
|
HBX_FRGETB:
|
|
LD (HBX_STKSAV),SP ; Save current stack
|
|
LD SP,HBX_TMPSTK ; Activate our private stack
|
|
LD A,(HB_CURBNK) ; Get current bank
|
|
LD (HBX_BNKSAV),A ; Save current bank
|
|
PUSH BC
|
|
LD A,C
|
|
HB_DI
|
|
CALL HBX_BNKSEL
|
|
LD C,(HL)
|
|
LD A,(HBX_BNKSAV)
|
|
CALL HBX_BNKSEL
|
|
HB_EI
|
|
LD A,C
|
|
POP BC
|
|
LD SP,(HBX_STKSAV) ; RESTORE ORIGINAL STACK FRAME
|
|
RET
|
|
|
|
;==================================================================================================
|
|
; LD DE,(C:HL)
|
|
;==================================================================================================
|
|
|
|
HBX_FRGETW:
|
|
LD (HBX_STKSAV),SP ; Save current stack
|
|
LD SP,HBX_TMPSTK ; Activate our private stack
|
|
LD A,(HB_CURBNK) ; Get current bank
|
|
LD (HBX_BNKSAV),A ; Save current bank
|
|
LD A,C
|
|
HB_DI
|
|
CALL HBX_BNKSEL
|
|
LD E,(HL)
|
|
INC HL
|
|
LD D,(HL)
|
|
DEC HL
|
|
LD A,(HBX_BNKSAV)
|
|
CALL HBX_BNKSEL
|
|
HB_EI
|
|
LD SP,(HBX_STKSAV) ; RESTORE ORIGINAL STACK FRAME
|
|
RET
|
|
|
|
;==================================================================================================
|
|
; LD (C:HL),A
|
|
;==================================================================================================
|
|
|
|
HBX_FRPUTB:
|
|
LD (HBX_STKSAV),SP ; Save current stack
|
|
LD SP,HBX_TMPSTK ; Activate our private stack
|
|
PUSH AF
|
|
LD A,(HB_CURBNK) ; Get current bank
|
|
LD (HBX_BNKSAV),A ; Save current bank
|
|
POP AF
|
|
PUSH BC
|
|
LD B,A
|
|
LD A,C
|
|
HB_DI
|
|
CALL HBX_BNKSEL
|
|
LD (HL),B
|
|
LD A,(HBX_BNKSAV)
|
|
CALL HBX_BNKSEL
|
|
HB_EI
|
|
POP BC
|
|
LD SP,(HBX_STKSAV) ; RESTORE ORIGINAL STACK FRAME
|
|
RET
|
|
|
|
;==================================================================================================
|
|
; LD (C:HL),DE
|
|
;==================================================================================================
|
|
|
|
HBX_FRPUTW:
|
|
LD (HBX_STKSAV),SP ; Save current stack
|
|
LD SP,HBX_TMPSTK ; Activate our private stack
|
|
LD A,(HB_CURBNK) ; Get current bank
|
|
LD (HBX_BNKSAV),A ; Save current bank
|
|
LD A,C
|
|
HB_DI
|
|
CALL HBX_BNKSEL
|
|
LD (HL),E
|
|
INC HL
|
|
LD (HL),D
|
|
DEC HL
|
|
LD A,(HBX_BNKSAV)
|
|
CALL HBX_BNKSEL
|
|
HB_EI
|
|
LD SP,(HBX_STKSAV) ; RESTORE ORIGINAL STACK FRAME
|
|
RET
|
|
|
|
;==================================================================================================
|
|
; PRIVATE DATA
|
|
;==================================================================================================
|
|
|
|
DSEG
|
|
|
|
HB_DSKBUF DEFW 0 ; Address of physical disk buffer in HBIOS bank
|
|
HBX_BNKSAV DEFB 0 ; Saved bank id during HBIOS calls
|
|
HBX_STKSAV DEFW 0 ; Saved stack pointer during HBIOS calls
|
|
DEFS 32 ; Private stack for HBIOS
|
|
HBX_TMPSTK EQU $ ; Top of private stack
|
|
|
|
IF INTPXY
|
|
|
|
HBX_BUFSIZ EQU 40H
|
|
HBX_BUF DEFS HBX_BUFSIZ ; Interbank copy buffer
|
|
|
|
ENDIF
|
|
|