TITLE TRANSFER - Z80 TO 6502 TRANSFER SUBTTL EQUATES, MACROS PUBLIC ITRAN ;TRANSFER INITIALIZATION ROUTINE ; VERSION SWITCHES ; ; THESE SWITCHES DETERMINE WHICH REGISTERS WILL BE PASSED RGS8080 ASET 1 ;1 TO PASS 8080 REGISTER SUBSET: SP,HL,BC,DE,AF PRIME ASET 0 ;1 TO PASS PRIME REGISTERS: HL',BC',DE',AF' INTRFSH ASET 0 ;1 TO PASS INTERRUPT & REFRESH REGISTERS INDEX ASET 0 ;1 TO PASS IX,IY INDEX REGISTERS IF1 .PRINTX * PASSING ALL REGISTERS * IFE RGS8080 AND PRIME AND INTRFSH AND INDEX .PRINTX * EXCEPT: * ENDIF IFE RGS8080 .PRINTX * 8080 REGISTER SUBSET * ENDIF IFE PRIME .PRINTX * ALTERNATE REGISTERS * ENDIF IFE INTRFSH .PRINTX * INTERRUPT & REFRESH * ENDIF IFE INDEX .PRINTX * INDEX REGISTERS * ENDIF IFE RGS8080 .PRINTX ! CANNOT BE DEBUGGED WITH DDT65 ! ENDIF ENDIF ; EQUATES: REGPTRZ EQU 0008H ;Z80 ADDRESS OF POINTER TO REGISTER PASS AREA VEC65 EQU 000AH ;Z80 ADDRESS OF NORMAL 6502 RETURN ROUTINE VEC65A EQU 000CH ;Z80 ADDRESS OF ALTERNATE 6502 RETURN ROUTINE ALTFLG EQU 000EH ;ALTERNATE/NORMAL RETURN ROUTINE FLAG TRAN EQU 000FH ;POSITION-INDEPENDENT ENTRY POINT TO TRAN1 REGPTR6 EQU 0F0FAH ;6502 ADDRESS OF PTR TO REGISTER PASS AREA Z80SLT EQU 0F3DEH ;SLOT ADDRESS OF Z80 CARD GO6502 EQU 0F3D0H ;6502 SUBROUTINE CALL ADDRESS ; MACRO DEFINITION PRINTE MACRO N,MSG ;MACRO TO PRINT 'BYTES GENERATED' IF1 .PRINTX * N MSG * ENDIF ENDM SUBTTL ITRAN - TRANSFER INITIALIZATION PAGE ; ITRAN ; ; ROUTINE TO INITIALIZE TRANSFER. ITRAN SETS UP REGPTRZ ; AND REGPTR6 TO POINT TO THE REGISTER PASS AREAS. IT ALSO ; STORES A 'JP TRAN1' INSTRUCTION AT LOCATION TRAN. FINALLY, ; ALTFLG IS INITIALIZED TO ZERO, AND BOTH VEC65 AND VEC65A ARE ; SET TO POINT TO BACK65, THE STANDARD 6502 RE-ENTRY ROUTINES. ; .Z80 ITRAN: LD HL,PASSA ;STORE ADDRESS OF REGISTER PASS AREA LD (REGPTRZ),HL ;INTO REGPTRZ LD HL,PASSA+1000H ;STORE 6502 ADDRESS OF REG PASS AREA LD (REGPTR6),HL ;INTO REGPTR6 LD A,0C3H ;STORE 'JP' INSTRUCTION AT TRAN LD (TRAN),A LD HL,TRAN1 ;STORE ADDRESS FIELD LD (TRAN+1),HL LD HL,BACK65 ;ADDRESS OF NORMAL 6502 RE-ENTRY ROUTINE LD (VEC65),HL ;INTO BOTH VECTORS JUST IN CASE LD (VEC65A),HL XOR A ;FLAG USING NORMAL RE-ENTRY VECTOR LD (ALTFLG),A RET SUBTTL TRAN1 - Z80 SUBROUTINE CALLER PAGE ; ; TRAN1 ; ; THIS CODE PERFORMS THE ACTUAL Z80 SUBROUTINE CALL. ON ENTRY, ; THE CONTENTS OF ALL Z80 REGISTERS ARE SAVED IN THE REGISTER ; PASS AREA. THEN, DEPENDING ON THE STATE OF ALTFLG, THE 6502 ; ROUTINE POINTED TO BY EITHER VEC65 OR VEC65A IS CALLED. ; UPON RETURN, PASSA+ZPC IS ASSUMED TO CONTAIN THE ADDRESS OF ; A Z80 SUBROUTINE TO CALL. SO, THE Z80 REGISTERS ARE LOADED ; FROM THE PASS AREA AND THE SUBROUTINE IS CALLED. HOWEVER, IF ; ALTFLG WAS NON-ZERO, THE CODE SIMPLY DOES A RETURN TO THE Z80 ; PROGRAM THAT INITIALLY CALLED 'TRAN'; NO SUBROUTINE CALL IS ; PERFORMED. ; ; SET THE SWITCHES AT THE BEGINNING OF THIS PROGRAM TO DETERMINE ; WHICH REGISTERS ARE PASSED IN THE REGISTER PASS AREA. ; TRAN1: IF RGS8080 LD (PASSA+ZSP),SP ;SAVE 8080 REGISTER SUBSET LD (PASSA+ZHL),HL LD (PASSA+ZDE),DE LD (PASSA+ZBC),BC PUSH AF ;GET A & F TO HL BY PUSHING POP HL ;AND POPPING INTO HL LD (PASSA+ZAF),HL ENDIF IF INDEX LD (PASSA+ZIX),IX LD (PASSA+ZIY),IY ENDIF IF INTRFSH LD A,I ;SAVE INTERRUPT REGISTER LD (PASSA+ZI),A LD A,R ;AND REFRESH REGISTERS LD (PASSA+ZR),A ENDIF IF PRIME EX AF,AF' PUSH AF ;PUSH ALTERNATE A & FLAGS POP HL ;POP THEM INTO HL LD (PASSA+ZAFP),HL EXX ;NOW SAVE ALTERNATE REGISTERS LD (PASSA+ZHLP),HL LD (PASSA+ZDEP),DE LD (PASSA+ZBCP),BC ENDIF LD A,(ALTFLG) ;SEE WHETHER TO USE VEC65 OR VEC65A OR A JR Z,NORMVEC ;USE VEC65 IF ZERO LD HL,(VEC65A) ;ELSE USE ALTERNATE 6502 ROUTINE TO EXECUTE XOR A LD (ALTFLG),A ;ALWAYS CLEAR ALTFLG JR GOVEC NORMVEC: LD HL,(VEC65) ;NORMAL 6502 ROUTINE TO EXECUTE GOVEC: LD (GO6502),HL LD HL,(Z80SLT) LD (HL),A ;TURN ON 6502 AND PUT Z80 TO SLEEP IF RGS8080 LD SP,(PASSA+ZSP) ;RESTORE STACK VALUE HERE FOR PUSHES LATER ENDIF LD A,(ALTFLG) ;NOW SEE IF 6502 WANTS US TO RETURN OR A ;OR CALL A SUBROUTINE JR NZ,RSTRGS ;IF NZ, THEN RESTORE REGISTER & RETURN. Z80SUB: LD HL,TRAN1 ;MAKE SURE SUBROUTINE WILL RETURN TO TRAN1 PUSH HL ;BY PUSHING A PSEUDO-RETURN ADDRESS LD HL,(PASSA+ZPC) ;GET ADDR OF SUBROUTINE TO CALL PUSH HL ;AND SAVE ON STACK - GO VIA RET LATER XOR A LD (ALTFLG),A ;CLEAR ALTERNATE VECTOR FLAG RSTRGS: IF PRIME LD HL,(PASSA+ZHLP) ;RESTORE PRIME REGISTERS LD DE,(PASSA+ZDEP) LD BC,(PASSA+ZBCP) EXX ;GET THEM INTO ALTERNATE REGISTERS LD HL,(PASSA+ZAFP) ;GET AF' PUSH HL POP AF EX AF,AF' ;PUT IN ALTERNATE REGISTERS ENDIF IF INTRFSH LD A,(PASSA+ZI) ;GET I & R REGISTERS LD I,A ;SET UP INTERRUPT REGISTER LD A,(PASSA+ZR) LD R,A ;SET UP REFRESH REGISTER ENDIF IF RGS8080 LD HL,(PASSA+ZAF) ;GET A & FLAGS PUSH HL POP AF LD HL,(PASSA+ZHL) LD DE,(PASSA+ZDE) LD BC,(PASSA+ZBC) ENDIF IF INDEX LD IX,(PASSA+ZIX) LD IY,(PASSA+ZIY) ENDIF RET ;DISPATCH TO SUBROUTINE (OR RETURN TO CALLER) SUBTTL NORMAL 6502 RE-ENTRY CODE PAGE ; ; BACK65 ; ; THIS SHORT SUBROUTINE IS USED TO RETURN TO THE INITIAL ; 'JSR $3C0' THAT WAS USED TO CALL THE Z80 SUBROUTINE. IT ; SIMPLY POPS OFF THE RETURN ADDRESS PUSHED BY THE 'JSR' AT ; $3CF (MAKING IT A 'JMP') AND RETURNS. ; ; A,X,Y & STATUS ARE UNKNOWN AFTER A RETURN. ; .6502 .PHASE *+$1000 BACK65: PLA ;POP OFF RETURN ADDR TO MAKE PLA ;'JSR' AT $3CF A 'JMP' RTS ;NOW RETURN TO ORIGINAL CALLER .DEPHASE SUBTTL REGISTER PASS AREA AND REGISTER OFFSETS PAGE ; REGISTER OFFSETS INTO REGISTER PASS AREA: DSECT ;TO GENERATE OFFSETS ORG 0 ;RELATIVE TO ZERO ; NOTE: SPACE FOR ALL REGS MUST BE ALLOCATED FOR USE WITH DDT65 ZPC: DS 2 ;PROGRAM COUNTER REGISTER OFFSET ZAF: DS 2 ;ACCUMULATOR AND FLAGS ZBC: DS 2 ;BC ZDE: DS 2 ;DE ZHL: DS 2 ;HL ZSP: DS 2 ;STACK POINTER ZAFP: DS 2 ;PRIME ACC AND FLAGS ZBCP: DS 2 ;BC' ZDEP: DS 2 ;DE' ZHLP: DS 2 ;HL' ZIX: DS 2 ;IX ZIY: DS 2 ;IY ZI: DS 1 ;INTERRUPT REGISTER ZR: DS 1 ;REFRESH REGISTER PASSIZ EQU $ ;SIZE OF REGISTER PASS AREA DEND ; REGISTER PASS AREA PASSA: DS PASSIZ PRINTE %($-ITRAN), SUBTTL SYMBOL TABLE END