************************************************************************* * * * This file contains the target processor (8080) * * simulation routines. * * * ************************************************************************* * Last revised September 10, 1987. xdef optabl,flags,mloop,traceit,tracesad,traceead,traceflg xref illegl,service,dump ifd tracehd trace equ 1 ;Include trace routines. endc ifnd tracehd trace equ 0 ;Don't include trace routines. endc return equr A6 ;JMP (return) is fast return to MLOOP. pseudopc equr A5 ;8080's PC is register A5. opptr equr A4 ;Pointer to opcode dispatch table pseudosp equr A3 ;8080's SP is register A3. flagptr equr A2 ;Pointer to 8080's flag lookup table is A2. targbase equr A1 ;Pointer to 8080's address space is A1. regs equr A1 ;Base pointer to 8080's registers is A1. regcon0e equr D7 ;Register-based constant #$E (for speed) regcon01 equr D6 ;Register-based constant #$1 regcon0f equr D5 ;Register-based constant #$F regconff equr D4 ;Register-based constant #$FF regf equr D3 ;8080's flags rega equr D2 ;8080's accumulator regop3 equ -9 ;Operand 3 for DAA storage regb equ -8 ;Offsets from register base pointer for regc equ -7 ; 8080's pseudo-registers. regd equ -6 ; A and F are in 68000's data registers. rege equ -5 ; Pseudo-PC is kept in an address register. regh equ -4 ; regl equ -3 ; regop1 equ -2 ;Operand 1 for DAA storage regop2 equ -1 ; " 2 " " " page ************************************************************************* * * * Macros used by opcode simulation routines * * * * These generate a lot of repetitive code sequences, * * but it's faster than doing subroutine calls. * * * ************************************************************************* setflag macro ;Set 8080 flags from 68000 flags. move sr,d0 and.w regcon0f,d0 move.b 0(flagptr,d0.w),regf jmp (return) endm inrflag macro ;Set flags after increment or decrement. move sr,d0 and.w regcon0e,d0 and.w regcon01,regf or.b 0(flagptr,d0.w),regf jmp (return) endm addflag macro ;Add and set flags. move.b d0,regop1(regs) move.b rega,regop2(regs) move.b regcon0e,regop3(regs) add.b d0,rega setflag endm adcflag macro ;Add with carry and set flags. move.b d0,regop1(regs) move.b rega,regop2(regs) moveq #0,d1 ;Set Zero flag for ADDX. addx.b d0,rega setflag endm sbbflag macro ;Subtract with borrow and set flags. moveq #0,d1 ;Set Zero flag for SUBX. subx.b d0,rega setflag endm ret80 macro ;Return from subroutine. move.b 1(pseudosp),d0 rol.w #8,d0 move.b (pseudosp),d0 addq.l #2,pseudosp lea 0(targbase,d0.l),pseudopc jmp (return) endm jmpaddr macro ;Get address for possible jump or call. move.b 1(pseudopc),d0 rol.w #8,d0 move.b (pseudopc),d0 addq.l #2,pseudopc endm call80 macro ;Call a subroutine move.l pseudopc,d1 sub.l targbase,d1 move.b d1,-2(pseudosp) rol.w #8,d1 move.b d1,-1(pseudosp) subq.l #2,pseudosp lea 0(targbase,d0.l),pseudopc jmp (return) endm rst80 macro ;8080 RST instruction move.l pseudopc,d1 sub.l targbase,d1 move.b d1,-2(pseudosp) rol.w #8,d1 move.b d1,-1(pseudosp) subq.l #2,pseudosp lea \1(targbase),pseudopc jmp (return) endm docyf macro ;Copy 68000's carry flag to 8080 bcs.s 1$ bclr #0,regf jmp (return) 1$ bset #0,regf jmp (return) endm page ************************************************************************* * * * Opcode dispatcher * * * ************************************************************************* code mloop: ifne trace ;Optional trace tst.b traceflg bne.s dotrace cmpa.l tracesad,pseudopc bne.s notrace move.b #1,traceflg dotrace jsr dump cmpa.l traceead,pseudopc bne.s notrace clr.b traceflg notrace equ * endc moveq #0,d0 ;Execute appropriate simulation subroutine. move.b (pseudopc)+,d0 ;Grab the next opcode. asl #2,d0 ;(D0 high word is still zero!) move.l 0(opptr,d0.w),a0 jmp (a0) ;Do the subroutine. page ************************************************************************* * * * Opcode simulation routines * * * * Note: I/O instructions are based as 68000 address $FF0000 * * as is appropriate for the Compupro CPU-68K card. * * * * Also, all routines assume that the high word of D0 is zero! * * * ************************************************************************* even nop00 jmp (return) ;00 NOP lxib move.b (pseudopc)+,regc(regs) ;01 LXI B,nnnn move.b (pseudopc)+,regb(regs) jmp (return) staxb move.w regb(regs),d0 ;02 STAX B move.b rega,0(targbase,d0.l) jmp (return) inxb addq.w #1,regb(regs) ;03 INX B jmp (return) inrb addq.b #1,regb(regs) ;04 INR B inrflag dcrb subq.b #1,regb(regs) ;05 DCR B inrflag mvib move.b (pseudopc)+,regb(regs) ;06 MVI B,nn jmp (return) rlca rol.b #1,rega ;07 RLC docyf nop08 jmp illegl ;08 Illegal for 8080 dadb move.w regb(regs),d0 ;09 DAD B add.w d0,regh(regs) docyf ldaxb move.w regb(regs),d0 ;0A LDAX B move.b 0(targbase,d0.l),rega jmp (return) dcxb subq.w #1,regb(regs) ;0B DCX B jmp (return) inrc addq.b #1,regc(regs) ;0C INR C inrflag dcrc subq.b #1,regc(regs) ;0D DCR C inrflag mvic move.b (pseudopc)+,regc(regs) ;0E MVI C jmp (return) rrca ror.b #1,rega ;0F RRC docyf nop10 jmp illegl ;10 Illegal for 8080 lxid move.b (pseudopc)+,rege(regs) ;11 LXI D,nnnn move.b (pseudopc)+,regd(regs) jmp (return) staxd move.w regd(regs),d0 ;12 STAX D move.b rega,0(targbase,d0.l) jmp (return) inxd addq.w #1,regd(regs) ;13 INX D jmp (return) inrd addq.b #1,regd(regs) ;14 INR D inrflag dcrd subq.b #1,regd(regs) ;15 DCR D inrflag mvid move.b (pseudopc)+,regd(regs) ;16 MVI D,nn jmp (return) ral roxr.b #1,regf ;17 RAL roxl.b #1,rega roxl.b #1,regf jmp (return) nop18 jmp illegl ;18 Illegal for 8080 dadd move.w regd(regs),d0 ;19 DAD D add.w d0,regh(regs) docyf ldaxd move.w regd(regs),d0 ;1A LDAX D move.b 0(targbase,d0.l),rega jmp (return) dcxd subq.w #1,regd(regs) ;1B DCX D jmp (return) inre addq.b #1,rege(regs) ;1C INR E inrflag dcre subq.b #1,rege(regs) ;1D DCR E inrflag mvie move.b (pseudopc)+,rege(regs) ;1E MVI E jmp (return) rar roxr.b #1,regf ;1F RAR roxr.b #1,rega roxl.b #1,regf jmp (return) nop20 jmp illegl ;20 Illegal for 8080 lxih move.b (pseudopc)+,regl(regs) ;21 LXI H,nnnn move.b (pseudopc)+,regh(regs) jmp (return) shld move.b 1(pseudopc),d0 ;22 SHLD addr rol.w #8,d0 move.b (pseudopc),d0 addq.l #2,pseudopc move.l d0,a0 adda.l targbase,a0 move.b regl(regs),(a0)+ move.b regh(regs),(a0)+ jmp (return) inxh addq.w #1,regh(regs) ;23 INX H jmp (return) inrh addq.b #1,regh(regs) ;24 INR H inrflag dcrh subq.b #1,regh(regs) ;25 DCR H inrflag mvih move.b (pseudopc)+,regh(regs) ;26 MVI H,nn jmp (return) daa move.b regop3(regs),d0 ;27 DAA roxr.b #1,d0 move.b regop2(regs),d0 move.b regop1(regs),d1 swap regcon0e move.b rega,regcon0e and.b regcon0f,regcon0e cmp.b #9,regcon0e bhi.s halfcy and.b regcon0f,d0 and.b regcon0f,d1 ori.b #$F0,d1 addx.b d0,d1 bcc.s nohalf halfcy add.b #6,rega bcs.s fullcy nohalf btst #0,regf bne.s fullcy move.b rega,regcon0e and.b #$F0,regcon0e cmp.b #$90,regcon0e bls.s nofull fullcy add.b #$60,rega ori #1,ccr enddaa move sr,regf swap regcon0e and.w regcon0f,regf move.b 0(flagptr,regf.w),regf jmp (return) nofull tst.b rega bra.s enddaa nop28 jmp illegl ;28 Illegal for 8080 dadh asl.w regh(regs) ;29 DAD H (multiply by 2) docyf lhld move.b 1(pseudopc),d0 ;2A LHLD addr rol.w #8,d0 move.b (pseudopc),d0 addq.l #2,pseudopc move.l d0,a0 adda.l targbase,a0 move.b (a0)+,regl(regs) move.b (a0),regh(regs) jmp (return) dcxh subq.w #1,regh(regs) ;2B DCX H jmp (return) inrl addq.b #1,regl(regs) ;2C INR L inrflag dcrl subq.b #1,regl(regs) ;2D DCR L inrflag mvil move.b (pseudopc)+,regl(regs) ;2E MVI L,nn jmp (return) cma not.b rega ;2F CMA jmp (return) nop30 jmp illegl ;30 Illegal for 8080 lxis move.b 1(pseudopc),d0 ;31 LXI SP,nnnn rol.w #8,d0 move.b (pseudopc),d0 addq.l #2,pseudopc move.l d0,pseudosp adda.l targbase,pseudosp jmp (return) sta move.b 1(pseudopc),d0 ;32 STA addr rol.w #8,d0 move.b (pseudopc),d0 addq.l #2,pseudopc move.b rega,0(targbase,d0.l) jmp (return) inxs addq.l #1,pseudosp ;33 INX SP jmp (return) inrm move.w regh(regs),d0 ;34 INR M addq.b #1,0(targbase,d0.l) inrflag dcrm move.w regh(regs),d0 ;35 DCR M subq.b #1,0(targbase,d0.l) inrflag mvim move.w regh(regs),d0 ;36 MVI M,nn move.b (pseudopc)+,0(targbase,d0.l) jmp (return) stc bset #0,regf ;37 STC jmp (return) nop38 jmp illegl ;38 Illegal for 8080 dads move.l pseudosp,d0 ;39 DAD SP sub.l targbase,d0 add.w d0,regh(regs) docyf lda move.b 1(pseudopc),d0 ;3A LDA addr rol.w #8,d0 move.b (pseudopc),d0 addq.l #2,pseudopc move.b 0(targbase,d0.l),rega jmp (return) dcxs subq.l #1,pseudosp ;3B DCX SP jmp (return) inra move.b rega,regop1(regs) ;3C INR A move.b regcon01,regop2(regs) move.b regcon0e,regop3(regs) addq.b #1,rega inrflag dcra subq.b #1,rega ;3D DCR A inrflag mvia move.b (pseudopc)+,rega ;3E MVI A jmp (return) cmc bchg #0,regf ;3F CMC jmp (return) movebb move.b regb(regs),regb(regs) ;40 MOV B,B jmp (return) movebc move.b regc(regs),regb(regs) ;41 MOV B,C jmp (return) movebd move.b regd(regs),regb(regs) ;42 MOV B,D jmp (return) movebe move.b rege(regs),regb(regs) ;43 MOV B,E jmp (return) movebh move.b regh(regs),regb(regs) ;44 MOV B,H jmp (return) movebl move.b regl(regs),regb(regs) ;45 MOV B,L jmp (return) movebm move.w regh(regs),d0 ;46 MOV B,M move.b 0(targbase,d0.l),regb(regs) jmp (return) moveba move.b rega,regb(regs) ;47 MOV B,A jmp (return) movecb move.b regb(regs),regc(regs) ;48 MOV C,B jmp (return) movecc move.b regc(regs),regc(regs) ;49 MOV C,C jmp (return) movecd move.b regd(regs),regc(regs) ;4A MOV C,D jmp (return) movece move.b rege(regs),regc(regs) ;4B MOV C,E jmp (return) movech move.b regh(regs),regc(regs) ;4C MOV C,H jmp (return) movecl move.b regl(regs),regc(regs) ;4D MOV C,L jmp (return) movecm move.w regh(regs),d0 ;4E MOV C,M move.b 0(targbase,d0.l),regc(regs) jmp (return) moveca move.b rega,regc(regs) ;4F MOV C,A jmp (return) movedb move.b regb(regs),regd(regs) ;50 MOV D,B jmp (return) movedc move.b regc(regs),regd(regs) ;51 MOV D,C jmp (return) movedd move.b regd(regs),regd(regs) ;52 MOV D,D jmp (return) movede move.b rege(regs),regd(regs) ;53 MOV D,E jmp (return) movedh move.b regh(regs),regd(regs) ;54 MOV D,H jmp (return) movedl move.b regl(regs),regd(regs) ;55 MOV D,L jmp (return) movedm move.w regh(regs),d0 ;56 MOV D,M move.b 0(targbase,d0.l),regd(regs) jmp (return) moveda move.b rega,regd(regs) ;57 MOV D,A jmp (return) moveeb move.b regb(regs),rege(regs) ;58 MOV E,B jmp (return) moveec move.b regc(regs),rege(regs) ;59 MOV E,C jmp (return) moveed move.b regd(regs),rege(regs) ;5A MOV E,D jmp (return) moveee move.b rege(regs),rege(regs) ;5B MOV E,E jmp (return) moveeh move.b regh(regs),rege(regs) ;5C MOV E,H jmp (return) moveel move.b regl(regs),rege(regs) ;5D MOV E,L jmp (return) moveem move.w regh(regs),d0 ;5E MOV E,M move.b 0(targbase,d0.l),rege(regs) jmp (return) moveea move.b rega,rege(regs) ;5F MOV E,A jmp (return) movehb move.b regb(regs),regh(regs) ;60 MOV H,B jmp (return) movehc move.b regc(regs),regh(regs) ;61 MOV H,C jmp (return) movehd move.b regd(regs),regh(regs) ;62 MOV H,D jmp (return) movehe move.b rege(regs),regh(regs) ;63 MOV H,E jmp (return) movehh move.b regh(regs),regh(regs) ;64 MOV H,H jmp (return) movehl move.b regl(regs),regh(regs) ;65 MOV H,L jmp (return) movehm move.w regh(regs),d0 ;66 MOV H,M move.b 0(targbase,d0.l),regh(regs) jmp (return) moveha move.b rega,regh(regs) ;67 MOV H,A jmp (return) movelb move.b regb(regs),regl(regs) ;68 MOV L,B jmp (return) movelc move.b regc(regs),regl(regs) ;69 MOV L,C jmp (return) moveld move.b regd(regs),regl(regs) ;6A MOV L,D jmp (return) movele move.b rege(regs),regl(regs) ;6B MOV L,E jmp (return) movelh move.b regh(regs),regl(regs) ;6C MOV L,H jmp (return) movell move.b regl(regs),regl(regs) ;6D MOV L,L jmp (return) movelm move.w regh(regs),d0 ;6E MOV L,M move.b 0(targbase,d0.l),regl(regs) jmp (return) movela move.b rega,regl(regs) ;6F MOV L,A jmp (return) movemb move.w regh(regs),d0 ;70 MOV M,B move.b regb(regs),0(targbase,d0.l) jmp (return) movemc move.w regh(regs),d0 ;71 MOV M,C move.b regc(regs),0(targbase,d0.l) jmp (return) movemd move.w regh(regs),d0 ;72 MOV M,D move.b regd(regs),0(targbase,d0.l) jmp (return) moveme move.w regh(regs),d0 ;73 MOV M,E move.b rege(regs),0(targbase,d0.l) jmp (return) movemh move.w regh(regs),d0 ;74 MOV M,H move.b regh(regs),0(targbase,d0.l) jmp (return) moveml move.w regh(regs),d0 ;75 MOV M,L move.b regl(regs),0(targbase,d0.l) jmp (return) halt jsr service ;76 HLT jmp (return) movema move.w regh(regs),d0 ;77 MOV M,A move.b rega,0(targbase,d0.l) jmp (return) moveab move.b regb(regs),rega ;78 MOV A,B jmp (return) moveac move.b regc(regs),rega ;79 MOV A,C jmp (return) movead move.b regd(regs),rega ;7A MOV A,D jmp (return) moveae move.b rege(regs),rega ;7B MOV A,E jmp (return) moveah move.b regh(regs),rega ;7C MOV A,H jmp (return) moveal move.b regl(regs),rega ;7D MOV A,L jmp (return) moveam move.w regh(regs),d0 ;7E MOV A,M move.b 0(targbase,d0.l),rega jmp (return) moveaa jmp (return) ;7F MOV A,A addb move.b regb(regs),d0 ;80 ADD B addflag addc move.b regc(regs),d0 ;81 ADD C addflag addd move.b regd(regs),d0 ;82 ADD D addflag adde move.b rege(regs),d0 ;83 ADD E addflag addh move.b regh(regs),d0 ;84 ADD H addflag addl move.b regl(regs),d0 ;85 ADD L addflag addm move.w regh(regs),d0 ;86 ADD M move.b 0(targbase,d0.l),d0 addflag adda move.b rega,regop1(regs) ;87 ADD A move.b rega,regop2(regs) move.b regcon0e,regop3(regs) add.b rega,rega setflag adcb move.b regf,regop3(regs) ;88 ADC B asr.b #1,regf move.b regb(regs),d0 adcflag adcc move.b regf,regop3(regs) ;89 ADC C asr.b #1,regf move.b regc(regs),d0 adcflag adcd move.b regf,regop3(regs) ;8A ADC D asr.b #1,regf move.b regd(regs),d0 adcflag adce move.b regf,regop3(regs) ;8B ADC E asr.b #1,regf move.b rege(regs),d0 adcflag adch move.b regf,regop3(regs) ;8C ADC H asr.b #1,regf move.b regh(regs),d0 adcflag adcl move.b regf,regop3(regs) ;8D ADC L asr.b #1,regf move.b regl(regs),d0 adcflag adcm move.b regf,regop3(regs) ;8E ADC M move.w regh(regs),d0 move.l d0,a0 adda.l targbase,a0 asr.b #1,regf move.b (a0),d0 adcflag adca move.b regf,regop3(regs) ;8F ADC A asr.b #1,regf move.b rega,d0 adcflag subb sub.b regb(regs),rega ;90 SUB B setflag subc sub.b regc(regs),rega ;91 SUB C setflag subd sub.b regd(regs),rega ;92 SUB D setflag sube sub.b rege(regs),rega ;93 SUB E setflag subh sub.b regh(regs),rega ;94 SUB H setflag subl sub.b regl(regs),rega ;95 SUB L setflag subm move.w regh(regs),d0 ;96 SUB M sub.b 0(targbase,d0.l),rega setflag suba sub.b rega,rega ;97 SUB A setflag sbbb asr.b #1,regf ;98 SBB B move.b regb(regs),d0 sbbflag sbbc asr.b #1,regf ;99 SBB C move.b regc(regs),d0 sbbflag sbbd asr.b #1,regf ;9A SBB D move.b regd(regs),d0 sbbflag sbbe asr.b #1,regf ;9B SBB E move.b rege(regs),d0 sbbflag sbbh asr.b #1,regf ;9C SBB H move.b regh(regs),d0 sbbflag sbbl asr.b #1,regf ;9D SBB L move.b regl(regs),d0 sbbflag sbbm move.w regh(regs),d0 ;9E SBB M move.l d0,a0 adda.l targbase,a0 asr.b #1,regf move.b (a0),d0 sbbflag sbba asr.b #1,regf ;9F SBB A move.b rega,d0 sbbflag andb and.b regb(regs),rega ;A0 ANA B move.b 16(flagptr,rega.w),regf jmp (return) andc and.b regc(regs),rega ;A1 ANA C move.b 16(flagptr,rega.w),regf jmp (return) andd and.b regd(regs),rega ;A2 ANA D move.b 16(flagptr,rega.w),regf jmp (return) ande and.b rege(regs),rega ;A3 ANA E move.b 16(flagptr,rega.w),regf jmp (return) andh and.b regh(regs),rega ;A4 ANA H move.b 16(flagptr,rega.w),regf jmp (return) andl and.b regl(regs),rega ;A5 ANA L move.b 16(flagptr,rega.w),regf jmp (return) andm move.w regh(regs),d0 ;A6 ANA M and.b 0(targbase,d0.l),rega move.b 16(flagptr,rega.w),regf jmp (return) anda move.b 16(flagptr,rega.w),regf ;A7 ANA A jmp (return) xrab move.b regb(regs),d0 ;A8 XRA B eor.b d0,rega move.b 16(flagptr,rega.w),regf jmp (return) xrac move.b regc(regs),d0 ;A9 XRA C eor.b d0,rega move.b 16(flagptr,rega.w),regf jmp (return) xrad move.b regd(regs),d0 ;AA XRA D eor.b d0,rega move.b 16(flagptr,rega.w),regf jmp (return) xrae move.b rege(regs),d0 ;AB XRA E eor.b d0,rega move.b 16(flagptr,rega.w),regf jmp (return) xrah move.b regh(regs),d0 ;AC XRA H eor.b d0,rega move.b 16(flagptr,rega.w),regf jmp (return) xral move.b regl(regs),d0 ;AD XRA L eor.b d0,rega move.b 16(flagptr,rega.w),regf jmp (return) xram move.w regh(regs),d0 ;AE XRA M move.b 0(targbase,d0.l),d0 eor.b d0,rega move.b 16(flagptr,rega.w),regf jmp (return) xraa moveq #0,rega ;AF XRA A (clears accumulator) move.b 16(flagptr),regf jmp (return) orab or.b regb(regs),rega ;B0 ORA B move.b 16(flagptr,rega.w),regf jmp (return) orac or.b regc(regs),rega ;B1 ORA C move.b 16(flagptr,rega.w),regf jmp (return) orad or.b regd(regs),rega ;B2 ORA D move.b 16(flagptr,rega.w),regf jmp (return) orae or.b rege(regs),rega ;B3 ORA E move.b 16(flagptr,rega.w),regf jmp (return) orah or.b regh(regs),rega ;B4 ORA H move.b 16(flagptr,rega.w),regf jmp (return) oral or.b regl(regs),rega ;B5 ORA L move.b 16(flagptr,rega.w),regf jmp (return) oram move.w regh(regs),d0 ;B6 ORA M or.b 0(targbase,d0.l),rega move.b 16(flagptr,rega.w),regf jmp (return) oraa move.b 16(flagptr,rega.w),regf ;B7 ORA A jmp (return) cmpb cmp.b regb(regs),rega ;B8 CMP B setflag cmpc cmp.b regc(regs),rega ;B9 CMP C setflag cmpd cmp.b regd(regs),rega ;BA CMP D setflag cmpe cmp.b rege(regs),rega ;BB CMP E setflag cmph cmp.b regh(regs),rega ;BC CMP H setflag cmpl cmp.b regl(regs),rega ;BD CMP L setflag cmpam move.w regh(regs),d0 ;BE CMP M cmp.b 0(targbase,d0.l),rega setflag cmpaa cmp.b rega,rega ;BF CMP A setflag rnz btst #6,regf ;C0 RNZ bne mloop ret80 popb move.b (pseudosp)+,regc(regs) ;C1 POP B move.b (pseudosp)+,regb(regs) jmp (return) jnz: ;C2 JNZ addr jmpaddr btst #6,regf bne mloop lea 0(targbase,d0.l),pseudopc jmp (return) jmpa: ;C3 JMP addr jmpaddr lea 0(targbase,d0.l),pseudopc jmp (return) cnz: ;C4 CNZ addr jmpaddr btst #6,regf bne mloop call80 pushb move.b regb(regs),-(pseudosp) ;C5 PUSH B move.b regc(regs),-(pseudosp) jmp (return) adi move.b (pseudopc)+,d0 ;C6 ADI nn addflag rst0: ;C7 RST 0 rst80 $0 rz btst #6,regf ;C8 RZ beq mloop ret: ;C9 RET ret80 jz: ;CA JZ addr jmpaddr btst #6,regf beq mloop lea 0(targbase,d0.l),pseudopc jmp (return) nopCB jmp illegl ;CB Illegal for 8080 cz: ;CC CZ addr jmpaddr btst #6,regf beq mloop call80 call: ;CD CALL addr jmpaddr call80 aci: move.b regf,regop3(regs) ;CE ACI nn asr.b #1,regf move.b (pseudopc)+,d0 adcflag rst1: ;CF RST 1 rst80 $8 rnc btst #0,regf ;D0 RNC bne mloop ret80 popd move.b (pseudosp)+,rege(regs) ;D1 POP D move.b (pseudosp)+,regd(regs) jmp (return) jnc: ;D2 JNC addr jmpaddr btst #0,regf bne mloop lea 0(targbase,d0.l),pseudopc jmp (return) out moveq #0,d0 ;D3 OUT nn * move.b (pseudopc)+,d0 * move.l #$ff0000,a0 * move.b rega,0(a0,d0.l) jmp (return) cnc ;D4 CNC addr jmpaddr btst #0,regf bne mloop call80 pushd move.b regd(regs),-(pseudosp) ;D5 PUSH D move.b rege(regs),-(pseudosp) jmp (return) sui move.b (pseudopc)+,d0 ;D6 SUI nn sub.b d0,rega setflag rst2: ;D7 RST 2 rst80 $10 rc btst #0,regf ;D8 RC beq mloop ret80 nopD9 jmp illegl ;D9 Illegal for 8080 jc: ;DA JC addr jmpaddr btst #0,regf beq mloop lea 0(targbase,d0.l),pseudopc jmp (return) in moveq #0,d0 ;DB IN nn * move.b (pseudopc)+,d0 * move.l #$FF0000,a0 * move.b 0(a0,d0.l),rega jmp (return) cc: ;DC CC addr jmpaddr btst #0,regf beq mloop call80 nopDD jmp illegl ;DD Illegal for 8080 sbi asr.b #1,regf ;DE SBI nn move.b (pseudopc)+,d0 sbbflag rst3: ;DF RST 3 rst80 $18 rpo btst #2,regf ;E0 RPO bne mloop ret80 poph move.b (pseudosp)+,regl(regs) ;E1 POP H move.b (pseudosp)+,regh(regs) jmp (return) jpo: ;E2 JPO addr jmpaddr btst #2,regf bne mloop lea 0(targbase,d0.l),pseudopc jmp (return) xthl move.b regl(regs),d0 ;E3 XTHL move.b (pseudosp),regl(regs) move.b d0,(pseudosp) move.b regh(regs),d0 move.b 1(pseudosp),regh(regs) move.b d0,1(pseudosp) jmp (return) cpo: ;E4 CPO addr jmpaddr btst #2,regf bne mloop call80 pushh move.b regh(regs),-(pseudosp) ;E5 PUSH H move.b regl(regs),-(pseudosp) jmp (return) ani and.b (pseudopc)+,rega ;E6 ANI nn move.b 16(flagptr,rega.w),regf jmp (return) rst4: ;E7 RST 4 rst80 $20 rpe btst #2,regf ;E8 RPE beq mloop ret80 pchl move.w regh(regs),d0 ;E9 PCHL lea 0(targbase,d0.l),pseudopc jmp (return) jpe: ;EA JPE addr jmpaddr btst #2,regf beq mloop lea 0(targbase,d0.l),pseudopc jmp (return) xchg move.w regd(regs),d0 ;EB XCHG move.w regh(regs),regd(regs) move.w d0,regh(regs) jmp (return) cpe: ;EC CPE addr jmpaddr btst #2,regf beq mloop call80 * ED-prefix Z80 instructions are simulated in the next module. xri move.b (pseudopc)+,d0 ;EE XRI nn eor.b d0,rega move.b 16(flagptr,rega.w),regf jmp (return) rst5: ;EF RST 5 rst80 $28 rp btst #7,regf ;F0 RP bne mloop ret80 popp move.b (pseudosp)+,regf ;F1 POP P move.b (pseudosp)+,rega jmp (return) jp: ;F2 JP addr jmpaddr btst #7,regf bne mloop lea 0(targbase,d0.l),pseudopc jmp (return) di jmp (return) ;F3 DI (treated as no-op) cp: ;F4 CP addr jmpaddr btst #7,regf bne mloop call80 pushp move.b rega,-(pseudosp) ;F5 PUSH PSW move.b regf,-(pseudosp) jmp (return) oria or.b (pseudopc)+,rega ;F6 ORI nn move.b 16(flagptr,rega.w),regf jmp (return) rst6: ;F7 RST 6 rst80 $30 rm btst #7,regf ;F8 RM beq mloop ret80 sphl move.w regh(regs),d0 ;F9 SPHL lea 0(targbase,d0.l),pseudosp jmp (return) jm: ;FA JM addr jmpaddr btst #7,regf beq mloop lea 0(targbase,d0.l),pseudopc jmp (return) ei jmp (return) ;FB EI (treated as a no-op) cm: ;FC CM addr jmpaddr btst #7,regf beq mloop call80 nopFD jmp illegl ;FD Illegal for 8080 cpi cmp.b (pseudopc)+,rega ;FE CPI nn setflag rst7: ;FF RST 7 rst80 $38 page ************************************************************************* * * * Z-80 opcode simulation routines * * * ************************************************************************* preED moveq #0,d1 ;Zero-fill high bits. move.b (pseudopc)+,d1 ;Grab next opcode. asl #2,d1 lea EDoptab,a0 move.l 0(a0,d1.w),-(sp) ;Do the operation. beq illgED rts illgED move.l (sp)+,d1 ;Trash the address. subq.l #1,pseudopc ;Fix PPC for ILLEGAL. jmp illegl ldir move.l d2,-(sp) move.w regb(regs),d0 ;Grab count, subq.w #1,d0 ; adjust for DBRA. moveq #0,d1 moveq #0,d2 move.w regh(regs),d1 ;Source move.w regd(regs),d1 ;Destination move.l a5,-(sp) ;We need an address register. lea 0(targbase,d2.l),a5 lea 0(targbase,d1.l),a0 ldirlop move.b (a0)+,(a5)+ addq.w #1,d1 addq.w #1,d2 dbra d0,ldirlop move.l (sp)+,a5 ;Restore a5. move.w d1,regh(regs) ;Update 8080 registers. move.w d2,regd(regs) move.w #0,regb(regs) moveq #0,regf move.l (sp)+,d2 jmp (return) lddr move.l d2,-(sp) move.w regb(regs),d0 ;Grab count, subq.w #1,d0 ; adjust for DBRA. moveq #0,d1 moveq #0,d2 move.w regh(regs),d1 ;Source move.w regd(regs),d1 ;Destination move.l a5,-(sp) ;We need an address register. lea 1(targbase,d2.l),a5 lea 1(targbase,d1.l),a0 lddrlop move.b -(a0),-(a5) subq.w #1,d1 subq.w #1,d2 dbra d0,lddrlop move.l (sp)+,a5 ;Restore a5. move.w d1,regh(regs) ;Update 8080 registers. move.w d2,regd(regs) move.w #0,regb(regs) moveq #0,regf move.l (sp)+,d2 jmp (return) page cpir move.w regb(regs),d0 ;Grab count, subq.w #1,d0 ; adjust for DBRA. moveq #0,d1 move.w regh(regs),d1 ;Source lea 0(targbase,d1.l),a0 cpirlop addq.w #1,d1 cmp.b (a0)+,rega dbeq d0,cpirlop seq regf move.w d1,regh(regs) ;Restore 8080 registers. addq.w #1,d0 move.w d0,regb(regs) tst.b regf bne cpir1 moveq #0,regf ;Not found. jmp (return) cpir1 tst d0 bne cpir2 moveq #$44,regf ;Found, in the string. jmp (return) cpir2 moveq #$40,regf ;Found, but at last place. jmp (return) page ************************************************************************* * * * Opcode dispatch table * * * ************************************************************************* data data even optabl dc.l nop00,lxib,staxb,inxb,inrb,dcrb,mvib,rlca dc.l nop08,dadb,ldaxb,dcxb,inrc,dcrc,mvic,rrca dc.l nop10,lxid,staxd,inxd,inrd,dcrd,mvid,ral dc.l nop18,dadd,ldaxd,dcxd,inre,dcre,mvie,rar dc.l nop20,lxih,shld,inxh,inrh,dcrh,mvih,daa dc.l nop28,dadh,lhld,dcxh,inrl,dcrl,mvil,cma dc.l nop30,lxis,sta,inxs,inrm,dcrm,mvim,stc dc.l nop38,dads,lda,dcxs,inra,dcra,mvia,cmc dc.l movebb,movebc,movebd,movebe,movebh,movebl,movebm,moveba dc.l movecb,movecc,movecd,movece,movech,movecl,movecm,moveca dc.l movedb,movedc,movedd,movede,movedh,movedl,movedm,moveda dc.l moveeb,moveec,moveed,moveee,moveeh,moveel,moveem,moveea dc.l movehb,movehc,movehd,movehe,movehh,movehl,movehm,moveha dc.l movelb,movelc,moveld,movele,movelh,movell,movelm,movela dc.l movemb,movemc,movemd,moveme,movemh,moveml,halt,movema dc.l moveab,moveac,movead,moveae,moveah,moveal,moveam,moveaa dc.l addb,addc,addd,adde,addh,addl,addm,adda dc.l adcb,adcc,adcd,adce,adch,adcl,adcm,adca dc.l subb,subc,subd,sube,subh,subl,subm,suba dc.l sbbb,sbbc,sbbd,sbbe,sbbh,sbbl,sbbm,sbba dc.l andb,andc,andd,ande,andh,andl,andm,anda dc.l xrab,xrac,xrad,xrae,xrah,xral,xram,xraa dc.l orab,orac,orad,orae,orah,oral,oram,oraa dc.l cmpb,cmpc,cmpd,cmpe,cmph,cmpl,cmpam,cmpaa dc.l rnz,popb,jnz,jmpa,cnz,pushb,adi,rst0 dc.l rz,ret,jz,nopCB,cz,call,aci,rst1 dc.l rnc,popd,jnc,out,cnc,pushd,sui,rst2 dc.l rc,nopD9,jc,in,cc,nopDD,sbi,rst3 dc.l rpo,poph,jpo,xthl,cpo,pushh,ani,rst4 dc.l rpe,pchl,jpe,xchg,cpe,preED,xri,rst5 dc.l rp,popp,jp,di,cp,pushp,oria,rst6 dc.l rm,sphl,jm,ei,cm,nopFD,cpi,rst7 page ************************************************************************* * * * Flag register lookup tables * * * ************************************************************************* flags dc.b $00,$01,$04,$05,$40,$41,$44,$45,$80,$81,$84,$85,$C0,$C1,$C4,$C5 dc.b $44,$00,$00,$04,$00,$04,$04,$00,$00,$04,$04,$00,$04,$00,$00,$04 dc.b $00,$04,$04,$00,$04,$00,$00,$04,$04,$00,$00,$04,$00,$04,$04,$00 dc.b $00,$04,$04,$00,$04,$00,$00,$04,$04,$00,$00,$04,$00,$04,$04,$00 dc.b $04,$00,$00,$04,$00,$04,$04,$00,$00,$04,$04,$00,$04,$00,$00,$04 dc.b $00,$04,$04,$00,$04,$00,$00,$04,$04,$00,$00,$04,$00,$04,$04,$00 dc.b $04,$00,$00,$04,$00,$04,$04,$00,$00,$04,$04,$00,$04,$00,$00,$04 dc.b $04,$00,$00,$04,$00,$04,$04,$00,$00,$04,$04,$00,$04,$00,$00,$04 dc.b $00,$04,$04,$00,$04,$00,$00,$04,$04,$00,$00,$04,$00,$04,$04,$00 dc.b $80,$84,$84,$80,$84,$80,$80,$84,$84,$80,$80,$84,$80,$84,$84,$80 dc.b $84,$80,$80,$84,$80,$84,$84,$80,$80,$84,$84,$80,$84,$80,$80,$84 dc.b $84,$80,$80,$84,$80,$84,$84,$80,$80,$84,$84,$80,$84,$80,$80,$84 dc.b $80,$84,$84,$80,$84,$80,$80,$84,$84,$80,$80,$84,$80,$84,$84,$80 dc.b $84,$80,$80,$84,$80,$84,$84,$80,$80,$84,$84,$80,$84,$80,$80,$84 dc.b $80,$84,$84,$80,$84,$80,$84,$80,$84,$80,$80,$84,$80,$84,$84,$80 dc.b $80,$84,$84,$80,$84,$80,$84,$80,$84,$80,$80,$84,$80,$84,$84,$80 dc.b $84,$80,$80,$84,$80,$84,$84,$80,$80,$84,$84,$80,$84,$80,$80,$84 page ************************************************************************* * * * Z80 opcode dispatch table. One longword entry per opcode * * of the target (Z-80) processor, including illegals. * * * ************************************************************************* * * * Only a few of the most popular instructions are simulated. * * Support for the Z-80 Block Move instructions is provided * * as the flags for this simulation resemble those of the Z-80 * * rather than the 8080. Certain packages (notably BDS C) check * * the flags and mistakenly assume a Z-80, then use LDIR/LDDR. * * Therefore, minimal Z-80 support is provided for these * * instructions. By no means is this a complete simulation * * of the Z-80. * * * ************************************************************************* EDoptab: dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;ED00 dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;ED10 dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;ED20 dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;ED30 dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;ED40 dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;ED50 dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;ED60 dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;ED70 dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;ED80 dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;ED90 dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;EDA0 dc.l ldir,cpir,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;EDB0 dc.l lddr,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;EDC0 dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;EDD0 dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;EDE0 dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;EDF0 traceit dc.b trace ;Trace option is available - used by SIMCPM1. bss bss even tracesad ds.l 1 ;Start address for trace traceead ds.l 1 ;End address for trace traceflg ds.b 1 ;Trace activity flag end