;:::::::::::::::::::::::::::::::::::::::***************************** ; IBMOVE - Inter-Bank Move Routines ***** Hardware-Specific ***** ; using RomWBW HBIOS ***************************** ; ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: CSEG ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ; Move Data - Possibly between banks. This resembles CP/M 3, but ; usage of the HL and DE registers is reversed. ; Enter: HL = Source Address ; DE = Destination Address ; BC = Number of bytes to move ; Exit : None ; Uses : AF,BC,DE,HL ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: MOVE EQU HB_MOVE ; Defer to HBIOS (see HBIOS.Z80) ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ; Routine to Switch to Local Stack for Banked Operations ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::: CSEG BIOSTK: DEFB 0 ; NOP if not currently in bank, ; ..RET if we are LD (USP-7),HL ; Save entry HL POP HL ; Retrieve caller's return address from stack LD (USP-5),HL ; ..and set in our stack for local return HB_DI ; No interrupts while we play with the stack LD (USP),SP ; Save User's Stack Pointer LD SP,USP-1 ; ..and point locally, saving 1 byte for Bank PUSH AF ; Save entry A and Flags ;LD A,(HB_CURBNK) ; Get current bank LD A,(CURBNK) ; Get current bank LD (USP-1),A ; ..and save for exitting LD A,0C9H ; Disable other calls here LD (BIOSTK),A ; ..by poking a RETurn at entry POP AF ; Restore entry AF LD HL,USRSTK ; Set banked return address PUSH HL ; ..at USP-2 & 3 LD SP,USP-7 ; Point stack pointer to do local return POP HL ; .restoring entry HL HB_EI ; ..enabling interrupts RET ; And return to caller ; Restore User Stack and Bank Routine USRSTK: PUSH AF LD A,(USP-1) ; Get bank control byte from entry CALL SELBNK XOR A LD (BIOSTK),A ; Patch NOP back in at start of code POP AF LD SP,(USP) ; Restore user stack RET ; And return to caller ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ; Restore Bank and Stack Ptr to Entry and Jump to (HL) ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: FRCLR: PUSH AF ; Save any entry in AF LD A,(USP-1) ; Get bank control byte CALL SELBNK XOR A LD (BIOSTK),A ; Patch NOP to enable stack switcher POP AF LD SP,(USP) ; Restore User Stack JP (HL) ; ..and jump to vector ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ; Abort a Process (possibly in Alternate Bank) and Warm Boot ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ABORT: LD SP,USP ; Insure stack is in Common Memory LD A,(TPABNK) CALL SELBNK ; Insure TPA in Context XOR A LD (BIOSTK),A ; Remove patch RST 0 ; ..And Warm Boot ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ; Return Current Memory Bank in Context ; Entry: none ; Exit : A = Current Memory Bank ; Uses : AF ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::: RETMEM: LD A,(CURBNK) RET ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ; Set Bank into context. Save all Registers. ; A = Bank ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::: SELMEM: LD (USRBNK),A ; Update user bank ;..fall thru to set specified bank.. IF HB_DEBUG AND FALSE CALL PRTSTRD DEFB '[SELMEM: $' CALL PRTHEXBYTE CALL PRTSTRD DEFB ']$' ENDIF ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ; SELBNK - Switch Memory Bank to Bank in A and show as current. ; Must preserve all Registers including Flags. ; All Bank Switching MUST be done by this routine ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ; ; Parameter to BNKADJ (ADD) is set dynamically at initialization. SELBNK: PUSH AF ; Save regs SELBN0: LD (CURBNK),A ; Save as current bank # IF HB_DEBUG AND FALSE CALL PRTSTRD DEFB '[SELBNK: $' CALL PRTHEXBYTE CALL PRTSTRD DEFB ']$' ENDIF CALL HBX_BNKSEL POP AF ; restore regs RET ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ; Set Bank for DMA Xfer. Preserve All Registers ; A = Bank Number ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::: SETBNK: LD (DMABNK),A RET ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ; Set Banks for Inter-Bank Xfer. Save all Registers. ; B = Destination Bank, C = Source Bank ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::: XMOVE: EQU HB_XMOVE ; Defer to HBIOS (see HBIOS.Z80) ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ; Select System Bank ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::: GOSYSB: PUSH AF LD A,(SYSBNK) ; Get system bank JR SELBN0 ; ..and set ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ; Set Bank for FRJP and FRCALL (Reg A) ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::: STFARC: LD (JPBNK),A RET ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ; Jump to (HL) in Alternate Bank ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::: FRJP: CALL BIOSTK ; Insure we are in a common stack PUSH AF LD A,(JPBNK) CALL SELBNK ; Select the destination bank POP AF JP (HL) ; ..and go ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ; Load A,(HL) from Alternate Bank (in Reg C) ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::: FRGETB: PUSH BC ; Save BC PUSH DE ; Save DE LD B,0FAH ; HBIOS Peek function LD D,C CALL HBX_INVOKE ; Do it LD A,E ; Value to A POP DE ; Restore DE POP BC ; Restore BC RET ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ; Load DE,(HL) from Alternate Bank ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::: FRGETW: PUSH AF ; Save AF CALL FRGETB ; Get LSB LD E,A ; ... into E INC HL ; Next address CALL FRGETB ; Get MSB LD D,A ; ... into D DEC HL ; Restore HL POP AF ; Restore AF RET ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ; Load (HL),A to Alternate Bank (in Reg C) ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::: FRPUTB: PUSH AF ; Save AF PUSH BC ; Save BC PUSH DE ; Save DE LD B,0FBH ; HBIOS Poke function LD E,A ; Value in E LD D,C CALL HBX_INVOKE ; Do it POP DE ; Restore DE POP BC ; Restore BC POP AF ; Restore AF RET ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ; Load (HL),DE to Alternate Bank ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::: FRPUTW: PUSH AF ; Save AF LD A,E ; LSB to A CALL FRPUTB ; Put LSB LD A,D ; MSB to A INC HL ; Next address CALL FRPUTB ; Put MSB DEC HL ; Restore HL POP AF ; Restore AF RET ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::: DSEG JPBNK: DEFS 1 ; Bank # for Far Jump or Call USRBNK: DEFS 1 ; User's selected bank # CURBNK: DEFS 1 ; Current bank # SRCBNK: EQU HB_SRCBNK ; Move Source Bank # DSTBNK: EQU HB_DSTBNK ; Move Destination Bank # DMABNK: DEFS 1 ; Target bank # for disk xfers DEFS 64 ; 32 level stack USP: DEFS 2 ; User stack pointer ;======================= End of IBMV-WW ===========================