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