;:::::::::::::::::::::::::::::::::::::::***************************** ; IBMOVE - Inter-Bank Move Routines ***** Hardware-Specific ***** ; D-X Designs Pty Ltd P112 ***************************** ; ; 1.0a- 17 Aug 01 - Cleaned up for GPL Release. HFB ; 1.0 - 10 Jun 96 - Initial Release for P112 from YASBEC. HFB ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 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: LD (ICNT),BC ; Save length of move LD BC,(SRCBNK) ; Get Source (C) and Dest (B) Banks RL H ; Move MSB of Source Addr to Carry LD A,C ; .get Source Bank JR NC,MOVB0 ; ..jump if Source < 8000H (Not Common Bank) LD A,(TPABNK) ; Else Set to TPA Bank for Common Access MOVB0: ADC A,0 ; ..add Carry to Bank # RRA ; ...shift Bank # in position for Z-180 DMA RR H ; .move Carry to Address Bit 7 LD (ISRC+2),A ; Save Source Bank physical byte LD (ISRC),HL ; ..and Save Source Address RL D ; Move MSB of Dest Addr to Carry LD A,B ; .Get Destination Bank JR NC,MOVB1 ; ..jump if Source < 8000H (Not Common Bank) LD A,(TPABNK) ; Else Set to TPA Bank for Common Access MOVB1: ADC A,0 ; ..add Carry to Bank # RRA ; ...shift into position for Z-180 DMA RR D ; .move Carry to Address Bit 7 LD (IDST+2),A ; Save Destination Bank byte LD (IDST),DE ; ..and Save Destination Address LD HL,ISRC ; Point to DMA Initialization block CALL DMAMOV ; ..and use the Z-180 DMA LD HL,(TPABNK) ; Get TPA Bank # LD H,L ; .to both H and L LD (SRCBNK),HL ; ..set Source & Destination Bank # to TPA RET ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ; 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 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 IN0 A,(BBR) ; Get current bank address 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 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 OUT0 (BBR),A ; ..and make it current 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 OUT0 (BBR),A ; ..and make current 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: IN0 A,(BBR) ; Read Bank Base Register RRA ; Shift RRA ; .to right RRA ; ..to give Bank # AND 1FH ; Mask off junk RET ; ..and return it to caller ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ; Set Bank into context. Save all Registers. ; A = Bank ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::: SELMEM: LD (USRBNK),A ; Update user bank ;..fall thru to set specified bank.. ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ; 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 ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: SELBNK: PUSH AF ; Save regs SELBN0: LD (CURBNK),A ; Save as current bank # ADD A,A ; Shift into position for Z-180 DMA regs ADD A,A ADD A,A OUT0 (BBR),A ; ..and Set the bank offset 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: LD (SRCBNK),BC RET ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ; 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: IN0 A,(BBR) ; Get current bank control byte PUSH BC ; Save regs LD B,A ; ..and entry bank LD A,C ; Get source bank ADD A,A ; Shift into position for Z-180 DMA regs ADD A,A ADD A,A DI ; .no Ints here OUT0 (BBR),A ; ..and Set the bank offset LD C,(HL) ; Get the byte LD A,B ; .entry bank OUT0 (BBR),A ; ..and restore entry bank EI LD A,C ; Get the byte POP BC ; ..and restore regs RET ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ; Load DE,(HL) from Alternate Bank ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::: FRGETW: PUSH BC ; Save regs LD B,A ; ..and entry bank IN0 A,(BBR) ; Get current Bank Byte LD (ASAVE),A ; ..saving locally LD A,C ; Get source bank ADD A,A ; Shift into position for Z-180 DMA regs ADD A,A ADD A,A DI ; .no ints allowed here OUT0 (BBR),A ; ..and Set the bank offset LD E,(HL) ; Get Low byte INC HL LD D,(HL) ; ..and High byte DEC HL ; Retain addr pointer JR GPEX ; ..and exit ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ; Load (HL),A to Alternate Bank (in Reg C) ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::: FRPUTB: PUSH BC ; Save all regs LD B,A ; Store byte temporarily IN0 A,(BBR) ; Get current bank byte LD (ASAVE),A ; ..saving in Common Memory LD A,C ; Get destination bank ADD A,A ; Shift into position for Z-180 DMA regs ADD A,A ADD A,A DI ; .allowing no interrupts OUT0 (BBR),A ; ..and Set the bank offset LD (HL),B ; ..and stuff the byte GPEX: LD A,(ASAVE) ; Retrieve Entry Bank byte OUT0 (BBR),A ; ..and restore to active EI ; Interrupts Ok now LD A,B ; Restore byte POP BC ; ..and rest of regs RET ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ; Load (HL),DE to Alternate Bank ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::: FRPUTW: PUSH BC ; Save regs LD B,A ; ..and entry bank IN0 A,(BBR) ; Get current Bank Byte LD (ASAVE),A ; ..saving locally LD A,C ; Get source bank ADD A,A ; Shift into position for Z-180 DMA regs ADD A,A ADD A,A DI ; .no Ints allowed OUT0 (BBR),A ; ..and Set the bank offset LD (HL),E ; Save Low byte INC HL LD (HL),D ; ..and High byte DEC HL ; Retain addr pointer JR GPEX ; ..and exit ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::: DSEG JPBNK: DEFS 1 ; Bank # for Far Jump or Call USRBNK: DEFS 1 ; User's selected bank # CURBNK: DEFS 1 ; Current bank # SRCBNK: DEFS 1 ; Move Source Bank # DSTBNK: DEFS 1 ; Move Destination Bank # DMABNK: DEFS 1 ; Target bank # for disk xfers DEFS 64 ; 32 level stack USP: DEFS 2 ; User stack pointer ASAVE: DEFS 1 ; Temp storage for User's A-Register ; Z-180 DMA transfer block for inter-bank moves ISRC: DEFS 2 ; Source Segment address DEFS 1 ; ..Source Bank in physical RAM IDST: DEFS 2 ; Destination Segment address DEFS 1 ; ..Destination Bank in physical RAM ICNT: DEFS 2 ; Number of bytes to move ; The P112 does not need this buffer, but other versions might IF INROM OR [NOT IBMOVS] DSEG IBMVBF: DEFS 256 ; Inter-bank move buffer ENDIF ;======================= End of IBMV-DX ===========================