; ZX65: SIMULATING A MICRO 1/80 R M KRUSE ; FOR Z80-BASED SYSTEMS USING THE CP/M DOS ; ; ; ; THIS FILE IS AN ENHANCED VERSION OF ZX65, BY R.M.KRUSE. ; THE FOLLOWING CHANGES HAVE BEEN MADE TO THE ORIGINAL: ; ; ; REVISION 1.0: 10/22/82 (RGF) ; THIS REVISION OF ZX65 ALLOWS ASSEMBLY UNDER THE M80 ; (MICROSOFT RELOCATING ASSEMBLER) ; ; SIMULATOR MODIFIED TO NOT NEED RELOCATION, BY REMAPPING 6502 ; MEMORY REFERENCES THROUGH A COMPANION MODULE (ZX65HOST.MAC) ; INTO Z80 MEMORY. THE TWO MODULES MUST BE LINKED TOGETHER ; USING L80. ; ; BUG FIXED 11/05/82 (RGF): FIXED PROBLEM WITH STORES ; IN MULTI-MODE INSTRUCTIONS WHERE DESTINATION=ACC ; (EG, LSR A) ; ; 11/22/82 (RGF) : ADDED IFETCH CALL TO MAPPER MODULE ; TO ALLOW INSTRUCTION FETCH SETUP. ALTHOUGH ; NOT CURRENTLY USED, THIS WILL ALLOW SETUP OF ; INSTRUCTION FETCH CYCLES IN COMPANION 6502 IN- ; CIRCUIT HARDWARE EMULATION THAT MAY SOMEDAY ; BE DESIGNED. (ANY TAKERS???) ; ; ADDED HISTOGRAM FEATURE, # OF STEPS ; SET BY VARIABLE 'HSIZE', WHICH IS ; THE # OF PREVIOUS PC'S TO REMEMBER ; THIS FEATURE AVAILABLE THROUGH THE "H" ; COMMAND. ; ; ; REMOVED SELF-CONTAINED DOS, WHICH IS ; NOT NEEDED WITH THE MEMORY REMAPPING ; FEATURE ; ; ZX65SIM IS BASED ON ZX65, A PROGRAM WRITTEN BY R.M. KRUSE. ; 90% OF THE CODE BELONGS TO MR. KRUSE. FOR MORE INFORMATION, ; SEE THE ACCOMPANYING DOCUMENTATION FILES. ; RON FOWLER ; 12/17/82 ; ; .Z80 ; ; HSIZE EQU 40 ;SIZE OF HISTOGRAM BUFFER (IN WORDS) ; EXTRN FETCHA,SENDA ;EXTRNAL ROUTINES TO FETCH ;AND SEND BYTE TO 6502 ;MEMORY (ADRS IN HL) EXTRN AINIT ;EXTERNAL INITIALIZATION EXTRN IFETCH ;INSTRUCTION FETCH SETUP ; ; ZX65 BEGINS... ; LD SP,SYSTK CALL AINIT ;INITIALIZE ATARI LD HL,(1) ;GET BIOS BASE LD L,0 LD DE,VECTBL ;MOVE TABLE TO LOCAL AREA LD BC,15*3 ;MOVE FIRST 15 VECTORS LDIR LD IY,INTRO CALL PRTXT ; PRINT HEADER CALL CRLF ; ; COMMAND LEVEL...RETURN HERE FROM ANY POINT IN PGM ; CMND:: LD HL,CMND PUSH HL ; RET ADDR ON STACK CALL CRLF CALL PROM CALL GETCHR ; GET COMMAND CP 'H' ; PRINT HISTOGRAM JP Z,PRTHIS CP 'E' JP Z,EXAM ; EXAM MEMORY CP 'M' JP Z,SUBM ; SUB MEMORY LD IX,VREG ; FOR SIMX CP 'B' JR Z,BRKP ; RUN TO BREAKPOINT CP 'C' JP Z,RGSTR ; DSPLY/MODIFY CPU REGS CP 'G' JP Z,RUN ; RUN FROM NPC CP 'T' JR Z,MULTX ; TRACE/DISPLAY N STEPS CP ' ' JR Z,EXONE ; EX ONE INSTR & STOP LD C,'?' CALL PRNC ; INVALID COMMAND JR CMND ; ; EXECUTE N STEPS ; MULTX:: LD IY,MLTMSG CALL PRTXT CALL GETWRD ; GET N LD A,E JR NZ,DOMULT EXONE:: LD A,1 ; EXECUTE 1 STEP ; ; EXECUTE # STEPS IN A ; DOMULT::LD (NSTEPS),A ; STORE N IN TEMP CALL STEP ; EXEC & DSPLY INSTR CALL DSPLY LD A,(NSTEPS) DEC A RET Z PUSH AF LD BC,DLYCON ; DELAY FOR VIEWING DOLP:: DEC BC LD A,B OR C JR NZ,DOLP POP AF JR DOMULT ; ; RUN WITHOUT DISPLAY TO BREAKPOINT ; BRKP:: LD IY,BKPMSG CALL PRTXT CALL GETWRD ; GET IT LD (BREAK),DE ; STORE IT IN TEMP BKLP:: CALL STEP ; EXEC ONE INSTR LD DE,(BREAK) LD A,H ; CHECK IF AT BKPT CP D JR NZ,INTST LD A,L CP E JR NZ,INTST CALL STEP ; DO ONE MORE JR DSPLY INTST:: CALL KBST ; TEST FOR KBD INP JR Z,BKLP ; CONTINUE IF NONE JR QDSP ; ; RUN ONLY..NO DISPLAY OR BREAKPOINT ; RUN:: CALL STEP ; DO A STEP CALL KBST ; CHECK FOR KB INPUT JR Z,RUN ; IF NONE JUST REPEAT ; ; STOP, DISPLAY, & RET TO CMND ; QDSP:: CALL KBIN ; CLEAR UART JR DSPLY ; DISP CPU & RET ; ; DISPLAY & UPDATE CPU REGISTERS ; RGSTR:: PUSH IX CALL CRLF LD IY,HEADR+42 CALL PRN6 ; PRINT RG NAME LD DE,(NPC) ; NEXT PC TO DE CALL PRTWRD ; PRINT IT CALL PROM ; PROMPT FOR CHANGE CALL GETWRD JR Z,AREG ; SPACE = NO CHANGE LD (NPC),DE ; PUT IN NEW VALUE AREG:: LD IY,HEADR+12 LD B,5 NREG:: CALL CRLF ; DO REST OF REGS CALL PRN6 ; PRINT NAME LD E,(IX+0) CALL PRTBYT ; PRINT CONTENTS CALL PROM ; PROMPT FOR CHANGE CALL GETWRD JR Z,NXTREG ; SPACE = NO CHANGE LD (IX+0),E NXTREG::INC IX ; POINT TO NEXT REG DJNZ NREG ; DO AGAIN IF MORE POP IX RET ; ; DISPLAY PC, INSTRUCTION, AND ALL REGISTERS ; DSPLY:: PUSH IX ; SAVE POINTER PUSH BC ; SAVE MNEMONIC CODE CALL CRLF LD IY,HEADR CALL PRN6 ; 'CPC' LD DE,(CPC) CALL PRTWRD ; VALUE CALL PRN6 ; 'INS' POP BC PUSH IY PUSH BC LD IY,MNMTBL ; DET MNEM FROM BC LD A,0FCH AND C SRL A LD E,A LD D,0 ADD IY,DE LD E,(IY+0) ; GET PACKED MNEM LD D,(IY+1) SLA E ; UNPACK IT RL D LD C,3 ; & PRINT THREE CHRS MNM2:: XOR A LD B,5 MNM1:: SLA E RL D RLA DJNZ MNM1 SET 6,A PUSH BC CALL PRNA POP BC DEC C JR NZ,MNM2 POP BC ; DECODE ADDR MODE LD A,B SLA A SLA A SLA A LD E,A LD D,0 LD IY,AMDTBL ADD IY,DE CALL PRN8 ; PRINT ADDR MODE POP IY LD B,5 DSP1:: CALL PRN6 ; PRINT ALL REGS LD E,(IX+0) CALL PRTBYT INC IX DJNZ DSP1 CALL PRN6 ; PRINT NEXT PC LD DE,(NPC) CALL PRTWRD POP IX RET ; PRN6:: LD E,6 ; PRINT 6 CHARS PER IY JP PRNLP PRN8:: LD E,8 ; PRINT 8 CHRS PER IY JP PRNLP ; ; QUEUE PC (IN HL) ; QUEPC:: PUSH HL ; SAVE PC LD HL,HSBUFR+(HSIZE*2)-3 ; GET END OF BUFR-2 LD DE,HSBUFR+(HSIZE*2)-1 ; GET END OF BUFFER LD BC,HSIZE*2-2 ; MOVE BUFR-2 WORDS LDDR ; CLEAR BOTTOM OF BUFFER POP DE ; RESTORE PC TO QUEUE LD HL,HSBUFR ; QUEUE IT AT START OF BUFR LD (HL),E ; PUT IT IN THE QUEUE INC HL LD (HL),D EX DE,HL ; GET PC BACK TO HL RET ; ; PRINT QUEUE ; PRTHIS::CALL CRLF ; TURN UP NEW LINE LD HL,HSBUFR ; GET POINTER TO HISTO BUFR LD BC,HSIZE ; GET COUNTER PHLP: LD A,B ; DONE PRINTING? (BC=0?) OR C JR Z,PHDONE ; JUMP IF SO LD E,(HL) ; ELSE FETCH ANOTHER PC INC HL LD D,(HL) INC HL PUSH HL ; SAVE BUFR PNTR PUSH BC ; AND COUNT CALL PRTWRD ; PRINT IT LD A,' ' ; SPACE BETWEEN WORDS CALL PRNA POP BC ; GET COUNTER PUSH BC LD A,C ; GET COUNT MOD 8 AND 7 CALL Z,CRLF ; CRLF EVERY 8 PC'S POP BC ; GET COUNTER BACK POP HL DEC BC ; COUNT DOWN JR PHLP PHDONE: CALL CRLF RET ; ; CODE FOR DECODING AND EXECUTING ONE INSTRUCTION ; ENTER WITH HL POINTING TO INSTR TO BE DECODED. EXITS ; WITH HL POINTING TO NEXT INSTR, B HOLDING ADDRESSING ; MODE CODE, C HOLDING MNEMONIC CODE ; STEP:: CALL IFETCH ; ALERT INSTR FETCH COMING LD HL,(NPC) ; NEXT PC TO HL CALL QUEPC ; GO PLACE IN QUEUE LD (CPC),HL ; BECOMES CURRENT PC CALL FETCHA ; GET OP CODE LD B,A ; SAVE IT OR A ; ZERO? JP Z,PBRK ; IF SO, 'BRK' BIT 0,A ; TEST LSD FOR ODD/EVEN JP NZ,MLTMOD ; ODD INSTRS MULTI MODE AND 0FH JR NZ,FLGTST LD A,B ; RESTORE OP CODE BIT 4,A ; MSD ODD/EVEN JP NZ,PBRNCH ; IF ODD, BRANCH CP 20H JP Z,PJSR ; PROCESS JSR CP 40H JP Z,PRTI ; PROCESS RTI CP 60H JP Z,PRTS ; PROCESS RTS JP MLTMOD ; ELSE MULTI MODE FLGTST::CP 8 JR NZ,IMP2 LD A,B ; RESTORE BIT 4,A ; MSD ODD/EVEN JP Z,PIMPL ; IF EVEN, MST BE IMPLD CP 98H ; MSD = 9? JP Z,PTYA ; YES, PROC TYA SPECIAL JP PFLGS ; ELSE PROCESS FLAG OPS IMP2:: CP 0AH JR NZ,JMPTST ; MUST BE JUMP LD A,B ; RESTORE AND 0F0H ; TESTS ON MSD BIT 4,A ; ODD/EVEN JP NZ,PTSS ; PROSESS SP OPS SPECIAL CP 70H JP C,MLTMOD ; PROCESS ACCUM MODES JP PIMPL ; ELSE MORE IMPLIEDS JMPTST::LD A,B ; RESTORE OP CODE CP 4CH JP Z,PJABS ; PROCESS ABS JMP CP 6CH JP Z,PJIND ; PROCESS INDIRECT JMP JP MLTMOD ; ; INSTURCTION PROCESSORS BEGIN HERE.. ENTER WITH ; HL = PC, IX POINTING TO SIM CPU ; ; IF BRK VECTOR (IPOINT) = 0, RETURN TO CMND ; PBRK:: SET 4,(IX+1) ; SET BRK STATUS BIT LD HL,(IPOINT) ; SEE IF RET TO CMND LD A,H OR L JR NZ,BRK1 POP BC ; ADJUST SP LD BC,429H ; RET TO CMND JP DSPLY BRK1:: INC HL ; NORMAL BREAK CALL TSPD ; SP TO IY LD A,D ; 'PUSH' PC CALL SENDA DEC HL LD A,E CALL SENDA DEC HL LD A,(IX+1) ; 'PUSH' P CALL SENDA DEC HL CALL TDSP ; DE TO SP LD HL,(IPOINT) ; GET INTERRUPT VECTOR LD BC,429H ; CODE FOR # BYTES & MNEM JP END1 ; AND FINISH ; ; PROCESS BRANCHES ; PBRNCH::LD B,0 ; FORM INDEX INTO MSKTBL CALL FETCHA LD C,A ; INSTR TO C LD IY,MSKTBL SRL C ; GET MSD SRL C SRL C SRL C DEC C ADD IY,BC INC HL ; POINT TO OFFSET BIT 1,C ; MSD ODD/EVEN LD A,(IX+1) ; P REG TO ACC LD C,(IY+0) ; # CODE LD B,(IY+1) ; FLAG MASK JR NZ,BRSET ; ODD/EVEN DET SET/CLR AND B ; ISOLATE BIT FOR TEST JR Z,TRUE JR FALSE BRSET:: AND B JR NZ,TRUE JR FALSE TRUE:: LD D,0 ; CONDITION MET; BRANCH CALL FETCHA LD E,A ; OFFSET TO E BIT 7,E ; CHECK SIGN OF OFFSET JR Z,TRU1 DEC D ; IF B7 IS SET, DO NEG TRU1:: ADD HL,DE ; ADD OFFSET FOR NEW PC FALSE:: LD B,0 ; COND NOT MET; GO ON JP END ; ; PROCESS JUMPS AND JSR...JMP 0-4 AND JSR 0-4 GO INTO Z80 ; ROUTINES PER JUMP TABLE AT USR0. CONTROL THEN RETURNS ; TO SIMULATOR UPON Z80 'RET' (C9).. ALL OTHERS PROCESSED ; NORMALLY. ; PJSR:: INC HL ; PROCESS JSR CALL SPCTST ; TEST FOR SPECIALS JR NZ,PJS2 CALL INUSR ; GO TO USER ROUTINES JR PJS3 PJS2:: PUSH DE ; SAVE NEW PC CALL TSPD ; NORMAL JSR LD A,D ; PUSH CURRENT PC CALL SENDA DEC HL LD A,E CALL SENDA DEC HL CALL TDSP POP DE ; RESTORE NEW PC EX DE,HL ; NEW PC PJS3:: LD BC,273H JP END1 PJABS:: INC HL ; ABS JUMP LD BC,26FH JR DOJP PJIND:: INC HL ; INDIRECT JUMP CALL FETCHA LD E,A INC HL CALL FETCHA LD D,A EX DE,HL ; ADDR OF POINTER TO HL LD BC,0C6FH DOJP:: CALL SPCTST ; TEST FOR SPECIALS JR NZ,DOJ1 PUSH BC CALL INUSR ; FOR SPECIALS CALL PRET ; DO SR RETURN POP BC EX DE,HL DOJ1:: EX DE,HL ; NEW PC JP END1 ; ; TEST FOR USER SUBROUTINE CALLS/JUMPS. IF TARGET ; ADDRESS < 0005 THEN RET WITH Z FLG SET, ELSE CLR ; SPCTST::CALL FETCHA ;TEST FOR USER SPECIALS LD E,A INC HL CALL FETCHA ;TARGET TO DE LD D,A INC HL ; NXT INSTR LD A,0 ; TARGET < 0005? OR D RET NZ LD A,4 CP E RET C XOR A ; SET Z FLAG RET ; ; INDEX INTO USER SUBROUTINE TABLE ; PASS A, X, & Y TO/FROM USER ROUTINE AS A, B, & C. ; INUSR:: PUSH BC ; SAVE CODES LD D,0 LD A,E ADD A,E ADD A,E LD E,A LD IY,USR0 LD BC,USRET ; RETURN ON STACK PUSH BC ADD IY,DE LD A,(IX+0) ; PASS A,X, & Y LD B,(IX+2) LD C,(IX+3) JP (IY) ; AND GO USRET:: LD (IX+0),A ; RETURN HERE LD (IX+2),B ; RETURN PARAMETERS LD (IX+3),C POP BC RET ; ; PROCESS SR AND INTERRUPT RETURNS ; PRTI:: CALL TSPD ; RTI INC HL ; GET TOS (FLAGS) CALL FETCHA LD (IX+1),A ; RESTORE CALL PRET1 LD BC,04A5H JP END1 PRTS:: CALL PRET ; RTS...RESTORE PC LD BC,4A9H JP END1 PRET:: CALL TSPD PRET1:: INC HL ; POINT TO LAST ENTRY CALL FETCHA ; RESTORE PC LO LD E,A INC HL ; RESTORE PC HI CALL FETCHA LD D,A JP TDSP ; GO RESTORE ; ; PROCESS SP EXCHANGES ; PTSS:: CP 90H ; WHICH ONE IS IT? JR NZ,PTSX PTXS:: LD A,(IX+2) ; MOVE DATA FROM X... LD (IX+4),A ; TO SP LD BC,4D9H JP END PTSX:: LD A,(IX+4) ; MOVE SP LD (IX+2),A ; TO X REG LD C,0D1H JP COMPL ; AND MODIFY FLAGS ; ; PROCESS ALL REMAINING IMPLIED INSTRUCTIONS ; PIMPL:: LD C,A ; OP CODE SRL C ; GET MSD SRL C SRL C SRL C AND 0FH ; CHECK LSD CP 8 LD IY,IMPTBL ; INDEX INTO TABLE JP Z,JPIB LD IY,IMPTBL+8 JP JPIB ; ; IMPLIED INSTR PROCESSORS ; PINX:: INC (IX+2) ; INX LD C,65H JR IDEFLG PINY:: INC (IX+3) ; INY LD C,69H JR IDEFLG PDEX:: DEC (IX+2) ; DEX LD C,55H JR IDEFLG PDEY:: DEC (IX+3) ; DEY LD C,59H IDEFLG::RES 1,(IX+1) ; SET/RES Z FLG JR NZ,SINTST ; PER Z80 FLAGS SET 1,(IX+1) SINTST::RES 7,(IX+1) ; ALSO SIGN FLG JP P,ENDIT SET 7,(IX+1) JP ENDIT PNOP:: LD BC,485H ; NOP JP END PPHA:: CALL TSPD ; PHA LD A,(IX+0) ; ACCUM LD C,8DH JR DOPUSH ; PUSH IT PPHP:: CALL TSPD ; PHP LD A,(IX+1) ; P REG LD C,91H DOPUSH::PUSH BC CALL SENDA ; PLACE ON STACK DEC HL ; BUMP SP DOWN CALL TDSP ; & REPLACE IT POP BC JP ENDIT PPLA:: CALL DOPULL ; PLA LD (IX+0),A ; DATA TO ACC CALL SINS1 ; SET/RES S,Z FLGS CALL TDSP ; RESTORE SP LD BC,495H JP END PPLP:: CALL DOPULL ; PLP LD (IX+1),A ; DATA TO P REG CALL TDSP ; RESTORE SP LD BC,499H JP END DOPULL::CALL TSPD ; GET SP INC HL ; BUMP SP CALL FETCHA ; GET DATA RET ; ; PROCESS ACC/INDEX TRANSFERS ; PTAX:: LD A,(IX+0) ; TAX LD (IX+2),A LD C,0C9H JR COMPL PTAY:: LD A,(IX+0) ; TAY LD (IX+3),A LD C,0CDH JR COMPL PTXA:: LD A,(IX+2) ; TXA LD (IX+0),A LD C,0D5H JR COMPL PTYA:: LD A,(IX+3) ; TYA LD (IX+0),A LD C,0DDH COMPL:: CALL SINS1 ; SET/RES S,Z FLGS JR ENDIT ; ; PROCESS FLAG SET/RES INSTRUCTIONS ; PFLGS:: LD IY,FLGTBL ; TABLE START LD B,0 CP 0B8H ; CLV SPECIAL JR NZ,PFL1 RES 5,A PFL1:: RRA ; CHECK MSD RRA RRA RRA AND 0EH ; MASK MSD + 1 BIT 1,A ; TEST FOR SET/RES LD C,A ; FORM TABLE INDEX ADD IY,BC LD C,(IY+0) ; GET MNEM CODE LD A,(IY+1) ; GET MASK JR NZ,PFL2 CPL ; DO CLEARS AND (IX+1) JR PFL3 PFL2:: OR (IX+1) ; DO SETS PFL3:: LD (IX+1),A ; AND STUFF IT ENDIT:: LD B,4 JP END ; ; PROCESS ALL INSTRUCTIONS HAVING MULTIPLE ADDRESSING ; MLTMOD::LD BC,MLTEND ; PUT RETURN ON STACK PUSH BC CALL FETCHA ; GET INSTR TO A LD C,A ; AND TO C SRL C ; TEST EVEN/ODD PUSH AF SRL C ; ROTATE MSD INTO LSD SRL C SRL C RES 0,C ; MASK LSB POP AF LD IY,EVNTBL ; JUMP PER TABLES JP NC,JPIB LD IY,ODDTBL JP JPIB ; ; MULTI-MODE INSTRUCTION PROCESSORS ; PASL:: CALL MODBBB ; GET MODE,ADDR,&DATA SLA A ; ASL CALL SINSET ; SET/RES S,Z,C FLGS CALL PUTDAT ; RESTORE DATA LD A,8 RET PBTRL:: BIT 1,A ; BIT OR ROL? JR Z,PBIT CALL MODBBB ; ROL CALL CARSET ; SET UP C FLAG PROL1:: RLA ; DO ROTATE CALL SINSET CALL PUTDAT LD A,9CH RET PBIT:: RES 6,(IX+1) ; BIT CALL MODBBX PUSH BC LD B,A ; SAVE IT IN B LD A,(IX+0) ; GET SIM ACC AND B ; AND IT BIT 6,A ; CHECK V BIT JR Z,PBIT1 SET 6,(IX+1) ; SET V BIT IF REQD PBIT1:: CALL SINS1 ; SET/RES S,Z FLGS POP BC LD A,18H RET PLSR:: CALL MODBBB ; LSR SRL A CALL SINSET CALL PUTDAT LD A,80H RET PROR:: CALL MODBBB ; ROR CALL CARSET ; SET UP C FLG PROR1:: RRA ; DO ROTATE CALL SINSET CALL PUTDAT LD A,0A0H RET PSTXY:: BIT 1,A ; WHICH ONE? JR Z,PSY CALL MODBBX ; STX LD A,(IX+2) CALL PUTDAT LD A,0C0H RET PSY:: CALL MODBBX ; STY LD A,(IX+3) CALL PUTDAT LD A,0C4H RET PLDXY:: BIT 1,A ; WHICH ONE? JR Z,PLY CALL MODDDD ; LDX LD (IX+2),A CALL SINS1 LD A,78H RET PLY:: CALL MODDDD ; LDY LD (IX+3),A CALL SINS1 LD A,7CH RET PDCY:: BIT 1,A ; WHICH ONE? JR Z,PCPY CALL MODBBX ; DEC DEC A CALL SINS1 CALL PUTDAT LD A,50H RET PICX:: BIT 1,A ; WHICH ONE? JR Z,PCPX CALL MODBBX ; INC INC A CALL SINS1 CALL PUTDAT LD A,60H RET PCPX:: CALL CXY ; CPX CALL SINSET LD A,48H RET PCPY:: INC IX CALL CXY ; CPY DEC IX CALL SINSET LD A,4CH RET CXY:: CALL MODCC PUSH BC LD B,A ; MEM DAT INTO B LD A,(IX+2) ; X (Y) INTO A SUB B CCF ; BORROW = 6502 /C POP BC RET PSBC:: RES 6,(IX+1) ; SBC...CLR V FLG CALL MODAAA PUSH BC LD B,A ; DATA TO B LD A,(IX+0) ; ACC TO A CALL CARSET ; SET UP C FLAG CCF ; AND COMPLEMENT IT PSBC1:: BIT 3,(IX+1) ; CHECK FOR DEC MODE JR NZ,PSDEC SBC A,B JR PSBC2 PSDEC:: SBC A,B ; DECIMAL MODE DAA PSBC2:: LD (IX+0),A ; RESULT TO ACCUM CCF ; BORROW = 6502 /C CALL SINSET AND 0C0H ; TEST XOR OF B6 & B7 JR Z,SBC3 CP 0C0H JR Z,SBC3 SET 6,(IX+1) ; SET V FLAG IF XOR = 1 SBC3:: POP BC LD A,0ACH RET PORA:: CALL MODAAA ; ORA PUSH BC LD B,A ; DATA TO B LD A,(IX+0) ; ACC TO A OR B LD (IX+0),A ; RESULT TO ACC CALL SINS1 POP BC LD A,88H RET PAND:: CALL MODAAA ; AND PUSH BC LD B,A ; DATA TO B LD A,(IX+0) ; ACC TO A AND B LD (IX+0),A ; RESULT TO ACC CALL SINS1 POP BC LD A,4 RET PEOR:: CALL MODAAA ; EOR PUSH BC LD B,A ; DATA TO B LD A,(IX+0) ; ACC TO A XOR B LD (IX+0),A ; RESULT TO ACC CALL SINS1 POP BC LD A,5CH RET PADC:: RES 6,(IX+1) ; ADC: CLEAR V FLAG CALL MODAAA PUSH BC LD B,A ; DATA TO B LD A,(IX+0) ; ACC TO A CALL CARSET ; SET UP C FLG PADC1:: BIT 3,(IX+1) ; CHECK FOR DEC MODE JR NZ,PADEC ADC A,B ; BINARY MODE JR PADC2 PADEC:: ADC A,B ; DECIMAL MODE DAA PADC2:: LD (IX+0),A ; RESULT TO ACC CALL SINSET AND 0C0H ; CHECK XOR OF B6 & B7 JR Z,PADC3 CP 0C0H JR Z,PADC3 SET 6,(IX+1) ; SET V FLG IF XOR = 1 PADC3:: POP BC LD A,0 RET PSTA:: CALL MODAAA ; STA LD A,(IX+0) ; ACC TO MEM CALL PUTDAT LD A,0BCH RET PLDA:: CALL MODAAA ; LDA LD (IX+0),A ; MEM TO ACC CALL SINS1 LD A,74H RET PCMP:: CALL MODAAA ; CMP PUSH BC LD B,A ; DATA TO B LD A,(IX+0) ; ACC TO A SUB B CCF ; BORROW = 6502 /C CALL SINSET POP BC LD A,44H RET ; ; END OF ALL MULTI MODE PROCESSORS ; MLTEND::PUSH AF ; SAVE MNEMONIC CODE LD A,0 ; TURN OFF ACCUM MODE FLAG LD (ACCFLG),A POP AF ADD A,C ; FORM MNEM CODE IN C LD C,A END:: INC HL ; POINT TO NXT INSTR END1:: LD (NPC),HL RET ; BACK TO CMND ; ; VARIOUS SUBROUTINES FOR TRANSLATOR ; ; SET Z80 C FLAG TO MATCH 6502 C FLG ; CARSET::SCF BIT 0,(IX+1) RET NZ CCF RET ; ; SET SIMULATOR S,Z,C FLAGS PER Z80 RESULTS ; SINSET::RES 0,(IX+1) ; RESET C FLAG JR NC,SINS1 SET 0,(IX+1) ; SET C PER Z80 C SINS1:: RES 1,(IX+1) ; CLEAR Z FLAG OR A ; SEE IF ACC = 0 JR NZ,SINS2 SET 1,(IX+1) ; SET Z FLG SINS2:: RES 7,(IX+1) ; CLEAR SIGN FLAG BIT 7,A ; CHECK SIGN OF ACC RET Z SET 7,(IX+1) ; SET S IF NECESSARY RET ; ; TRANSFER SIMULATOR SP TO/FROM HL ; TSPD:: LD D,1 ; XFER SP TO DE LD E,(IX+4) EX DE,HL ; PC TO DE, SP TO HL RET TDSP:: EX DE,HL ; PC TO HL, SP TO DE LD (IX+4),E ; RESTORE SP RET ; ; ADDRESS MODE DECODERS...RETURN WITH DATA TO BE MODIFIED ; IN A, ADDRESS MODE CODE IN B, # BYTES IN C, ADDRESS OF ; DATA IN DE ; MODAAA::LD IY,AAATBL ; GROUP 1 JR MOD1 MODBBB::LD IY,BBBTBL ; GROUP 2 JR MOD1 MODDDD::LD IY,DDDTBL ; GROUP 3 CP 0B6H ; LDX ZPG,Y SPECIAL JR NZ,DDD1 LD A,10H DDD1:: CP 0BEH ; LDX ABS,Y SPECIAL JR NZ,MOD1 LD A,18H JR MOD1 MODBBX::LD IY,BBXTBL ; GROUP 4 & 6 CP 96H ; STX ZPG,Y SPECIAL JR Z,BBX RRA ; EXTRA SHIFT AND 0CH ; EXTRA MASK JR MOD1 BBX:: LD A,10H ; SPECIAL JR MOD1 MODCC:: LD IY,CCTBL ; GROUP 5 MOD1:: RRA ; ROTATE MODE INTO LSD AND 0EH ; MASK THE REST LD B,0 ; FORM OFFSET IN BC LD C,A ADD IY,BC ; ADD TO TABLE START LD C,(IY+0) ; MODE OFFSET LD B,(IY+1) ; # CODE PUSH BC ; SAVE FOR LATER GETDAT::LD IY,GETTBL ; JUMP TABLE JP JPIB PABY:: INC HL ; ABS,Y CALL FETCHA ; 2ND BYTE INSTR ADD A,(IX+3) ; PLUS Y INDEX LD E,A ; TO E INC HL CALL FETCHA ; 3RD BYTE INSTR ADC A,0 ; PLUS CARRY LD D,A ; TO D JP EXIT PIMM:: INC HL ; IMMEDIATE CALL FETCHA ; DATA TO ACC JR EX1 PACX:: LD A,1 ; SET ACCUM MODE FLAG LD (ACCFLG),A LD A,(IX+0) ; ACCUM PUSH IX POP DE JR EX1 PZPG:: INC HL ; ZPG CALL FETCHA LD E,A ; ADDRESS TO DE LD D,0 JR EXIT PAB:: INC HL ; ABSOLUTE CALL FETCHA LD E,A ; ADDRESS TO DE INC HL CALL FETCHA LD D,A JR EXIT PZX:: LD A,(IX+2) ; ZPG,X...GET X INDEX JR PZ1 PZY:: LD A,(IX+3) ; ZPG,Y...GET Y INDEX PZ1:: INC HL PUSH BC ; GET A WORK REG LD B,A ; SAVE IN B CALL FETCHA ; GET BASE ADRS ADD A,B ; ADD IT IN POP BC LD E,A ; PUT IN E LD D,0 ; ZERO PAGE, NO WRAP JR EXIT PZIX:: INC HL ; (ZPG,X) CALL FETCHA ; 2ND BYTE INSTR ADD A,(IX+2) ; ADD X INDEX LD E,A ; TO FORM BASE ADDRESS... LD D,0 ; IN ZERO PG, NO WRAP LD IY,0 ADD IY,DE ; TRANSFER TO IY LD E,(IY+0) ; EFF ADDR TO DE LD D,(IY+1) JR EXIT PZIY:: INC HL ; (ZPG),Y CALL FETCHA LD E,A ; BASE ADDRESS LD D,0 ; IN ZERO PAGE LD IY,0 ADD IY,DE ; TRANSFER TO IY LD A,(IY+0) ; EFF ADDRESS... ADD A,(IX+3) ; PLUS Y INDEX... LD E,A ; TO DE LD A,(IY+1) ADC A,0 LD D,A JR EXIT PABX:: INC HL ; ABS,X CALL FETCHA ; 2ND BYTE INSTR ADD A,(IX+2) ; PLUS X INDEX LD E,A ; TO E INC HL ; 3RD BYTE INSTR CALL FETCHA ADC A,0 ; PLUS CARRY LD D,A ; TO E EXIT:: EX DE,HL CALL FETCHA ; GET DATA EX DE,HL EX1:: POP BC ; RESTORE # CODE PUSH AF ; SAVE DATA LD A,3 AND B ; # BYTES... LD C,A ; TO C SRL B SRL B ; B=ADDR MODE POP AF ; RESTORE DATA RET ; ; STORE DATA TO ADDRESS FROM GETDAT ; PUTDAT::EX DE,HL PUSH AF ; SAVE OUTPUT BYTE LD A,(ACCFLG) ; GET ACCUMULATOR MODE FLAG OR A ; TEST IT JR Z,P65MEM ; GO STORE IN 6502 MEMORY IF OFF LD A,0 ; NOPE, TURN OFF FLAG LD (ACCFLG),A POP AF ; HL HAS POINTER TO ACCUMULATOR LD (HL),A ; (IN Z80 MEMORY SPACE) EX DE,HL RET P65MEM: POP AF ; GET BYTE TO SEND CALL SENDA EX DE,HL RET ; ; INDEX INTO JUMP TABLES...ENTER WITH TABLE START ; ADDRESS IN IY AND OFFSET IN C. CALCULATES TABLE ; POSITION AND JUMPS TO RESULT ; JPIB:: LD B,0 ; INDIRECT JUMP PER TABLE ADD IY,BC ; TABLE ADDRESS TO IY LD C,(IY+0) ; TABLE ENTRY TO BC LD B,(IY+1) PUSH BC POP IY ; ENTRY TO IY JP (IY) ; AND GO TO IT ; ; ELEMENTARY MONITOR FUNCTIONS TO EXAMINE A BLOCK OF ; MEMORY LOCATIONS (E) AND TO CHECK AND UPDATE ; INDIVIDUAL LOCATIONS (M) ; EXAM:: LD DE,GETADR ; EXAM BLOCK OF MEM CALL PRTDE CALL GETWRD ; GET START ADDR PUSH DE CALL LINF LD DE,GETN CALL PRTDE CALL GETWRD ; GET # BYTES PUSH DE POP BC LD E,4 ; CHANGE TO # LINES (/16) XOR A BYTLN:: SRL B RR C JR NC,XXX INC A XXX:: DEC E JR NZ,BYTLN OR A ; SEE IF PARTIAL LINE JR Z,YYY INC BC YYY:: POP HL ; HL = START, BC = COUNT DEC BC ; ONE LESS LINE EXLP:: PUSH BC ; LOOP FOR ONE LINE CALL CRLF CALL LADR ; PRINT ADDRESS AT START CALL TWO ; INSERT TWO SPACES PUSH HL ; SAVE ADDRESS FOR ALPHA LD E,16 ; 16 ENTRIES PER LINE LNLP:: CALL FETCHA ; GET BYTE FROM MEMORY CALL PACC ; PRINT IT HEX CALL ONE ; SPACE INC HL ; POINT TO NEXT BYTE DEC E ; DONE WITH HEX? JR NZ,LNLP ; NO, DO NEXT BYTE CALL TWO ; YES, SET UP FOR ALPHA POP HL ; SAME STARTING ADDRESS LD E,16 ASCII:: CALL FETCHA ; GET BYTE CP 20H ; IS IT PRINTABLE? JR C,DOT CP 80H JR C,ASOK DOT:: LD A,'.' ; NO, PRINT A DOT ASOK:: CALL PRNA INC HL ; BUMP POINTER DEC E ; DONE WITH LINE? JR NZ,ASCII POP BC LD A,B ; SEE IF ALL DONE OR C RET Z ; YES, RET TO CMND DEC BC JR EXLP ; ELSE DO ANOTHER LINE ; ; SUBSTITUTE MEMORY...ENTER BY 'M' ; SUBM:: LD DE,GETADR ; ASK FOR ADDRESS CALL PRTDE CALL GETWRD ; GET IT EX DE,HL ; MOVE IT TO HL SULP:: CALL CRLF CALL LADR ; PRINT THE ADDRESS CALL TWO CALL FETCHA CALL PACC ; PRINT THE CONTENTS CALL TWO JLP:: CALL GETCHR ; GET INPUT CP 2EH ; EXIT ON "." RET Z CP 20H JR Z,FWD ; SKIP AHEAD ON "SPACE" CALL CONV ; CONV HEX IF POSSIBLE JR Z,JLP ; NOT A HEX NUMBER PUSH HL ; SAVE ADDRESS AGAIN LD HL,0 ; CLEAR FOR ROTATE LLP:: CALL ROBYT ; ROTATE NYBBLE INTO HL KLP:: CALL GETCHR ; GET ANOTHER CHARACTER CP 0DH JR Z,PUTIN ; IF "CR" STUFF IT CALL CONV ; CONV BINARY JR Z,KLP ; NOT A HEX NUMBER JR LLP ; CONTINUE PUTIN:: PUSH HL ; DATA TO BC POP BC POP HL ; RETRIEVE ADDRESS LD A,C CALL SENDA ; STUFF THE DATA FWD:: INC HL ; BUMP POINTER JR SULP ; ...AND CONTINUE LADR:: EX DE,HL ; PRINT WORD IN HL CALL PRTWRD EX DE,HL RET PACC:: PUSH DE ; PRINT BYTE IN A LD E,A CALL PRTBYT POP DE RET TWO:: CALL ONE ; PRINT 2 SPACES ONE:: PUSH BC ; PRINT SPACE LD C,' ' CALL PRNC POP BC RET ; ; VARIOUS ROUTINES USED BY TRANSLATOR, MONITOR, AND DOS ; CRLF:: LD C,0DH ; PRINT CRLF CALL PRNC LINF:: LD C,0AH JP PRNC PROM:: LD C,' ' ; PRINT ' >' CALL PRNC LD C,'>' JP PRNC ; ; GET HEX DATA IN DE. ROTATE CONTINUOUSLY UNTIL A ; 'CR' IS INPUT. LSB IN E. SET Z FLG AND RET ON 'SPACE' ; GETWRD::CALL GETCHR ; GET BINARY DATA CP ' ' ; RET Z IF SPACE RET Z EX DE,HL LD HL,0 ; CLEAR HOLDING REG CALL CONV ; CHANGE TO HEX JR Z,GETWRD ; INVALID CHAR CALL ROBYT ; ROTATE INTO HL WRDLP:: CALL GETCHR ; GET NEXT CHAR CP 0DH ; TERMINATOR JR Z,WRDON CALL CONV JR Z,WRDLP CALL ROBYT JR WRDLP WRDON:: OR A ; CLEAR Z FLAG EX DE,HL ; DATA INTO DE RET ; ; CONVERT ASCII DATA IN A TO HEX. SET Z FLG IF INVALID ; CONV:: CP '0' ; CONVERT TO BINARY JR C,BAD CP 3AH JR C,GOOD CP 41H JR C,BAD CP 47H JR C,GOOD BAD:: LD C,'?' CALL PRNC ; NOTIFY BAD INPUT XOR A ; SET Z FLAG RET GOOD:: SUB 30H CP 10 JR C,GOOD1 SUB 7 GOOD1:: CP 0FFH ; CLEAR Z FLAG RET ; ; ROTATE BYTE IN A INTO HL VIA L ; ROBYT:: ADD HL,HL ; ROTATE A INTO HL ADD HL,HL ; ROTATE HL 4 BITS LEFT ADD HL,HL ADD HL,HL OR L ; PUT NEW DIGIT INTO L LD L,A RET ; ; PRINT FOUR DIGIT VALUE IN DE ; PRTWRD::LD A,D CALL PRBIN PRTBYT::LD A,E ; PRINT VALUE IN E PRBIN:: PUSH AF RRC A RRC A RRC A RRC A CALL PRB1 POP AF PRB1:: AND 0FH ADD A,90H DAA ADC A,40H DAA JR PRNA ; ; PRINT STRING POINTED TO BY DE. USES PRTXT ; PRTDE:: PUSH IY ; PRNT PER DE PUSH DE POP IY CALL PRTXT POP IY RET ; ; PRINT ASCII STRING POINTED TO BY IY. CHECK FOR ; SPECIALS: '1' PRINTS AS BYTE POINTED TO BY HL, '2' ; PRINTS (HL+1), '!' DOES NOT PRINT, '^' TERMINATES. ; PRTXT:: LD E,0 ; PRNT UP TO 255 CHRSY PRNLP:: LD A,(IY+0) CP '^' ; TERMINATOR? RET Z CP '!' ; NO PRINT? JR Z,DONXT+1 PUSH DE LD HL,(CPC) INC HL CP '2' ; PRINT (HL+1)? JR NZ,PRN1 INC HL CALL FETCHA LD E,A CALL PRTBYT JR DONXT PRN1:: CP '1' ; PRINT (HL)? JR NZ,DOALPH CALL FETCHA LD E,A CALL PRTBYT JR DONXT DOALPH::LD C,A ; ALL OTHER CHARACTERS CALL PRNC DONXT:: POP DE INC IY DEC E JR NZ,PRNLP RET ; SPAC:: PUSH BC ; PRINT 6 SPACES LD B,6 LD C,' ' SPLP:: CALL PRNC DJNZ SPLP POP BC RET ; ; CONSOLE I/O ; GETCHR::CALL KBIN ; GET CHAR & TEST CP 3 ; ^C.... JP Z,CPWRM ; CP/M WARM START CP 18H ; ^X (CAN)... JR NZ,PRNA LD SP,SYSTK-2 ; FOR RET TO CMND LD A,'#' PRNA:: LD C,A ; PRINT CHAR IN A CALL PRNC RET ; ; VECTOR TABLE COPY MOVED FROM BIOS ; VECTBL EQU $ ; CPMCLD::JP $-$ ; VECTOR TABLE FILLED IN.. CPWRM:: JP $-$ ; ...AT STARTUP KBST:: JP $-$ KBIN:: JP $-$ PRNC:: JP $-$ JP $-$ ;LIST JP $-$ ;PUNCH JP $-$ ;READER HOMB:: JP $-$ DRVS:: JP $-$ TRKS:: JP $-$ SECS:: JP $-$ BUFS:: JP $-$ RDONE:: JP $-$ WRONE:: JP $-$ ; ; HISTOGRAM BUFFER ; HSBUFR:: REPT HSIZE DW 0 ;INIT TO ZEROES ENDM ; ; ; JUMP TABLE FOR LINKS TO Z80 ROUTINES...FILL IN AS REQD ; FIRST TWO INITIALIZED TO CONSOLE I/O VIA ACC ; USR0:: JP KBIN ; 6502 USER ROUTINES USR1:: JP PRNA USR2:: DEFB 0C9H,0,0 USR3:: DEFB 0C9H,0,0 USR4:: DEFB 0C9H,0,0 ; ; 6502 BREAK VECTOR...INIT TO GO TO COMMAND LEVEL ; IPOINT::DEFW 0 ; ; TEMPORARIES FOR TRANSLATOR ; NSTEPS::DEFB 1 ; # STEPS TO EXECUTE NBYTES::DEFB 0 ; # BYTES IN INSTR DLYCON::DEFW 0A00H ; TIME DELAY FOR # STEP BREAK:: DEFW 0 ; BREAKPOINT ADDRESS ACCFLG::DEFB 0 ; MODE=ACCUM FLAG ; ; SIMULATED 6502 CPU REGISTERS...INIT TO THESE VALUES ; VREG:: DEFB 0 ; ACCUMULATOR DEFB 0 ; STATUS (P) REG DEFB 0 ; X INDEX REG DEFB 0 ; Y INDEX REG DEFB 0FFH ; STACK POINTER CPC:: DEFW 1000H ; PROGRAM COUNTER NPC:: DEFW 1000H ; LOCATION OF NXT INSTR ; ; VARIOUS MESSAGES FOR SYSTEM ; INTRO:: DEFM '* ZX/65 65xx SIMULATOR *^' HEADR:: DEFM ' CPC: INS: A:... P:...' DEFM ' X:... Y:... SP:.. NPC: ' GETADR::DEFM ' ENTER START ADDRESS: ^' GETN:: DEFM ' ENTER NO. BYTES: ^' MLTMSG::DEFM ' ENTER # STEPS: ^' BKPMSG::DEFM ' ENTER BRKP ADDR: ^' ; ; DATA TABLES FOR TRANSLATOR BEGIN HERE ; ; ADDRESSING MODE TABLES ; AAATBL::DEFW 1A0CH ; (ZPG,X) DEFW 0E04H ; ZPG DEFW 0600H ; IMM DEFW 0B06H ; ABS DEFW 1E0EH ; (ZPG),Y DEFW 2208H ; ZPG,X DEFW 2F12H ; ABS,Y DEFW 2B10H ; ABS,X BBBTBL::DEFW 0 ; INVALID DEFW 0E04H ; ZPG DEFW 1502H ; ACC DEFW 0B06H ; ABS DEFW 260AH ; ZPG,Y DEFW 2208H ; ZPG,X DEFW 2F12H ; ABS,Y DEFW 2B10H ; ABS,X DDDTBL::DEFW 0600H ; IMM DEFW 0E04H ; ZPG DEFW 0 ; INVALID DEFW 0B06H ; ABS DEFW 260AH ; ZPG,Y DEFW 2208H ; ZPG,X DEFW 2F12H ; ABS,Y DEFW 2B10H ; ABS,X BBXTBL::DEFW 0E04H ; ZPG DEFW 0B06H ; ABS DEFW 2208H ; ZPG,X DEFW 2B10H ; ABS,X DEFW 260AH ; ZPG,Y CCTBL:: DEFW 0600H ; IMM DEFW 0E04H ; ZPG DEFW 0 ; INVALID DEFW 0B06H ; ABS ; ; BRANCH MASK TABLE ; MSKTBL::DEFW 8026H ; BPL DEFW 801EH ; BMI DEFW 402EH ; BVC DEFW 4032H ; BVS DEFW 010EH ; BCC DEFW 0112H ; BCS DEFW 0222H ; BNE DEFW 0216H ; BEQ ; ; FLAG SET/RESET CODES ; FLGTBL::DEFW 0135H ; CLC DEFW 01B1H ; SEC DEFW 043DH ; CLI DEFW 04B9H ; SEI DEFW 4041H ; CLV DEFW 0000 ; INVALID DEFW 0839H ; CLD DEFW 08B5H ; SED ; ; JUMP TABLES TO IMPLIED INSTRUCTIONS ; IMPTBL::DEFW PPHP ; IMPLIED INSTR TABLE DEFW PPLP DEFW PPHA DEFW PPLA DEFW PDEY DEFW PTAY DEFW PINY DEFW PINX DEFW PTXA DEFW PTAX DEFW PDEX DEFW PNOP ; ; JUMP TABLE TO ADDR MODE PROCESSORS ; GETTBL::DEFW PIMM ; INSTR MODE TABLE DEFW PACX DEFW PZPG DEFW PAB DEFW PZX DEFW PZY DEFW PZIX DEFW PZIY DEFW PABX DEFW PABY ; ; JUMP TABLES TO MULTI-MODE PROCESSORS ; EVNTBL::DEFW PASL ; JUMPS TO PROCESSORS DEFW PBTRL DEFW PLSR DEFW PROR DEFW PSTXY DEFW PLDXY DEFW PDCY DEFW PICX ODDTBL::DEFW PORA DEFW PAND DEFW PEOR DEFW PADC DEFW PSTA DEFW PLDA DEFW PCMP DEFW PSBC ; ; MNEMONIC ASCII CODES (PACKED INTO 2 BYTES) ; MNMTBL::DEFW 0483H ; MNEMONIC TABLE DEFW 05C4H DEFW 066CH DEFW 0863H ; BCC DEFW 0873H DEFW 08B1H DEFW 0934H DEFW 09A9H DEFW 09C5H DEFW 0A0CH DEFW 0A4BH DEFW 0AC3H DEFW 0AD3H DEFW 0D83H ; CLC DEFW 0D84H DEFW 0D89H DEFW 0D96H DEFW 0DB0H DEFW 0E18H DEFW 0E19H DEFW 10A3H ; DEC DEFW 10B8H DEFW 10B9H DEFW 15F2H ; EOR DEFW 25C3H ; INC DEFW 25D8H DEFW 25D9H DEFW 29B0H ; JMP DEFW 2A72H DEFW 3081H ; LDA DEFW 3098H DEFW 3099H DEFW 3272H DEFW 39F0H ; NOP DEFW 3E41H ; ORA DEFW 4101H ; PHA DEFW 4110H DEFW 4181H DEFW 4190H DEFW 49ECH ; ROL DEFW 49F2H DEFW 4A89H DEFW 4A93H DEFW 4C43H ; SBC DEFW 4CA3H DEFW 4CA4H DEFW 4CA9H DEFW 4E81H DEFW 4E98H DEFW 4E99H DEFW 5038H ; TAX DEFW 5039H DEFW 5278H DEFW 5301H DEFW 5313H DEFW 5321H ; ; ADDRESS MODE PRINT TABLE ; AMDTBL::DEFM ' $1 !' ; ADDR MODE TABLE...REL DEFM ' #$1 !' ; IMMEDIATE DEFM ' $21 !!' ; ABS DEFM ' $1 !' ; ZPG DEFM ' ' ; IMPLIED DEFM ' A ' ; ACCUM DEFM ' ($1,X)!' ; (ZPG,X) DEFM ' ($1),Y!' ; (ZPG),Y DEFM ' $1,X !' ; ZPG,X DEFM ' $1,Y !' ; ZPG,Y DEFM ' $21,X!!' ; ABS,X DEFM ' $21,Y!!' ; ABS,Y DEFM ' ($21)!!' ; INDIRECT ; ; DEFS 200 ; STACK AREA ; SYSTK EQU $ ; ; ; THAT'S ALL! ; END