; Original Author : empty head ; Last changes : 25th Oct. 1998, gerhard.janka P65C02 ; we emulate this version of processor (6502 has a bug in jump code, ; you can emulate this bug by commenting out this line :) ; PROFILE ; fills the 'instruction_count' array for instruction profiling OPT P=68040,L1,O+,W- output cpu_m68k.o xref _bounty_bob2 xref _bounty_bob1 xref _GTIA_GetByte xref _POKEY_GetByte xref _PIA_GetByte xref _ANTIC_GetByte xref _GTIA_PutByte xref _POKEY_PutByte xref _PIA_PutByte xref _ANTIC_PutByte xref _SuperCart_PutByte xref _AtariEscape xref _break_addr xref _wsync_halt ;CPU is stopped xdef _regPC xdef _regA xdef _regP ;/* Processor Status Byte (Partial) */ xdef _regS xdef _regX xdef _regY xref _memory xref _attrib ifd PROFILE xref _instruction_count endc xdef _IRQ xdef _NMI xdef _RTI xdef _GO xdef _CPUGET xdef _CPUPUT xdef _CPU_INIT xdef _cycles ;temporarily needed outside :) regA ds.b 1 _regA ds.b 1 ;d2 -A regX ds.b 1 _regX ds.b 1 ;d3 -X regY ds.b 1 _regY ds.b 1 ;d4 -Y regPC _regPC ds.w 1 ;a2 PC regS ds.b 1 _regS ds.b 1 ;a4 stack regP ds.b 1 BDIFLAG ;same as regP _regP ds.b 1 ; -CCR IRQ _IRQ ds.b 1 even memory_pointer equr a5 attrib_pointer equr a3 stack_pointer equr a4 PC6502 equr a2 CD equr d6 ; cycles counter down ZFLAG equr d1 ; Bit 0..7 NFLAG equr d1 ; Bit 8..15 VFLAG equr d5 ; Bit 16 CCR6502 equr d5 ; Bit 0..15, only carry is usable (Extended on 68000) A equr d2 X equr d3 Y equr d4 ;d0 contains usually adress where we are working or temporary value ;d7 contains is a working register or adress LoHi macro ;change order of lo and hi byte in d7 (address) ror.w #8,d7 endm ; ========================================================== ; Emulated Registers and Flags are kept local to this module ; ========================================================== ;#define UPDATE_GLOBAL_REGS regPC=PC;regA=A;regX=X;regY=Y UPDATE_GLOBAL_REGS macro sub.l memory_pointer,PC6502 movem.w d2-d4/a2,regA ;d2-d4 (A,X,Y) a2 (regPC) endm ;#define UPDATE_LOCAL_REGS PC=regPC;A=regA;X=regX;Y=regY UPDATE_LOCAL_REGS macro clr.l d7 movem.w regA,d2-d4 ;d2-d4 (A,X,Y) lea $100(memory_pointer),stack_pointer move.w regPC,d7 move.l memory_pointer,PC6502 add.l d7,PC6502 endm GetTable: dc.l GetGTIA5,GetNone,GetNone,GetNone ; c0..3 dc.l GetNone,GetNone,GetNone,GetNone ; c4..7 dc.l GetNone,GetNone,GetNone,GetNone ; c8..b dc.l GetNone,GetNone,GetNone,GetNone ; cc..f dc.l GetGTIA8,GetNone,GetPOKEY8,GetPIA8 ; d0..3 dc.l GetANTIC8,GetNone,GetNone,GetNone ; d4..7 dc.l GetNone,GetNone,GetNone,GetNone ; d8..b dc.l GetNone,GetNone,GetNone,GetNone ; dc..f dc.l GetNone,GetNone,GetNone,GetNone ; e0..3 dc.l GetNone,GetNone,GetNone,GetNone ; e4..7 dc.l GetPOKEY5,GetNone,GetNone,GetPOKEY5 ; e8..b dc.l GetNone,GetNone,GetNone,GetNone ; ec..f dc.l GetNone,GetNone,GetNone,GetNone ; f0..3 dc.l GetNone,GetNone,GetNone,GetNone ; f4..7 dc.l GetNone,GetNone,GetNone,GetNone ; f8..b dc.l GetNone,GetNone,GetNone,GetNone ; fc..f _Local_GetByte: move.l d7,d1 clr.l d0 move.b d1,d0 lsr.w #8,d1 sub.l #$c0,d1 bmi CouldBeBob lea GetTable,a1 jmp ([a1,d1.l*4]) CouldBeBob: add.l #$c0,d1 cmp.w #$4f,d1 beq ItsBob1 cmp.w #$5f,d1 bne GetNone ItsBob2: move.w d7,-(a7) clr.w -(a7) jsr _bounty_bob2 addq.l #4,a7 clr.l d0 rts ItsBob1: move.w d7,-(a7) clr.w -(a7) jsr _bounty_bob1 addq.l #4,a7 clr.l d0 rts GetNone: move.l #255,d0 rts GetGTIA8: GetGTIA5: move.l d0,-(a7) jsr _GTIA_GetByte addq.l #4,a7 rts GetPOKEY8: GetPOKEY5: move.l d0,-(a7) jsr _POKEY_GetByte addq.l #4,a7 rts GetPIA8: move.l d0,-(a7) jsr _PIA_GetByte addq.l #4,a7 rts GetANTIC8: move.l d0,-(a7) jsr _ANTIC_GetByte addq.l #4,a7 rts PutTable: dc.l PutGTIA5,PutNone,PutNone,PutNone ; c0..3 dc.l PutNone,PutNone,PutNone,PutNone ; c4..7 dc.l PutNone,PutNone,PutNone,PutNone ; c8..b dc.l PutNone,PutNone,PutNone,PutNone ; cc..f dc.l PutGTIA8,PutNone,PutPOKEY8,PutPIA8 ; d0..3 dc.l PutANTIC8,PutSCart,PutNone,PutNone ; d4..7 dc.l PutNone,PutNone,PutNone,PutNone ; d8..b dc.l PutNone,PutNone,PutNone,PutNone ; dc..f dc.l PutNone,PutNone,PutNone,PutNone ; e0..3 dc.l PutNone,PutNone,PutNone,PutNone ; e4..7 dc.l PutPOKEY5,PutNone,PutNone,PutPOKEY5 ; e8..b dc.l PutNone,PutNone,PutNone,PutNone ; ec..f dc.l PutNone,PutNone,PutNone,PutNone ; f0..3 dc.l PutNone,PutNone,PutNone,PutNone ; f4..7 dc.l PutNone,PutNone,PutNone,PutNone ; f8..b dc.l PutNone,PutNone,PutNone,PutNone ; fc..f _Local_PutByte: clr.l d1 move.w d7,d1 lsr.w #8,d1 sub.l #$c0,d1 bmi CouldBeBobP lea PutTable,a1 jmp ([a1,d1.l*4]) CouldBeBobP: add.l #$c0,d1 cmp.w #$4f,d1 beq ItsBob1P cmp.w #$5f,d1 bne PutNone ItsBob2P: move.w d7,-(a7) clr.w -(a7) jsr _bounty_bob2 addq.l #4,a7 clr.l d0 rts ItsBob1P: move.w d7,-(a7) clr.w -(a7) jsr _bounty_bob1 addq.l #4,a7 clr.l d0 rts PutNone: clr.l d0 rts PutGTIA8: PutGTIA5: clr.l -(a7) move.b d0,3(a7) clr.l -(a7) move.b d7,3(a7) jsr _GTIA_PutByte addq.l #8,a7 rts PutPOKEY8: PutPOKEY5: clr.l -(a7) move.b d0,3(a7) clr.l -(a7) move.b d7,3(a7) jsr _POKEY_PutByte addq.l #8,a7 rts PutPIA8: clr.l -(a7) move.b d0,3(a7) clr.l -(a7) move.b d7,3(a7) jsr _PIA_PutByte addq.l #8,a7 rts PutANTIC8: clr.l -(a7) move.b d0,3(a7) clr.l -(a7) move.b d7,3(a7) jsr _ANTIC_PutByte addq.l #8,a7 rts PutSCart: clr.l -(a7) move.b d0,3(a7) move.w d7,-(a7) clr.w -(a7) jsr _SuperCart_PutByte addq.l #8,a7 rts EXE_GETBYTE macro ; move.l d7,-(a7) jsr _Local_GetByte ; addq.l #4,a7 ;put stack onto right place endm EXE_PUTBYTE macro ; clr.l -(a7) ; move.b \1,3(a7) ;byte move.b \1,d0 jsr _Local_PutByte ; addq.l #8,a7 endm EXE_PUTBYTE_d0 macro ; clr.l -(a7) ; move.b d0,3(a7) ;byte jsr _Local_PutByte ; addq.l #8,a7 endm _GenerateIRQ: move.b #1,_IRQ clr.l -(a7) bsr _GO addq.l #4,a7 rts _CPU_INIT: rts ;these are bit in MC68000 CCR register NB68 equ 3 EB68 equ 4 ;used as a carry in 6502 emulation ZB68 equ 2 OB68 equ 1 CB68 equ 0 N_FLAG equ $80 N_FLAGN equ $7f N_FLAGB equ 7 V_FLAG equ $40 V_FLAGN equ $bf V_FLAGB equ 6 G_FLAG equ $20 G_FLAGB equ $5 B_FLAG equ $10 B_FLAGB equ 4 D_FLAG equ $08 D_FLAGN equ $f7 D_FLAGB equ 3 I_FLAG equ $04 I_FLAGN equ $fb I_FLAGB equ 2 Z_FLAG equ $02 Z_FLAGN equ $fd Z_FLAGB equ 1 C_FLAG equ $01 C_FLAGN equ $fe C_FLAGB equ 0 VCZN_FLAGS equ $c3 SetI macro ori.b #I_FLAG,_regP endm ClrI macro andi.b #I_FLAGN,_regP endm SetB macro ori.b #B_FLAG,_regP endm ClrD macro andi.b #D_FLAGN,_regP endm SetD macro ori.b #D_FLAG,_regP endm ;static UBYTE N; /* bit7 zero (0) or bit 7 non-zero (1) */ ;static UBYTE Z; /* zero (0) or non-zero (1) */ ;static UBYTE V; ;static UBYTE C; /* zero (0) or one(1) */ isRAM equ 0 isROM equ 1 isHARDWARE equ 2 ;/* ; * The following array is used for 6502 instruction profiling ; */ ;int instruction_count[256]; ;UBYTE memory[65536]; ;UBYTE attrib[65536]; ;/* ; =============================================================== ; Z flag: This actually contains the result of an operation which ; would modify the Z flag. The value is tested for ; equality by the BEQ and BNE instruction. ; =============================================================== ;*/ ; Bit : 76543210 ; CCR6502: ***XNZVC ; _RegP : NV*BDIZC ConvertSTATUS_RegP macro move.b _regP,\1 ;put flag BDI into d0 ori.b #VCZN_FLAGS,\1 ; set overflow, carry, zero & negative flag btst #EB68,CCR6502 bne.s .SETC\@ andi.b #C_FLAGN,\1 .SETC\@ tst.w NFLAG bmi.s .SETN\@ andi.b #N_FLAGN,\1 .SETN\@ tst.b ZFLAG beq.s .SETZ\@ ; beware! reverse compare is ok andi.b #Z_FLAGN,\1 .SETZ\@ btst #16,VFLAG bne.s .SETV\@ andi.b #V_FLAGN,\1 .SETV\@ endm ConvertRegP_STATUS macro move.b _regP,\1 clr.l CCR6502 btst #V_FLAGB,\1 beq.s .SETV\@ bset #16,VFLAG .SETV\@ btst #C_FLAGB,\1 beq.s .SETC\@ not.w CCR6502 .SETC\@ move.b \1,NFLAG lsl.w #8,NFLAG ; sets NFLAG and clears ZFLAG btst #Z_FLAGB,\1 bne.s .SETZ\@ ;reverse is ok not.b ZFLAG .SETZ\@ endm CPU_GetStatus macro ConvertSTATUS_RegP \1 move.b \1,_regP endm CPU_PutStatus macro ConvertRegP_STATUS \1 endm PHP macro clr.l \2 move.b _regS,\2 ConvertSTATUS_RegP \1 move.b \1,(stack_pointer,\2.l) subq.b #1,\2 move.b \2,_regS endm PLP macro clr.l \2 move.b _regS,\2 addq.b #1,\2 move.b (stack_pointer,\2.l),_regP ConvertRegP_STATUS \1 move.b \2,_regS endm PHB macro clr.l \2 move.b _regS,\2 move.b \1,(stack_pointer,\2.l) subq.b #1,\2 move.b \2,_regS endm PLB macro clr.l \2 move.b _regS,\2 addq.b #1,\2 move.b (stack_pointer,\2.l),\1 move.b \2,_regS endm PHW macro clr.l \2 move.b _regS,\2 subq.b #1,\2 ; wrong way around move.b \1,(stack_pointer,\2.l) addq.b #1,\2 ror.w #8,\1 move.b \1,(stack_pointer,\2.l) subq.b #2,\2 move.b \2,_regS endm PLW macro clr.l \2 move.b _regS,\2 addq.b #2,\2 ; wrong way around move.b (stack_pointer,\2.l),\1 asl.w #8,\1 subq.b #1,\2 or.b (stack_pointer,\2.l),\1 addq.b #1,\2 move.b \2,_regS endm PHW_AND_P macro clr.l \2 move.b _regS,\2 subq.b #1,\2 ; wrong way around move.b \1,(stack_pointer,\2.l) addq.b #1,\2 ror.w #8,\1 move.b \1,(stack_pointer,\2.l) subq.b #2,\2 ConvertSTATUS_RegP \1 move.b \1,(stack_pointer,\2.l) subq.b #1,\2 move.b \2,_regS endm PLP_AND_W macro clr.l \2 move.b _regS,\2 addq.b #1,\2 move.b (stack_pointer,\2.l),_regP ConvertRegP_STATUS \1 addq.b #2,\2 ; wrong way around move.b (stack_pointer,\2.l),\1 asl.w #8,\1 subq.b #1,\2 or.b (stack_pointer,\2.l),\1 addq.b #1,\2 move.b \2,_regS endm CPUCHECKIRQ macro tst.b _IRQ beq.w NEXTCHANGE_WITHOUT move.b _regP,d0 andi.b #I_FLAG,d0 bne.w NEXTCHANGE_WITHOUT move.l PC6502,d7 sub.l memory_pointer,d7 PHW_AND_P d7,d0 SetI move.w (memory_pointer,$fffe.l),d7 LoHi move.l d7,PC6502 add.l memory_pointer,PC6502 clr.b _IRQ bra.w NEXTCHANGE_WITHOUT endm CPUGET: _CPUGET: CPU_GetStatus d0 rts CPUPUT: _CPUPUT: CPU_PutStatus d0 rts NMI: _NMI: lea _memory,a0 lea $100(a0),a1 clr.l d1 move.b _regS,d1 move.b _regPC,(a1,d1) subq.b #1,d1 move.b _regPC+1,(a1,d1) subq.b #1,d1 move.b _regP,(a1,d1) ;put P onto stack subq.b #1,d1 move.b d1,_regS SetI ;put regPC & Stack pointer adress on its place move.w (a0,$fffa.l),d1 ror.w #8,d1 move.w d1,_regPC rts section data _cycles: ; dc.l for the world outside, equ for internal use cy_CIM equ 2 cy_NOP equ 2 cy_SKB equ 3 cy_SKW equ 4 cy_Bcc equ 2 cy_Bcc1 equ 3 cy_Bcc2 equ 4 cy_00 equ 7 cy_01 equ 6 cy_03 equ 8 cy_05 equ 3 cy_06 equ 5 cy_07 equ 5 cy_08 equ 3 cy_09 equ 2 cy_0a equ 2 cy_0d equ 4 cy_0e equ 6 cy_0f equ 6 cy_11 equ 5 cy_13 equ 8 cy_14 equ 4 cy_15 equ 4 cy_16 equ 6 cy_17 equ 6 cy_18 equ 2 cy_19 equ 4 cy_1b equ 7 cy_1d equ 4 cy_1e equ 7 cy_1f equ 7 cy_20 equ 6 cy_21 equ 6 cy_23 equ 8 cy_24 equ 3 cy_25 equ 3 cy_26 equ 5 cy_27 equ 5 cy_28 equ 4 cy_29 equ 2 cy_2a equ 2 cy_2c equ 4 cy_2d equ 4 cy_2e equ 6 cy_2f equ 6 cy_31 equ 5 cy_33 equ 8 cy_34 equ 4 cy_35 equ 4 cy_36 equ 6 cy_37 equ 6 cy_38 equ 2 cy_39 equ 4 cy_3b equ 7 cy_3d equ 4 cy_3e equ 7 cy_3f equ 7 cy_40 equ 6 cy_41 equ 6 cy_43 equ 8 cy_45 equ 3 cy_46 equ 5 cy_47 equ 5 cy_48 equ 3 cy_49 equ 2 cy_4a equ 2 cy_4b equ 2 cy_4c equ 3 cy_4d equ 4 cy_4e equ 6 cy_4f equ 6 cy_51 equ 5 cy_53 equ 8 cy_54 equ 4 cy_55 equ 4 cy_56 equ 6 cy_57 equ 6 cy_58 equ 2 cy_59 equ 4 cy_5b equ 7 cy_5d equ 4 cy_5e equ 7 cy_5f equ 7 cy_60 equ 6 cy_61 equ 6 cy_63 equ 8 cy_65 equ 3 cy_66 equ 5 cy_67 equ 5 cy_68 equ 4 cy_69 equ 2 cy_6a equ 2 cy_6b equ 2 cy_6c equ 5 cy_6d equ 4 cy_6e equ 6 cy_6f equ 6 cy_71 equ 5 cy_73 equ 8 cy_74 equ 4 cy_75 equ 4 cy_76 equ 6 cy_77 equ 6 cy_78 equ 2 cy_79 equ 4 cy_7b equ 7 cy_7d equ 4 cy_7e equ 7 cy_7f equ 7 cy_80 equ 2 cy_81 equ 6 cy_82 equ 2 cy_83 equ 6 cy_84 equ 3 cy_85 equ 3 cy_86 equ 3 cy_87 equ 3 cy_88 equ 2 cy_89 equ 2 cy_8a equ 2 cy_8c equ 4 cy_8d equ 4 cy_8e equ 4 cy_8f equ 4 cy_91 equ 6 cy_93 equ 6 cy_94 equ 4 cy_95 equ 4 cy_96 equ 4 cy_97 equ 4 cy_98 equ 2 cy_99 equ 5 cy_9a equ 2 cy_9b equ 5 cy_9c equ 5 cy_9d equ 5 cy_a0 equ 2 cy_a1 equ 6 cy_a2 equ 2 cy_a3 equ 6 cy_a4 equ 3 cy_a5 equ 3 cy_a6 equ 3 cy_a7 equ 3 cy_a8 equ 2 cy_a9 equ 2 cy_aa equ 2 cy_ab equ 2 cy_ac equ 4 cy_ad equ 4 cy_ae equ 4 cy_af equ 4 cy_b1 equ 5 cy_b3 equ 5 cy_b4 equ 4 cy_b5 equ 4 cy_b6 equ 4 cy_b7 equ 4 cy_b8 equ 2 cy_b9 equ 4 cy_ba equ 2 cy_bb equ 4 cy_bc equ 4 cy_bd equ 4 cy_be equ 4 cy_bf equ 4 cy_c0 equ 2 cy_c1 equ 6 cy_c2 equ 2 cy_c3 equ 8 cy_c4 equ 3 cy_c5 equ 3 cy_c6 equ 5 cy_c7 equ 5 cy_c8 equ 2 cy_c9 equ 2 cy_ca equ 2 cy_cb equ 2 cy_cc equ 4 cy_cd equ 4 cy_ce equ 6 cy_cf equ 6 cy_d1 equ 5 cy_d2 equ 2 cy_d3 equ 8 cy_d4 equ 4 cy_d5 equ 4 cy_d6 equ 6 cy_d7 equ 6 cy_d8 equ 2 cy_d9 equ 4 cy_db equ 7 cy_dd equ 4 cy_de equ 7 cy_df equ 7 cy_e0 equ 2 cy_e1 equ 6 cy_e2 equ 2 cy_e3 equ 8 cy_e4 equ 3 cy_e5 equ 3 cy_e6 equ 5 cy_e7 equ 5 cy_e8 equ 2 cy_e9 equ 2 cy_ec equ 4 cy_ed equ 4 cy_ee equ 6 cy_ef equ 6 cy_f1 equ 5 cy_f2 equ 2 cy_f3 equ 8 cy_f4 equ 4 cy_f5 equ 4 cy_f6 equ 6 cy_f7 equ 6 cy_f8 equ 2 cy_f9 equ 4 cy_fb equ 7 cy_fd equ 4 cy_fe equ 7 cy_ff equ 7 dc.l cy_00,cy_01,cy_CIM,cy_03,cy_SKB,cy_05,cy_06,cy_07 dc.l cy_08,cy_09,cy_0a,cy_29,cy_SKW,cy_0d,cy_0e,cy_0f dc.l cy_Bcc,cy_11,cy_CIM,cy_13,cy_14,cy_15,cy_16,cy_17 dc.l cy_18,cy_19,cy_NOP,cy_1b,cy_SKW,cy_1d,cy_1e,cy_1f dc.l cy_20,cy_21,cy_CIM,cy_23,cy_24,cy_25,cy_26,cy_27 dc.l cy_28,cy_29,cy_2a,cy_29,cy_2c,cy_2d,cy_2e,cy_2f dc.l cy_Bcc,cy_31,cy_CIM,cy_33,cy_34,cy_35,cy_36,cy_37 dc.l cy_38,cy_39,cy_NOP,cy_3b,cy_SKW,cy_3d,cy_3e,cy_3f dc.l cy_40,cy_41,cy_CIM,cy_43,cy_SKB,cy_45,cy_46,cy_47 dc.l cy_48,cy_49,cy_4a,cy_4b,cy_4c,cy_4d,cy_4e,cy_4f dc.l cy_Bcc,cy_51,cy_CIM,cy_53,cy_54,cy_55,cy_56,cy_57 dc.l cy_58,cy_59,cy_NOP,cy_5b,cy_SKW,cy_5d,cy_5e,cy_5f dc.l cy_60,cy_61,cy_CIM,cy_63,cy_SKB,cy_65,cy_66,cy_67 dc.l cy_68,cy_69,cy_6a,cy_6b,cy_6c,cy_6d,cy_6e,cy_6f dc.l cy_Bcc,cy_71,cy_CIM,cy_73,cy_74,cy_75,cy_76,cy_77 dc.l cy_78,cy_79,cy_NOP,cy_7b,cy_SKW,cy_7d,cy_7e,cy_7f dc.l cy_80,cy_81,cy_82,cy_83,cy_84,cy_85,cy_86,cy_87 dc.l cy_88,cy_89,cy_8a,cy_29,cy_8c,cy_8d,cy_8e,cy_8f dc.l cy_Bcc,cy_91,cy_CIM,cy_93,cy_94,cy_95,cy_96,cy_97 dc.l cy_98,cy_99,cy_9a,cy_9b,cy_9c,cy_9d,cy_9b,cy_9b dc.l cy_a0,cy_a1,cy_a2,cy_a3,cy_a4,cy_a5,cy_a6,cy_a7 dc.l cy_a8,cy_a9,cy_aa,cy_ab,cy_ac,cy_ad,cy_ae,cy_af dc.l cy_Bcc,cy_b1,cy_CIM,cy_b3,cy_b4,cy_b5,cy_b6,cy_b7 dc.l cy_b8,cy_b9,cy_ba,cy_bb,cy_bc,cy_bd,cy_be,cy_bf dc.l cy_c0,cy_c1,cy_c2,cy_c3,cy_c4,cy_c5,cy_c6,cy_c7 dc.l cy_c8,cy_c9,cy_ca,cy_cb,cy_cc,cy_cd,cy_ce,cy_cf dc.l cy_Bcc,cy_d1,cy_d2,cy_d3,cy_d4,cy_d5,cy_d6,cy_d7 dc.l cy_d8,cy_d9,cy_NOP,cy_db,cy_SKW,cy_dd,cy_de,cy_df dc.l cy_e0,cy_e1,cy_e2,cy_e3,cy_e4,cy_e5,cy_e6,cy_e7 dc.l cy_e8,cy_e9,cy_NOP,cy_e9,cy_ec,cy_ed,cy_ee,cy_ef dc.l cy_Bcc,cy_f1,cy_f2,cy_f3,cy_f4,cy_f5,cy_f6,cy_f7 dc.l cy_f8,cy_f9,cy_NOP,cy_fb,cy_SKW,cy_fd,cy_fe,cy_ff OPMODE_TABLE: dc.l opcode_00,opcode_01,instr_CIM,opcode_03 ; brk ora illegal illegal dc.l instr_SKB,opcode_05,opcode_06,opcode_07 ; nop ora asl nop dc.l opcode_08,opcode_09,opcode_0a,opcode_29 ; php ora asla illegal dc.l instr_SKW,opcode_0d,opcode_0e,opcode_0f ; nop 3 ora asl illegal dc.l opcode_10,opcode_11,instr_CIM,opcode_13 ; bpl ora illegal illegal dc.l opcode_14,opcode_15,opcode_16,opcode_17 ; nop ora asl illegal dc.l opcode_18,opcode_19,instr_NOP,opcode_1b ; clc ora nop illegal dc.l instr_SKW,opcode_1d,opcode_1e,opcode_1f ; nop ora asl illegal dc.l opcode_20,opcode_21,instr_CIM,opcode_23 ; jsr and illegal illegal dc.l opcode_24,opcode_25,opcode_26,opcode_27 ; bit and rol illegal dc.l opcode_28,opcode_29,opcode_2a,opcode_29 ; plp and rolA illegal dc.l opcode_2c,opcode_2d,opcode_2e,opcode_2f ; bit and rol illegal dc.l opcode_30,opcode_31,instr_CIM,opcode_33 ; bmi and illegal illegal dc.l opcode_34,opcode_35,opcode_36,opcode_37 ; nop and rol illegal dc.l opcode_38,opcode_39,instr_NOP,opcode_3b ; sec and nop illegal dc.l instr_SKW,opcode_3d,opcode_3e,opcode_3f ; nop and rol illegal dc.l opcode_40,opcode_41,instr_CIM,opcode_43 ; rti eor illegal illegal dc.l instr_SKB,opcode_45,opcode_46,opcode_47 ; nop eor lsr illegal dc.l opcode_48,opcode_49,opcode_4a,opcode_4b ; pha eor lsrA illegal dc.l opcode_4c,opcode_4d,opcode_4e,opcode_4f ; jmp eor lsr illegal dc.l opcode_50,opcode_51,instr_CIM,opcode_53 ; bvc eor illegal illegal dc.l opcode_54,opcode_55,opcode_56,opcode_57 ; nop eor lsr illegal dc.l opcode_58,opcode_59,instr_NOP,opcode_5b ; cli eor nop illegal dc.l instr_SKW,opcode_5d,opcode_5e,opcode_5f ; nop eor lsr illegal dc.l opcode_60,opcode_61,instr_CIM,opcode_63 ; rts adc illegal illegal dc.l instr_SKB,opcode_65,opcode_66,opcode_67 ; nop adc ror illegal dc.l opcode_68,opcode_69,opcode_6a,opcode_6b ; pla adc rorA illegal dc.l opcode_6c,opcode_6d,opcode_6e,opcode_6f ; jmp (abcd) adc ror illegal dc.l opcode_70,opcode_71,instr_CIM,opcode_73 ; bvs adc illegal illegal dc.l opcode_74,opcode_75,opcode_76,opcode_77 ; nop adc ror illegal dc.l opcode_78,opcode_79,instr_NOP,opcode_7b ; SEI adc illegal illegal dc.l instr_SKW,opcode_7d,opcode_7e,opcode_7f ; nop adc ror illegal dc.l opcode_80,opcode_81,opcode_82,opcode_83 ; nop sta nop illegal dc.l opcode_84,opcode_85,opcode_86,opcode_87 ; sty sta stx illegal dc.l opcode_88,opcode_89,opcode_8a,opcode_29 ; dey nop txa illegal dc.l opcode_8c,opcode_8d,opcode_8e,opcode_8f ; sty sta stx illegal dc.l opcode_90,opcode_91,instr_CIM,opcode_93 ; bcc sta illegal illegal dc.l opcode_94,opcode_95,opcode_96,opcode_97 ; sty sta stx illegal dc.l opcode_98,opcode_99,opcode_9a,opcode_9b ; tya sta txs illegal dc.l opcode_9c,opcode_9d,opcode_9b,opcode_9b ; illegal sta illegal illegal dc.l opcode_a0,opcode_a1,opcode_a2,opcode_a3 ; ldy lda ldx lax dc.l opcode_a4,opcode_a5,opcode_a6,opcode_a7 ; ldy lda ldx lax dc.l opcode_a8,opcode_a9,opcode_aa,opcode_ab ; tay lda tax oal dc.l opcode_ac,opcode_ad,opcode_ae,opcode_af ; ldy lda ldx lax dc.l opcode_b0,opcode_b1,instr_CIM,opcode_b3 ; bcs lda illegal lax dc.l opcode_b4,opcode_b5,opcode_b6,opcode_b7 ; ldy lda ldx lax dc.l opcode_b8,opcode_b9,opcode_ba,opcode_bb ; clv lda tsx illegal dc.l opcode_bc,opcode_bd,opcode_be,opcode_bf ; ldy lda ldx lax dc.l opcode_c0,opcode_c1,opcode_c2,opcode_c3 ; cpy cmp nop dcm dc.l opcode_c4,opcode_c5,opcode_c6,opcode_c7 ; cpy cmp dec illegal dc.l opcode_c8,opcode_c9,opcode_ca,opcode_cb ; iny cmp dex illegal dc.l opcode_cc,opcode_cd,opcode_ce,opcode_cf ; cpy cmp dec illegal dc.l opcode_d0,opcode_d1,opcode_d2,opcode_d3 ; bne cmp escrts illegal dc.l opcode_d4,opcode_d5,opcode_d6,opcode_d7 ; nop cmp dec illegal dc.l opcode_d8,opcode_d9,instr_NOP,opcode_db ; cld cmp nop illegal dc.l instr_SKW,opcode_dd,opcode_de,opcode_df ; nop cmp dec illegal dc.l opcode_e0,opcode_e1,opcode_e2,opcode_e3 ; cpx sbc nop nop dc.l opcode_e4,opcode_e5,opcode_e6,opcode_e7 ; cpx sbc inc illegal dc.l opcode_e8,opcode_e9,instr_NOP,opcode_e9 ; inx sbc nop illegal dc.l opcode_ec,opcode_ed,opcode_ee,opcode_ef ; cpx sbc inc illegal dc.l opcode_f0,opcode_f1,opcode_f2,opcode_f3 ; beq sbc esc#ab illegal dc.l opcode_f4,opcode_f5,opcode_f6,opcode_f7 ; nop sbc inc illegal dc.l opcode_f8,opcode_f9,instr_NOP,opcode_fb ; sed sbc nop illegal dc.l instr_SKW,opcode_fd,opcode_fe,opcode_ff ; nop sbc inc esc#ab section text _GO: ;cycles (d0) ; UWORD PC; ; UBYTE S; ; UBYTE A; ; UBYTE X; ; UBYTE Y; ; ; UWORD addr; ; UBYTE data; ;/* ; This used to be in the main loop but has been removed to improve ; execution speed. It does not seem to have any adverse effect on ; the emulation for two reasons:- ; ; 1. NMI's will can only be raised in atari_custom.c - there is ; no way an NMI can be generated whilst in this routine. ; ; 2. The timing of the IRQs are not that critical. ;*/ movem.l d2-d7/a2-a5,-(a7) move.l 44(a7),CD ; how many cycles ( d8=40 from movem ) lea _memory,memory_pointer UPDATE_LOCAL_REGS ConvertRegP_STATUS d0 lea OPMODE_TABLE,a1 lea _attrib,attrib_pointer tst.b _IRQ ; ~ CPUCHECKIRQ beq NEXTCHANGE_WITHOUT move.b _regP,d0 and.b #I_FLAG,d0 ;is interrupt active bne NEXTCHANGE_WITHOUT ;yes, no other interrupt move.w _regPC,d7 PHW d7,d0 move.b _regP,d7 PHB d7,d0 SetI clr.l d7 move.w (memory_pointer,$fffe.l),d7 LoHi move.l d7,PC6502 add.l memory_pointer,PC6502 clr.b _IRQ ;clear interrupt..... bra NEXTCHANGE_WITHOUT ;/* ; ===================================== ; Extract Address if Required by Opcode ; ===================================== ;*/ ;d0 contains final value for use in program ; addressing macros NCYCLES_XY macro cmp.b \1,d7 ; if ( (UBYTE) addr < X,Y ) ncycles--; bpl.s .NCY_XY_NC\@ subq.l #1,CD .NCY_XY_NC\@: endm ABSOLUTE macro move.w (PC6502)+,d7 ror.w #8,d7 ;d7 contains reversed value endm ABSOLUTE_X macro ABSOLUTE add.w X,d7 endm ABSOLUTE_X_NCY macro ABSOLUTE_X \1 NCYCLES_XY X endm ABSOLUTE_Y macro ABSOLUTE add.w Y,d7 endm ABSOLUTE_Y_NCY macro ABSOLUTE_Y \1 subq.l #\1,CD NCYCLES_XY Y endm IMMEDIATE macro move.b (PC6502)+,\1 endm INDIRECT_X macro move.b (PC6502)+,d7 add.b X,d7 move.w (memory_pointer,d7.l),d7 ror.w #8,d7 endm INDIRECT_Y macro move.b (PC6502)+,d7 move.w (memory_pointer,d7.l),d7 ror.w #8,d7 ;swap bytes add.w Y,d7 endm INDIRECT_Y_NCY macro INDIRECT_Y subq.l #\1,CD NCYCLES_XY Y endm ZPAGE macro move.b (PC6502)+,d7 endm ZPAGE_X macro move.b (PC6502)+,d7 add.b X,d7 endm ZPAGE_Y macro move.b (PC6502)+,d7 add.b Y,d7 endm ; branching macros NEXTCHANGE_REG macro move.b \1,ZFLAG bra.w NEXTCHANGE_N endm DONT_BRA macro addq.l #1,PC6502 subq.l #cy_Bcc,CD bgt.w NEXTCHANGE_WSYNC bra.w END_OF_CYCLE endm JMP_C macro move.w (PC6502)+,d7 LoHi ;(in d7 adress where we want to jump) lea (memory_pointer,d7.l),PC6502 subq.l #\1,CD bgt.w NEXTCHANGE_WSYNC bra.w END_OF_CYCLE endm ; get byte macros LOAD_IMMEDIATE macro move.b (PC6502)+,\2 move.b \2,ZFLAG ext.w NFLAG subq.l #\1,CD bgt.w NEXTCHANGE_WSYNC bra.w END_OF_CYCLE endm LOAD_ZPAGE macro move.b (PC6502)+,d7 move.b (memory_pointer,d7.l),\2 ;get byte move.b \2,ZFLAG ext.w NFLAG subq.l #\1,CD bgt.w NEXTCHANGE_WSYNC bra.w END_OF_CYCLE endm GETZPBYTE macro move.b (memory_pointer,d7.l),\1 ;get byte endm GETANYBYTE macro cmp.b #isHARDWARE,(attrib_pointer,d7.l) bne.s .Getbyte_RAMROM\@ EXE_GETBYTE move.b d0,\1 lea OPMODE_TABLE,a1 bra.s .AFTER_READ\@ .Getbyte_RAMROM\@ move.b (memory_pointer,d7.l),\1 ;get byte .AFTER_READ\@ endm GETANYBYTE_d0 macro cmp.b #isHARDWARE,(attrib_pointer,d7.l) bne.s .Getbyte_RAMROM\@ EXE_GETBYTE lea OPMODE_TABLE,a1 bra.s .AFTER_READ\@ .Getbyte_RAMROM\@ move.b (memory_pointer,d7.l),d0 ;get byte .AFTER_READ\@ endm LOADANYBYTE macro cmp.b #isHARDWARE,(attrib_pointer,d7.l) beq.s .LoadByte_HW\@ move.b (memory_pointer,d7.l),\1 ;get byte NEXTCHANGE_REG \1 .LoadByte_HW\@ EXE_GETBYTE move.b d0,\1 lea OPMODE_TABLE,a1 NEXTCHANGE_REG \1 endm ; put byte macros PUTZPBYTE macro move.b \2,(memory_pointer,d7.l) subq.l #\1,CD bgt.w NEXTCHANGE_WSYNC bra.w END_OF_CYCLE endm PUTZPBYTE_Z macro move.b ZFLAG,(memory_pointer,d7.l) subq.l #\1,CD bra.w NEXTCHANGE_N endm STOREANYBYTE macro tst.b (attrib_pointer,d7.l) bne.s .GO_PUTBYTE\@ move.b \2,(memory_pointer,d7.l) subq.l #\1,CD bgt.w NEXTCHANGE_WSYNC bra.w END_OF_CYCLE .GO_PUTBYTE\@: move.b \2,d0 subq.l #\1,CD bra.w A800PUTB endm PUTANYBYTE_N macro ext.w NFLAG tst.b (attrib_pointer,d7.l) bne.s .GO_PUTBYTE\@ move.b ZFLAG,(memory_pointer,d7.l) subq.l #\1,CD bgt.w NEXTCHANGE_WSYNC bra.w END_OF_CYCLE .GO_PUTBYTE\@: subq.l #\1,CD bra.w A800PUTB_Ld0 endm PUTANYBYTE macro tst.b (attrib_pointer,d7.l) bne.s .GO_PUTBYTE\@ move.b d0,(memory_pointer,d7.l) subq.l #\1,CD bgt.w NEXTCHANGE_WSYNC bra.w END_OF_CYCLE .GO_PUTBYTE\@: subq.l #\1,CD bra.w A800PUTB endm A800PUTB_Ld0: move.b ZFLAG,d0 A800PUTB: cmp.b #isROM,(attrib_pointer,d7.l) beq.w A800PUTBE move.l d1,-(a7) EXE_PUTBYTE_d0 move.l (a7)+,d1 lea OPMODE_TABLE,a1 A800PUTBE: bra.w NEXTCHANGE_WITHOUT ; command macros ROL_C macro move.w CCR6502,CCR addx.b \1,\1 ;left move.w CCR,CCR6502 endm RPW_ROL_C macro tst.b (attrib_pointer,d7.l) bne.s .RPW_NO_RAM_ROL\@ move.b (memory_pointer,d7.l),ZFLAG ;get byte ROL_C ZFLAG move.b ZFLAG,(memory_pointer,d7.l) bra.w NEXTCHANGE_N .RPW_NO_RAM_ROL\@: bra.w RPW_HW_ROL endm RPW_HW_ROL: cmp.b #isROM,(attrib_pointer,d7.l) beq.s RPW_ROM_ROL EXE_GETBYTE move.b d0,ZFLAG ROL_C ZFLAG ext.w NFLAG move.l ZFLAG,-(a7) EXE_PUTBYTE ZFLAG move.l (a7)+,ZFLAG lea OPMODE_TABLE,a1 bra.w NEXTCHANGE_WITHOUT RPW_ROM_ROL: move.b (memory_pointer,d7.l),ZFLAG ;get byte ROL_C ZFLAG bra.w NEXTCHANGE_N ROR_C macro move.w CCR6502,CCR roxr.b #1,\1 move.w CCR,CCR6502 endm RPW_ROR_C macro tst.b (attrib_pointer,d7.l) bne.s .RPW_NO_RAM_ROR\@ move.b (memory_pointer,d7.l),ZFLAG ;get byte ROR_C ZFLAG move.b ZFLAG,(memory_pointer,d7.l) bra.w NEXTCHANGE_N .RPW_NO_RAM_ROR\@: bra.w RPW_HW_ROR endm RPW_HW_ROR: cmp.b #isROM,(attrib_pointer,d7.l) beq.s RPW_ROM_ROR EXE_GETBYTE move.b d0,ZFLAG ROR_C ZFLAG ext.w NFLAG move.l ZFLAG,-(a7) EXE_PUTBYTE ZFLAG move.l (a7)+,ZFLAG lea OPMODE_TABLE,a1 bra.w NEXTCHANGE_WITHOUT RPW_ROM_ROR: move.b (memory_pointer,d7.l),ZFLAG ;get byte ROR_C ZFLAG bra.w NEXTCHANGE_N ASL_C macro add.b \1,\1 ;left move.w CCR,CCR6502 endm RPW_ASL_C macro tst.b (attrib_pointer,d7.l) bne.s .RPW_NO_RAM_ASL\@ move.b (memory_pointer,d7.l),ZFLAG ;get byte ASL_C ZFLAG move.b ZFLAG,(memory_pointer,d7.l) bra.w NEXTCHANGE_N .RPW_NO_RAM_ASL\@: bra.w RPW_HW_ASL endm RPW_HW_ASL: cmp.b #isROM,(attrib_pointer,d7.l) beq.s RPW_ROM_ASL EXE_GETBYTE move.b d0,ZFLAG ASL_C ZFLAG ext.w NFLAG move.l ZFLAG,-(a7) EXE_PUTBYTE ZFLAG move.l (a7)+,ZFLAG lea OPMODE_TABLE,a1 bra.w NEXTCHANGE_WITHOUT RPW_ROM_ASL: move.b (memory_pointer,d7.l),ZFLAG ;get byte ASL_C ZFLAG bra.w NEXTCHANGE_N LSR_C macro lsr.b #1,\1 move.w CCR,CCR6502 endm RPW_LSR_C macro clr.w NFLAG tst.b (attrib_pointer,d7.l) bne.s .RPW_NO_RAM_LSR\@ move.b (memory_pointer,d7.l),ZFLAG ;get byte LSR_C ZFLAG move.b ZFLAG,(memory_pointer,d7.l) bra.w NEXTCHANGE_WITHOUT .RPW_NO_RAM_LSR\@: bra.w RPW_HW_LSR endm RPW_HW_LSR: cmp.b #isROM,(attrib_pointer,d7.l) beq.s RPW_ROM_LSR EXE_GETBYTE move.b d0,ZFLAG LSR_C ZFLAG move.l ZFLAG,-(a7) EXE_PUTBYTE ZFLAG move.l (a7)+,ZFLAG lea OPMODE_TABLE,a1 bra.w NEXTCHANGE_WITHOUT RPW_ROM_LSR: move.b (memory_pointer,d7.l),ZFLAG ;get byte LSR_C ZFLAG bra.w NEXTCHANGE_WITHOUT ASO_C_CONT macro ;/* [unofficial - ASL Mem then ORA with Acc] */ ASL_C d0 or.b d0,A move.b A,ZFLAG ext.w NFLAG tst.b (attrib_pointer,d7.l) bne.s .ROM_OR_HW\@ move.b d0,(memory_pointer,d7.l) bra.w NEXTCHANGE_WITHOUT .ROM_OR_HW\@ cmp.b #isROM,(attrib_pointer,d7.l) bne.w A800PUTB bra.w NEXTCHANGE_WITHOUT endm LSE_C_CONT macro ;/* [unofficial - LSR Mem then EOR with A] */ LSR_C d0 eor.b d0,A move.b A,ZFLAG ext.w NFLAG tst.b (attrib_pointer,d7.l) bne.s .ROM_OR_HW\@ move.b d0,(memory_pointer,d7.l) bra.w NEXTCHANGE_WITHOUT .ROM_OR_HW\@ cmp.b #isROM,(attrib_pointer,d7.l) bne.w A800PUTB bra.w NEXTCHANGE_WITHOUT endm CIM_C_CONT macro ;/* [unofficial - crash intermediate] */ subq.w #1,PC6502 subq.l #\1,CD bgt.w NEXTCHANGE_WSYNC bra.w END_OF_CYCLE endm SKB_C_CONT macro ;/* [unofficial - skip byte] */ addq.l #1,PC6502 subq.l #\1,CD bgt.w NEXTCHANGE_WSYNC bra.w END_OF_CYCLE endm SKW_C_CONT macro ;/* [unofficial - skip word] */ addq.l #2,PC6502 subq.l #\1,CD bgt.w NEXTCHANGE_WSYNC bra.w END_OF_CYCLE endm XA1_C_CONT macro ;/* [unofficial - X AND A AND 1 to Mem] */ move.b X,d0 and.b A,d0 and.b #1,d0 PUTANYBYTE \1 endm AXS_C_CONT macro ;/* [unofficial - Store result A AND X] */ move.b X,ZFLAG and.b A,ZFLAG PUTANYBYTE_N \1 endm RLA_C macro ;/* [unofficial - ROL Mem, then AND with A] */ ROL_C d0 move.b d0,ZFLAG and.b A,ZFLAG ext.w NFLAG endm RRA_C_CONT macro ;/* [unofficial - ROR Mem, then ADC to Acc] */ ROR_C d0 tst.b (attrib_pointer,d7.l) bne.s .ROM_OR_HW\@ move.b d0,(memory_pointer,d7.l) bra.w adc .ROM_OR_HW\@ cmp.b #isROM,(attrib_pointer,d7.l) bne.w Putbyte_ADC bra.w adc endm DCM_C_CONT macro ;/* [unofficial - DEC Mem then CMP with Acc] */ subq.b #1,d0 tst.b (attrib_pointer,d7.l) bne.s .ROM_OR_HW\@ move.b d0,(memory_pointer,d7.l) bra.w COMPARE_A .ROM_OR_HW\@ cmp.b #isROM,(attrib_pointer,d7.l) bne.w Putbyte_CMP bra.w COMPARE_A endm INS_C_CONT macro ;/* [unofficial - INC Mem then SBC with Acc] */ addq.b #1,d0 tst.b (attrib_pointer,d7.l) bne.s .ROM_OR_HW\@ move.b d0,(memory_pointer,d7.l) bra.w sbc .ROM_OR_HW\@ cmp.b #isROM,(attrib_pointer,d7.l) bne.w Putbyte_SBC bra.w sbc endm OR_IMMEDIATE macro subq.l #\1,CD or.b (PC6502)+,A move.b A,ZFLAG bra.w NEXTCHANGE_N endm OR_ZPBYTE macro or.b (memory_pointer,d7.l),A move.b A,ZFLAG bra.w NEXTCHANGE_N endm OR_ANYBYTE macro cmp.b #isHARDWARE,(attrib_pointer,d7.l) beq.s .Getbyte_HW\@ or.b (memory_pointer,d7.l),A move.b A,ZFLAG bra.w NEXTCHANGE_N .Getbyte_HW\@: EXE_GETBYTE or.b d0,A lea OPMODE_TABLE,a1 move.b A,ZFLAG bra.w NEXTCHANGE_N endm EOR_C_CONT macro eor.b d0,A move.b A,ZFLAG bra.w NEXTCHANGE_N endm AND_IMMEDIATE macro subq.l #\1,CD and.b (PC6502)+,A move.b A,ZFLAG bra.w NEXTCHANGE_N endm AND_ZPBYTE macro and.b (memory_pointer,d7.l),A move.b A,ZFLAG bra.w NEXTCHANGE_N endm AND_ANYBYTE macro cmp.b #isHARDWARE,(attrib_pointer,d7.l) beq.s .Getbyte_HW\@ and.b (memory_pointer,d7.l),A move.b A,ZFLAG bra.w NEXTCHANGE_N .Getbyte_HW\@: EXE_GETBYTE and.b d0,A lea OPMODE_TABLE,a1 move.b A,ZFLAG bra.w NEXTCHANGE_N endm BIT_C_CONT macro btst #V_FLAGB,ZFLAG beq.s .CLEAR_IT\@ bset #16,VFLAG ;exactly V_FLAGB,_regP ext.w NFLAG and.b A,ZFLAG subq.l #\1,CD bgt.w NEXTCHANGE_WSYNC bra.w END_OF_CYCLE .CLEAR_IT\@: bclr #16,VFLAG ;exactly V_FLAGB,_regP ext.w NFLAG and.b A,ZFLAG subq.l #\1,CD bgt.w NEXTCHANGE_WSYNC bra.w END_OF_CYCLE endm ; opcodes ; inofficial opcodes ;opcode_02: ;/* CIM [unofficial] */ instr_CIM: CIM_C_CONT cy_CIM opcode_03: ;/* ASO (ab,x) [unofficial] */ INDIRECT_X subq.l #cy_03,CD GETANYBYTE_d0 ASO_C_CONT ; opcode_04: ;/* SKB [unofficial] */ instr_SKB: SKB_C_CONT cy_SKB opcode_07: ;/* ASO ZPAGE [unofficial] */ subq.l #cy_07,CD ZPAGE GETZPBYTE d0 ASO_C_CONT ;opcode_0b: ;/* AND #ab [unofficial] ( at _29 ) */ ; opcode_0c: ;/* SKW [unofficial] */ instr_SKW: SKW_C_CONT cy_SKW opcode_0f: ;/* ASO abcd [unofficial] */ ABSOLUTE subq.l #cy_0f,CD GETANYBYTE_d0 ASO_C_CONT ; opcode_12: ;/* CIM [unofficial] ( at _02 ) */ opcode_13: ;/* ASO (ab),y [unofficial] */ INDIRECT_Y subq.l #cy_13,CD GETANYBYTE_d0 ASO_C_CONT opcode_14: SKB_C_CONT cy_14 opcode_17: ;/* ASO zpage,x [unofficial] */ subq.l #cy_17,CD ZPAGE_X GETZPBYTE d0 ASO_C_CONT ; opcode_1a: ;/* NOP [unofficial] ( at _ea ) */ opcode_1b: ;/* ASO abcd,y [unofficial] */ ABSOLUTE_Y subq.l #cy_1b,CD GETANYBYTE_d0 ASO_C_CONT ; opcode_1c: ;/* SKW [unofficial] ( at _0c ) */ opcode_1f: ;/* ASO abcd,x [unofficial] */ ABSOLUTE_X subq.l #cy_1f,CD GETANYBYTE_d0 ASO_C_CONT ; opcode_22: ;/* CIM [unofficial] ( at _02 ) */ opcode_23: ;/* RLA (ab,x) [unofficial] */ INDIRECT_X GETANYBYTE_d0 RLA_C PUTANYBYTE cy_23 opcode_27: ;/* RLA ZPAGE [unofficial] */ ZPAGE GETZPBYTE d0 RLA_C PUTZPBYTE cy_27,d0 ;opcode_2b: ;/* AND #ab [unofficial] ( at _29 ) */ opcode_2f: ;/* RLA abcd [unofficial] */ ABSOLUTE GETANYBYTE_d0 RLA_C PUTANYBYTE cy_2f ; opcode_32: ;/* CIM [unofficial] ( at _02 ) */ opcode_33: ;/* RLA (ab),y [unofficial] */ INDIRECT_Y GETANYBYTE_d0 RLA_C PUTANYBYTE cy_33 opcode_34: SKB_C_CONT cy_34 opcode_37: ;/* RLA zpage,x [unofficial] */ ZPAGE_X GETZPBYTE d0 RLA_C PUTZPBYTE cy_37,d0 ; opcode_3a: ;/* NOP [unofficial] ( at _ea ) */ opcode_3b: ;/* RLA abcd,y [unofficial] */ ABSOLUTE_Y GETANYBYTE_d0 RLA_C PUTANYBYTE cy_3b ; opcode_3c: ;/* SKW [unofficial] ( at _0c ) */ opcode_3f: ;/* RLA abcd,x [unofficial] */ ABSOLUTE_X GETANYBYTE_d0 RLA_C PUTANYBYTE cy_3f ; opcode_42: ;/* CIM [unofficial] ( at _02 ) */ opcode_43: ;/* LSE (ab,x) [unofficial] */ INDIRECT_X subq.l #cy_43,CD GETANYBYTE_d0 LSE_C_CONT ; opcode_44: ;/* SKB [unofficial] ( at _04 ) */ opcode_47: ;/* LSE ZPAGE [unofficial] */ subq.l #cy_47,CD ZPAGE GETZPBYTE d0 LSE_C_CONT opcode_4b: ;/* ALR #ab [unofficial - Acc AND Data, LSR result] */ IMMEDIATE ZFLAG subq.l #cy_4b,CD and.b A,ZFLAG LSR_C ZFLAG bra.w NEXTCHANGE_N opcode_4f: ;/* LSE abcd [unofficial] */ ABSOLUTE subq.l #cy_4f,CD GETANYBYTE_d0 LSE_C_CONT ; opcode_52: ;/* CIM [unofficial] ( at _02 ) */ opcode_53: ;/* LSE (ab),y [unofficial] */ INDIRECT_Y subq.l #cy_53,CD GETANYBYTE_d0 LSE_C_CONT opcode_54: SKB_C_CONT cy_54 opcode_57: ;/* LSE zpage,x [unofficial] */ subq.l #cy_57,CD ZPAGE_X GETZPBYTE d0 LSE_C_CONT ; opcode_5a: ;/* NOP [unofficial] ( at _ea ) */ opcode_5b: ;/* LSE abcd,y [unofficial] */ ABSOLUTE_Y subq.l #cy_5b,CD GETANYBYTE_d0 LSE_C_CONT ; opcode_5c: ;/* SKW [unofficial] ( at _0c ) */ opcode_5f: ;/* LSE abcd,x [unofficial] */ ABSOLUTE_X subq.l #cy_5f,CD GETANYBYTE_d0 LSE_C_CONT ; opcode_62: ;/* CIM [unofficial] ( at _02 ) */ opcode_63: ;/* RRA (ab,x) [unofficial] */ INDIRECT_X subq.l #cy_63,CD GETANYBYTE_d0 RRA_C_CONT ; opcode_64: ;/* SKB [unofficial] ( at _04 ) */ opcode_67: ;/* RRA ZPAGE [unofficial] */ subq.l #cy_67,CD ZPAGE GETZPBYTE d0 RRA_C_CONT opcode_6b: ;/* ARR #ab [unofficial - Acc AND Data, ROR result] */ IMMEDIATE ZFLAG subq.l #cy_6b,CD and.b A,ZFLAG ROR_C ZFLAG bra.w NEXTCHANGE_N opcode_6f: ;/* RRA abcd [unofficial] */ ABSOLUTE subq.l #cy_6f,CD GETANYBYTE_d0 RRA_C_CONT ; opcode_72: ;/* CIM [unofficial] ( at _02 ) */ opcode_73: ;/* RRA (ab),y [unofficial] */ INDIRECT_Y subq.l #cy_73,CD GETANYBYTE_d0 RRA_C_CONT opcode_74: SKB_C_CONT cy_74 opcode_77: ;/* RRA zpage,x [unofficial] */ subq.l #cy_77,CD ZPAGE_X GETZPBYTE d0 RRA_C_CONT ; opcode_7a: ;/* NOP [unofficial] ( at _ea ) */ opcode_7b: ;/* RRA abcd,y [unofficial] */ ABSOLUTE_Y subq.l #cy_7b,CD GETANYBYTE_d0 RRA_C_CONT ; opcode_7c: ;/* SKW [unofficial] ( at _0c ) */ opcode_7f: ;/* RRA abcd,x [unofficial] */ ABSOLUTE_X subq.l #cy_7f,CD GETANYBYTE_d0 RRA_C_CONT opcode_80: SKB_C_CONT cy_80 opcode_82: SKB_C_CONT cy_82 opcode_83: ;/* AXS (ab,x) [unofficial] */ INDIRECT_X AXS_C_CONT cy_83 opcode_87: ;/* AXS ZPAGE [unofficial] */ ZPAGE move.b X,ZFLAG and.b A,ZFLAG PUTZPBYTE_Z cy_87 opcode_89: SKB_C_CONT cy_89 ;opcode_8b: ;/* AND #ab [unofficial] ( at _29 ) */ opcode_8f: ;/* AXS abcd [unofficial] */ ABSOLUTE AXS_C_CONT cy_8f ; opcode_92: ;/* CIM [unofficial] ( at _02 ) */ opcode_93: ;/* AXS (ab),y [unofficial] */ INDIRECT_Y AXS_C_CONT cy_93 opcode_97: ;/* AXS zpage,y [unofficial] */ ZPAGE_Y move.b X,ZFLAG and.b A,ZFLAG PUTZPBYTE_Z cy_97 opcode_9b: ;/* XA1 abcd,y [unofficial] */ ABSOLUTE_Y XA1_C_CONT cy_9b opcode_9c: SKW_C_CONT cy_9c ;opcode_9e: ;/* XA1 abcd,y (_9b)[unofficial] */ ;opcode_9f: ;/* XA1 abcd,y (_9b)[unofficial] */ opcode_a3: ;/* LAX (ind,x) [unofficial] */ INDIRECT_X subq.l #cy_a3,CD GETANYBYTE A move.b A,X NEXTCHANGE_REG A opcode_a7: ;/* LAX ZPAGE [unofficial] */ subq.l #cy_a7,CD ZPAGE GETZPBYTE A move.b A,X NEXTCHANGE_REG A opcode_ab: ;/* ANX #ab [unofficial - AND #ab, TAX] */ IMMEDIATE d0 subq.l #cy_ab,CD and.b d0,A move.b A,X NEXTCHANGE_REG A opcode_af: ;/* LAX absolute [unofficial] */ ABSOLUTE subq.l #cy_af,CD GETANYBYTE A move.b A,X NEXTCHANGE_REG A ; opcode_b2: ;/* CIM [unofficial] ( at _02 ) */ opcode_b3: ;/* LAX (ind),y [unofficial] */ INDIRECT_Y subq.l #cy_b3,CD GETANYBYTE A move.b A,X NEXTCHANGE_REG A opcode_b7: ;/* LAX zpage,y [unofficial] */ subq.l #cy_b7,CD ZPAGE_Y GETZPBYTE A move.b A,X NEXTCHANGE_REG A opcode_bb: ;/* AXA abcd,y [unofficial - Store Mem AND #$FD to Acc and X, ;then set stackpoint to value (Acc - 4) */ ABSOLUTE_Y GETANYBYTE_d0 and.b #$fd,d0 clr.l A move.b d0,A move.b d0,X move.b d0,ZFLAG ext.w NFLAG move.b A,d0 subq.b #4,d0 move.b d0,_regS subq.l #cy_bb,CD bgt.w NEXTCHANGE_WSYNC bra.w END_OF_CYCLE opcode_bf: ;/* LAX absolute,y [unofficial] */ ABSOLUTE_Y subq.l #cy_bf,CD GETANYBYTE A move.b A,X NEXTCHANGE_REG A opcode_c2: SKB_C_CONT cy_c2 opcode_c3: ;/* DCM (ab,x) [unofficial] */ INDIRECT_X subq.l #cy_c3,CD GETANYBYTE_d0 DCM_C_CONT opcode_c7: ;/* DCM ZPAGE [unofficial] */ subq.l #cy_c7,CD ZPAGE GETZPBYTE d0 DCM_C_CONT opcode_cb: ;/* SAX #ab [unofficial - A AND X, then SBC Mem, store to X] */ IMMEDIATE d0 subq.l #cy_cb,CD and.b A,X btst #D_FLAGB,_regP bne.s .BCD_SBC_X not.w CCR6502 move.w CCR6502,CCR subx.b d0,X move.w CCR,CCR6502 bvs.s .SET_V bclr #16,VFLAG not.w CCR6502 NEXTCHANGE_REG X .SET_V: bset #16,VFLAG not.w CCR6502 NEXTCHANGE_REG X .BCD_SBC_X: move.b X,ZFLAG not.w CCR6502 move.w CCR6502,CCR subx.b d0,ZFLAG bvs.s .SET_V_X bclr #16,VFLAG bra.s .END_V_X .SET_V_X: bset #16,VFLAG .END_V_X: ext.w NFLAG move.w CCR6502,CCR sbcd d0,X move.w CCR,CCR6502 not.w CCR6502 bra.w NEXTCHANGE_WITHOUT opcode_cf: ;/* DCM abcd [unofficial] */ ABSOLUTE subq.l #cy_cf,CD GETANYBYTE_d0 DCM_C_CONT opcode_d3: ;/* DCM (ab),y [unofficial] */ INDIRECT_Y subq.l #cy_d3,CD GETANYBYTE_d0 DCM_C_CONT opcode_d4: SKB_C_CONT cy_d4 opcode_d7: ;/* DCM zpage,x [unofficial] */ subq.l #cy_d7,CD ZPAGE_X GETZPBYTE d0 DCM_C_CONT ; opcode_da: ;/* NOP [unofficial] ( at _ea ) */ opcode_db: ;/* DCM abcd,y [unofficial] */ ABSOLUTE_Y subq.l #cy_db,CD GETANYBYTE_d0 DCM_C_CONT ; opcode_dc: ;/* SKW [unofficial] ( at _0c ) */ opcode_df: ;/* DCM abcd,x [unofficial] */ ABSOLUTE_X subq.l #cy_df,CD GETANYBYTE_d0 DCM_C_CONT opcode_e2: SKB_C_CONT cy_e2 opcode_e3: ;/* INS (ab,x) [unofficial] */ INDIRECT_X subq.l #cy_e3,CD GETANYBYTE_d0 INS_C_CONT opcode_e7: ;/* INS ZPAGE [unofficial] */ subq.l #cy_e7,CD ZPAGE GETZPBYTE d0 addq.b #1,d0 move.b d0,(memory_pointer,d7.l) bra sbc ;opcode_eb: ;/* SBC #ab (_e9)[unofficial] */ opcode_ef: ;/* INS abcd [unofficial] */ ABSOLUTE subq.l #cy_ef,CD GETANYBYTE_d0 INS_C_CONT opcode_f3: ;/* INS (ab),y [unofficial] */ INDIRECT_Y subq.l #cy_f3,CD GETANYBYTE_d0 INS_C_CONT opcode_f4: SKB_C_CONT cy_f4 opcode_f7: ;/* INS zpage,x [unofficial] */ subq.l #cy_f7,CD ZPAGE_X GETZPBYTE d0 addq.b #1,d0 move.b d0,(memory_pointer,d7.l) bra sbc ; opcode_fa: ;/* NOP [unofficial] ( at _ea ) */ opcode_fb: ;/* INS abcd,y [unofficial] */ ABSOLUTE_Y subq.l #cy_fb,CD GETANYBYTE_d0 INS_C_CONT ; opcode_fc: ;/* SKW [unofficial] ( at _0c ) */ opcode_ff: ;/* INS abcd,x [unofficial] */ ABSOLUTE_X subq.l #cy_ff,CD GETANYBYTE_d0 INS_C_CONT ; official opcodes opcode_00: ;/* BRK */ subq.l #cy_00,CD btst #I_FLAGB,_regP bne.w NEXTCHANGE_WITHOUT SetB move.l PC6502,d7 sub.l memory_pointer,d7 addq.w #1,d7 PHW_AND_P d7,d0 SetI move.w (memory_pointer,$fffe.l),d7 LoHi move.l d7,PC6502 add.l memory_pointer,PC6502 bra.w NEXTCHANGE_WITHOUT opcode_01: ;/* ORA (ab,x) */ INDIRECT_X subq.l #cy_01,CD OR_ANYBYTE opcode_05: ;/* ORA ab */ subq.l #cy_05,CD ZPAGE OR_ZPBYTE opcode_06: ;/* ASL ab */ ZPAGE GETZPBYTE ZFLAG ASL_C ZFLAG PUTZPBYTE_Z cy_06 opcode_08: ;/* PHP */ PHP d7,d0 subq.l #cy_08,CD bgt.w NEXTCHANGE_WSYNC bra.w END_OF_CYCLE opcode_09: ;/* ORA #ab */ OR_IMMEDIATE cy_09 opcode_0a: ;/* ASLA */ subq.l #cy_0a,CD ASL_C A NEXTCHANGE_REG A opcode_0d: ;/* ORA abcd */ ABSOLUTE subq.l #cy_0d,CD OR_ANYBYTE opcode_0e: ;/* ASL abcd */ ABSOLUTE subq.l #cy_0e,CD RPW_ASL_C opcode_10: ;/* BPL */ tst.w NFLAG bpl SOLVE DONT_BRA opcode_11: ;/* ORA (ab),y */ INDIRECT_Y_NCY cy_11 OR_ANYBYTE opcode_15: ;/* ORA ab,x */ subq.l #cy_15,CD ZPAGE_X OR_ZPBYTE opcode_16: ;/* ASL ab,x */ ZPAGE_X GETZPBYTE ZFLAG ASL_C ZFLAG PUTZPBYTE_Z cy_16 opcode_18: ;/* CLC */ clr.w CCR6502 subq.l #cy_18,CD bgt.w NEXTCHANGE_WSYNC bra.w END_OF_CYCLE opcode_19: ;/* ORA abcd,y */ ABSOLUTE_Y_NCY cy_19 OR_ANYBYTE opcode_1d: ;/* ORA abcd,x */ ABSOLUTE_X_NCY cy_1d OR_ANYBYTE opcode_1e: ;/* ASL abcd,x */ ABSOLUTE_X subq.l #cy_1e,CD RPW_ASL_C opcode_20: ;/* JSR abcd */ move.l PC6502,d7 ;current pointer sub.l memory_pointer,d7 addq.l #1,d7 ;back addres PHW d7,d0 JMP_C cy_20 opcode_21: ;/* AND (ab,x) */ INDIRECT_X subq.l #cy_21,CD AND_ANYBYTE opcode_24: ;/* BIT ab */ ZPAGE GETZPBYTE ZFLAG BIT_C_CONT cy_24 opcode_25: ;/* AND ab */ subq.l #cy_25,CD ZPAGE AND_ZPBYTE opcode_26: ;/* ROL ab */ ZPAGE GETZPBYTE ZFLAG ROL_C ZFLAG PUTZPBYTE_Z cy_26 opcode_28: ;/* PLP */ subq.l #cy_28,CD PLP d7,d0 CPUCHECKIRQ opcode_29: ;/* AND #ab */ AND_IMMEDIATE cy_29 opcode_2a: ;/* ROLA */ subq.l #cy_2a,CD ROL_C A NEXTCHANGE_REG A opcode_2c: ;/* BIT abcd */ ABSOLUTE GETANYBYTE ZFLAG BIT_C_CONT cy_2c opcode_2d: ;/* AND abcd */ ABSOLUTE subq.l #cy_2d,CD AND_ANYBYTE opcode_2e: ;/* ROL abcd */ ABSOLUTE subq.l #cy_2e,CD RPW_ROL_C opcode_30: ;/* BMI */ tst.w NFLAG bmi SOLVE DONT_BRA opcode_31: ;/* AND (ab),y */ INDIRECT_Y_NCY cy_31 AND_ANYBYTE opcode_35: ;/* AND ab,x */ subq.l #cy_35,CD ZPAGE_X AND_ZPBYTE opcode_36: ;/* ROL ab,x */ ZPAGE_X GETZPBYTE ZFLAG ROL_C ZFLAG PUTZPBYTE_Z cy_36 opcode_38: ;/* SEC */ clr.w CCR6502 not.w CCR6502 subq.l #cy_38,CD bgt.w NEXTCHANGE_WSYNC bra.w END_OF_CYCLE opcode_39: ;/* AND abcd,y */ ABSOLUTE_Y_NCY cy_39 AND_ANYBYTE opcode_3d: ;/* AND abcd,x */ ABSOLUTE_X_NCY cy_3d AND_ANYBYTE opcode_3e: ;/* ROL abcd,x */ ABSOLUTE_X subq.l #cy_3e,CD RPW_ROL_C opcode_40: ;/* RTI */ _RTI: subq.l #cy_40,CD PLP_AND_W d7,d0 lea (memory_pointer,d7.l),PC6502 CPUCHECKIRQ opcode_41: ;/* EOR (ab,x) */ INDIRECT_X subq.l #cy_41,CD GETANYBYTE_d0 EOR_C_CONT opcode_45: ;/* EOR ab */ subq.l #cy_45,CD ZPAGE GETZPBYTE d0 EOR_C_CONT opcode_46: ;/* LSR ab */ ZPAGE clr.w NFLAG GETZPBYTE ZFLAG LSR_C ZFLAG PUTZPBYTE cy_46,ZFLAG opcode_48: ;/* PHA */ PHB A,d0 subq.l #cy_48,CD bgt.w NEXTCHANGE_WSYNC bra.w END_OF_CYCLE opcode_49: ;/* EOR #ab */ IMMEDIATE d0 subq.l #cy_49,CD EOR_C_CONT opcode_4a: ;/* LSRA */ clr.w NFLAG LSR_C A move.b A,ZFLAG subq.l #cy_4a,CD bgt.w NEXTCHANGE_WSYNC bra.w END_OF_CYCLE opcode_4c: ;/* JMP abcd */ JMP_C cy_4c opcode_4d: ;/* EOR abcd */ ABSOLUTE subq.l #cy_4d,CD GETANYBYTE_d0 EOR_C_CONT opcode_4e: ;/* LSR abcd */ ABSOLUTE subq.l #cy_4e,CD RPW_LSR_C opcode_50: ;/* BVC */ btst #16,VFLAG ;V_FLAGB,_regP - exactly beq SOLVE DONT_BRA opcode_51: ;/* EOR (ab),y */ INDIRECT_Y_NCY cy_51 GETANYBYTE_d0 EOR_C_CONT opcode_55: ;/* EOR ab,x */ subq.l #cy_55,CD ZPAGE_X GETZPBYTE d0 EOR_C_CONT opcode_56: ;/* LSR ab,x */ ZPAGE_X clr.w NFLAG GETZPBYTE ZFLAG LSR_C ZFLAG PUTZPBYTE cy_56,ZFLAG opcode_58: ;/* CLI */ subq.l #cy_58,CD ClrI tst.b _IRQ ; ~ CPUCHECKIRQ beq.w NEXTCHANGE_WITHOUT move.l PC6502,d7 sub.l memory_pointer,d7 PHW_AND_P d7,d0 SetI move.w (memory_pointer,$fffe.l),d7 LoHi move.l d7,PC6502 add.l memory_pointer,PC6502 clr.b _IRQ bra.w NEXTCHANGE_WITHOUT opcode_59: ;/* EOR abcd,y */ ABSOLUTE_Y_NCY cy_59 GETANYBYTE_d0 EOR_C_CONT opcode_5d: ;/* EOR abcd,x */ ABSOLUTE_X_NCY cy_5d GETANYBYTE_d0 EOR_C_CONT opcode_5e: ;/* LSR abcd,x */ ABSOLUTE_X subq.l #cy_5e,CD RPW_LSR_C opcode_60: ;/* RTS */ PLW d7,d0 lea 1(memory_pointer,d7.l),PC6502 subq.l #cy_60,CD bgt.w NEXTCHANGE_WSYNC bra.w END_OF_CYCLE opcode_61: ;/* ADC (ab,x) */ INDIRECT_X subq.l #cy_61,CD GETANYBYTE_d0 bra adc opcode_65: ;/* ADC ab */ subq.l #cy_65,CD ZPAGE GETZPBYTE d0 bra adc opcode_66: ;/* ROR ab */ ZPAGE GETZPBYTE ZFLAG ROR_C ZFLAG PUTZPBYTE_Z cy_66 opcode_68: ;/* PLA */ subq.l #cy_68,CD PLB A,d0 NEXTCHANGE_REG A opcode_69: ;/* ADC #ab */ IMMEDIATE d0 subq.l #cy_69,CD bra adc opcode_6a: ;/* RORA */ subq.l #cy_6a,CD ROR_C A NEXTCHANGE_REG A opcode_6c: ;/* JMP (abcd) */ move.w (PC6502)+,d7 LoHi ifd P65C02 move.w (memory_pointer,d7.l),d7 LoHi lea (memory_pointer,d7.l),PC6502 else ;/* original 6502 had a bug in jmp (addr) when addr crossed page boundary */ cmp.b #$ff,d7 beq.s .PROBLEM_FOUND ;when problematic jump is found move.w (memory_pointer,d7.l),d7 LoHi lea (memory_pointer,d7.l),PC6502 subq.l #cy_6c,CD bgt.w NEXTCHANGE_WSYNC bra.w END_OF_CYCLE .PROBLEM_FOUND: move.l d7,d0 ;we have to use both of them clr.b d7 ;instead of reading right this adress, ;we read adress at this start of page move.b (memory_pointer,d7.l),d7 LoHi move.b (memory_pointer,d0.l),d7 lea (memory_pointer,d7.l),PC6502 endc subq.l #cy_6c,CD bgt.w NEXTCHANGE_WSYNC bra.w END_OF_CYCLE opcode_6d: ;/* ADC abcd */ ABSOLUTE subq.l #cy_6d,CD GETANYBYTE_d0 bra adc opcode_6e: ;/* ROR abcd */ ABSOLUTE subq.l #cy_6e,CD RPW_ROR_C opcode_70: ;/* BVS */ btst #16,VFLAG bne SOLVE DONT_BRA opcode_71: ;/* ADC (ab),y */ INDIRECT_Y_NCY cy_71 GETANYBYTE_d0 bra adc opcode_75: ;/* ADC ab,x */ subq.l #cy_75,CD ZPAGE_X GETZPBYTE d0 bra adc opcode_76: ;/* ROR ab,x */ ZPAGE_X GETZPBYTE ZFLAG ROR_C ZFLAG PUTZPBYTE_Z cy_76 opcode_78: ;/* SEI */ SetI subq.l #cy_78,CD bgt.w NEXTCHANGE_WSYNC bra.w END_OF_CYCLE opcode_79: ;/* ADC abcd,y */ ABSOLUTE_Y_NCY cy_79 GETANYBYTE_d0 bra adc opcode_7d: ;/* ADC abcd,x */ ABSOLUTE_X_NCY cy_7d GETANYBYTE_d0 bra adc opcode_7e: ;/* ROR abcd,x */ ABSOLUTE_X subq.l #cy_7e,CD RPW_ROR_C opcode_81: ;/* STA (ab,x) */ INDIRECT_X STOREANYBYTE cy_81,A opcode_84: ;/* STY ab */ ZPAGE PUTZPBYTE cy_84,Y opcode_85: ;/* STA ab */ ZPAGE PUTZPBYTE cy_85,A opcode_86: ;/* STX ab */ ZPAGE PUTZPBYTE cy_86,X opcode_88: ;/* DEY */ subq.l #cy_88,CD subq.b #1,Y NEXTCHANGE_REG Y opcode_8a: ;/* TXA */ subq.l #cy_8a,CD move.b X,A NEXTCHANGE_REG A opcode_8c: ;/* STY abcd */ ABSOLUTE STOREANYBYTE cy_8c,Y opcode_8d: ;/* STA abcd */ ABSOLUTE STOREANYBYTE cy_8d,A opcode_8e: ;/* STX abcd */ ABSOLUTE STOREANYBYTE cy_8e,X opcode_90: ;/* BCC */ btst #EB68,CCR6502 beq SOLVE DONT_BRA opcode_91: ;/* STA (ab),y */ INDIRECT_Y STOREANYBYTE cy_91,A opcode_94: ;/* STY ab,x */ ZPAGE_X PUTZPBYTE cy_94,Y opcode_95: ;/* STA ab,x */ ZPAGE_X PUTZPBYTE cy_95,A opcode_96: ;/* STX ab,y */ ZPAGE_Y PUTZPBYTE cy_96,X opcode_98: ;/* TYA */ subq.l #cy_98,CD move.b Y,A NEXTCHANGE_REG A opcode_99: ;/* STA abcd,y */ ABSOLUTE_Y STOREANYBYTE cy_99,A opcode_9a: ;/* TXS */ move.b X,_regS subq.l #cy_9a,CD bgt.w NEXTCHANGE_WSYNC bra.w END_OF_CYCLE opcode_9d: ;/* STA abcd,x */ ABSOLUTE_X STOREANYBYTE cy_9d,A opcode_a0: ;/* LDY #ab */ LOAD_IMMEDIATE cy_a0,Y opcode_a1: ;/* LDA (ab,x) */ INDIRECT_X subq.l #cy_a1,CD LOADANYBYTE A opcode_a2: ;/* LDX #ab */ LOAD_IMMEDIATE cy_a2,X opcode_a4: ;/* LDY ab */ LOAD_ZPAGE cy_a4,Y opcode_a5: ;/* LDA ab */ LOAD_ZPAGE cy_a5,A opcode_a6: ;/* LDX ab */ LOAD_ZPAGE cy_a6,X opcode_a8: ;/* TAY */ subq.l #cy_a8,CD move.b A,Y NEXTCHANGE_REG A opcode_a9: ;/* LDA #ab */ LOAD_IMMEDIATE cy_a9,A opcode_aa: ;/* TAX */ subq.l #cy_aa,CD move.b A,X NEXTCHANGE_REG A opcode_ac: ;/* LDY abcd */ ABSOLUTE subq.l #cy_ac,CD LOADANYBYTE Y opcode_ad: ;/* LDA abcd */ ABSOLUTE subq.l #cy_ad,CD LOADANYBYTE A opcode_ae: ;/* LDX abcd */ ABSOLUTE subq.l #cy_ae,CD LOADANYBYTE X opcode_b0: ;/* BCS */ btst #EB68,CCR6502 bne SOLVE DONT_BRA opcode_b1: ;/* LDA (ab),y */ INDIRECT_Y_NCY cy_b1 LOADANYBYTE A opcode_b4: ;/* LDY ab,x */ subq.l #cy_b4,CD ZPAGE_X GETZPBYTE Y NEXTCHANGE_REG Y opcode_b5: ;/* LDA ab,x */ subq.l #cy_b5,CD ZPAGE_X GETZPBYTE A NEXTCHANGE_REG A opcode_b6: ;/* LDX ab,y */ subq.l #cy_b6,CD ZPAGE_Y GETZPBYTE X NEXTCHANGE_REG X opcode_b8: ;/* CLV */ bclr #16,VFLAG subq.l #cy_b8,CD bgt.w NEXTCHANGE_WSYNC bra.w END_OF_CYCLE opcode_b9: ;/* LDA abcd,y */ ABSOLUTE_Y_NCY cy_b9 LOADANYBYTE A opcode_ba: ;/* TSX */ subq.l #cy_ba,CD move.b _regS,X NEXTCHANGE_REG X opcode_bc: ;/* LDY abcd,x */ ABSOLUTE_X_NCY cy_bc LOADANYBYTE Y opcode_bd: ;/* LDA abcd,x */ ABSOLUTE_X_NCY cy_bd LOADANYBYTE A opcode_be: ;/* LDX abcd,y */ ABSOLUTE_Y_NCY cy_be LOADANYBYTE X opcode_c0: ;/* CPY #ab */ IMMEDIATE d0 subq.l #cy_c0,CD move.b Y,ZFLAG bra COMPARE opcode_c1: ;/* CMP (ab,x) */ INDIRECT_X subq.l #cy_c1,CD GETANYBYTE_d0 bra COMPARE_A opcode_c4: ;/* CPY ab */ subq.l #cy_c4,CD ZPAGE GETZPBYTE d0 move.b Y,ZFLAG bra COMPARE opcode_c5: ;/* CMP ab */ subq.l #cy_c5,CD ZPAGE GETZPBYTE d0 bra COMPARE_A opcode_c6: ;/* DEC ab */ ZPAGE GETZPBYTE ZFLAG subq.b #1,ZFLAG PUTZPBYTE_Z cy_c6 opcode_c8: ;/* INY */ subq.l #cy_c8,CD addq.b #1,Y NEXTCHANGE_REG Y opcode_c9: ;/* CMP #ab */ IMMEDIATE d0 subq.l #cy_c9,CD bra COMPARE_A opcode_ca: ;/* DEX */ subq.l #cy_ca,CD subq.b #1,X NEXTCHANGE_REG X opcode_cc: ;/* CPY abcd */ ABSOLUTE subq.l #cy_cc,CD GETANYBYTE_d0 move.b Y,ZFLAG bra COMPARE opcode_cd: ;/* CMP abcd */ ABSOLUTE subq.l #cy_cd,CD GETANYBYTE_d0 bra COMPARE_A opcode_ce: ;/* DEC abcd */ ABSOLUTE GETANYBYTE ZFLAG subq.b #1,ZFLAG PUTANYBYTE_N cy_ce opcode_d0: ;/* BNE */ tst.b ZFLAG bne SOLVE DONT_BRA opcode_d1: ;/* CMP (ab),y */ INDIRECT_Y_NCY cy_d1 GETANYBYTE_d0 bra COMPARE_A opcode_d2: ;/* ESCRTS #ab (JAM) - on Atari is here instruction CIM ;[unofficial] !RS! */ move.b (PC6502)+,d7 movem.l d1/a1,-(a7) move.l d7,-(a7) UPDATE_GLOBAL_REGS CPU_GetStatus d0 jsr _AtariEscape /*in atari c*/ addq.l #4,a7 CPU_PutStatus d0 movem.l (a7)+,d1/a1 UPDATE_LOCAL_REGS PLW d7,d0 lea (memory_pointer,d7.l),PC6502 addq.l #1,PC6502 subq.l #cy_d2,CD bgt.w NEXTCHANGE_WSYNC bra.w END_OF_CYCLE opcode_d5: ;/* CMP ab,x */ subq.l #cy_d5,CD ZPAGE_X GETZPBYTE d0 bra COMPARE_A opcode_d6: ;/* DEC ab,x */ ZPAGE_X GETZPBYTE ZFLAG subq.b #1,ZFLAG PUTZPBYTE_Z cy_d6 opcode_d8: ;/* CLD */ ClrD subq.l #cy_d8,CD bgt.w NEXTCHANGE_WSYNC bra.w END_OF_CYCLE opcode_d9: ;/* CMP abcd,y */ ABSOLUTE_Y_NCY cy_d9 GETANYBYTE_d0 bra COMPARE_A opcode_dd: ;/* CMP abcd,x */ ABSOLUTE_X_NCY cy_dd GETANYBYTE_d0 bra COMPARE_A opcode_de: ;/* DEC abcd,x */ ABSOLUTE_X GETANYBYTE ZFLAG subq.b #1,ZFLAG PUTANYBYTE_N cy_de opcode_e0: ;/* CPX #ab */ IMMEDIATE d0 subq.l #cy_e0,CD move.b X,ZFLAG bra COMPARE opcode_e1: ;/* SBC (ab,x) */ INDIRECT_X subq.l #cy_e1,CD GETANYBYTE_d0 bra sbc opcode_e4: ;/* CPX ab */ subq.l #cy_e4,CD ZPAGE GETZPBYTE d0 move.b X,ZFLAG bra COMPARE opcode_e5: ;/* SBC ab */ subq.l #cy_e5,CD ZPAGE GETZPBYTE d0 bra sbc opcode_e6: ;/* INC ab */ ZPAGE GETZPBYTE ZFLAG addq.b #1,ZFLAG PUTZPBYTE_Z cy_e6 opcode_e8: ;/* INX */ subq.l #cy_e8,CD addq.b #1,X NEXTCHANGE_REG X opcode_e9: ;/* SBC #ab */ IMMEDIATE d0 subq.l #cy_e9,CD bra sbc ;opcode_ea: ;/* NOP */ ;official instr_NOP: subq.l #cy_NOP,CD bgt.w NEXTCHANGE_WSYNC bra.w END_OF_CYCLE opcode_ec: ;/* CPX abcd */ ABSOLUTE subq.l #cy_ec,CD GETANYBYTE_d0 move.b X,ZFLAG bra COMPARE opcode_ed: ;/* SBC abcd */ ABSOLUTE subq.l #cy_ed,CD GETANYBYTE_d0 bra sbc opcode_ee: ;/* INC abcd */ ABSOLUTE GETANYBYTE ZFLAG addq.b #1,ZFLAG PUTANYBYTE_N cy_ee opcode_f0: ;/* BEQ */ tst.b ZFLAG beq SOLVE DONT_BRA opcode_f1: ;/* SBC (ab),y */ INDIRECT_Y_NCY cy_f1 GETANYBYTE_d0 bra sbc opcode_f2: ;/* ESC #ab (JAM) - on Atari is here instruction CIM ;[unofficial] !RS! */ move.b (PC6502)+,d7 movem.l d1/a1,-(a7) move.l d7,-(a7) UPDATE_GLOBAL_REGS CPU_GetStatus d0 jsr _AtariEscape addq.l #4,a7 CPU_PutStatus d0 movem.l (a7)+,d1/a1 UPDATE_LOCAL_REGS subq.l #cy_f2,CD bgt.w NEXTCHANGE_WSYNC bra.w END_OF_CYCLE opcode_f5: ;/* SBC ab,x */ subq.l #cy_f5,CD ZPAGE_X GETZPBYTE d0 bra sbc opcode_f6: ;/* INC ab,x */ ZPAGE_X GETZPBYTE ZFLAG addq.b #1,ZFLAG PUTZPBYTE_Z cy_f6 opcode_f8: ;/* SED */ SetD subq.l #cy_f8,CD bgt.w NEXTCHANGE_WSYNC bra.w END_OF_CYCLE opcode_f9: ;/* SBC abcd,y */ ABSOLUTE_Y_NCY cy_f9 GETANYBYTE_d0 bra sbc opcode_fd: ;/* SBC abcd,x */ ABSOLUTE_X_NCY cy_fd GETANYBYTE_d0 bra sbc opcode_fe: ;/* INC abcd,x */ ABSOLUTE_X GETANYBYTE ZFLAG addq.b #1,ZFLAG PUTANYBYTE_N cy_fe COMPARE_A: move.b A,ZFLAG COMPARE: sub.b d0,ZFLAG move.w CCR,CCR6502 not.w CCR6502 ; bra.w NEXTCHANGE_N ;MAIN LOOP , where we are counting cycles and working with other STUFF NEXTCHANGE_N: ext.w NFLAG NEXTCHANGE_WITHOUT: tst.l CD ble.s END_OF_CYCLE NEXTCHANGE_WSYNC: tst.l _wsync_halt ; or tst.w _wsync_halt+2 ? bne HELD_BY_WSYNC **************************************** ifd MONITOR_BREAK ;following block of code allows you to enter move ccr,-(sp) ;a break address in monitor move.l PC6502,d7 sub.l memory_pointer,d7 cmp.w _break_addr,d7 bne.s .get_first move.b #$ff,d7 move (sp)+,ccr bsr odskoc_si ;on break monitor is invoked move ccr,-(sp) .get_first move (sp)+,ccr endc **************************************** clr.l d7 move.b (PC6502)+,d7 ifd PROFILE lea _instruction_count,a0 addq.l #1,(a0,d7.l*4) endc jmp ([a1,d7.l*4]) HELD_BY_WSYNC: clr.l CD END_OF_CYCLE: CPU_GetStatus d0 UPDATE_GLOBAL_REGS move.l CD,d0 ;returned value movem.l (a7)+,d2-d7/a2-a5 rts SOLVE: move.b (PC6502)+,d7 extb.l d7 add.l d7,PC6502 move.w PC6502,d0 cmp.b d7,d0 bmi.s SOLVE_PB subq.l #cy_Bcc1,CD bgt.w NEXTCHANGE_WSYNC bra.w END_OF_CYCLE SOLVE_PB: subq.l #cy_Bcc2,CD bgt.w NEXTCHANGE_WSYNC bra.w END_OF_CYCLE adc: btst #D_FLAGB,_regP bne.s BCD_ADC move.w CCR6502,CCR addx.b d0,A ;data are added with carry (in 68000 Extended bit in this case) move.w CCR,CCR6502 bvs.s .SET_V bclr #16,VFLAG NEXTCHANGE_REG A .SET_V: bset #16,VFLAG NEXTCHANGE_REG A ; Version 1 : exact like Thor ; Z from binary calc. ; N + V after lower nibble decimal correction ; C from decimal calc. ; a lot of code necessary to replicate a 6502 bug BCD_ADC: move.w d6,-(a7) ; no movem because d0 is needed first move.w d7,-(a7) move.w d0,-(a7) move.b d0,d6 lsr.b #4,d6 andi.b #$0f,d0 ; low nibble Add move.b A,d7 andi.b #$0f,d7 ; low nibble A move.w CCR6502,CCR addx.b d0,d7 cmp.b #10,d7 bmi.s .lonib_e addq.b #6,d7 ; low nibble BCD fixup andi.b #15,d7 addq.b #1,d6 ; add to high nibble Add .lonib_e: move.b A,d0 lsr.b #4,d0 ; high nibble A add.b d0,d6 move.b d6,ZFLAG lsl.b #4,ZFLAG ext.w NFLAG ; NFLAG finished move.w (a7),d0 ; without + because we need it again eor.b A,d0 not.b d0 bpl.s .CLR_V eor.b A,ZFLAG bpl.s .CLR_V bset #16,VFLAG bra.s .V_DONE .CLR_V: bclr #16,VFLAG .V_DONE: ; VFLAG finished cmp.b #10,d6 bmi.s .hinib_e addq.b #6,d6 ; high nibble BCD fixup .hinib_e: move.w (a7)+,d0 ; second time restored move.w CCR6502,CCR addx.b d0,A move.b A,ZFLAG ; ZFLAG finished clr.w CCR6502 cmp.b #16,d6 bmi.s .C_DONE not.w CCR6502 .C_DONE ; CCR6502 finished lsl.b #4,d6 or.b d6,d7 ; compose result move.b d7,A move.w (a7)+,d7 move.w (a7)+,d6 bra.w NEXTCHANGE_WITHOUT sbc: btst #D_FLAGB,_regP bne.s BCD_SBC not.w CCR6502 move.w CCR6502,CCR subx.b d0,A move.w CCR,CCR6502 bvs.s .SET_V bclr #16,VFLAG not.w CCR6502 NEXTCHANGE_REG A .SET_V: bset #16,VFLAG not.w CCR6502 NEXTCHANGE_REG A BCD_SBC: move.b A,ZFLAG not.w CCR6502 move.w CCR6502,CCR subx.b d0,ZFLAG bvs.s .SET_VX bclr #16,VFLAG bra.s .END_VX .SET_VX: bset #16,VFLAG .END_VX: ext.w NFLAG move.w CCR6502,CCR sbcd d0,A move.w CCR,CCR6502 not.w CCR6502 bra.w NEXTCHANGE_WITHOUT Putbyte_SPCL macro move.l d1,-(a7) EXE_PUTBYTE_d0 move.l (a7)+,d1 lea OPMODE_TABLE,a1 endm Putbyte_ADC: Putbyte_SPCL bra.w adc Putbyte_CMP: Putbyte_SPCL bra.w COMPARE_A Putbyte_SBC: Putbyte_SPCL bra.w sbc odskoc_si: UPDATE_GLOBAL_REGS movem.l d1/a1,-(a7) CPU_GetStatus d0 move.l d7,-(a7) jsr _AtariEscape addq.l #4,a7 CPU_PutStatus d0 movem.l (a7)+,d1/a1 UPDATE_LOCAL_REGS rts