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

;:::::::::::::::::::::::::::::::::::::::*****************************
; 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