TITLE DEMO SUBTTL EQUATES ; ; A SIMPLE DEMONSTRATION OF Z80 SUBROUTINE CALLING BY A 6502 PROGRAM. ; THE 6502 PROGRAM BELOW ACTUALLY PERFORMS A CP/M FUNCTION CALL TO ; PRINT A MESSAGE. ; .SALL ;SUPPRESS MACRO EXPANSION ; EXTERNAL DECLARATIONS: EXTRN ITRAN ;CONTROL TRANSFER INITIALIZATION ; Z80 EQUATES: BDOS EQU 0005H ;CP/M BDOS ENTRY POINT REGPTRZ EQU 0008H ;PTR TO Z80 REGISTER SAVE AREA VEC65 EQU 000AH ;PTR TO NORMAL 6502 RE-ENTRY ROUTINE VEC65A EQU 000CH ;PTR TO ALTERNATE 6502 RE-ENTRY ROUTINE ALTFLG EQU 000EH ;ALTERNATE/NORMAL RE-ENTRY FLAG TRAN EQU 000FH ;ENTRY TO CONTROL TRANSFER LOOP GO6502 EQU 0F3D0H ;6502 SUBROUTINE CALL VECTOR Z80SLT EQU 0F3DEH ;ADDRESS OF Z80 CARD PRMSGF EQU 9 ;CP/M PRINT MESSAGE FUNCTION ESC EQU 01BH ;ESCAPE KEY CODE CR EQU 0DH ;CARRIAGE RETURN CHARACTER LF EQU 0AH ;LINE FEED CHARACTER ; 6502 EQUATES: .6502 ;(SO WE CAN USE '$' FOR HEX CONSTANTS) REGPTR6 EQU $FA ;6502 POINTER TO Z80 REG SAVE AREA GOZ80 EQU $3C0 ;ENTRY POINT TO 6502 SUBROUTINE CALLING LOOP KEYBD EQU $C000 ;LOCATION OF APPLE KEYBOARD KBDSTB EQU $C010 ;KEYBOARD STROBE BELL EQU $FBDD ;APPLE MONITOR BELL SUBROUTINE ; OFFSETS INTO Z80 REGISTER SAVE AREA: ZPC EQU 0 ;PROGRAM COUNTER ZBC EQU 4 ;BC REGISTER ZDE EQU 6 ;DE REGISTER SUBTTL MACROS PAGE ; ; MACRO DEFINITIONS: ; ; THESE MACROS ARE INCLUDED ONLY AS EXAMPLES OF SOME USEFUL 6502 ; MACROS, ALTHOUGH NOT ALL OF THEM ARE USED IN THIS PROGRAM. ; PRINTE MACRO N,MSG ;PRINT A MESSAGE (SEE ITS INVOCATION) IF1 .PRINTX * N MSG * ENDIF ENDM SUB MACRO N ;SUBTRACT WITHOUT BORROW SEC SBC N ENDM JEQ MACRO ADDR ;JUMP IF EQUAL BNE *+5 JMP ADDR ENDM RNE MACRO ;RETURN IF NON-ZERO BEQ *+3 RTS ENDM CMI MACRO ADDR ;CALL IF MINUS BPL *+5 JSR ADDR ENDM LDXAI MACRO WORD ;LOAD WORD IMMEDIATE INTO X,A LDA #<(WORD) LDX #>(WORD) ENDM LDAYI MACRO WORD ;LOAD WORD IMMEDIATE INTO A,Y LDY #<(WORD) LDA #>(WORD) ENDM LDYA MACRO ADDR ;LOAD WORD INTO Y,A FROM ADDRESS A LDA ADDR LDY ADDR+1 ENDM SUBTTL MAIN PROGRAM - Z80 CODE PAGE ; ; THIS CODE SIMPLY CALLS THE MAIN 6502 PROGRAM, AND BEEPS ; AFTER IT RETURNS. ; .Z80 DEMO: LD SP,(BDOS+1) ;INIT STACK POINTER TO TOP OF MEMORY CALL ITRAN ;INIT Z80 SUBROUTINE CALLER MECHANISM LD HL,DEMO65 ;SET UP ENTRY POINT OF 6502 CODE LD (VEC65A),HL LD A,1 ;ALTFLG=1 FOR INITIAL ENTRY LD (ALTFLG),A CALL TRAN ;CALL THE 6502 MAIN PROGRAM LD HL,BELL ;NOW CALL THE 6502 BELL SUBROUTINE LD (GO6502),HL ;IN THE APPLE MONITOR WITH A 'STANDARD' LD HL,(Z80SLT) ;6502 SUBROUTINE CALL LD (HL),A ;TURN ON 6502... JP 0 ;REBOOT CP/M AFTER WE HAVE RANG THE BELL SUBTTL MAIN PROGRAM - 6502 CODE PAGE ; ; START OF 6502 CODE ; ; THIS SIMPLY PRINTS A MESSAGE OVER AND OVER UNTIL SOMEONE HITS ; THE ESCAPE KEY ON THE APPLE KEYBOARD. ; .6502 .PHASE *+$1000 ;COMPENSATE FOR Z80 CARD ADDR OFFSET DEMO65: LDX #$FF ;INITIALIZE STACK POINTER TXS DEMLOP: LDAYI MESSAGE ;GET POINTER TO MESSAGE JSR PRMSG ;PRINT IT LDA KEYBD ;SEE IF HE HIT A KEY AND #$7F ;STRIP PARITY BIT (CP/M MAY HAVE EATEN CHAR) CMP #ESC ;WAS IT ESCAPE? BNE DEMLOP ;CONTINUE UNTIL HE DOES STA KBDSTB ;EAT THE CHARACTER (IF CP/M HASN'T ALREADY) ; ; RETURN TO Z80 CODE BY SETTING ALTFLG NON-ZERO. THIS TELLS TRAN ; THAT WE DON'T WANT TO DO A Z80 SUBROUTINE CALL. ; LDA #$FF ;SET ALTFLG=NON-ZERO TO TELL TRAN THAT STA ALTFLG+$1000 ;6502 CODE IS RETURNING JMP GOZ80 ;RETURN TO Z80 ; ; PRMSG - PRINT A MESSAGE ; ; A,Y CONTAIN POINTER TO MESSAGE TO PRINT (A=HI, Y=LO). CHARS IN MSG ; MUST HAVE THEIR HI BITS CLEAR, AND MESSAGE MUST TERMINATE WITH A ; DOLLAR SIGN. ; PRMSG: SUB #$10 ;CONVERT 6502 ADDRESS INTO Z80 ADDRESS TAX ;PUT HI BYTE INTO X TYA ;GET LOW BYTE OF PTR TO A REG LDY #ZDE ;GET PTR TO MSG INTO Z80 D,E REGS JSR STORWD LDY #ZBC ;GET BDOS COMMAND #9 - PRINT MESSAGE LDA #PRMSGF ;INTO Z80 C REGISTER STA (REGPTR6),Y LDXAI BDOS JMP CALLZ80 ;CALL BDOS AND RETURN ; ; CALLZ80 - CALL Z80 SUBROUTINE ; ; Z80 ADDRESS OF SUBROUTINE TO CALL MUST BE IN X,A (X=HI,A=LO) ; CALLZ80: LDY #ZPC ;POINT TO Z80 PC REGISTER JSR STORWD ;STORE CALL ADDRESS CONTAINED IN A,X JMP GOZ80 ;TRANSFER CONTROL TO Z80 ; ; STORWD - STORE WORD INTO REG SAVE AREA ; ; STORES WORD IN X,A INTO Z80 REGISTER SAVE LOC POINTED TO BY Y REG. ; (X=HI,A=LO) ; STORWD: STA (REGPTR6),Y ;STORE A,X INTO REGISTER SAVE AREA INY ;WITH PTR TO REGISTER IN Y TXA STA (REGPTR6),Y ;STORE HI BYTE RTS ; ; MESSAGE TEXT ; MESSAGE: ASC '*** HIT "ESC" TO RING THE BELL ***' DFB CR,LF ASC '$' .DEPHASE PRINTE %(*-DEMO), SUBTTL SYMBOL TABLE END DEMO