| Previous | 199869 Revisions | Next |
| r18875 Tuesday 6th November, 2012 at 16:27:39 UTC by O. Galibert |
|---|
| 6502: Rewrite modern, cycle-exact and interruptible [O. Galibert] |
| [docs] | m6502.txt |
| [src/emu/cpu] | cpu.mak |
| [src/emu/cpu/m6502] | |
| [src/emu/sound] | nes_apu.c |
| [src/mame/audio] | dkong.c |
| [src/mame/drivers] | 4roses.c allied.c alvg.c bwing.c calomega.c cham24.c cmmb.c exprraid.c famibox.c funworld.c gts3.c liberate.c multigam.c playch10.c punchout.c rgum.c seta.c snookr10.c tceptor.c thedeep.c vsnes.c |
| [src/mame/video] | liberate.c |
| [src/mess/drivers] | apple2.c apple3.c bbc.c c128.c c64.c clcd.c lisa.c lynx.c mephisto.c mmodular.c nes.c plus4.c sbc6510.c svision.c vic10.c |
| [src/mess/includes] | c128.h c64.h plus4.h vic10.h vic20.h |
| [src/mess/machine] | c1541.h c1551.c c1551.h c2040.h c64.c c65.c e01.h fd2000.h isa_finalchs.c lynx.c serialbox.h |
| [src/tools] | unidasm.c |
| r18874 | r18875 | |
|---|---|---|
| 9 | 9 | |
| 10 | 10 | #include "emu.h" |
| 11 | 11 | #include "isa_finalchs.h" |
| 12 | #include "cpu/m6502/m6502.h" | |
| 12 | #include "cpu/m6502/m65c02.h" | |
| 13 | 13 | |
| 14 | 14 | static UINT8 FCH_latch_data = 0; |
| 15 | 15 |
| r18874 | r18875 | |
|---|---|---|
| 4 | 4 | |
| 5 | 5 | #include "emu.h" |
| 6 | 6 | #include "includes/lynx.h" |
| 7 | #include "cpu/m6502/m6502.h" | |
| 7 | #include "cpu/m6502/m65sc02.h" | |
| 8 | 8 | #include "imagedev/cartslot.h" |
| 9 | 9 | |
| 10 | 10 |
| r18874 | r18875 | |
|---|---|---|
| 100 | 100 | |
| 101 | 101 | inline void set_iec_data(); |
| 102 | 102 | |
| 103 | required_device< | |
| 103 | required_device<m6502_device> m_maincpu; | |
| 104 | 104 | required_device<via6522_device> m_via0; |
| 105 | 105 | required_device<via6522_device> m_via1; |
| 106 | 106 | required_device<c64h156_device> m_ga; |
| r18874 | r18875 | |
|---|---|---|
| 15 | 15 | #define ADDRESS_MAP_MODERN |
| 16 | 16 | |
| 17 | 17 | #include "emu.h" |
| 18 | #include "cpu/m6502/m6502.h" | |
| 18 | #include "cpu/m6502/m65c02.h" | |
| 19 | 19 | #include "imagedev/flopdrv.h" |
| 20 | 20 | #include "formats/mfi_dsk.h" |
| 21 | 21 | #include "machine/6522via.h" |
| r18874 | r18875 | |
| 62 | 62 | void cbm_iec_data(int state); |
| 63 | 63 | void cbm_iec_reset(int state); |
| 64 | 64 | |
| 65 | required_device<c | |
| 65 | required_device<m65c02_device> m_maincpu; | |
| 66 | 66 | }; |
| 67 | 67 | |
| 68 | 68 |
| r18874 | r18875 | |
|---|---|---|
| 131 | 131 | m_ga->ds_w((data >> 5) & 0x03); |
| 132 | 132 | } |
| 133 | 133 | |
| 134 | static M6510_INTERFACE( cpu_intf ) | |
| 135 | { | |
| 136 | DEVCB_NULL, // read_indexed_func | |
| 137 | DEVCB_NULL, // write_indexed_func | |
| 138 | DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, c1551_device, port_r), | |
| 139 | DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, c1551_device, port_w), | |
| 140 | 0x00, | |
| 141 | 0x00 | |
| 142 | }; | |
| 143 | ||
| 144 | ||
| 145 | 134 | //------------------------------------------------- |
| 146 | 135 | // tpi6525_interface tpi0_intf |
| 147 | 136 | //------------------------------------------------- |
| r18874 | r18875 | |
| 408 | 397 | static MACHINE_CONFIG_FRAGMENT( c1551 ) |
| 409 | 398 | MCFG_CPU_ADD(M6510T_TAG, M6510T, XTAL_16MHz/8) |
| 410 | 399 | MCFG_CPU_PROGRAM_MAP(c1551_mem) |
| 411 | MCFG_ | |
| 400 | MCFG_M6510T_PORT_CALLBACKS(READ8(c1551_device, port_r), WRITE8(c1551_device, port_w)) | |
| 412 | 401 | MCFG_QUANTUM_PERFECT_CPU(M6510T_TAG) |
| 413 | 402 | |
| 414 | 403 | MCFG_PLS100_ADD(PLA_TAG) |
| r18874 | r18875 | |
|---|---|---|
| 14 | 14 | |
| 15 | 15 | |
| 16 | 16 | #include "emu.h" |
| 17 | #include "cpu/m6502/m650 | |
| 17 | #include "cpu/m6502/m6510t.h" | |
| 18 | 18 | #include "imagedev/flopdrv.h" |
| 19 | 19 | #include "formats/d64_dsk.h" |
| 20 | 20 | #include "formats/g64_dsk.h" |
| r18874 | r18875 | |
| 84 | 84 | private: |
| 85 | 85 | bool tpi1_selected(offs_t offset); |
| 86 | 86 | |
| 87 | required_device< | |
| 87 | required_device<m6510t_device> m_maincpu; | |
| 88 | 88 | required_device<device_t> m_tpi0; |
| 89 | 89 | required_device<device_t> m_tpi1; |
| 90 | 90 | required_device<c64h156_device> m_ga; |
| r18874 | r18875 | |
|---|---|---|
| 15 | 15 | |
| 16 | 16 | #include "emu.h" |
| 17 | 17 | |
| 18 | #include "cpu/m6502/m650 | |
| 18 | #include "cpu/m6502/m6510.h" | |
| 19 | 19 | #include "cpu/z80/z80.h" |
| 20 | 20 | #include "sound/sid6581.h" |
| 21 | 21 | #include "machine/6526cia.h" |
| r18874 | r18875 | |
| 159 | 159 | legacy_c64_state *state = machine.driver_data<legacy_c64_state>(); |
| 160 | 160 | int loram, hiram, charen; |
| 161 | 161 | int ultimax_mode = 0; |
| 162 | int data = m | |
| 162 | int data = machine.device<m6510_device>("maincpu")->get_port() & 0x07; | |
| 163 | 163 | |
| 164 | 164 | /* Are we in Ultimax mode? */ |
| 165 | 165 | if (!state->m_game && state->m_exrom) |
| r18874 | r18875 | |
|---|---|---|
| 102 | 102 | c65_state *state = machine.driver_data<c65_state>(); |
| 103 | 103 | if (level != state->m_old_level) |
| 104 | 104 | { |
| 105 | DBG_LOG(machine, 3, "mos6510", ("irq %s\n", level ? "start" : "end")); | |
| 106 | machine.device("maincpu")->execute().set_input_line(M6510_IRQ_LINE, level); | |
| 105 | DBG_LOG(machine, 3, "mos4510", ("irq %s\n", level ? "start" : "end")); | |
| 106 | machine.device("maincpu")->execute().set_input_line(M4510_IRQ_LINE, level); | |
| 107 | 107 | state->m_old_level = level; |
| 108 | 108 | } |
| 109 | 109 | } |
| r18874 | r18875 | |
| 837 | 837 | c65_state *state = machine.driver_data<c65_state>(); |
| 838 | 838 | int data, loram, hiram, charen; |
| 839 | 839 | |
| 840 | data = | |
| 840 | data = 0x00; // machine.device<m4510_device>("maincpu")->get_port(); | |
| 841 | 841 | if (data == state->m_old_data) |
| 842 | 842 | return; |
| 843 | 843 |
| r18874 | r18875 | |
|---|---|---|
| 14 | 14 | |
| 15 | 15 | |
| 16 | 16 | #include "emu.h" |
| 17 | #include "cpu/m6502/m6502.h" | |
| 17 | #include "cpu/m6502/m65c02.h" | |
| 18 | 18 | #include "machine/cbmiec.h" |
| 19 | 19 | |
| 20 | 20 | |
| r18874 | r18875 | |
| 57 | 57 | void cbm_iec_reset(int state); |
| 58 | 58 | |
| 59 | 59 | private: |
| 60 | required_device<c | |
| 60 | required_device<m65c02_device> m_maincpu; | |
| 61 | 61 | }; |
| 62 | 62 | |
| 63 | 63 |
| r18874 | r18875 | |
|---|---|---|
| 15 | 15 | |
| 16 | 16 | #include "emu.h" |
| 17 | 17 | #include "cpu/m6502/m6502.h" |
| 18 | #include "cpu/m6502/m6504.h" | |
| 18 | 19 | #include "imagedev/flopdrv.h" |
| 19 | 20 | #include "formats/d64_dsk.h" |
| 20 | 21 | #include "formats/g64_dsk.h" |
| r18874 | r18875 | |
| 97 | 98 | inline void mpi_step_motor(int unit, int stp); |
| 98 | 99 | inline void initialize(int drives); |
| 99 | 100 | |
| 100 | required_device<cpu_device> m_maincpu; | |
| 101 | required_device<cpu_device> m_fdccpu; | |
| 101 | required_device<m6502_device> m_maincpu; | |
| 102 | required_device<m6504_device> m_fdccpu; | |
| 102 | 103 | required_device<riot6532_device> m_riot0; |
| 103 | 104 | required_device<riot6532_device> m_riot1; |
| 104 | 105 | required_device<device_t> m_miot; |
| r18874 | r18875 | |
|---|---|---|
| 13 | 13 | #define __E01__ |
| 14 | 14 | |
| 15 | 15 | #include "emu.h" |
| 16 | #include "cpu/m6502/m6502.h" | |
| 16 | #include "cpu/m6502/m65c02.h" | |
| 17 | 17 | #include "imagedev/flopdrv.h" |
| 18 | 18 | #include "machine/6522via.h" |
| 19 | 19 | #include "machine/ctronics.h" |
| r18874 | r18875 | |
| 79 | 79 | // device_econet_interface overrides |
| 80 | 80 | virtual void econet_clk(int state); |
| 81 | 81 | |
| 82 | required_device<c | |
| 82 | required_device<m65c02_device> m_maincpu; | |
| 83 | 83 | required_device<device_t> m_fdc; |
| 84 | 84 | required_device<device_t> m_adlc; |
| 85 | 85 | required_device<mc146818_device> m_rtc; |
| r18874 | r18875 | |
|---|---|---|
| 4 | 4 | #define __C64__ |
| 5 | 5 | |
| 6 | 6 | #include "emu.h" |
| 7 | #include "cpu/m6502/m6510.h" | |
| 7 | 8 | #include "formats/cbm_snqk.h" |
| 8 | 9 | #include "includes/cbm.h" |
| 9 | 10 | #include "machine/c64exp.h" |
| r18874 | r18875 | |
| 63 | 64 | m_iec_srq(1) |
| 64 | 65 | { } |
| 65 | 66 | |
| 66 | required_device< | |
| 67 | required_device<m6510_device> m_maincpu; | |
| 67 | 68 | required_device<pls100_device> m_pla; |
| 68 | 69 | required_device<mos6566_device> m_vic; |
| 69 | 70 | required_device<sid6581_device> m_sid; |
| r18874 | r18875 | |
|---|---|---|
| 5 | 5 | |
| 6 | 6 | |
| 7 | 7 | #include "emu.h" |
| 8 | #include "cpu/m6502/m6510.h" | |
| 8 | 9 | #include "includes/cbm.h" |
| 9 | 10 | #include "machine/cbmipt.h" |
| 10 | 11 | #include "machine/mos6526.h" |
| r18874 | r18875 | |
| 44 | 45 | m_exp_irq(CLEAR_LINE) |
| 45 | 46 | { } |
| 46 | 47 | |
| 47 | required_device< | |
| 48 | required_device<m6510_device> m_maincpu; | |
| 48 | 49 | required_device<mos6566_device> m_vic; |
| 49 | 50 | required_device<sid6581_device> m_sid; |
| 50 | 51 | required_device<mos6526_device> m_cia; |
| r18874 | r18875 | |
|---|---|---|
| 7 | 7 | #include "emu.h" |
| 8 | 8 | #include "includes/cbm.h" |
| 9 | 9 | #include "formats/cbm_snqk.h" |
| 10 | #include "cpu/m6502/m650 | |
| 10 | #include "cpu/m6502/m6510.h" | |
| 11 | 11 | #include "imagedev/cartslot.h" |
| 12 | 12 | #include "machine/6522via.h" |
| 13 | 13 | #include "machine/cbmiec.h" |
| r18874 | r18875 | |
| 48 | 48 | m_color_ram(*this, "color_ram") |
| 49 | 49 | { } |
| 50 | 50 | |
| 51 | required_device< | |
| 51 | required_device<m6510_device> m_maincpu; | |
| 52 | 52 | required_device<via6522_device> m_via0; |
| 53 | 53 | required_device<via6522_device> m_via1; |
| 54 | 54 | required_device<mos6560_device> m_vic; |
| r18874 | r18875 | |
|---|---|---|
| 4 | 4 | #define __PLUS4__ |
| 5 | 5 | |
| 6 | 6 | #include "emu.h" |
| 7 | #include "cpu/m6502/m7501.h" | |
| 7 | 8 | #include "formats/cbm_snqk.h" |
| 8 | 9 | #include "includes/cbm.h" |
| 9 | 10 | #include "audio/t6721.h" |
| r18874 | r18875 | |
| 52 | 53 | m_exp_irq(CLEAR_LINE) |
| 53 | 54 | { } |
| 54 | 55 | |
| 55 | required_device< | |
| 56 | required_device<m7501_device> m_maincpu; | |
| 56 | 57 | required_device<pls100_device> m_pla; |
| 57 | 58 | required_device<mos7360_device> m_ted; |
| 58 | 59 | optional_device<acia6551_device> m_acia; |
| r18874 | r18875 | |
|---|---|---|
| 6 | 6 | #include "emu.h" |
| 7 | 7 | #include "formats/cbm_snqk.h" |
| 8 | 8 | #include "includes/cbm.h" |
| 9 | #include "cpu/m6502/m8502.h" | |
| 10 | #include "machine/6526cia.h" | |
| 9 | 11 | #include "machine/c64exp.h" |
| 10 | 12 | #include "machine/c64user.h" |
| 11 | 13 | #include "machine/cbmiec.h" |
| r18874 | r18875 | |
| 88 | 90 | { } |
| 89 | 91 | |
| 90 | 92 | required_device<legacy_cpu_device> m_maincpu; |
| 91 | required_device< | |
| 93 | required_device<m8502_device> m_subcpu; | |
| 92 | 94 | required_device<mos8722_device> m_mmu; |
| 93 | 95 | required_device<mos8721_device> m_pla; |
| 94 | 96 | required_device<mos8563_device> m_vdc; |
| r18874 | r18875 | |
|---|---|---|
| 1131 | 1131 | m_cassette->motor_w(BIT(data, 5)); |
| 1132 | 1132 | } |
| 1133 | 1133 | |
| 1134 | static M6510_INTERFACE( cpu_intf ) | |
| 1135 | { | |
| 1136 | DEVCB_NULL, | |
| 1137 | DEVCB_NULL, | |
| 1138 | DEVCB_DRIVER_MEMBER(c128_state, cpu_r), | |
| 1139 | DEVCB_DRIVER_MEMBER(c128_state, cpu_w), | |
| 1140 | 0x07, | |
| 1141 | 0x20 | |
| 1142 | }; | |
| 1143 | 1134 | |
| 1144 | ||
| 1145 | 1135 | //------------------------------------------------- |
| 1146 | 1136 | // CBM_IEC_INTERFACE( cbm_iec_intf ) |
| 1147 | 1137 | //------------------------------------------------- |
| r18874 | r18875 | |
| 1386 | 1376 | MCFG_QUANTUM_PERFECT_CPU(Z80A_TAG) |
| 1387 | 1377 | |
| 1388 | 1378 | MCFG_CPU_ADD(M8502_TAG, M8502, VIC6567_CLOCK) |
| 1379 | MCFG_M8502_PORT_CALLBACKS(READ8(c128_state, cpu_r), WRITE8(c128_state, cpu_w)) | |
| 1380 | MCFG_M8502_PORT_PULLS(0x07, 0x20) | |
| 1389 | 1381 | MCFG_CPU_PROGRAM_MAP(m8502_mem) |
| 1390 | MCFG_CPU_CONFIG(cpu_intf) | |
| 1391 | 1382 | MCFG_CPU_VBLANK_INT_DRIVER(SCREEN_VIC_TAG, c128_state, frame_interrupt) |
| 1392 | 1383 | MCFG_QUANTUM_PERFECT_CPU(M8502_TAG) |
| 1393 | 1384 | |
| r18874 | r18875 | |
| 1491 | 1482 | MCFG_QUANTUM_PERFECT_CPU(Z80A_TAG) |
| 1492 | 1483 | |
| 1493 | 1484 | MCFG_CPU_ADD(M8502_TAG, M8502, VIC6569_CLOCK) |
| 1485 | MCFG_M8502_PORT_CALLBACKS(READ8(c128_state, cpu_r), WRITE8(c128_state, cpu_w)) | |
| 1486 | MCFG_M8502_PORT_PULLS(0x07, 0x20) | |
| 1494 | 1487 | MCFG_CPU_PROGRAM_MAP(m8502_mem) |
| 1495 | MCFG_CPU_CONFIG(cpu_intf) | |
| 1496 | 1488 | MCFG_CPU_VBLANK_INT_DRIVER(SCREEN_VIC_TAG, c128_state, frame_interrupt) |
| 1497 | 1489 | MCFG_QUANTUM_PERFECT_CPU(M8502_TAG) |
| 1498 | 1490 |
| r18874 | r18875 | |
|---|---|---|
| 713 | 713 | m_cassette->motor_w(BIT(data, 5)); |
| 714 | 714 | } |
| 715 | 715 | |
| 716 | static M6510_INTERFACE( cpu_intf ) | |
| 717 | { | |
| 718 | DEVCB_NULL, | |
| 719 | DEVCB_NULL, | |
| 720 | DEVCB_DRIVER_MEMBER(c64_state, cpu_r), | |
| 721 | DEVCB_DRIVER_MEMBER(c64_state, cpu_w), | |
| 722 | 0x17, | |
| 723 | 0x20 | |
| 724 | }; | |
| 725 | ||
| 726 | ||
| 727 | 716 | //------------------------------------------------- |
| 728 | 717 | // M6510_INTERFACE( sx64_cpu_intf ) |
| 729 | 718 | //------------------------------------------------- |
| r18874 | r18875 | |
| 767 | 756 | m_charen = BIT(data, 2); |
| 768 | 757 | } |
| 769 | 758 | |
| 770 | static M6510_INTERFACE( sx64_cpu_intf ) | |
| 771 | { | |
| 772 | DEVCB_NULL, | |
| 773 | DEVCB_NULL, | |
| 774 | DEVCB_DRIVER_MEMBER(sx64_state, cpu_r), | |
| 775 | DEVCB_DRIVER_MEMBER(sx64_state, cpu_w), | |
| 776 | 0x07, | |
| 777 | 0x00 | |
| 778 | }; | |
| 779 | ||
| 780 | ||
| 781 | 759 | //------------------------------------------------- |
| 782 | 760 | // M6510_INTERFACE( c64gs_cpu_intf ) |
| 783 | 761 | //------------------------------------------------- |
| r18874 | r18875 | |
| 821 | 799 | m_charen = BIT(data, 2); |
| 822 | 800 | } |
| 823 | 801 | |
| 824 | static M6510_INTERFACE( c64gs_cpu_intf ) | |
| 825 | { | |
| 826 | DEVCB_NULL, | |
| 827 | DEVCB_NULL, | |
| 828 | DEVCB_DRIVER_MEMBER(c64gs_state, cpu_r), | |
| 829 | DEVCB_DRIVER_MEMBER(c64gs_state, cpu_w), | |
| 830 | 0x07, | |
| 831 | 0x00 | |
| 832 | }; | |
| 833 | ||
| 834 | ||
| 835 | 802 | //------------------------------------------------- |
| 836 | 803 | // PET_DATASSETTE_PORT_INTERFACE( datassette_intf ) |
| 837 | 804 | //------------------------------------------------- |
| r18874 | r18875 | |
| 1042 | 1009 | // basic hardware |
| 1043 | 1010 | MCFG_CPU_ADD(M6510_TAG, M6510, VIC6567_CLOCK) |
| 1044 | 1011 | MCFG_CPU_PROGRAM_MAP(c64_mem) |
| 1045 | MCFG_CPU_CONFIG(cpu_intf) | |
| 1012 | MCFG_M6510_PORT_CALLBACKS(READ8(c64_state, cpu_r), WRITE8(c64_state, cpu_w)) | |
| 1013 | MCFG_M6510_PORT_PULLS(0x17, 0xc8) | |
| 1046 | 1014 | MCFG_CPU_VBLANK_INT_DRIVER(SCREEN_TAG, c64_state, frame_interrupt) |
| 1047 | 1015 | MCFG_QUANTUM_PERFECT_CPU(M6510_TAG) |
| 1048 | 1016 | |
| r18874 | r18875 | |
| 1101 | 1069 | |
| 1102 | 1070 | // basic hardware |
| 1103 | 1071 | MCFG_CPU_MODIFY(M6510_TAG) |
| 1104 | MCFG_CPU_CONFIG(sx64_cpu_intf) | |
| 1072 | MCFG_M6510_PORT_CALLBACKS(READ8(sx64_state, cpu_r), WRITE8(sx64_state, cpu_w)) | |
| 1073 | MCFG_M6510_PORT_PULLS(0x07, 0xc0) | |
| 1105 | 1074 | |
| 1106 | 1075 | // devices |
| 1107 | 1076 | MCFG_DEVICE_REMOVE("iec8") |
| r18874 | r18875 | |
| 1141 | 1110 | // basic hardware |
| 1142 | 1111 | MCFG_CPU_ADD(M6510_TAG, M6510, VIC6569_CLOCK) |
| 1143 | 1112 | MCFG_CPU_PROGRAM_MAP(c64_mem) |
| 1144 | MCFG_CPU_CONFIG(cpu_intf) | |
| 1113 | MCFG_M6510_PORT_CALLBACKS(READ8(c64_state, cpu_r), WRITE8(c64_state, cpu_w)) | |
| 1114 | MCFG_M6510_PORT_PULLS(0x17, 0xc8) | |
| 1145 | 1115 | MCFG_CPU_VBLANK_INT_DRIVER(SCREEN_TAG, c64_state, frame_interrupt) |
| 1146 | 1116 | MCFG_QUANTUM_PERFECT_CPU(M6510_TAG) |
| 1147 | 1117 | |
| r18874 | r18875 | |
| 1191 | 1161 | |
| 1192 | 1162 | // basic hardware |
| 1193 | 1163 | MCFG_CPU_MODIFY(M6510_TAG) |
| 1194 | MCFG_CPU_CONFIG(sx64_cpu_intf) | |
| 1164 | MCFG_M6510_PORT_CALLBACKS(READ8(sx64_state, cpu_r), WRITE8(sx64_state, cpu_w)) | |
| 1165 | MCFG_M6510_PORT_PULLS(0x07, 0xc0) | |
| 1195 | 1166 | |
| 1196 | 1167 | // devices |
| 1197 | 1168 | MCFG_DEVICE_REMOVE("iec8") |
| r18874 | r18875 | |
| 1218 | 1189 | // basic hardware |
| 1219 | 1190 | MCFG_CPU_ADD(M6510_TAG, M6510, VIC6569_CLOCK) |
| 1220 | 1191 | MCFG_CPU_PROGRAM_MAP(c64_mem) |
| 1221 | MCFG_CPU_CONFIG(c64gs_cpu_intf) | |
| 1192 | MCFG_M6510_PORT_CALLBACKS(READ8(c64gs_state, cpu_r), WRITE8(c64gs_state, cpu_w)) | |
| 1193 | MCFG_M6510_PORT_PULLS(0x07, 0xc0) | |
| 1194 | ||
| 1222 | 1195 | MCFG_CPU_VBLANK_INT_DRIVER(SCREEN_TAG, c64_state, frame_interrupt) |
| 1223 | 1196 | MCFG_QUANTUM_PERFECT_CPU(M6510_TAG) |
| 1224 | 1197 |
| r18874 | r18875 | |
|---|---|---|
| 183 | 183 | |
| 184 | 184 | #include "emu.h" |
| 185 | 185 | #include "cpu/m6502/m6502.h" |
| 186 | #include "cpu/m6502/m65c02.h" | |
| 186 | 187 | #include "cpu/z80/z80.h" |
| 187 | 188 | #include "imagedev/flopdrv.h" |
| 188 | 189 | #include "imagedev/cassette.h" |
| r18874 | r18875 | |
|---|---|---|
| 12 | 12 | |
| 13 | 13 | #include "emu.h" |
| 14 | 14 | #include "cpu/m6502/m6502.h" |
| 15 | #include "cpu/m6502/m65sc02.h" | |
| 15 | 16 | #include "machine/6522via.h" |
| 16 | 17 | #include "machine/econet.h" |
| 17 | 18 | #include "machine/e01.h" |
| r18874 | r18875 | |
|---|---|---|
| 34 | 34 | /* the Apple /// does some weird tricks whereby it monitors the SYNC pin |
| 35 | 35 | * on the CPU to check for indexed instructions and directs them to |
| 36 | 36 | * different memory locations */ |
| 37 | #if 0 | |
| 37 | 38 | static const m6502_interface apple3_m6502_interface = |
| 38 | 39 | { |
| 39 | 40 | DEVCB_DRIVER_MEMBER(apple3_state, apple3_indexed_read), /* read_indexed_func */ |
| r18874 | r18875 | |
| 43 | 44 | 0x00, |
| 44 | 45 | 0x00 |
| 45 | 46 | }; |
| 47 | #endif | |
| 46 | 48 | |
| 47 | 49 | static const floppy_interface apple3_floppy_interface = |
| 48 | 50 | { |
| r18874 | r18875 | |
| 70 | 72 | /* basic machine hardware */ |
| 71 | 73 | MCFG_CPU_ADD("maincpu", M6502, 2000000) /* 2 MHz */ |
| 72 | 74 | MCFG_CPU_PROGRAM_MAP(apple3_map) |
| 73 | MCFG_CPU_CONFIG( apple3_m6502_interface ) | |
| 75 | // MCFG_CPU_CONFIG( apple3_m6502_interface ) | |
| 74 | 76 | MCFG_CPU_PERIODIC_INT_DRIVER(apple3_state, apple3_interrupt, 192) |
| 75 | 77 | MCFG_QUANTUM_TIME(attotime::from_hz(60)) |
| 76 | 78 |
| r18874 | r18875 | |
|---|---|---|
| 87 | 87 | |
| 88 | 88 | #include "emu.h" |
| 89 | 89 | #include "cpu/m68000/m68000.h" |
| 90 | #include "cpu/m6502/m6502.h" | |
| 90 | #include "cpu/m6502/m65c02.h" | |
| 91 | 91 | #include "cpu/arm/arm.h" |
| 92 | 92 | #include "sound/beep.h" |
| 93 | 93 | //#include "machine/6551acia.h" |
| r18874 | r18875 | |
| 813 | 813 | |
| 814 | 814 | TIMER_DEVICE_CALLBACK_MEMBER(polgar_state::cause_M6502_irq) |
| 815 | 815 | { |
| 816 | machine().device("maincpu")->execute().set_input_line(M6502_IRQ_LINE, ASSERT_LINE); | |
| 817 | machine().device("maincpu")->execute().set_input_line(M6502_IRQ_LINE, CLEAR_LINE); | |
| 818 | ||
| 816 | // That will not work | |
| 817 | machine().device("maincpu")->execute().set_input_line(M65C02_IRQ_LINE, ASSERT_LINE); | |
| 818 | machine().device("maincpu")->execute().set_input_line(M65C02_IRQ_LINE, CLEAR_LINE); | |
| 819 | 819 | } |
| 820 | 820 | |
| 821 | 821 |
| r18874 | r18875 | |
|---|---|---|
| 61 | 61 | |
| 62 | 62 | |
| 63 | 63 | #include "emu.h" |
| 64 | #include "cpu/m6502/m6502.h" | |
| 64 | #include "cpu/m6502/m65c02.h" | |
| 65 | 65 | #include "sound/beep.h" |
| 66 | 66 | //#include "mephisto.lh" |
| 67 | 67 | |
| r18874 | r18875 | |
| 77 | 77 | m_beep(*this, BEEPER_TAG) |
| 78 | 78 | { } |
| 79 | 79 | |
| 80 | required_device<c | |
| 80 | required_device<m65c02_device> m_maincpu; | |
| 81 | 81 | required_device<device_t> m_beep; |
| 82 | 82 | DECLARE_WRITE8_MEMBER(write_lcd); |
| 83 | 83 | DECLARE_WRITE8_MEMBER(mephisto_NMI); |
| r18874 | r18875 | |
| 351 | 351 | |
| 352 | 352 | TIMER_DEVICE_CALLBACK_MEMBER(mephisto_state::update_irq)//only mm2 |
| 353 | 353 | { |
| 354 | machine().device("maincpu")->execute().set_input_line(M6502_IRQ_LINE, ASSERT_LINE); | |
| 355 | machine().device("maincpu")->execute().set_input_line(M6502_IRQ_LINE, CLEAR_LINE); | |
| 354 | // That will not work | |
| 355 | machine().device("maincpu")->execute().set_input_line(M65C02_IRQ_LINE, ASSERT_LINE); | |
| 356 | machine().device("maincpu")->execute().set_input_line(M65C02_IRQ_LINE, CLEAR_LINE); | |
| 356 | 357 | |
| 357 | 358 | beep_set_state(m_beep, m_led_status&64?1:0); |
| 358 | 359 | } |
| r18874 | r18875 | |
|---|---|---|
| 409 | 409 | m_cassette->motor_w(BIT(data, 5)); |
| 410 | 410 | } |
| 411 | 411 | |
| 412 | static M6510_INTERFACE( cpu_intf ) | |
| 413 | { | |
| 414 | DEVCB_NULL, | |
| 415 | DEVCB_NULL, | |
| 416 | DEVCB_DRIVER_MEMBER(vic10_state, cpu_r), | |
| 417 | DEVCB_DRIVER_MEMBER(vic10_state, cpu_w), | |
| 418 | 0x10, | |
| 419 | 0x20 | |
| 420 | }; | |
| 421 | ||
| 422 | ||
| 423 | 412 | //------------------------------------------------- |
| 424 | 413 | // PET_DATASSETTE_PORT_INTERFACE( datassette_intf ) |
| 425 | 414 | //------------------------------------------------- |
| r18874 | r18875 | |
| 505 | 494 | // basic hardware |
| 506 | 495 | MCFG_CPU_ADD(M6510_TAG, M6510, VIC6566_CLOCK) |
| 507 | 496 | MCFG_CPU_PROGRAM_MAP(vic10_mem) |
| 508 | MCFG_CPU_CONFIG(cpu_intf) | |
| 497 | MCFG_M6510_PORT_CALLBACKS(READ8(vic10_state, cpu_r), WRITE8(vic10_state, cpu_w)) | |
| 498 | MCFG_M6510_PORT_PULLS(0x10, 0x20) | |
| 509 | 499 | MCFG_CPU_VBLANK_INT_DRIVER(SCREEN_TAG, vic10_state, vic10_frame_interrupt) |
| 510 | 500 | MCFG_QUANTUM_PERFECT_CPU(M6510_TAG) |
| 511 | 501 |
| r18874 | r18875 | |
|---|---|---|
| 10 | 10 | |
| 11 | 11 | #include "emu.h" |
| 12 | 12 | #include "cpu/m68000/m68000.h" |
| 13 | #include "cpu/m6502/m650 | |
| 13 | #include "cpu/m6502/m6504.h" | |
| 14 | 14 | #include "cpu/cop400/cop400.h" |
| 15 | 15 | #include "includes/lisa.h" |
| 16 | 16 | #include "devices/sonydriv.h" |
| r18874 | r18875 | |
|---|---|---|
| 7 | 7 | ******************************************************************************/ |
| 8 | 8 | |
| 9 | 9 | #include "emu.h" |
| 10 | #include "cpu/m6502/m6502.h" | |
| 10 | #include "cpu/m6502/m65sc02.h" | |
| 11 | 11 | #include "includes/lynx.h" |
| 12 | 12 | |
| 13 | 13 | #include "imagedev/snapquik.h" |
| r18874 | r18875 | |
|---|---|---|
| 542 | 542 | m_cassette->write(!BIT(data, 1)); |
| 543 | 543 | } |
| 544 | 544 | |
| 545 | static M6510_INTERFACE( cpu_intf ) | |
| 546 | { | |
| 547 | DEVCB_NULL, | |
| 548 | DEVCB_NULL, | |
| 549 | DEVCB_DRIVER_MEMBER(plus4_state, cpu_r), | |
| 550 | DEVCB_DRIVER_MEMBER(plus4_state, cpu_w), | |
| 551 | 0x00, | |
| 552 | 0xc0 | |
| 553 | }; | |
| 554 | ||
| 555 | static M6510_INTERFACE( c16_cpu_intf ) | |
| 556 | { | |
| 557 | DEVCB_NULL, | |
| 558 | DEVCB_NULL, | |
| 559 | DEVCB_DRIVER_MEMBER(plus4_state, c16_cpu_r), | |
| 560 | DEVCB_DRIVER_MEMBER(plus4_state, cpu_w), | |
| 561 | 0x00, | |
| 562 | 0xc0 | |
| 563 | }; | |
| 564 | ||
| 565 | 545 | //------------------------------------------------- |
| 566 | 546 | // ted7360_interface ted_intf |
| 567 | 547 | //------------------------------------------------- |
| r18874 | r18875 | |
| 911 | 891 | // basic machine hardware |
| 912 | 892 | MCFG_CPU_ADD(MOS7501_TAG, M7501, XTAL_14_31818MHz/16) |
| 913 | 893 | MCFG_CPU_PROGRAM_MAP(plus4_mem) |
| 914 | MCFG_CPU_CONFIG(cpu_intf) | |
| 894 | MCFG_M7501_PORT_CALLBACKS(READ8(plus4_state, cpu_r), WRITE8(plus4_state, cpu_w)) | |
| 895 | MCFG_M7501_PORT_PULLS(0x00, 0xc0) | |
| 915 | 896 | MCFG_CPU_VBLANK_INT_DRIVER(SCREEN_TAG, plus4_state, c16_frame_interrupt) |
| 916 | 897 | MCFG_CPU_PERIODIC_INT_DRIVER(plus4_state, c16_raster_interrupt, TED7360_HRETRACERATE) |
| 917 | 898 | MCFG_QUANTUM_TIME(attotime::from_hz(60)) |
| r18874 | r18875 | |
| 950 | 931 | // basic machine hardware |
| 951 | 932 | MCFG_CPU_ADD(MOS7501_TAG, M7501, XTAL_17_73447MHz/20) |
| 952 | 933 | MCFG_CPU_PROGRAM_MAP(plus4_mem) |
| 953 | MCFG_CPU_CONFIG(cpu_intf) | |
| 934 | MCFG_M7501_PORT_CALLBACKS(READ8(plus4_state, cpu_r), WRITE8(plus4_state, cpu_w)) | |
| 935 | MCFG_M7501_PORT_PULLS(0x00, 0xc0) | |
| 954 | 936 | MCFG_CPU_VBLANK_INT_DRIVER(SCREEN_TAG, plus4_state, c16_frame_interrupt) |
| 955 | 937 | MCFG_CPU_PERIODIC_INT_DRIVER(plus4_state, c16_raster_interrupt, TED7360_HRETRACERATE) |
| 956 | 938 | MCFG_QUANTUM_TIME(attotime::from_hz(60)) |
| r18874 | r18875 | |
| 987 | 969 | |
| 988 | 970 | static MACHINE_CONFIG_DERIVED( c16n, ntsc ) |
| 989 | 971 | MCFG_CPU_MODIFY(MOS7501_TAG) |
| 990 | MCFG_CPU_CONFIG(c16_cpu_intf) | |
| 972 | MCFG_M7501_PORT_CALLBACKS(READ8(plus4_state, c16_cpu_r), WRITE8(plus4_state, cpu_w)) | |
| 973 | MCFG_M7501_PORT_PULLS(0x00, 0xc0) | |
| 991 | 974 | |
| 992 | 975 | MCFG_DEVICE_REMOVE(MOS6551_TAG) |
| 993 | 976 | MCFG_DEVICE_REMOVE(MOS6529_USER_TAG) |
| r18874 | r18875 | |
| 1008 | 991 | |
| 1009 | 992 | static MACHINE_CONFIG_DERIVED( c16p, pal ) |
| 1010 | 993 | MCFG_CPU_MODIFY(MOS7501_TAG) |
| 1011 | MCFG_CPU_CONFIG(c16_cpu_intf) | |
| 994 | MCFG_M7501_PORT_CALLBACKS(READ8(plus4_state, c16_cpu_r), WRITE8(plus4_state, cpu_w)) | |
| 995 | MCFG_M7501_PORT_PULLS(0x00, 0xc0) | |
| 1012 | 996 | |
| 1013 | 997 | MCFG_DEVICE_REMOVE(MOS6551_TAG) |
| 1014 | 998 | MCFG_DEVICE_REMOVE(MOS6529_USER_TAG) |
| r18874 | r18875 | |
|---|---|---|
| 14 | 14 | #include "video/ppu2c0x.h" |
| 15 | 15 | #include "includes/nes.h" |
| 16 | 16 | //#include "includes/nes_mmc.h" |
| 17 | #include "cpu/m6502/ | |
| 17 | #include "cpu/m6502/n2a03.h" | |
| 18 | 18 | #include "imagedev/cartslot.h" |
| 19 | 19 | #include "sound/nes_apu.h" |
| 20 | 20 | #include "imagedev/flopdrv.h" |
| r18874 | r18875 | |
|---|---|---|
| 10 | 10 | |
| 11 | 11 | |
| 12 | 12 | #include "emu.h" |
| 13 | #include "cpu/m6502/m6502.h" | |
| 13 | #include "cpu/m6502/m65c02.h" | |
| 14 | 14 | #include "machine/6522via.h" |
| 15 | 15 | #include "machine/6551acia.h" |
| 16 | 16 | #include "rendlay.h" |
| r18874 | r18875 | |
| 253 | 253 | DEVCB_NULL,//DEVCB_DRIVER_LINE_MEMBER(clcd_state, via0_ca2_w), // CASS MOTOR |
| 254 | 254 | DEVCB_NULL, |
| 255 | 255 | |
| 256 | DEVCB_CPU_INPUT_LINE("maincpu", M6502_IRQ_LINE) | |
| 256 | DEVCB_CPU_INPUT_LINE("maincpu", M65C02_IRQ_LINE) | |
| 257 | 257 | }; |
| 258 | 258 | |
| 259 | 259 | static const via6522_interface via1_intf = |
| r18874 | r18875 | |
|---|---|---|
| 6 | 6 | |
| 7 | 7 | #include <assert.h> |
| 8 | 8 | #include "emu.h" |
| 9 | #include "cpu/m6502/m6502.h" | |
| 9 | #include "cpu/m6502/m65c02.h" | |
| 10 | 10 | |
| 11 | 11 | #include "includes/svision.h" |
| 12 | 12 | #include "imagedev/cartslot.h" |
| r18874 | r18875 | |
| 61 | 61 | int irq = state->m_svision.timer_shot && (state->BANK & 2); |
| 62 | 62 | irq = irq || (*state->m_dma_finished && (state->BANK & 4)); |
| 63 | 63 | |
| 64 | machine.device("maincpu")->execute().set_input_line(M6502_IRQ_LINE, irq ? ASSERT_LINE : CLEAR_LINE); | |
| 64 | machine.device("maincpu")->execute().set_input_line(M65C02_IRQ_LINE, irq ? ASSERT_LINE : CLEAR_LINE); | |
| 65 | 65 | } |
| 66 | 66 | |
| 67 | 67 | TIMER_CALLBACK_MEMBER(svision_state::svision_timer) |
| r18874 | r18875 | |
|---|---|---|
| 49 | 49 | ****************************************************************************/ |
| 50 | 50 | |
| 51 | 51 | #include "emu.h" |
| 52 | #include "cpu/m6502/m650 | |
| 52 | #include "cpu/m6502/m6510.h" | |
| 53 | 53 | #include "machine/6526cia.h" |
| 54 | 54 | #include "sound/ay8910.h" |
| 55 | 55 | #include "machine/terminal.h" |
| r18874 | r18875 | |
| 198 | 198 | { |
| 199 | 199 | } |
| 200 | 200 | |
| 201 | static M6510_INTERFACE( sbc6510_m6510_interface ) | |
| 202 | { | |
| 203 | DEVCB_NULL, | |
| 204 | DEVCB_NULL, | |
| 205 | DEVCB_NULL, | |
| 206 | DEVCB_NULL, | |
| 207 | 0x00, | |
| 208 | 0x00 | |
| 209 | }; | |
| 210 | ||
| 211 | 201 | READ8_MEMBER( sbc6510_state::psg_a_r ) |
| 212 | 202 | { |
| 213 | 203 | return 0xff; |
| r18874 | r18875 | |
| 250 | 240 | |
| 251 | 241 | const legacy_mos6526_interface cia_intf = |
| 252 | 242 | { |
| 253 | DEVCB_CPU_INPUT_LINE("maincpu", M650 | |
| 243 | DEVCB_CPU_INPUT_LINE("maincpu", M6510_IRQ_LINE), // irq | |
| 254 | 244 | DEVCB_NULL, // pc (timer related) not connected |
| 255 | 245 | DEVCB_NULL, // cnt (serial related) not connected |
| 256 | 246 | DEVCB_NULL, // sp (serial related) not connected |
| r18874 | r18875 | |
| 263 | 253 | static MACHINE_CONFIG_START( sbc6510, sbc6510_state ) |
| 264 | 254 | /* basic machine hardware */ |
| 265 | 255 | MCFG_CPU_ADD("maincpu",M6510, XTAL_1MHz) |
| 266 | MCFG_CPU_CONFIG( sbc6510_m6510_interface ) | |
| 267 | 256 | MCFG_CPU_PROGRAM_MAP(sbc6510_mem) |
| 268 | 257 | |
| 269 | 258 |
| r18874 | r18875 | |
|---|---|---|
| 1 | 1 | #include "emu.h" |
| 2 | 2 | #include "cpu/mcs48/mcs48.h" |
| 3 | #include "cpu/m6502/ | |
| 3 | #include "cpu/m6502/n2a03.h" | |
| 4 | 4 | #include "sound/nes_apu.h" |
| 5 | 5 | #include "sound/discrete.h" |
| 6 | 6 | #include "machine/latch8.h" |
| r18874 | r18875 | |
|---|---|---|
| 10 | 10 | *******************************************************************************/ |
| 11 | 11 | |
| 12 | 12 | #include "emu.h" |
| 13 | #include "cpu/m6502/deco16.h" | |
| 13 | 14 | #include "cpu/m6502/m6502.h" |
| 14 | 15 | #include "includes/liberate.h" |
| 15 | 16 |
| r18874 | r18875 | |
|---|---|---|
| 1 | 1 | |
| 2 | 2 | #include "emu.h" |
| 3 | #include "cpu/m6502/m65c | |
| 3 | #include "cpu/m6502/m65c02.h" | |
| 4 | 4 | |
| 5 | 5 | class alvg_state : public driver_device |
| 6 | 6 | { |
| r18874 | r18875 | |
|---|---|---|
| 7 | 7 | */ |
| 8 | 8 | |
| 9 | 9 | #include "emu.h" |
| 10 | #include "cpu/m6502/m6502.h" | |
| 10 | #include "cpu/m6502/m65c02.h" | |
| 11 | 11 | #include "cpu/m6809/m6809.h" |
| 12 | 12 | #include "cpu/m6800/m6800.h" |
| 13 | 13 | #include "cpu/m68000/m68000.h" |
| r18874 | r18875 | |
|---|---|---|
| 111 | 111 | |
| 112 | 112 | #include "emu.h" |
| 113 | 113 | #include "cpu/z80/z80.h" |
| 114 | #include "cpu/m6502/ | |
| 114 | #include "cpu/m6502/n2a03.h" | |
| 115 | 115 | #include "sound/vlm5030.h" |
| 116 | 116 | #include "sound/nes_apu.h" |
| 117 | 117 | #include "machine/nvram.h" |
| r18874 | r18875 | |
|---|---|---|
| 55 | 55 | */ |
| 56 | 56 | |
| 57 | 57 | #include "emu.h" |
| 58 | #include "cpu/m6502/ | |
| 58 | #include "cpu/m6502/n2a03.h" | |
| 59 | 59 | #include "sound/dac.h" |
| 60 | 60 | #include "sound/nes_apu.h" |
| 61 | 61 | #include "video/ppu2c0x.h" |
| r18874 | r18875 | |
|---|---|---|
| 15 | 15 | *******************************************************************************/ |
| 16 | 16 | |
| 17 | 17 | #include "emu.h" |
| 18 | #include "cpu/m6502/deco16.h" | |
| 18 | 19 | #include "cpu/m6502/m6502.h" |
| 19 | 20 | #include "sound/ay8910.h" |
| 20 | 21 | #include "includes/liberate.h" |
| r18874 | r18875 | |
|---|---|---|
| 173 | 173 | #define MASTER_CLOCK XTAL_16MHz |
| 174 | 174 | |
| 175 | 175 | #include "emu.h" |
| 176 | #include "cpu/m6502/m6502.h" | |
| 176 | #include "cpu/m6502/m65c02.h" | |
| 177 | 177 | #include "video/mc6845.h" |
| 178 | 178 | #include "sound/ay8910.h" |
| 179 | 179 | #include "machine/nvram.h" |
| r18874 | r18875 | |
|---|---|---|
| 59 | 59 | |
| 60 | 60 | #include "emu.h" |
| 61 | 61 | #include "video/ppu2c0x.h" |
| 62 | #include "cpu/m6502/ | |
| 62 | #include "cpu/m6502/n2a03.h" | |
| 63 | 63 | #include "imagedev/cartslot.h" |
| 64 | 64 | #include "sound/nes_apu.h" |
| 65 | 65 | #include "sound/dac.h" |
| r18874 | r18875 | |
|---|---|---|
| 7 | 7 | ***************************************************************************/ |
| 8 | 8 | |
| 9 | 9 | #include "emu.h" |
| 10 | #include "cpu/m6502/m650 | |
| 10 | #include "cpu/m6502/m6504.h" | |
| 11 | 11 | |
| 12 | 12 | class allied_state : public driver_device |
| 13 | 13 | { |
| r18874 | r18875 | |
|---|---|---|
| 362 | 362 | #define MASTER_CLOCK XTAL_16MHz |
| 363 | 363 | |
| 364 | 364 | #include "emu.h" |
| 365 | #include "cpu/m6502/m6502.h" | |
| 365 | #include "cpu/m6502/m65sc02.h" | |
| 366 | 366 | #include "sound/okim6295.h" |
| 367 | 367 | #include "snookr10.lh" |
| 368 | 368 | #include "includes/snookr10.h" |
| r18874 | r18875 | |
|---|---|---|
| 66 | 66 | */ |
| 67 | 67 | |
| 68 | 68 | #include "emu.h" |
| 69 | #include "cpu/m6502/ | |
| 69 | #include "cpu/m6502/n2a03.h" | |
| 70 | 70 | #include "sound/dac.h" |
| 71 | 71 | #include "sound/nes_apu.h" |
| 72 | 72 | #include "video/ppu2c0x.h" |
| r18874 | r18875 | |
|---|---|---|
| 23 | 23 | |
| 24 | 24 | #include "emu.h" |
| 25 | 25 | #include "cpu/m6809/m6809.h" |
| 26 | #include "cpu/m6502/ | |
| 26 | #include "cpu/m6502/deco16.h" | |
| 27 | 27 | #include "sound/ay8910.h" |
| 28 | 28 | #include "sound/dac.h" |
| 29 | 29 | #include "includes/bwing.h" |
| r18874 | r18875 | |
|---|---|---|
| 45 | 45 | ***************************************************************************/ |
| 46 | 46 | |
| 47 | 47 | #include "emu.h" |
| 48 | #include "cpu/m6502/m6502.h" | |
| 48 | #include "cpu/m6502/m65sc02.h" | |
| 49 | 49 | |
| 50 | 50 | |
| 51 | 51 | class cmmb_state : public driver_device |
| r18874 | r18875 | |
|---|---|---|
| 13 | 13 | |
| 14 | 14 | #include "emu.h" |
| 15 | 15 | #include "cpu/z80/z80.h" |
| 16 | #include "cpu/m6502/m6502.h" | |
| 16 | #include "cpu/m6502/m65c02.h" | |
| 17 | 17 | #include "video/mc6845.h" |
| 18 | 18 | #include "machine/i8255.h" |
| 19 | 19 | #include "sound/ay8910.h" |
| r18874 | r18875 | |
|---|---|---|
| 4 | 4 | |
| 5 | 5 | |
| 6 | 6 | #include "emu.h" |
| 7 | #include "cpu/m6502/m65c | |
| 7 | #include "cpu/m6502/m65c02.h" | |
| 8 | 8 | |
| 9 | 9 | class gts3_state : public driver_device |
| 10 | 10 | { |
| r18874 | r18875 | |
|---|---|---|
| 1357 | 1357 | #include "emu.h" |
| 1358 | 1358 | #include "cpu/z80/z80.h" |
| 1359 | 1359 | #include "cpu/m68000/m68000.h" |
| 1360 | #include "cpu/m6502/m6502.h" | |
| 1360 | #include "cpu/m6502/m65c02.h" | |
| 1361 | 1361 | #include "includes/seta.h" |
| 1362 | 1362 | #include "machine/6821pia.h" |
| 1363 | 1363 | #include "machine/6850acia.h" |
| r18874 | r18875 | |
|---|---|---|
| 645 | 645 | |
| 646 | 646 | #include "emu.h" |
| 647 | 647 | #include "cpu/m6502/m6502.h" |
| 648 | #include "cpu/m6502/m65c02.h" | |
| 648 | 649 | #include "video/mc6845.h" |
| 649 | 650 | #include "machine/6821pia.h" |
| 650 | 651 | #include "machine/6850acia.h" |
| r18874 | r18875 | |
|---|---|---|
| 26 | 26 | |
| 27 | 27 | #include "emu.h" |
| 28 | 28 | #include "cpu/z80/z80.h" |
| 29 | #include "cpu/m6502/m6502.h" | |
| 29 | #include "cpu/m6502/m65c02.h" | |
| 30 | 30 | #include "cpu/mcs51/mcs51.h" |
| 31 | 31 | #include "includes/thedeep.h" |
| 32 | 32 | #include "sound/2203intf.h" |
| r18874 | r18875 | |
|---|---|---|
| 138 | 138 | ***************************************************************************/ |
| 139 | 139 | |
| 140 | 140 | #include "emu.h" |
| 141 | #include "cpu/m6502/ | |
| 141 | #include "cpu/m6502/n2a03.h" | |
| 142 | 142 | #include "rendlay.h" |
| 143 | 143 | #include "video/ppu2c0x.h" |
| 144 | 144 | #include "machine/rp5h01.h" |
| r18874 | r18875 | |
|---|---|---|
| 810 | 810 | #define MASTER_CLOCK XTAL_16MHz |
| 811 | 811 | |
| 812 | 812 | #include "emu.h" |
| 813 | #include "cpu/m6502/m6502.h" | |
| 813 | #include "cpu/m6502/m65c02.h" | |
| 814 | #include "cpu/m6502/m65sc02.h" | |
| 814 | 815 | #include "video/mc6845.h" |
| 815 | 816 | #include "machine/6821pia.h" |
| 816 | 817 | #include "sound/ay8910.h" |
| r18874 | r18875 | |
|---|---|---|
| 204 | 204 | ***************************************************************************/ |
| 205 | 205 | |
| 206 | 206 | #include "emu.h" |
| 207 | #include "cpu/m6502/deco16.h" | |
| 207 | 208 | #include "cpu/m6502/m6502.h" |
| 208 | 209 | #include "cpu/m6809/m6809.h" |
| 209 | 210 | #include "sound/2203intf.h" |
| r18874 | r18875 | |
|---|---|---|
| 290 | 290 | ***************************************************************************/ |
| 291 | 291 | |
| 292 | 292 | #include "emu.h" |
| 293 | #include "cpu/m6502/ | |
| 293 | #include "cpu/m6502/n2a03.h" | |
| 294 | 294 | #include "video/ppu2c0x.h" |
| 295 | 295 | #include "cpu/z80/z80.h" |
| 296 | 296 | #include "machine/rp5h01.h" |
| r18874 | r18875 | |
|---|---|---|
| 125 | 125 | CPU_DISASSEMBLE( lh5801 ); |
| 126 | 126 | CPU_DISASSEMBLE( lr35902 ); |
| 127 | 127 | CPU_DISASSEMBLE( m37710_generic ); |
| 128 | CPU_DISASSEMBLE( m6502 ); | |
| 129 | CPU_DISASSEMBLE( m65sc02 ); | |
| 130 | CPU_DISASSEMBLE( m65c02 ); | |
| 131 | CPU_DISASSEMBLE( m65ce02 ); | |
| 132 | CPU_DISASSEMBLE( m6510 ); | |
| 133 | CPU_DISASSEMBLE( deco16 ); | |
| 134 | CPU_DISASSEMBLE( m4510 ); | |
| 135 | 128 | CPU_DISASSEMBLE( m6800 ); |
| 136 | 129 | CPU_DISASSEMBLE( m6801 ); |
| 137 | 130 | CPU_DISASSEMBLE( m6802 ); |
| r18874 | r18875 | |
| 254 | 247 | { "lh5801", _8bit, 0, CPU_DISASSEMBLE_NAME(lh5801) }, |
| 255 | 248 | { "lr35902", _8bit, 0, CPU_DISASSEMBLE_NAME(lr35902) }, |
| 256 | 249 | { "m37710", _8bit, 0, CPU_DISASSEMBLE_NAME(m37710_generic) }, |
| 257 | { "m6502", _8bit, 0, CPU_DISASSEMBLE_NAME(m6502) }, | |
| 258 | { "m65sc02", _8bit, 0, CPU_DISASSEMBLE_NAME(m65sc02) }, | |
| 259 | { "m65c02", _8bit, 0, CPU_DISASSEMBLE_NAME(m65c02) }, | |
| 260 | { "m65ce02", _8bit, 0, CPU_DISASSEMBLE_NAME(m65ce02) }, | |
| 261 | { "m6510", _8bit, 0, CPU_DISASSEMBLE_NAME(m6510) }, | |
| 262 | { "deco16", _8bit, 0, CPU_DISASSEMBLE_NAME(deco16) }, | |
| 263 | { "m4510", _8bit, 0, CPU_DISASSEMBLE_NAME(m4510) }, | |
| 264 | 250 | { "m6800", _8bit, 0, CPU_DISASSEMBLE_NAME(m6800) }, |
| 265 | 251 | { "m6801", _8bit, 0, CPU_DISASSEMBLE_NAME(m6801) }, |
| 266 | 252 | { "m6802", _8bit, 0, CPU_DISASSEMBLE_NAME(m6802) }, |
| r18874 | r18875 | |
|---|---|---|
| 1 | /*************************************************************** | |
| 2 | *************************************************************** | |
| 3 | * Macros to emulate the N2A03 opcodes | |
| 4 | *************************************************************** | |
| 5 | ***************************************************************/ | |
| 6 | ||
| 7 | ||
| 8 | /* N2A03 ******************************************************* | |
| 9 | * ADC Add with carry - no decimal mode | |
| 10 | ***************************************************************/ | |
| 11 | #define ADC_NES \ | |
| 12 | { \ | |
| 13 | int c = (P & F_C); \ | |
| 14 | int sum = A + tmp + c; \ | |
| 15 | P &= ~(F_V | F_C); \ | |
| 16 | if( ~(A^tmp) & (A^sum) & F_N ) \ | |
| 17 | P |= F_V; \ | |
| 18 | if( sum & 0xff00 ) \ | |
| 19 | P |= F_C; \ | |
| 20 | A = (UINT8) sum; \ | |
| 21 | } \ | |
| 22 | SET_NZ(A) | |
| 23 | ||
| 24 | /* N2A03 ******************************************************* | |
| 25 | * SBC Subtract with carry - no decimal mode | |
| 26 | ***************************************************************/ | |
| 27 | #define SBC_NES \ | |
| 28 | { \ | |
| 29 | int c = (P & F_C) ^ F_C; \ | |
| 30 | int sum = A - tmp - c; \ | |
| 31 | P &= ~(F_V | F_C); \ | |
| 32 | if( (A^tmp) & (A^sum) & F_N ) \ | |
| 33 | P |= F_V; \ | |
| 34 | if( (sum & 0xff00) == 0 ) \ | |
| 35 | P |= F_C; \ | |
| 36 | A = (UINT8) sum; \ | |
| 37 | } \ | |
| 38 | SET_NZ(A) |
| r18874 | r18875 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * tbl6510.c | |
| 4 | * 6510 opcode functions and function pointer table | |
| 5 | * | |
| 6 | * Copyright Juergen Buchmueller, all rights reserved. | |
| 7 | * | |
| 8 | * - This source code is released as freeware for non-commercial purposes. | |
| 9 | * - You are free to use and redistribute this code in modified or | |
| 10 | * unmodified form, provided you list me in the credits. | |
| 11 | * - If you modify this source code, you must add a notice to each modified | |
| 12 | * source file that it has been changed. If you're a nice person, you | |
| 13 | * will clearly mark each change too. :) | |
| 14 | * - If you wish to use this for commercial purposes, please contact me at | |
| 15 | * pullmoll@t-online.de | |
| 16 | * - The author of this copywritten work reserves the right to change the | |
| 17 | * terms of its usage and license at any time, including retroactively | |
| 18 | * - This entire notice must remain in the source code. | |
| 19 | * | |
| 20 | * - Opcode information based on an Intel 386 '6510.asm' core | |
| 21 | * written by R.F. van Ee (1993) | |
| 22 | * - Cycle counts are guesswork :-) | |
| 23 | * | |
| 24 | *****************************************************************************/ | |
| 25 | ||
| 26 | #undef OP | |
| 27 | #define OP(nn) INLINE void m6510_##nn(m6502_Regs *cpustate) | |
| 28 | ||
| 29 | /***************************************************************************** | |
| 30 | ***************************************************************************** | |
| 31 | * | |
| 32 | * plain vanilla 6502 opcodes | |
| 33 | * | |
| 34 | ***************************************************************************** | |
| 35 | * op temp cycles rdmem opc wrmem ********************/ | |
| 36 | ||
| 37 | OP(00) { BRK; } /* 7 BRK */ | |
| 38 | OP(20) { JSR; } /* 6 JSR */ | |
| 39 | OP(40) { RTI; } /* 6 RTI */ | |
| 40 | OP(60) { RTS; } /* 6 RTS */ | |
| 41 | OP(80) { RDOPARG(); NOP; } /* 2 NOP IMM */ | |
| 42 | OP(a0) { int tmp; RD_IMM; LDY; } /* 2 LDY IMM */ | |
| 43 | OP(c0) { int tmp; RD_IMM; CPY; } /* 2 CPY IMM */ | |
| 44 | OP(e0) { int tmp; RD_IMM; CPX; } /* 2 CPX IMM */ | |
| 45 | ||
| 46 | OP(10) { BPL; } /* 2-4 BPL REL */ | |
| 47 | OP(30) { BMI; } /* 2-4 BMI REL */ | |
| 48 | OP(50) { BVC; } /* 2-4 BVC REL */ | |
| 49 | OP(70) { BVS; } /* 2-4 BVS REL */ | |
| 50 | OP(90) { BCC; } /* 2-4 BCC REL */ | |
| 51 | OP(b0) { BCS; } /* 2-4 BCS REL */ | |
| 52 | OP(d0) { BNE; } /* 2-4 BNE REL */ | |
| 53 | OP(f0) { BEQ; } /* 2-4 BEQ REL */ | |
| 54 | ||
| 55 | OP(01) { int tmp; RD_IDX; ORA; } /* 6 ORA IDX */ | |
| 56 | OP(21) { int tmp; RD_IDX; AND; } /* 6 AND IDX */ | |
| 57 | OP(41) { int tmp; RD_IDX; EOR; } /* 6 EOR IDX */ | |
| 58 | OP(61) { int tmp; RD_IDX; ADC; } /* 6 ADC IDX */ | |
| 59 | OP(81) { int tmp; STA; WR_IDX; } /* 6 STA IDX */ | |
| 60 | OP(a1) { int tmp; RD_IDX; LDA; } /* 6 LDA IDX */ | |
| 61 | OP(c1) { int tmp; RD_IDX; CMP; } /* 6 CMP IDX */ | |
| 62 | OP(e1) { int tmp; RD_IDX; SBC; } /* 6 SBC IDX */ | |
| 63 | ||
| 64 | OP(11) { int tmp; RD_IDY_P; ORA; } /* 5 ORA IDY page penalty */ | |
| 65 | OP(31) { int tmp; RD_IDY_P; AND; } /* 5 AND IDY page penalty */ | |
| 66 | OP(51) { int tmp; RD_IDY_P; EOR; } /* 5 EOR IDY page penalty */ | |
| 67 | OP(71) { int tmp; RD_IDY_P; ADC; } /* 5 ADC IDY page penalty */ | |
| 68 | OP(91) { int tmp; STA; WR_IDY_NP; } /* 6 STA IDY */ | |
| 69 | OP(b1) { int tmp; RD_IDY_P; LDA; } /* 5 LDA IDY page penalty */ | |
| 70 | OP(d1) { int tmp; RD_IDY_P; CMP; } /* 5 CMP IDY page penalty */ | |
| 71 | OP(f1) { int tmp; RD_IDY_P; SBC; } /* 5 SBC IDY page penalty */ | |
| 72 | ||
| 73 | OP(02) { KIL; } /* 1 KIL */ | |
| 74 | OP(22) { KIL; } /* 1 KIL */ | |
| 75 | OP(42) { KIL; } /* 1 KIL */ | |
| 76 | OP(62) { KIL; } /* 1 KIL */ | |
| 77 | OP(82) { RDOPARG(); NOP; } /* 2 NOP IMM */ | |
| 78 | OP(a2) { int tmp; RD_IMM; LDX; } /* 2 LDX IMM */ | |
| 79 | OP(c2) { RDOPARG(); NOP; } /* 2 NOP IMM */ | |
| 80 | OP(e2) { RDOPARG(); NOP; } /* 2 NOP IMM */ | |
| 81 | ||
| 82 | OP(12) { KIL; } /* 1 KIL */ | |
| 83 | OP(32) { KIL; } /* 1 KIL */ | |
| 84 | OP(52) { KIL; } /* 1 KIL */ | |
| 85 | OP(72) { KIL; } /* 1 KIL */ | |
| 86 | OP(92) { KIL; } /* 1 KIL */ | |
| 87 | OP(b2) { KIL; } /* 1 KIL */ | |
| 88 | OP(d2) { KIL; } /* 1 KIL */ | |
| 89 | OP(f2) { KIL; } /* 1 KIL */ | |
| 90 | ||
| 91 | OP(03) { int tmp; RD_IDX; WB_EA; SLO; WB_EA; } /* 7 SLO IDX */ | |
| 92 | OP(23) { int tmp; RD_IDX; WB_EA; RLA; WB_EA; } /* 7 RLA IDX */ | |
| 93 | OP(43) { int tmp; RD_IDX; WB_EA; SRE; WB_EA; } /* 7 SRE IDX */ | |
| 94 | OP(63) { int tmp; RD_IDX; WB_EA; RRA; WB_EA; } /* 7 RRA IDX */ | |
| 95 | OP(83) { int tmp; SAX; WR_IDX; } /* 6 SAX IDX */ | |
| 96 | OP(a3) { int tmp; RD_IDX; LAX; } /* 6 LAX IDX */ | |
| 97 | OP(c3) { int tmp; RD_IDX; WB_EA; DCP; WB_EA; } /* 7 DCP IDX */ | |
| 98 | OP(e3) { int tmp; RD_IDX; WB_EA; ISB; WB_EA; } /* 7 ISB IDX */ | |
| 99 | ||
| 100 | OP(13) { int tmp; RD_IDY_NP; WB_EA; SLO; WB_EA; } /* 7 SLO IDY */ | |
| 101 | OP(33) { int tmp; RD_IDY_NP; WB_EA; RLA; WB_EA; } /* 7 RLA IDY */ | |
| 102 | OP(53) { int tmp; RD_IDY_NP; WB_EA; SRE; WB_EA; } /* 7 SRE IDY */ | |
| 103 | OP(73) { int tmp; RD_IDY_NP; WB_EA; RRA; WB_EA; } /* 7 RRA IDY */ | |
| 104 | OP(93) { int tmp; EA_IDY_NP; SAH; WB_EA; } /* 5 SAH IDY */ | |
| 105 | OP(b3) { int tmp; RD_IDY_P; LAX; } /* 5 LAX IDY page penalty */ | |
| 106 | OP(d3) { int tmp; RD_IDY_NP; WB_EA; DCP; WB_EA; } /* 7 DCP IDY */ | |
| 107 | OP(f3) { int tmp; RD_IDY_NP; WB_EA; ISB; WB_EA; } /* 7 ISB IDY */ | |
| 108 | ||
| 109 | OP(04) { RD_ZPG_DISCARD; NOP; } /* 3 NOP ZPG */ | |
| 110 | OP(24) { int tmp; RD_ZPG; BIT; } /* 3 BIT ZPG */ | |
| 111 | OP(44) { RD_ZPG_DISCARD; NOP; } /* 3 NOP ZPG */ | |
| 112 | OP(64) { RD_ZPG_DISCARD; NOP; } /* 3 NOP ZPG */ | |
| 113 | OP(84) { int tmp; STY; WR_ZPG; } /* 3 STY ZPG */ | |
| 114 | OP(a4) { int tmp; RD_ZPG; LDY; } /* 3 LDY ZPG */ | |
| 115 | OP(c4) { int tmp; RD_ZPG; CPY; } /* 3 CPY ZPG */ | |
| 116 | OP(e4) { int tmp; RD_ZPG; CPX; } /* 3 CPX ZPG */ | |
| 117 | ||
| 118 | OP(14) { RD_ZPX_DISCARD; NOP; } /* 4 NOP ZPX */ | |
| 119 | OP(34) { RD_ZPX_DISCARD; NOP; } /* 4 NOP ZPX */ | |
| 120 | OP(54) { RD_ZPX_DISCARD; NOP; } /* 4 NOP ZPX */ | |
| 121 | OP(74) { RD_ZPX_DISCARD; NOP; } /* 4 NOP ZPX */ | |
| 122 | OP(94) { int tmp; STY; WR_ZPX; } /* 4 STY ZPX */ | |
| 123 | OP(b4) { int tmp; RD_ZPX; LDY; } /* 4 LDY ZPX */ | |
| 124 | OP(d4) { RD_ZPX_DISCARD; NOP; } /* 4 NOP ZPX */ | |
| 125 | OP(f4) { RD_ZPX_DISCARD; NOP; } /* 4 NOP ZPX */ | |
| 126 | ||
| 127 | OP(05) { int tmp; RD_ZPG; ORA; } /* 3 ORA ZPG */ | |
| 128 | OP(25) { int tmp; RD_ZPG; AND; } /* 3 AND ZPG */ | |
| 129 | OP(45) { int tmp; RD_ZPG; EOR; } /* 3 EOR ZPG */ | |
| 130 | OP(65) { int tmp; RD_ZPG; ADC; } /* 3 ADC ZPG */ | |
| 131 | OP(85) { int tmp; STA; WR_ZPG; } /* 3 STA ZPG */ | |
| 132 | OP(a5) { int tmp; RD_ZPG; LDA; } /* 3 LDA ZPG */ | |
| 133 | OP(c5) { int tmp; RD_ZPG; CMP; } /* 3 CMP ZPG */ | |
| 134 | OP(e5) { int tmp; RD_ZPG; SBC; } /* 3 SBC ZPG */ | |
| 135 | ||
| 136 | OP(15) { int tmp; RD_ZPX; ORA; } /* 4 ORA ZPX */ | |
| 137 | OP(35) { int tmp; RD_ZPX; AND; } /* 4 AND ZPX */ | |
| 138 | OP(55) { int tmp; RD_ZPX; EOR; } /* 4 EOR ZPX */ | |
| 139 | OP(75) { int tmp; RD_ZPX; ADC; } /* 4 ADC ZPX */ | |
| 140 | OP(95) { int tmp; STA; WR_ZPX; } /* 4 STA ZPX */ | |
| 141 | OP(b5) { int tmp; RD_ZPX; LDA; } /* 4 LDA ZPX */ | |
| 142 | OP(d5) { int tmp; RD_ZPX; CMP; } /* 4 CMP ZPX */ | |
| 143 | OP(f5) { int tmp; RD_ZPX; SBC; } /* 4 SBC ZPX */ | |
| 144 | ||
| 145 | OP(06) { int tmp; RD_ZPG; WB_EA; ASL; WB_EA; } /* 5 ASL ZPG */ | |
| 146 | OP(26) { int tmp; RD_ZPG; WB_EA; ROL; WB_EA; } /* 5 ROL ZPG */ | |
| 147 | OP(46) { int tmp; RD_ZPG; WB_EA; LSR; WB_EA; } /* 5 LSR ZPG */ | |
| 148 | OP(66) { int tmp; RD_ZPG; WB_EA; ROR; WB_EA; } /* 5 ROR ZPG */ | |
| 149 | OP(86) { int tmp; STX; WR_ZPG; } /* 3 STX ZPG */ | |
| 150 | OP(a6) { int tmp; RD_ZPG; LDX; } /* 3 LDX ZPG */ | |
| 151 | OP(c6) { int tmp; RD_ZPG; WB_EA; DEC; WB_EA; } /* 5 DEC ZPG */ | |
| 152 | OP(e6) { int tmp; RD_ZPG; WB_EA; INC; WB_EA; } /* 5 INC ZPG */ | |
| 153 | ||
| 154 | OP(16) { int tmp; RD_ZPX; WB_EA; ASL; WB_EA; } /* 6 ASL ZPX */ | |
| 155 | OP(36) { int tmp; RD_ZPX; WB_EA; ROL; WB_EA; } /* 6 ROL ZPX */ | |
| 156 | OP(56) { int tmp; RD_ZPX; WB_EA; LSR; WB_EA; } /* 6 LSR ZPX */ | |
| 157 | OP(76) { int tmp; RD_ZPX; WB_EA; ROR; WB_EA; } /* 6 ROR ZPX */ | |
| 158 | OP(96) { int tmp; STX; WR_ZPY; } /* 4 STX ZPY */ | |
| 159 | OP(b6) { int tmp; RD_ZPY; LDX; } /* 4 LDX ZPY */ | |
| 160 | OP(d6) { int tmp; RD_ZPX; WB_EA; DEC; WB_EA; } /* 6 DEC ZPX */ | |
| 161 | OP(f6) { int tmp; RD_ZPX; WB_EA; INC; WB_EA; } /* 6 INC ZPX */ | |
| 162 | ||
| 163 | OP(07) { int tmp; RD_ZPG; WB_EA; SLO; WB_EA; } /* 5 SLO ZPG */ | |
| 164 | OP(27) { int tmp; RD_ZPG; WB_EA; RLA; WB_EA; } /* 5 RLA ZPG */ | |
| 165 | OP(47) { int tmp; RD_ZPG; WB_EA; SRE; WB_EA; } /* 5 SRE ZPG */ | |
| 166 | OP(67) { int tmp; RD_ZPG; WB_EA; RRA; WB_EA; } /* 5 RRA ZPG */ | |
| 167 | OP(87) { int tmp; SAX; WR_ZPG; } /* 3 SAX ZPG */ | |
| 168 | OP(a7) { int tmp; RD_ZPG; LAX; } /* 3 LAX ZPG */ | |
| 169 | OP(c7) { int tmp; RD_ZPG; WB_EA; DCP; WB_EA; } /* 5 DCP ZPG */ | |
| 170 | OP(e7) { int tmp; RD_ZPG; WB_EA; ISB; WB_EA; } /* 5 ISB ZPG */ | |
| 171 | ||
| 172 | OP(17) { int tmp; RD_ZPX; WB_EA; SLO; WB_EA; } /* 6 SLO ZPX */ | |
| 173 | OP(37) { int tmp; RD_ZPX; WB_EA; RLA; WB_EA; } /* 6 RLA ZPX */ | |
| 174 | OP(57) { int tmp; RD_ZPX; WB_EA; SRE; WB_EA; } /* 6 SRE ZPX */ | |
| 175 | OP(77) { int tmp; RD_ZPX; WB_EA; RRA; WB_EA; } /* 6 RRA ZPX */ | |
| 176 | OP(97) { int tmp; SAX; WR_ZPY; } /* 4 SAX ZPY */ | |
| 177 | OP(b7) { int tmp; RD_ZPY; LAX; } /* 4 LAX ZPY */ | |
| 178 | OP(d7) { int tmp; RD_ZPX; WB_EA; DCP; WB_EA; } /* 6 DCP ZPX */ | |
| 179 | OP(f7) { int tmp; RD_ZPX; WB_EA; ISB; WB_EA; } /* 6 ISB ZPX */ | |
| 180 | ||
| 181 | OP(08) { RD_DUM; PHP; } /* 3 PHP */ | |
| 182 | OP(28) { RD_DUM; PLP; } /* 4 PLP */ | |
| 183 | OP(48) { RD_DUM; PHA; } /* 3 PHA */ | |
| 184 | OP(68) { RD_DUM; PLA; } /* 4 PLA */ | |
| 185 | OP(88) { RD_DUM; DEY; } /* 2 DEY */ | |
| 186 | OP(a8) { RD_DUM; TAY; } /* 2 TAY */ | |
| 187 | OP(c8) { RD_DUM; INY; } /* 2 INY */ | |
| 188 | OP(e8) { RD_DUM; INX; } /* 2 INX */ | |
| 189 | ||
| 190 | OP(18) { RD_DUM; CLC; } /* 2 CLC */ | |
| 191 | OP(38) { RD_DUM; SEC; } /* 2 SEC */ | |
| 192 | OP(58) { RD_DUM; CLI; } /* 2 CLI */ | |
| 193 | OP(78) { RD_DUM; SEI; } /* 2 SEI */ | |
| 194 | OP(98) { RD_DUM; TYA; } /* 2 TYA */ | |
| 195 | OP(b8) { RD_DUM; CLV; } /* 2 CLV */ | |
| 196 | OP(d8) { RD_DUM; CLD; } /* 2 CLD */ | |
| 197 | OP(f8) { RD_DUM; SED; } /* 2 SED */ | |
| 198 | ||
| 199 | OP(09) { int tmp; RD_IMM; ORA; } /* 2 ORA IMM */ | |
| 200 | OP(29) { int tmp; RD_IMM; AND; } /* 2 AND IMM */ | |
| 201 | OP(49) { int tmp; RD_IMM; EOR; } /* 2 EOR IMM */ | |
| 202 | OP(69) { int tmp; RD_IMM; ADC; } /* 2 ADC IMM */ | |
| 203 | OP(89) { RD_IMM_DISCARD; NOP; } /* 2 NOP IMM */ | |
| 204 | OP(a9) { int tmp; RD_IMM; LDA; } /* 2 LDA IMM */ | |
| 205 | OP(c9) { int tmp; RD_IMM; CMP; } /* 2 CMP IMM */ | |
| 206 | OP(e9) { int tmp; RD_IMM; SBC; } /* 2 SBC IMM */ | |
| 207 | ||
| 208 | OP(19) { int tmp; RD_ABY_P; ORA; } /* 4 ORA ABY page penalty */ | |
| 209 | OP(39) { int tmp; RD_ABY_P; AND; } /* 4 AND ABY page penalty */ | |
| 210 | OP(59) { int tmp; RD_ABY_P; EOR; } /* 4 EOR ABY page penalty */ | |
| 211 | OP(79) { int tmp; RD_ABY_P; ADC; } /* 4 ADC ABY page penalty */ | |
| 212 | OP(99) { int tmp; STA; WR_ABY_NP; } /* 5 STA ABY */ | |
| 213 | OP(b9) { int tmp; RD_ABY_P; LDA; } /* 4 LDA ABY page penalty */ | |
| 214 | OP(d9) { int tmp; RD_ABY_P; CMP; } /* 4 CMP ABY page penalty */ | |
| 215 | OP(f9) { int tmp; RD_ABY_P; SBC; } /* 4 SBC ABY page penalty */ | |
| 216 | ||
| 217 | OP(0a) { int tmp; RD_DUM; RD_ACC; ASL; WB_ACC; } /* 2 ASL A */ | |
| 218 | OP(2a) { int tmp; RD_DUM; RD_ACC; ROL; WB_ACC; } /* 2 ROL A */ | |
| 219 | OP(4a) { int tmp; RD_DUM; RD_ACC; LSR; WB_ACC; } /* 2 LSR A */ | |
| 220 | OP(6a) { int tmp; RD_DUM; RD_ACC; ROR; WB_ACC; } /* 2 ROR A */ | |
| 221 | OP(8a) { RD_DUM; TXA; } /* 2 TXA */ | |
| 222 | OP(aa) { RD_DUM; TAX; } /* 2 TAX */ | |
| 223 | OP(ca) { RD_DUM; DEX; } /* 2 DEX */ | |
| 224 | OP(ea) { RD_DUM; NOP; } /* 2 NOP */ | |
| 225 | ||
| 226 | OP(1a) { RD_DUM; NOP; } /* 2 NOP */ | |
| 227 | OP(3a) { RD_DUM; NOP; } /* 2 NOP */ | |
| 228 | OP(5a) { RD_DUM; NOP; } /* 2 NOP */ | |
| 229 | OP(7a) { RD_DUM; NOP; } /* 2 NOP */ | |
| 230 | OP(9a) { RD_DUM; TXS; } /* 2 TXS */ | |
| 231 | OP(ba) { RD_DUM; TSX; } /* 2 TSX */ | |
| 232 | OP(da) { RD_DUM; NOP; } /* 2 NOP */ | |
| 233 | OP(fa) { RD_DUM; NOP; } /* 2 NOP */ | |
| 234 | ||
| 235 | OP(0b) { int tmp; RD_IMM; ANC; } /* 2 ANC IMM */ | |
| 236 | OP(2b) { int tmp; RD_IMM; ANC; } /* 2 ANC IMM */ | |
| 237 | OP(4b) { int tmp; RD_IMM; ASR; WB_ACC; } /* 2 ASR IMM */ | |
| 238 | OP(6b) { int tmp; RD_IMM; ARR; WB_ACC; } /* 2 ARR IMM */ | |
| 239 | OP(8b) { int tmp; RD_IMM; AXA; } /* 2 AXA IMM */ | |
| 240 | OP(ab) { int tmp; RD_IMM; OAL_6510; } /* 2 OAL IMM */ | |
| 241 | OP(cb) { int tmp; RD_IMM; ASX; } /* 2 ASX IMM */ | |
| 242 | OP(eb) { int tmp; RD_IMM; SBC; } /* 2 SBC IMM */ | |
| 243 | ||
| 244 | OP(1b) { int tmp; RD_ABY_NP; WB_EA; SLO; WB_EA; } /* 7 SLO ABY */ | |
| 245 | OP(3b) { int tmp; RD_ABY_NP; WB_EA; RLA; WB_EA; } /* 7 RLA ABY */ | |
| 246 | OP(5b) { int tmp; RD_ABY_NP; WB_EA; SRE; WB_EA; } /* 7 SRE ABY */ | |
| 247 | OP(7b) { int tmp; RD_ABY_NP; WB_EA; RRA; WB_EA; } /* 7 RRA ABY */ | |
| 248 | OP(9b) { int tmp; EA_ABY_NP; SSH; WB_EA; } /* 5 SSH ABY */ | |
| 249 | OP(bb) { int tmp; RD_ABY_P; AST; } /* 4 AST ABY page penalty */ | |
| 250 | OP(db) { int tmp; RD_ABY_NP; WB_EA; DCP; WB_EA; } /* 7 DCP ABY */ | |
| 251 | OP(fb) { int tmp; RD_ABY_NP; WB_EA; ISB; WB_EA; } /* 7 ISB ABY */ | |
| 252 | ||
| 253 | OP(0c) { RD_ABS_DISCARD; NOP; } /* 4 NOP ABS */ | |
| 254 | OP(2c) { int tmp; RD_ABS; BIT; } /* 4 BIT ABS */ | |
| 255 | OP(4c) { EA_ABS; JMP; } /* 3 JMP ABS */ | |
| 256 | OP(6c) { int tmp; EA_IND; JMP; } /* 5 JMP IND */ | |
| 257 | OP(8c) { int tmp; STY; WR_ABS; } /* 4 STY ABS */ | |
| 258 | OP(ac) { int tmp; RD_ABS; LDY; } /* 4 LDY ABS */ | |
| 259 | OP(cc) { int tmp; RD_ABS; CPY; } /* 4 CPY ABS */ | |
| 260 | OP(ec) { int tmp; RD_ABS; CPX; } /* 4 CPX ABS */ | |
| 261 | ||
| 262 | OP(1c) { RD_ABX_P_DISCARD; NOP; } /* 4 NOP ABX page penalty */ | |
| 263 | OP(3c) { RD_ABX_P_DISCARD; NOP; } /* 4 NOP ABX page penalty */ | |
| 264 | OP(5c) { RD_ABX_P_DISCARD; NOP; } /* 4 NOP ABX page penalty */ | |
| 265 | OP(7c) { RD_ABX_P_DISCARD; NOP; } /* 4 NOP ABX page penalty */ | |
| 266 | OP(9c) { int tmp; EA_ABX_NP; SYH; WB_EA; } /* 5 SYH ABX */ | |
| 267 | OP(bc) { int tmp; RD_ABX_P; LDY; } /* 4 LDY ABX page penalty */ | |
| 268 | OP(dc) { RD_ABX_P_DISCARD; NOP; } /* 4 NOP ABX page penalty */ | |
| 269 | OP(fc) { RD_ABX_P_DISCARD; NOP; } /* 4 NOP ABX page penalty */ | |
| 270 | ||
| 271 | OP(0d) { int tmp; RD_ABS; ORA; } /* 4 ORA ABS */ | |
| 272 | OP(2d) { int tmp; RD_ABS; AND; } /* 4 AND ABS */ | |
| 273 | OP(4d) { int tmp; RD_ABS; EOR; } /* 4 EOR ABS */ | |
| 274 | OP(6d) { int tmp; RD_ABS; ADC; } /* 4 ADC ABS */ | |
| 275 | OP(8d) { int tmp; STA; WR_ABS; } /* 4 STA ABS */ | |
| 276 | OP(ad) { int tmp; RD_ABS; LDA; } /* 4 LDA ABS */ | |
| 277 | OP(cd) { int tmp; RD_ABS; CMP; } /* 4 CMP ABS */ | |
| 278 | OP(ed) { int tmp; RD_ABS; SBC; } /* 4 SBC ABS */ | |
| 279 | ||
| 280 | OP(1d) { int tmp; RD_ABX_P; ORA; } /* 4 ORA ABX page penalty */ | |
| 281 | OP(3d) { int tmp; RD_ABX_P; AND; } /* 4 AND ABX page penalty */ | |
| 282 | OP(5d) { int tmp; RD_ABX_P; EOR; } /* 4 EOR ABX page penalty */ | |
| 283 | OP(7d) { int tmp; RD_ABX_P; ADC; } /* 4 ADC ABX page penalty */ | |
| 284 | OP(9d) { int tmp; STA; WR_ABX_NP; } /* 5 STA ABX */ | |
| 285 | OP(bd) { int tmp; RD_ABX_P; LDA; } /* 4 LDA ABX page penalty */ | |
| 286 | OP(dd) { int tmp; RD_ABX_P; CMP; } /* 4 CMP ABX page penalty */ | |
| 287 | OP(fd) { int tmp; RD_ABX_P; SBC; } /* 4 SBC ABX page penalty */ | |
| 288 | ||
| 289 | OP(0e) { int tmp; RD_ABS; WB_EA; ASL; WB_EA; } /* 6 ASL ABS */ | |
| 290 | OP(2e) { int tmp; RD_ABS; WB_EA; ROL; WB_EA; } /* 6 ROL ABS */ | |
| 291 | OP(4e) { int tmp; RD_ABS; WB_EA; LSR; WB_EA; } /* 6 LSR ABS */ | |
| 292 | OP(6e) { int tmp; RD_ABS; WB_EA; ROR; WB_EA; } /* 6 ROR ABS */ | |
| 293 | OP(8e) { int tmp; STX; WR_ABS; } /* 4 STX ABS */ | |
| 294 | OP(ae) { int tmp; RD_ABS; LDX; } /* 4 LDX ABS */ | |
| 295 | OP(ce) { int tmp; RD_ABS; WB_EA; DEC; WB_EA; } /* 6 DEC ABS */ | |
| 296 | OP(ee) { int tmp; RD_ABS; WB_EA; INC; WB_EA; } /* 6 INC ABS */ | |
| 297 | ||
| 298 | OP(1e) { int tmp; RD_ABX_NP; WB_EA; ASL; WB_EA; } /* 7 ASL ABX */ | |
| 299 | OP(3e) { int tmp; RD_ABX_NP; WB_EA; ROL; WB_EA; } /* 7 ROL ABX */ | |
| 300 | OP(5e) { int tmp; RD_ABX_NP; WB_EA; LSR; WB_EA; } /* 7 LSR ABX */ | |
| 301 | OP(7e) { int tmp; RD_ABX_NP; WB_EA; ROR; WB_EA; } /* 7 ROR ABX */ | |
| 302 | OP(9e) { int tmp; EA_ABY_NP; SXH; WB_EA; } /* 5 SXH ABY */ | |
| 303 | OP(be) { int tmp; RD_ABY_P; LDX; } /* 4 LDX ABY page penalty */ | |
| 304 | OP(de) { int tmp; RD_ABX_NP; WB_EA; DEC; WB_EA; } /* 7 DEC ABX */ | |
| 305 | OP(fe) { int tmp; RD_ABX_NP; WB_EA; INC; WB_EA; } /* 7 INC ABX */ | |
| 306 | ||
| 307 | OP(0f) { int tmp; RD_ABS; WB_EA; SLO; WB_EA; } /* 6 SLO ABS */ | |
| 308 | OP(2f) { int tmp; RD_ABS; WB_EA; RLA; WB_EA; } /* 6 RLA ABS */ | |
| 309 | OP(4f) { int tmp; RD_ABS; WB_EA; SRE; WB_EA; } /* 6 SRE ABS */ | |
| 310 | OP(6f) { int tmp; RD_ABS; WB_EA; RRA; WB_EA; } /* 6 RRA ABS */ | |
| 311 | OP(8f) { int tmp; SAX; WR_ABS; } /* 4 SAX ABS */ | |
| 312 | OP(af) { int tmp; RD_ABS; LAX; } /* 4 LAX ABS */ | |
| 313 | OP(cf) { int tmp; RD_ABS; WB_EA; DCP; WB_EA; } /* 6 DCP ABS */ | |
| 314 | OP(ef) { int tmp; RD_ABS; WB_EA; ISB; WB_EA; } /* 6 ISB ABS */ | |
| 315 | ||
| 316 | OP(1f) { int tmp; RD_ABX_NP; WB_EA; SLO; WB_EA; } /* 7 SLO ABX */ | |
| 317 | OP(3f) { int tmp; RD_ABX_NP; WB_EA; RLA; WB_EA; } /* 7 RLA ABX */ | |
| 318 | OP(5f) { int tmp; RD_ABX_NP; WB_EA; SRE; WB_EA; } /* 7 SRE ABX */ | |
| 319 | OP(7f) { int tmp; RD_ABX_NP; WB_EA; RRA; WB_EA; } /* 7 RRA ABX */ | |
| 320 | OP(9f) { int tmp; EA_ABY_NP; SAH; WB_EA; } /* 5 SAH ABY */ | |
| 321 | OP(bf) { int tmp; RD_ABY_P; LAX; } /* 4 LAX ABY page penalty */ | |
| 322 | OP(df) { int tmp; RD_ABX_NP; WB_EA; DCP; WB_EA; } /* 7 DCP ABX */ | |
| 323 | OP(ff) { int tmp; RD_ABX_NP; WB_EA; ISB; WB_EA; } /* 7 ISB ABX */ | |
| 324 | ||
| 325 | /* and here's the array of function pointers */ | |
| 326 | ||
| 327 | static void (*const insn6510[0x100])(m6502_Regs *cpustate) = { | |
| 328 | m6510_00,m6510_01,m6510_02,m6510_03,m6510_04,m6510_05,m6510_06,m6510_07, | |
| 329 | m6510_08,m6510_09,m6510_0a,m6510_0b,m6510_0c,m6510_0d,m6510_0e,m6510_0f, | |
| 330 | m6510_10,m6510_11,m6510_12,m6510_13,m6510_14,m6510_15,m6510_16,m6510_17, | |
| 331 | m6510_18,m6510_19,m6510_1a,m6510_1b,m6510_1c,m6510_1d,m6510_1e,m6510_1f, | |
| 332 | m6510_20,m6510_21,m6510_22,m6510_23,m6510_24,m6510_25,m6510_26,m6510_27, | |
| 333 | m6510_28,m6510_29,m6510_2a,m6510_2b,m6510_2c,m6510_2d,m6510_2e,m6510_2f, | |
| 334 | m6510_30,m6510_31,m6510_32,m6510_33,m6510_34,m6510_35,m6510_36,m6510_37, | |
| 335 | m6510_38,m6510_39,m6510_3a,m6510_3b,m6510_3c,m6510_3d,m6510_3e,m6510_3f, | |
| 336 | m6510_40,m6510_41,m6510_42,m6510_43,m6510_44,m6510_45,m6510_46,m6510_47, | |
| 337 | m6510_48,m6510_49,m6510_4a,m6510_4b,m6510_4c,m6510_4d,m6510_4e,m6510_4f, | |
| 338 | m6510_50,m6510_51,m6510_52,m6510_53,m6510_54,m6510_55,m6510_56,m6510_57, | |
| 339 | m6510_58,m6510_59,m6510_5a,m6510_5b,m6510_5c,m6510_5d,m6510_5e,m6510_5f, | |
| 340 | m6510_60,m6510_61,m6510_62,m6510_63,m6510_64,m6510_65,m6510_66,m6510_67, | |
| 341 | m6510_68,m6510_69,m6510_6a,m6510_6b,m6510_6c,m6510_6d,m6510_6e,m6510_6f, | |
| 342 | m6510_70,m6510_71,m6510_72,m6510_73,m6510_74,m6510_75,m6510_76,m6510_77, | |
| 343 | m6510_78,m6510_79,m6510_7a,m6510_7b,m6510_7c,m6510_7d,m6510_7e,m6510_7f, | |
| 344 | m6510_80,m6510_81,m6510_82,m6510_83,m6510_84,m6510_85,m6510_86,m6510_87, | |
| 345 | m6510_88,m6510_89,m6510_8a,m6510_8b,m6510_8c,m6510_8d,m6510_8e,m6510_8f, | |
| 346 | m6510_90,m6510_91,m6510_92,m6510_93,m6510_94,m6510_95,m6510_96,m6510_97, | |
| 347 | m6510_98,m6510_99,m6510_9a,m6510_9b,m6510_9c,m6510_9d,m6510_9e,m6510_9f, | |
| 348 | m6510_a0,m6510_a1,m6510_a2,m6510_a3,m6510_a4,m6510_a5,m6510_a6,m6510_a7, | |
| 349 | m6510_a8,m6510_a9,m6510_aa,m6510_ab,m6510_ac,m6510_ad,m6510_ae,m6510_af, | |
| 350 | m6510_b0,m6510_b1,m6510_b2,m6510_b3,m6510_b4,m6510_b5,m6510_b6,m6510_b7, | |
| 351 | m6510_b8,m6510_b9,m6510_ba,m6510_bb,m6510_bc,m6510_bd,m6510_be,m6510_bf, | |
| 352 | m6510_c0,m6510_c1,m6510_c2,m6510_c3,m6510_c4,m6510_c5,m6510_c6,m6510_c7, | |
| 353 | m6510_c8,m6510_c9,m6510_ca,m6510_cb,m6510_cc,m6510_cd,m6510_ce,m6510_cf, | |
| 354 | m6510_d0,m6510_d1,m6510_d2,m6510_d3,m6510_d4,m6510_d5,m6510_d6,m6510_d7, | |
| 355 | m6510_d8,m6510_d9,m6510_da,m6510_db,m6510_dc,m6510_dd,m6510_de,m6510_df, | |
| 356 | m6510_e0,m6510_e1,m6510_e2,m6510_e3,m6510_e4,m6510_e5,m6510_e6,m6510_e7, | |
| 357 | m6510_e8,m6510_e9,m6510_ea,m6510_eb,m6510_ec,m6510_ed,m6510_ee,m6510_ef, | |
| 358 | m6510_f0,m6510_f1,m6510_f2,m6510_f3,m6510_f4,m6510_f5,m6510_f6,m6510_f7, | |
| 359 | m6510_f8,m6510_f9,m6510_fa,m6510_fb,m6510_fc,m6510_fd,m6510_fe,m6510_ff | |
| 360 | }; | |
| 361 |
| r18874 | r18875 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * opsce02.h | |
| 4 | * Addressing mode and opcode macros for 65ce02 CPU | |
| 5 | * | |
| 6 | * Copyright Peter Trauner, all rights reserved. | |
| 7 | * documentation preliminary databook | |
| 8 | * documentation by michael steil mist@c64.org | |
| 9 | * available at ftp://ftp.funet.fi/pub/cbm/c65 | |
| 10 | * | |
| 11 | * - This source code is released as freeware for non-commercial purposes. | |
| 12 | * - You are free to use and redistribute this code in modified or | |
| 13 | * unmodified form, provided you list me in the credits. | |
| 14 | * - If you modify this source code, you must add a notice to each modified | |
| 15 | * source file that it has been changed. If you're a nice person, you | |
| 16 | * will clearly mark each change too. :) | |
| 17 | * - If you wish to use this for commercial purposes, please contact me at | |
| 18 | * pullmoll@t-online.de | |
| 19 | * - The author of this copywritten work reserves the right to change the | |
| 20 | * terms of its usage and license at any time, including retroactively | |
| 21 | * - This entire notice must remain in the source code. | |
| 22 | * | |
| 23 | *****************************************************************************/ | |
| 24 | ||
| 25 | ||
| 26 | #define SET_NZ(n) if ((n) == 0) P = (P & ~F_N) | F_Z; else P = (P & ~(F_N | F_Z)) | ((n) & F_N) | |
| 27 | #define SET_Z(n) if ((n) == 0) P |= F_Z; else P &= ~F_Z | |
| 28 | ||
| 29 | #define RDMEM_WORD(addr, pair) pair.b.l=RDMEM( addr ); pair.b.h=RDMEM( (addr+1) & 0xffff ) | |
| 30 | #define WRMEM_WORD(addr,pair) WRMEM(addr,pair.b.l); WRMEM((addr+1)&0xffff,pair.b.h) | |
| 31 | ||
| 32 | #define SET_NZ_WORD(n) \ | |
| 33 | if( n.w.l == 0 ) \ | |
| 34 | P = (P & ~F_N) | F_Z; \ | |
| 35 | else \ | |
| 36 | P = (P & ~(F_N | F_Z)) | ((n.b.h) & F_N) | |
| 37 | ||
| 38 | /*************************************************************** | |
| 39 | * EA = absolute address | |
| 40 | ***************************************************************/ | |
| 41 | #define EA_ABS \ | |
| 42 | EAL = RDOPARG(); \ | |
| 43 | EAH = RDOPARG() | |
| 44 | ||
| 45 | /*************************************************************** | |
| 46 | * EA = absolute address + X | |
| 47 | ***************************************************************/ | |
| 48 | #define EA_ABX \ | |
| 49 | EA_ABS; \ | |
| 50 | EAW += X | |
| 51 | ||
| 52 | /*************************************************************** | |
| 53 | * EA = absolute address + Y | |
| 54 | * one additional read if page boundary is crossed | |
| 55 | ***************************************************************/ | |
| 56 | #define EA_ABY \ | |
| 57 | EA_ABS; \ | |
| 58 | EAW += Y; | |
| 59 | ||
| 60 | /*************************************************************** | |
| 61 | * EA = zero page address | |
| 62 | ***************************************************************/ | |
| 63 | #define EA_ZPG \ | |
| 64 | ZPL = RDOPARG(); \ | |
| 65 | EAD = ZPD | |
| 66 | ||
| 67 | /*************************************************************** | |
| 68 | * EA = zero page address + X | |
| 69 | ***************************************************************/ | |
| 70 | #define EA_ZPX \ | |
| 71 | ZPL = RDOPARG(); \ | |
| 72 | ZPL = X + ZPL; \ | |
| 73 | EAD = ZPD | |
| 74 | ||
| 75 | /*************************************************************** | |
| 76 | * EA = zero page address + Y | |
| 77 | ***************************************************************/ | |
| 78 | #define EA_ZPY \ | |
| 79 | ZPL = RDOPARG(); \ | |
| 80 | ZPL = Y + ZPL; \ | |
| 81 | EAD = ZPD | |
| 82 | ||
| 83 | /*************************************************************** | |
| 84 | * EA = zero page + X indirect (pre indexed) | |
| 85 | ***************************************************************/ | |
| 86 | #define EA_IDX \ | |
| 87 | ZPL = RDOPARG(); \ | |
| 88 | ZPL = ZPL + X; \ | |
| 89 | EAL = RDMEM(ZPD); \ | |
| 90 | ZPL++; \ | |
| 91 | EAH = RDMEM(ZPD) | |
| 92 | ||
| 93 | /*************************************************************** | |
| 94 | * EA = zero page indirect + Y (post indexed) | |
| 95 | ***************************************************************/ | |
| 96 | #define EA_IDY \ | |
| 97 | ZPL = RDOPARG(); \ | |
| 98 | EAL = RDMEM(ZPD); \ | |
| 99 | ZPL++; \ | |
| 100 | EAH = RDMEM(ZPD); \ | |
| 101 | EAW += Y | |
| 102 | ||
| 103 | /*************************************************************** | |
| 104 | * EA = zero page indirect + Z (post indexed) | |
| 105 | * ???? subtract 1 cycle if page boundary is crossed | |
| 106 | ***************************************************************/ | |
| 107 | #define EA_IDZ \ | |
| 108 | ZPL = RDOPARG(); \ | |
| 109 | EAL = RDMEM(ZPD); \ | |
| 110 | ZPL++; \ | |
| 111 | EAH = RDMEM(ZPD); \ | |
| 112 | EAW += Z | |
| 113 | ||
| 114 | /*************************************************************** | |
| 115 | * EA = zero page indexed stack, indirect + Y (post indexed) | |
| 116 | ***************************************************************/ | |
| 117 | #define EA_INSY \ | |
| 118 | { \ | |
| 119 | PAIR pair={{0}}; \ | |
| 120 | pair.b.l = SPL+RDOPARG(); \ | |
| 121 | pair.b.h = SPH; \ | |
| 122 | EAL = RDMEM(pair.d); \ | |
| 123 | if( P & F_E ) \ | |
| 124 | pair.b.l++; \ | |
| 125 | else \ | |
| 126 | pair.w.l++; \ | |
| 127 | EAH = RDMEM(pair.d); \ | |
| 128 | /* RDMEM(PCW-1); */ \ | |
| 129 | EAW += Y; \ | |
| 130 | } | |
| 131 | ||
| 132 | /*************************************************************** | |
| 133 | * EA = indirect (only used by JMP) | |
| 134 | ***************************************************************/ | |
| 135 | #define EA_IND \ | |
| 136 | EA_ABS; \ | |
| 137 | tmp = RDMEM(EAD); \ | |
| 138 | EAL++; \ | |
| 139 | EAH = RDMEM(EAD); \ | |
| 140 | EAL = tmp | |
| 141 | ||
| 142 | /* 65ce02 ****************************************************** | |
| 143 | * EA = indirect plus x (only used by 65c02 JMP) | |
| 144 | ***************************************************************/ | |
| 145 | #define EA_IAX \ | |
| 146 | EA_ABS; \ | |
| 147 | EAW += X; \ | |
| 148 | tmp = RDMEM(EAD); \ | |
| 149 | EAL++; \ | |
| 150 | EAH = RDMEM(EAD); \ | |
| 151 | EAL = tmp | |
| 152 | ||
| 153 | /* read a value into tmp */ | |
| 154 | /* Base number of cycles taken for each mode (including reading of opcode): | |
| 155 | RD_ACC/WR_ACC 0 | |
| 156 | RD_IMM 2 | |
| 157 | RD_DUM 2 | |
| 158 | RD_ABS/WR_ABS 4 | |
| 159 | RD_ABS_WORD/WR_ABS_WORD 5 | |
| 160 | RD_ABX/WR_ABX 4 | |
| 161 | RD_ABY/WR_ABY 4 | |
| 162 | RD_IDX/WR_IDX 5 | |
| 163 | RD_IDY/WR_IDY 5 | |
| 164 | RD_IDZ 5 | |
| 165 | RD_INSY/WR_INSY 6 | |
| 166 | RD_ZPG/WR_ZPG 3 | |
| 167 | RD_ZPG_WORD 4 | |
| 168 | RD_ZPX/WR_ZPX 3 | |
| 169 | RD_ZPY/WR_ZPY 3 | |
| 170 | */ | |
| 171 | #define RD_ACC tmp = A | |
| 172 | #define RD_IMM tmp = RDOPARG() | |
| 173 | #define RD_IMM_WORD tmp.b.l = RDOPARG(); tmp.b.h=RDOPARG() | |
| 174 | #define RD_DUM RDMEM(PCW-1) | |
| 175 | #define RD_ABS EA_ABS; tmp = RDMEM(EAD) | |
| 176 | #define RD_ABS_WORD EA_ABS; RDMEM_WORD(EAD, tmp) | |
| 177 | #define RD_ABX EA_ABX; tmp = RDMEM(EAD) | |
| 178 | #define RD_ABY EA_ABY; tmp = RDMEM(EAD) | |
| 179 | #define RD_IDX EA_IDX; tmp = RDMEM(EAD) | |
| 180 | #define RD_IDY EA_IDY; tmp = RDMEM(EAD) | |
| 181 | #define RD_IDZ EA_IDZ; tmp = RDMEM(EAD) | |
| 182 | #define RD_IDZ_DISCARD EA_IDZ; RDMEM(EAD) | |
| 183 | #define RD_INSY EA_INSY; tmp = RDMEM(EAD) | |
| 184 | #define RD_INSY_DISCARD EA_INSY; RDMEM(EAD) | |
| 185 | #define RD_ZPG EA_ZPG; tmp = RDMEM(EAD) | |
| 186 | #define RD_ZPG_WORD EA_ZPG; RDMEM_WORD(EAD, tmp) | |
| 187 | #define RD_ZPX EA_ZPX; tmp = RDMEM(EAD) | |
| 188 | #define RD_ZPY EA_ZPY; tmp = RDMEM(EAD) | |
| 189 | ||
| 190 | /* write a value from tmp */ | |
| 191 | #define WR_ACC A = (UINT8)tmp | |
| 192 | #define WR_ABS EA_ABS; WRMEM(EAD, tmp) | |
| 193 | #define WR_ABS_WORD EA_ABS; WRMEM_WORD(EAD, tmp) | |
| 194 | #define WR_ABX EA_ABX; WRMEM(EAD, tmp) | |
| 195 | #define WR_ABY EA_ABY; WRMEM(EAD, tmp) | |
| 196 | #define WR_IDX EA_IDX; WRMEM(EAD, tmp) | |
| 197 | #define WR_IDY EA_IDY; WRMEM(EAD, tmp) | |
| 198 | #define WR_INSY EA_INSY; WRMEM(EAD, tmp) | |
| 199 | #define WR_ZPG EA_ZPG; WRMEM(EAD, tmp) | |
| 200 | #define WR_ZPX EA_ZPX; WRMEM(EAD, tmp) | |
| 201 | #define WR_ZPY EA_ZPY; WRMEM(EAD, tmp) | |
| 202 | ||
| 203 | #define WB_EA WRMEM(EAD, tmp) | |
| 204 | #define WB_EA_WORD WRMEM_WORD(EAD, tmp) | |
| 205 | ||
| 206 | /*************************************************************** | |
| 207 | * push a register onto the stack | |
| 208 | ***************************************************************/ | |
| 209 | #define PUSH(Rg) WRMEM(SPD, Rg); if (P&F_E) { SPL--; } else { SW--; } | |
| 210 | ||
| 211 | /*************************************************************** | |
| 212 | * pull a register from the stack | |
| 213 | ***************************************************************/ | |
| 214 | #define PULL(Rg) if (P&F_E) { SPL++; } else { SW++; } Rg = RDMEM(SPD) | |
| 215 | ||
| 216 | /* the order in which the args are pushed is correct! */ | |
| 217 | #define PUSH_WORD(pair) PUSH(pair.b.l);PUSH(pair.b.h) | |
| 218 | ||
| 219 | /* 65ce02 ******************************************************* | |
| 220 | * ADC Add with carry | |
| 221 | * correct setting of flags in decimal mode | |
| 222 | ***************************************************************/ | |
| 223 | #define ADC \ | |
| 224 | if (P & F_D) { \ | |
| 225 | int c = (P & F_C); \ | |
| 226 | int lo = (A & 0x0f) + (tmp & 0x0f) + c; \ | |
| 227 | int hi = (A & 0xf0) + (tmp & 0xf0); \ | |
| 228 | P &= ~(F_V | F_C); \ | |
| 229 | if( lo > 0x09 ) { \ | |
| 230 | hi += 0x10; \ | |
| 231 | lo += 0x06; \ | |
| 232 | } \ | |
| 233 | if( ~(A^tmp) & (A^hi) & F_N ) \ | |
| 234 | P |= F_V; \ | |
| 235 | if( hi > 0x90 ) \ | |
| 236 | hi += 0x60; \ | |
| 237 | if( hi & 0xff00 ) \ | |
| 238 | P |= F_C; \ | |
| 239 | A = (lo & 0x0f) + (hi & 0xf0); \ | |
| 240 | } else { \ | |
| 241 | int c = (P & F_C); \ | |
| 242 | int sum = A + tmp + c; \ | |
| 243 | P &= ~(F_V | F_C); \ | |
| 244 | if( ~(A^tmp) & (A^sum) & F_N ) \ | |
| 245 | P |= F_V; \ | |
| 246 | if( sum & 0xff00 ) \ | |
| 247 | P |= F_C; \ | |
| 248 | A = (UINT8) sum; \ | |
| 249 | } \ | |
| 250 | SET_NZ(A) | |
| 251 | ||
| 252 | /* 65ce02 ****************************************************** | |
| 253 | * AND Logical and | |
| 254 | ***************************************************************/ | |
| 255 | #define AND \ | |
| 256 | A = (UINT8)(A & tmp); \ | |
| 257 | SET_NZ(A) | |
| 258 | ||
| 259 | /* 65ce02 ****************************************************** | |
| 260 | * ASL Arithmetic shift left | |
| 261 | ***************************************************************/ | |
| 262 | #define ASL \ | |
| 263 | P = (P & ~F_C) | ((tmp >> 7) & F_C); \ | |
| 264 | tmp = (UINT8)(tmp << 1); \ | |
| 265 | SET_NZ(tmp) | |
| 266 | ||
| 267 | /* 65ce02 ****************************************************** | |
| 268 | * ASR arithmetic (signed) shift right | |
| 269 | * [7] -> [7][6][5][4][3][2][1][0] -> C | |
| 270 | ***************************************************************/ | |
| 271 | #define ASR_65CE02 \ | |
| 272 | P = (P & ~F_C) | (tmp & F_C); \ | |
| 273 | tmp = (signed char)tmp >> 1; \ | |
| 274 | SET_NZ(tmp) | |
| 275 | ||
| 276 | /* 65ce02 ****************************************************** | |
| 277 | * ASW arithmetic shift left word | |
| 278 | * [c] <- [15]..[6][5][4][3][2][1][0] | |
| 279 | ***************************************************************/ | |
| 280 | /* not sure about how 16 bit memory modifying is executed */ | |
| 281 | #define ASW \ | |
| 282 | tmp.w.l = tmp.w.l << 1; \ | |
| 283 | P = (P & ~F_C) | (tmp.b.h2 & F_C); \ | |
| 284 | SET_NZ_WORD(tmp); | |
| 285 | ||
| 286 | ||
| 287 | /* 65ce02 ****************************************************** | |
| 288 | * augment | |
| 289 | ***************************************************************/ | |
| 290 | #define AUG \ | |
| 291 | t1=RDOPARG(); \ | |
| 292 | t2=RDOPARG(); \ | |
| 293 | t3=RDOPARG(); \ | |
| 294 | logerror("m65ce02 at pc:%.4x reserved op aug %.2x %.2x %.2x\n", cpustate->device->pc(),t1,t2,t3); | |
| 295 | ||
| 296 | /* 65ce02 ****************************************************** | |
| 297 | * BBR Branch if bit is reset | |
| 298 | ***************************************************************/ | |
| 299 | #define BBR(bit) \ | |
| 300 | BRA(!(tmp & (1<<bit))) | |
| 301 | ||
| 302 | /* 65ce02 ****************************************************** | |
| 303 | * BBS Branch if bit is set | |
| 304 | ***************************************************************/ | |
| 305 | #define BBS(bit) \ | |
| 306 | BRA(tmp & (1<<bit)) | |
| 307 | ||
| 308 | /* 65ce02 ****************************************************** | |
| 309 | * BIT Bit test | |
| 310 | ***************************************************************/ | |
| 311 | #undef BIT | |
| 312 | #define BIT \ | |
| 313 | P &= ~(F_N|F_V|F_Z); \ | |
| 314 | P |= tmp & (F_N|F_V); \ | |
| 315 | if ((tmp & A) == 0) \ | |
| 316 | P |= F_Z | |
| 317 | ||
| 318 | /*************************************************************** | |
| 319 | * BRA branch relative | |
| 320 | ***************************************************************/ | |
| 321 | #define BRA(cond) \ | |
| 322 | if (cond) \ | |
| 323 | { \ | |
| 324 | tmp = RDOPARG(); \ | |
| 325 | EAW = PCW + (signed char)tmp; \ | |
| 326 | PCD = EAD; \ | |
| 327 | } \ | |
| 328 | else \ | |
| 329 | { \ | |
| 330 | PCW += 1; \ | |
| 331 | } | |
| 332 | ||
| 333 | /*************************************************************** | |
| 334 | * BRA branch relative | |
| 335 | ***************************************************************/ | |
| 336 | #define BRA_WORD(cond) \ | |
| 337 | if (cond) \ | |
| 338 | { \ | |
| 339 | EAL = RDOPARG(); \ | |
| 340 | EAH = RDOPARG(); \ | |
| 341 | EAW = PCW + (short)(EAW-1); \ | |
| 342 | PCD = EAD; \ | |
| 343 | } \ | |
| 344 | else \ | |
| 345 | { \ | |
| 346 | PCW += 2; \ | |
| 347 | } | |
| 348 | /* 65ce02 ****************************************************** | |
| 349 | * BRK Break | |
| 350 | * increment PC, push PC hi, PC lo, flags (with B bit set), | |
| 351 | * set I flag, jump via IRQ vector | |
| 352 | ***************************************************************/ | |
| 353 | #define BRK \ | |
| 354 | RDOPARG(); \ | |
| 355 | PUSH(PCH); \ | |
| 356 | PUSH(PCL); \ | |
| 357 | PUSH(P | F_B); \ | |
| 358 | P = (P | F_I); \ | |
| 359 | PCL = RDMEM(M6502_IRQ_VEC); \ | |
| 360 | PCH = RDMEM(M6502_IRQ_VEC+1); | |
| 361 | ||
| 362 | /* 65ce02 ******************************************************** | |
| 363 | * BSR Branch to subroutine | |
| 364 | ***************************************************************/ | |
| 365 | #define BSR \ | |
| 366 | EAL = RDOPARG(); \ | |
| 367 | PUSH(PCH); \ | |
| 368 | PUSH(PCL); \ | |
| 369 | EAH = RDOPARG(); \ | |
| 370 | EAW = PCW + (INT16)(EAW-1); \ | |
| 371 | PCD = EAD; | |
| 372 | ||
| 373 | /* 65ce02 ****************************************************** | |
| 374 | * CLC Clear carry flag | |
| 375 | ***************************************************************/ | |
| 376 | #define CLC \ | |
| 377 | P &= ~F_C | |
| 378 | ||
| 379 | /* 65ce02 ****************************************************** | |
| 380 | * CLD Clear decimal flag | |
| 381 | ***************************************************************/ | |
| 382 | #define CLD \ | |
| 383 | P &= ~F_D | |
| 384 | ||
| 385 | /* 65ce02 ****************************************************** | |
| 386 | * cle clear disable extended stack flag | |
| 387 | ***************************************************************/ | |
| 388 | #define CLE \ | |
| 389 | P|=F_E | |
| 390 | ||
| 391 | /* 65ce02 ****************************************************** | |
| 392 | * CLI Clear interrupt flag | |
| 393 | ***************************************************************/ | |
| 394 | #define CLI \ | |
| 395 | if ((IRQ_STATE != CLEAR_LINE) && (P & F_I)) { \ | |
| 396 | AFTER_CLI = 1; \ | |
| 397 | } \ | |
| 398 | P &= ~F_I | |
| 399 | ||
| 400 | /* 65ce02 ****************************************************** | |
| 401 | * CLV Clear overflow flag | |
| 402 | ***************************************************************/ | |
| 403 | #define CLV \ | |
| 404 | P &= ~F_V | |
| 405 | ||
| 406 | /* 65ce02 ****************************************************** | |
| 407 | * CMP Compare accumulator | |
| 408 | ***************************************************************/ | |
| 409 | #define CMP \ | |
| 410 | P &= ~F_C; \ | |
| 411 | if (A >= tmp) \ | |
| 412 | P |= F_C; \ | |
| 413 | SET_NZ((UINT8)(A - tmp)) | |
| 414 | ||
| 415 | /* 65ce02 ****************************************************** | |
| 416 | * CPX Compare index X | |
| 417 | ***************************************************************/ | |
| 418 | #define CPX \ | |
| 419 | P &= ~F_C; \ | |
| 420 | if (X >= tmp) \ | |
| 421 | P |= F_C; \ | |
| 422 | SET_NZ((UINT8)(X - tmp)) | |
| 423 | ||
| 424 | /* 65ce02 ****************************************************** | |
| 425 | * CPY Compare index Y | |
| 426 | ***************************************************************/ | |
| 427 | #define CPY \ | |
| 428 | P &= ~F_C; \ | |
| 429 | if (Y >= tmp) \ | |
| 430 | P |= F_C; \ | |
| 431 | SET_NZ((UINT8)(Y - tmp)) | |
| 432 | ||
| 433 | /* 65ce02 ****************************************************** | |
| 434 | * CPZ Compare index Z | |
| 435 | ***************************************************************/ | |
| 436 | #define CPZ \ | |
| 437 | P &= ~F_C; \ | |
| 438 | if (Z >= tmp) \ | |
| 439 | P |= F_C; \ | |
| 440 | SET_NZ((UINT8)(Z - tmp)) | |
| 441 | ||
| 442 | /* 65ce02 ****************************************************** | |
| 443 | * DEA Decrement accumulator | |
| 444 | ***************************************************************/ | |
| 445 | #define DEA \ | |
| 446 | A = (UINT8)(A - 1); \ | |
| 447 | SET_NZ(A) | |
| 448 | ||
| 449 | /* 65ce02 ****************************************************** | |
| 450 | * DEC Decrement memory | |
| 451 | ***************************************************************/ | |
| 452 | #define DEC \ | |
| 453 | tmp = (UINT8)(tmp-1); \ | |
| 454 | SET_NZ(tmp) | |
| 455 | ||
| 456 | /* 65ce02 ****************************************************** | |
| 457 | * DEW Decrement memory word | |
| 458 | ***************************************************************/ | |
| 459 | #define DEW \ | |
| 460 | tmp.w.l -= 1; \ | |
| 461 | SET_NZ_WORD(tmp) | |
| 462 | ||
| 463 | /* 65ce02 ****************************************************** | |
| 464 | * DEX Decrement index X | |
| 465 | ***************************************************************/ | |
| 466 | #define DEX \ | |
| 467 | X = (UINT8)(X-1); \ | |
| 468 | SET_NZ(X) | |
| 469 | ||
| 470 | /* 65ce02 ****************************************************** | |
| 471 | * DEY Decrement index Y | |
| 472 | ***************************************************************/ | |
| 473 | #define DEY \ | |
| 474 | Y = (UINT8)(Y-1); \ | |
| 475 | SET_NZ(Y) | |
| 476 | ||
| 477 | /* 65ce02 ****************************************************** | |
| 478 | * DEZ Decrement index Z | |
| 479 | ***************************************************************/ | |
| 480 | #define DEZ \ | |
| 481 | Z = (UINT8)(Z-1); \ | |
| 482 | SET_NZ(Z) | |
| 483 | ||
| 484 | /* 65ce02 ****************************************************** | |
| 485 | * EOR Logical exclusive or | |
| 486 | ***************************************************************/ | |
| 487 | #define EOR \ | |
| 488 | A = (UINT8)(A ^ tmp); \ | |
| 489 | SET_NZ(A) | |
| 490 | ||
| 491 | /* 65ce02 ****************************************************** | |
| 492 | * INA Increment accumulator | |
| 493 | ***************************************************************/ | |
| 494 | #define INA \ | |
| 495 | A = (UINT8)(A + 1); \ | |
| 496 | SET_NZ(A) | |
| 497 | ||
| 498 | /* 65ce02 ****************************************************** | |
| 499 | * INC Increment memory | |
| 500 | ***************************************************************/ | |
| 501 | #define INC \ | |
| 502 | tmp = (UINT8)(tmp+1); \ | |
| 503 | SET_NZ(tmp) | |
| 504 | ||
| 505 | /* 65ce02 ****************************************************** | |
| 506 | * INW Increment memory word | |
| 507 | ***************************************************************/ | |
| 508 | #define INW \ | |
| 509 | tmp.w.l += 1; \ | |
| 510 | SET_NZ_WORD(tmp) | |
| 511 | ||
| 512 | /* 65ce02 ****************************************************** | |
| 513 | * INX Increment index X | |
| 514 | ***************************************************************/ | |
| 515 | #define INX \ | |
| 516 | X = (UINT8)(X+1); \ | |
| 517 | SET_NZ(X) | |
| 518 | ||
| 519 | /* 65ce02 ****************************************************** | |
| 520 | * INY Increment index Y | |
| 521 | ***************************************************************/ | |
| 522 | #define INY \ | |
| 523 | Y = (UINT8)(Y+1); \ | |
| 524 | SET_NZ(Y) | |
| 525 | ||
| 526 | /* 65ce02 ****************************************************** | |
| 527 | * INZ Increment index Z | |
| 528 | ***************************************************************/ | |
| 529 | #define INZ \ | |
| 530 | Z = (UINT8)(Z+1); \ | |
| 531 | SET_NZ(Z) | |
| 532 | ||
| 533 | /* 65ce02 ****************************************************** | |
| 534 | * JMP Jump to address | |
| 535 | * set PC to the effective address | |
| 536 | ***************************************************************/ | |
| 537 | #define JMP \ | |
| 538 | PCD = EAD; | |
| 539 | ||
| 540 | /* 65ce02 ****************************************************** | |
| 541 | * JSR Jump to subroutine | |
| 542 | * decrement PC (sic!) push PC hi, push PC lo and set | |
| 543 | * PC to the effective address | |
| 544 | ***************************************************************/ | |
| 545 | #define JSR \ | |
| 546 | EAL = RDOPARG(); \ | |
| 547 | PUSH(PCH); \ | |
| 548 | PUSH(PCL); \ | |
| 549 | EAH = RDOPARG(); \ | |
| 550 | PCD = EAD; | |
| 551 | ||
| 552 | /* 65ce02 ****************************************************** | |
| 553 | * JSR Jump to subroutine | |
| 554 | * decrement PC (sic!) push PC hi, push PC lo and set | |
| 555 | * PC to the effective address | |
| 556 | ***************************************************************/ | |
| 557 | #define JSR_IND \ | |
| 558 | EAL = RDOPARG(); \ | |
| 559 | PUSH(PCH); \ | |
| 560 | PUSH(PCL); \ | |
| 561 | EAH = RDOPARG(); \ | |
| 562 | PCL = RDMEM(EAD); \ | |
| 563 | PCH = RDMEM(EAD+1); | |
| 564 | ||
| 565 | /* 65ce02 ****************************************************** | |
| 566 | * JSR Jump to subroutine | |
| 567 | * decrement PC (sic!) push PC hi, push PC lo and set | |
| 568 | * PC to the effective address | |
| 569 | ***************************************************************/ | |
| 570 | #define JSR_INDX \ | |
| 571 | EAL = RDOPARG()+X; \ | |
| 572 | PUSH(PCH); \ | |
| 573 | PUSH(PCL); \ | |
| 574 | EAH = RDOPARG(); \ | |
| 575 | PCL = RDMEM(EAD); \ | |
| 576 | PCH = RDMEM(EAD+1); | |
| 577 | ||
| 578 | /* 65ce02 ****************************************************** | |
| 579 | * LDA Load accumulator | |
| 580 | ***************************************************************/ | |
| 581 | #define LDA \ | |
| 582 | A = (UINT8)tmp; \ | |
| 583 | SET_NZ(A) | |
| 584 | ||
| 585 | /* 65ce02 ****************************************************** | |
| 586 | * LDX Load index X | |
| 587 | ***************************************************************/ | |
| 588 | #define LDX \ | |
| 589 | X = (UINT8)tmp; \ | |
| 590 | SET_NZ(X) | |
| 591 | ||
| 592 | /* 65ce02 ****************************************************** | |
| 593 | * LDY Load index Y | |
| 594 | ***************************************************************/ | |
| 595 | #define LDY \ | |
| 596 | Y = (UINT8)tmp; \ | |
| 597 | SET_NZ(Y) | |
| 598 | ||
| 599 | /* 65ce02 ****************************************************** | |
| 600 | * LDZ Load index Z | |
| 601 | ***************************************************************/ | |
| 602 | #define LDZ \ | |
| 603 | Z = (UINT8)tmp; \ | |
| 604 | SET_NZ(Z) | |
| 605 | ||
| 606 | /* 65ce02 ****************************************************** | |
| 607 | * LSR Logic shift right | |
| 608 | * 0 -> [7][6][5][4][3][2][1][0] -> C | |
| 609 | ***************************************************************/ | |
| 610 | #define LSR \ | |
| 611 | P = (P & ~F_C) | (tmp & F_C); \ | |
| 612 | tmp = (UINT8)tmp >> 1; \ | |
| 613 | SET_NZ(tmp) | |
| 614 | ||
| 615 | /* 65ce02 ****************************************************** | |
| 616 | * NEG accu | |
| 617 | * twos complement | |
| 618 | ***************************************************************/ | |
| 619 | #define NEG \ | |
| 620 | A= (A^0xff)+1; \ | |
| 621 | SET_NZ(A) | |
| 622 | ||
| 623 | /* 65ce02 ****************************************************** | |
| 624 | * NOP No operation | |
| 625 | ***************************************************************/ | |
| 626 | #define NOP | |
| 627 | ||
| 628 | /* 65ce02 ****************************************************** | |
| 629 | * ORA Logical inclusive or | |
| 630 | ***************************************************************/ | |
| 631 | #define ORA \ | |
| 632 | A = (UINT8)(A | tmp); \ | |
| 633 | SET_NZ(A) | |
| 634 | ||
| 635 | /* 65ce02 ****************************************************** | |
| 636 | * PHA Push accumulator | |
| 637 | ***************************************************************/ | |
| 638 | #define PHA \ | |
| 639 | PUSH(A) | |
| 640 | ||
| 641 | /* 65ce02 ****************************************************** | |
| 642 | * PHP Push processor status (flags) | |
| 643 | ***************************************************************/ | |
| 644 | #define PHP \ | |
| 645 | PUSH(P) | |
| 646 | ||
| 647 | /* 65ce02 ****************************************************** | |
| 648 | * PHX Push index X | |
| 649 | ***************************************************************/ | |
| 650 | #define PHX \ | |
| 651 | PUSH(X) | |
| 652 | ||
| 653 | /* 65ce02 ****************************************************** | |
| 654 | * PHY Push index Y | |
| 655 | ***************************************************************/ | |
| 656 | #define PHY \ | |
| 657 | PUSH(Y) | |
| 658 | ||
| 659 | /* 65ce02 ****************************************************** | |
| 660 | * PHZ Push index z | |
| 661 | ***************************************************************/ | |
| 662 | #define PHZ \ | |
| 663 | PUSH(Z) | |
| 664 | ||
| 665 | /* 65ce02 ****************************************************** | |
| 666 | * PLA Pull accumulator | |
| 667 | ***************************************************************/ | |
| 668 | #define PLA \ | |
| 669 | PULL(A); \ | |
| 670 | SET_NZ(A) | |
| 671 | ||
| 672 | /* 65ce02 ****************************************************** | |
| 673 | * PLP Pull processor status (flags) | |
| 674 | ***************************************************************/ | |
| 675 | #define PLP \ | |
| 676 | if ( P & F_I ) { \ | |
| 677 | UINT8 temp; \ | |
| 678 | PULL(temp); \ | |
| 679 | P=(P&F_E)|F_B|(temp&~F_E); \ | |
| 680 | if( IRQ_STATE != CLEAR_LINE && !(P & F_I) ) { \ | |
| 681 | LOG(("M65ce02 '%s' PLP sets after_cli\n", cpustate->device->tag())); \ | |
| 682 | AFTER_CLI = 1; \ | |
| 683 | } \ | |
| 684 | } else { \ | |
| 685 | UINT8 temp; \ | |
| 686 | PULL(temp); \ | |
| 687 | P=(P&F_E)|F_B|(temp&~F_E); \ | |
| 688 | } | |
| 689 | ||
| 690 | /* 65ce02 ****************************************************** | |
| 691 | * PLX Pull index X | |
| 692 | ***************************************************************/ | |
| 693 | #define PLX \ | |
| 694 | PULL(X); \ | |
| 695 | SET_NZ(X) | |
| 696 | ||
| 697 | /* 65ce02 ****************************************************** | |
| 698 | * PLY Pull index Y | |
| 699 | ***************************************************************/ | |
| 700 | #define PLY \ | |
| 701 | PULL(Y); \ | |
| 702 | SET_NZ(Y) | |
| 703 | ||
| 704 | /* 65ce02 ****************************************************** | |
| 705 | * PLZ Pull index Z | |
| 706 | ***************************************************************/ | |
| 707 | #define PLZ \ | |
| 708 | PULL(Z); \ | |
| 709 | SET_NZ(Z) | |
| 710 | ||
| 711 | /* 65ce02 ****************************************************** | |
| 712 | * RMB Reset memory bit | |
| 713 | ***************************************************************/ | |
| 714 | #define RMB(bit) \ | |
| 715 | tmp &= ~(1<<bit) | |
| 716 | ||
| 717 | /* 65ce02 ****************************************************** | |
| 718 | * ROL Rotate left | |
| 719 | * new C <- [7][6][5][4][3][2][1][0] <- C | |
| 720 | ***************************************************************/ | |
| 721 | #define ROL \ | |
| 722 | tmp = (tmp << 1) | (P & F_C); \ | |
| 723 | P = (P & ~F_C) | ((tmp >> 8) & F_C); \ | |
| 724 | tmp = (UINT8)tmp; \ | |
| 725 | SET_NZ(tmp) | |
| 726 | ||
| 727 | /* 65ce02 ****************************************************** | |
| 728 | * ROR Rotate right | |
| 729 | * C -> [7][6][5][4][3][2][1][0] -> new C | |
| 730 | ***************************************************************/ | |
| 731 | #define ROR \ | |
| 732 | tmp |= (P & F_C) << 8; \ | |
| 733 | P = (P & ~F_C) | (tmp & F_C); \ | |
| 734 | tmp = (UINT8)(tmp >> 1); \ | |
| 735 | SET_NZ(tmp) | |
| 736 | ||
| 737 | /* 65ce02 ****************************************************** | |
| 738 | * ROW rotate left word | |
| 739 | * [c] <- [15]..[6][5][4][3][2][1][0] <- C | |
| 740 | ***************************************************************/ | |
| 741 | /* not sure about how 16 bit memory modifying is executed */ | |
| 742 | #define ROW \ | |
| 743 | tmp.d =(tmp.d << 1); \ | |
| 744 | tmp.w.l |= (P & F_C); \ | |
| 745 | P = (P & ~F_C) | (tmp.w.l & F_C); \ | |
| 746 | SET_NZ_WORD(tmp); | |
| 747 | ||
| 748 | ||
| 749 | /* 65ce02 ******************************************************** | |
| 750 | * RTI Return from interrupt | |
| 751 | * pull flags, pull PC lo, pull PC hi | |
| 752 | ***************************************************************/ | |
| 753 | #define RTI \ | |
| 754 | RDMEM(SPD); \ | |
| 755 | PULL(tmp); \ | |
| 756 | P = (P&F_E)|F_B|(tmp&~F_E); \ | |
| 757 | PULL(PCL); \ | |
| 758 | PULL(PCH); \ | |
| 759 | if( IRQ_STATE != CLEAR_LINE && !(P & F_I) ) \ | |
| 760 | { \ | |
| 761 | LOG(("M65ce02 '%s' RTI sets after_cli\n", cpustate->device->tag())); \ | |
| 762 | AFTER_CLI = 1; \ | |
| 763 | } | |
| 764 | ||
| 765 | /* 65ce02 ****************************************************** | |
| 766 | * RTS Return from subroutine | |
| 767 | * pull PC lo, PC hi and increment PC | |
| 768 | ***************************************************************/ | |
| 769 | #define RTS \ | |
| 770 | PULL(PCL); \ | |
| 771 | PULL(PCH); \ | |
| 772 | RDMEM(PCW); PCW++; | |
| 773 | ||
| 774 | /* 65ce02 ****************************************************** | |
| 775 | * RTS imm | |
| 776 | * Is the stack adjustment done before or after the return actions? | |
| 777 | * Exact order of the read instructions unknown | |
| 778 | ***************************************************************/ | |
| 779 | #define RTN \ | |
| 780 | if (P&F_E) { \ | |
| 781 | SPL+=tmp; \ | |
| 782 | } else { \ | |
| 783 | SW+=tmp; \ | |
| 784 | } \ | |
| 785 | RDMEM(PCW-1); \ | |
| 786 | RDMEM(PCW-1); \ | |
| 787 | RDMEM(SPD); \ | |
| 788 | P = (P&F_E)|F_B|(tmp&~F_E); \ | |
| 789 | PULL(PCL); \ | |
| 790 | PULL(PCH); \ | |
| 791 | if( IRQ_STATE != CLEAR_LINE && !(P & F_I) ) { \ | |
| 792 | LOG(("M65ce02 '%s' RTI sets after_cli\n", cpustate->device->tag())); \ | |
| 793 | AFTER_CLI = 1; \ | |
| 794 | } | |
| 795 | ||
| 796 | ||
| 797 | /* 65ce02 ******************************************************* | |
| 798 | * SBC Subtract with carry | |
| 799 | * correct setting of flags in decimal mode | |
| 800 | ***************************************************************/ | |
| 801 | #define SBC \ | |
| 802 | if (P & F_D) { \ | |
| 803 | int c = (P & F_C) ^ F_C; \ | |
| 804 | int sum = A - tmp - c; \ | |
| 805 | int lo = (A & 0x0f) - (tmp & 0x0f) - c; \ | |
| 806 | int hi = (A & 0xf0) - (tmp & 0xf0); \ | |
| 807 | P &= ~(F_V | F_C); \ | |
| 808 | if( (A^tmp) & (A^sum) & F_N ) \ | |
| 809 | P |= F_V; \ | |
| 810 | if( lo & 0xf0 ) \ | |
| 811 | lo -= 6; \ | |
| 812 | if( lo & 0x80 ) \ | |
| 813 | hi -= 0x10; \ | |
| 814 | if( hi & 0x0f00 ) \ | |
| 815 | hi -= 0x60; \ | |
| 816 | if( (sum & 0xff00) == 0 ) \ | |
| 817 | P |= F_C; \ | |
| 818 | A = (lo & 0x0f) + (hi & 0xf0); \ | |
| 819 | } else { \ | |
| 820 | int c = (P & F_C) ^ F_C; \ | |
| 821 | int sum = A - tmp - c; \ | |
| 822 | P &= ~(F_V | F_C); \ | |
| 823 | if( (A^tmp) & (A^sum) & F_N ) \ | |
| 824 | P |= F_V; \ | |
| 825 | if( (sum & 0xff00) == 0 ) \ | |
| 826 | P |= F_C; \ | |
| 827 | A = (UINT8) sum; \ | |
| 828 | } \ | |
| 829 | SET_NZ(A) | |
| 830 | ||
| 831 | /* 65ce02 ****************************************************** | |
| 832 | * SEC Set carry flag | |
| 833 | ***************************************************************/ | |
| 834 | #if defined(SEC) | |
| 835 | #undef SEC | |
| 836 | #endif | |
| 837 | #define SEC \ | |
| 838 | P |= F_C | |
| 839 | ||
| 840 | /* 65ce02 ****************************************************** | |
| 841 | * SED Set decimal flag | |
| 842 | ***************************************************************/ | |
| 843 | #define SED \ | |
| 844 | P |= F_D | |
| 845 | ||
| 846 | /* 65ce02 ****************************************************** | |
| 847 | * see set disable extended stack flag | |
| 848 | ***************************************************************/ | |
| 849 | #define SEE \ | |
| 850 | P&=~F_E | |
| 851 | ||
| 852 | /* 65ce02 ****************************************************** | |
| 853 | * SEI Set interrupt flag | |
| 854 | ***************************************************************/ | |
| 855 | #define SEI \ | |
| 856 | P |= F_I | |
| 857 | ||
| 858 | /* 65ce02 ****************************************************** | |
| 859 | * SMB Set memory bit | |
| 860 | ***************************************************************/ | |
| 861 | #define SMB(bit) \ | |
| 862 | tmp |= (1<<bit) | |
| 863 | ||
| 864 | /* 65ce02 ****************************************************** | |
| 865 | * STA Store accumulator | |
| 866 | ***************************************************************/ | |
| 867 | #define STA \ | |
| 868 | tmp = A | |
| 869 | ||
| 870 | /* 65ce02 ****************************************************** | |
| 871 | * STX Store index X | |
| 872 | ***************************************************************/ | |
| 873 | #define STX \ | |
| 874 | tmp = X | |
| 875 | ||
| 876 | /* 65ce02 ****************************************************** | |
| 877 | * STY Store index Y | |
| 878 | ***************************************************************/ | |
| 879 | #define STY \ | |
| 880 | tmp = Y | |
| 881 | ||
| 882 | /* 65ce02 ****************************************************** | |
| 883 | * STZ Store index Z | |
| 884 | ***************************************************************/ | |
| 885 | #define STZ_65CE02 \ | |
| 886 | tmp = Z | |
| 887 | ||
| 888 | /* 65ce02 ****************************************************** | |
| 889 | * TAB Transfer accumulator to Direct Page | |
| 890 | ***************************************************************/ | |
| 891 | #define TAB \ | |
| 892 | B = A; \ | |
| 893 | SET_NZ(B) | |
| 894 | ||
| 895 | /* 65ce02 ****************************************************** | |
| 896 | * TAX Transfer accumulator to index X | |
| 897 | ***************************************************************/ | |
| 898 | #define TAX \ | |
| 899 | X = A; \ | |
| 900 | SET_NZ(X) | |
| 901 | ||
| 902 | /* 65ce02 ****************************************************** | |
| 903 | * TAY Transfer accumulator to index Y | |
| 904 | ***************************************************************/ | |
| 905 | #define TAY \ | |
| 906 | Y = A; \ | |
| 907 | SET_NZ(Y) | |
| 908 | ||
| 909 | /* 65ce02 ****************************************************** | |
| 910 | * TAZ Transfer accumulator to index z | |
| 911 | ***************************************************************/ | |
| 912 | #define TAZ \ | |
| 913 | Z = A; \ | |
| 914 | SET_NZ(Z) | |
| 915 | ||
| 916 | /* 65ce02 ****************************************************** | |
| 917 | * TBA Transfer direct page to accumulator | |
| 918 | ***************************************************************/ | |
| 919 | #define TBA \ | |
| 920 | A = B; \ | |
| 921 | SET_NZ(A) | |
| 922 | ||
| 923 | /* 65ce02 ****************************************************** | |
| 924 | * TRB Test and reset bits | |
| 925 | ***************************************************************/ | |
| 926 | #define TRB \ | |
| 927 | SET_Z(tmp&A); \ | |
| 928 | tmp &= ~A | |
| 929 | ||
| 930 | /* 65ce02 ****************************************************** | |
| 931 | * TSB Test and set bits | |
| 932 | ***************************************************************/ | |
| 933 | #define TSB \ | |
| 934 | SET_Z(tmp&A); \ | |
| 935 | tmp |= A | |
| 936 | ||
| 937 | /* 65ce02 ****************************************************** | |
| 938 | * TSX Transfer stack LSB to index X | |
| 939 | ***************************************************************/ | |
| 940 | #define TSX \ | |
| 941 | X = SPL; \ | |
| 942 | SET_NZ(X) | |
| 943 | ||
| 944 | /* 65ce02 ****************************************************** | |
| 945 | * TSY Transfer stack pointer to index y | |
| 946 | ***************************************************************/ | |
| 947 | #define TSY \ | |
| 948 | Y = SPH; \ | |
| 949 | SET_NZ(Y) | |
| 950 | ||
| 951 | /* 65ce02 ****************************************************** | |
| 952 | * TXA Transfer index X to accumulator | |
| 953 | ***************************************************************/ | |
| 954 | #define TXA \ | |
| 955 | A = X; \ | |
| 956 | SET_NZ(A) | |
| 957 | ||
| 958 | /* 65ce02 ******************************************************** | |
| 959 | * TXS Transfer index X to stack LSB | |
| 960 | * no flags changed (sic!) | |
| 961 | * txs tys not interruptable | |
| 962 | ***************************************************************/ | |
| 963 | #define TXS \ | |
| 964 | SPL = X; \ | |
| 965 | if (PEEK_OP() == 0x2b /*TYS*/ ) { \ | |
| 966 | UINT8 op = RDOP(); \ | |
| 967 | (*cpustate->insn[op])(cpustate); \ | |
| 968 | } | |
| 969 | ||
| 970 | ||
| 971 | /* 65ce02 ****************************************************** | |
| 972 | * TYA Transfer index Y to accumulator | |
| 973 | ***************************************************************/ | |
| 974 | #define TYA \ | |
| 975 | A = Y; \ | |
| 976 | SET_NZ(A) | |
| 977 | ||
| 978 | /* 65ce02 ****************************************************** | |
| 979 | * TYS Transfer index y to stack pointer | |
| 980 | ***************************************************************/ | |
| 981 | #define TYS \ | |
| 982 | SPH = Y; | |
| 983 | ||
| 984 | /* 65ce02 ****************************************************** | |
| 985 | * TZA Transfer index z to accumulator | |
| 986 | ***************************************************************/ | |
| 987 | #define TZA \ | |
| 988 | A = Z; \ | |
| 989 | SET_NZ(A) |
| r18874 | r18875 | |
|---|---|---|
| 1 | #pragma once | |
| 2 | ||
| 3 | #ifndef __ILL02_H__ | |
| 4 | #define __ILL02_H__ | |
| 5 | ||
| 6 | /***************************************************************************** | |
| 7 | * | |
| 8 | * ill02.h | |
| 9 | * Addressing mode and opcode macros for the NMOS 6502 illegal opcodes | |
| 10 | * | |
| 11 | * Copyright Juergen Buchmueller, all rights reserved. | |
| 12 | * 65sc02 core Copyright Peter Trauner, all rights reserved. | |
| 13 | * | |
| 14 | * - This source code is released as freeware for non-commercial purposes. | |
| 15 | * - You are free to use and redistribute this code in modified or | |
| 16 | * unmodified form, provided you list me in the credits. | |
| 17 | * - If you modify this source code, you must add a notice to each modified | |
| 18 | * source file that it has been changed. If you're a nice person, you | |
| 19 | * will clearly mark each change too. :) | |
| 20 | * - If you wish to use this for commercial purposes, please contact me at | |
| 21 | * pullmoll@t-online.de | |
| 22 | * - The author of this copywritten work reserves the right to change the | |
| 23 | * terms of its usage and license at any time, including retroactively | |
| 24 | * - This entire notice must remain in the source code. | |
| 25 | * | |
| 26 | *****************************************************************************/ | |
| 27 | ||
| 28 | /* test with the excellent C64 Emulator test suite | |
| 29 | ? at www.funet.fi/pub/cbm/documents/chipdata/tsuit215.zip | |
| 30 | good reference in the vice emulator (source) distribution doc/64doc.txt | |
| 31 | ||
| 32 | $ab=OAL like in 6502-NMOS.extra.opcodes, vice so in vice (lxa) | |
| 33 | */ | |
| 34 | ||
| 35 | /*************************************************************** | |
| 36 | *************************************************************** | |
| 37 | * Macros to emulate the 6510 opcodes | |
| 38 | *************************************************************** | |
| 39 | ***************************************************************/ | |
| 40 | ||
| 41 | /* 6510 ******************************************************** | |
| 42 | * ANC logical and, set carry from bit of A | |
| 43 | ***************************************************************/ | |
| 44 | #define ANC \ | |
| 45 | P &= ~F_C; \ | |
| 46 | A = (UINT8)(A & tmp); \ | |
| 47 | if (A & 0x80) \ | |
| 48 | P |= F_C; \ | |
| 49 | SET_NZ(A) | |
| 50 | ||
| 51 | /* 6510 ******************************************************** | |
| 52 | * ASR logical and, logical shift right | |
| 53 | ***************************************************************/ | |
| 54 | #define ASR \ | |
| 55 | tmp &= A; \ | |
| 56 | LSR | |
| 57 | ||
| 58 | /* 6510 ******************************************************** | |
| 59 | * AST and stack; transfer to accumulator and index X | |
| 60 | * logical and stack (LSB) with data, transfer result to S | |
| 61 | * transfer result to accumulator and index X also | |
| 62 | ***************************************************************/ | |
| 63 | #define AST \ | |
| 64 | S &= tmp; \ | |
| 65 | A = X = S; \ | |
| 66 | SET_NZ(A) | |
| 67 | ||
| 68 | /* 6510 ******************************************************** | |
| 69 | * ARR logical and, rotate right | |
| 70 | ***************************************************************/ | |
| 71 | #define ARR \ | |
| 72 | if( P & F_D ) \ | |
| 73 | { \ | |
| 74 | int lo, hi, t; \ | |
| 75 | tmp &= A; \ | |
| 76 | t = tmp; \ | |
| 77 | hi = tmp &0xf0; \ | |
| 78 | lo = tmp &0x0f; \ | |
| 79 | if( P & F_C ) \ | |
| 80 | { \ | |
| 81 | tmp = (tmp >> 1) | 0x80; \ | |
| 82 | P |= F_N; \ | |
| 83 | } \ | |
| 84 | else \ | |
| 85 | { \ | |
| 86 | tmp >>= 1; \ | |
| 87 | P &= ~F_N; \ | |
| 88 | } \ | |
| 89 | if( tmp ) \ | |
| 90 | P &= ~F_Z; \ | |
| 91 | else \ | |
| 92 | P |= F_Z; \ | |
| 93 | if( (t^tmp) & 0x40 ) \ | |
| 94 | P|=F_V; \ | |
| 95 | else \ | |
| 96 | P &= ~F_V; \ | |
| 97 | if( lo + (lo & 0x01) > 0x05 ) \ | |
| 98 | tmp = (tmp & 0xf0) | ((tmp+6) & 0xf); \ | |
| 99 | if( hi + (hi & 0x10) > 0x50 ) \ | |
| 100 | { \ | |
| 101 | P |= F_C; \ | |
| 102 | tmp = (tmp+0x60) & 0xff; \ | |
| 103 | } \ | |
| 104 | else \ | |
| 105 | P &= ~F_C; \ | |
| 106 | } \ | |
| 107 | else \ | |
| 108 | { \ | |
| 109 | tmp &= A; \ | |
| 110 | ROR; \ | |
| 111 | P &=~(F_V|F_C); \ | |
| 112 | if( tmp & 0x40 ) \ | |
| 113 | P|=F_C; \ | |
| 114 | if( (tmp & 0x60) == 0x20 || (tmp & 0x60) == 0x40 ) \ | |
| 115 | P|=F_V; \ | |
| 116 | } | |
| 117 | ||
| 118 | /* 6510 ******************************************************** | |
| 119 | * ASX logical and X w/ A, subtract data from X | |
| 120 | ***************************************************************/ | |
| 121 | #define ASX \ | |
| 122 | P &= ~F_C; \ | |
| 123 | X &= A; \ | |
| 124 | if (X >= tmp) \ | |
| 125 | P |= F_C; \ | |
| 126 | X = (UINT8)(X - tmp); \ | |
| 127 | SET_NZ(X) | |
| 128 | ||
| 129 | /* 6510 ******************************************************** | |
| 130 | * AXA transfer index X to accumulator, logical and | |
| 131 | * depends on the data of the dma device (videochip) fetched | |
| 132 | * between opcode read and operand read | |
| 133 | ***************************************************************/ | |
| 134 | #define AXA \ | |
| 135 | A = (UINT8)( (A|0xee)& X & tmp); \ | |
| 136 | SET_NZ(A) | |
| 137 | ||
| 138 | /* 6510 ******************************************************** | |
| 139 | * DCP decrement data and compare | |
| 140 | ***************************************************************/ | |
| 141 | #define DCP \ | |
| 142 | tmp = (UINT8)(tmp-1); \ | |
| 143 | P &= ~F_C; \ | |
| 144 | if (A >= tmp) \ | |
| 145 | P |= F_C; \ | |
| 146 | SET_NZ((UINT8)(A - tmp)) | |
| 147 | ||
| 148 | /* 6502 ******************************************************** | |
| 149 | * DOP double no operation | |
| 150 | ***************************************************************/ | |
| 151 | #define DOP \ | |
| 152 | RDOPARG() | |
| 153 | ||
| 154 | /* 6510 ******************************************************** | |
| 155 | * ISB increment and subtract with carry | |
| 156 | ***************************************************************/ | |
| 157 | #define ISB \ | |
| 158 | tmp = (UINT8)(tmp+1); \ | |
| 159 | SBC | |
| 160 | ||
| 161 | /* 6510 ******************************************************** | |
| 162 | * LAX load accumulator and index X | |
| 163 | ***************************************************************/ | |
| 164 | #define LAX \ | |
| 165 | A = X = (UINT8)tmp; \ | |
| 166 | SET_NZ(A) | |
| 167 | ||
| 168 | /* 6502 ******************************************************** | |
| 169 | * OAL load accumulator and index X | |
| 170 | ***************************************************************/ | |
| 171 | #define OAL \ | |
| 172 | A = X = (UINT8)(A&tmp); \ | |
| 173 | SET_NZ(A) | |
| 174 | ||
| 175 | /* 6510 ******************************************************** | |
| 176 | * OAL load accumulator and index X | |
| 177 | ***************************************************************/ | |
| 178 | #define OAL_6510 \ | |
| 179 | A = X = (UINT8)((A|0xee)&tmp); \ | |
| 180 | SET_NZ(A) | |
| 181 | ||
| 182 | /* 6510 ******************************************************** | |
| 183 | * RLA rotate left and logical and accumulator | |
| 184 | * new C <- [7][6][5][4][3][2][1][0] <- C | |
| 185 | ***************************************************************/ | |
| 186 | #define RLA \ | |
| 187 | tmp = (tmp << 1) | (P & F_C); \ | |
| 188 | P = (P & ~F_C) | ((tmp >> 8) & F_C); \ | |
| 189 | tmp = (UINT8)tmp; \ | |
| 190 | A &= tmp; \ | |
| 191 | SET_NZ(A) | |
| 192 | ||
| 193 | /* 6510 ******************************************************** | |
| 194 | * RRA rotate right and add with carry | |
| 195 | * C -> [7][6][5][4][3][2][1][0] -> C | |
| 196 | ***************************************************************/ | |
| 197 | #define RRA \ | |
| 198 | tmp |= (P & F_C) << 8; \ | |
| 199 | P = (P & ~F_C) | (tmp & F_C); \ | |
| 200 | tmp = (UINT8)(tmp >> 1); \ | |
| 201 | ADC | |
| 202 | ||
| 203 | /* 6510 ******************************************************** | |
| 204 | * SAX logical and accumulator with index X and store | |
| 205 | ***************************************************************/ | |
| 206 | #define SAX \ | |
| 207 | tmp = A & X | |
| 208 | ||
| 209 | /* 6510 ******************************************************** | |
| 210 | * SLO shift left and logical or | |
| 211 | ***************************************************************/ | |
| 212 | #define SLO \ | |
| 213 | P = (P & ~F_C) | ((tmp >> 7) & F_C); \ | |
| 214 | tmp = (UINT8)(tmp << 1); \ | |
| 215 | A |= tmp; \ | |
| 216 | SET_NZ(A) | |
| 217 | ||
| 218 | /* 6510 ******************************************************** | |
| 219 | * SRE logical shift right and logical exclusive or | |
| 220 | * 0 -> [7][6][5][4][3][2][1][0] -> C | |
| 221 | ***************************************************************/ | |
| 222 | #define SRE \ | |
| 223 | P = (P & ~F_C) | (tmp & F_C); \ | |
| 224 | tmp = (UINT8)tmp >> 1; \ | |
| 225 | A ^= tmp; \ | |
| 226 | SET_NZ(A) | |
| 227 | ||
| 228 | /* 6510 ******************************************************** | |
| 229 | * SAH store accumulator and index X and high + 1 | |
| 230 | * result = accumulator and index X and memory [PC+1] + 1 | |
| 231 | ***************************************************************/ | |
| 232 | #define SAH tmp = A & X & (EAH+1) | |
| 233 | ||
| 234 | /* 6510 ******************************************************** | |
| 235 | * SSH store stack high | |
| 236 | * logical and accumulator with index X, transfer result to S | |
| 237 | * logical and result with memory [PC+1] + 1 | |
| 238 | ***************************************************************/ | |
| 239 | #define SSH \ | |
| 240 | S = A & X; \ | |
| 241 | tmp = S & (EAH+1) | |
| 242 | #if 0 | |
| 243 | #define SSH \ | |
| 244 | tmp = S = A & X; \ | |
| 245 | tmp &= (UINT8)(cpustate->direct->read_raw_byte((PCW + 1) & 0xffff) + 1) | |
| 246 | #endif | |
| 247 | ||
| 248 | /* 6510 ******************************************************** | |
| 249 | * SXH store index X high | |
| 250 | * logical and index X with memory[PC+1] and store the result | |
| 251 | ***************************************************************/ | |
| 252 | #define SXH tmp = X & (EAH+1) | |
| 253 | ||
| 254 | /* 6510 ******************************************************** | |
| 255 | * SYH store index Y and (high + 1) | |
| 256 | * logical and index Y with memory[PC+1] + 1 and store the result | |
| 257 | ***************************************************************/ | |
| 258 | #define SYH tmp = Y & (EAH+1) | |
| 259 | ||
| 260 | /* 6510 ******************************************************** | |
| 261 | * TOP triple no operation | |
| 262 | ***************************************************************/ | |
| 263 | #define TOP \ | |
| 264 | PCW+=2 | |
| 265 | ||
| 266 | /* 6510 ******************************************************** | |
| 267 | * KIL Illegal opcode | |
| 268 | * processor halted: no hardware interrupt will help, | |
| 269 | * only reset | |
| 270 | ***************************************************************/ | |
| 271 | #define KIL \ | |
| 272 | PCW--; \ | |
| 273 | logerror("M6510 KILL opcode %04x: %02x\n", \ | |
| 274 | PCW, cpustate->direct->read_decrypted_byte(PCW)) | |
| 275 | ||
| 276 | /* N2A03 ******************************************************* | |
| 277 | * ARR logical and, rotate right - no decimal mode | |
| 278 | ***************************************************************/ | |
| 279 | #define ARR_NES \ | |
| 280 | { \ | |
| 281 | tmp &= A; \ | |
| 282 | ROR; \ | |
| 283 | P &=~(F_V|F_C); \ | |
| 284 | if( tmp & 0x40 ) \ | |
| 285 | P|=F_C; \ | |
| 286 | if( (tmp & 0x60) == 0x20 || (tmp & 0x60) == 0x40 ) \ | |
| 287 | P|=F_V; \ | |
| 288 | } | |
| 289 | ||
| 290 | /* N2A03 ******************************************************* | |
| 291 | * ISB increment and subtract with carry | |
| 292 | ***************************************************************/ | |
| 293 | #define ISB_NES \ | |
| 294 | tmp = (UINT8)(tmp+1); \ | |
| 295 | SBC_NES | |
| 296 | ||
| 297 | /* N2A03 ******************************************************* | |
| 298 | * RRA rotate right and add with carry | |
| 299 | * C -> [7][6][5][4][3][2][1][0] -> C | |
| 300 | ***************************************************************/ | |
| 301 | #define RRA_NES \ | |
| 302 | tmp |= (P & F_C) << 8; \ | |
| 303 | P = (P & ~F_C) | (tmp & F_C); \ | |
| 304 | tmp = (UINT8)(tmp >> 1); \ | |
| 305 | ADC_NES | |
| 306 | ||
| 307 | /* N2A03 ******************************************************* | |
| 308 | * OAL load accumulator and index X | |
| 309 | ***************************************************************/ | |
| 310 | #define OAL_NES \ | |
| 311 | A = X = (UINT8)((A|0xff)&tmp); \ | |
| 312 | SET_NZ(A) | |
| 313 | ||
| 314 | /* N2A03 ******************************************************* | |
| 315 | * SXH store index X high | |
| 316 | * logical and index X with memory[PC+1] and store the result | |
| 317 | * | |
| 318 | * This instruction writes to an odd address when crossing | |
| 319 | * a page boundary. The one known test case can be explained | |
| 320 | * with a shift of Y. More testing will be needed to determine | |
| 321 | * if this is correct. | |
| 322 | * | |
| 323 | ***************************************************************/ | |
| 324 | #define SXH_NES \ | |
| 325 | if ( Y && Y > EAL ) \ | |
| 326 | EAH |= ( Y << 1 ); \ | |
| 327 | tmp = X & (EAH+1) | |
| 328 | ||
| 329 | /* N2A03 ******************************************************* | |
| 330 | * SYH store index Y and (high + 1) | |
| 331 | * logical and index Y with memory[PC+1] + 1 and store the result | |
| 332 | * | |
| 333 | * This instruction writs to an odd address when crossing a | |
| 334 | * a page boundary. The one known test case can be explained | |
| 335 | * with a shoft of X. More testing will be needed to determine | |
| 336 | * if this is correct. | |
| 337 | * | |
| 338 | ***************************************************************/ | |
| 339 | #define SYH_NES \ | |
| 340 | if ( X && X > EAL ) \ | |
| 341 | EAH |= ( X << 1 ); \ | |
| 342 | tmp = Y & (EAH+1) | |
| 343 | ||
| 344 | #endif /* __ILL02_H__ */ |
| r18874 | r18875 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * mincce02.h | |
| 4 | * Base macros for 65ce02 CPU files | |
| 5 | * | |
| 6 | *****************************************************************************/ | |
| 7 | ||
| 8 | ||
| 9 | /* 65ce02 flags */ | |
| 10 | #define F_C 0x01 | |
| 11 | #define F_Z 0x02 | |
| 12 | #define F_I 0x04 | |
| 13 | #define F_D 0x08 | |
| 14 | #define F_B 0x10 | |
| 15 | #define F_E 0x20 | |
| 16 | #define F_V 0x40 | |
| 17 | #define F_N 0x80 | |
| 18 | ||
| 19 | /* some shortcuts for improved readability */ | |
| 20 | #define A cpustate->a | |
| 21 | #define X cpustate->x | |
| 22 | #define Y cpustate->y | |
| 23 | #define P cpustate->p | |
| 24 | #define Z cpustate->z | |
| 25 | #define B cpustate->zp.b.h | |
| 26 | #define SW cpustate->sp.w.l | |
| 27 | #define SPL cpustate->sp.b.l | |
| 28 | #define SPH cpustate->sp.b.h | |
| 29 | #define SPD cpustate->sp.d | |
| 30 | ||
| 31 | #define NZ cpustate->nz | |
| 32 | ||
| 33 | #define EAL cpustate->ea.b.l | |
| 34 | #define EAH cpustate->ea.b.h | |
| 35 | #define EAW cpustate->ea.w.l | |
| 36 | #define EAD cpustate->ea.d | |
| 37 | ||
| 38 | #define ZPL cpustate->zp.b.l | |
| 39 | #define ZPH cpustate->zp.b.h | |
| 40 | #define ZPW cpustate->zp.w.l | |
| 41 | #define ZPD cpustate->zp.d | |
| 42 | ||
| 43 | #define PCL cpustate->pc.b.l | |
| 44 | #define PCH cpustate->pc.b.h | |
| 45 | #define PCW cpustate->pc.w.l | |
| 46 | #define PCD cpustate->pc.d | |
| 47 | ||
| 48 | #define PPC cpustate->ppc.d | |
| 49 | ||
| 50 | #define RDMEM_ID(a) cpustate->rdmem_id(*cpustate->space, a) | |
| 51 | #define WRMEM_ID(a,d) cpustate->wrmem_id(*cpustate->space, a, d) | |
| 52 | ||
| 53 | #define IRQ_STATE cpustate->irq_state | |
| 54 | #define AFTER_CLI cpustate->after_cli | |
| 55 | ||
| 56 | /*************************************************************** | |
| 57 | * RDOP read an opcode | |
| 58 | ***************************************************************/ | |
| 59 | #define RDOP() cpustate->direct->read_decrypted_byte(PCW++); cpustate->icount -= 1 | |
| 60 | ||
| 61 | /*************************************************************** | |
| 62 | * RDOPARG read an opcode argument | |
| 63 | ***************************************************************/ | |
| 64 | #define RDOPARG() cpustate->direct->read_raw_byte(PCW++); cpustate->icount -= 1 | |
| 65 | ||
| 66 | #define PEEK_OP() cpustate->direct->read_decrypted_byte(PCW) | |
| 67 | ||
| 68 | #define RDMEM(addr) cpustate->space->read_byte(addr); cpustate->icount -= 1 | |
| 69 | #define WRMEM(addr,data) cpustate->space->write_byte(addr,data); cpustate->icount -= 1 |
| r18874 | r18875 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * ops02.h | |
| 4 | * Addressing mode and opcode macros for 6502,65c02,65sc02,6510,n2a03 CPUs | |
| 5 | * | |
| 6 | * Copyright Juergen Buchmueller, all rights reserved. | |
| 7 | * 65sc02 core Copyright Peter Trauner, all rights reserved. | |
| 8 | * | |
| 9 | * - This source code is released as freeware for non-commercial purposes. | |
| 10 | * - You are free to use and redistribute this code in modified or | |
| 11 | * unmodified form, provided you list me in the credits. | |
| 12 | * - If you modify this source code, you must add a notice to each modified | |
| 13 | * source file that it has been changed. If you're a nice person, you | |
| 14 | * will clearly mark each change too. :) | |
| 15 | * - If you wish to use this for commercial purposes, please contact me at | |
| 16 | * pullmoll@t-online.de | |
| 17 | * - The author of this copywritten work reserves the right to change the | |
| 18 | * terms of its usage and license at any time, including retroactively | |
| 19 | * - This entire notice must remain in the source code. | |
| 20 | * | |
| 21 | *****************************************************************************/ | |
| 22 | ||
| 23 | ||
| 24 | /* 6502 flags */ | |
| 25 | #define F_C 0x01 | |
| 26 | #define F_Z 0x02 | |
| 27 | #define F_I 0x04 | |
| 28 | #define F_D 0x08 | |
| 29 | #define F_B 0x10 | |
| 30 | #define F_T 0x20 | |
| 31 | #define F_V 0x40 | |
| 32 | #define F_N 0x80 | |
| 33 | ||
| 34 | /* some shortcuts for improved readability */ | |
| 35 | #define A cpustate->a | |
| 36 | #define X cpustate->x | |
| 37 | #define Y cpustate->y | |
| 38 | #define P cpustate->p | |
| 39 | #define S cpustate->sp.b.l | |
| 40 | #define SPD cpustate->sp.d | |
| 41 | ||
| 42 | #define NZ cpustate->nz | |
| 43 | ||
| 44 | #define SET_NZ(n) \ | |
| 45 | if ((n) == 0) P = (P & ~F_N) | F_Z; else P = (P & ~(F_N | F_Z)) | ((n) & F_N) | |
| 46 | ||
| 47 | #define SET_Z(n) \ | |
| 48 | if ((n) == 0) P |= F_Z; else P &= ~F_Z | |
| 49 | ||
| 50 | #define EAL cpustate->ea.b.l | |
| 51 | #define EAH cpustate->ea.b.h | |
| 52 | #define EAW cpustate->ea.w.l | |
| 53 | #define EAD cpustate->ea.d | |
| 54 | ||
| 55 | #define ZPL cpustate->zp.b.l | |
| 56 | #define ZPH cpustate->zp.b.h | |
| 57 | #define ZPW cpustate->zp.w.l | |
| 58 | #define ZPD cpustate->zp.d | |
| 59 | ||
| 60 | #define PCL cpustate->pc.b.l | |
| 61 | #define PCH cpustate->pc.b.h | |
| 62 | #define PCW cpustate->pc.w.l | |
| 63 | #define PCD cpustate->pc.d | |
| 64 | ||
| 65 | #define PPC cpustate->ppc.d | |
| 66 | ||
| 67 | #define RDMEM_ID(a) (cpustate->rdmem_id.isnull() ? cpustate->space->read_byte(a) : cpustate->rdmem_id(a)) | |
| 68 | #define WRMEM_ID(a,d) (cpustate->wrmem_id.isnull() ? cpustate->space->write_byte(a,d) : cpustate->wrmem_id(a,d)) | |
| 69 | ||
| 70 | /*************************************************************** | |
| 71 | * RDOP read an opcode | |
| 72 | ***************************************************************/ | |
| 73 | #define RDOP() cpustate->direct->read_decrypted_byte(PCW++); cpustate->icount -= 1 | |
| 74 | #define PEEKOP() cpustate->direct->read_decrypted_byte(PCW) | |
| 75 | ||
| 76 | /*************************************************************** | |
| 77 | * RDOPARG read an opcode argument | |
| 78 | ***************************************************************/ | |
| 79 | #define RDOPARG() cpustate->direct->read_raw_byte(PCW++); cpustate->icount -= 1 | |
| 80 | ||
| 81 | /*************************************************************** | |
| 82 | * RDMEM read memory | |
| 83 | ***************************************************************/ | |
| 84 | #define RDMEM(addr) cpustate->space->read_byte(addr); cpustate->icount -= 1 | |
| 85 | ||
| 86 | /*************************************************************** | |
| 87 | * WRMEM write memory | |
| 88 | ***************************************************************/ | |
| 89 | #define WRMEM(addr,data) cpustate->space->write_byte(addr,data); cpustate->icount -= 1 | |
| 90 | ||
| 91 | /*************************************************************** | |
| 92 | * BRA branch relative | |
| 93 | * extra cycle if page boundary is crossed | |
| 94 | ***************************************************************/ | |
| 95 | #define BRA(cond) \ | |
| 96 | { \ | |
| 97 | INT8 tmp2 = RDOPARG(); \ | |
| 98 | if (cond) \ | |
| 99 | { \ | |
| 100 | RDMEM(PCW); \ | |
| 101 | EAW = PCW + (signed char)tmp2; \ | |
| 102 | if ( EAH != PCH ) { \ | |
| 103 | RDMEM( (PCH << 8 ) | EAL) ; \ | |
| 104 | } \ | |
| 105 | PCD = EAD; \ | |
| 106 | } \ | |
| 107 | } | |
| 108 | ||
| 109 | /*************************************************************** | |
| 110 | * | |
| 111 | * Helper macros to build the effective address | |
| 112 | * | |
| 113 | ***************************************************************/ | |
| 114 | ||
| 115 | /*************************************************************** | |
| 116 | * EA = zero page address | |
| 117 | ***************************************************************/ | |
| 118 | #define EA_ZPG \ | |
| 119 | ZPL = RDOPARG(); \ | |
| 120 | EAD = ZPD | |
| 121 | ||
| 122 | /*************************************************************** | |
| 123 | * EA = zero page address + X | |
| 124 | ***************************************************************/ | |
| 125 | #define EA_ZPX \ | |
| 126 | ZPL = RDOPARG(); \ | |
| 127 | RDMEM(ZPD); \ | |
| 128 | ZPL = X + ZPL; \ | |
| 129 | EAD = ZPD | |
| 130 | ||
| 131 | /*************************************************************** | |
| 132 | * EA = zero page address + Y | |
| 133 | ***************************************************************/ | |
| 134 | #define EA_ZPY \ | |
| 135 | ZPL = RDOPARG(); \ | |
| 136 | RDMEM(ZPD); \ | |
| 137 | ZPL = Y + ZPL; \ | |
| 138 | EAD = ZPD | |
| 139 | ||
| 140 | /*************************************************************** | |
| 141 | * EA = absolute address | |
| 142 | ***************************************************************/ | |
| 143 | #define EA_ABS \ | |
| 144 | EAL = RDOPARG(); \ | |
| 145 | EAH = RDOPARG() | |
| 146 | ||
| 147 | /*************************************************************** | |
| 148 | * EA = absolute address + X | |
| 149 | * one additional read if page boundary is crossed | |
| 150 | ***************************************************************/ | |
| 151 | #define EA_ABX_P \ | |
| 152 | EA_ABS; \ | |
| 153 | if ( EAL + X > 0xff ) { \ | |
| 154 | RDMEM( ( EAH << 8 ) | ( ( EAL + X ) & 0xff ) ); \ | |
| 155 | } \ | |
| 156 | EAW += X; | |
| 157 | ||
| 158 | /*************************************************************** | |
| 159 | * EA = absolute address + X | |
| 160 | ***************************************************************/ | |
| 161 | #define EA_ABX_NP \ | |
| 162 | EA_ABS; \ | |
| 163 | RDMEM( ( EAH << 8 ) | ( ( EAL + X ) & 0xff ) ); \ | |
| 164 | EAW += X | |
| 165 | ||
| 166 | /*************************************************************** | |
| 167 | * EA = absolute address + Y | |
| 168 | * one additional read if page boundary is crossed | |
| 169 | ***************************************************************/ | |
| 170 | #define EA_ABY_P \ | |
| 171 | EA_ABS; \ | |
| 172 | if ( EAL + Y > 0xff ) { \ | |
| 173 | RDMEM( ( EAH << 8 ) | ( ( EAL + Y ) & 0xff ) ); \ | |
| 174 | } \ | |
| 175 | EAW += Y; | |
| 176 | ||
| 177 | /*************************************************************** | |
| 178 | * EA = absolute address + Y | |
| 179 | ***************************************************************/ | |
| 180 | #define EA_ABY_NP \ | |
| 181 | EA_ABS; \ | |
| 182 | RDMEM( ( EAH << 8 ) | ( ( EAL + Y ) & 0xff ) ); \ | |
| 183 | EAW += Y | |
| 184 | ||
| 185 | /*************************************************************** | |
| 186 | * EA = zero page + X indirect (pre indexed) | |
| 187 | ***************************************************************/ | |
| 188 | #define EA_IDX \ | |
| 189 | ZPL = RDOPARG(); \ | |
| 190 | RDMEM(ZPD); \ | |
| 191 | ZPL = ZPL + X; \ | |
| 192 | EAL = RDMEM(ZPD); \ | |
| 193 | ZPL++; \ | |
| 194 | EAH = RDMEM(ZPD) | |
| 195 | ||
| 196 | /*************************************************************** | |
| 197 | * EA = zero page indirect + Y (post indexed) | |
| 198 | * subtract 1 cycle if page boundary is crossed | |
| 199 | ***************************************************************/ | |
| 200 | #define EA_IDY_P \ | |
| 201 | ZPL = RDOPARG(); \ | |
| 202 | EAL = RDMEM(ZPD); \ | |
| 203 | ZPL++; \ | |
| 204 | EAH = RDMEM(ZPD); \ | |
| 205 | if (EAL + Y > 0xff) { \ | |
| 206 | RDMEM( ( EAH << 8 ) | ( ( EAL + Y ) & 0xff ) ); \ | |
| 207 | } \ | |
| 208 | EAW += Y; | |
| 209 | ||
| 210 | /*************************************************************** | |
| 211 | * EA = zero page indirect + Y | |
| 212 | ***************************************************************/ | |
| 213 | #define EA_IDY_NP \ | |
| 214 | ZPL = RDOPARG(); \ | |
| 215 | EAL = RDMEM(ZPD); \ | |
| 216 | ZPL++; \ | |
| 217 | EAH = RDMEM(ZPD); \ | |
| 218 | RDMEM( ( EAH << 8 ) | ( ( EAL + Y ) & 0xff ) ); \ | |
| 219 | EAW += Y | |
| 220 | ||
| 221 | /*************************************************************** | |
| 222 | * EA = zero page indirect (65c02 pre indexed w/o X) | |
| 223 | ***************************************************************/ | |
| 224 | #define EA_ZPI \ | |
| 225 | ZPL = RDOPARG(); \ | |
| 226 | EAL = RDMEM(ZPD); \ | |
| 227 | ZPL++; \ | |
| 228 | EAH = RDMEM(ZPD) | |
| 229 | ||
| 230 | /*************************************************************** | |
| 231 | * EA = indirect (only used by JMP) | |
| 232 | ***************************************************************/ | |
| 233 | #define EA_IND \ | |
| 234 | EA_ABS; \ | |
| 235 | tmp = RDMEM(EAD); \ | |
| 236 | EAL++; /* booby trap: stay in same page! ;-) */ \ | |
| 237 | EAH = RDMEM(EAD); \ | |
| 238 | EAL = tmp | |
| 239 | ||
| 240 | ||
| 241 | /* read a value into tmp */ | |
| 242 | /* Base number of cycles taken for each mode (including reading of opcode): | |
| 243 | RD_IMM 2 | |
| 244 | RD_DUM 2 | |
| 245 | RD_ACC 0 | |
| 246 | RD_ZPG/WR_ZPG 3 | |
| 247 | RD_ZPX/WR_ZPX 4 | |
| 248 | RD_ZPY/WR_ZPY 4 | |
| 249 | RD_ABS/WR_ABS 4 | |
| 250 | RD_ABX_P 4/5 | |
| 251 | RD_ABX_NP/WR_ABX_NP 5 | |
| 252 | RD_ABY_P 4/5 | |
| 253 | RD_ABY_NP/WR_ABY_NP 5 | |
| 254 | RD_IDX/WR_IDX 6 | |
| 255 | RD_IDY_P 5/6 | |
| 256 | RD_IDY_NP/WR_IDY_NP 6 | |
| 257 | RD_ZPI/WR_ZPI 5 | |
| 258 | */ | |
| 259 | #define RD_IMM tmp = RDOPARG() | |
| 260 | #define RD_IMM_DISCARD RDOPARG() | |
| 261 | #define RD_DUM RDMEM(PCW) | |
| 262 | #define RD_ACC tmp = A | |
| 263 | #define RD_ZPG EA_ZPG; tmp = RDMEM(EAD) | |
| 264 | #define RD_ZPG_DISCARD EA_ZPG; RDMEM(EAD) | |
| 265 | #define RD_ZPX EA_ZPX; tmp = RDMEM(EAD) | |
| 266 | #define RD_ZPX_DISCARD EA_ZPX; RDMEM(EAD) | |
| 267 | #define RD_ZPY EA_ZPY; tmp = RDMEM(EAD) | |
| 268 | #define RD_ABS EA_ABS; tmp = RDMEM(EAD) | |
| 269 | #define RD_ABS_DISCARD EA_ABS; RDMEM(EAD) | |
| 270 | #define RD_ABX_P EA_ABX_P; tmp = RDMEM(EAD) | |
| 271 | #define RD_ABX_P_DISCARD EA_ABX_P; RDMEM(EAD); | |
| 272 | #define RD_ABX_NP EA_ABX_NP; tmp = RDMEM(EAD) | |
| 273 | #define RD_ABY_P EA_ABY_P; tmp = RDMEM(EAD) | |
| 274 | #define RD_ABY_NP EA_ABY_NP; tmp = RDMEM(EAD) | |
| 275 | #define RD_IDX EA_IDX; tmp = RDMEM_ID(EAD); cpustate->icount -= 1 | |
| 276 | #define RD_IDY_P EA_IDY_P; tmp = RDMEM_ID(EAD); cpustate->icount -= 1 | |
| 277 | #define RD_IDY_NP EA_IDY_NP; tmp = RDMEM_ID(EAD); cpustate->icount -= 1 | |
| 278 | #define RD_ZPI EA_ZPI; tmp = RDMEM(EAD) | |
| 279 | ||
| 280 | /* write a value from tmp */ | |
| 281 | #define WR_ZPG EA_ZPG; WRMEM(EAD, tmp) | |
| 282 | #define WR_ZPX EA_ZPX; WRMEM(EAD, tmp) | |
| 283 | #define WR_ZPY EA_ZPY; WRMEM(EAD, tmp) | |
| 284 | #define WR_ABS EA_ABS; WRMEM(EAD, tmp) | |
| 285 | #define WR_ABX_NP EA_ABX_NP; WRMEM(EAD, tmp) | |
| 286 | #define WR_ABY_NP EA_ABY_NP; WRMEM(EAD, tmp) | |
| 287 | #define WR_IDX EA_IDX; WRMEM_ID(EAD, tmp); cpustate->icount -= 1 | |
| 288 | #define WR_IDY_NP EA_IDY_NP; WRMEM_ID(EAD, tmp); cpustate->icount -= 1 | |
| 289 | #define WR_ZPI EA_ZPI; WRMEM(EAD, tmp) | |
| 290 | ||
| 291 | /* dummy read from the last EA */ | |
| 292 | #define RD_EA RDMEM(EAD) | |
| 293 | ||
| 294 | /* write back a value from tmp to the last EA */ | |
| 295 | #define WB_ACC A = (UINT8)tmp; | |
| 296 | #define WB_EA WRMEM(EAD, tmp) | |
| 297 | ||
| 298 | /*************************************************************** | |
| 299 | *************************************************************** | |
| 300 | * Macros to emulate the plain 6502 opcodes | |
| 301 | *************************************************************** | |
| 302 | ***************************************************************/ | |
| 303 | ||
| 304 | /*************************************************************** | |
| 305 | * push a register onto the stack | |
| 306 | ***************************************************************/ | |
| 307 | #define PUSH(Rg) WRMEM(SPD, Rg); S-- | |
| 308 | ||
| 309 | /*************************************************************** | |
| 310 | * pull a register from the stack | |
| 311 | ***************************************************************/ | |
| 312 | #define PULL(Rg) S++; Rg = RDMEM(SPD) | |
| 313 | ||
| 314 | /* 6502 ******************************************************** | |
| 315 | * ADC Add with carry | |
| 316 | ***************************************************************/ | |
| 317 | #define ADC \ | |
| 318 | if (P & F_D) { \ | |
| 319 | int c = (P & F_C); \ | |
| 320 | int lo = (A & 0x0f) + (tmp & 0x0f) + c; \ | |
| 321 | int hi = (A & 0xf0) + (tmp & 0xf0); \ | |
| 322 | P &= ~(F_V | F_C|F_N|F_Z); \ | |
| 323 | if (!((lo+hi)&0xff)) P|=F_Z; \ | |
| 324 | if (lo > 0x09) { \ | |
| 325 | hi += 0x10; \ | |
| 326 | lo += 0x06; \ | |
| 327 | } \ | |
| 328 | if (hi&0x80) P|=F_N; \ | |
| 329 | if (~(A^tmp) & (A^hi) & F_N) \ | |
| 330 | P |= F_V; \ | |
| 331 | if (hi > 0x90) \ | |
| 332 | hi += 0x60; \ | |
| 333 | if (hi & 0xff00) \ | |
| 334 | P |= F_C; \ | |
| 335 | A = (lo & 0x0f) + (hi & 0xf0); \ | |
| 336 | } else { \ | |
| 337 | int c = (P & F_C); \ | |
| 338 | int sum = A + tmp + c; \ | |
| 339 | P &= ~(F_V | F_C); \ | |
| 340 | if (~(A^tmp) & (A^sum) & F_N) \ | |
| 341 | P |= F_V; \ | |
| 342 | if (sum & 0xff00) \ | |
| 343 | P |= F_C; \ | |
| 344 | A = (UINT8) sum; \ | |
| 345 | SET_NZ(A); \ | |
| 346 | } | |
| 347 | ||
| 348 | /* 6502 ******************************************************** | |
| 349 | * AND Logical and | |
| 350 | ***************************************************************/ | |
| 351 | #define AND \ | |
| 352 | A = (UINT8)(A & tmp); \ | |
| 353 | SET_NZ(A) | |
| 354 | ||
| 355 | /* 6502 ******************************************************** | |
| 356 | * ASL Arithmetic shift left | |
| 357 | ***************************************************************/ | |
| 358 | #define ASL \ | |
| 359 | P = (P & ~F_C) | ((tmp >> 7) & F_C); \ | |
| 360 | tmp = (UINT8)(tmp << 1); \ | |
| 361 | SET_NZ(tmp) | |
| 362 | ||
| 363 | /* 6502 ******************************************************** | |
| 364 | * BCC Branch if carry clear | |
| 365 | ***************************************************************/ | |
| 366 | #define BCC BRA(!(P & F_C)) | |
| 367 | ||
| 368 | /* 6502 ******************************************************** | |
| 369 | * BCS Branch if carry set | |
| 370 | ***************************************************************/ | |
| 371 | #define BCS BRA(P & F_C) | |
| 372 | ||
| 373 | /* 6502 ******************************************************** | |
| 374 | * BEQ Branch if equal | |
| 375 | ***************************************************************/ | |
| 376 | #define BEQ BRA(P & F_Z) | |
| 377 | ||
| 378 | /* 6502 ******************************************************** | |
| 379 | * BIT Bit test | |
| 380 | ***************************************************************/ | |
| 381 | #undef BIT | |
| 382 | #define BIT \ | |
| 383 | P &= ~(F_N|F_V|F_Z); \ | |
| 384 | P |= tmp & (F_N|F_V); \ | |
| 385 | if ((tmp & A) == 0) \ | |
| 386 | P |= F_Z | |
| 387 | ||
| 388 | /* 6502 ******************************************************** | |
| 389 | * BMI Branch if minus | |
| 390 | ***************************************************************/ | |
| 391 | #define BMI BRA(P & F_N) | |
| 392 | ||
| 393 | /* 6502 ******************************************************** | |
| 394 | * BNE Branch if not equal | |
| 395 | ***************************************************************/ | |
| 396 | #define BNE BRA(!(P & F_Z)) | |
| 397 | ||
| 398 | /* 6502 ******************************************************** | |
| 399 | * BPL Branch if plus | |
| 400 | ***************************************************************/ | |
| 401 | #define BPL BRA(!(P & F_N)) | |
| 402 | ||
| 403 | /* 6502 ******************************************************** | |
| 404 | * BRK Break | |
| 405 | * increment PC, push PC hi, PC lo, flags (with B bit set), | |
| 406 | * set I flag, jump via IRQ vector | |
| 407 | ***************************************************************/ | |
| 408 | #define BRK \ | |
| 409 | RDOPARG(); \ | |
| 410 | PUSH(PCH); \ | |
| 411 | PUSH(PCL); \ | |
| 412 | PUSH(P | F_B); \ | |
| 413 | P = (P | F_I); \ | |
| 414 | PCL = RDMEM(M6502_IRQ_VEC); \ | |
| 415 | PCH = RDMEM(M6502_IRQ_VEC+1) | |
| 416 | ||
| 417 | /* 6502 ******************************************************** | |
| 418 | * BVC Branch if overflow clear | |
| 419 | ***************************************************************/ | |
| 420 | #define BVC BRA(!(P & F_V)) | |
| 421 | ||
| 422 | /* 6502 ******************************************************** | |
| 423 | * BVS Branch if overflow set | |
| 424 | ***************************************************************/ | |
| 425 | #define BVS BRA(P & F_V) | |
| 426 | ||
| 427 | /* 6502 ******************************************************** | |
| 428 | * CLC Clear carry flag | |
| 429 | ***************************************************************/ | |
| 430 | #define CLC \ | |
| 431 | P &= ~F_C | |
| 432 | ||
| 433 | /* 6502 ******************************************************** | |
| 434 | * CLD Clear decimal flag | |
| 435 | ***************************************************************/ | |
| 436 | #define CLD \ | |
| 437 | P &= ~F_D | |
| 438 | ||
| 439 | /* 6502 ******************************************************** | |
| 440 | * CLI Clear interrupt flag | |
| 441 | ***************************************************************/ | |
| 442 | #define CLI \ | |
| 443 | if ((cpustate->irq_state != CLEAR_LINE) && (P & F_I)) { \ | |
| 444 | /* kludge for now until IRQ rewrite: ignore if RTI follows */ \ | |
| 445 | if (PEEKOP() != 0x40) \ | |
| 446 | cpustate->after_cli = 1; \ | |
| 447 | } \ | |
| 448 | P &= ~F_I | |
| 449 | ||
| 450 | /* 6502 ******************************************************** | |
| 451 | * CLV Clear overflow flag | |
| 452 | ***************************************************************/ | |
| 453 | #define CLV \ | |
| 454 | P &= ~F_V | |
| 455 | ||
| 456 | /* 6502 ******************************************************** | |
| 457 | * CMP Compare accumulator | |
| 458 | ***************************************************************/ | |
| 459 | #define CMP \ | |
| 460 | P &= ~F_C; \ | |
| 461 | if (A >= tmp) \ | |
| 462 | P |= F_C; \ | |
| 463 | SET_NZ((UINT8)(A - tmp)) | |
| 464 | ||
| 465 | /* 6502 ******************************************************** | |
| 466 | * CPX Compare index X | |
| 467 | ***************************************************************/ | |
| 468 | #define CPX \ | |
| 469 | P &= ~F_C; \ | |
| 470 | if (X >= tmp) \ | |
| 471 | P |= F_C; \ | |
| 472 | SET_NZ((UINT8)(X - tmp)) | |
| 473 | ||
| 474 | /* 6502 ******************************************************** | |
| 475 | * CPY Compare index Y | |
| 476 | ***************************************************************/ | |
| 477 | #define CPY \ | |
| 478 | P &= ~F_C; \ | |
| 479 | if (Y >= tmp) \ | |
| 480 | P |= F_C; \ | |
| 481 | SET_NZ((UINT8)(Y - tmp)) | |
| 482 | ||
| 483 | /* 6502 ******************************************************** | |
| 484 | * DEC Decrement memory | |
| 485 | ***************************************************************/ | |
| 486 | #define DEC \ | |
| 487 | tmp = (UINT8)(tmp-1); \ | |
| 488 | SET_NZ(tmp) | |
| 489 | ||
| 490 | /* 6502 ******************************************************** | |
| 491 | * DEX Decrement index X | |
| 492 | ***************************************************************/ | |
| 493 | #define DEX \ | |
| 494 | X = (UINT8)(X-1); \ | |
| 495 | SET_NZ(X) | |
| 496 | ||
| 497 | /* 6502 ******************************************************** | |
| 498 | * DEY Decrement index Y | |
| 499 | ***************************************************************/ | |
| 500 | #define DEY \ | |
| 501 | Y = (UINT8)(Y-1); \ | |
| 502 | SET_NZ(Y) | |
| 503 | ||
| 504 | /* 6502 ******************************************************** | |
| 505 | * EOR Logical exclusive or | |
| 506 | ***************************************************************/ | |
| 507 | #define EOR \ | |
| 508 | A = (UINT8)(A ^ tmp); \ | |
| 509 | SET_NZ(A) | |
| 510 | ||
| 511 | /* 6502 ******************************************************** | |
| 512 | * ILL Illegal opcode | |
| 513 | ***************************************************************/ | |
| 514 | #define ILL \ | |
| 515 | logerror("M6502 illegal opcode %04x: %02x\n",(PCW-1)&0xffff, cpustate->direct->read_decrypted_byte((PCW-1)&0xffff)) | |
| 516 | ||
| 517 | /* 6502 ******************************************************** | |
| 518 | * INC Increment memory | |
| 519 | ***************************************************************/ | |
| 520 | #define INC \ | |
| 521 | tmp = (UINT8)(tmp+1); \ | |
| 522 | SET_NZ(tmp) | |
| 523 | ||
| 524 | /* 6502 ******************************************************** | |
| 525 | * INX Increment index X | |
| 526 | ***************************************************************/ | |
| 527 | #define INX \ | |
| 528 | X = (UINT8)(X+1); \ | |
| 529 | SET_NZ(X) | |
| 530 | ||
| 531 | /* 6502 ******************************************************** | |
| 532 | * INY Increment index Y | |
| 533 | ***************************************************************/ | |
| 534 | #define INY \ | |
| 535 | Y = (UINT8)(Y+1); \ | |
| 536 | SET_NZ(Y) | |
| 537 | ||
| 538 | /* 6502 ******************************************************** | |
| 539 | * JMP Jump to address | |
| 540 | * set PC to the effective address | |
| 541 | ***************************************************************/ | |
| 542 | #define JMP \ | |
| 543 | if( EAD == PPC && !cpustate->pending_irq && !cpustate->after_cli ) \ | |
| 544 | if( cpustate->icount > 0 ) cpustate->icount = 0; \ | |
| 545 | PCD = EAD | |
| 546 | ||
| 547 | /* 6502 ******************************************************** | |
| 548 | * JSR Jump to subroutine | |
| 549 | * decrement PC (sic!) push PC hi, push PC lo and set | |
| 550 | * PC to the effective address | |
| 551 | ***************************************************************/ | |
| 552 | #define JSR \ | |
| 553 | EAL = RDOPARG(); \ | |
| 554 | RDMEM(SPD); \ | |
| 555 | PUSH(PCH); \ | |
| 556 | PUSH(PCL); \ | |
| 557 | EAH = RDOPARG(); \ | |
| 558 | PCD = EAD | |
| 559 | ||
| 560 | /* 6502 ******************************************************** | |
| 561 | * LDA Load accumulator | |
| 562 | ***************************************************************/ | |
| 563 | #define LDA \ | |
| 564 | A = (UINT8)tmp; \ | |
| 565 | SET_NZ(A) | |
| 566 | ||
| 567 | /* 6502 ******************************************************** | |
| 568 | * LDX Load index X | |
| 569 | ***************************************************************/ | |
| 570 | #define LDX \ | |
| 571 | X = (UINT8)tmp; \ | |
| 572 | SET_NZ(X) | |
| 573 | ||
| 574 | /* 6502 ******************************************************** | |
| 575 | * LDY Load index Y | |
| 576 | ***************************************************************/ | |
| 577 | #define LDY \ | |
| 578 | Y = (UINT8)tmp; \ | |
| 579 | SET_NZ(Y) | |
| 580 | ||
| 581 | /* 6502 ******************************************************** | |
| 582 | * LSR Logic shift right | |
| 583 | * 0 -> [7][6][5][4][3][2][1][0] -> C | |
| 584 | ***************************************************************/ | |
| 585 | #define LSR \ | |
| 586 | P = (P & ~F_C) | (tmp & F_C); \ | |
| 587 | tmp = (UINT8)tmp >> 1; \ | |
| 588 | SET_NZ(tmp) | |
| 589 | ||
| 590 | /* 6502 ******************************************************** | |
| 591 | * NOP No operation | |
| 592 | ***************************************************************/ | |
| 593 | #define NOP | |
| 594 | ||
| 595 | /* 6502 ******************************************************** | |
| 596 | * ORA Logical inclusive or | |
| 597 | ***************************************************************/ | |
| 598 | #define ORA \ | |
| 599 | A = (UINT8)(A | tmp); \ | |
| 600 | SET_NZ(A) | |
| 601 | ||
| 602 | /* 6502 ******************************************************** | |
| 603 | * PHA Push accumulator | |
| 604 | ***************************************************************/ | |
| 605 | #define PHA \ | |
| 606 | PUSH(A) | |
| 607 | ||
| 608 | /* 6502 ******************************************************** | |
| 609 | * PHP Push processor status (flags) | |
| 610 | ***************************************************************/ | |
| 611 | #define PHP \ | |
| 612 | PUSH(P) | |
| 613 | ||
| 614 | /* 6502 ******************************************************** | |
| 615 | * PLA Pull accumulator | |
| 616 | ***************************************************************/ | |
| 617 | #define PLA \ | |
| 618 | RDMEM(SPD); \ | |
| 619 | PULL(A); \ | |
| 620 | SET_NZ(A) | |
| 621 | ||
| 622 | ||
| 623 | /* 6502 ******************************************************** | |
| 624 | * PLP Pull processor status (flags) | |
| 625 | ***************************************************************/ | |
| 626 | #define PLP \ | |
| 627 | RDMEM(SPD); \ | |
| 628 | if ( P & F_I ) { \ | |
| 629 | PULL(P); \ | |
| 630 | if ((cpustate->irq_state != CLEAR_LINE) && !(P & F_I)) { \ | |
| 631 | LOG(("M6502 '%s' PLP sets after_cli\n",cpustate->device->tag())); \ | |
| 632 | cpustate->after_cli = 1; \ | |
| 633 | } \ | |
| 634 | } else { \ | |
| 635 | PULL(P); \ | |
| 636 | } \ | |
| 637 | P |= (F_T|F_B); | |
| 638 | ||
| 639 | /* 6502 ******************************************************** | |
| 640 | * ROL Rotate left | |
| 641 | * new C <- [7][6][5][4][3][2][1][0] <- C | |
| 642 | ***************************************************************/ | |
| 643 | #define ROL \ | |
| 644 | tmp = (tmp << 1) | (P & F_C); \ | |
| 645 | P = (P & ~F_C) | ((tmp >> 8) & F_C); \ | |
| 646 | tmp = (UINT8)tmp; \ | |
| 647 | SET_NZ(tmp) | |
| 648 | ||
| 649 | /* 6502 ******************************************************** | |
| 650 | * ROR Rotate right | |
| 651 | * C -> [7][6][5][4][3][2][1][0] -> new C | |
| 652 | ***************************************************************/ | |
| 653 | #define ROR \ | |
| 654 | tmp |= (P & F_C) << 8; \ | |
| 655 | P = (P & ~F_C) | (tmp & F_C); \ | |
| 656 | tmp = (UINT8)(tmp >> 1); \ | |
| 657 | SET_NZ(tmp) | |
| 658 | ||
| 659 | /* 6502 ******************************************************** | |
| 660 | * RTI Return from interrupt | |
| 661 | * pull flags, pull PC lo, pull PC hi and increment PC | |
| 662 | * PCW++; | |
| 663 | ***************************************************************/ | |
| 664 | #define RTI \ | |
| 665 | RDOPARG(); \ | |
| 666 | RDMEM(SPD); \ | |
| 667 | PULL(P); \ | |
| 668 | PULL(PCL); \ | |
| 669 | PULL(PCH); \ | |
| 670 | P |= F_T | F_B; \ | |
| 671 | if( (cpustate->irq_state != CLEAR_LINE) && !(P & F_I) ) \ | |
| 672 | { \ | |
| 673 | LOG(("M6502 '%s' RTI sets after_cli\n",cpustate->device->tag())); \ | |
| 674 | cpustate->after_cli = 1; \ | |
| 675 | } | |
| 676 | ||
| 677 | /* 6502 ******************************************************** | |
| 678 | * RTS Return from subroutine | |
| 679 | * pull PC lo, PC hi and increment PC | |
| 680 | ***************************************************************/ | |
| 681 | #define RTS \ | |
| 682 | RDOPARG(); \ | |
| 683 | RDMEM(SPD); \ | |
| 684 | PULL(PCL); \ | |
| 685 | PULL(PCH); \ | |
| 686 | RDMEM(PCW); PCW++ | |
| 687 | ||
| 688 | /* 6502 ******************************************************** | |
| 689 | * SBC Subtract with carry | |
| 690 | ***************************************************************/ | |
| 691 | #define SBC \ | |
| 692 | if (P & F_D) \ | |
| 693 | { \ | |
| 694 | int c = (P & F_C) ^ F_C; \ | |
| 695 | int sum = A - tmp - c; \ | |
| 696 | int lo = (A & 0x0f) - (tmp & 0x0f) - c; \ | |
| 697 | int hi = (A & 0xf0) - (tmp & 0xf0); \ | |
| 698 | if (lo & 0x10) \ | |
| 699 | { \ | |
| 700 | lo -= 6; \ | |
| 701 | hi--; \ | |
| 702 | } \ | |
| 703 | P &= ~(F_V | F_C|F_Z|F_N); \ | |
| 704 | if( (A^tmp) & (A^sum) & F_N ) \ | |
| 705 | P |= F_V; \ | |
| 706 | if( hi & 0x0100 ) \ | |
| 707 | hi -= 0x60; \ | |
| 708 | if( (sum & 0xff00) == 0 ) \ | |
| 709 | P |= F_C; \ | |
| 710 | if( !((A-tmp-c) & 0xff) ) \ | |
| 711 | P |= F_Z; \ | |
| 712 | if( (A-tmp-c) & 0x80 ) \ | |
| 713 | P |= F_N; \ | |
| 714 | A = (lo & 0x0f) | (hi & 0xf0); \ | |
| 715 | } \ | |
| 716 | else \ | |
| 717 | { \ | |
| 718 | int c = (P & F_C) ^ F_C; \ | |
| 719 | int sum = A - tmp - c; \ | |
| 720 | P &= ~(F_V | F_C); \ | |
| 721 | if( (A^tmp) & (A^sum) & F_N ) \ | |
| 722 | P |= F_V; \ | |
| 723 | if( (sum & 0xff00) == 0 ) \ | |
| 724 | P |= F_C; \ | |
| 725 | A = (UINT8) sum; \ | |
| 726 | SET_NZ(A); \ | |
| 727 | } | |
| 728 | ||
| 729 | /* 6502 ******************************************************** | |
| 730 | * SEC Set carry flag | |
| 731 | ***************************************************************/ | |
| 732 | #if defined(SEC) | |
| 733 | #undef SEC | |
| 734 | #endif | |
| 735 | #define SEC \ | |
| 736 | P |= F_C | |
| 737 | ||
| 738 | /* 6502 ******************************************************** | |
| 739 | * SED Set decimal flag | |
| 740 | ***************************************************************/ | |
| 741 | #define SED \ | |
| 742 | P |= F_D | |
| 743 | ||
| 744 | /* 6502 ******************************************************** | |
| 745 | * SEI Set interrupt flag | |
| 746 | ***************************************************************/ | |
| 747 | #define SEI \ | |
| 748 | P |= F_I | |
| 749 | ||
| 750 | /* 6502 ******************************************************** | |
| 751 | * STA Store accumulator | |
| 752 | ***************************************************************/ | |
| 753 | #define STA \ | |
| 754 | tmp = A | |
| 755 | ||
| 756 | /* 6502 ******************************************************** | |
| 757 | * STX Store index X | |
| 758 | ***************************************************************/ | |
| 759 | #define STX \ | |
| 760 | tmp = X | |
| 761 | ||
| 762 | /* 6502 ******************************************************** | |
| 763 | * STY Store index Y | |
| 764 | ***************************************************************/ | |
| 765 | #define STY \ | |
| 766 | tmp = Y | |
| 767 | ||
| 768 | /* 6502 ******************************************************** | |
| 769 | * TAX Transfer accumulator to index X | |
| 770 | ***************************************************************/ | |
| 771 | #define TAX \ | |
| 772 | X = A; \ | |
| 773 | SET_NZ(X) | |
| 774 | ||
| 775 | /* 6502 ******************************************************** | |
| 776 | * TAY Transfer accumulator to index Y | |
| 777 | ***************************************************************/ | |
| 778 | #define TAY \ | |
| 779 | Y = A; \ | |
| 780 | SET_NZ(Y) | |
| 781 | ||
| 782 | /* 6502 ******************************************************** | |
| 783 | * TSX Transfer stack LSB to index X | |
| 784 | ***************************************************************/ | |
| 785 | #define TSX \ | |
| 786 | X = S; \ | |
| 787 | SET_NZ(X) | |
| 788 | ||
| 789 | /* 6502 ******************************************************** | |
| 790 | * TXA Transfer index X to accumulator | |
| 791 | ***************************************************************/ | |
| 792 | #define TXA \ | |
| 793 | A = X; \ | |
| 794 | SET_NZ(A) | |
| 795 | ||
| 796 | /* 6502 ******************************************************** | |
| 797 | * TXS Transfer index X to stack LSB | |
| 798 | * no flags changed (sic!) | |
| 799 | ***************************************************************/ | |
| 800 | #define TXS \ | |
| 801 | S = X | |
| 802 | ||
| 803 | /* 6502 ******************************************************** | |
| 804 | * TYA Transfer index Y to accumulator | |
| 805 | ***************************************************************/ | |
| 806 | #define TYA \ | |
| 807 | A = Y; \ | |
| 808 | SET_NZ(A) |
| r18874 | r18875 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * m6502ops.h | |
| 4 | * Addressing mode and opcode macros for 6502,65c02,65sc02,6510,n2a03 CPUs | |
| 5 | * | |
| 6 | * Copyright Juergen Buchmueller, all rights reserved. | |
| 7 | * 65sc02 core Copyright Peter Trauner, all rights reserved. | |
| 8 | * | |
| 9 | * - This source code is released as freeware for non-commercial purposes. | |
| 10 | * - You are free to use and redistribute this code in modified or | |
| 11 | * unmodified form, provided you list me in the credits. | |
| 12 | * - If you modify this source code, you must add a notice to each modified | |
| 13 | * source file that it has been changed. If you're a nice person, you | |
| 14 | * will clearly mark each change too. :) | |
| 15 | * - If you wish to use this for commercial purposes, please contact me at | |
| 16 | * pullmoll@t-online.de | |
| 17 | * - The author of this copywritten work reserves the right to change the | |
| 18 | * terms of its usage and license at any time, including retroactively | |
| 19 | * - This entire notice must remain in the source code. | |
| 20 | * | |
| 21 | *****************************************************************************/ | |
| 22 | ||
| 23 | ||
| 24 | /*************************************************************** | |
| 25 | *************************************************************** | |
| 26 | * Macros to emulate the 65C02 opcodes | |
| 27 | *************************************************************** | |
| 28 | ***************************************************************/ | |
| 29 | ||
| 30 | /* 65C02 ******************************************************* | |
| 31 | * EA = absolute address + X | |
| 32 | * one additional read if page boundary is crossed | |
| 33 | ***************************************************************/ | |
| 34 | #define EA_ABX_C02_P \ | |
| 35 | EA_ABS; \ | |
| 36 | if ( EAL + X > 0xff ) { \ | |
| 37 | RDMEM( PCW - 1 ); \ | |
| 38 | } \ | |
| 39 | EAW += X; | |
| 40 | ||
| 41 | /* 65C02 ******************************************************* | |
| 42 | * EA = absolute address + X | |
| 43 | ***************************************************************/ | |
| 44 | #define EA_ABX_C02_NP \ | |
| 45 | EA_ABS; \ | |
| 46 | RDMEM( PCW - 1 ); \ | |
| 47 | EAW += X; | |
| 48 | ||
| 49 | /*************************************************************** | |
| 50 | * EA = absolute address + Y | |
| 51 | * one additional read if page boundary is crossed | |
| 52 | ***************************************************************/ | |
| 53 | #define EA_ABY_C02_P \ | |
| 54 | EA_ABS; \ | |
| 55 | if ( EAL + Y > 0xff ) { \ | |
| 56 | RDMEM( PCW - 1 ); \ | |
| 57 | } \ | |
| 58 | EAW += Y; | |
| 59 | ||
| 60 | /* 65C02 ******************************************************* | |
| 61 | * EA = absolute address + Y | |
| 62 | ***************************************************************/ | |
| 63 | #define EA_ABY_C02_NP \ | |
| 64 | EA_ABS; \ | |
| 65 | RDMEM( PCW - 1 ); \ | |
| 66 | EAW += Y | |
| 67 | ||
| 68 | /* 65C02 ******************************************************* | |
| 69 | * EA = zero page indirect + Y (post indexed) | |
| 70 | * subtract 1 cycle if page boundary is crossed | |
| 71 | ***************************************************************/ | |
| 72 | #define EA_IDY_C02_P \ | |
| 73 | ZPL = RDOPARG(); \ | |
| 74 | EAL = RDMEM(ZPD); \ | |
| 75 | ZPL++; \ | |
| 76 | EAH = RDMEM(ZPD); \ | |
| 77 | if (EAL + Y > 0xff) { \ | |
| 78 | RDMEM( PCW - 1 ); \ | |
| 79 | } \ | |
| 80 | EAW += Y; | |
| 81 | ||
| 82 | /* 65C02 ******************************************************* | |
| 83 | * EA = zero page indirect + Y | |
| 84 | ***************************************************************/ | |
| 85 | #define EA_IDY_C02_NP \ | |
| 86 | ZPL = RDOPARG(); \ | |
| 87 | EAL = RDMEM(ZPD); \ | |
| 88 | ZPL++; \ | |
| 89 | EAH = RDMEM(ZPD); \ | |
| 90 | RDMEM( PCW - 1 ); \ | |
| 91 | EAW += Y | |
| 92 | ||
| 93 | /* 65C02 ******************************************************* | |
| 94 | * EA = indirect (only used by JMP) | |
| 95 | * correct overflow handling | |
| 96 | ***************************************************************/ | |
| 97 | #define EA_IND_C02 \ | |
| 98 | EA_ABS; \ | |
| 99 | tmp = RDMEM(EAD); \ | |
| 100 | RDMEM(PCW-1); \ | |
| 101 | EAD++; \ | |
| 102 | EAH = RDMEM(EAD); \ | |
| 103 | EAL = tmp | |
| 104 | ||
| 105 | /* 65C02 ******************************************************* | |
| 106 | * EA = indirect plus x (only used by 65c02 JMP) | |
| 107 | ***************************************************************/ | |
| 108 | #define EA_IAX \ | |
| 109 | EA_ABS; \ | |
| 110 | RDMEM( PCW - 1 ); \ | |
| 111 | if (EAL + X > 0xff) { \ | |
| 112 | RDMEM( PCW - 1 ); \ | |
| 113 | } \ | |
| 114 | EAW += X; \ | |
| 115 | tmp = RDMEM(EAD); \ | |
| 116 | EAD++; \ | |
| 117 | EAH = RDMEM(EAD); \ | |
| 118 | EAL = tmp | |
| 119 | ||
| 120 | /* read a value into tmp */ | |
| 121 | /* Base number of cycles taken for each mode (including reading of opcode): | |
| 122 | RD_ABX_C02_P 4/5 | |
| 123 | RD_ABX_C02_NP/WR_ABX_C02_NP 5 | |
| 124 | RD_ABY_C02_P 4/5 | |
| 125 | RD_IDY_C02_P 5/6 | |
| 126 | WR_IDY_C02_NP 6 | |
| 127 | */ | |
| 128 | #define RD_ABX_C02_P EA_ABX_C02_P; tmp = RDMEM(EAD) | |
| 129 | #define RD_ABX_C02_NP EA_ABX_C02_NP; tmp = RDMEM(EAD) | |
| 130 | #define RD_ABX_C02_NP_DISCARD EA_ABX_C02_NP; RDMEM(EAD) | |
| 131 | #define RD_ABY_C02_P EA_ABY_C02_P; tmp = RDMEM(EAD) | |
| 132 | #define RD_IDY_C02_P EA_IDY_C02_P; tmp = RDMEM_ID(EAD); cpustate->icount -= 1 | |
| 133 | ||
| 134 | #define WR_ABX_C02_NP EA_ABX_C02_NP; WRMEM(EAD, tmp) | |
| 135 | #define WR_ABY_C02_NP EA_ABY_C02_NP; WRMEM(EAD, tmp) | |
| 136 | #define WR_IDY_C02_NP EA_IDY_C02_NP; WRMEM_ID(EAD, tmp); cpustate->icount -= 1 | |
| 137 | ||
| 138 | ||
| 139 | /* 65C02******************************************************** | |
| 140 | * BRA branch relative | |
| 141 | * extra cycle if page boundary is crossed | |
| 142 | ***************************************************************/ | |
| 143 | #define BRA_C02(cond) \ | |
| 144 | tmp = RDOPARG(); \ | |
| 145 | if (cond) \ | |
| 146 | { \ | |
| 147 | RDMEM(PCW); \ | |
| 148 | EAW = PCW + (signed char)tmp; \ | |
| 149 | if ( EAH != PCH ) { \ | |
| 150 | RDMEM( PCW - 1 ); \ | |
| 151 | } \ | |
| 152 | PCD = EAD; \ | |
| 153 | } | |
| 154 | ||
| 155 | /* 65C02 ******************************************************** | |
| 156 | * ADC Add with carry | |
| 157 | * different setting of flags in decimal mode | |
| 158 | ***************************************************************/ | |
| 159 | #define ADC_C02 \ | |
| 160 | if (P & F_D) \ | |
| 161 | { \ | |
| 162 | int c = (P & F_C); \ | |
| 163 | int lo = (A & 0x0f) + (tmp & 0x0f) + c; \ | |
| 164 | int hi = (A & 0xf0) + (tmp & 0xf0); \ | |
| 165 | P &= ~(F_V | F_C); \ | |
| 166 | if( lo > 0x09 ) \ | |
| 167 | { \ | |
| 168 | hi += 0x10; \ | |
| 169 | lo += 0x06; \ | |
| 170 | } \ | |
| 171 | if( ~(A^tmp) & (A^hi) & F_N ) \ | |
| 172 | P |= F_V; \ | |
| 173 | if( hi > 0x90 ) \ | |
| 174 | hi += 0x60; \ | |
| 175 | if( hi & 0xff00 ) \ | |
| 176 | P |= F_C; \ | |
| 177 | A = (lo & 0x0f) + (hi & 0xf0); \ | |
| 178 | RDMEM( PCW - 1 ); \ | |
| 179 | } \ | |
| 180 | else \ | |
| 181 | { \ | |
| 182 | int c = (P & F_C); \ | |
| 183 | int sum = A + tmp + c; \ | |
| 184 | P &= ~(F_V | F_C); \ | |
| 185 | if( ~(A^tmp) & (A^sum) & F_N ) \ | |
| 186 | P |= F_V; \ | |
| 187 | if( sum & 0xff00 ) \ | |
| 188 | P |= F_C; \ | |
| 189 | A = (UINT8) sum; \ | |
| 190 | } \ | |
| 191 | SET_NZ(A) | |
| 192 | ||
| 193 | /* 65C02 ******************************************************** | |
| 194 | * SBC Subtract with carry | |
| 195 | * different setting of flags in decimal mode | |
| 196 | ***************************************************************/ | |
| 197 | #define SBC_C02 \ | |
| 198 | if (P & F_D) \ | |
| 199 | { \ | |
| 200 | int c = (P & F_C) ^ F_C; \ | |
| 201 | int sum = A - tmp - c; \ | |
| 202 | int lo = (A & 0x0f) - (tmp & 0x0f) - c; \ | |
| 203 | int hi = (A & 0xf0) - (tmp & 0xf0); \ | |
| 204 | P &= ~(F_V | F_C); \ | |
| 205 | if( (A^tmp) & (A^sum) & F_N ) \ | |
| 206 | P |= F_V; \ | |
| 207 | if( lo & 0xf0 ) \ | |
| 208 | lo -= 6; \ | |
| 209 | if( lo & 0x80 ) \ | |
| 210 | hi -= 0x10; \ | |
| 211 | if( hi & 0x0f00 ) \ | |
| 212 | hi -= 0x60; \ | |
| 213 | if( (sum & 0xff00) == 0 ) \ | |
| 214 | P |= F_C; \ | |
| 215 | A = (lo & 0x0f) + (hi & 0xf0); \ | |
| 216 | RDMEM( PCW - 1 ); \ | |
| 217 | } \ | |
| 218 | else \ | |
| 219 | { \ | |
| 220 | int c = (P & F_C) ^ F_C; \ | |
| 221 | int sum = A - tmp - c; \ | |
| 222 | P &= ~(F_V | F_C); \ | |
| 223 | if( (A^tmp) & (A^sum) & F_N ) \ | |
| 224 | P |= F_V; \ | |
| 225 | if( (sum & 0xff00) == 0 ) \ | |
| 226 | P |= F_C; \ | |
| 227 | A = (UINT8) sum; \ | |
| 228 | } \ | |
| 229 | SET_NZ(A) | |
| 230 | ||
| 231 | /* 65C02 ******************************************************* | |
| 232 | * BBR Branch if bit is reset | |
| 233 | ***************************************************************/ | |
| 234 | #define BBR(bit) \ | |
| 235 | BRA(!(tmp & (1<<bit))) | |
| 236 | ||
| 237 | /* 65C02 ******************************************************* | |
| 238 | * BBS Branch if bit is set | |
| 239 | ***************************************************************/ | |
| 240 | #define BBS(bit) \ | |
| 241 | BRA(tmp & (1<<bit)) | |
| 242 | ||
| 243 | /* 65c02 ******************************************************** | |
| 244 | * BRK Break | |
| 245 | * increment PC, push PC hi, PC lo, flags (with B bit set), | |
| 246 | * set I flag, reset D flag and jump via IRQ vector | |
| 247 | ***************************************************************/ | |
| 248 | #define BRK_C02 \ | |
| 249 | RDOPARG(); \ | |
| 250 | PUSH(PCH); \ | |
| 251 | PUSH(PCL); \ | |
| 252 | PUSH(P | F_B); \ | |
| 253 | P = (P | F_I) & ~F_D; \ | |
| 254 | PCL = RDMEM(M6502_IRQ_VEC); \ | |
| 255 | PCH = RDMEM(M6502_IRQ_VEC+1); | |
| 256 | ||
| 257 | ||
| 258 | /* 65C02 ******************************************************* | |
| 259 | * DEA Decrement accumulator | |
| 260 | ***************************************************************/ | |
| 261 | #define DEA \ | |
| 262 | A = (UINT8)(A - 1); \ | |
| 263 | SET_NZ(A) | |
| 264 | ||
| 265 | /* 65C02 ******************************************************* | |
| 266 | * INA Increment accumulator | |
| 267 | ***************************************************************/ | |
| 268 | #define INA \ | |
| 269 | A = (UINT8)(A + 1); \ | |
| 270 | SET_NZ(A) | |
| 271 | ||
| 272 | /* 65C02 ******************************************************* | |
| 273 | * PHX Push index X | |
| 274 | ***************************************************************/ | |
| 275 | #define PHX \ | |
| 276 | PUSH(X) | |
| 277 | ||
| 278 | /* 65C02 ******************************************************* | |
| 279 | * PHY Push index Y | |
| 280 | ***************************************************************/ | |
| 281 | #define PHY \ | |
| 282 | PUSH(Y) | |
| 283 | ||
| 284 | /* 65C02 ******************************************************* | |
| 285 | * PLX Pull index X | |
| 286 | ***************************************************************/ | |
| 287 | #define PLX \ | |
| 288 | RDMEM(SPD); \ | |
| 289 | PULL(X); \ | |
| 290 | SET_NZ(X) | |
| 291 | ||
| 292 | /* 65C02 ******************************************************* | |
| 293 | * PLY Pull index Y | |
| 294 | ***************************************************************/ | |
| 295 | #define PLY \ | |
| 296 | RDMEM(SPD); \ | |
| 297 | PULL(Y); \ | |
| 298 | SET_NZ(Y) | |
| 299 | ||
| 300 | /* 65C02 ******************************************************* | |
| 301 | * RMB Reset memory bit | |
| 302 | ***************************************************************/ | |
| 303 | #define RMB(bit) \ | |
| 304 | tmp &= ~(1<<bit) | |
| 305 | ||
| 306 | /* 65C02 ******************************************************* | |
| 307 | * SMB Set memory bit | |
| 308 | ***************************************************************/ | |
| 309 | #define SMB(bit) \ | |
| 310 | tmp |= (1<<bit) | |
| 311 | ||
| 312 | /* 65C02 ******************************************************* | |
| 313 | * STZ Store zero | |
| 314 | ***************************************************************/ | |
| 315 | #define STZ \ | |
| 316 | tmp = 0 | |
| 317 | ||
| 318 | /* 65C02 ******************************************************* | |
| 319 | * TRB Test and reset bits | |
| 320 | ***************************************************************/ | |
| 321 | #define TRB \ | |
| 322 | SET_Z(tmp&A); \ | |
| 323 | tmp &= ~A | |
| 324 | ||
| 325 | /* 65C02 ******************************************************* | |
| 326 | * TSB Test and set bits | |
| 327 | ***************************************************************/ | |
| 328 | #define TSB \ | |
| 329 | SET_Z(tmp&A); \ | |
| 330 | tmp |= A | |
| 331 | ||
| 332 | /* 6502 ******************************************************** | |
| 333 | * BIT Bit test Immediate, only Z affected | |
| 334 | ***************************************************************/ | |
| 335 | #undef BIT_IMM_C02 | |
| 336 | #define BIT_IMM_C02 \ | |
| 337 | P &= ~(F_Z); \ | |
| 338 | if ((tmp & A) == 0) \ | |
| 339 | P |= F_Z | |
| 340 | ||
| 341 | ||
| 342 | /*************************************************************** | |
| 343 | *************************************************************** | |
| 344 | * Macros to emulate the 65sc02 opcodes | |
| 345 | *************************************************************** | |
| 346 | ***************************************************************/ | |
| 347 | ||
| 348 | ||
| 349 | /* 65sc02 ******************************************************** | |
| 350 | * BSR Branch to subroutine | |
| 351 | ***************************************************************/ | |
| 352 | #define BSR \ | |
| 353 | EAL = RDOPARG(); \ | |
| 354 | RDMEM(SPD); \ | |
| 355 | PUSH(PCH); \ | |
| 356 | PUSH(PCL); \ | |
| 357 | EAH = RDOPARG(); \ | |
| 358 | EAW = PCW + (INT16)(EAW-1); \ | |
| 359 | PCD = EAD; |
| r18874 | r18875 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * ops4510.h | |
| 4 | * Addressing mode and opcode macros for 4510 CPU | |
| 5 | * | |
| 6 | * Copyright Peter Trauner, all rights reserved. | |
| 7 | * documentation preliminary databook | |
| 8 | * documentation by michael steil mist@c64.org | |
| 9 | * available at ftp://ftp.funet.fi/pub/cbm/c65 | |
| 10 | * | |
| 11 | * - This source code is released as freeware for non-commercial purposes. | |
| 12 | * - You are free to use and redistribute this code in modified or | |
| 13 | * unmodified form, provided you list me in the credits. | |
| 14 | * - If you modify this source code, you must add a notice to each modified | |
| 15 | * source file that it has been changed. If you're a nice person, you | |
| 16 | * will clearly mark each change too. :) | |
| 17 | * - If you wish to use this for commercial purposes, please contact me at | |
| 18 | * pullmoll@t-online.de | |
| 19 | * - The author of this copywritten work reserves the right to change the | |
| 20 | * terms of its usage and license at any time, including retroactively | |
| 21 | * - This entire notice must remain in the source code. | |
| 22 | * | |
| 23 | *****************************************************************************/ | |
| 24 | ||
| 25 | ||
| 26 | /* 65ce02 ******************************************************** | |
| 27 | * TXS Transfer index X to stack LSB | |
| 28 | * no flags changed (sic!) | |
| 29 | * txs tys not interruptable | |
| 30 | ***************************************************************/ | |
| 31 | #undef TXS | |
| 32 | #define TXS \ | |
| 33 | SPL = X; \ | |
| 34 | if (PEEK_OP() == 0x2b /*TYS*/ ) { \ | |
| 35 | UINT8 op = RDOP(); \ | |
| 36 | (*cpustate->insn[op])(cpustate); \ | |
| 37 | } | |
| 38 | ||
| 39 | #undef NOP | |
| 40 | #define NOP \ | |
| 41 | cpustate->interrupt_inhibit = 0; | |
| 42 | ||
| 43 | /* c65 docu says transfer of axyz to the mapper register | |
| 44 | so no readback!? */ | |
| 45 | #define MAP \ | |
| 46 | cpustate->interrupt_inhibit = 1; \ | |
| 47 | cpustate->low=cpustate->a|(cpustate->x<<8); \ | |
| 48 | cpustate->high=cpustate->y|(cpustate->z<<8); \ | |
| 49 | cpustate->mem[0]=(cpustate->low&0x1000) ? (cpustate->low&0xfff)<<8:0; \ | |
| 50 | cpustate->mem[1]=(cpustate->low&0x2000) ? (cpustate->low&0xfff)<<8:0; \ | |
| 51 | cpustate->mem[2]=(cpustate->low&0x4000) ? (cpustate->low&0xfff)<<8:0; \ | |
| 52 | cpustate->mem[3]=(cpustate->low&0x8000) ? (cpustate->low&0xfff)<<8:0; \ | |
| 53 | cpustate->mem[4]=(cpustate->high&0x1000) ? (cpustate->high&0xfff)<<8:0; \ | |
| 54 | cpustate->mem[5]=(cpustate->high&0x2000) ? (cpustate->high&0xfff)<<8:0; \ | |
| 55 | cpustate->mem[6]=(cpustate->high&0x4000) ? (cpustate->high&0xfff)<<8:0; \ | |
| 56 | cpustate->mem[7]=(cpustate->high&0x8000) ? (cpustate->high&0xfff)<<8:0; \ | |
| 57 | cpustate->icount -= 3; \ | |
| 58 | { \ | |
| 59 | UINT8 op = RDOP(); \ | |
| 60 | (*cpustate->insn[op])(cpustate); \ | |
| 61 | } | |
| 62 | ||
| 63 | #undef RDMEM_ID | |
| 64 | #undef WRMEM_ID | |
| 65 | #define RDMEM_ID(a) (cpustate->rdmem_id.isnull() ? cpustate->space->read_byte(M4510_MEM(a)) : cpustate->rdmem_id(M4510_MEM(a))) | |
| 66 | #define WRMEM_ID(a,d) (cpustate->wrmem_id.isnull() ? cpustate->space->write_byte(M4510_MEM(a),d) : cpustate->wrmem_id(M4510_MEM(a),d)) |
| r18874 | r18875 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * tbl6502.c | |
| 4 | * 6502 opcode functions and function pointer table | |
| 5 | * | |
| 6 | * Copyright Juergen Buchmueller, all rights reserved. | |
| 7 | * | |
| 8 | * - This source code is released as freeware for non-commercial purposes. | |
| 9 | * - You are free to use and redistribute this code in modified or | |
| 10 | * unmodified form, provided you list me in the credits. | |
| 11 | * - If you modify this source code, you must add a notice to each modified | |
| 12 | * source file that it has been changed. If you're a nice person, you | |
| 13 | * will clearly mark each change too. :) | |
| 14 | * - If you wish to use this for commercial purposes, please contact me at | |
| 15 | * pullmoll@t-online.de | |
| 16 | * - The author of this copywritten work reserves the right to change the | |
| 17 | * terms of its usage and license at any time, including retroactively | |
| 18 | * - This entire notice must remain in the source code. | |
| 19 | * | |
| 20 | * 2003-05-26 Fixed PHP, PLP, PHA, PLA cycle counts. [SJ] | |
| 21 | * 2004-04-30 Fixed STX (abs) cycle count. [SJ] | |
| 22 | * | |
| 23 | *****************************************************************************/ | |
| 24 | ||
| 25 | #undef OP | |
| 26 | #define OP(nn) INLINE void m6502_##nn(m6502_Regs *cpustate) | |
| 27 | ||
| 28 | /***************************************************************************** | |
| 29 | ***************************************************************************** | |
| 30 | * | |
| 31 | * plain vanilla 6502 opcodes | |
| 32 | * | |
| 33 | ***************************************************************************** | |
| 34 | * op temp cycles rdmem opc wrmem ********************/ | |
| 35 | ||
| 36 | OP(00) { BRK; } /* 7 BRK */ | |
| 37 | OP(20) { JSR; } /* 6 JSR */ | |
| 38 | OP(40) { RTI; } /* 6 RTI */ | |
| 39 | OP(60) { RTS; } /* 6 RTS */ | |
| 40 | OP(80) { RDOPARG(); NOP; } /* 2 NOP IMM */ | |
| 41 | OP(a0) { int tmp; RD_IMM; LDY; } /* 2 LDY IMM */ | |
| 42 | OP(c0) { int tmp; RD_IMM; CPY; } /* 2 CPY IMM */ | |
| 43 | OP(e0) { int tmp; RD_IMM; CPX; } /* 2 CPX IMM */ | |
| 44 | ||
| 45 | OP(10) { BPL; } /* 2-4 BPL REL */ | |
| 46 | OP(30) { BMI; } /* 2-4 BMI REL */ | |
| 47 | OP(50) { BVC; } /* 2-4 BVC REL */ | |
| 48 | OP(70) { BVS; } /* 2-4 BVS REL */ | |
| 49 | OP(90) { BCC; } /* 2-4 BCC REL */ | |
| 50 | OP(b0) { BCS; } /* 2-4 BCS REL */ | |
| 51 | OP(d0) { BNE; } /* 2-4 BNE REL */ | |
| 52 | OP(f0) { BEQ; } /* 2-4 BEQ REL */ | |
| 53 | ||
| 54 | OP(01) { int tmp; RD_IDX; ORA; } /* 6 ORA IDX */ | |
| 55 | OP(21) { int tmp; RD_IDX; AND; } /* 6 AND IDX */ | |
| 56 | OP(41) { int tmp; RD_IDX; EOR; } /* 6 EOR IDX */ | |
| 57 | OP(61) { int tmp; RD_IDX; ADC; } /* 6 ADC IDX */ | |
| 58 | OP(81) { int tmp; STA; WR_IDX; } /* 6 STA IDX */ | |
| 59 | OP(a1) { int tmp; RD_IDX; LDA; } /* 6 LDA IDX */ | |
| 60 | OP(c1) { int tmp; RD_IDX; CMP; } /* 6 CMP IDX */ | |
| 61 | OP(e1) { int tmp; RD_IDX; SBC; } /* 6 SBC IDX */ | |
| 62 | ||
| 63 | OP(11) { int tmp; RD_IDY_P; ORA; } /* 5 ORA IDY page penalty */ | |
| 64 | OP(31) { int tmp; RD_IDY_P; AND; } /* 5 AND IDY page penalty */ | |
| 65 | OP(51) { int tmp; RD_IDY_P; EOR; } /* 5 EOR IDY page penalty */ | |
| 66 | OP(71) { int tmp; RD_IDY_P; ADC; } /* 5 ADC IDY page penalty */ | |
| 67 | OP(91) { int tmp; STA; WR_IDY_NP; } /* 6 STA IDY */ | |
| 68 | OP(b1) { int tmp; RD_IDY_P; LDA; } /* 5 LDA IDY page penalty */ | |
| 69 | OP(d1) { int tmp; RD_IDY_P; CMP; } /* 5 CMP IDY page penalty */ | |
| 70 | OP(f1) { int tmp; RD_IDY_P; SBC; } /* 5 SBC IDY page penalty */ | |
| 71 | ||
| 72 | OP(02) { KIL; } /* 1 KIL */ | |
| 73 | OP(22) { KIL; } /* 1 KIL */ | |
| 74 | OP(42) { KIL; } /* 1 KIL */ | |
| 75 | OP(62) { KIL; } /* 1 KIL */ | |
| 76 | OP(82) { RDOPARG(); NOP; } /* 2 NOP IMM */ | |
| 77 | OP(a2) { int tmp; RD_IMM; LDX; } /* 2 LDX IMM */ | |
| 78 | OP(c2) { RDOPARG(); NOP; } /* 2 NOP IMM */ | |
| 79 | OP(e2) { RDOPARG(); NOP; } /* 2 NOP IMM */ | |
| 80 | ||
| 81 | OP(12) { KIL; } /* 1 KIL */ | |
| 82 | OP(32) { KIL; } /* 1 KIL */ | |
| 83 | OP(52) { KIL; } /* 1 KIL */ | |
| 84 | OP(72) { KIL; } /* 1 KIL */ | |
| 85 | OP(92) { KIL; } /* 1 KIL */ | |
| 86 | OP(b2) { KIL; } /* 1 KIL */ | |
| 87 | OP(d2) { KIL; } /* 1 KIL */ | |
| 88 | OP(f2) { KIL; } /* 1 KIL */ | |
| 89 | ||
| 90 | OP(03) { int tmp; RD_IDX; WB_EA; SLO; WB_EA; } /* 7 SLO IDX */ | |
| 91 | OP(23) { int tmp; RD_IDX; WB_EA; RLA; WB_EA; } /* 7 RLA IDX */ | |
| 92 | OP(43) { int tmp; RD_IDX; WB_EA; SRE; WB_EA; } /* 7 SRE IDX */ | |
| 93 | OP(63) { int tmp; RD_IDX; WB_EA; RRA; WB_EA; } /* 7 RRA IDX */ | |
| 94 | OP(83) { int tmp; SAX; WR_IDX; } /* 6 SAX IDX */ | |
| 95 | OP(a3) { int tmp; RD_IDX; LAX; } /* 6 LAX IDX */ | |
| 96 | OP(c3) { int tmp; RD_IDX; WB_EA; DCP; WB_EA; } /* 7 DCP IDX */ | |
| 97 | OP(e3) { int tmp; RD_IDX; WB_EA; ISB; WB_EA; } /* 7 ISB IDX */ | |
| 98 | ||
| 99 | OP(13) { int tmp; RD_IDY_NP; WB_EA; SLO; WB_EA; } /* 7 SLO IDY */ | |
| 100 | OP(33) { int tmp; RD_IDY_NP; WB_EA; RLA; WB_EA; } /* 7 RLA IDY */ | |
| 101 | OP(53) { int tmp; RD_IDY_NP; WB_EA; SRE; WB_EA; } /* 7 SRE IDY */ | |
| 102 | OP(73) { int tmp; RD_IDY_NP; WB_EA; RRA; WB_EA; } /* 7 RRA IDY */ | |
| 103 | OP(93) { int tmp; EA_IDY_NP; SAH; WB_EA; } /* 5 SAH IDY */ | |
| 104 | OP(b3) { int tmp; RD_IDY_P; LAX; } /* 5 LAX IDY page penalty */ | |
| 105 | OP(d3) { int tmp; RD_IDY_NP; WB_EA; DCP; WB_EA; } /* 7 DCP IDY */ | |
| 106 | OP(f3) { int tmp; RD_IDY_NP; WB_EA; ISB; WB_EA; } /* 7 ISB IDY */ | |
| 107 | ||
| 108 | OP(04) { RD_ZPG_DISCARD; NOP; } /* 3 NOP ZPG */ | |
| 109 | OP(24) { int tmp; RD_ZPG; BIT; } /* 3 BIT ZPG */ | |
| 110 | OP(44) { RD_ZPG_DISCARD; NOP; } /* 3 NOP ZPG */ | |
| 111 | OP(64) { RD_ZPG_DISCARD; NOP; } /* 3 NOP ZPG */ | |
| 112 | OP(84) { int tmp; STY; WR_ZPG; } /* 3 STY ZPG */ | |
| 113 | OP(a4) { int tmp; RD_ZPG; LDY; } /* 3 LDY ZPG */ | |
| 114 | OP(c4) { int tmp; RD_ZPG; CPY; } /* 3 CPY ZPG */ | |
| 115 | OP(e4) { int tmp; RD_ZPG; CPX; } /* 3 CPX ZPG */ | |
| 116 | ||
| 117 | OP(14) { RD_ZPX_DISCARD; NOP; } /* 4 NOP ZPX */ | |
| 118 | OP(34) { RD_ZPX_DISCARD; NOP; } /* 4 NOP ZPX */ | |
| 119 | OP(54) { RD_ZPX_DISCARD; NOP; } /* 4 NOP ZPX */ | |
| 120 | OP(74) { RD_ZPX_DISCARD; NOP; } /* 4 NOP ZPX */ | |
| 121 | OP(94) { int tmp; STY; WR_ZPX; } /* 4 STY ZPX */ | |
| 122 | OP(b4) { int tmp; RD_ZPX; LDY; } /* 4 LDY ZPX */ | |
| 123 | OP(d4) { RD_ZPX_DISCARD; NOP; } /* 4 NOP ZPX */ | |
| 124 | OP(f4) { RD_ZPX_DISCARD; NOP; } /* 4 NOP ZPX */ | |
| 125 | ||
| 126 | OP(05) { int tmp; RD_ZPG; ORA; } /* 3 ORA ZPG */ | |
| 127 | OP(25) { int tmp; RD_ZPG; AND; } /* 3 AND ZPG */ | |
| 128 | OP(45) { int tmp; RD_ZPG; EOR; } /* 3 EOR ZPG */ | |
| 129 | OP(65) { int tmp; RD_ZPG; ADC; } /* 3 ADC ZPG */ | |
| 130 | OP(85) { int tmp; STA; WR_ZPG; } /* 3 STA ZPG */ | |
| 131 | OP(a5) { int tmp; RD_ZPG; LDA; } /* 3 LDA ZPG */ | |
| 132 | OP(c5) { int tmp; RD_ZPG; CMP; } /* 3 CMP ZPG */ | |
| 133 | OP(e5) { int tmp; RD_ZPG; SBC; } /* 3 SBC ZPG */ | |
| 134 | ||
| 135 | OP(15) { int tmp; RD_ZPX; ORA; } /* 4 ORA ZPX */ | |
| 136 | OP(35) { int tmp; RD_ZPX; AND; } /* 4 AND ZPX */ | |
| 137 | OP(55) { int tmp; RD_ZPX; EOR; } /* 4 EOR ZPX */ | |
| 138 | OP(75) { int tmp; RD_ZPX; ADC; } /* 4 ADC ZPX */ | |
| 139 | OP(95) { int tmp; STA; WR_ZPX; } /* 4 STA ZPX */ | |
| 140 | OP(b5) { int tmp; RD_ZPX; LDA; } /* 4 LDA ZPX */ | |
| 141 | OP(d5) { int tmp; RD_ZPX; CMP; } /* 4 CMP ZPX */ | |
| 142 | OP(f5) { int tmp; RD_ZPX; SBC; } /* 4 SBC ZPX */ | |
| 143 | ||
| 144 | OP(06) { int tmp; RD_ZPG; WB_EA; ASL; WB_EA; } /* 5 ASL ZPG */ | |
| 145 | OP(26) { int tmp; RD_ZPG; WB_EA; ROL; WB_EA; } /* 5 ROL ZPG */ | |
| 146 | OP(46) { int tmp; RD_ZPG; WB_EA; LSR; WB_EA; } /* 5 LSR ZPG */ | |
| 147 | OP(66) { int tmp; RD_ZPG; WB_EA; ROR; WB_EA; } /* 5 ROR ZPG */ | |
| 148 | OP(86) { int tmp; STX; WR_ZPG; } /* 3 STX ZPG */ | |
| 149 | OP(a6) { int tmp; RD_ZPG; LDX; } /* 3 LDX ZPG */ | |
| 150 | OP(c6) { int tmp; RD_ZPG; WB_EA; DEC; WB_EA; } /* 5 DEC ZPG */ | |
| 151 | OP(e6) { int tmp; RD_ZPG; WB_EA; INC; WB_EA; } /* 5 INC ZPG */ | |
| 152 | ||
| 153 | OP(16) { int tmp; RD_ZPX; WB_EA; ASL; WB_EA; } /* 6 ASL ZPX */ | |
| 154 | OP(36) { int tmp; RD_ZPX; WB_EA; ROL; WB_EA; } /* 6 ROL ZPX */ | |
| 155 | OP(56) { int tmp; RD_ZPX; WB_EA; LSR; WB_EA; } /* 6 LSR ZPX */ | |
| 156 | OP(76) { int tmp; RD_ZPX; WB_EA; ROR; WB_EA; } /* 6 ROR ZPX */ | |
| 157 | OP(96) { int tmp; STX; WR_ZPY; } /* 4 STX ZPY */ | |
| 158 | OP(b6) { int tmp; RD_ZPY; LDX; } /* 4 LDX ZPY */ | |
| 159 | OP(d6) { int tmp; RD_ZPX; WB_EA; DEC; WB_EA; } /* 6 DEC ZPX */ | |
| 160 | OP(f6) { int tmp; RD_ZPX; WB_EA; INC; WB_EA; } /* 6 INC ZPX */ | |
| 161 | ||
| 162 | OP(07) { int tmp; RD_ZPG; WB_EA; SLO; WB_EA; } /* 5 SLO ZPG */ | |
| 163 | OP(27) { int tmp; RD_ZPG; WB_EA; RLA; WB_EA; } /* 5 RLA ZPG */ | |
| 164 | OP(47) { int tmp; RD_ZPG; WB_EA; SRE; WB_EA; } /* 5 SRE ZPG */ | |
| 165 | OP(67) { int tmp; RD_ZPG; WB_EA; RRA; WB_EA; } /* 5 RRA ZPG */ | |
| 166 | OP(87) { int tmp; SAX; WR_ZPG; } /* 3 SAX ZPG */ | |
| 167 | OP(a7) { int tmp; RD_ZPG; LAX; } /* 3 LAX ZPG */ | |
| 168 | OP(c7) { int tmp; RD_ZPG; WB_EA; DCP; WB_EA; } /* 5 DCP ZPG */ | |
| 169 | OP(e7) { int tmp; RD_ZPG; WB_EA; ISB; WB_EA; } /* 5 ISB ZPG */ | |
| 170 | ||
| 171 | OP(17) { int tmp; RD_ZPX; WB_EA; SLO; WB_EA; } /* 6 SLO ZPX */ | |
| 172 | OP(37) { int tmp; RD_ZPX; WB_EA; RLA; WB_EA; } /* 6 RLA ZPX */ | |
| 173 | OP(57) { int tmp; RD_ZPX; WB_EA; SRE; WB_EA; } /* 6 SRE ZPX */ | |
| 174 | OP(77) { int tmp; RD_ZPX; WB_EA; RRA; WB_EA; } /* 6 RRA ZPX */ | |
| 175 | OP(97) { int tmp; SAX; WR_ZPY; } /* 4 SAX ZPY */ | |
| 176 | OP(b7) { int tmp; RD_ZPY; LAX; } /* 4 LAX ZPY */ | |
| 177 | OP(d7) { int tmp; RD_ZPX; WB_EA; DCP; WB_EA; } /* 6 DCP ZPX */ | |
| 178 | OP(f7) { int tmp; RD_ZPX; WB_EA; ISB; WB_EA; } /* 6 ISB ZPX */ | |
| 179 | ||
| 180 | OP(08) { RD_DUM; PHP; } /* 3 PHP */ | |
| 181 | OP(28) { RD_DUM; PLP; } /* 4 PLP */ | |
| 182 | OP(48) { RD_DUM; PHA; } /* 3 PHA */ | |
| 183 | OP(68) { RD_DUM; PLA; } /* 4 PLA */ | |
| 184 | OP(88) { RD_DUM; DEY; } /* 2 DEY */ | |
| 185 | OP(a8) { RD_DUM; TAY; } /* 2 TAY */ | |
| 186 | OP(c8) { RD_DUM; INY; } /* 2 INY */ | |
| 187 | OP(e8) { RD_DUM; INX; } /* 2 INX */ | |
| 188 | ||
| 189 | OP(18) { RD_DUM; CLC; } /* 2 CLC */ | |
| 190 | OP(38) { RD_DUM; SEC; } /* 2 SEC */ | |
| 191 | OP(58) { RD_DUM; CLI; } /* 2 CLI */ | |
| 192 | OP(78) { RD_DUM; SEI; } /* 2 SEI */ | |
| 193 | OP(98) { RD_DUM; TYA; } /* 2 TYA */ | |
| 194 | OP(b8) { RD_DUM; CLV; } /* 2 CLV */ | |
| 195 | OP(d8) { RD_DUM; CLD; } /* 2 CLD */ | |
| 196 | OP(f8) { RD_DUM; SED; } /* 2 SED */ | |
| 197 | ||
| 198 | OP(09) { int tmp; RD_IMM; ORA; } /* 2 ORA IMM */ | |
| 199 | OP(29) { int tmp; RD_IMM; AND; } /* 2 AND IMM */ | |
| 200 | OP(49) { int tmp; RD_IMM; EOR; } /* 2 EOR IMM */ | |
| 201 | OP(69) { int tmp; RD_IMM; ADC; } /* 2 ADC IMM */ | |
| 202 | OP(89) { RD_IMM_DISCARD; NOP; } /* 2 NOP IMM */ | |
| 203 | OP(a9) { int tmp; RD_IMM; LDA; } /* 2 LDA IMM */ | |
| 204 | OP(c9) { int tmp; RD_IMM; CMP; } /* 2 CMP IMM */ | |
| 205 | OP(e9) { int tmp; RD_IMM; SBC; } /* 2 SBC IMM */ | |
| 206 | ||
| 207 | OP(19) { int tmp; RD_ABY_P; ORA; } /* 4 ORA ABY page penalty */ | |
| 208 | OP(39) { int tmp; RD_ABY_P; AND; } /* 4 AND ABY page penalty */ | |
| 209 | OP(59) { int tmp; RD_ABY_P; EOR; } /* 4 EOR ABY page penalty */ | |
| 210 | OP(79) { int tmp; RD_ABY_P; ADC; } /* 4 ADC ABY page penalty */ | |
| 211 | OP(99) { int tmp; STA; WR_ABY_NP; } /* 5 STA ABY */ | |
| 212 | OP(b9) { int tmp; RD_ABY_P; LDA; } /* 4 LDA ABY page penalty */ | |
| 213 | OP(d9) { int tmp; RD_ABY_P; CMP; } /* 4 CMP ABY page penalty */ | |
| 214 | OP(f9) { int tmp; RD_ABY_P; SBC; } /* 4 SBC ABY page penalty */ | |
| 215 | ||
| 216 | OP(0a) { int tmp; RD_DUM; RD_ACC; ASL; WB_ACC; } /* 2 ASL A */ | |
| 217 | OP(2a) { int tmp; RD_DUM; RD_ACC; ROL; WB_ACC; } /* 2 ROL A */ | |
| 218 | OP(4a) { int tmp; RD_DUM; RD_ACC; LSR; WB_ACC; } /* 2 LSR A */ | |
| 219 | OP(6a) { int tmp; RD_DUM; RD_ACC; ROR; WB_ACC; } /* 2 ROR A */ | |
| 220 | OP(8a) { RD_DUM; TXA; } /* 2 TXA */ | |
| 221 | OP(aa) { RD_DUM; TAX; } /* 2 TAX */ | |
| 222 | OP(ca) { RD_DUM; DEX; } /* 2 DEX */ | |
| 223 | OP(ea) { RD_DUM; NOP; } /* 2 NOP */ | |
| 224 | ||
| 225 | OP(1a) { RD_DUM; NOP; } /* 2 NOP */ | |
| 226 | OP(3a) { RD_DUM; NOP; } /* 2 NOP */ | |
| 227 | OP(5a) { RD_DUM; NOP; } /* 2 NOP */ | |
| 228 | OP(7a) { RD_DUM; NOP; } /* 2 NOP */ | |
| 229 | OP(9a) { RD_DUM; TXS; } /* 2 TXS */ | |
| 230 | OP(ba) { RD_DUM; TSX; } /* 2 TSX */ | |
| 231 | OP(da) { RD_DUM; NOP; } /* 2 NOP */ | |
| 232 | OP(fa) { RD_DUM; NOP; } /* 2 NOP */ | |
| 233 | ||
| 234 | OP(0b) { int tmp; RD_IMM; ANC; } /* 2 ANC IMM */ | |
| 235 | OP(2b) { int tmp; RD_IMM; ANC; } /* 2 ANC IMM */ | |
| 236 | OP(4b) { int tmp; RD_IMM; ASR; WB_ACC; } /* 2 ASR IMM */ | |
| 237 | OP(6b) { int tmp; RD_IMM; ARR; WB_ACC; } /* 2 ARR IMM */ | |
| 238 | OP(8b) { int tmp; RD_IMM; AXA; } /* 2 AXA IMM */ | |
| 239 | OP(ab) { int tmp; RD_IMM; OAL; } /* 2 OAL IMM */ | |
| 240 | OP(cb) { int tmp; RD_IMM; ASX; } /* 2 ASX IMM */ | |
| 241 | OP(eb) { int tmp; RD_IMM; SBC; } /* 2 SBC IMM */ | |
| 242 | ||
| 243 | OP(1b) { int tmp; RD_ABY_NP; WB_EA; SLO; WB_EA; } /* 7 SLO ABY */ | |
| 244 | OP(3b) { int tmp; RD_ABY_NP; WB_EA; RLA; WB_EA; } /* 7 RLA ABY */ | |
| 245 | OP(5b) { int tmp; RD_ABY_NP; WB_EA; SRE; WB_EA; } /* 7 SRE ABY */ | |
| 246 | OP(7b) { int tmp; RD_ABY_NP; WB_EA; RRA; WB_EA; } /* 7 RRA ABY */ | |
| 247 | OP(9b) { int tmp; EA_ABY_NP; SSH; WB_EA; } /* 5 SSH ABY */ | |
| 248 | OP(bb) { int tmp; RD_ABY_P; AST; } /* 4 AST ABY page penalty */ | |
| 249 | OP(db) { int tmp; RD_ABY_NP; WB_EA; DCP; WB_EA; } /* 7 DCP ABY */ | |
| 250 | OP(fb) { int tmp; RD_ABY_NP; WB_EA; ISB; WB_EA; } /* 7 ISB ABY */ | |
| 251 | ||
| 252 | OP(0c) { RD_ABS_DISCARD; NOP; } /* 4 NOP ABS */ | |
| 253 | OP(2c) { int tmp; RD_ABS; BIT; } /* 4 BIT ABS */ | |
| 254 | OP(4c) { EA_ABS; JMP; } /* 3 JMP ABS */ | |
| 255 | OP(6c) { int tmp; EA_IND; JMP; } /* 5 JMP IND */ | |
| 256 | OP(8c) { int tmp; STY; WR_ABS; } /* 4 STY ABS */ | |
| 257 | OP(ac) { int tmp; RD_ABS; LDY; } /* 4 LDY ABS */ | |
| 258 | OP(cc) { int tmp; RD_ABS; CPY; } /* 4 CPY ABS */ | |
| 259 | OP(ec) { int tmp; RD_ABS; CPX; } /* 4 CPX ABS */ | |
| 260 | ||
| 261 | OP(1c) { RD_ABX_P_DISCARD; NOP; } /* 4 NOP ABX page penalty */ | |
| 262 | OP(3c) { RD_ABX_P_DISCARD; NOP; } /* 4 NOP ABX page penalty */ | |
| 263 | OP(5c) { RD_ABX_P_DISCARD; NOP; } /* 4 NOP ABX page penalty */ | |
| 264 | OP(7c) { RD_ABX_P_DISCARD; NOP; } /* 4 NOP ABX page penalty */ | |
| 265 | OP(9c) { int tmp; EA_ABX_NP; SYH; WB_EA; } /* 5 SYH ABX */ | |
| 266 | OP(bc) { int tmp; RD_ABX_P; LDY; } /* 4 LDY ABX page penalty */ | |
| 267 | OP(dc) { RD_ABX_P_DISCARD; NOP; } /* 4 NOP ABX page penalty */ | |
| 268 | OP(fc) { RD_ABX_P_DISCARD; NOP; } /* 4 NOP ABX page penalty */ | |
| 269 | ||
| 270 | OP(0d) { int tmp; RD_ABS; ORA; } /* 4 ORA ABS */ | |
| 271 | OP(2d) { int tmp; RD_ABS; AND; } /* 4 AND ABS */ | |
| 272 | OP(4d) { int tmp; RD_ABS; EOR; } /* 4 EOR ABS */ | |
| 273 | OP(6d) { int tmp; RD_ABS; ADC; } /* 4 ADC ABS */ | |
| 274 | OP(8d) { int tmp; STA; WR_ABS; } /* 4 STA ABS */ | |
| 275 | OP(ad) { int tmp; RD_ABS; LDA; } /* 4 LDA ABS */ | |
| 276 | OP(cd) { int tmp; RD_ABS; CMP; } /* 4 CMP ABS */ | |
| 277 | OP(ed) { int tmp; RD_ABS; SBC; } /* 4 SBC ABS */ | |
| 278 | ||
| 279 | OP(1d) { int tmp; RD_ABX_P; ORA; } /* 4 ORA ABX page penalty */ | |
| 280 | OP(3d) { int tmp; RD_ABX_P; AND; } /* 4 AND ABX page penalty */ | |
| 281 | OP(5d) { int tmp; RD_ABX_P; EOR; } /* 4 EOR ABX page penalty */ | |
| 282 | OP(7d) { int tmp; RD_ABX_P; ADC; } /* 4 ADC ABX page penalty */ | |
| 283 | OP(9d) { int tmp; STA; WR_ABX_NP; } /* 5 STA ABX */ | |
| 284 | OP(bd) { int tmp; RD_ABX_P; LDA; } /* 4 LDA ABX page penalty */ | |
| 285 | OP(dd) { int tmp; RD_ABX_P; CMP; } /* 4 CMP ABX page penalty */ | |
| 286 | OP(fd) { int tmp; RD_ABX_P; SBC; } /* 4 SBC ABX page penalty */ | |
| 287 | ||
| 288 | OP(0e) { int tmp; RD_ABS; WB_EA; ASL; WB_EA; } /* 6 ASL ABS */ | |
| 289 | OP(2e) { int tmp; RD_ABS; WB_EA; ROL; WB_EA; } /* 6 ROL ABS */ | |
| 290 | OP(4e) { int tmp; RD_ABS; WB_EA; LSR; WB_EA; } /* 6 LSR ABS */ | |
| 291 | OP(6e) { int tmp; RD_ABS; WB_EA; ROR; WB_EA; } /* 6 ROR ABS */ | |
| 292 | OP(8e) { int tmp; STX; WR_ABS; } /* 4 STX ABS */ | |
| 293 | OP(ae) { int tmp; RD_ABS; LDX; } /* 4 LDX ABS */ | |
| 294 | OP(ce) { int tmp; RD_ABS; WB_EA; DEC; WB_EA; } /* 6 DEC ABS */ | |
| 295 | OP(ee) { int tmp; RD_ABS; WB_EA; INC; WB_EA; } /* 6 INC ABS */ | |
| 296 | ||
| 297 | OP(1e) { int tmp; RD_ABX_NP; WB_EA; ASL; WB_EA; } /* 7 ASL ABX */ | |
| 298 | OP(3e) { int tmp; RD_ABX_NP; WB_EA; ROL; WB_EA; } /* 7 ROL ABX */ | |
| 299 | OP(5e) { int tmp; RD_ABX_NP; WB_EA; LSR; WB_EA; } /* 7 LSR ABX */ | |
| 300 | OP(7e) { int tmp; RD_ABX_NP; WB_EA; ROR; WB_EA; } /* 7 ROR ABX */ | |
| 301 | OP(9e) { int tmp; EA_ABY_NP; SXH; WB_EA; } /* 5 SXH ABY */ | |
| 302 | OP(be) { int tmp; RD_ABY_P; LDX; } /* 4 LDX ABY page penalty */ | |
| 303 | OP(de) { int tmp; RD_ABX_NP; WB_EA; DEC; WB_EA; } /* 7 DEC ABX */ | |
| 304 | OP(fe) { int tmp; RD_ABX_NP; WB_EA; INC; WB_EA; } /* 7 INC ABX */ | |
| 305 | ||
| 306 | OP(0f) { int tmp; RD_ABS; WB_EA; SLO; WB_EA; } /* 6 SLO ABS */ | |
| 307 | OP(2f) { int tmp; RD_ABS; WB_EA; RLA; WB_EA; } /* 6 RLA ABS */ | |
| 308 | OP(4f) { int tmp; RD_ABS; WB_EA; SRE; WB_EA; } /* 6 SRE ABS */ | |
| 309 | OP(6f) { int tmp; RD_ABS; WB_EA; RRA; WB_EA; } /* 6 RRA ABS */ | |
| 310 | OP(8f) { int tmp; SAX; WR_ABS; } /* 4 SAX ABS */ | |
| 311 | OP(af) { int tmp; RD_ABS; LAX; } /* 4 LAX ABS */ | |
| 312 | OP(cf) { int tmp; RD_ABS; WB_EA; DCP; WB_EA; } /* 6 DCP ABS */ | |
| 313 | OP(ef) { int tmp; RD_ABS; WB_EA; ISB; WB_EA; } /* 6 ISB ABS */ | |
| 314 | ||
| 315 | OP(1f) { int tmp; RD_ABX_NP; WB_EA; SLO; WB_EA; } /* 7 SLO ABX */ | |
| 316 | OP(3f) { int tmp; RD_ABX_NP; WB_EA; RLA; WB_EA; } /* 7 RLA ABX */ | |
| 317 | OP(5f) { int tmp; RD_ABX_NP; WB_EA; SRE; WB_EA; } /* 7 SRE ABX */ | |
| 318 | OP(7f) { int tmp; RD_ABX_NP; WB_EA; RRA; WB_EA; } /* 7 RRA ABX */ | |
| 319 | OP(9f) { int tmp; EA_ABY_NP; SAH; WB_EA; } /* 5 SAH ABY */ | |
| 320 | OP(bf) { int tmp; RD_ABY_P; LAX; } /* 4 LAX ABY page penalty */ | |
| 321 | OP(df) { int tmp; RD_ABX_NP; WB_EA; DCP; WB_EA; } /* 7 DCP ABX */ | |
| 322 | OP(ff) { int tmp; RD_ABX_NP; WB_EA; ISB; WB_EA; } /* 7 ISB ABX */ | |
| 323 | ||
| 324 | /* and here's the array of function pointers */ | |
| 325 | ||
| 326 | static void (*const insn6502[0x100])(m6502_Regs *cpustate) = { | |
| 327 | m6502_00,m6502_01,m6502_02,m6502_03,m6502_04,m6502_05,m6502_06,m6502_07, | |
| 328 | m6502_08,m6502_09,m6502_0a,m6502_0b,m6502_0c,m6502_0d,m6502_0e,m6502_0f, | |
| 329 | m6502_10,m6502_11,m6502_12,m6502_13,m6502_14,m6502_15,m6502_16,m6502_17, | |
| 330 | m6502_18,m6502_19,m6502_1a,m6502_1b,m6502_1c,m6502_1d,m6502_1e,m6502_1f, | |
| 331 | m6502_20,m6502_21,m6502_22,m6502_23,m6502_24,m6502_25,m6502_26,m6502_27, | |
| 332 | m6502_28,m6502_29,m6502_2a,m6502_2b,m6502_2c,m6502_2d,m6502_2e,m6502_2f, | |
| 333 | m6502_30,m6502_31,m6502_32,m6502_33,m6502_34,m6502_35,m6502_36,m6502_37, | |
| 334 | m6502_38,m6502_39,m6502_3a,m6502_3b,m6502_3c,m6502_3d,m6502_3e,m6502_3f, | |
| 335 | m6502_40,m6502_41,m6502_42,m6502_43,m6502_44,m6502_45,m6502_46,m6502_47, | |
| 336 | m6502_48,m6502_49,m6502_4a,m6502_4b,m6502_4c,m6502_4d,m6502_4e,m6502_4f, | |
| 337 | m6502_50,m6502_51,m6502_52,m6502_53,m6502_54,m6502_55,m6502_56,m6502_57, | |
| 338 | m6502_58,m6502_59,m6502_5a,m6502_5b,m6502_5c,m6502_5d,m6502_5e,m6502_5f, | |
| 339 | m6502_60,m6502_61,m6502_62,m6502_63,m6502_64,m6502_65,m6502_66,m6502_67, | |
| 340 | m6502_68,m6502_69,m6502_6a,m6502_6b,m6502_6c,m6502_6d,m6502_6e,m6502_6f, | |
| 341 | m6502_70,m6502_71,m6502_72,m6502_73,m6502_74,m6502_75,m6502_76,m6502_77, | |
| 342 | m6502_78,m6502_79,m6502_7a,m6502_7b,m6502_7c,m6502_7d,m6502_7e,m6502_7f, | |
| 343 | m6502_80,m6502_81,m6502_82,m6502_83,m6502_84,m6502_85,m6502_86,m6502_87, | |
| 344 | m6502_88,m6502_89,m6502_8a,m6502_8b,m6502_8c,m6502_8d,m6502_8e,m6502_8f, | |
| 345 | m6502_90,m6502_91,m6502_92,m6502_93,m6502_94,m6502_95,m6502_96,m6502_97, | |
| 346 | m6502_98,m6502_99,m6502_9a,m6502_9b,m6502_9c,m6502_9d,m6502_9e,m6502_9f, | |
| 347 | m6502_a0,m6502_a1,m6502_a2,m6502_a3,m6502_a4,m6502_a5,m6502_a6,m6502_a7, | |
| 348 | m6502_a8,m6502_a9,m6502_aa,m6502_ab,m6502_ac,m6502_ad,m6502_ae,m6502_af, | |
| 349 | m6502_b0,m6502_b1,m6502_b2,m6502_b3,m6502_b4,m6502_b5,m6502_b6,m6502_b7, | |
| 350 | m6502_b8,m6502_b9,m6502_ba,m6502_bb,m6502_bc,m6502_bd,m6502_be,m6502_bf, | |
| 351 | m6502_c0,m6502_c1,m6502_c2,m6502_c3,m6502_c4,m6502_c5,m6502_c6,m6502_c7, | |
| 352 | m6502_c8,m6502_c9,m6502_ca,m6502_cb,m6502_cc,m6502_cd,m6502_ce,m6502_cf, | |
| 353 | m6502_d0,m6502_d1,m6502_d2,m6502_d3,m6502_d4,m6502_d5,m6502_d6,m6502_d7, | |
| 354 | m6502_d8,m6502_d9,m6502_da,m6502_db,m6502_dc,m6502_dd,m6502_de,m6502_df, | |
| 355 | m6502_e0,m6502_e1,m6502_e2,m6502_e3,m6502_e4,m6502_e5,m6502_e6,m6502_e7, | |
| 356 | m6502_e8,m6502_e9,m6502_ea,m6502_eb,m6502_ec,m6502_ed,m6502_ee,m6502_ef, | |
| 357 | m6502_f0,m6502_f1,m6502_f2,m6502_f3,m6502_f4,m6502_f5,m6502_f6,m6502_f7, | |
| 358 | m6502_f8,m6502_f9,m6502_fa,m6502_fb,m6502_fc,m6502_fd,m6502_fe,m6502_ff | |
| 359 | }; | |
| 360 |
| r18874 | r18875 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * minc4510.h | |
| 4 | * Base macros for 4510 CPU files | |
| 5 | * | |
| 6 | *****************************************************************************/ | |
| 7 | ||
| 8 | ||
| 9 | /* 4510 flags */ | |
| 10 | #define F_C 0x01 | |
| 11 | #define F_Z 0x02 | |
| 12 | #define F_I 0x04 | |
| 13 | #define F_D 0x08 | |
| 14 | #define F_B 0x10 | |
| 15 | #define F_E 0x20 | |
| 16 | #define F_V 0x40 | |
| 17 | #define F_N 0x80 | |
| 18 | ||
| 19 | /* some shortcuts for improved readability */ | |
| 20 | #define A cpustate->a | |
| 21 | #define X cpustate->x | |
| 22 | #define Y cpustate->y | |
| 23 | #define P cpustate->p | |
| 24 | #define Z cpustate->z | |
| 25 | #define B cpustate->zp.b.h | |
| 26 | #define SW cpustate->sp.w.l | |
| 27 | #define SPL cpustate->sp.b.l | |
| 28 | #define SPH cpustate->sp.b.h | |
| 29 | #define SPD cpustate->sp.d | |
| 30 | ||
| 31 | #define NZ cpustate->nz | |
| 32 | ||
| 33 | #define EAL cpustate->ea.b.l | |
| 34 | #define EAH cpustate->ea.b.h | |
| 35 | #define EAW cpustate->ea.w.l | |
| 36 | #define EAD cpustate->ea.d | |
| 37 | ||
| 38 | #define ZPL cpustate->zp.b.l | |
| 39 | #define ZPH cpustate->zp.b.h | |
| 40 | #define ZPW cpustate->zp.w.l | |
| 41 | #define ZPD cpustate->zp.d | |
| 42 | ||
| 43 | #define PCL cpustate->pc.b.l | |
| 44 | #define PCH cpustate->pc.b.h | |
| 45 | #define PCW cpustate->pc.w.l | |
| 46 | #define PCD cpustate->pc.d | |
| 47 | ||
| 48 | #define PPC cpustate->ppc.d | |
| 49 | ||
| 50 | #define IRQ_STATE cpustate->irq_state | |
| 51 | #define AFTER_CLI cpustate->after_cli | |
| 52 | ||
| 53 | #define M4510_MEM(addr) (cpustate->mem[(addr)>>13]+(addr)) | |
| 54 | ||
| 55 | #define PEEK_OP() cpustate->direct->read_decrypted_byte(M4510_MEM(PCW)) | |
| 56 | ||
| 57 | #define RDMEM(addr) cpustate->space->read_byte(M4510_MEM(addr)); cpustate->icount -= 1 | |
| 58 | #define WRMEM(addr,data) cpustate->space->write_byte(M4510_MEM(addr),data); cpustate->icount -= 1 | |
| 59 | ||
| 60 | /*************************************************************** | |
| 61 | * RDOP read an opcode | |
| 62 | ***************************************************************/ | |
| 63 | #undef RDOP | |
| 64 | #define RDOP() m4510_cpu_readop(cpustate); cpustate->icount -= 1 | |
| 65 | ||
| 66 | /*************************************************************** | |
| 67 | * RDOPARG read an opcode argument | |
| 68 | ***************************************************************/ | |
| 69 | #undef RDOPARG | |
| 70 | #define RDOPARG() m4510_cpu_readop_arg(cpustate); cpustate->icount -= 1 |
| r18874 | r18875 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * tbl65c02.c | |
| 4 | * 65c02 opcode functions and function pointer table | |
| 5 | * | |
| 6 | * Copyright Juergen Buchmueller, all rights reserved. | |
| 7 | * | |
| 8 | * - This source code is released as freeware for non-commercial purposes. | |
| 9 | * - You are free to use and redistribute this code in modified or | |
| 10 | * unmodified form, provided you list me in the credits. | |
| 11 | * - If you modify this source code, you must add a notice to each modified | |
| 12 | * source file that it has been changed. If you're a nice person, you | |
| 13 | * will clearly mark each change too. :) | |
| 14 | * - If you wish to use this for commercial purposes, please contact me at | |
| 15 | * pullmoll@t-online.de | |
| 16 | * - The author of this copywritten work reserves the right to change the | |
| 17 | * terms of its usage and license at any time, including retroactively | |
| 18 | * - This entire notice must remain in the source code. | |
| 19 | * | |
| 20 | * Not sure about the timing of all the extra (undocumented) NOP instructions. | |
| 21 | * Core may need to be split up into two 65c02 core. Not all versions supported | |
| 22 | * the bit operation RMB/SMB/etc. | |
| 23 | * | |
| 24 | *****************************************************************************/ | |
| 25 | ||
| 26 | #undef OP | |
| 27 | #define OP(nn) INLINE void m65c02_##nn(m6502_Regs *cpustate) | |
| 28 | ||
| 29 | /***************************************************************************** | |
| 30 | ***************************************************************************** | |
| 31 | * | |
| 32 | * Implementations for 65C02 opcodes | |
| 33 | * | |
| 34 | * There are a few slight differences between Rockwell and WDC 65C02 CPUs. | |
| 35 | * The absolute indexed addressing mode RMW instructions take 6 cycles on | |
| 36 | * WDC 65C02 CPU but 7 cycles on a regular 6502 and a Rockwell 65C02 CPU. | |
| 37 | * TODO: Implement STP and WAI for wdc65c02. | |
| 38 | * | |
| 39 | ***************************************************************************** | |
| 40 | * op temp cycles rdmem opc wrmem ********************/ | |
| 41 | OP(00) { BRK_C02; } /* 7 BRK */ | |
| 42 | OP(20) { JSR; } /* 6 JSR */ | |
| 43 | OP(40) { RTI; } /* 6 RTI */ | |
| 44 | OP(60) { RTS; } /* 6 RTS */ | |
| 45 | OP(80) { int tmp; BRA_C02( 1 ); } /* 3-4 BRA REL */ | |
| 46 | OP(a0) { int tmp; RD_IMM; LDY; } /* 2 LDY IMM */ | |
| 47 | OP(c0) { int tmp; RD_IMM; CPY; } /* 2 CPY IMM */ | |
| 48 | OP(e0) { int tmp; RD_IMM; CPX; } /* 2 CPX IMM */ | |
| 49 | ||
| 50 | OP(10) { int tmp; BRA_C02( ! ( P & F_N ) ); } /* 2-4 BPL REL */ | |
| 51 | OP(30) { int tmp; BRA_C02( ( P & F_N ) ); } /* 2-4 BMI REL */ | |
| 52 | OP(50) { int tmp; BRA_C02( ! ( P & F_V ) ); } /* 2-4 BVC REL */ | |
| 53 | OP(70) { int tmp; BRA_C02( ( P & F_V ) ); } /* 2-4 BVS REL */ | |
| 54 | OP(90) { int tmp; BRA_C02( ! ( P & F_C ) ); } /* 2-4 BCC REL */ | |
| 55 | OP(b0) { int tmp; BRA_C02( ( P & F_C ) ); } /* 2-4 BCS REL */ | |
| 56 | OP(d0) { int tmp; BRA_C02( ! ( P & F_Z ) ); } /* 2-4 BNE REL */ | |
| 57 | OP(f0) { int tmp; BRA_C02( ( P & F_Z ) ); } /* 2-4 BEQ REL */ | |
| 58 | ||
| 59 | OP(01) { int tmp; RD_IDX; ORA; } /* 6 ORA IDX */ | |
| 60 | OP(21) { int tmp; RD_IDX; AND; } /* 6 AND IDX */ | |
| 61 | OP(41) { int tmp; RD_IDX; EOR; } /* 6 EOR IDX */ | |
| 62 | OP(61) { int tmp; RD_IDX; ADC_C02; } /* 6/7 ADC IDX */ | |
| 63 | OP(81) { int tmp; STA; WR_IDX; } /* 6 STA IDX */ | |
| 64 | OP(a1) { int tmp; RD_IDX; LDA; } /* 6 LDA IDX */ | |
| 65 | OP(c1) { int tmp; RD_IDX; CMP; } /* 6 CMP IDX */ | |
| 66 | OP(e1) { int tmp; RD_IDX; SBC_C02; } /* 6/7 SBC IDX */ | |
| 67 | ||
| 68 | OP(11) { int tmp; RD_IDY_C02_P; ORA; } /* 5 ORA IDY page penalty */ | |
| 69 | OP(31) { int tmp; RD_IDY_C02_P; AND; } /* 5 AND IDY page penalty */ | |
| 70 | OP(51) { int tmp; RD_IDY_C02_P; EOR; } /* 5 EOR IDY page penalty */ | |
| 71 | OP(71) { int tmp; RD_IDY_C02_P; ADC_C02; } /* 5/6 ADC IDY page penalty */ | |
| 72 | OP(91) { int tmp; STA; WR_IDY_C02_NP; } /* 6 STA IDY */ | |
| 73 | OP(b1) { int tmp; RD_IDY_C02_P; LDA; } /* 5 LDA IDY page penalty */ | |
| 74 | OP(d1) { int tmp; RD_IDY_C02_P; CMP; } /* 5 CMP IDY page penalty */ | |
| 75 | OP(f1) { int tmp; RD_IDY_C02_P; SBC_C02; } /* 5/6 SBC IDY page penalty */ | |
| 76 | ||
| 77 | OP(02) { RD_IMM_DISCARD; NOP; } /* 2 NOP not sure for rockwell */ | |
| 78 | OP(22) { RD_IMM_DISCARD; NOP; } /* 2 NOP not sure for rockwell */ | |
| 79 | OP(42) { RD_IMM_DISCARD; NOP; } /* 2 NOP not sure for rockwell */ | |
| 80 | OP(62) { RD_IMM_DISCARD; NOP; } /* 2 NOP not sure for rockwell */ | |
| 81 | OP(82) { RD_IMM_DISCARD; NOP; } /* 2 NOP not sure for rockwell */ | |
| 82 | OP(a2) { int tmp; RD_IMM; LDX; } /* 2 LDX IMM */ | |
| 83 | OP(c2) { RD_IMM_DISCARD; NOP; } /* 2 NOP not sure for rockwell */ | |
| 84 | OP(e2) { RD_IMM_DISCARD; NOP; } /* 2 NOP not sure for rockwell */ | |
| 85 | ||
| 86 | OP(12) { int tmp; RD_ZPI; ORA; } /* 5 ORA ZPI */ | |
| 87 | OP(32) { int tmp; RD_ZPI; AND; } /* 5 AND ZPI */ | |
| 88 | OP(52) { int tmp; RD_ZPI; EOR; } /* 5 EOR ZPI */ | |
| 89 | OP(72) { int tmp; RD_ZPI; ADC_C02; } /* 5/6 ADC ZPI */ | |
| 90 | OP(92) { int tmp; STA; WR_ZPI; } /* 5 STA ZPI */ | |
| 91 | OP(b2) { int tmp; RD_ZPI; LDA; } /* 5 LDA ZPI */ | |
| 92 | OP(d2) { int tmp; RD_ZPI; CMP; } /* 5 CMP ZPI */ | |
| 93 | OP(f2) { int tmp; RD_ZPI; SBC_C02; } /* 5/6 SBC ZPI */ | |
| 94 | ||
| 95 | OP(03) { NOP; } /* 1 NOP not sure for rockwell */ | |
| 96 | OP(23) { NOP; } /* 1 NOP not sure for rockwell */ | |
| 97 | OP(43) { NOP; } /* 1 NOP not sure for rockwell */ | |
| 98 | OP(63) { NOP; } /* 1 NOP not sure for rockwell */ | |
| 99 | OP(83) { NOP; } /* 1 NOP not sure for rockwell */ | |
| 100 | OP(a3) { NOP; } /* 1 NOP not sure for rockwell */ | |
| 101 | OP(c3) { NOP; } /* 1 NOP not sure for rockwell */ | |
| 102 | OP(e3) { NOP; } /* 1 NOP not sure for rockwell */ | |
| 103 | ||
| 104 | OP(13) { NOP; } /* 1 NOP not sure for rockwell */ | |
| 105 | OP(33) { NOP; } /* 1 NOP not sure for rockwell */ | |
| 106 | OP(53) { NOP; } /* 1 NOP not sure for rockwell */ | |
| 107 | OP(73) { NOP; } /* 1 NOP not sure for rockwell */ | |
| 108 | OP(93) { NOP; } /* 1 NOP not sure for rockwell */ | |
| 109 | OP(b3) { NOP; } /* 1 NOP not sure for rockwell */ | |
| 110 | OP(d3) { NOP; } /* 1 NOP not sure for rockwell */ | |
| 111 | OP(f3) { NOP; } /* 1 NOP not sure for rockwell */ | |
| 112 | ||
| 113 | OP(04) { int tmp; RD_ZPG; RD_EA; TSB; WB_EA; } /* 5 TSB ZPG */ | |
| 114 | OP(24) { int tmp; RD_ZPG; BIT; } /* 3 BIT ZPG */ | |
| 115 | OP(44) { RD_ZPG_DISCARD; NOP; } /* 3 NOP not sure for rockwell */ | |
| 116 | OP(64) { int tmp; STZ; WR_ZPG; } /* 3 STZ ZPG */ | |
| 117 | OP(84) { int tmp; STY; WR_ZPG; } /* 3 STY ZPG */ | |
| 118 | OP(a4) { int tmp; RD_ZPG; LDY; } /* 3 LDY ZPG */ | |
| 119 | OP(c4) { int tmp; RD_ZPG; CPY; } /* 3 CPY ZPG */ | |
| 120 | OP(e4) { int tmp; RD_ZPG; CPX; } /* 3 CPX ZPG */ | |
| 121 | ||
| 122 | OP(14) { int tmp; RD_ZPG; RD_EA; TRB; WB_EA; } /* 5 TRB ZPG */ | |
| 123 | OP(34) { int tmp; RD_ZPX; BIT; } /* 4 BIT ZPX */ | |
| 124 | OP(54) { RD_ZPX_DISCARD; NOP; } /* 4 NOP not sure for rockwell */ | |
| 125 | OP(74) { int tmp; STZ; WR_ZPX; } /* 4 STZ ZPX */ | |
| 126 | OP(94) { int tmp; STY; WR_ZPX; } /* 4 STY ZPX */ | |
| 127 | OP(b4) { int tmp; RD_ZPX; LDY; } /* 4 LDY ZPX */ | |
| 128 | OP(d4) { RD_ZPX_DISCARD; NOP; } /* 4 NOP not sure for rockwell */ | |
| 129 | OP(f4) { RD_ZPX_DISCARD; NOP; } /* 4 NOP not sure for rockwell */ | |
| 130 | ||
| 131 | OP(05) { int tmp; RD_ZPG; ORA; } /* 3 ORA ZPG */ | |
| 132 | OP(25) { int tmp; RD_ZPG; AND; } /* 3 AND ZPG */ | |
| 133 | OP(45) { int tmp; RD_ZPG; EOR; } /* 3 EOR ZPG */ | |
| 134 | OP(65) { int tmp; RD_ZPG; ADC_C02; } /* 3/4 ADC ZPG */ | |
| 135 | OP(85) { int tmp; STA; WR_ZPG; } /* 3 STA ZPG */ | |
| 136 | OP(a5) { int tmp; RD_ZPG; LDA; } /* 3 LDA ZPG */ | |
| 137 | OP(c5) { int tmp; RD_ZPG; CMP; } /* 3 CMP ZPG */ | |
| 138 | OP(e5) { int tmp; RD_ZPG; SBC_C02; } /* 3/4 SBC ZPG */ | |
| 139 | ||
| 140 | OP(15) { int tmp; RD_ZPX; ORA; } /* 4 ORA ZPX */ | |
| 141 | OP(35) { int tmp; RD_ZPX; AND; } /* 4 AND ZPX */ | |
| 142 | OP(55) { int tmp; RD_ZPX; EOR; } /* 4 EOR ZPX */ | |
| 143 | OP(75) { int tmp; RD_ZPX; ADC_C02; } /* 4/5 ADC ZPX */ | |
| 144 | OP(95) { int tmp; STA; WR_ZPX; } /* 4 STA ZPX */ | |
| 145 | OP(b5) { int tmp; RD_ZPX; LDA; } /* 4 LDA ZPX */ | |
| 146 | OP(d5) { int tmp; RD_ZPX; CMP; } /* 4 CMP ZPX */ | |
| 147 | OP(f5) { int tmp; RD_ZPX; SBC_C02; } /* 4/5 SBC ZPX */ | |
| 148 | ||
| 149 | OP(06) { int tmp; RD_ZPG, RD_EA; ASL; WB_EA; } /* 5 ASL ZPG */ | |
| 150 | OP(26) { int tmp; RD_ZPG; RD_EA; ROL; WB_EA; } /* 5 ROL ZPG */ | |
| 151 | OP(46) { int tmp; RD_ZPG; RD_EA; LSR; WB_EA; } /* 5 LSR ZPG */ | |
| 152 | OP(66) { int tmp; RD_ZPG; RD_EA; ROR; WB_EA; } /* 5 ROR ZPG */ | |
| 153 | OP(86) { int tmp; STX; WR_ZPG; } /* 3 STX ZPG */ | |
| 154 | OP(a6) { int tmp; RD_ZPG; LDX; } /* 3 LDX ZPG */ | |
| 155 | OP(c6) { int tmp; RD_ZPG; RD_EA; DEC; WB_EA; } /* 5 DEC ZPG */ | |
| 156 | OP(e6) { int tmp; RD_ZPG; RD_EA; INC; WB_EA; } /* 5 INC ZPG */ | |
| 157 | ||
| 158 | OP(16) { int tmp; RD_ZPX; RD_EA; ASL; WB_EA; } /* 6 ASL ZPX */ | |
| 159 | OP(36) { int tmp; RD_ZPX; RD_EA; ROL; WB_EA; } /* 6 ROL ZPX */ | |
| 160 | OP(56) { int tmp; RD_ZPX; RD_EA; LSR; WB_EA; } /* 6 LSR ZPX */ | |
| 161 | OP(76) { int tmp; RD_ZPX; RD_EA; ROR; WB_EA; } /* 6 ROR ZPX */ | |
| 162 | OP(96) { int tmp; STX; WR_ZPY; } /* 4 STX ZPY */ | |
| 163 | OP(b6) { int tmp; RD_ZPY; LDX; } /* 4 LDX ZPY */ | |
| 164 | OP(d6) { int tmp; RD_ZPX; RD_EA; DEC; WB_EA; } /* 6 DEC ZPX */ | |
| 165 | OP(f6) { int tmp; RD_ZPX; RD_EA; INC; WB_EA; } /* 6 INC ZPX */ | |
| 166 | ||
| 167 | OP(07) { int tmp; RD_ZPG; RD_EA; RMB(0);WB_EA; } /* 5 RMB0 ZPG */ | |
| 168 | OP(27) { int tmp; RD_ZPG; RD_EA; RMB(2);WB_EA; } /* 5 RMB2 ZPG */ | |
| 169 | OP(47) { int tmp; RD_ZPG; RD_EA; RMB(4);WB_EA; } /* 5 RMB4 ZPG */ | |
| 170 | OP(67) { int tmp; RD_ZPG; RD_EA; RMB(6);WB_EA; } /* 5 RMB6 ZPG */ | |
| 171 | OP(87) { int tmp; RD_ZPG; RD_EA; SMB(0);WB_EA; } /* 5 SMB0 ZPG */ | |
| 172 | OP(a7) { int tmp; RD_ZPG; RD_EA; SMB(2);WB_EA; } /* 5 SMB2 ZPG */ | |
| 173 | OP(c7) { int tmp; RD_ZPG; RD_EA; SMB(4);WB_EA; } /* 5 SMB4 ZPG */ | |
| 174 | OP(e7) { int tmp; RD_ZPG; RD_EA; SMB(6);WB_EA; } /* 5 SMB6 ZPG */ | |
| 175 | ||
| 176 | OP(17) { int tmp; RD_ZPG; RD_EA; RMB(1);WB_EA; } /* 5 RMB1 ZPG */ | |
| 177 | OP(37) { int tmp; RD_ZPG; RD_EA; RMB(3);WB_EA; } /* 5 RMB3 ZPG */ | |
| 178 | OP(57) { int tmp; RD_ZPG; RD_EA; RMB(5);WB_EA; } /* 5 RMB5 ZPG */ | |
| 179 | OP(77) { int tmp; RD_ZPG; RD_EA; RMB(7);WB_EA; } /* 5 RMB7 ZPG */ | |
| 180 | OP(97) { int tmp; RD_ZPG; RD_EA; SMB(1);WB_EA; } /* 5 SMB1 ZPG */ | |
| 181 | OP(b7) { int tmp; RD_ZPG; RD_EA; SMB(3);WB_EA; } /* 5 SMB3 ZPG */ | |
| 182 | OP(d7) { int tmp; RD_ZPG; RD_EA; SMB(5);WB_EA; } /* 5 SMB5 ZPG */ | |
| 183 | OP(f7) { int tmp; RD_ZPG; RD_EA; SMB(7);WB_EA; } /* 5 SMB7 ZPG */ | |
| 184 | ||
| 185 | OP(08) { RD_DUM; PHP; } /* 3 PHP */ | |
| 186 | OP(28) { RD_DUM; PLP; } /* 4 PLP */ | |
| 187 | OP(48) { RD_DUM; PHA; } /* 3 PHA */ | |
| 188 | OP(68) { RD_DUM; PLA; } /* 4 PLA */ | |
| 189 | OP(88) { RD_DUM; DEY; } /* 2 DEY */ | |
| 190 | OP(a8) { RD_DUM; TAY; } /* 2 TAY */ | |
| 191 | OP(c8) { RD_DUM; INY; } /* 2 INY */ | |
| 192 | OP(e8) { RD_DUM; INX; } /* 2 INX */ | |
| 193 | ||
| 194 | OP(18) { RD_DUM; CLC; } /* 2 CLC */ | |
| 195 | OP(38) { RD_DUM; SEC; } /* 2 SEC */ | |
| 196 | OP(58) { RD_DUM; CLI; } /* 2 CLI */ | |
| 197 | OP(78) { RD_DUM; SEI; } /* 2 SEI */ | |
| 198 | OP(98) { RD_DUM; TYA; } /* 2 TYA */ | |
| 199 | OP(b8) { RD_DUM; CLV; } /* 2 CLV */ | |
| 200 | OP(d8) { RD_DUM; CLD; } /* 2 CLD */ | |
| 201 | OP(f8) { RD_DUM; SED; } /* 2 SED */ | |
| 202 | ||
| 203 | OP(09) { int tmp; RD_IMM; ORA; } /* 2 ORA IMM */ | |
| 204 | OP(29) { int tmp; RD_IMM; AND; } /* 2 AND IMM */ | |
| 205 | OP(49) { int tmp; RD_IMM; EOR; } /* 2 EOR IMM */ | |
| 206 | OP(69) { int tmp; RD_IMM; ADC_C02; } /* 2/3 ADC IMM */ | |
| 207 | OP(89) { int tmp; RD_IMM; BIT_IMM_C02; } /* 2 BIT IMM */ | |
| 208 | OP(a9) { int tmp; RD_IMM; LDA; } /* 2 LDA IMM */ | |
| 209 | OP(c9) { int tmp; RD_IMM; CMP; } /* 2 CMP IMM */ | |
| 210 | OP(e9) { int tmp; RD_IMM; SBC_C02; } /* 2/3 SBC IMM */ | |
| 211 | ||
| 212 | OP(19) { int tmp; RD_ABY_C02_P; ORA; } /* 4 ORA ABY page penalty */ | |
| 213 | OP(39) { int tmp; RD_ABY_C02_P; AND; } /* 4 AND ABY page penalty */ | |
| 214 | OP(59) { int tmp; RD_ABY_C02_P; EOR; } /* 4 EOR ABY page penalty */ | |
| 215 | OP(79) { int tmp; RD_ABY_C02_P; ADC_C02; } /* 4/5 ADC ABY page penalty */ | |
| 216 | OP(99) { int tmp; STA; WR_ABY_C02_NP; } /* 5 STA ABY */ | |
| 217 | OP(b9) { int tmp; RD_ABY_C02_P; LDA; } /* 4 LDA ABY page penalty */ | |
| 218 | OP(d9) { int tmp; RD_ABY_C02_P; CMP; } /* 4 CMP ABY page penalty */ | |
| 219 | OP(f9) { int tmp; RD_ABY_C02_P; SBC_C02; } /* 4/5 SBC ABY page penalty */ | |
| 220 | ||
| 221 | OP(0a) { int tmp; RD_DUM; RD_ACC; ASL; WB_ACC; } /* 2 ASL A */ | |
| 222 | OP(2a) { int tmp; RD_DUM; RD_ACC; ROL; WB_ACC; } /* 2 ROL A */ | |
| 223 | OP(4a) { int tmp; RD_DUM; RD_ACC; LSR; WB_ACC; } /* 2 LSR A */ | |
| 224 | OP(6a) { int tmp; RD_DUM; RD_ACC; ROR; WB_ACC; } /* 2 ROR A */ | |
| 225 | OP(8a) { RD_DUM; TXA; } /* 2 TXA */ | |
| 226 | OP(aa) { RD_DUM; TAX; } /* 2 TAX */ | |
| 227 | OP(ca) { RD_DUM; DEX; } /* 2 DEX */ | |
| 228 | OP(ea) { RD_DUM; NOP; } /* 2 NOP */ | |
| 229 | ||
| 230 | OP(1a) { RD_DUM;INA; } /* 2 INA */ | |
| 231 | OP(3a) { RD_DUM;DEA; } /* 2 DEA */ | |
| 232 | OP(5a) { RD_DUM;PHY; } /* 3 PHY */ | |
| 233 | OP(7a) { RD_DUM;PLY; } /* 4 PLY */ | |
| 234 | OP(9a) { RD_DUM; TXS; } /* 2 TXS */ | |
| 235 | OP(ba) { RD_DUM; TSX; } /* 2 TSX */ | |
| 236 | OP(da) { RD_DUM;PHX; } /* 3 PHX */ | |
| 237 | OP(fa) { RD_DUM;PLX; } /* 4 PLX */ | |
| 238 | ||
| 239 | OP(0b) { NOP; } /* 1 NOP not sure for rockwell */ | |
| 240 | OP(2b) { NOP; } /* 1 NOP not sure for rockwell */ | |
| 241 | OP(4b) { NOP; } /* 1 NOP not sure for rockwell */ | |
| 242 | OP(6b) { NOP; } /* 1 NOP not sure for rockwell */ | |
| 243 | OP(8b) { NOP; } /* 1 NOP not sure for rockwell */ | |
| 244 | OP(ab) { NOP; } /* 1 NOP not sure for rockwell */ | |
| 245 | OP(cb) { NOP; } /* 1 NOP not sure for rockwell */ | |
| 246 | OP(eb) { NOP; } /* 1 NOP not sure for rockwell */ | |
| 247 | ||
| 248 | OP(1b) { NOP; } /* 1 NOP not sure for rockwell */ | |
| 249 | OP(3b) { NOP; } /* 1 NOP not sure for rockwell */ | |
| 250 | OP(5b) { NOP; } /* 1 NOP not sure for rockwell */ | |
| 251 | OP(7b) { NOP; } /* 1 NOP not sure for rockwell */ | |
| 252 | OP(9b) { NOP; } /* 1 NOP not sure for rockwell */ | |
| 253 | OP(bb) { NOP; } /* 1 NOP not sure for rockwell */ | |
| 254 | OP(db) { NOP; } /* 1 NOP not sure for rockwell */ | |
| 255 | OP(fb) { NOP; } /* 1 NOP not sure for rockwell */ | |
| 256 | ||
| 257 | OP(0c) { int tmp; RD_ABS; RD_EA; TSB; WB_EA; } /* 6 TSB ABS */ | |
| 258 | OP(2c) { int tmp; RD_ABS; BIT; } /* 4 BIT ABS */ | |
| 259 | OP(4c) { EA_ABS; JMP; } /* 3 JMP ABS */ | |
| 260 | OP(6c) { int tmp; EA_IND_C02; JMP; } /* 6 JMP IND */ | |
| 261 | OP(8c) { int tmp; STY; WR_ABS; } /* 4 STY ABS */ | |
| 262 | OP(ac) { int tmp; RD_ABS; LDY; } /* 4 LDY ABS */ | |
| 263 | OP(cc) { int tmp; RD_ABS; CPY; } /* 4 CPY ABS */ | |
| 264 | OP(ec) { int tmp; RD_ABS; CPX; } /* 4 CPX ABS */ | |
| 265 | ||
| 266 | OP(1c) { int tmp; RD_ABS; RD_EA; TRB; WB_EA; } /* 6 TRB ABS */ | |
| 267 | OP(3c) { int tmp; RD_ABX_C02_P; BIT; } /* 4 BIT ABX page penalty */ | |
| 268 | OP(5c) { RD_ABX_C02_NP_DISCARD; RD_DUM; RD_DUM; RD_DUM; RD_DUM; } /* 8 NOP ABX not sure for rockwell. Page penalty not sure */ | |
| 269 | OP(7c) { int tmp; EA_IAX; JMP; } /* 6 JMP IAX page penalty */ | |
| 270 | OP(9c) { int tmp; STZ; WR_ABS; } /* 4 STZ ABS */ | |
| 271 | OP(bc) { int tmp; RD_ABX_C02_P; LDY; } /* 4 LDY ABX page penalty */ | |
| 272 | OP(dc) { RD_ABX_C02_NP_DISCARD; NOP; } /* 4 NOP ABX not sure for rockwell. Page penalty not sure */ | |
| 273 | OP(fc) { RD_ABX_C02_NP_DISCARD; NOP; } /* 4 NOP ABX not sure for rockwell. Page penalty not sure */ | |
| 274 | ||
| 275 | OP(0d) { int tmp; RD_ABS; ORA; } /* 4 ORA ABS */ | |
| 276 | OP(2d) { int tmp; RD_ABS; AND; } /* 4 AND ABS */ | |
| 277 | OP(4d) { int tmp; RD_ABS; EOR; } /* 4 EOR ABS */ | |
| 278 | OP(6d) { int tmp; RD_ABS; ADC_C02; } /* 4/5 ADC ABS */ | |
| 279 | OP(8d) { int tmp; STA; WR_ABS; } /* 4 STA ABS */ | |
| 280 | OP(ad) { int tmp; RD_ABS; LDA; } /* 4 LDA ABS */ | |
| 281 | OP(cd) { int tmp; RD_ABS; CMP; } /* 4 CMP ABS */ | |
| 282 | OP(ed) { int tmp; RD_ABS; SBC_C02; } /* 4/5 SBC ABS */ | |
| 283 | ||
| 284 | OP(1d) { int tmp; RD_ABX_C02_P; ORA; } /* 4 ORA ABX page penalty */ | |
| 285 | OP(3d) { int tmp; RD_ABX_C02_P; AND; } /* 4 AND ABX page penalty */ | |
| 286 | OP(5d) { int tmp; RD_ABX_C02_P; EOR; } /* 4 EOR ABX page penalty */ | |
| 287 | OP(7d) { int tmp; RD_ABX_C02_P; ADC_C02; } /* 4/5 ADC ABX page penalty */ | |
| 288 | OP(9d) { int tmp; STA; WR_ABX_C02_NP; } /* 5 STA ABX */ | |
| 289 | OP(bd) { int tmp; RD_ABX_C02_P; LDA; } /* 4 LDA ABX page penalty */ | |
| 290 | OP(dd) { int tmp; RD_ABX_C02_P; CMP; } /* 4 CMP ABX page penalty */ | |
| 291 | OP(fd) { int tmp; RD_ABX_C02_P; SBC_C02; } /* 4/5 SBC ABX page penalty */ | |
| 292 | ||
| 293 | OP(0e) { int tmp; RD_ABS; RD_EA; ASL; WB_EA; } /* 6 ASL ABS */ | |
| 294 | OP(2e) { int tmp; RD_ABS; RD_EA; ROL; WB_EA; } /* 6 ROL ABS */ | |
| 295 | OP(4e) { int tmp; RD_ABS; RD_EA; LSR; WB_EA; } /* 6 LSR ABS */ | |
| 296 | OP(6e) { int tmp; RD_ABS; RD_EA; ROR; WB_EA; } /* 6 ROR ABS */ | |
| 297 | OP(8e) { int tmp; STX; WR_ABS; } /* 4 STX ABS */ | |
| 298 | OP(ae) { int tmp; RD_ABS; LDX; } /* 4 LDX ABS */ | |
| 299 | OP(ce) { int tmp; RD_ABS; RD_EA; DEC; WB_EA; } /* 6 DEC ABS */ | |
| 300 | OP(ee) { int tmp; RD_ABS; RD_EA; INC; WB_EA; } /* 6 INC ABS */ | |
| 301 | ||
| 302 | OP(1e) { int tmp; RD_ABX_C02_NP; RD_EA; ASL; WB_EA; } /* 7 ASL ABX */ | |
| 303 | OP(3e) { int tmp; RD_ABX_C02_NP; RD_EA; ROL; WB_EA; } /* 7 ROL ABX */ | |
| 304 | OP(5e) { int tmp; RD_ABX_C02_NP; RD_EA; LSR; WB_EA; } /* 7 LSR ABX */ | |
| 305 | OP(7e) { int tmp; RD_ABX_C02_NP; RD_EA; ROR; WB_EA; } /* 7 ROR ABX */ | |
| 306 | OP(9e) { int tmp; STZ; WR_ABX_C02_NP; } /* 5 STZ ABX */ | |
| 307 | OP(be) { int tmp; RD_ABY_C02_P; LDX; } /* 4 LDX ABY page penalty */ | |
| 308 | OP(de) { int tmp; RD_ABX_C02_NP; RD_EA; DEC; WB_EA; } /* 7 DEC ABX */ | |
| 309 | OP(fe) { int tmp; RD_ABX_C02_NP; RD_EA; INC; WB_EA; } /* 7 INC ABX */ | |
| 310 | ||
| 311 | OP(0f) { int tmp; RD_ZPG; BBR(0); } /* 5-7 BBR0 ZPG */ | |
| 312 | OP(2f) { int tmp; RD_ZPG; BBR(2); } /* 5-7 BBR2 ZPG */ | |
| 313 | OP(4f) { int tmp; RD_ZPG; BBR(4); } /* 5-7 BBR4 ZPG */ | |
| 314 | OP(6f) { int tmp; RD_ZPG; BBR(6); } /* 5-7 BBR6 ZPG */ | |
| 315 | OP(8f) { int tmp; RD_ZPG; BBS(0); } /* 5-7 BBS0 ZPG */ | |
| 316 | OP(af) { int tmp; RD_ZPG; BBS(2); } /* 5-7 BBS2 ZPG */ | |
| 317 | OP(cf) { int tmp; RD_ZPG; BBS(4); } /* 5-7 BBS4 ZPG */ | |
| 318 | OP(ef) { int tmp; RD_ZPG; BBS(6); } /* 5-7 BBS6 ZPG */ | |
| 319 | ||
| 320 | OP(1f) { int tmp; RD_ZPG; BBR(1); } /* 5-7 BBR1 ZPG */ | |
| 321 | OP(3f) { int tmp; RD_ZPG; BBR(3); } /* 5-7 BBR3 ZPG */ | |
| 322 | OP(5f) { int tmp; RD_ZPG; BBR(5); } /* 5-7 BBR5 ZPG */ | |
| 323 | OP(7f) { int tmp; RD_ZPG; BBR(7); } /* 5-7 BBR7 ZPG */ | |
| 324 | OP(9f) { int tmp; RD_ZPG; BBS(1); } /* 5-7 BBS1 ZPG */ | |
| 325 | OP(bf) { int tmp; RD_ZPG; BBS(3); } /* 5-7 BBS3 ZPG */ | |
| 326 | OP(df) { int tmp; RD_ZPG; BBS(5); } /* 5-7 BBS5 ZPG */ | |
| 327 | OP(ff) { int tmp; RD_ZPG; BBS(7); } /* 5-7 BBS7 ZPG */ | |
| 328 | ||
| 329 | static void (*const insn65c02[0x100])(m6502_Regs *cpustate) = { | |
| 330 | m65c02_00,m65c02_01,m65c02_02,m65c02_03,m65c02_04,m65c02_05,m65c02_06,m65c02_07, | |
| 331 | m65c02_08,m65c02_09,m65c02_0a,m65c02_0b,m65c02_0c,m65c02_0d,m65c02_0e,m65c02_0f, | |
| 332 | m65c02_10,m65c02_11,m65c02_12,m65c02_13,m65c02_14,m65c02_15,m65c02_16,m65c02_17, | |
| 333 | m65c02_18,m65c02_19,m65c02_1a,m65c02_1b,m65c02_1c,m65c02_1d,m65c02_1e,m65c02_1f, | |
| 334 | m65c02_20,m65c02_21,m65c02_22,m65c02_23,m65c02_24,m65c02_25,m65c02_26,m65c02_27, | |
| 335 | m65c02_28,m65c02_29,m65c02_2a,m65c02_2b,m65c02_2c,m65c02_2d,m65c02_2e,m65c02_2f, | |
| 336 | m65c02_30,m65c02_31,m65c02_32,m65c02_33,m65c02_34,m65c02_35,m65c02_36,m65c02_37, | |
| 337 | m65c02_38,m65c02_39,m65c02_3a,m65c02_3b,m65c02_3c,m65c02_3d,m65c02_3e,m65c02_3f, | |
| 338 | m65c02_40,m65c02_41,m65c02_42,m65c02_43,m65c02_44,m65c02_45,m65c02_46,m65c02_47, | |
| 339 | m65c02_48,m65c02_49,m65c02_4a,m65c02_4b,m65c02_4c,m65c02_4d,m65c02_4e,m65c02_4f, | |
| 340 | m65c02_50,m65c02_51,m65c02_52,m65c02_53,m65c02_54,m65c02_55,m65c02_56,m65c02_57, | |
| 341 | m65c02_58,m65c02_59,m65c02_5a,m65c02_5b,m65c02_5c,m65c02_5d,m65c02_5e,m65c02_5f, | |
| 342 | m65c02_60,m65c02_61,m65c02_62,m65c02_63,m65c02_64,m65c02_65,m65c02_66,m65c02_67, | |
| 343 | m65c02_68,m65c02_69,m65c02_6a,m65c02_6b,m65c02_6c,m65c02_6d,m65c02_6e,m65c02_6f, | |
| 344 | m65c02_70,m65c02_71,m65c02_72,m65c02_73,m65c02_74,m65c02_75,m65c02_76,m65c02_77, | |
| 345 | m65c02_78,m65c02_79,m65c02_7a,m65c02_7b,m65c02_7c,m65c02_7d,m65c02_7e,m65c02_7f, | |
| 346 | m65c02_80,m65c02_81,m65c02_82,m65c02_83,m65c02_84,m65c02_85,m65c02_86,m65c02_87, | |
| 347 | m65c02_88,m65c02_89,m65c02_8a,m65c02_8b,m65c02_8c,m65c02_8d,m65c02_8e,m65c02_8f, | |
| 348 | m65c02_90,m65c02_91,m65c02_92,m65c02_93,m65c02_94,m65c02_95,m65c02_96,m65c02_97, | |
| 349 | m65c02_98,m65c02_99,m65c02_9a,m65c02_9b,m65c02_9c,m65c02_9d,m65c02_9e,m65c02_9f, | |
| 350 | m65c02_a0,m65c02_a1,m65c02_a2,m65c02_a3,m65c02_a4,m65c02_a5,m65c02_a6,m65c02_a7, | |
| 351 | m65c02_a8,m65c02_a9,m65c02_aa,m65c02_ab,m65c02_ac,m65c02_ad,m65c02_ae,m65c02_af, | |
| 352 | m65c02_b0,m65c02_b1,m65c02_b2,m65c02_b3,m65c02_b4,m65c02_b5,m65c02_b6,m65c02_b7, | |
| 353 | m65c02_b8,m65c02_b9,m65c02_ba,m65c02_bb,m65c02_bc,m65c02_bd,m65c02_be,m65c02_bf, | |
| 354 | m65c02_c0,m65c02_c1,m65c02_c2,m65c02_c3,m65c02_c4,m65c02_c5,m65c02_c6,m65c02_c7, | |
| 355 | m65c02_c8,m65c02_c9,m65c02_ca,m65c02_cb,m65c02_cc,m65c02_cd,m65c02_ce,m65c02_cf, | |
| 356 | m65c02_d0,m65c02_d1,m65c02_d2,m65c02_d3,m65c02_d4,m65c02_d5,m65c02_d6,m65c02_d7, | |
| 357 | m65c02_d8,m65c02_d9,m65c02_da,m65c02_db,m65c02_dc,m65c02_dd,m65c02_de,m65c02_df, | |
| 358 | m65c02_e0,m65c02_e1,m65c02_e2,m65c02_e3,m65c02_e4,m65c02_e5,m65c02_e6,m65c02_e7, | |
| 359 | m65c02_e8,m65c02_e9,m65c02_ea,m65c02_eb,m65c02_ec,m65c02_ed,m65c02_ee,m65c02_ef, | |
| 360 | m65c02_f0,m65c02_f1,m65c02_f2,m65c02_f3,m65c02_f4,m65c02_f5,m65c02_f6,m65c02_f7, | |
| 361 | m65c02_f8,m65c02_f9,m65c02_fa,m65c02_fb,m65c02_fc,m65c02_fd,m65c02_fe,m65c02_ff | |
| 362 | }; | |
| 363 | ||
| 364 | #ifdef WDC65C02 | |
| 365 | OP(cb_wdc) { RD_DUM; RD_DUM; } /* 3 WAI, TODO: Implement HALT mode */ | |
| 366 | OP(db_wdc) { RD_DUM; RD_DUM; } /* 3 STP, TODO: Implement STP mode */ | |
| 367 | OP(1e_wdc) { int tmp; RD_ABX_P; RD_EA; ASL; WB_EA; } /* 6 ASL ABX page penalty */ | |
| 368 | OP(3e_wdc) { int tmp; RD_ABX_P; RD_EA; ROL; WB_EA; } /* 6 ROL ABX page penalty */ | |
| 369 | OP(5e_wdc) { int tmp; RD_ABX_P; RD_EA; LSR; WB_EA; } /* 6 LSR ABX page penalty */ | |
| 370 | OP(7e_wdc) { int tmp; RD_ABX_P; RD_EA; ROR; WB_EA; } /* 6 ROR ABX page penalty */ | |
| 371 | OP(de_wdc) { int tmp; RD_ABX_P; RD_EA; DEC; WB_EA; } /* 6 DEC ABX page penalty */ | |
| 372 | OP(fe_wdc) { int tmp; RD_ABX_P; RD_EA; INC; WB_EA; } /* 6 INC ABX page penalty */ | |
| 373 | ||
| 374 | static void (*const insnwdc65c02[0x100])(m6502_Regs *cpustate) = { | |
| 375 | m65c02_00,m65c02_01,m65c02_02,m65c02_03,m65c02_04,m65c02_05,m65c02_06,m65c02_07, | |
| 376 | m65c02_08,m65c02_09,m65c02_0a,m65c02_0b,m65c02_0c,m65c02_0d,m65c02_0e,m65c02_0f, | |
| 377 | m65c02_10,m65c02_11,m65c02_12,m65c02_13,m65c02_14,m65c02_15,m65c02_16,m65c02_17, | |
| 378 | m65c02_18,m65c02_19,m65c02_1a,m65c02_1b,m65c02_1c,m65c02_1d,m65c02_1e_wdc,m65c02_1f, | |
| 379 | m65c02_20,m65c02_21,m65c02_22,m65c02_23,m65c02_24,m65c02_25,m65c02_26,m65c02_27, | |
| 380 | m65c02_28,m65c02_29,m65c02_2a,m65c02_2b,m65c02_2c,m65c02_2d,m65c02_2e,m65c02_2f, | |
| 381 | m65c02_30,m65c02_31,m65c02_32,m65c02_33,m65c02_34,m65c02_35,m65c02_36,m65c02_37, | |
| 382 | m65c02_38,m65c02_39,m65c02_3a,m65c02_3b,m65c02_3c,m65c02_3d,m65c02_3e_wdc,m65c02_3f, | |
| 383 | m65c02_40,m65c02_41,m65c02_42,m65c02_43,m65c02_44,m65c02_45,m65c02_46,m65c02_47, | |
| 384 | m65c02_48,m65c02_49,m65c02_4a,m65c02_4b,m65c02_4c,m65c02_4d,m65c02_4e,m65c02_4f, | |
| 385 | m65c02_50,m65c02_51,m65c02_52,m65c02_53,m65c02_54,m65c02_55,m65c02_56,m65c02_57, | |
| 386 | m65c02_58,m65c02_59,m65c02_5a,m65c02_5b,m65c02_5c,m65c02_5d,m65c02_5e_wdc,m65c02_5f, | |
| 387 | m65c02_60,m65c02_61,m65c02_62,m65c02_63,m65c02_64,m65c02_65,m65c02_66,m65c02_67, | |
| 388 | m65c02_68,m65c02_69,m65c02_6a,m65c02_6b,m65c02_6c,m65c02_6d,m65c02_6e,m65c02_6f, | |
| 389 | m65c02_70,m65c02_71,m65c02_72,m65c02_73,m65c02_74,m65c02_75,m65c02_76,m65c02_77, | |
| 390 | m65c02_78,m65c02_79,m65c02_7a,m65c02_7b,m65c02_7c,m65c02_7d,m65c02_7e_wdc,m65c02_7f, | |
| 391 | m65c02_80,m65c02_81,m65c02_82,m65c02_83,m65c02_84,m65c02_85,m65c02_86,m65c02_87, | |
| 392 | m65c02_88,m65c02_89,m65c02_8a,m65c02_8b,m65c02_8c,m65c02_8d,m65c02_8e,m65c02_8f, | |
| 393 | m65c02_90,m65c02_91,m65c02_92,m65c02_93,m65c02_94,m65c02_95,m65c02_96,m65c02_97, | |
| 394 | m65c02_98,m65c02_99,m65c02_9a,m65c02_9b,m65c02_9c,m65c02_9d,m65c02_9e,m65c02_9f, | |
| 395 | m65c02_a0,m65c02_a1,m65c02_a2,m65c02_a3,m65c02_a4,m65c02_a5,m65c02_a6,m65c02_a7, | |
| 396 | m65c02_a8,m65c02_a9,m65c02_aa,m65c02_ab,m65c02_ac,m65c02_ad,m65c02_ae,m65c02_af, | |
| 397 | m65c02_b0,m65c02_b1,m65c02_b2,m65c02_b3,m65c02_b4,m65c02_b5,m65c02_b6,m65c02_b7, | |
| 398 | m65c02_b8,m65c02_b9,m65c02_ba,m65c02_bb,m65c02_bc,m65c02_bd,m65c02_be,m65c02_bf, | |
| 399 | m65c02_c0,m65c02_c1,m65c02_c2,m65c02_c3,m65c02_c4,m65c02_c5,m65c02_c6,m65c02_c7, | |
| 400 | m65c02_c8,m65c02_c9,m65c02_ca,m65c02_cb_wdc,m65c02_cc,m65c02_cd,m65c02_ce,m65c02_cf, | |
| 401 | m65c02_d0,m65c02_d1,m65c02_d2,m65c02_d3,m65c02_d4,m65c02_d5,m65c02_d6,m65c02_d7, | |
| 402 | m65c02_d8,m65c02_d9,m65c02_da,m65c02_db_wdc,m65c02_dc,m65c02_dd,m65c02_de_wdc,m65c02_df, | |
| 403 | m65c02_e0,m65c02_e1,m65c02_e2,m65c02_e3,m65c02_e4,m65c02_e5,m65c02_e6,m65c02_e7, | |
| 404 | m65c02_e8,m65c02_e9,m65c02_ea,m65c02_eb,m65c02_ec,m65c02_ed,m65c02_ee,m65c02_ef, | |
| 405 | m65c02_f0,m65c02_f1,m65c02_f2,m65c02_f3,m65c02_f4,m65c02_f5,m65c02_f6,m65c02_f7, | |
| 406 | m65c02_f8,m65c02_f9,m65c02_fa,m65c02_fb,m65c02_fc,m65c02_fd,m65c02_fe_wdc,m65c02_ff | |
| 407 | }; | |
| 408 | #endif | |
| 409 | ||
| 410 |
| r18874 | r18875 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * t65ce02.c | |
| 4 | * 65ce02 opcode functions and function pointer table | |
| 5 | * | |
| 6 | * Copyright Peter Trauner, all rights reserved. | |
| 7 | * | |
| 8 | * - This source code is released as freeware for non-commercial purposes. | |
| 9 | * - You are free to use and redistribute this code in modified or | |
| 10 | * unmodified form, provided you list me in the credits. | |
| 11 | * - If you modify this source code, you must add a notice to each modified | |
| 12 | * source file that it has been changed. If you're a nice person, you | |
| 13 | * will clearly mark each change too. :) | |
| 14 | * - If you wish to use this for commercial purposes, please contact me at | |
| 15 | * pullmoll@t-online.de | |
| 16 | * - The author of this copywritten work reserves the right to change the | |
| 17 | * terms of its usage and license at any time, including retroactively | |
| 18 | * - This entire notice must remain in the source code. | |
| 19 | * | |
| 20 | *****************************************************************************/ | |
| 21 | ||
| 22 | #undef OP | |
| 23 | #ifdef M4510 | |
| 24 | #define OP(nn) INLINE void m4510_##nn(m4510_Regs *cpustate) | |
| 25 | #else | |
| 26 | #define OP(nn) INLINE void m65ce02_##nn(m65ce02_Regs *cpustate) | |
| 27 | #endif | |
| 28 | ||
| 29 | /***************************************************************************** | |
| 30 | ***************************************************************************** | |
| 31 | * | |
| 32 | * overrides for 65CE02 opcodes | |
| 33 | * | |
| 34 | ***************************************************************************** | |
| 35 | * op temp cycles rdmem opc wrmem ********************/ | |
| 36 | OP(00) { BRK; } /* 7 BRK */ | |
| 37 | OP(20) { JSR; } /* 5 JSR */ | |
| 38 | OP(40) { int tmp; RTI; } /* 5 RTI */ | |
| 39 | OP(60) { RTS; } /* 4 RTS */ | |
| 40 | OP(80) { int tmp; BRA(1); } /* 2 BRA */ | |
| 41 | OP(a0) { int tmp; RD_IMM; LDY; } /* 2 LDY IMM */ | |
| 42 | OP(c0) { int tmp; RD_IMM; CPY; } /* 2 CPY IMM */ | |
| 43 | OP(e0) { int tmp; RD_IMM; CPX; } /* 2 CPX IMM */ | |
| 44 | ||
| 45 | OP(10) { int tmp; BRA( ! ( P & F_N ) ); } /* 2 BPL REL */ | |
| 46 | OP(30) { int tmp; BRA( ( P & F_N ) ); } /* 2 BMI REL */ | |
| 47 | OP(50) { int tmp; BRA( ! ( P & F_V ) ); } /* 2 BVC REL */ | |
| 48 | OP(70) { int tmp; BRA( ( P & F_V ) ); } /* 2 BVS REL */ | |
| 49 | OP(90) { int tmp; BRA( ! ( P & F_C ) ); } /* 2 BCC REL */ | |
| 50 | OP(b0) { int tmp; BRA( ( P & F_C ) ); } /* 2 BCS REL */ | |
| 51 | OP(d0) { int tmp; BRA( ! ( P & F_Z ) ); } /* 2 BNE REL */ | |
| 52 | OP(f0) { int tmp; BRA( ( P & F_Z ) ); } /* 2 BEQ REL */ | |
| 53 | ||
| 54 | OP(01) { int tmp; RD_IDX; ORA; } /* 5 ORA IDX */ | |
| 55 | OP(21) { int tmp; RD_IDX; AND; } /* 5 AND IDX */ | |
| 56 | OP(41) { int tmp; RD_IDX; EOR; } /* 5 EOR IDX */ | |
| 57 | OP(61) { int tmp; RD_IDX; ADC; } /* 5 ADC IDX */ | |
| 58 | OP(81) { int tmp; STA; WR_IDX; } /* 5 STA IDX */ | |
| 59 | OP(a1) { int tmp; RD_IDX; LDA; } /* 5 LDA IDX */ | |
| 60 | OP(c1) { int tmp; RD_IDX; CMP; } /* 5 CMP IDX */ | |
| 61 | OP(e1) { int tmp; RD_IDX; SBC; } /* 5 SBC IDX */ | |
| 62 | ||
| 63 | OP(11) { int tmp; RD_IDY; ORA; } /* 5 ORA IDY */ | |
| 64 | OP(31) { int tmp; RD_IDY; AND; } /* 5 AND IDY */ | |
| 65 | OP(51) { int tmp; RD_IDY; EOR; } /* 5 EOR IDY */ | |
| 66 | OP(71) { int tmp; RD_IDY; ADC; } /* 5 ADC IDY */ | |
| 67 | OP(91) { int tmp; STA; WR_IDY; } /* 5 STA IDY */ | |
| 68 | OP(b1) { int tmp; RD_IDY; LDA; } /* 5 LDA IDY */ | |
| 69 | OP(d1) { int tmp; RD_IDY; CMP; } /* 5 CMP IDY */ | |
| 70 | OP(f1) { int tmp; RD_IDY; SBC; } /* 5 SBC IDY */ | |
| 71 | ||
| 72 | OP(02) { RD_DUM; CLE; } /* 2 CLE */ | |
| 73 | OP(22) { JSR_IND; } /* 7 JSR IND */ | |
| 74 | OP(42) { RD_DUM; NEG; } /* 2 NEG */ | |
| 75 | OP(62) { int tmp; RD_IMM; RTN; } /* 7 RTN IMM */ | |
| 76 | OP(82) { RD_INSY_DISCARD; } /* 6 STA INSY */ | |
| 77 | OP(a2) { int tmp; RD_IMM; LDX; } /* 2 LDX IMM */ | |
| 78 | OP(c2) { int tmp; RD_IMM; CPZ; } /* 2 CPZ IMM */ | |
| 79 | OP(e2) { int tmp; RD_INSY; LDA; } /* 6 LDA INSY */ | |
| 80 | ||
| 81 | OP(12) { int tmp; RD_IDZ; ORA; } /* 5 ORA IDZ */ | |
| 82 | OP(32) { int tmp; RD_IDZ; AND; } /* 5 AND IDZ */ | |
| 83 | OP(52) { int tmp; RD_IDZ; EOR; } /* 5 EOR IDZ */ | |
| 84 | OP(72) { int tmp; RD_IDZ; ADC; } /* 5 ADC IDZ */ | |
| 85 | OP(92) { RD_IDZ_DISCARD; } /* 5 STA IDZ */ | |
| 86 | OP(b2) { int tmp; RD_IDZ; LDA; } /* 5 LDA IDZ */ | |
| 87 | OP(d2) { int tmp; RD_IDZ; CMP; } /* 5 CMP IDZ */ | |
| 88 | OP(f2) { int tmp; RD_IDZ; SBC; } /* 5 SBC IDZ */ | |
| 89 | ||
| 90 | OP(03) { RD_DUM; SEE; } /* 2 SEE */ | |
| 91 | OP(23) { JSR_INDX; } /* 7 JSR INDX */ | |
| 92 | OP(43) { int tmp; RD_DUM; RD_ACC; ASR_65CE02; WR_ACC; } /* 2 ASR A */ | |
| 93 | OP(63) { BSR; } /* 5 BSR */ | |
| 94 | OP(83) { BRA_WORD(1); } /* 3 BRA REL WORD */ | |
| 95 | OP(a3) { int tmp; RD_IMM; LDZ; } /* 2 LDZ IMM */ | |
| 96 | OP(c3) { PAIR tmp; RD_ZPG_WORD; DEW; WB_EA_WORD; } /* 6 DEW ABS */ | |
| 97 | OP(e3) { PAIR tmp; RD_ZPG_WORD; INW; WB_EA_WORD; } /* 6 INW ABS */ | |
| 98 | ||
| 99 | OP(13) { BRA_WORD( ! ( P & F_N ) ); } /* 3 BPL REL WORD */ | |
| 100 | OP(33) { BRA_WORD( ( P & F_N ) ); } /* 3 BMI REL WORD */ | |
| 101 | OP(53) { BRA_WORD( ! ( P & F_V ) ); } /* 3 BVC REL WORD */ | |
| 102 | OP(73) { BRA_WORD( ( P & F_V ) ); } /* 3 BVS REL WORD */ | |
| 103 | OP(93) { BRA_WORD( ! ( P & F_C ) ); } /* 3 BCC REL WORD */ | |
| 104 | OP(b3) { BRA_WORD( ( P & F_C ) ); } /* 3 BCS REL WORD */ | |
| 105 | OP(d3) { BRA_WORD( ! ( P & F_Z ) ); } /* 3 BNE REL WORD */ | |
| 106 | OP(f3) { BRA_WORD( ( P & F_Z ) ); } /* 3 BEQ REL WORD */ | |
| 107 | ||
| 108 | OP(04) { int tmp; RD_ZPG; TSB; WB_EA; } /* 4 TSB ZPG */ | |
| 109 | OP(24) { int tmp; RD_ZPG; RD_DUM; BIT; } /* 4 BIT ZPG */ | |
| 110 | OP(44) { int tmp; RD_ZPG; ASR_65CE02; WB_EA; } /* 4 ASR ZPG */ | |
| 111 | OP(64) { int tmp; STZ_65CE02; WR_ZPG; } /* 3 STZ ZPG */ | |
| 112 | OP(84) { int tmp; STY; WR_ZPG; } /* 3 STY ZPG */ | |
| 113 | OP(a4) { int tmp; RD_ZPG; LDY; } /* 3 LDY ZPG */ | |
| 114 | OP(c4) { int tmp; RD_ZPG; CPY; } /* 3 CPY ZPG */ | |
| 115 | OP(e4) { int tmp; RD_ZPG; CPX; } /* 3 CPX ZPG */ | |
| 116 | ||
| 117 | OP(14) { int tmp; RD_ZPG; TRB; WB_EA; } /* 4 TRB ZPG */ | |
| 118 | OP(34) { int tmp; RD_ZPX; RD_DUM; BIT; } /* 4 BIT ZPX */ | |
| 119 | OP(54) { int tmp; RD_ZPX; ASR_65CE02; WB_EA; } /* 4 ASR ZPX */ | |
| 120 | OP(74) { int tmp; STZ_65CE02; WR_ZPX; } /* 3 STZ ZPX */ | |
| 121 | OP(94) { int tmp; STY; WR_ZPX; } /* 3 STY ZPX */ | |
| 122 | OP(b4) { int tmp; RD_ZPX; LDY; } /* 3 LDY ZPX */ | |
| 123 | OP(d4) { int tmp; RD_ZPG; CPZ; } /* 3 CPZ ZPG */ | |
| 124 | OP(f4) { PAIR tmp; RD_IMM_WORD; PUSH_WORD(tmp); } /* 5 PHW imm16 */ | |
| 125 | ||
| 126 | OP(05) { int tmp; RD_ZPG; ORA; } /* 3 ORA ZPG */ | |
| 127 | OP(25) { int tmp; RD_ZPG; AND; } /* 3 AND ZPG */ | |
| 128 | OP(45) { int tmp; RD_ZPG; EOR; } /* 3 EOR ZPG */ | |
| 129 | OP(65) { int tmp; RD_ZPG; ADC; } /* 3 ADC ZPG */ | |
| 130 | OP(85) { int tmp; STA; WR_ZPG; } /* 3 STA ZPG */ | |
| 131 | OP(a5) { int tmp; RD_ZPG; LDA; } /* 3 LDA ZPG */ | |
| 132 | OP(c5) { int tmp; RD_ZPG; CMP; } /* 3 CMP ZPG */ | |
| 133 | OP(e5) { int tmp; RD_ZPG; SBC; } /* 3 SBC ZPG */ | |
| 134 | ||
| 135 | OP(15) { int tmp; RD_ZPX; ORA; } /* 3 ORA ZPX */ | |
| 136 | OP(35) { int tmp; RD_ZPX; AND; } /* 3 AND ZPX */ | |
| 137 | OP(55) { int tmp; RD_ZPX; EOR; } /* 3 EOR ZPX */ | |
| 138 | OP(75) { int tmp; RD_ZPX; ADC; } /* 3 ADC ZPX */ | |
| 139 | OP(95) { int tmp; STA; WR_ZPX; } /* 3 STA ZPX */ | |
| 140 | OP(b5) { int tmp; RD_ZPX; LDA; } /* 3 LDA ZPX */ | |
| 141 | OP(d5) { int tmp; RD_ZPX; CMP; } /* 3 CMP ZPX */ | |
| 142 | OP(f5) { int tmp; RD_ZPX; SBC; } /* 3 SBC ZPX */ | |
| 143 | ||
| 144 | OP(06) { int tmp; RD_ZPG; ASL; WB_EA; } /* 4 ASL ZPG */ | |
| 145 | OP(26) { int tmp; RD_ZPG; ROL; WB_EA; } /* 4 ROL ZPG */ | |
| 146 | OP(46) { int tmp; RD_ZPG; LSR; WB_EA; } /* 4 LSR ZPG */ | |
| 147 | OP(66) { int tmp; RD_ZPG; ROR; WB_EA; } /* 4 ROR ZPG */ | |
| 148 | OP(86) { int tmp; STX; WR_ZPG; } /* 3 STX ZPG */ | |
| 149 | OP(a6) { int tmp; RD_ZPG; LDX; } /* 3 LDX ZPG */ | |
| 150 | OP(c6) { int tmp; RD_ZPG; DEC; WB_EA; } /* 4 DEC ZPG */ | |
| 151 | OP(e6) { int tmp; RD_ZPG; INC; WB_EA; } /* 4 INC ZPG */ | |
| 152 | ||
| 153 | OP(16) { int tmp; RD_ZPX; ASL; WB_EA; } /* 4 ASL ZPX */ | |
| 154 | OP(36) { int tmp; RD_ZPX; ROL; WB_EA; } /* 4 ROL ZPX */ | |
| 155 | OP(56) { int tmp; RD_ZPX; LSR; WB_EA; } /* 4 LSR ZPX */ | |
| 156 | OP(76) { int tmp; RD_ZPX; ROR; WB_EA; } /* 4 ROR ZPX */ | |
| 157 | OP(96) { int tmp; STX; WR_ZPY; } /* 3 STX ZPY */ | |
| 158 | OP(b6) { int tmp; RD_ZPY; LDX; } /* 3 LDX ZPY */ | |
| 159 | OP(d6) { int tmp; RD_ZPX; DEC; WB_EA; } /* 4 DEC ZPX */ | |
| 160 | OP(f6) { int tmp; RD_ZPX; INC; WB_EA; } /* 4 INC ZPX */ | |
| 161 | ||
| 162 | OP(07) { int tmp; RD_ZPG; RMB(0); WB_EA; } /* 4 RMB0 ZPG */ | |
| 163 | OP(27) { int tmp; RD_ZPG; RMB(2); WB_EA; } /* 4 RMB2 ZPG */ | |
| 164 | OP(47) { int tmp; RD_ZPG; RMB(4); WB_EA; } /* 4 RMB4 ZPG */ | |
| 165 | OP(67) { int tmp; RD_ZPG; RMB(6); WB_EA; } /* 4 RMB6 ZPG */ | |
| 166 | OP(87) { int tmp; RD_ZPG; SMB(0); WB_EA; } /* 4 SMB0 ZPG */ | |
| 167 | OP(a7) { int tmp; RD_ZPG; SMB(2); WB_EA; } /* 4 SMB2 ZPG */ | |
| 168 | OP(c7) { int tmp; RD_ZPG; SMB(4); WB_EA; } /* 4 SMB4 ZPG */ | |
| 169 | OP(e7) { int tmp; RD_ZPG; SMB(6); WB_EA; } /* 4 SMB6 ZPG */ | |
| 170 | ||
| 171 | OP(17) { int tmp; RD_ZPG; RMB(1); WB_EA; } /* 4 RMB1 ZPG */ | |
| 172 | OP(37) { int tmp; RD_ZPG; RMB(3); WB_EA; } /* 4 RMB3 ZPG */ | |
| 173 | OP(57) { int tmp; RD_ZPG; RMB(5); WB_EA; } /* 4 RMB5 ZPG */ | |
| 174 | OP(77) { int tmp; RD_ZPG; RMB(7); WB_EA; } /* 4 RMB7 ZPG */ | |
| 175 | OP(97) { int tmp; RD_ZPG; SMB(1); WB_EA; } /* 4 SMB1 ZPG */ | |
| 176 | OP(b7) { int tmp; RD_ZPG; SMB(3); WB_EA; } /* 4 SMB3 ZPG */ | |
| 177 | OP(d7) { int tmp; RD_ZPG; SMB(5); WB_EA; } /* 4 SMB5 ZPG */ | |
| 178 | OP(f7) { int tmp; RD_ZPG; SMB(7); WB_EA; } /* 4 SMB7 ZPG */ | |
| 179 | ||
| 180 | OP(08) { RD_DUM; PHP; } /* 3 PHP */ | |
| 181 | OP(28) { RD_DUM; PLP; } /* 3 PLP */ | |
| 182 | OP(48) { RD_DUM; PHA; } /* 3 PHA */ | |
| 183 | OP(68) { RD_DUM; PLA; } /* 3 PLA */ | |
| 184 | OP(88) { DEY; } /* 1 DEY */ | |
| 185 | OP(a8) { TAY; } /* 1 TAY */ | |
| 186 | OP(c8) { INY; } /* 1 INY */ | |
| 187 | OP(e8) { INX; } /* 1 INX */ | |
| 188 | ||
| 189 | OP(18) { CLC; } /* 1 CLC */ | |
| 190 | OP(38) { SEC; } /* 1 SEC */ | |
| 191 | OP(58) { CLI; } /* 1 CLI */ | |
| 192 | OP(78) { RD_DUM; SEI; } /* 2 SEI */ | |
| 193 | OP(98) { TYA; } /* 1 TYA */ | |
| 194 | OP(b8) { CLV; } /* 1 CLV */ | |
| 195 | OP(d8) { CLD; } /* 1 CLD */ | |
| 196 | OP(f8) { SED; } /* 1 SED */ | |
| 197 | ||
| 198 | OP(09) { int tmp; RD_IMM; ORA; } /* 2 ORA IMM */ | |
| 199 | OP(29) { int tmp; RD_IMM; AND; } /* 2 AND IMM */ | |
| 200 | OP(49) { int tmp; RD_IMM; EOR; } /* 2 EOR IMM */ | |
| 201 | OP(69) { int tmp; RD_IMM; ADC; } /* 2 ADC IMM */ | |
| 202 | OP(89) { int tmp; RD_IMM; BIT; } /* 2 BIT IMM */ | |
| 203 | OP(a9) { int tmp; RD_IMM; LDA; } /* 2 LDA IMM */ | |
| 204 | OP(c9) { int tmp; RD_IMM; CMP; } /* 2 CMP IMM */ | |
| 205 | OP(e9) { int tmp; RD_IMM; SBC; } /* 2 SBC IMM */ | |
| 206 | ||
| 207 | OP(19) { int tmp; RD_ABY; ORA; } /* 4 ORA ABY */ | |
| 208 | OP(39) { int tmp; RD_ABY; AND; } /* 4 AND ABY */ | |
| 209 | OP(59) { int tmp; RD_ABY; EOR; } /* 4 EOR ABY */ | |
| 210 | OP(79) { int tmp; RD_ABY; ADC; } /* 4 ADC ABY */ | |
| 211 | OP(99) { int tmp; STA; WR_ABY; } /* 4 STA ABY */ | |
| 212 | OP(b9) { int tmp; RD_ABY; LDA; } /* 4 LDA ABY */ | |
| 213 | OP(d9) { int tmp; RD_ABY; CMP; } /* 4 CMP ABY */ | |
| 214 | OP(f9) { int tmp; RD_ABY; SBC; } /* 4 SBC ABY */ | |
| 215 | ||
| 216 | OP(0a) { int tmp; RD_ACC; ASL; WR_ACC; } /* 1 ASL A */ | |
| 217 | OP(2a) { int tmp; RD_ACC; ROL; WR_ACC; } /* 1 ROL A */ | |
| 218 | OP(4a) { int tmp; RD_ACC; LSR; WR_ACC; } /* 1 LSR A */ | |
| 219 | OP(6a) { int tmp; RD_ACC; ROR; WR_ACC; } /* 1 ROR A */ | |
| 220 | OP(8a) { TXA; } /* 1 TXA */ | |
| 221 | OP(aa) { TAX; } /* 1 TAX */ | |
| 222 | OP(ca) { DEX; } /* 1 DEX */ | |
| 223 | OP(ea) { NOP; } /* 1 NOP */ | |
| 224 | ||
| 225 | OP(1a) { INA; } /* 1 INA */ | |
| 226 | OP(3a) { DEA; } /* 1 DEA */ | |
| 227 | OP(5a) { RD_DUM; PHY; } /* 3 PHY */ | |
| 228 | OP(7a) { RD_DUM; PLY; } /* 3 PLY */ | |
| 229 | OP(9a) { TXS; } /* 1 TXS */ | |
| 230 | OP(ba) { TSX; } /* 1 TSX */ | |
| 231 | OP(da) { RD_DUM; PHX; } /* 3 PHX */ | |
| 232 | OP(fa) { RD_DUM; PLX; } /* 3 PLX */ | |
| 233 | ||
| 234 | OP(0b) { TSY; } /* 1 TSY */ | |
| 235 | OP(2b) { TYS; } /* 1 TYS */ | |
| 236 | OP(4b) { TAZ; } /* 1 TAZ */ | |
| 237 | OP(6b) { TZA; } /* 1 TZA */ | |
| 238 | OP(8b) { int tmp; STY; WR_ABX; } /* 4 STY ABX */ | |
| 239 | OP(ab) { int tmp; RD_ABS; LDZ; } /* 4 LDZ ABS */ | |
| 240 | OP(cb) { PAIR tmp; tmp.d = 0; RD_ABS_WORD; ASW; WB_EA_WORD; } /* 7 ASW ABS */ | |
| 241 | OP(eb) { PAIR tmp; RD_ABS_WORD; ROW; WB_EA_WORD; } /* 6/7? roW ABS */ | |
| 242 | ||
| 243 | OP(1b) { INZ; } /* 1 INZ */ | |
| 244 | OP(3b) { DEZ; } /* 1 DEZ */ | |
| 245 | OP(5b) { TAB; } /* 1 TAB */ | |
| 246 | OP(7b) { TBA; } /* 1 TBA */ | |
| 247 | OP(9b) { int tmp; STX; WR_ABY; } /* 4 STX ABY */ | |
| 248 | OP(bb) { int tmp; RD_ABX; LDZ; } /* 4 LDZ ABX */ | |
| 249 | OP(db) { RD_DUM; PHZ; } /* 3 PHZ */ | |
| 250 | OP(fb) { RD_DUM; PLZ; } /* 3 PLZ */ | |
| 251 | ||
| 252 | OP(0c) { int tmp; RD_ABS; TSB; WB_EA; } /* 5 TSB ABS */ | |
| 253 | OP(2c) { int tmp; RD_ABS; RD_DUM; BIT; } /* 5 BIT ABS */ | |
| 254 | OP(4c) { EA_ABS; JMP; } /* 3 JMP ABS */ | |
| 255 | OP(6c) { int tmp; EA_IND; JMP; } /* 5 JMP IND */ | |
| 256 | OP(8c) { int tmp; STY; WR_ABS; } /* 4 STY ABS */ | |
| 257 | OP(ac) { int tmp; RD_ABS; LDY; } /* 4 LDY ABS */ | |
| 258 | OP(cc) { int tmp; RD_ABS; CPY; } /* 4 CPY ABS */ | |
| 259 | OP(ec) { int tmp; RD_ABS; CPX; } /* 4 CPX ABS */ | |
| 260 | ||
| 261 | OP(1c) { int tmp; RD_ABS; TRB; WB_EA; } /* 5 TRB ABS */ | |
| 262 | OP(3c) { int tmp; RD_ABX; RD_DUM; BIT; } /* 5 BIT ABX */ | |
| 263 | #ifdef M4510 | |
| 264 | OP(5c) { MAP; } /* 4? MAP */ | |
| 265 | #else | |
| 266 | OP(5c) { int t1,t2,t3; AUG; } /* 4 AUGMENT/no operation */ | |
| 267 | #endif | |
| 268 | OP(7c) { int tmp; EA_IAX; JMP; } /* 5 JMP IAX */ | |
| 269 | OP(9c) { int tmp; STZ_65CE02; WR_ABS; } /* 4 STZ ABS */ | |
| 270 | OP(bc) { int tmp; RD_ABX; LDY; } /* 4 LDY ABX */ | |
| 271 | OP(dc) { int tmp; RD_ABS; CPZ; } /* 4 CPZ ABS */ | |
| 272 | OP(fc) { PAIR tmp; RD_ABS_WORD; PUSH_WORD(tmp); } /* 7 PHW ab */ | |
| 273 | ||
| 274 | OP(0d) { int tmp; RD_ABS; ORA; } /* 4 ORA ABS */ | |
| 275 | OP(2d) { int tmp; RD_ABS; AND; } /* 4 AND ABS */ | |
| 276 | OP(4d) { int tmp; RD_ABS; EOR; } /* 4 EOR ABS */ | |
| 277 | OP(6d) { int tmp; RD_ABS; ADC; } /* 4 ADC ABS */ | |
| 278 | OP(8d) { int tmp; STA; WR_ABS; } /* 4 STA ABS */ | |
| 279 | OP(ad) { int tmp; RD_ABS; LDA; } /* 4 LDA ABS */ | |
| 280 | OP(cd) { int tmp; RD_ABS; CMP; } /* 4 CMP ABS */ | |
| 281 | OP(ed) { int tmp; RD_ABS; SBC; } /* 4 SBC ABS */ | |
| 282 | ||
| 283 | OP(1d) { int tmp; RD_ABX; ORA; } /* 4 ORA ABX */ | |
| 284 | OP(3d) { int tmp; RD_ABX; AND; } /* 4 AND ABX */ | |
| 285 | OP(5d) { int tmp; RD_ABX; EOR; } /* 4 EOR ABX */ | |
| 286 | OP(7d) { int tmp; RD_ABX; ADC; } /* 4 ADC ABX */ | |
| 287 | OP(9d) { int tmp; STA; WR_ABX; } /* 4 STA ABX */ | |
| 288 | OP(bd) { int tmp; RD_ABX; LDA; } /* 4 LDA ABX */ | |
| 289 | OP(dd) { int tmp; RD_ABX; CMP; } /* 4 CMP ABX */ | |
| 290 | OP(fd) { int tmp; RD_ABX; SBC; } /* 4 SBC ABX */ | |
| 291 | ||
| 292 | OP(0e) { int tmp; RD_ABS; ASL; WB_EA; } /* 5 ASL ABS */ | |
| 293 | OP(2e) { int tmp; RD_ABS; ROL; WB_EA; } /* 5 ROL ABS */ | |
| 294 | OP(4e) { int tmp; RD_ABS; LSR; WB_EA; } /* 5 LSR ABS */ | |
| 295 | OP(6e) { int tmp; RD_ABS; ROR; WB_EA; } /* 5 ROR ABS */ | |
| 296 | OP(8e) { int tmp; STX; WR_ABS; } /* 4 STX ABS */ | |
| 297 | OP(ae) { int tmp; RD_ABS; LDX; } /* 4 LDX ABS */ | |
| 298 | OP(ce) { int tmp; RD_ABS; DEC; WB_EA; } /* 5 DEC ABS */ | |
| 299 | OP(ee) { int tmp; RD_ABS; INC; WB_EA; } /* 5 INC ABS */ | |
| 300 | ||
| 301 | OP(1e) { int tmp; RD_ABX; ASL; WB_EA; } /* 5 ASL ABX */ | |
| 302 | OP(3e) { int tmp; RD_ABX; ROL; WB_EA; } /* 5 ROL ABX */ | |
| 303 | OP(5e) { int tmp; RD_ABX; LSR; WB_EA; } /* 5 LSR ABX */ | |
| 304 | OP(7e) { int tmp; RD_ABX; ROR; WB_EA; } /* 5 ROR ABX */ | |
| 305 | OP(9e) { int tmp; STZ_65CE02; WR_ABX; } /* 4 STZ ABX */ | |
| 306 | OP(be) { int tmp; RD_ABY; LDX; } /* 4 LDX ABY */ | |
| 307 | OP(de) { int tmp; RD_ABX; DEC; WB_EA; } /* 5 DEC ABX */ | |
| 308 | OP(fe) { int tmp; RD_ABX; INC; WB_EA; } /* 5 INC ABX */ | |
| 309 | ||
| 310 | OP(0f) { int tmp; RD_ZPG; BBR(0); } /* 4 BBR0 ZPG */ | |
| 311 | OP(2f) { int tmp; RD_ZPG; BBR(2); } /* 4 BBR2 ZPG */ | |
| 312 | OP(4f) { int tmp; RD_ZPG; BBR(4); } /* 4 BBR4 ZPG */ | |
| 313 | OP(6f) { int tmp; RD_ZPG; BBR(6); } /* 4 BBR6 ZPG */ | |
| 314 | OP(8f) { int tmp; RD_ZPG; BBS(0); } /* 4 BBS0 ZPG */ | |
| 315 | OP(af) { int tmp; RD_ZPG; BBS(2); } /* 4 BBS2 ZPG */ | |
| 316 | OP(cf) { int tmp; RD_ZPG; BBS(4); } /* 4 BBS4 ZPG */ | |
| 317 | OP(ef) { int tmp; RD_ZPG; BBS(6); } /* 4 BBS6 ZPG */ | |
| 318 | ||
| 319 | OP(1f) { int tmp; RD_ZPG; BBR(1); } /* 4 BBR1 ZPG */ | |
| 320 | OP(3f) { int tmp; RD_ZPG; BBR(3); } /* 4 BBR3 ZPG */ | |
| 321 | OP(5f) { int tmp; RD_ZPG; BBR(5); } /* 4 BBR5 ZPG */ | |
| 322 | OP(7f) { int tmp; RD_ZPG; BBR(7); } /* 4 BBR7 ZPG */ | |
| 323 | OP(9f) { int tmp; RD_ZPG; BBS(1); } /* 4 BBS1 ZPG */ | |
| 324 | OP(bf) { int tmp; RD_ZPG; BBS(3); } /* 4 BBS3 ZPG */ | |
| 325 | OP(df) { int tmp; RD_ZPG; BBS(5); } /* 4 BBS5 ZPG */ | |
| 326 | OP(ff) { int tmp; RD_ZPG; BBS(7); } /* 4 BBS7 ZPG */ | |
| 327 | ||
| 328 | #ifdef M4510 | |
| 329 | static void (*const insn4510[0x100])(m4510_Regs *) = { | |
| 330 | m4510_00,m4510_01,m4510_02,m4510_03,m4510_04,m4510_05,m4510_06,m4510_07, | |
| 331 | m4510_08,m4510_09,m4510_0a,m4510_0b,m4510_0c,m4510_0d,m4510_0e,m4510_0f, | |
| 332 | m4510_10,m4510_11,m4510_12,m4510_13,m4510_14,m4510_15,m4510_16,m4510_17, | |
| 333 | m4510_18,m4510_19,m4510_1a,m4510_1b,m4510_1c,m4510_1d,m4510_1e,m4510_1f, | |
| 334 | m4510_20,m4510_21,m4510_22,m4510_23,m4510_24,m4510_25,m4510_26,m4510_27, | |
| 335 | m4510_28,m4510_29,m4510_2a,m4510_2b,m4510_2c,m4510_2d,m4510_2e,m4510_2f, | |
| 336 | m4510_30,m4510_31,m4510_32,m4510_33,m4510_34,m4510_35,m4510_36,m4510_37, | |
| 337 | m4510_38,m4510_39,m4510_3a,m4510_3b,m4510_3c,m4510_3d,m4510_3e,m4510_3f, | |
| 338 | m4510_40,m4510_41,m4510_42,m4510_43,m4510_44,m4510_45,m4510_46,m4510_47, | |
| 339 | m4510_48,m4510_49,m4510_4a,m4510_4b,m4510_4c,m4510_4d,m4510_4e,m4510_4f, | |
| 340 | m4510_50,m4510_51,m4510_52,m4510_53,m4510_54,m4510_55,m4510_56,m4510_57, | |
| 341 | m4510_58,m4510_59,m4510_5a,m4510_5b,m4510_5c,m4510_5d,m4510_5e,m4510_5f, | |
| 342 | m4510_60,m4510_61,m4510_62,m4510_63,m4510_64,m4510_65,m4510_66,m4510_67, | |
| 343 | m4510_68,m4510_69,m4510_6a,m4510_6b,m4510_6c,m4510_6d,m4510_6e,m4510_6f, | |
| 344 | m4510_70,m4510_71,m4510_72,m4510_73,m4510_74,m4510_75,m4510_76,m4510_77, | |
| 345 | m4510_78,m4510_79,m4510_7a,m4510_7b,m4510_7c,m4510_7d,m4510_7e,m4510_7f, | |
| 346 | m4510_80,m4510_81,m4510_82,m4510_83,m4510_84,m4510_85,m4510_86,m4510_87, | |
| 347 | m4510_88,m4510_89,m4510_8a,m4510_8b,m4510_8c,m4510_8d,m4510_8e,m4510_8f, | |
| 348 | m4510_90,m4510_91,m4510_92,m4510_93,m4510_94,m4510_95,m4510_96,m4510_97, | |
| 349 | m4510_98,m4510_99,m4510_9a,m4510_9b,m4510_9c,m4510_9d,m4510_9e,m4510_9f, | |
| 350 | m4510_a0,m4510_a1,m4510_a2,m4510_a3,m4510_a4,m4510_a5,m4510_a6,m4510_a7, | |
| 351 | m4510_a8,m4510_a9,m4510_aa,m4510_ab,m4510_ac,m4510_ad,m4510_ae,m4510_af, | |
| 352 | m4510_b0,m4510_b1,m4510_b2,m4510_b3,m4510_b4,m4510_b5,m4510_b6,m4510_b7, | |
| 353 | m4510_b8,m4510_b9,m4510_ba,m4510_bb,m4510_bc,m4510_bd,m4510_be,m4510_bf, | |
| 354 | m4510_c0,m4510_c1,m4510_c2,m4510_c3,m4510_c4,m4510_c5,m4510_c6,m4510_c7, | |
| 355 | m4510_c8,m4510_c9,m4510_ca,m4510_cb,m4510_cc,m4510_cd,m4510_ce,m4510_cf, | |
| 356 | m4510_d0,m4510_d1,m4510_d2,m4510_d3,m4510_d4,m4510_d5,m4510_d6,m4510_d7, | |
| 357 | m4510_d8,m4510_d9,m4510_da,m4510_db,m4510_dc,m4510_dd,m4510_de,m4510_df, | |
| 358 | m4510_e0,m4510_e1,m4510_e2,m4510_e3,m4510_e4,m4510_e5,m4510_e6,m4510_e7, | |
| 359 | m4510_e8,m4510_e9,m4510_ea,m4510_eb,m4510_ec,m4510_ed,m4510_ee,m4510_ef, | |
| 360 | m4510_f0,m4510_f1,m4510_f2,m4510_f3,m4510_f4,m4510_f5,m4510_f6,m4510_f7, | |
| 361 | m4510_f8,m4510_f9,m4510_fa,m4510_fb,m4510_fc,m4510_fd,m4510_fe,m4510_ff | |
| 362 | }; | |
| 363 | #else | |
| 364 | static void (*const insn65ce02[0x100])(m65ce02_Regs *) = { | |
| 365 | m65ce02_00,m65ce02_01,m65ce02_02,m65ce02_03,m65ce02_04,m65ce02_05,m65ce02_06,m65ce02_07, | |
| 366 | m65ce02_08,m65ce02_09,m65ce02_0a,m65ce02_0b,m65ce02_0c,m65ce02_0d,m65ce02_0e,m65ce02_0f, | |
| 367 | m65ce02_10,m65ce02_11,m65ce02_12,m65ce02_13,m65ce02_14,m65ce02_15,m65ce02_16,m65ce02_17, | |
| 368 | m65ce02_18,m65ce02_19,m65ce02_1a,m65ce02_1b,m65ce02_1c,m65ce02_1d,m65ce02_1e,m65ce02_1f, | |
| 369 | m65ce02_20,m65ce02_21,m65ce02_22,m65ce02_23,m65ce02_24,m65ce02_25,m65ce02_26,m65ce02_27, | |
| 370 | m65ce02_28,m65ce02_29,m65ce02_2a,m65ce02_2b,m65ce02_2c,m65ce02_2d,m65ce02_2e,m65ce02_2f, | |
| 371 | m65ce02_30,m65ce02_31,m65ce02_32,m65ce02_33,m65ce02_34,m65ce02_35,m65ce02_36,m65ce02_37, | |
| 372 | m65ce02_38,m65ce02_39,m65ce02_3a,m65ce02_3b,m65ce02_3c,m65ce02_3d,m65ce02_3e,m65ce02_3f, | |
| 373 | m65ce02_40,m65ce02_41,m65ce02_42,m65ce02_43,m65ce02_44,m65ce02_45,m65ce02_46,m65ce02_47, | |
| 374 | m65ce02_48,m65ce02_49,m65ce02_4a,m65ce02_4b,m65ce02_4c,m65ce02_4d,m65ce02_4e,m65ce02_4f, | |
| 375 | m65ce02_50,m65ce02_51,m65ce02_52,m65ce02_53,m65ce02_54,m65ce02_55,m65ce02_56,m65ce02_57, | |
| 376 | m65ce02_58,m65ce02_59,m65ce02_5a,m65ce02_5b,m65ce02_5c,m65ce02_5d,m65ce02_5e,m65ce02_5f, | |
| 377 | m65ce02_60,m65ce02_61,m65ce02_62,m65ce02_63,m65ce02_64,m65ce02_65,m65ce02_66,m65ce02_67, | |
| 378 | m65ce02_68,m65ce02_69,m65ce02_6a,m65ce02_6b,m65ce02_6c,m65ce02_6d,m65ce02_6e,m65ce02_6f, | |
| 379 | m65ce02_70,m65ce02_71,m65ce02_72,m65ce02_73,m65ce02_74,m65ce02_75,m65ce02_76,m65ce02_77, | |
| 380 | m65ce02_78,m65ce02_79,m65ce02_7a,m65ce02_7b,m65ce02_7c,m65ce02_7d,m65ce02_7e,m65ce02_7f, | |
| 381 | m65ce02_80,m65ce02_81,m65ce02_82,m65ce02_83,m65ce02_84,m65ce02_85,m65ce02_86,m65ce02_87, | |
| 382 | m65ce02_88,m65ce02_89,m65ce02_8a,m65ce02_8b,m65ce02_8c,m65ce02_8d,m65ce02_8e,m65ce02_8f, | |
| 383 | m65ce02_90,m65ce02_91,m65ce02_92,m65ce02_93,m65ce02_94,m65ce02_95,m65ce02_96,m65ce02_97, | |
| 384 | m65ce02_98,m65ce02_99,m65ce02_9a,m65ce02_9b,m65ce02_9c,m65ce02_9d,m65ce02_9e,m65ce02_9f, | |
| 385 | m65ce02_a0,m65ce02_a1,m65ce02_a2,m65ce02_a3,m65ce02_a4,m65ce02_a5,m65ce02_a6,m65ce02_a7, | |
| 386 | m65ce02_a8,m65ce02_a9,m65ce02_aa,m65ce02_ab,m65ce02_ac,m65ce02_ad,m65ce02_ae,m65ce02_af, | |
| 387 | m65ce02_b0,m65ce02_b1,m65ce02_b2,m65ce02_b3,m65ce02_b4,m65ce02_b5,m65ce02_b6,m65ce02_b7, | |
| 388 | m65ce02_b8,m65ce02_b9,m65ce02_ba,m65ce02_bb,m65ce02_bc,m65ce02_bd,m65ce02_be,m65ce02_bf, | |
| 389 | m65ce02_c0,m65ce02_c1,m65ce02_c2,m65ce02_c3,m65ce02_c4,m65ce02_c5,m65ce02_c6,m65ce02_c7, | |
| 390 | m65ce02_c8,m65ce02_c9,m65ce02_ca,m65ce02_cb,m65ce02_cc,m65ce02_cd,m65ce02_ce,m65ce02_cf, | |
| 391 | m65ce02_d0,m65ce02_d1,m65ce02_d2,m65ce02_d3,m65ce02_d4,m65ce02_d5,m65ce02_d6,m65ce02_d7, | |
| 392 | m65ce02_d8,m65ce02_d9,m65ce02_da,m65ce02_db,m65ce02_dc,m65ce02_dd,m65ce02_de,m65ce02_df, | |
| 393 | m65ce02_e0,m65ce02_e1,m65ce02_e2,m65ce02_e3,m65ce02_e4,m65ce02_e5,m65ce02_e6,m65ce02_e7, | |
| 394 | m65ce02_e8,m65ce02_e9,m65ce02_ea,m65ce02_eb,m65ce02_ec,m65ce02_ed,m65ce02_ee,m65ce02_ef, | |
| 395 | m65ce02_f0,m65ce02_f1,m65ce02_f2,m65ce02_f3,m65ce02_f4,m65ce02_f5,m65ce02_f6,m65ce02_f7, | |
| 396 | m65ce02_f8,m65ce02_f9,m65ce02_fa,m65ce02_fb,m65ce02_fc,m65ce02_fd,m65ce02_fe,m65ce02_ff | |
| 397 | }; | |
| 398 | #endif | |
| 399 |
| r18874 | r18875 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * 6502dasm.c | |
| 4 | * 6502/65c02/6510 disassembler | |
| 5 | * | |
| 6 | * Copyright Juergen Buchmueller, all rights reserved. | |
| 7 | * | |
| 8 | * - This source code is released as freeware for non-commercial purposes. | |
| 9 | * - You are free to use and redistribute this code in modified or | |
| 10 | * unmodified form, provided you list me in the credits. | |
| 11 | * - If you modify this source code, you must add a notice to each modified | |
| 12 | * source file that it has been changed. If you're a nice person, you | |
| 13 | * will clearly mark each change too. :) | |
| 14 | * - If you wish to use this for commercial purposes, please contact me at | |
| 15 | * pullmoll@t-online.de | |
| 16 | * - The author of this copywritten work reserves the right to change the | |
| 17 | * terms of its usage and license at any time, including retroactively | |
| 18 | * - This entire notice must remain in the source code. | |
| 19 | * | |
| 20 | *****************************************************************************/ | |
| 21 | /* 2. February 2000 PeT added support for 65sc02 subtype */ | |
| 22 | /* 2. February 2000 PeT added support for 65ce02 variant */ | |
| 23 | /* 3. February 2000 PeT bbr bbs displayment */ | |
| 24 | /* 4. February 2000 PeT ply inw dew */ | |
| 25 | /* 4. February 2000 PeT fixed relative word operand */ | |
| 26 | /* 9. May 2000 PeT added m4510 */ | |
| 27 | /* 18.April 2008 Roberto Fresca fixed bbr, bbs, rmb & smb displayment, | |
| 28 | showing the correct bit to operate */ | |
| 29 | ||
| 30 | #include "emu.h" | |
| 31 | #include "debugger.h" | |
| 32 | #include "m6502.h" | |
| 33 | #include "m65ce02.h" | |
| 34 | #include "m6509.h" | |
| 35 | #include "m4510.h" | |
| 36 | ||
| 37 | enum addr_mode { | |
| 38 | non, /* no additional arguments */ | |
| 39 | imp, /* implicit */ | |
| 40 | acc, /* accumulator */ | |
| 41 | imm, /* immediate */ | |
| 42 | iw2, /* immediate word (65ce02) */ | |
| 43 | iw3, /* augment (65ce02) */ | |
| 44 | adr, /* absolute address (jmp,jsr) */ | |
| 45 | aba, /* absolute */ | |
| 46 | zpg, /* zero page */ | |
| 47 | zpx, /* zero page + X */ | |
| 48 | zpy, /* zero page + Y */ | |
| 49 | zpi, /* zero page indirect (65c02) */ | |
| 50 | zpb, /* zero page and branch (65c02 bbr,bbs) */ | |
| 51 | abx, /* absolute + X */ | |
| 52 | aby, /* absolute + Y */ | |
| 53 | rel, /* relative */ | |
| 54 | rw2, /* relative word (65cs02, 65ce02) */ | |
| 55 | idx, /* zero page pre indexed */ | |
| 56 | idy, /* zero page post indexed */ | |
| 57 | idz, /* zero page post indexed (65ce02) */ | |
| 58 | isy, /* zero page pre indexed sp and post indexed y (65ce02) */ | |
| 59 | ind, /* indirect (jmp) */ | |
| 60 | iax /* indirect + X (65c02 jmp) */ | |
| 61 | }; | |
| 62 | ||
| 63 | enum opcodes { | |
| 64 | adc, and_,asl, bcc, bcs, beq, bit, bmi, | |
| 65 | bne, bpl, m6502_brk, bvc, bvs, clc, cld, cli, | |
| 66 | clv, cmp, cpx, cpy, dec, dex, dey, eor, | |
| 67 | inc, inx, iny, jmp, jsr, lda, ldx, ldy, | |
| 68 | lsr, nop, ora, pha, php, pla, plp, rol, | |
| 69 | ror, rti, rts, sbc, sec, sed, sei, sta, | |
| 70 | stx, sty, tax, tay, tsx, txa, txs, tya, | |
| 71 | ill, | |
| 72 | /* 65c02 (only) mnemonics */ | |
| 73 | bbr, bbs, bra, rmb, smb, stz, trb, tsb, | |
| 74 | /* 65sc02 (only) mnemonics */ | |
| 75 | bsr, | |
| 76 | /* 6510 + 65c02 mnemonics */ | |
| 77 | anc, asr, ast, arr, asx, axa, dcp, dea, | |
| 78 | dop, ina, isb, lax, phx, phy, plx, ply, | |
| 79 | rla, rra, sax, slo, sre, sah, say, ssh, | |
| 80 | sxh, syh, top, oal, kil, | |
| 81 | /* 65ce02 mnemonics */ | |
| 82 | cle, see, rtn, aug, | |
| 83 | tab, tba, taz, tza, tys, tsy, | |
| 84 | ldz, stz2/* real register store */, | |
| 85 | dez, inz, cpz, phz, plz, | |
| 86 | neg, asr2/* arithmetic shift right */, | |
| 87 | asw, row, dew, inw, phw, | |
| 88 | /* 4510 mnemonics */ | |
| 89 | map, | |
| 90 | ||
| 91 | /* Deco CPU16 mnemonics */ | |
| 92 | vbl, u13, u8F, uAB, u87, u0B, uA3, u4B, | |
| 93 | u3F, uBB, u23 | |
| 94 | }; | |
| 95 | ||
| 96 | ||
| 97 | static const char *const token[]= | |
| 98 | { | |
| 99 | "adc", "and", "asl", "bcc", "bcs", "beq", "bit", "bmi", | |
| 100 | "bne", "bpl", "m6502_brk", "bvc", "bvs", "clc", "cld", "cli", | |
| 101 | "clv", "cmp", "cpx", "cpy", "dec", "dex", "dey", "eor", | |
| 102 | "inc", "inx", "iny", "jmp", "jsr", "lda", "ldx", "ldy", | |
| 103 | "lsr", "nop", "ora", "pha", "php", "pla", "plp", "rol", | |
| 104 | "ror", "rti", "rts", "sbc", "sec", "sed", "sei", "sta", | |
| 105 | "stx", "sty", "tax", "tay", "tsx", "txa", "txs", "tya", | |
| 106 | "ill", | |
| 107 | /* 65c02 mnemonics */ | |
| 108 | "bbr", "bbs", "bra", "rmb", "smb", "stz", "trb", "tsb", | |
| 109 | /* 65sc02 mnemonics */ | |
| 110 | "bsr", | |
| 111 | /* 6510 mnemonics */ | |
| 112 | "anc", "asr", "ast", "arr", "asx", "axa", "dcp", "dea", | |
| 113 | "dop", "ina", "isb", "lax", "phx", "phy", "plx", "ply", | |
| 114 | "rla", "rra", "sax", "slo", "sre", "sah", "say", "ssh", | |
| 115 | "sxh", "syh", "top", "oal", "kil", | |
| 116 | /* 65ce02 mnemonics */ | |
| 117 | "cle", "see", "rtn", "aug", | |
| 118 | "tab", "tba", "taz", "tza", "tys", "tsy", | |
| 119 | "ldz", "stz", | |
| 120 | "dez", "inz", "cpz", "phz", "plz", | |
| 121 | "neg", "asr", | |
| 122 | "asw", "row", "dew", "inw", "phw", | |
| 123 | /* 4510 mnemonics */ | |
| 124 | "map", | |
| 125 | ||
| 126 | /* Deco CPU16 mnemonics */ | |
| 127 | "VBL", "u13", "u8F", "uAB", "u87", "u0B", "uA3", "u4B", | |
| 128 | "u3F", "uBB", "u23" | |
| 129 | }; | |
| 130 | ||
| 131 | struct op6502_info | |
| 132 | { | |
| 133 | UINT8 opc; | |
| 134 | UINT8 arg; | |
| 135 | }; | |
| 136 | ||
| 137 | static const struct op6502_info op6502[256] = { | |
| 138 | {m6502_brk,imm},{ora,idx},{kil,non},{slo,idx},/* 00 */ | |
| 139 | {nop,zpg},{ora,zpg},{asl,zpg},{slo,zpg}, | |
| 140 | {php,imp},{ora,imm},{asl,acc},{anc,imm}, | |
| 141 | {nop,aba},{ora,aba},{asl,aba},{slo,aba}, | |
| 142 | {bpl,rel},{ora,idy},{kil,non},{slo,idy},/* 10 */ | |
| 143 | {nop,zpx},{ora,zpx},{asl,zpx},{slo,zpx}, | |
| 144 | {clc,imp},{ora,aby},{nop,imp},{slo,aby}, | |
| 145 | {nop,abx},{ora,abx},{asl,abx},{slo,abx}, | |
| 146 | {jsr,adr},{and_,idx},{kil,non},{rla,idx},/* 20 */ | |
| 147 | {bit,zpg},{and_,zpg},{rol,zpg},{rla,zpg}, | |
| 148 | {plp,imp},{and_,imm},{rol,acc},{anc,imm}, | |
| 149 | {bit,aba},{and_,aba},{rol,aba},{rla,aba}, | |
| 150 | {bmi,rel},{and_,idy},{kil,non},{rla,idy},/* 30 */ | |
| 151 | {nop,zpx},{and_,zpx},{rol,zpx},{rla,zpx}, | |
| 152 | {sec,imp},{and_,aby},{nop,imp},{rla,aby}, | |
| 153 | {nop,abx},{and_,abx},{rol,abx},{rla,abx}, | |
| 154 | {rti,imp},{eor,idx},{kil,non},{sre,idx},/* 40 */ | |
| 155 | {nop,zpg},{eor,zpg},{lsr,zpg},{sre,zpg}, | |
| 156 | {pha,imp},{eor,imm},{lsr,acc},{asr,imm}, | |
| 157 | {jmp,adr},{eor,aba},{lsr,aba},{sre,aba}, | |
| 158 | {bvc,rel},{eor,idy},{kil,non},{sre,idy},/* 50 */ | |
| 159 | {nop,zpx},{eor,zpx},{lsr,zpx},{sre,zpx}, | |
| 160 | {cli,imp},{eor,aby},{nop,imp},{sre,aby}, | |
| 161 | {nop,abx},{eor,abx},{lsr,abx},{sre,abx}, | |
| 162 | {rts,imp},{adc,idx},{kil,non},{rra,idx},/* 60 */ | |
| 163 | {nop,zpg},{adc,zpg},{ror,zpg},{rra,zpg}, | |
| 164 | {pla,imp},{adc,imm},{ror,acc},{arr,imm}, | |
| 165 | {jmp,ind},{adc,aba},{ror,aba},{rra,aba}, | |
| 166 | {bvs,rel},{adc,idy},{kil,non},{rra,idy},/* 70 */ | |
| 167 | {nop,zpx},{adc,zpx},{ror,zpx},{rra,zpx}, | |
| 168 | {sei,imp},{adc,aby},{nop,imp},{rra,aby}, | |
| 169 | {nop,abx},{adc,abx},{ror,abx},{rra,abx}, | |
| 170 | {nop,imm},{sta,idx},{nop,imm},{sax,idx},/* 80 */ | |
| 171 | {sty,zpg},{sta,zpg},{stx,zpg},{sax,zpg}, | |
| 172 | {dey,imp},{nop,imm},{txa,imp},{axa,imm}, | |
| 173 | {sty,aba},{sta,aba},{stx,aba},{sax,aba}, | |
| 174 | {bcc,rel},{sta,idy},{kil,non},{say,idy},/* 90 */ | |
| 175 | {sty,zpx},{sta,zpx},{stx,zpy},{sax,zpy}, | |
| 176 | {tya,imp},{sta,aby},{txs,imp},{ssh,aby}, | |
| 177 | {syh,abx},{sta,abx},{sxh,aby},{sah,aby}, | |
| 178 | {ldy,imm},{lda,idx},{ldx,imm},{lax,idx},/* a0 */ | |
| 179 | {ldy,zpg},{lda,zpg},{ldx,zpg},{lax,zpg}, | |
| 180 | {tay,imp},{lda,imm},{tax,imp},{oal,imm}, | |
| 181 | {ldy,aba},{lda,aba},{ldx,aba},{lax,aba}, | |
| 182 | {bcs,rel},{lda,idy},{kil,non},{lax,idy},/* b0 */ | |
| 183 | {ldy,zpx},{lda,zpx},{ldx,zpy},{lax,zpy}, | |
| 184 | {clv,imp},{lda,aby},{tsx,imp},{ast,aby}, | |
| 185 | {ldy,abx},{lda,abx},{ldx,aby},{lax,aby}, | |
| 186 | {cpy,imm},{cmp,idx},{nop,imm},{dcp,idx},/* c0 */ | |
| 187 | {cpy,zpg},{cmp,zpg},{dec,zpg},{dcp,zpg}, | |
| 188 | {iny,imp},{cmp,imm},{dex,imp},{asx,imm}, | |
| 189 | {cpy,aba},{cmp,aba},{dec,aba},{dcp,aba}, | |
| 190 | {bne,rel},{cmp,idy},{kil,non},{dcp,idy},/* d0 */ | |
| 191 | {nop,zpx},{cmp,zpx},{dec,zpx},{dcp,zpx}, | |
| 192 | {cld,imp},{cmp,aby},{nop,imp},{dcp,aby}, | |
| 193 | {nop,abx},{cmp,abx},{dec,abx},{dcp,abx}, | |
| 194 | {cpx,imm},{sbc,idx},{nop,imm},{isb,idx},/* e0 */ | |
| 195 | {cpx,zpg},{sbc,zpg},{inc,zpg},{isb,zpg}, | |
| 196 | {inx,imp},{sbc,imm},{nop,imp},{sbc,imm}, | |
| 197 | {cpx,aba},{sbc,aba},{inc,aba},{isb,aba}, | |
| 198 | {beq,rel},{sbc,idy},{kil,non},{isb,idy},/* f0 */ | |
| 199 | {nop,zpx},{sbc,zpx},{inc,zpx},{isb,zpx}, | |
| 200 | {sed,imp},{sbc,aby},{nop,imp},{isb,aby}, | |
| 201 | {nop,abx},{sbc,abx},{inc,abx},{isb,abx} | |
| 202 | }; | |
| 203 | ||
| 204 | static const struct op6502_info op65c02[256] = { | |
| 205 | {m6502_brk,imm},{ora,idx},{ill,non},{ill,non},/* 00 */ | |
| 206 | {tsb,zpg},{ora,zpg},{asl,zpg},{rmb,zpg}, | |
| 207 | {php,imp},{ora,imm},{asl,acc},{ill,non}, | |
| 208 | {tsb,aba},{ora,aba},{asl,aba},{bbr,zpb}, | |
| 209 | {bpl,rel},{ora,idy},{ora,zpi},{ill,non},/* 10 */ | |
| 210 | {trb,zpg},{ora,zpx},{asl,zpx},{rmb,zpg}, | |
| 211 | {clc,imp},{ora,aby},{ina,imp},{ill,non}, | |
| 212 | {trb,aba},{ora,abx},{asl,abx},{bbr,zpb}, | |
| 213 | {jsr,adr},{and_,idx},{ill,non},{ill,non},/* 20 */ | |
| 214 | {bit,zpg},{and_,zpg},{rol,zpg},{rmb,zpg}, | |
| 215 | {plp,imp},{and_,imm},{rol,acc},{ill,non}, | |
| 216 | {bit,aba},{and_,aba},{rol,aba},{bbr,zpb}, | |
| 217 | {bmi,rel},{and_,idy},{and_,zpi},{ill,non},/* 30 */ | |
| 218 | {bit,zpx},{and_,zpx},{rol,zpx},{rmb,zpg}, | |
| 219 | {sec,imp},{and_,aby},{dea,imp},{ill,non}, | |
| 220 | {bit,abx},{and_,abx},{rol,abx},{bbr,zpb}, | |
| 221 | {rti,imp},{eor,idx},{ill,non},{ill,non},/* 40 */ | |
| 222 | {ill,non},{eor,zpg},{lsr,zpg},{rmb,zpg}, | |
| 223 | {pha,imp},{eor,imm},{lsr,acc},{ill,non}, | |
| 224 | {jmp,adr},{eor,aba},{lsr,aba},{bbr,zpb}, | |
| 225 | {bvc,rel},{eor,idy},{eor,zpi},{ill,non},/* 50 */ | |
| 226 | {ill,non},{eor,zpx},{lsr,zpx},{rmb,zpg}, | |
| 227 | {cli,imp},{eor,aby},{phy,imp},{ill,non}, | |
| 228 | {ill,non},{eor,abx},{lsr,abx},{bbr,zpb}, | |
| 229 | {rts,imp},{adc,idx},{ill,non},{ill,non},/* 60 */ | |
| 230 | {stz,zpg},{adc,zpg},{ror,zpg},{rmb,zpg}, | |
| 231 | {pla,imp},{adc,imm},{ror,acc},{ill,non}, | |
| 232 | {jmp,ind},{adc,aba},{ror,aba},{bbr,zpb}, | |
| 233 | {bvs,rel},{adc,idy},{adc,zpi},{ill,non},/* 70 */ | |
| 234 | {stz,zpx},{adc,zpx},{ror,zpx},{rmb,zpg}, | |
| 235 | {sei,imp},{adc,aby},{ply,imp},{ill,non}, | |
| 236 | {jmp,iax},{adc,abx},{ror,abx},{bbr,zpb}, | |
| 237 | {bra,rel},{sta,idx},{ill,non},{ill,non},/* 80 */ | |
| 238 | {sty,zpg},{sta,zpg},{stx,zpg},{smb,zpg}, | |
| 239 | {dey,imp},{bit,imm},{txa,imp},{ill,non}, | |
| 240 | {sty,aba},{sta,aba},{stx,aba},{bbs,zpb}, | |
| 241 | {bcc,rel},{sta,idy},{sta,zpi},{ill,non},/* 90 */ | |
| 242 | {sty,zpx},{sta,zpx},{stx,zpy},{smb,zpg}, | |
| 243 | {tya,imp},{sta,aby},{txs,imp},{ill,non}, | |
| 244 | {stz,aba},{sta,abx},{stz,abx},{bbs,zpb}, | |
| 245 | {ldy,imm},{lda,idx},{ldx,imm},{ill,non},/* a0 */ | |
| 246 | {ldy,zpg},{lda,zpg},{ldx,zpg},{smb,zpg}, | |
| 247 | {tay,imp},{lda,imm},{tax,imp},{ill,non}, | |
| 248 | {ldy,aba},{lda,aba},{ldx,aba},{bbs,zpb}, | |
| 249 | {bcs,rel},{lda,idy},{lda,zpi},{ill,non},/* b0 */ | |
| 250 | {ldy,zpx},{lda,zpx},{ldx,zpy},{smb,zpg}, | |
| 251 | {clv,imp},{lda,aby},{tsx,imp},{ill,non}, | |
| 252 | {ldy,abx},{lda,abx},{ldx,aby},{bbs,zpb}, | |
| 253 | {cpy,imm},{cmp,idx},{ill,non},{ill,non},/* c0 */ | |
| 254 | {cpy,zpg},{cmp,zpg},{dec,zpg},{smb,zpg}, | |
| 255 | {iny,imp},{cmp,imm},{dex,imp},{ill,non}, | |
| 256 | {cpy,aba},{cmp,aba},{dec,aba},{bbs,zpb}, | |
| 257 | {bne,rel},{cmp,idy},{cmp,zpi},{ill,non},/* d0 */ | |
| 258 | {ill,non},{cmp,zpx},{dec,zpx},{smb,zpg}, | |
| 259 | {cld,imp},{cmp,aby},{phx,imp},{ill,non}, | |
| 260 | {ill,non},{cmp,abx},{dec,abx},{bbs,zpb}, | |
| 261 | {cpx,imm},{sbc,idx},{ill,non},{ill,non},/* e0 */ | |
| 262 | {cpx,zpg},{sbc,zpg},{inc,zpg},{smb,zpg}, | |
| 263 | {inx,imp},{sbc,imm},{nop,imp},{ill,non}, | |
| 264 | {cpx,aba},{sbc,aba},{inc,aba},{bbs,zpb}, | |
| 265 | {beq,rel},{sbc,idy},{sbc,zpi},{ill,non},/* f0 */ | |
| 266 | {ill,non},{sbc,zpx},{inc,zpx},{smb,zpg}, | |
| 267 | {sed,imp},{sbc,aby},{plx,imp},{ill,non}, | |
| 268 | {ill,non},{sbc,abx},{inc,abx},{bbs,zpb} | |
| 269 | }; | |
| 270 | ||
| 271 | /* only bsr additional to 65c02 yet */ | |
| 272 | static const struct op6502_info op65sc02[256] = { | |
| 273 | {m6502_brk,imm},{ora,idx},{ill,non},{ill,non},/* 00 */ | |
| 274 | {tsb,zpg},{ora,zpg},{asl,zpg},{rmb,zpg}, | |
| 275 | {php,imp},{ora,imm},{asl,acc},{ill,non}, | |
| 276 | {tsb,aba},{ora,aba},{asl,aba},{bbr,zpb}, | |
| 277 | {bpl,rel},{ora,idy},{ora,zpi},{ill,non},/* 10 */ | |
| 278 | {trb,zpg},{ora,zpx},{asl,zpx},{rmb,zpg}, | |
| 279 | {clc,imp},{ora,aby},{ina,imp},{ill,non}, | |
| 280 | {trb,aba},{ora,abx},{asl,abx},{bbr,zpb}, | |
| 281 | {jsr,adr},{and_,idx},{ill,non},{ill,non},/* 20 */ | |
| 282 | {bit,zpg},{and_,zpg},{rol,zpg},{rmb,zpg}, | |
| 283 | {plp,imp},{and_,imm},{rol,acc},{ill,non}, | |
| 284 | {bit,aba},{and_,aba},{rol,aba},{bbr,zpb}, | |
| 285 | {bmi,rel},{and_,idy},{and_,zpi},{ill,non},/* 30 */ | |
| 286 | {bit,zpx},{and_,zpx},{rol,zpx},{rmb,zpg}, | |
| 287 | {sec,imp},{and_,aby},{dea,imp},{ill,non}, | |
| 288 | {bit,abx},{and_,abx},{rol,abx},{bbr,zpb}, | |
| 289 | {rti,imp},{eor,idx},{ill,non},{ill,non},/* 40 */ | |
| 290 | {ill,non},{eor,zpg},{lsr,zpg},{rmb,zpg}, | |
| 291 | {pha,imp},{eor,imm},{lsr,acc},{ill,non}, | |
| 292 | {jmp,adr},{eor,aba},{lsr,aba},{bbr,zpb}, | |
| 293 | {bvc,rel},{eor,idy},{eor,zpi},{ill,non},/* 50 */ | |
| 294 | {ill,non},{eor,zpx},{lsr,zpx},{rmb,zpg}, | |
| 295 | {cli,imp},{eor,aby},{phy,imp},{ill,non}, | |
| 296 | {ill,non},{eor,abx},{lsr,abx},{bbr,zpb}, | |
| 297 | {rts,imp},{adc,idx},{ill,non},{bsr,rw2},/* 60 */ | |
| 298 | {stz,zpg},{adc,zpg},{ror,zpg},{rmb,zpg}, | |
| 299 | {pla,imp},{adc,imm},{ror,acc},{ill,non}, | |
| 300 | {jmp,ind},{adc,aba},{ror,aba},{bbr,zpb}, | |
| 301 | {bvs,rel},{adc,idy},{adc,zpi},{ill,non},/* 70 */ | |
| 302 | {stz,zpx},{adc,zpx},{ror,zpx},{rmb,zpg}, | |
| 303 | {sei,imp},{adc,aby},{ply,imp},{ill,non}, | |
| 304 | {jmp,iax},{adc,abx},{ror,abx},{bbr,zpb}, | |
| 305 | {bra,rel},{sta,idx},{ill,non},{ill,non},/* 80 */ | |
| 306 | {sty,zpg},{sta,zpg},{stx,zpg},{smb,zpg}, | |
| 307 | {dey,imp},{bit,imm},{txa,imp},{ill,non}, | |
| 308 | {sty,aba},{sta,aba},{stx,aba},{bbs,zpb}, | |
| 309 | {bcc,rel},{sta,idy},{sta,zpi},{ill,non},/* 90 */ | |
| 310 | {sty,zpx},{sta,zpx},{stx,zpy},{smb,zpg}, | |
| 311 | {tya,imp},{sta,aby},{txs,imp},{ill,non}, | |
| 312 | {stz,aba},{sta,abx},{stz,abx},{bbs,zpb}, | |
| 313 | {ldy,imm},{lda,idx},{ldx,imm},{ill,non},/* a0 */ | |
| 314 | {ldy,zpg},{lda,zpg},{ldx,zpg},{smb,zpg}, | |
| 315 | {tay,imp},{lda,imm},{tax,imp},{ill,non}, | |
| 316 | {ldy,aba},{lda,aba},{ldx,aba},{bbs,zpb}, | |
| 317 | {bcs,rel},{lda,idy},{lda,zpi},{ill,non},/* b0 */ | |
| 318 | {ldy,zpx},{lda,zpx},{ldx,zpy},{smb,zpg}, | |
| 319 | {clv,imp},{lda,aby},{tsx,imp},{ill,non}, | |
| 320 | {ldy,abx},{lda,abx},{ldx,aby},{bbs,zpb}, | |
| 321 | {cpy,imm},{cmp,idx},{ill,non},{ill,non},/* c0 */ | |
| 322 | {cpy,zpg},{cmp,zpg},{dec,zpg},{smb,zpg}, | |
| 323 | {iny,imp},{cmp,imm},{dex,imp},{ill,non}, | |
| 324 | {cpy,aba},{cmp,aba},{dec,aba},{bbs,zpb}, | |
| 325 | {bne,rel},{cmp,idy},{cmp,zpi},{ill,non},/* d0 */ | |
| 326 | {ill,non},{cmp,zpx},{dec,zpx},{smb,zpg}, | |
| 327 | {cld,imp},{cmp,aby},{phx,imp},{ill,non}, | |
| 328 | {ill,non},{cmp,abx},{dec,abx},{bbs,zpb}, | |
| 329 | {cpx,imm},{sbc,idx},{ill,non},{ill,non},/* e0 */ | |
| 330 | {cpx,zpg},{sbc,zpg},{inc,zpg},{smb,zpg}, | |
| 331 | {inx,imp},{sbc,imm},{nop,imp},{ill,non}, | |
| 332 | {cpx,aba},{sbc,aba},{inc,aba},{bbs,zpb}, | |
| 333 | {beq,rel},{sbc,idy},{sbc,zpi},{ill,non},/* f0 */ | |
| 334 | {ill,non},{sbc,zpx},{inc,zpx},{smb,zpg}, | |
| 335 | {sed,imp},{sbc,aby},{plx,imp},{ill,non}, | |
| 336 | {ill,non},{sbc,abx},{inc,abx},{bbs,zpb} | |
| 337 | }; | |
| 338 | ||
| 339 | static const struct op6502_info op65ce02[256] = { | |
| 340 | {m6502_brk,imm},{ora,idx},{cle,imp},{see,imp},/* 00 */ | |
| 341 | {tsb,zpg},{ora,zpg},{asl,zpg},{rmb,zpg}, | |
| 342 | {php,imp},{ora,imm},{asl,acc},{tsy,imp}, | |
| 343 | {tsb,aba},{ora,aba},{asl,aba},{bbr,zpb}, | |
| 344 | {bpl,rel},{ora,idy},{ora,idz},{bpl,rw2},/* 10 */ | |
| 345 | {trb,zpg},{ora,zpx},{asl,zpx},{rmb,zpg}, | |
| 346 | {clc,imp},{ora,aby},{ina,imp},{inz,imp}, | |
| 347 | {trb,aba},{ora,abx},{asl,abx},{bbr,zpb}, | |
| 348 | {jsr,adr},{and_,idx},{jsr,ind},{jsr,iax},/* 20 */ | |
| 349 | {bit,zpg},{and_,zpg},{rol,zpg},{rmb,zpg}, | |
| 350 | {plp,imp},{and_,imm},{rol,acc},{tys,imp}, | |
| 351 | {bit,aba},{and_,aba},{rol,aba},{bbr,zpb}, | |
| 352 | {bmi,rel},{and_,idz},{and_,zpi},{bmi,rw2},/* 30 */ | |
| 353 | {bit,zpx},{and_,zpx},{rol,zpx},{rmb,zpg}, | |
| 354 | {sec,imp},{and_,aby},{dea,imp},{dez,imp}, | |
| 355 | {bit,abx},{and_,abx},{rol,abx},{bbr,zpb}, | |
| 356 | {rti,imp},{eor,idx},{neg,imp},{asr2,imp},/* 40 */ | |
| 357 | {asr2,zpg},{eor,zpg},{lsr,zpg},{rmb,zpg}, | |
| 358 | {pha,imp},{eor,imm},{lsr,acc},{taz,imp}, | |
| 359 | {jmp,adr},{eor,aba},{lsr,aba},{bbr,zpb}, | |
| 360 | {bvc,rel},{eor,idy},{eor,idz},{bvc,rw2},/* 50 */ | |
| 361 | {asr2,zpx},{eor,zpx},{lsr,zpx},{rmb,zpg}, | |
| 362 | {cli,imp},{eor,aby},{phy,imp},{tab,imp}, | |
| 363 | {aug,iw3},{eor,abx},{lsr,abx},{bbr,zpb}, | |
| 364 | {rts,imp},{adc,idx},{rtn,imm},{bsr,rw2},/* 60 */ | |
| 365 | {stz2,zpg},{adc,zpg},{ror,zpg},{rmb,zpg}, | |
| 366 | {pla,imp},{adc,imm},{ror,acc},{tza,imp}, | |
| 367 | {jmp,ind},{adc,aba},{ror,aba},{bbr,zpb}, | |
| 368 | {bvs,rel},{adc,idy},{adc,zpi},{bvs,rw2},/* 70 */ | |
| 369 | {stz2,zpx},{adc,zpx},{ror,zpx},{rmb,zpg}, | |
| 370 | {sei,imp},{adc,aby},{ply,imp},{tba,imp}, | |
| 371 | {jmp,iax},{adc,abx},{ror,abx},{bbr,zpb}, | |
| 372 | {bra,rel},{sta,idx},{sta,isy},{bra,rw2},/* 80 */ | |
| 373 | {sty,zpg},{sta,zpg},{stx,zpg},{smb,zpg}, | |
| 374 | {dey,imp},{bit,imm},{txa,imp},{sty,abx}, | |
| 375 | {sty,aba},{sta,aba},{stx,aba},{bbs,zpb}, | |
| 376 | {bcc,rel},{sta,idy},{sta,inz},{bcc,rw2},/* 90 */ | |
| 377 | {sty,zpx},{sta,zpx},{stx,zpy},{smb,zpg}, | |
| 378 | {tya,imp},{sta,aby},{txs,imp},{stx,aby}, | |
| 379 | {stz2,aba},{sta,abx},{stz2,abx},{bbs,zpb}, | |
| 380 | {ldy,imm},{lda,idx},{ldx,imm},{ldz,imm},/* a0 */ | |
| 381 | {ldy,zpg},{lda,zpg},{ldx,zpg},{smb,zpg}, | |
| 382 | {tay,imp},{lda,imm},{tax,imp},{ldz,aba}, | |
| 383 | {ldy,aba},{lda,aba},{ldx,aba},{bbs,zpb}, | |
| 384 | {bcs,rel},{lda,idy},{lda,inz},{bcs,rw2},/* b0 */ | |
| 385 | {ldy,zpx},{lda,zpx},{ldx,zpy},{smb,zpg}, | |
| 386 | {clv,imp},{lda,aby},{tsx,imp},{ldz,abx}, | |
| 387 | {ldy,abx},{lda,abx},{ldx,aby},{bbs,zpb}, | |
| 388 | {cpy,imm},{cmp,idx},{cpz,imm},{dew,zpg},/* c0 */ | |
| 389 | {cpy,zpg},{cmp,zpg},{dec,zpg},{smb,zpg}, | |
| 390 | {iny,imp},{cmp,imm},{dex,imp},{asw,aba}, | |
| 391 | {cpy,aba},{cmp,aba},{dec,aba},{bbs,zpb}, | |
| 392 | {bne,rel},{cmp,idy},{cmp,idz},{bne,rw2},/* d0 */ | |
| 393 | {cpz,zpg},{cmp,zpx},{dec,zpx},{smb,zpg}, | |
| 394 | {cld,imp},{cmp,aby},{phx,imp},{phz,imp}, | |
| 395 | {cpz,aba},{cmp,abx},{dec,abx},{bbs,zpb}, | |
| 396 | {cpx,imm},{sbc,idx},{lda,isy},{inw,zpg},/* e0 */ | |
| 397 | {cpx,zpg},{sbc,zpg},{inc,zpg},{smb,zpg}, | |
| 398 | {inx,imp},{sbc,imm},{nop,imp},{row,aba}, | |
| 399 | {cpx,aba},{sbc,aba},{inc,aba},{bbs,zpb}, | |
| 400 | {beq,rel},{sbc,idy},{sbc,idz},{beq,rw2},/* f0 */ | |
| 401 | {phw,iw2},{sbc,zpx},{inc,zpx},{smb,zpg}, | |
| 402 | {sed,imp},{sbc,aby},{plx,imp},{plz,imp}, | |
| 403 | {phw,aba},{sbc,abx},{inc,abx},{bbs,zpb} | |
| 404 | }; | |
| 405 | ||
| 406 | // only map instead of aug and 20 bit memory management | |
| 407 | static const struct op6502_info op4510[256] = { | |
| 408 | {m6502_brk,imm},{ora,idx},{cle,imp},{see,imp},/* 00 */ | |
| 409 | {tsb,zpg},{ora,zpg},{asl,zpg},{rmb,zpg}, | |
| 410 | {php,imp},{ora,imm},{asl,acc},{tsy,imp}, | |
| 411 | {tsb,aba},{ora,aba},{asl,aba},{bbr,zpb}, | |
| 412 | {bpl,rel},{ora,idy},{ora,idz},{bpl,rw2},/* 10 */ | |
| 413 | {trb,zpg},{ora,zpx},{asl,zpx},{rmb,zpg}, | |
| 414 | {clc,imp},{ora,aby},{ina,imp},{inz,imp}, | |
| 415 | {trb,aba},{ora,abx},{asl,abx},{bbr,zpb}, | |
| 416 | {jsr,adr},{and_,idx},{jsr,ind},{jsr,iax},/* 20 */ | |
| 417 | {bit,zpg},{and_,zpg},{rol,zpg},{rmb,zpg}, | |
| 418 | {plp,imp},{and_,imm},{rol,acc},{tys,imp}, | |
| 419 | {bit,aba},{and_,aba},{rol,aba},{bbr,zpb}, | |
| 420 | {bmi,rel},{and_,idz},{and_,zpi},{bmi,rw2},/* 30 */ | |
| 421 | {bit,zpx},{and_,zpx},{rol,zpx},{rmb,zpg}, | |
| 422 | {sec,imp},{and_,aby},{dea,imp},{dez,imp}, | |
| 423 | {bit,abx},{and_,abx},{rol,abx},{bbr,zpb}, | |
| 424 | {rti,imp},{eor,idx},{neg,imp},{asr2,imp},/* 40 */ | |
| 425 | {asr2,zpg},{eor,zpg},{lsr,zpg},{rmb,zpg}, | |
| 426 | {pha,imp},{eor,imm},{lsr,acc},{taz,imp}, | |
| 427 | {jmp,adr},{eor,aba},{lsr,aba},{bbr,zpb}, | |
| 428 | {bvc,rel},{eor,idy},{eor,idz},{bvc,rw2},/* 50 */ | |
| 429 | {asr2,zpx},{eor,zpx},{lsr,zpx},{rmb,zpg}, | |
| 430 | {cli,imp},{eor,aby},{phy,imp},{tab,imp}, | |
| 431 | {map,imp},{eor,abx},{lsr,abx},{bbr,zpb}, | |
| 432 | {rts,imp},{adc,idx},{rtn,imm},{bsr,rw2},/* 60 */ | |
| 433 | {stz2,zpg},{adc,zpg},{ror,zpg},{rmb,zpg}, | |
| 434 | {pla,imp},{adc,imm},{ror,acc},{tza,imp}, | |
| 435 | {jmp,ind},{adc,aba},{ror,aba},{bbr,zpb}, | |
| 436 | {bvs,rel},{adc,idy},{adc,zpi},{bvs,rw2},/* 70 */ | |
| 437 | {stz2,zpx},{adc,zpx},{ror,zpx},{rmb,zpg}, | |
| 438 | {sei,imp},{adc,aby},{ply,imp},{tba,imp}, | |
| 439 | {jmp,iax},{adc,abx},{ror,abx},{bbr,zpb}, | |
| 440 | {bra,rel},{sta,idx},{sta,isy},{bra,rw2},/* 80 */ | |
| 441 | {sty,zpg},{sta,zpg},{stx,zpg},{smb,zpg}, | |
| 442 | {dey,imp},{bit,imm},{txa,imp},{sty,abx}, | |
| 443 | {sty,aba},{sta,aba},{stx,aba},{bbs,zpb}, | |
| 444 | {bcc,rel},{sta,idy},{sta,inz},{bcc,rw2},/* 90 */ | |
| 445 | {sty,zpx},{sta,zpx},{stx,zpy},{smb,zpg}, | |
| 446 | {tya,imp},{sta,aby},{txs,imp},{stx,aby}, | |
| 447 | {stz2,aba},{sta,abx},{stz2,abx},{bbs,zpb}, | |
| 448 | {ldy,imm},{lda,idx},{ldx,imm},{ldz,imm},/* a0 */ | |
| 449 | {ldy,zpg},{lda,zpg},{ldx,zpg},{smb,zpg}, | |
| 450 | {tay,imp},{lda,imm},{tax,imp},{ldz,aba}, | |
| 451 | {ldy,aba},{lda,aba},{ldx,aba},{bbs,zpb}, | |
| 452 | {bcs,rel},{lda,idy},{lda,inz},{bcs,rw2},/* b0 */ | |
| 453 | {ldy,zpx},{lda,zpx},{ldx,zpy},{smb,zpg}, | |
| 454 | {clv,imp},{lda,aby},{tsx,imp},{ldz,abx}, | |
| 455 | {ldy,abx},{lda,abx},{ldx,aby},{bbs,zpb}, | |
| 456 | {cpy,imm},{cmp,idx},{cpz,imm},{dew,zpg},/* c0 */ | |
| 457 | {cpy,zpg},{cmp,zpg},{dec,zpg},{smb,zpg}, | |
| 458 | {iny,imp},{cmp,imm},{dex,imp},{asw,aba}, | |
| 459 | {cpy,aba},{cmp,aba},{dec,aba},{bbs,zpb}, | |
| 460 | {bne,rel},{cmp,idy},{cmp,idz},{bne,rw2},/* d0 */ | |
| 461 | {cpz,zpg},{cmp,zpx},{dec,zpx},{smb,zpg}, | |
| 462 | {cld,imp},{cmp,aby},{phx,imp},{phz,imp}, | |
| 463 | {cpz,aba},{cmp,abx},{dec,abx},{bbs,zpb}, | |
| 464 | {cpx,imm},{sbc,idx},{lda,isy},{inw,zpg},/* e0 */ | |
| 465 | {cpx,zpg},{sbc,zpg},{inc,zpg},{smb,zpg}, | |
| 466 | {inx,imp},{sbc,imm},{nop,imp},{row,aba}, | |
| 467 | {cpx,aba},{sbc,aba},{inc,aba},{bbs,zpb}, | |
| 468 | {beq,rel},{sbc,idy},{sbc,idz},{beq,rw2},/* f0 */ | |
| 469 | {phw,iw2},{sbc,zpx},{inc,zpx},{smb,zpg}, | |
| 470 | {sed,imp},{sbc,aby},{plx,imp},{plz,imp}, | |
| 471 | {phw,aba},{sbc,abx},{inc,abx},{bbs,zpb} | |
| 472 | }; | |
| 473 | ||
| 474 | static const struct op6502_info opdeco16[256] = | |
| 475 | { | |
| 476 | {m6502_brk,imp},{ora,idx},{ill,non},{ill,non},/* 00 */ | |
| 477 | {ill,non},{ora,zpg},{asl,zpg},{ill,non}, | |
| 478 | {php,imp},{ora,imm},{asl,acc},{u0B,zpg}, | |
| 479 | {ill,non},{ora,aba},{asl,aba},{ill,non}, | |
| 480 | {bpl,rel},{ora,idy},{ill,non},{u13,zpg},/* 10 */ | |
| 481 | {ill,non},{ora,zpx},{asl,zpx},{ill,non}, | |
| 482 | {clc,imp},{ora,aby},{ill,non},{ill,non}, | |
| 483 | {ill,non},{ora,abx},{asl,abx},{ill,non}, | |
| 484 | {jsr,adr},{and_,idx},{ill,non},{u23,zpg},/* 20 */ | |
| 485 | {bit,zpg},{and_,zpg},{rol,zpg},{ill,non}, | |
| 486 | {plp,imp},{and_,imm},{rol,acc},{ill,non}, | |
| 487 | {bit,aba},{and_,aba},{rol,aba},{ill,non}, | |
| 488 | {bmi,rel},{and_,idy},{ill,non},{ill,non},/* 30 */ | |
| 489 | {ill,non},{and_,zpx},{rol,zpx},{ill,non}, | |
| 490 | {sec,imp},{and_,aby},{ill,non},{ill,non}, | |
| 491 | {ill,non},{and_,abx},{rol,abx},{u3F,zpg}, | |
| 492 | {rti,imp},{eor,idx},{ill,non},{ill,non},/* 40 */ | |
| 493 | {ill,non},{eor,zpg},{lsr,zpg},{ill,non}, | |
| 494 | {pha,imp},{eor,imm},{lsr,acc},{u4B,zpg}, | |
| 495 | {jmp,adr},{eor,aba},{lsr,aba},{ill,non}, | |
| 496 | {bvc,rel},{eor,idy},{ill,non},{ill,non},/* 50 */ | |
| 497 | {ill,non},{eor,zpx},{lsr,zpx},{ill,non}, | |
| 498 | {cli,imp},{eor,aby},{ill,non},{ill,non}, | |
| 499 | {ill,non},{eor,abx},{lsr,abx},{ill,non}, | |
| 500 | {rts,imp},{adc,idx},{ill,non},{ill,non},/* 60 */ | |
| 501 | {ill,non},{adc,zpg},{ror,zpg},{vbl,zpg}, // MISH | |
| 502 | {pla,imp},{adc,imm},{ror,acc},{ill,non}, | |
| 503 | {jmp,ind},{adc,aba},{ror,aba},{ill,non}, | |
| 504 | {bvs,rel},{adc,idy},{ill,non},{ill,non},/* 70 */ | |
| 505 | {ill,non},{adc,zpx},{ror,zpx},{ill,non}, | |
| 506 | {sei,imp},{adc,aby},{ill,non},{ill,non}, | |
| 507 | {ill,non},{adc,abx},{ror,abx},{ill,non}, | |
| 508 | {ill,non},{sta,idx},{ill,non},{ill,non},/* 80 */ | |
| 509 | {sty,zpg},{sta,zpg},{stx,zpg},{u87,zpg}, | |
| 510 | {dey,imp},{ill,non},{txa,imp},{ill,non}, | |
| 511 | {sty,aba},{sta,aba},{stx,aba},{u8F,zpg}, | |
| 512 | {bcc,rel},{sta,idy},{ill,non},{ill,non},/* 90 */ | |
| 513 | {sty,zpx},{sta,zpx},{stx,zpy},{ill,non}, | |
| 514 | {tya,imp},{sta,aby},{txs,imp},{ill,non}, | |
| 515 | {ill,non},{sta,abx},{ill,non},{ill,non}, | |
| 516 | {ldy,imm},{lda,idx},{ldx,imm},{uA3,zpg},/* a0 */ | |
| 517 | {ldy,zpg},{lda,zpg},{ldx,zpg},{ill,non}, | |
| 518 | {tay,imp},{lda,imm},{tax,imp},{uAB,zpg}, | |
| 519 | {ldy,aba},{lda,aba},{ldx,aba},{ill,non}, | |
| 520 | {bcs,rel},{lda,idy},{ill,non},{ill,non},/* b0 */ | |
| 521 | {ldy,zpx},{lda,zpx},{ldx,zpy},{ill,non}, | |
| 522 | {clv,imp},{lda,aby},{tsx,imp},{uBB,zpg}, | |
| 523 | {ldy,abx},{lda,abx},{ldx,aby},{ill,non}, | |
| 524 | {cpy,imm},{cmp,idx},{ill,non},{ill,non},/* c0 */ | |
| 525 | {cpy,zpg},{cmp,zpg},{dec,zpg},{ill,non}, | |
| 526 | {iny,imp},{cmp,imm},{dex,imp},{ill,non}, | |
| 527 | {cpy,aba},{cmp,aba},{dec,aba},{ill,non}, | |
| 528 | {bne,rel},{cmp,idy},{ill,non},{ill,non},/* d0 */ | |
| 529 | {ill,non},{cmp,zpx},{dec,zpx},{ill,non}, | |
| 530 | {cld,imp},{cmp,aby},{ill,non},{ill,non}, | |
| 531 | {ill,non},{cmp,abx},{dec,abx},{ill,non}, | |
| 532 | {cpx,imm},{sbc,idx},{ill,non},{ill,non},/* e0 */ | |
| 533 | {cpx,zpg},{sbc,zpg},{inc,zpg},{ill,non}, | |
| 534 | {inx,imp},{sbc,imm},{nop,imp},{ill,non}, | |
| 535 | {cpx,aba},{sbc,aba},{inc,aba},{ill,non}, | |
| 536 | {beq,rel},{sbc,idy},{ill,non},{ill,non},/* f0 */ | |
| 537 | {ill,non},{sbc,zpx},{inc,zpx},{ill,non}, | |
| 538 | {sed,imp},{sbc,aby},{ill,non},{ill,non}, | |
| 539 | {ill,non},{sbc,abx},{inc,abx},{ill,non} | |
| 540 | }; | |
| 541 | ||
| 542 | /***************************************************************************** | |
| 543 | * Disassemble a single opcode starting at pc | |
| 544 | *****************************************************************************/ | |
| 545 | static unsigned internal_m6502_dasm(const struct op6502_info *opinfo, char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram) | |
| 546 | { | |
| 547 | char *dst = buffer; | |
| 548 | INT8 offset; | |
| 549 | INT16 offset16; | |
| 550 | unsigned PC = pc; | |
| 551 | UINT16 addr; | |
| 552 | UINT8 op, opc, arg, value; | |
| 553 | UINT32 flags; | |
| 554 | int pos = 0; | |
| 555 | ||
| 556 | op = oprom[pos++]; | |
| 557 | pc++; | |
| 558 | ||
| 559 | opc = opinfo[op].opc; | |
| 560 | arg = opinfo[op].arg; | |
| 561 | ||
| 562 | /* determine dasmflags */ | |
| 563 | switch(opc) | |
| 564 | { | |
| 565 | case jsr: | |
| 566 | case bsr: | |
| 567 | flags = DASMFLAG_SUPPORTED | DASMFLAG_STEP_OVER; | |
| 568 | break; | |
| 569 | ||
| 570 | case rts: | |
| 571 | case rti: | |
| 572 | case rtn: | |
| 573 | flags = DASMFLAG_SUPPORTED | DASMFLAG_STEP_OUT; | |
| 574 | break; | |
| 575 | ||
| 576 | default: | |
| 577 | flags = DASMFLAG_SUPPORTED; | |
| 578 | break; | |
| 579 | } | |
| 580 | ||
| 581 | dst += sprintf(dst, "%-5s", token[opc]); | |
| 582 | if( opc == bbr || opc == bbs || opc == rmb || opc == smb ) | |
| 583 | dst += sprintf(dst, "%d,", (op >> 4) & 7); | |
| 584 | ||
| 585 | switch(arg) | |
| 586 | { | |
| 587 | case imp: | |
| 588 | break; | |
| 589 | ||
| 590 | case acc: | |
| 591 | dst += sprintf(dst,"a"); | |
| 592 | break; | |
| 593 | ||
| 594 | case rel: | |
| 595 | offset = (INT8) opram[pos++]; | |
| 596 | pc++; | |
| 597 | dst += sprintf(dst, "$%04X", (pc + offset) & 0xFFFF); | |
| 598 | break; | |
| 599 | ||
| 600 | case rw2: | |
| 601 | offset16 = (opram[pos] | (opram[pos+1] << 8)) -1; | |
| 602 | pos += 2; | |
| 603 | pc += 2; | |
| 604 | dst += sprintf(dst, "$%04X", (pc + offset16) & 0xFFFF); | |
| 605 | break; | |
| 606 | ||
| 607 | case imm: | |
| 608 | value = opram[pos++]; | |
| 609 | pc++; | |
| 610 | dst += sprintf(dst,"#$%02X", value); | |
| 611 | break; | |
| 612 | ||
| 613 | case zpg: | |
| 614 | addr = opram[pos++]; | |
| 615 | pc++; | |
| 616 | dst += sprintf(dst,"$%02X", addr); | |
| 617 | break; | |
| 618 | ||
| 619 | case zpx: | |
| 620 | addr = opram[pos++]; | |
| 621 | pc++; | |
| 622 | dst += sprintf(dst,"$%02X,x", addr); | |
| 623 | break; | |
| 624 | ||
| 625 | case zpy: | |
| 626 | addr = opram[pos++]; | |
| 627 | pc++; | |
| 628 | dst += sprintf(dst,"$%02X,y", addr); | |
| 629 | break; | |
| 630 | ||
| 631 | case idx: | |
| 632 | addr = opram[pos++]; | |
| 633 | pc++; | |
| 634 | dst += sprintf(dst,"($%02X,x)", addr); | |
| 635 | break; | |
| 636 | ||
| 637 | case idy: | |
| 638 | addr = opram[pos++]; | |
| 639 | pc++; | |
| 640 | dst += sprintf(dst,"($%02X),y", addr); | |
| 641 | break; | |
| 642 | ||
| 643 | case zpi: | |
| 644 | addr = opram[pos++]; | |
| 645 | pc++; | |
| 646 | dst += sprintf(dst,"($%02X)", addr); | |
| 647 | break; | |
| 648 | ||
| 649 | case zpb: | |
| 650 | addr = opram[pos++]; | |
| 651 | pc++; | |
| 652 | dst += sprintf(dst,"$%02X", addr); | |
| 653 | offset = (INT8) opram[pos++]; | |
| 654 | pc++; | |
| 655 | dst += sprintf(dst,",$%04X", pc + offset); | |
| 656 | break; | |
| 657 | ||
| 658 | case adr: | |
| 659 | addr = (opram[pos] | (opram[pos+1] << 8)); | |
| 660 | pos += 2; | |
| 661 | pc += 2; | |
| 662 | dst += sprintf(dst, "$%04X", addr); | |
| 663 | break; | |
| 664 | ||
| 665 | case aba: | |
| 666 | addr = (opram[pos] | (opram[pos+1] << 8)); | |
| 667 | pos += 2; | |
| 668 | pc += 2; | |
| 669 | dst += sprintf(dst, "$%04X", addr); | |
| 670 | break; | |
| 671 | ||
| 672 | case abx: | |
| 673 | addr = (opram[pos] | (opram[pos+1] << 8)); | |
| 674 | pos += 2; | |
| 675 | pc += 2; | |
| 676 | dst += sprintf(dst,"$%04X,x", addr); | |
| 677 | break; | |
| 678 | ||
| 679 | case aby: | |
| 680 | addr = (opram[pos] | (opram[pos+1] << 8)); | |
| 681 | pos += 2; | |
| 682 | pc += 2; | |
| 683 | dst += sprintf(dst,"$%04X,y", addr); | |
| 684 | break; | |
| 685 | ||
| 686 | case ind: | |
| 687 | addr = (opram[pos] | (opram[pos+1] << 8)); | |
| 688 | pos += 2; | |
| 689 | pc += 2; | |
| 690 | dst += sprintf(dst,"($%04X)", addr); | |
| 691 | break; | |
| 692 | ||
| 693 | case iax: | |
| 694 | addr = (opram[pos] | (opram[pos+1] << 8)); | |
| 695 | pos += 2; | |
| 696 | pc += 2; | |
| 697 | dst += sprintf(dst,"($%04X),X", addr); | |
| 698 | break; | |
| 699 | ||
| 700 | case iw2: | |
| 701 | addr = (opram[pos] | (opram[pos+1] << 8)); | |
| 702 | pos += 2; | |
| 703 | pc += 2; | |
| 704 | dst += sprintf(dst,"#%04X", addr); | |
| 705 | break; | |
| 706 | ||
| 707 | case iw3: | |
| 708 | addr = (opram[pos] | (opram[pos+1] << 8) | (opram[pos+2] << 16)); | |
| 709 | pos += 3; | |
| 710 | pc += 3; | |
| 711 | dst += sprintf(dst,"#%06x", addr); | |
| 712 | break; | |
| 713 | ||
| 714 | case idz: | |
| 715 | addr = (INT8) opram[pos++]; | |
| 716 | pc++; | |
| 717 | dst += sprintf(dst,"($%02X),z", addr); | |
| 718 | break; | |
| 719 | ||
| 720 | case isy: | |
| 721 | op = opram[pos++]; | |
| 722 | pc++; | |
| 723 | addr = op; | |
| 724 | dst += sprintf(dst,"(s,$%02X),y", addr); | |
| 725 | break; | |
| 726 | ||
| 727 | default: | |
| 728 | dst += sprintf(dst,"$%02X", op); | |
| 729 | break; | |
| 730 | } | |
| 731 | return (pc - PC) | flags; | |
| 732 | } | |
| 733 | ||
| 734 | CPU_DISASSEMBLE( m6502 ) | |
| 735 | { | |
| 736 | return internal_m6502_dasm(op6502, buffer, pc, oprom, opram); | |
| 737 | } | |
| 738 | ||
| 739 | CPU_DISASSEMBLE( m65sc02 ) | |
| 740 | { | |
| 741 | return internal_m6502_dasm(op65sc02, buffer, pc, oprom, opram); | |
| 742 | } | |
| 743 | ||
| 744 | CPU_DISASSEMBLE( m65c02 ) | |
| 745 | { | |
| 746 | return internal_m6502_dasm(op65c02, buffer, pc, oprom, opram); | |
| 747 | } | |
| 748 | ||
| 749 | CPU_DISASSEMBLE( m65ce02 ) | |
| 750 | { | |
| 751 | return internal_m6502_dasm(op65ce02, buffer, pc, oprom, opram); | |
| 752 | } | |
| 753 | ||
| 754 | CPU_DISASSEMBLE( m6510 ) | |
| 755 | { | |
| 756 | return internal_m6502_dasm(op6502, buffer, pc, oprom, opram); | |
| 757 | } | |
| 758 | ||
| 759 | CPU_DISASSEMBLE( deco16 ) | |
| 760 | { | |
| 761 | return internal_m6502_dasm(opdeco16, buffer, pc, oprom, opram); | |
| 762 | } | |
| 763 | ||
| 764 | CPU_DISASSEMBLE( m4510 ) | |
| 765 | { | |
| 766 | return internal_m6502_dasm(op4510, buffer, pc, oprom, opram); | |
| 767 | } |
| r18874 | r18875 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * Deco CPU16 instructions - still very work in progress! | |
| 3 | * | |
| 4 | *****************************************************************************/ | |
| 5 | ||
| 6 | #define DECO16_VERBOSE 0 | |
| 7 | ||
| 8 | #undef OP | |
| 9 | #define OP(nn) INLINE void deco16_##nn(m6502_Regs *cpustate) | |
| 10 | ||
| 11 | #define DECO16_BRK \ | |
| 12 | logerror("%04x: BRK\n",PCW); \ | |
| 13 | RDOPARG(); \ | |
| 14 | PUSH(PCH); \ | |
| 15 | PUSH(PCL); \ | |
| 16 | PUSH(P | F_B); \ | |
| 17 | P = (P | F_I); \ | |
| 18 | PCL = RDMEM(DECO16_IRQ_VEC+1); \ | |
| 19 | PCH = RDMEM(DECO16_IRQ_VEC); | |
| 20 | ||
| 21 | ||
| 22 | /***************************************************************************** | |
| 23 | ***************************************************************************** | |
| 24 | * | |
| 25 | * overrides for 6502 opcodes | |
| 26 | * | |
| 27 | ***************************************************************************** | |
| 28 | * op temp cycles rdmem opc wrmem ********************/ | |
| 29 | OP(00) { DECO16_BRK; } /* 7 BRK */ | |
| 30 | #define deco16_20 m6502_20 /* 6 JSR ABS */ | |
| 31 | #define deco16_40 m6502_40 /* 6 RTI */ | |
| 32 | #define deco16_60 m6502_60 /* 6 RTS */ | |
| 33 | OP(80) { RD_DUM; ILL; } /* 2 ILL */ | |
| 34 | #define deco16_a0 m6502_a0 /* 2 LDY IMM */ | |
| 35 | #define deco16_c0 m6502_c0 /* 2 CPY IMM */ | |
| 36 | #define deco16_e0 m6502_e0 /* 2 CPX IMM */ | |
| 37 | ||
| 38 | #define deco16_10 m6502_10 /* 2 BPL */ | |
| 39 | #define deco16_30 m6502_30 /* 2 BMI */ | |
| 40 | #define deco16_50 m6502_50 /* 2 BVC */ | |
| 41 | #define deco16_70 m6502_70 /* 2 BVS */ | |
| 42 | #define deco16_90 m6502_90 /* 2 BCC */ | |
| 43 | #define deco16_b0 m6502_b0 /* 2 BCS */ | |
| 44 | #define deco16_d0 m6502_d0 /* 2 BNE */ | |
| 45 | #define deco16_f0 m6502_f0 /* 2 BEQ */ | |
| 46 | ||
| 47 | #define deco16_01 m6502_01 /* 6 ORA IDX */ | |
| 48 | #define deco16_21 m6502_21 /* 6 AND IDX */ | |
| 49 | #define deco16_41 m6502_41 /* 6 EOR IDX */ | |
| 50 | #define deco16_61 m6502_61 /* 6 ADC IDX */ | |
| 51 | #define deco16_81 m6502_81 /* 6 STA IDX */ | |
| 52 | #define deco16_a1 m6502_a1 /* 6 LDA IDX */ | |
| 53 | #define deco16_c1 m6502_c1 /* 6 CMP IDX */ | |
| 54 | #define deco16_e1 m6502_e1 /* 6 SBC IDX */ | |
| 55 | ||
| 56 | #define deco16_11 m6502_11 /* 5 ORA IDY; */ | |
| 57 | #define deco16_31 m6502_31 /* 5 AND IDY; */ | |
| 58 | #define deco16_51 m6502_51 /* 5 EOR IDY; */ | |
| 59 | #define deco16_71 m6502_71 /* 5 ADC IDY; */ | |
| 60 | #define deco16_91 m6502_91 /* 6 STA IDY; */ | |
| 61 | #define deco16_b1 m6502_b1 /* 5 LDA IDY; */ | |
| 62 | #define deco16_d1 m6502_d1 /* 5 CMP IDY; */ | |
| 63 | #define deco16_f1 m6502_f1 /* 5 SBC IDY; */ | |
| 64 | ||
| 65 | OP(02) { RD_DUM; ILL; } /* 2 ILL */ | |
| 66 | OP(22) { RD_DUM; ILL; } /* 2 ILL */ | |
| 67 | OP(42) { RD_DUM; ILL; } /* 2 ILL */ | |
| 68 | OP(62) { RD_DUM; ILL; } /* 2 ILL */ | |
| 69 | OP(82) { RD_DUM; ILL; } /* 2 ILL */ | |
| 70 | #define deco16_a2 m6502_a2 /* 2 LDX IMM */ | |
| 71 | OP(c2) { RD_DUM; ILL; } /* 2 ILL */ | |
| 72 | OP(e2) { RD_DUM; ILL; } /* 2 ILL */ | |
| 73 | ||
| 74 | OP(12) { RD_DUM; ILL; } /* 2 ILL / 3 ora zpi ?? */ | |
| 75 | OP(32) { RD_DUM; ILL; } /* 2 ILL / 3 and zpi ?? */ | |
| 76 | OP(52) { RD_DUM; ILL; } /* 2 ILL / 3 eor zpi ?? */ | |
| 77 | OP(72) { RD_DUM; ILL; } /* 2 ILL / 3 adc zpi ?? */ | |
| 78 | OP(92) { RD_DUM; ILL; } /* 2 ILL / 3 sta zpi ?? */ | |
| 79 | OP(b2) { RD_DUM; ILL; } /* 2 ILL / 3 lda zpi ?? */ | |
| 80 | OP(d2) { RD_DUM; ILL; } /* 2 ILL / 3 cmp zpi ?? */ | |
| 81 | OP(f2) { RD_DUM; ILL; } /* 2 ILL / 3 sbc zpi ?? */ | |
| 82 | ||
| 83 | OP(03) { RD_DUM; ILL; } /* 2 ILL */ | |
| 84 | OP(23) { | |
| 85 | int tmp; | |
| 86 | ||
| 87 | cpustate->icount -= 1; | |
| 88 | RD_IMM; | |
| 89 | ||
| 90 | if (DECO16_VERBOSE) | |
| 91 | logerror("%04x: OP23 %02x\n",PCW,tmp); | |
| 92 | } | |
| 93 | OP(43) { RD_DUM; ILL; } /* 2 ILL */ | |
| 94 | OP(63) { | |
| 95 | int tmp; | |
| 96 | ||
| 97 | cpustate->icount -= 1; | |
| 98 | RD_IMM; | |
| 99 | ||
| 100 | if (DECO16_VERBOSE) | |
| 101 | logerror("%04x: OP63 %02x\n",PCW,tmp); | |
| 102 | } | |
| 103 | OP(83) { RD_DUM; ILL; } /* 2 ILL */ | |
| 104 | OP(a3) { | |
| 105 | int tmp; | |
| 106 | ||
| 107 | cpustate->icount -= 1; | |
| 108 | RD_IMM; | |
| 109 | ||
| 110 | if (DECO16_VERBOSE) | |
| 111 | logerror("%04x: OPA3 %02x\n",PCW,tmp); | |
| 112 | } | |
| 113 | OP(c3) { RD_DUM; ILL; } /* 2 ILL */ | |
| 114 | OP(e3) { RD_DUM; ILL; } /* 2 ILL */ | |
| 115 | ||
| 116 | OP(13) { int tmp; cpustate->icount -= 1; RD_IMM; | |
| 117 | ||
| 118 | if (DECO16_VERBOSE) | |
| 119 | logerror("%04x: OP13 %02x\n",PCW,tmp); | |
| 120 | ||
| 121 | //bank select control? | |
| 122 | ||
| 123 | } /* */ | |
| 124 | OP(33) { RD_DUM; ILL; } /* 2 ILL */ | |
| 125 | OP(53) { RD_DUM; ILL; } /* 2 ILL */ | |
| 126 | OP(73) { RD_DUM; ILL; } /* 2 ILL */ | |
| 127 | OP(93) { RD_DUM; ILL; } /* 2 ILL */ | |
| 128 | OP(b3) { RD_DUM; ILL; } /* 2 ILL */ | |
| 129 | OP(d3) { RD_DUM; ILL; } /* 2 ILL */ | |
| 130 | OP(f3) { RD_DUM; ILL; } /* 2 ILL */ | |
| 131 | ||
| 132 | OP(04) { RD_DUM; ILL; } /* 2 ILL / 3 tsb zpg ?? */ | |
| 133 | #define deco16_24 m6502_24 /* 3 BIT ZPG */ | |
| 134 | OP(44) { RD_DUM; ILL; } /* 2 ILL */ | |
| 135 | OP(64) { RD_DUM; ILL; } /* 2 ILL / 3 stz zpg ?? */ | |
| 136 | #define deco16_84 m6502_84 /* 3 STY ZPG */ | |
| 137 | #define deco16_a4 m6502_a4 /* 3 LDY ZPG */ | |
| 138 | #define deco16_c4 m6502_c4 /* 3 CPY ZPG */ | |
| 139 | #define deco16_e4 m6502_e4 /* 3 CPX ZPG */ | |
| 140 | ||
| 141 | OP(14) { RD_DUM; ILL; } /* 2 ILL / 3 trb zpg ?? */ | |
| 142 | OP(34) { RD_DUM; ILL; } /* 2 ILL / 4 bit zpx ?? */ | |
| 143 | OP(54) { RD_DUM; ILL; } /* 2 ILL */ | |
| 144 | OP(74) { RD_DUM; ILL; } /* 2 ILL / 4 stz zpx ?? */ | |
| 145 | #define deco16_94 m6502_94 /* 4 sty zpx */ | |
| 146 | #define deco16_b4 m6502_b4 /* 4 ldy zpx */ | |
| 147 | OP(d4) { RD_DUM; ILL; } /* 2 ILL */ | |
| 148 | OP(f4) { RD_DUM; ILL; } /* 2 ILL */ | |
| 149 | ||
| 150 | #define deco16_05 m6502_05 /* 3 ORA ZPG */ | |
| 151 | #define deco16_25 m6502_25 /* 3 AND ZPG */ | |
| 152 | #define deco16_45 m6502_45 /* 3 EOR ZPG */ | |
| 153 | #define deco16_65 m6502_65 /* 3 ADC ZPG */ | |
| 154 | #define deco16_85 m6502_85 /* 3 STA ZPG */ | |
| 155 | #define deco16_a5 m6502_a5 /* 3 LDA ZPG */ | |
| 156 | #define deco16_c5 m6502_c5 /* 3 CMP ZPG */ | |
| 157 | #define deco16_e5 m6502_e5 /* 3 SBC ZPG */ | |
| 158 | ||
| 159 | #define deco16_15 m6502_15 /* 4 ORA ZPX */ | |
| 160 | #define deco16_35 m6502_35 /* 4 AND ZPX */ | |
| 161 | #define deco16_55 m6502_55 /* 4 EOR ZPX */ | |
| 162 | #define deco16_75 m6502_75 /* 4 ADC ZPX */ | |
| 163 | #define deco16_95 m6502_95 /* 4 STA ZPX */ | |
| 164 | #define deco16_b5 m6502_b5 /* 4 LDA ZPX */ | |
| 165 | #define deco16_d5 m6502_d5 /* 4 CMP ZPX */ | |
| 166 | #define deco16_f5 m6502_f5 /* 4 SBC ZPX */ | |
| 167 | ||
| 168 | #define deco16_06 m6502_06 /* 5 ASL ZPG */ | |
| 169 | #define deco16_26 m6502_26 /* 5 ROL ZPG */ | |
| 170 | #define deco16_46 m6502_46 /* 5 LSR ZPG */ | |
| 171 | #define deco16_66 m6502_66 /* 5 ROR ZPG */ | |
| 172 | #define deco16_86 m6502_86 /* 3 STX ZPG */ | |
| 173 | #define deco16_a6 m6502_a6 /* 3 LDX ZPG */ | |
| 174 | #define deco16_c6 m6502_c6 /* 5 DEC ZPG */ | |
| 175 | #define deco16_e6 m6502_e6 /* 5 INC ZPG */ | |
| 176 | ||
| 177 | #define deco16_16 m6502_16 /* 6 ASL ZPX */ | |
| 178 | #define deco16_36 m6502_36 /* 6 ROL ZPX */ | |
| 179 | #define deco16_56 m6502_56 /* 6 LSR ZPX */ | |
| 180 | #define deco16_76 m6502_76 /* 6 ROR ZPX */ | |
| 181 | #define deco16_96 m6502_96 /* 4 STX ZPY */ | |
| 182 | #define deco16_b6 m6502_b6 /* 4 LDX ZPY */ | |
| 183 | #define deco16_d6 m6502_d6 /* 6 DEC ZPX */ | |
| 184 | #define deco16_f6 m6502_f6 /* 6 INC ZPX */ | |
| 185 | ||
| 186 | OP(07) { RD_DUM; ILL; } /* 2 ILL / 5 RMB0 ZPG ?? */ | |
| 187 | OP(27) { RD_DUM; ILL; } /* 2 ILL / 5 RMB2 ZPG ?? */ | |
| 188 | OP(47) { RD_DUM; ILL; } /* 2 ILL / 5 RMB4 ZPG ?? */ | |
| 189 | OP(67) { | |
| 190 | RD_IMM_DISCARD; | |
| 191 | cpustate->a=cpustate->io->read_byte(0); | |
| 192 | ||
| 193 | // logerror("%04x: VBL (0x67)\n",PCW); | |
| 194 | ||
| 195 | // really - wait for status? | |
| 196 | ||
| 197 | } /* */ | |
| 198 | OP(87) { int tmp; cpustate->icount -= 1; RD_IMM; | |
| 199 | logerror("%04x: OP87 %02x\n",PCW,tmp); | |
| 200 | ||
| 201 | } /* */ | |
| 202 | OP(a7) { RD_DUM; ILL; } /* 2 ILL / 5 SMB2 ZPG ?? */ | |
| 203 | OP(c7) { RD_DUM; ILL; } /* 2 ILL / 5 SMB4 ZPG ?? */ | |
| 204 | OP(e7) { RD_DUM; ILL; } /* 2 ILL / 5 SMB6 ZPG ?? */ | |
| 205 | ||
| 206 | OP(17) { RD_DUM; ILL; } /* 2 ILL / 5 RMB1 ZPG ?? */ | |
| 207 | OP(37) { RD_DUM; ILL; } /* 2 ILL / 5 RMB3 ZPG ?? */ | |
| 208 | OP(57) { RD_DUM; ILL; } /* 2 ILL / 5 RMB5 ZPG ?? */ | |
| 209 | OP(77) { RD_DUM; ILL; } /* 2 ILL / 5 RMB7 ZPG ?? */ | |
| 210 | OP(97) { RD_DUM; ILL; } /* 2 ILL / 5 SMB1 ZPG ?? */ | |
| 211 | OP(b7) { RD_DUM; ILL; } /* 2 ILL / 5 SMB3 ZPG ?? */ | |
| 212 | OP(d7) { RD_DUM; ILL; } /* 2 ILL / 5 SMB5 ZPG ?? */ | |
| 213 | OP(f7) { RD_DUM; ILL; } /* 2 ILL / 5 SMB7 ZPG ?? */ | |
| 214 | ||
| 215 | #define deco16_08 m6502_08 /* 3 PHP */ | |
| 216 | #define deco16_28 m6502_28 /* 4 PLP */ | |
| 217 | #define deco16_48 m6502_48 /* 3 PHA */ | |
| 218 | #define deco16_68 m6502_68 /* 4 PLA */ | |
| 219 | #define deco16_88 m6502_88 /* 2 DEY */ | |
| 220 | #define deco16_a8 m6502_a8 /* 2 TAY */ | |
| 221 | #define deco16_c8 m6502_c8 /* 2 INY */ | |
| 222 | #define deco16_e8 m6502_e8 /* 2 INX */ | |
| 223 | ||
| 224 | #define deco16_18 m6502_18 /* 2 CLC */ | |
| 225 | #define deco16_38 m6502_38 /* 2 SEC */ | |
| 226 | #define deco16_58 m6502_58 /* 2 CLI */ | |
| 227 | #define deco16_78 m6502_78 /* 2 SEI */ | |
| 228 | #define deco16_98 m6502_98 /* 2 TYA */ | |
| 229 | #define deco16_b8 m6502_b8 /* 2 CLV */ | |
| 230 | #define deco16_d8 m6502_d8 /* 2 CLD */ | |
| 231 | #define deco16_f8 m6502_f8 /* 2 SED */ | |
| 232 | ||
| 233 | #define deco16_09 m6502_09 /* 2 ORA IMM */ | |
| 234 | #define deco16_29 m6502_29 /* 2 AND IMM */ | |
| 235 | #define deco16_49 m6502_49 /* 2 EOR IMM */ | |
| 236 | #define deco16_69 m6502_69 /* 2 ADC IMM */ | |
| 237 | #define deco16_89 m65c02_89 /* 2 BIT IMM */ | |
| 238 | #define deco16_a9 m6502_a9 /* 2 LDA IMM */ | |
| 239 | #define deco16_c9 m6502_c9 /* 2 CMP IMM */ | |
| 240 | #define deco16_e9 m6502_e9 /* 2 SBC IMM */ | |
| 241 | ||
| 242 | #define deco16_19 m6502_19 /* 4 ORA ABY */ | |
| 243 | #define deco16_39 m6502_39 /* 4 AND ABY */ | |
| 244 | #define deco16_59 m6502_59 /* 4 EOR ABY */ | |
| 245 | #define deco16_79 m6502_79 /* 4 ADC ABY */ | |
| 246 | #define deco16_99 m6502_99 /* 5 STA ABY */ | |
| 247 | #define deco16_b9 m6502_b9 /* 4 LDA ABY */ | |
| 248 | #define deco16_d9 m6502_d9 /* 4 CMP ABY */ | |
| 249 | #define deco16_f9 m6502_f9 /* 4 SBC ABY */ | |
| 250 | ||
| 251 | #define deco16_0a m6502_0a /* 2 ASL */ | |
| 252 | #define deco16_2a m6502_2a /* 2 ROL */ | |
| 253 | #define deco16_4a m6502_4a /* 2 LSR */ | |
| 254 | #define deco16_6a m6502_6a /* 2 ROR */ | |
| 255 | #define deco16_8a m6502_8a /* 2 TXA */ | |
| 256 | #define deco16_aa m6502_aa /* 2 TAX */ | |
| 257 | #define deco16_ca m6502_ca /* 2 DEX */ | |
| 258 | #define deco16_ea m6502_ea /* 2 NOP */ | |
| 259 | ||
| 260 | #define deco16_1a m65c02_1a /* 2 INA */ | |
| 261 | #define deco16_3a m65c02_3a /* 2 DEA */ | |
| 262 | #define deco16_5a m65c02_5a /* 3 PHY */ | |
| 263 | #define deco16_7a m65c02_7a /* 4 PLY */ | |
| 264 | #define deco16_9a m6502_9a /* 2 TXS */ | |
| 265 | #define deco16_ba m6502_ba /* 2 TSX */ | |
| 266 | #define deco16_da m65c02_da /* 3 PHX */ | |
| 267 | #define deco16_fa m65c02_fa /* 4 PLX */ | |
| 268 | ||
| 269 | OP(0b) { int tmp; cpustate->icount -= 1; RD_IMM; | |
| 270 | logerror("%04x: OP0B %02x\n",PCW,tmp); | |
| 271 | ||
| 272 | } | |
| 273 | OP(2b) { RD_DUM; ILL; } /* 2 ILL */ | |
| 274 | OP(4b) { cpustate->icount -= 1; RD_IMM_DISCARD; | |
| 275 | //logerror("%04x: OP4B %02x\n",PCW,tmp); | |
| 276 | /* TODO: Maybe it's just read I/O 0 and do a logic AND with bit 1? */ | |
| 277 | cpustate->a=cpustate->io->read_byte(1); | |
| 278 | ||
| 279 | //tilt?? | |
| 280 | ||
| 281 | //VBL on expr-raider | |
| 282 | //VBL on boomrang (bit 2) | |
| 283 | ||
| 284 | } | |
| 285 | OP(6b) { RD_DUM; ILL; } /* 2 ILL */ | |
| 286 | OP(8b) { RD_DUM; ILL; } /* 2 ILL */ | |
| 287 | OP(ab) { RD_DUM; ILL; } /* 2 ILL */ | |
| 288 | OP(cb) { RD_DUM; ILL; } /* 2 ILL */ | |
| 289 | OP(eb) { RD_DUM; ILL; } /* 2 ILL */ | |
| 290 | ||
| 291 | OP(1b) { RD_DUM; ILL; } /* 2 ILL */ | |
| 292 | OP(3b) { RD_DUM; ILL; } /* 2 ILL */ | |
| 293 | OP(5b) { RD_DUM; ILL; } /* 2 ILL */ | |
| 294 | OP(7b) { RD_DUM; ILL; } /* 2 ILL */ | |
| 295 | OP(9b) { RD_DUM; ILL; } /* 2 ILL */ | |
| 296 | OP(bb) { | |
| 297 | int tmp; | |
| 298 | ||
| 299 | cpustate->icount -= 1; | |
| 300 | RD_IMM; | |
| 301 | ||
| 302 | if (DECO16_VERBOSE) | |
| 303 | logerror("%04x: OPBB %02x\n",PCW,tmp); | |
| 304 | } | |
| 305 | OP(db) { RD_DUM; ILL; } /* 2 ILL */ | |
| 306 | OP(fb) { RD_DUM; ILL; } /* 2 ILL */ | |
| 307 | ||
| 308 | #define deco16_0c m65c02_0c /* 4 TSB ABS */ | |
| 309 | #define deco16_2c m6502_2c /* 4 BIT ABS */ | |
| 310 | #define deco16_4c m6502_4c /* 3 JMP ABS */ | |
| 311 | #define deco16_6c m65c02_6c /* 5 JMP IND */ | |
| 312 | #define deco16_8c m6502_8c /* 4 STY ABS */ | |
| 313 | #define deco16_ac m6502_ac /* 4 LDY ABS */ | |
| 314 | #define deco16_cc m6502_cc /* 4 CPY ABS */ | |
| 315 | #define deco16_ec m6502_ec /* 4 CPX ABS */ | |
| 316 | ||
| 317 | #define deco16_1c m65c02_1c /* 4 TRB ABS */ | |
| 318 | #define deco16_3c m65c02_3c /* 4 BIT ABX */ | |
| 319 | OP(5c) { RD_DUM; ILL; } /* 2 ILL */ | |
| 320 | #define deco16_7c m65c02_7c /* 6 JMP IAX */ | |
| 321 | #define deco16_9c m65c02_9c /* 4 STZ ABS */ | |
| 322 | #define deco16_bc m65c02_bc /* 4 LDY ABX */ | |
| 323 | OP(dc) { RD_DUM; ILL; } /* 2 ILL */ | |
| 324 | OP(fc) { RD_DUM; ILL; } /* 2 ILL */ | |
| 325 | ||
| 326 | #define deco16_0d m6502_0d /* 4 ORA ABS */ | |
| 327 | #define deco16_2d m6502_2d /* 4 AND ABS */ | |
| 328 | #define deco16_4d m6502_4d /* 4 EOR ABS */ | |
| 329 | #define deco16_6d m6502_6d /* 4 ADC ABS */ | |
| 330 | #define deco16_8d m6502_8d /* 4 STA ABS */ | |
| 331 | #define deco16_ad m6502_ad /* 4 LDA ABS */ | |
| 332 | #define deco16_cd m6502_cd /* 4 CMP ABS */ | |
| 333 | #define deco16_ed m6502_ed /* 4 SBC ABS */ | |
| 334 | ||
| 335 | #define deco16_1d m6502_1d /* 4 ORA ABX */ | |
| 336 | #define deco16_3d m6502_3d /* 4 AND ABX */ | |
| 337 | #define deco16_5d m6502_5d /* 4 EOR ABX */ | |
| 338 | #define deco16_7d m6502_7d /* 4 ADC ABX */ | |
| 339 | #define deco16_9d m6502_9d /* 5 STA ABX */ | |
| 340 | #define deco16_bd m6502_bd /* 4 LDA ABX */ | |
| 341 | #define deco16_dd m6502_dd /* 4 CMP ABX */ | |
| 342 | #define deco16_fd m6502_fd /* 4 SBC ABX */ | |
| 343 | ||
| 344 | #define deco16_0e m6502_0e /* 6 ASL ABS */ | |
| 345 | #define deco16_2e m6502_2e /* 6 ROL ABS */ | |
| 346 | #define deco16_4e m6502_4e /* 6 LSR ABS */ | |
| 347 | #define deco16_6e m6502_6e /* 6 ROR ABS */ | |
| 348 | #define deco16_8e m6502_8e /* 4 STX ABS */ | |
| 349 | #define deco16_ae m6502_ae /* 4 LDX ABS */ | |
| 350 | #define deco16_ce m6502_ce /* 6 DEC ABS */ | |
| 351 | #define deco16_ee m6502_ee /* 6 INC ABS */ | |
| 352 | ||
| 353 | #define deco16_1e m6502_1e /* 7 ASL ABX */ | |
| 354 | #define deco16_3e m6502_3e /* 7 ROL ABX */ | |
| 355 | #define deco16_5e m6502_5e /* 7 LSR ABX */ | |
| 356 | #define deco16_7e m6502_7e /* 7 ROR ABX */ | |
| 357 | #define deco16_9e m65c02_9e /* 5 STZ ABX */ | |
| 358 | #define deco16_be m6502_be /* 4 LDX ABY */ | |
| 359 | #define deco16_de m6502_de /* 7 DEC ABX */ | |
| 360 | #define deco16_fe m6502_fe /* 7 INC ABX */ | |
| 361 | ||
| 362 | OP(0f) { RD_DUM; ILL; } /* 2 ILL / 5 BBR0 ZPG ?? */ | |
| 363 | OP(2f) { RD_DUM; ILL; } /* 2 ILL / 5 BBR2 ZPG ?? */ | |
| 364 | OP(4f) { RD_DUM; ILL; } /* 2 ILL / 5 BBR4 ZPG ?? */ | |
| 365 | OP(6f) { RD_DUM; ILL; } /* 2 ILL / 5 BBR6 ZPG ?? */ | |
| 366 | OP(8f) { int tmp; cpustate->icount -= 1; RD_IMM; | |
| 367 | if (DECO16_VERBOSE) | |
| 368 | logerror("%04x: BANK (8F) %02x\n",PCW,tmp); | |
| 369 | ||
| 370 | cpustate->io->write_byte(0,tmp); | |
| 371 | ||
| 372 | //swap bank in/out | |
| 373 | } /* */ | |
| 374 | OP(af) { RD_DUM; ILL; } /* 2 ILL / 5 BBS2 ZPG ?? */ | |
| 375 | OP(cf) { RD_DUM; ILL; } /* 2 ILL / 5 BBS4 ZPG ?? */ | |
| 376 | OP(ef) { RD_DUM; ILL; } /* 2 ILL / 5 BBS6 ZPG ?? */ | |
| 377 | ||
| 378 | OP(1f) { RD_DUM; ILL; } /* 2 ILL / 5 BBR1 ZPG ?? */ | |
| 379 | OP(3f) { | |
| 380 | int tmp; | |
| 381 | ||
| 382 | cpustate->icount -= 1; | |
| 383 | RD_IMM; | |
| 384 | ||
| 385 | if (DECO16_VERBOSE) | |
| 386 | logerror("%04x: OP3F %02x\n",PCW,tmp); | |
| 387 | } | |
| 388 | OP(5f) { RD_DUM; ILL; } /* 2 ILL / 5 BBR5 ZPG ?? */ | |
| 389 | OP(7f) { RD_DUM; ILL; } /* 2 ILL / 5 BBR7 ZPG ?? */ | |
| 390 | OP(9f) { RD_DUM; ILL; } /* 2 ILL / 5 BBS1 ZPG ?? */ | |
| 391 | OP(bf) { RD_DUM; ILL; } /* 2 ILL / 5 BBS3 ZPG ?? */ | |
| 392 | OP(df) { RD_DUM; ILL; } /* 2 ILL / 5 BBS5 ZPG ?? */ | |
| 393 | OP(ff) { RD_DUM; ILL; } /* 2 ILL / 5 BBS7 ZPG ?? */ | |
| 394 | ||
| 395 | static void (*const insndeco16[0x100])(m6502_Regs *cpustate) = { | |
| 396 | deco16_00,deco16_01,deco16_02,deco16_03,deco16_04,deco16_05,deco16_06,deco16_07, | |
| 397 | deco16_08,deco16_09,deco16_0a,deco16_0b,deco16_0c,deco16_0d,deco16_0e,deco16_0f, | |
| 398 | deco16_10,deco16_11,deco16_12,deco16_13,deco16_14,deco16_15,deco16_16,deco16_17, | |
| 399 | deco16_18,deco16_19,deco16_1a,deco16_1b,deco16_1c,deco16_1d,deco16_1e,deco16_1f, | |
| 400 | deco16_20,deco16_21,deco16_22,deco16_23,deco16_24,deco16_25,deco16_26,deco16_27, | |
| 401 | deco16_28,deco16_29,deco16_2a,deco16_2b,deco16_2c,deco16_2d,deco16_2e,deco16_2f, | |
| 402 | deco16_30,deco16_31,deco16_32,deco16_33,deco16_34,deco16_35,deco16_36,deco16_37, | |
| 403 | deco16_38,deco16_39,deco16_3a,deco16_3b,deco16_3c,deco16_3d,deco16_3e,deco16_3f, | |
| 404 | deco16_40,deco16_41,deco16_42,deco16_43,deco16_44,deco16_45,deco16_46,deco16_47, | |
| 405 | deco16_48,deco16_49,deco16_4a,deco16_4b,deco16_4c,deco16_4d,deco16_4e,deco16_4f, | |
| 406 | deco16_50,deco16_51,deco16_52,deco16_53,deco16_54,deco16_55,deco16_56,deco16_57, | |
| 407 | deco16_58,deco16_59,deco16_5a,deco16_5b,deco16_5c,deco16_5d,deco16_5e,deco16_5f, | |
| 408 | deco16_60,deco16_61,deco16_62,deco16_63,deco16_64,deco16_65,deco16_66,deco16_67, | |
| 409 | deco16_68,deco16_69,deco16_6a,deco16_6b,deco16_6c,deco16_6d,deco16_6e,deco16_6f, | |
| 410 | deco16_70,deco16_71,deco16_72,deco16_73,deco16_74,deco16_75,deco16_76,deco16_77, | |
| 411 | deco16_78,deco16_79,deco16_7a,deco16_7b,deco16_7c,deco16_7d,deco16_7e,deco16_7f, | |
| 412 | deco16_80,deco16_81,deco16_82,deco16_83,deco16_84,deco16_85,deco16_86,deco16_87, | |
| 413 | deco16_88,deco16_89,deco16_8a,deco16_8b,deco16_8c,deco16_8d,deco16_8e,deco16_8f, | |
| 414 | deco16_90,deco16_91,deco16_92,deco16_93,deco16_94,deco16_95,deco16_96,deco16_97, | |
| 415 | deco16_98,deco16_99,deco16_9a,deco16_9b,deco16_9c,deco16_9d,deco16_9e,deco16_9f, | |
| 416 | deco16_a0,deco16_a1,deco16_a2,deco16_a3,deco16_a4,deco16_a5,deco16_a6,deco16_a7, | |
| 417 | deco16_a8,deco16_a9,deco16_aa,deco16_ab,deco16_ac,deco16_ad,deco16_ae,deco16_af, | |
| 418 | deco16_b0,deco16_b1,deco16_b2,deco16_b3,deco16_b4,deco16_b5,deco16_b6,deco16_b7, | |
| 419 | deco16_b8,deco16_b9,deco16_ba,deco16_bb,deco16_bc,deco16_bd,deco16_be,deco16_bf, | |
| 420 | deco16_c0,deco16_c1,deco16_c2,deco16_c3,deco16_c4,deco16_c5,deco16_c6,deco16_c7, | |
| 421 | deco16_c8,deco16_c9,deco16_ca,deco16_cb,deco16_cc,deco16_cd,deco16_ce,deco16_cf, | |
| 422 | deco16_d0,deco16_d1,deco16_d2,deco16_d3,deco16_d4,deco16_d5,deco16_d6,deco16_d7, | |
| 423 | deco16_d8,deco16_d9,deco16_da,deco16_db,deco16_dc,deco16_dd,deco16_de,deco16_df, | |
| 424 | deco16_e0,deco16_e1,deco16_e2,deco16_e3,deco16_e4,deco16_e5,deco16_e6,deco16_e7, | |
| 425 | deco16_e8,deco16_e9,deco16_ea,deco16_eb,deco16_ec,deco16_ed,deco16_ee,deco16_ef, | |
| 426 | deco16_f0,deco16_f1,deco16_f2,deco16_f3,deco16_f4,deco16_f5,deco16_f6,deco16_f7, | |
| 427 | deco16_f8,deco16_f9,deco16_fa,deco16_fb,deco16_fc,deco16_fd,deco16_fe,deco16_ff | |
| 428 | }; |
| r18874 | r18875 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * tbl65sc02.c | |
| 4 | * 65sc02 opcode functions and function pointer table | |
| 5 | * | |
| 6 | * Copyright Peter Trauner, all rights reserved. | |
| 7 | * | |
| 8 | * - This source code is released as freeware for non-commercial purposes. | |
| 9 | * - You are free to use and redistribute this code in modified or | |
| 10 | * unmodified form, provided you list me in the credits. | |
| 11 | * - If you modify this source code, you must add a notice to each modified | |
| 12 | * source file that it has been changed. If you're a nice person, you | |
| 13 | * will clearly mark each change too. :) | |
| 14 | * - If you wish to use this for commercial purposes, please contact me at | |
| 15 | * pullmoll@t-online.de | |
| 16 | * - The author of this copywritten work reserves the right to change the | |
| 17 | * terms of its usage and license at any time, including retroactively | |
| 18 | * - This entire notice must remain in the source code. | |
| 19 | * | |
| 20 | *****************************************************************************/ | |
| 21 | /* 4. February 2000 PeT fixed relative word operand */ | |
| 22 | ||
| 23 | /* opcode already in 65c02 | |
| 24 | although docu says they were introduced with this cpu | |
| 25 | ||
| 26 | bbr | |
| 27 | bbs | |
| 28 | rmb | |
| 29 | smb | |
| 30 | trb | |
| 31 | tsb | |
| 32 | */ | |
| 33 | ||
| 34 | #undef OP | |
| 35 | #define OP(nn) INLINE void m65sc02_##nn(m6502_Regs *cpustate) | |
| 36 | ||
| 37 | /***************************************************************************** | |
| 38 | ***************************************************************************** | |
| 39 | * | |
| 40 | * overrides for 65SC02 opcodes | |
| 41 | * | |
| 42 | ***************************************************************************** | |
| 43 | * op temp cycles rdmem opc wrmem ********************/ | |
| 44 | OP(63) { BSR; } /* 5? BSR */ | |
| 45 | ||
| 46 | static void (*const insn65sc02[0x100])(m6502_Regs *cpustate) = { | |
| 47 | m65c02_00,m65c02_01,m65c02_02,m65c02_03,m65c02_04,m65c02_05,m65c02_06,m65c02_07, | |
| 48 | m65c02_08,m65c02_09,m65c02_0a,m65c02_0b,m65c02_0c,m65c02_0d,m65c02_0e,m65c02_0f, | |
| 49 | m65c02_10,m65c02_11,m65c02_12,m65c02_13,m65c02_14,m65c02_15,m65c02_16,m65c02_17, | |
| 50 | m65c02_18,m65c02_19,m65c02_1a,m65c02_1b,m65c02_1c,m65c02_1d,m65c02_1e,m65c02_1f, | |
| 51 | m65c02_20,m65c02_21,m65c02_22,m65c02_23,m65c02_24,m65c02_25,m65c02_26,m65c02_27, | |
| 52 | m65c02_28,m65c02_29,m65c02_2a,m65c02_2b,m65c02_2c,m65c02_2d,m65c02_2e,m65c02_2f, | |
| 53 | m65c02_30,m65c02_31,m65c02_32,m65c02_33,m65c02_34,m65c02_35,m65c02_36,m65c02_37, | |
| 54 | m65c02_38,m65c02_39,m65c02_3a,m65c02_3b,m65c02_3c,m65c02_3d,m65c02_3e,m65c02_3f, | |
| 55 | m65c02_40,m65c02_41,m65c02_42,m65c02_43,m65c02_44,m65c02_45,m65c02_46,m65c02_47, | |
| 56 | m65c02_48,m65c02_49,m65c02_4a,m65c02_4b,m65c02_4c,m65c02_4d,m65c02_4e,m65c02_4f, | |
| 57 | m65c02_50,m65c02_51,m65c02_52,m65c02_53,m65c02_54,m65c02_55,m65c02_56,m65c02_57, | |
| 58 | m65c02_58,m65c02_59,m65c02_5a,m65c02_5b,m65c02_5c,m65c02_5d,m65c02_5e,m65c02_5f, | |
| 59 | m65c02_60,m65c02_61,m65c02_62,m65c02_63,m65c02_64,m65c02_65,m65c02_66,m65c02_67, | |
| 60 | m65c02_68,m65c02_69,m65c02_6a,m65c02_6b,m65c02_6c,m65c02_6d,m65c02_6e,m65c02_6f, | |
| 61 | m65c02_70,m65c02_71,m65c02_72,m65c02_73,m65c02_74,m65c02_75,m65c02_76,m65c02_77, | |
| 62 | m65c02_78,m65c02_79,m65c02_7a,m65c02_7b,m65c02_7c,m65c02_7d,m65c02_7e,m65c02_7f, | |
| 63 | m65c02_80,m65c02_81,m65c02_82,m65c02_83,m65c02_84,m65c02_85,m65c02_86,m65c02_87, | |
| 64 | m65c02_88,m65c02_89,m65c02_8a,m65c02_8b,m65c02_8c,m65c02_8d,m65c02_8e,m65c02_8f, | |
| 65 | m65c02_90,m65c02_91,m65c02_92,m65c02_93,m65c02_94,m65c02_95,m65c02_96,m65c02_97, | |
| 66 | m65c02_98,m65c02_99,m65c02_9a,m65c02_9b,m65c02_9c,m65c02_9d,m65c02_9e,m65c02_9f, | |
| 67 | m65c02_a0,m65c02_a1,m65c02_a2,m65c02_a3,m65c02_a4,m65c02_a5,m65c02_a6,m65c02_a7, | |
| 68 | m65c02_a8,m65c02_a9,m65c02_aa,m65c02_ab,m65c02_ac,m65c02_ad,m65c02_ae,m65c02_af, | |
| 69 | m65c02_b0,m65c02_b1,m65c02_b2,m65c02_b3,m65c02_b4,m65c02_b5,m65c02_b6,m65c02_b7, | |
| 70 | m65c02_b8,m65c02_b9,m65c02_ba,m65c02_bb,m65c02_bc,m65c02_bd,m65c02_be,m65c02_bf, | |
| 71 | m65c02_c0,m65c02_c1,m65c02_c2,m65c02_c3,m65c02_c4,m65c02_c5,m65c02_c6,m65c02_c7, | |
| 72 | m65c02_c8,m65c02_c9,m65c02_ca,m65c02_cb,m65c02_cc,m65c02_cd,m65c02_ce,m65c02_cf, | |
| 73 | m65c02_d0,m65c02_d1,m65c02_d2,m65c02_d3,m65c02_d4,m65c02_d5,m65c02_d6,m65c02_d7, | |
| 74 | m65c02_d8,m65c02_d9,m65c02_da,m65c02_db,m65c02_dc,m65c02_dd,m65c02_de,m65c02_df, | |
| 75 | m65c02_e0,m65c02_e1,m65c02_e2,m65c02_e3,m65c02_e4,m65c02_e5,m65c02_e6,m65c02_e7, | |
| 76 | m65c02_e8,m65c02_e9,m65c02_ea,m65c02_eb,m65c02_ec,m65c02_ed,m65c02_ee,m65c02_ef, | |
| 77 | m65c02_f0,m65c02_f1,m65c02_f2,m65c02_f3,m65c02_f4,m65c02_f5,m65c02_f6,m65c02_f7, | |
| 78 | m65c02_f8,m65c02_f9,m65c02_fa,m65c02_fb,m65c02_fc,m65c02_fd,m65c02_fe,m65c02_ff | |
| 79 | }; | |
| 80 |
| r18874 | r18875 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * tbl2a03.c | |
| 4 | * 2a03 opcode functions and function pointer table | |
| 5 | * | |
| 6 | * The 2a03 is a 6502 CPU that does not support the decimal mode | |
| 7 | * of the ADC and SBC instructions, so all opcodes except ADC/SBC | |
| 8 | * are simply mapped to the m6502 ones. | |
| 9 | * | |
| 10 | * Copyright Juergen Buchmueller, all rights reserved. | |
| 11 | * | |
| 12 | * - This source code is released as freeware for non-commercial purposes. | |
| 13 | * - You are free to use and redistribute this code in modified or | |
| 14 | * unmodified form, provided you list me in the credits. | |
| 15 | * - If you modify this source code, you must add a notice to each modified | |
| 16 | * source file that it has been changed. If you're a nice person, you | |
| 17 | * will clearly mark each change too. :) | |
| 18 | * - If you wish to use this for commercial purposes, please contact me at | |
| 19 | * pullmoll@t-online.de | |
| 20 | * - The author of this copywritten work reserves the right to change the | |
| 21 | * terms of its usage and license at any time, including retroactively | |
| 22 | * - This entire notice must remain in the source code. | |
| 23 | * | |
| 24 | *****************************************************************************/ | |
| 25 | ||
| 26 | /* | |
| 27 | based on the nmos 6502 | |
| 28 | ||
| 29 | b flag handling might be changed, | |
| 30 | although only nmos series b-flag handling is quite sure | |
| 31 | */ | |
| 32 | ||
| 33 | ||
| 34 | #undef OP | |
| 35 | #define OP(nn) INLINE void n2a03_##nn(m6502_Regs *cpustate) | |
| 36 | ||
| 37 | /***************************************************************************** | |
| 38 | ***************************************************************************** | |
| 39 | * | |
| 40 | * overrides for 2a03 opcodes | |
| 41 | * | |
| 42 | ***************************************************************************** | |
| 43 | ********** insn temp cycles rdmem opc wrmem **********/ | |
| 44 | OP(61) { int tmp; RD_IDX; ADC_NES; } /* 6 ADC IDX */ | |
| 45 | OP(e1) { int tmp; RD_IDX; SBC_NES; } /* 6 SBC IDX */ | |
| 46 | OP(71) { int tmp; RD_IDY_P; ADC_NES; } /* 5 ADC IDY page penalty */ | |
| 47 | OP(f1) { int tmp; RD_IDY_P; SBC_NES; } /* 5 SBC IDY page penalty */ | |
| 48 | OP(63) { int tmp; RD_IDX; WB_EA; RRA_NES; WB_EA; } /* 7 RRA IDX */ | |
| 49 | OP(73) { int tmp; RD_IDY_NP; WB_EA; RRA_NES; WB_EA; } /* 7 RRA IDY */ | |
| 50 | OP(e3) { int tmp; RD_IDX; WB_EA; ISB_NES; WB_EA; } /* 7 ISB IDX */ | |
| 51 | OP(f3) { int tmp; RD_IDY_NP; WB_EA; ISB_NES; WB_EA; } /* 7 ISB IDY */ | |
| 52 | OP(65) { int tmp; RD_ZPG; ADC_NES; } /* 3 ADC ZPG */ | |
| 53 | OP(e5) { int tmp; RD_ZPG; SBC_NES; } /* 3 SBC ZPG */ | |
| 54 | OP(75) { int tmp; RD_ZPX; ADC_NES; } /* 4 ADC ZPX */ | |
| 55 | OP(f5) { int tmp; RD_ZPX; SBC_NES; } /* 4 SBC ZPX */ | |
| 56 | OP(67) { int tmp; RD_ZPG; WB_EA; RRA_NES; WB_EA; } /* 5 RRA ZPG */ | |
| 57 | OP(77) { int tmp; RD_ZPX; WB_EA; RRA_NES; WB_EA; } /* 6 RRA ZPX */ | |
| 58 | OP(e7) { int tmp; RD_ZPG; WB_EA; ISB_NES; WB_EA; } /* 5 ISB ZPG */ | |
| 59 | OP(f7) { int tmp; RD_ZPX; WB_EA; ISB_NES; WB_EA; } /* 6 ISB ZPX */ | |
| 60 | OP(69) { int tmp; RD_IMM; ADC_NES; } /* 2 ADC IMM */ | |
| 61 | OP(e9) { int tmp; RD_IMM; SBC_NES; } /* 2 SBC IMM */ | |
| 62 | OP(79) { int tmp; RD_ABY_P; ADC_NES; } /* 4 ADC ABY page penalty */ | |
| 63 | OP(f9) { int tmp; RD_ABY_P; SBC_NES; } /* 4 SBC ABY page penalty */ | |
| 64 | OP(6b) { int tmp; RD_IMM; ARR_NES; WB_ACC; } /* 2 ARR IMM */ | |
| 65 | OP(7b) { int tmp; RD_ABY_NP; WB_EA; RRA_NES; WB_EA; } /* 7 RRA ABY */ | |
| 66 | OP(ab) { int tmp; RD_IMM; OAL_NES; } /* 2 OAL IMM */ | |
| 67 | OP(eb) { int tmp; RD_IMM; SBC_NES; } /* 2 SBC IMM */ | |
| 68 | OP(fb) { int tmp; RD_ABY_NP; WB_EA; ISB_NES; WB_EA; } /* 7 ISB ABY */ | |
| 69 | OP(9c) { int tmp; EA_ABX_NP; SYH_NES; WB_EA; } /* 5 SYH ABX */ | |
| 70 | OP(6d) { int tmp; RD_ABS; ADC_NES; } /* 4 ADC ABS */ | |
| 71 | OP(ed) { int tmp; RD_ABS; SBC_NES; } /* 4 SBC ABS */ | |
| 72 | OP(7d) { int tmp; RD_ABX_P; ADC_NES; } /* 4 ADC ABX page penalty */ | |
| 73 | OP(fd) { int tmp; RD_ABX_P; SBC_NES; } /* 4 SBC ABX page penalty */ | |
| 74 | OP(9e) { int tmp; EA_ABY_NP; SXH_NES; WB_EA; } /* 5 SXH ABY */ | |
| 75 | OP(6f) { int tmp; RD_ABS; WB_EA; RRA_NES; WB_EA; } /* 6 RRA ABS */ | |
| 76 | OP(7f) { int tmp; RD_ABX_NP; WB_EA; RRA_NES; WB_EA; } /* 7 RRA ABX */ | |
| 77 | OP(ef) { int tmp; RD_ABS; WB_EA; ISB_NES; WB_EA; } /* 6 ISB ABS */ | |
| 78 | OP(ff) { int tmp; RD_ABX_NP; WB_EA; ISB_NES; WB_EA; } /* 7 ISB ABX */ | |
| 79 | ||
| 80 | ||
| 81 | static void (*const insn2a03[0x100])(m6502_Regs *cpustate) = { | |
| 82 | m6502_00,m6502_01,m6502_02,m6502_03,m6502_04,m6502_05,m6502_06,m6502_07, | |
| 83 | m6502_08,m6502_09,m6502_0a,m6502_0b,m6502_0c,m6502_0d,m6502_0e,m6502_0f, | |
| 84 | m6502_10,m6502_11,m6502_12,m6502_13,m6502_14,m6502_15,m6502_16,m6502_17, | |
| 85 | m6502_18,m6502_19,m6502_1a,m6502_1b,m6502_1c,m6502_1d,m6502_1e,m6502_1f, | |
| 86 | m6502_20,m6502_21,m6502_22,m6502_23,m6502_24,m6502_25,m6502_26,m6502_27, | |
| 87 | m6502_28,m6502_29,m6502_2a,m6502_2b,m6502_2c,m6502_2d,m6502_2e,m6502_2f, | |
| 88 | m6502_30,m6502_31,m6502_32,m6502_33,m6502_34,m6502_35,m6502_36,m6502_37, | |
| 89 | m6502_38,m6502_39,m6502_3a,m6502_3b,m6502_3c,m6502_3d,m6502_3e,m6502_3f, | |
| 90 | m6502_40,m6502_41,m6502_42,m6502_43,m6502_44,m6502_45,m6502_46,m6502_47, | |
| 91 | m6502_48,m6502_49,m6502_4a,m6502_4b,m6502_4c,m6502_4d,m6502_4e,m6502_4f, | |
| 92 | m6502_50,m6502_51,m6502_52,m6502_53,m6502_54,m6502_55,m6502_56,m6502_57, | |
| 93 | m6502_58,m6502_59,m6502_5a,m6502_5b,m6502_5c,m6502_5d,m6502_5e,m6502_5f, | |
| 94 | m6502_60,n2a03_61,m6502_62,n2a03_63,m6502_64,n2a03_65,m6502_66,n2a03_67, | |
| 95 | m6502_68,n2a03_69,m6502_6a,n2a03_6b,m6502_6c,n2a03_6d,m6502_6e,n2a03_6f, | |
| 96 | m6502_70,n2a03_71,m6502_72,n2a03_73,m6502_74,n2a03_75,m6502_76,n2a03_77, | |
| 97 | m6502_78,n2a03_79,m6502_7a,n2a03_7b,m6502_7c,n2a03_7d,m6502_7e,n2a03_7f, | |
| 98 | m6502_80,m6502_81,m6502_82,m6502_83,m6502_84,m6502_85,m6502_86,m6502_87, | |
| 99 | m6502_88,m6502_89,m6502_8a,m6502_8b,m6502_8c,m6502_8d,m6502_8e,m6502_8f, | |
| 100 | m6502_90,m6502_91,m6502_92,m6502_93,m6502_94,m6502_95,m6502_96,m6502_97, | |
| 101 | m6502_98,m6502_99,m6502_9a,m6502_9b,n2a03_9c,m6502_9d,n2a03_9e,m6502_9f, | |
| 102 | m6502_a0,m6502_a1,m6502_a2,m6502_a3,m6502_a4,m6502_a5,m6502_a6,m6502_a7, | |
| 103 | m6502_a8,m6502_a9,m6502_aa,n2a03_ab,m6502_ac,m6502_ad,m6502_ae,m6502_af, | |
| 104 | m6502_b0,m6502_b1,m6502_b2,m6502_b3,m6502_b4,m6502_b5,m6502_b6,m6502_b7, | |
| 105 | m6502_b8,m6502_b9,m6502_ba,m6502_bb,m6502_bc,m6502_bd,m6502_be,m6502_bf, | |
| 106 | m6502_c0,m6502_c1,m6502_c2,m6502_c3,m6502_c4,m6502_c5,m6502_c6,m6502_c7, | |
| 107 | m6502_c8,m6502_c9,m6502_ca,m6502_cb,m6502_cc,m6502_cd,m6502_ce,m6502_cf, | |
| 108 | m6502_d0,m6502_d1,m6502_d2,m6502_d3,m6502_d4,m6502_d5,m6502_d6,m6502_d7, | |
| 109 | m6502_d8,m6502_d9,m6502_da,m6502_db,m6502_dc,m6502_dd,m6502_de,m6502_df, | |
| 110 | m6502_e0,n2a03_e1,m6502_e2,n2a03_e3,m6502_e4,n2a03_e5,m6502_e6,n2a03_e7, | |
| 111 | m6502_e8,n2a03_e9,m6502_ea,n2a03_eb,m6502_ec,n2a03_ed,m6502_ee,n2a03_ef, | |
| 112 | m6502_f0,n2a03_f1,m6502_f2,n2a03_f3,m6502_f4,n2a03_f5,m6502_f6,n2a03_f7, | |
| 113 | m6502_f8,n2a03_f9,m6502_fa,n2a03_fb,m6502_fc,n2a03_fd,m6502_fe,n2a03_ff | |
| 114 | }; |
| r18874 | r18875 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * ops09.h | |
| 4 | * | |
| 5 | * Copyright Peter Trauner, all rights reserved. | |
| 6 | * documentation by michael steil mist@c64.org | |
| 7 | * available at ftp://ftp.funet.fi/pub/cbm/c65 | |
| 8 | * | |
| 9 | * - This source code is released as freeware for non-commercial purposes. | |
| 10 | * - You are free to use and redistribute this code in modified or | |
| 11 | * unmodified form, provided you list me in the credits. | |
| 12 | * - If you modify this source code, you must add a notice to each modified | |
| 13 | * source file that it has been changed. If you're a nice person, you | |
| 14 | * will clearly mark each change too. :) | |
| 15 | * - If you wish to use this for commercial purposes, please contact me at | |
| 16 | * pullmoll@t-online.de | |
| 17 | * - The author of this copywritten work reserves the right to change the | |
| 18 | * terms of its usage and license at any time, including retroactively | |
| 19 | * - This entire notice must remain in the source code. | |
| 20 | * | |
| 21 | *****************************************************************************/ | |
| 22 | ||
| 23 | #define ZPWH cpustate->zp.w.h | |
| 24 | ||
| 25 | #define EAWH cpustate->ea.w.h | |
| 26 | ||
| 27 | #define PBWH cpustate->pc_bank.w.h | |
| 28 | #define PB cpustate->pc_bank.d | |
| 29 | ||
| 30 | #define IBWH cpustate->ind_bank.w.h | |
| 31 | #define IB cpustate->ind_bank.d | |
| 32 | ||
| 33 | /*************************************************************** | |
| 34 | * RDOP read an opcode | |
| 35 | ***************************************************************/ | |
| 36 | #undef RDOP | |
| 37 | #define RDOP() cpustate->direct->read_decrypted_byte((PCW++)|PB); cpustate->icount -= 1 | |
| 38 | ||
| 39 | /*************************************************************** | |
| 40 | * RDOPARG read an opcode argument | |
| 41 | ***************************************************************/ | |
| 42 | #undef RDOPARG | |
| 43 | #define RDOPARG() cpustate->direct->read_raw_byte((PCW++)|PB); cpustate->icount -= 1 | |
| 44 | ||
| 45 | /*************************************************************** | |
| 46 | * RDMEM read memory | |
| 47 | ***************************************************************/ | |
| 48 | #undef RDMEM | |
| 49 | #define RDMEM(addr) cpustate->space->read_byte(addr); cpustate->icount -= 1 | |
| 50 | ||
| 51 | /*************************************************************** | |
| 52 | * WRMEM write memory | |
| 53 | ***************************************************************/ | |
| 54 | #undef WRMEM | |
| 55 | #define WRMEM(addr,data) cpustate->space->write_byte(addr,data); cpustate->icount -= 1 | |
| 56 | ||
| 57 | /*************************************************************** | |
| 58 | * push a register onto the stack | |
| 59 | ***************************************************************/ | |
| 60 | #undef PUSH | |
| 61 | #define PUSH(Rg) WRMEM(SPD|PB, Rg); S-- | |
| 62 | ||
| 63 | /*************************************************************** | |
| 64 | * pull a register from the stack | |
| 65 | ***************************************************************/ | |
| 66 | #undef PULL | |
| 67 | #define PULL(Rg) S++; Rg = RDMEM(SPD|PB) | |
| 68 | ||
| 69 | ||
| 70 | /*************************************************************** | |
| 71 | * EA = zero page address | |
| 72 | ***************************************************************/ | |
| 73 | #undef EA_ZPG | |
| 74 | #define EA_ZPG \ | |
| 75 | ZPL = RDOPARG(); \ | |
| 76 | ZPWH = PBWH; \ | |
| 77 | EAD = ZPD | |
| 78 | ||
| 79 | /*************************************************************** | |
| 80 | * EA = zero page address + X | |
| 81 | ***************************************************************/ | |
| 82 | #undef EA_ZPX | |
| 83 | #define EA_ZPX \ | |
| 84 | ZPL = X + RDOPARG(); \ | |
| 85 | ZPWH = PBWH; \ | |
| 86 | EAD = ZPD | |
| 87 | ||
| 88 | /*************************************************************** | |
| 89 | * EA = zero page address + Y | |
| 90 | ***************************************************************/ | |
| 91 | #undef EA_ZPY | |
| 92 | #define EA_ZPY \ | |
| 93 | ZPL = Y + RDOPARG(); \ | |
| 94 | ZPWH = PBWH; \ | |
| 95 | EAD = ZPD | |
| 96 | ||
| 97 | /*************************************************************** | |
| 98 | * EA = absolute address | |
| 99 | ***************************************************************/ | |
| 100 | #undef EA_ABS | |
| 101 | #define EA_ABS \ | |
| 102 | EAL = RDOPARG(); \ | |
| 103 | EAH = RDOPARG(); \ | |
| 104 | EAWH = PBWH | |
| 105 | ||
| 106 | /*************************************************************** | |
| 107 | * EA = zero page + X indirect (pre indexed) | |
| 108 | ***************************************************************/ | |
| 109 | #undef EA_IDX | |
| 110 | #define EA_IDX \ | |
| 111 | ZPL = X + RDOPARG(); \ | |
| 112 | ZPWH=PBWH; \ | |
| 113 | EAL = RDMEM(ZPD); \ | |
| 114 | ZPL++; \ | |
| 115 | EAH = RDMEM(ZPD); \ | |
| 116 | EAWH = PBWH | |
| 117 | ||
| 118 | /*************************************************************** | |
| 119 | * EA = zero page indirect + Y (post indexed) | |
| 120 | * subtract 1 cycle if page boundary is crossed | |
| 121 | ***************************************************************/ | |
| 122 | #undef EA_IDY | |
| 123 | #define EA_IDY \ | |
| 124 | ZPL = RDOPARG(); \ | |
| 125 | ZPWH = PBWH; \ | |
| 126 | EAL = RDMEM(ZPD); \ | |
| 127 | ZPL++; \ | |
| 128 | EAH = RDMEM(ZPD); \ | |
| 129 | EAWH = PBWH; \ | |
| 130 | if (EAL + Y > 0xff) \ | |
| 131 | cpustate->icount--; \ | |
| 132 | EAW += Y | |
| 133 | ||
| 134 | /*************************************************************** | |
| 135 | * EA = zero page indirect + Y (post indexed) | |
| 136 | * subtract 1 cycle if page boundary is crossed | |
| 137 | ***************************************************************/ | |
| 138 | #undef EA_IDY_P | |
| 139 | #define EA_IDY_P \ | |
| 140 | ZPL = RDOPARG(); \ | |
| 141 | EAL = RDMEM(ZPD); \ | |
| 142 | ZPL++; \ | |
| 143 | EAH = RDMEM(ZPD); \ | |
| 144 | EAWH = PBWH; \ | |
| 145 | if (EAL + Y > 0xff) { \ | |
| 146 | RDMEM( ( EAH << 8 ) | ( ( EAL + Y ) & 0xff ) ); \ | |
| 147 | } \ | |
| 148 | EAW += Y; | |
| 149 | ||
| 150 | /*************************************************************** | |
| 151 | * EA = zero page indirect + Y (post indexed) | |
| 152 | * subtract 1 cycle if page boundary is crossed | |
| 153 | ***************************************************************/ | |
| 154 | #define EA_IDY_6509 \ | |
| 155 | ZPL = RDOPARG(); \ | |
| 156 | ZPWH = PBWH; \ | |
| 157 | EAL = RDMEM(ZPD); \ | |
| 158 | ZPL++; \ | |
| 159 | EAH = RDMEM(ZPD); \ | |
| 160 | EAWH = IBWH; \ | |
| 161 | if (EAL + Y > 0xff) \ | |
| 162 | cpustate->icount--; \ | |
| 163 | EAW += Y | |
| 164 | ||
| 165 | /*************************************************************** | |
| 166 | * EA = indirect (only used by JMP) | |
| 167 | ***************************************************************/ | |
| 168 | #undef EA_IND | |
| 169 | #define EA_IND \ | |
| 170 | EA_ABS; \ | |
| 171 | tmp = RDMEM(EAD); \ | |
| 172 | EAL++; /* booby trap: stay in same page! ;-) */ \ | |
| 173 | EAH = RDMEM(EAD); \ | |
| 174 | EAL = tmp; | |
| 175 | /* EAWH = PBWH */ | |
| 176 | ||
| 177 | #define RD_IDY_6509 EA_IDY_6509; tmp = RDMEM(EAD) | |
| 178 | #define WR_IDY_6509 EA_IDY_6509; WRMEM(EAD, tmp) | |
| 179 | ||
| 180 | /*************************************************************** | |
| 181 | * BRA branch relative | |
| 182 | * extra cycle if page boundary is crossed | |
| 183 | ***************************************************************/ | |
| 184 | #undef BRA | |
| 185 | #define BRA(cond) \ | |
| 186 | if (cond) \ | |
| 187 | { \ | |
| 188 | tmp = RDOPARG(); \ | |
| 189 | EAW = PCW + (signed char)tmp; \ | |
| 190 | cpustate->icount -= (PCH == EAH) ? 1 : 2; \ | |
| 191 | PCD = EAD|PB; \ | |
| 192 | } \ | |
| 193 | else \ | |
| 194 | { \ | |
| 195 | PCW++; \ | |
| 196 | cpustate->icount -= 1; \ | |
| 197 | } | |
| 198 | ||
| 199 | /* 6502 ******************************************************** | |
| 200 | * JSR Jump to subroutine | |
| 201 | * decrement PC (sic!) push PC hi, push PC lo and set | |
| 202 | * PC to the effective address | |
| 203 | ***************************************************************/ | |
| 204 | #undef JSR | |
| 205 | #define JSR \ | |
| 206 | EAL = RDOPARG(); \ | |
| 207 | PUSH(PCH); \ | |
| 208 | PUSH(PCL); \ | |
| 209 | EAH = RDOPARG(); \ | |
| 210 | EAWH = PBWH; \ | |
| 211 | PCD = EAD | |
| 212 | ||
| 213 | /* 6510 ******************************************************** | |
| 214 | * KIL Illegal opcode | |
| 215 | * processor haltet, no hardware interrupt will help | |
| 216 | * only reset | |
| 217 | ***************************************************************/ | |
| 218 | #undef KIL | |
| 219 | #define KIL \ | |
| 220 | PCW--; \ | |
| 221 | logerror("M6509 KILL opcode %05x: %02x\n", PCD, cpustate->direct->read_decrypted_byte(PCD)) |
| r18874 | r18875 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * tbl6509.c | |
| 4 | * 6509 opcode functions and function pointer table | |
| 5 | * | |
| 6 | * Copyright Peter Trauner, all rights reserved. | |
| 7 | * | |
| 8 | * - This source code is released as freeware for non-commercial purposes. | |
| 9 | * - You are free to use and redistribute this code in modified or | |
| 10 | * unmodified form, provided you list me in the credits. | |
| 11 | * - If you modify this source code, you must add a notice to each modified | |
| 12 | * source file that it has been changed. If you're a nice person, you | |
| 13 | * will clearly mark each change too. :) | |
| 14 | * - If you wish to use this for commercial purposes, please contact me at | |
| 15 | * pullmoll@t-online.de | |
| 16 | * - The author of this copywritten work reserves the right to change the | |
| 17 | * terms of its usage and license at any time, including retroactively | |
| 18 | * - This entire notice must remain in the source code. | |
| 19 | * | |
| 20 | * - Opcode information based on an Intel 386 '6510.asm' core | |
| 21 | * written by R.F. van Ee (1993) | |
| 22 | * - Cycle counts are guesswork :-) | |
| 23 | * | |
| 24 | *****************************************************************************/ | |
| 25 | ||
| 26 | #undef OP | |
| 27 | #define OP(nn) INLINE void m6509_##nn(m6509_Regs *cpustate) | |
| 28 | ||
| 29 | OP(00) { BRK; } /* 7 BRK */ | |
| 30 | OP(20) { JSR; } /* 6 JSR */ | |
| 31 | OP(40) { RTI; } /* 6 RTI */ | |
| 32 | OP(60) { RTS; } /* 6 RTS */ | |
| 33 | OP(80) { RD_IMM_DISCARD; NOP; } /* 2 NOP IMM */ | |
| 34 | OP(a0) { int tmp; RD_IMM; LDY; } /* 2 LDY IMM */ | |
| 35 | OP(c0) { int tmp; RD_IMM; CPY; } /* 2 CPY IMM */ | |
| 36 | OP(e0) { int tmp; RD_IMM; CPX; } /* 2 CPX IMM */ | |
| 37 | ||
| 38 | OP(10) { int tmp; BPL; } /* 2-4 BPL REL */ | |
| 39 | OP(30) { int tmp; BMI; } /* 2-4 BMI REL */ | |
| 40 | OP(50) { int tmp; BVC; } /* 2-4 BVC REL */ | |
| 41 | OP(70) { int tmp; BVS; } /* 2-4 BVS REL */ | |
| 42 | OP(90) { int tmp; BCC; } /* 2-4 BCC REL */ | |
| 43 | OP(b0) { int tmp; BCS; } /* 2-4 BCS REL */ | |
| 44 | OP(d0) { int tmp; BNE; } /* 2-4 BNE REL */ | |
| 45 | OP(f0) { int tmp; BEQ; } /* 2-4 BEQ REL */ | |
| 46 | ||
| 47 | OP(01) { int tmp; RD_IDX; ORA; } /* 6 ORA IDX */ | |
| 48 | OP(21) { int tmp; RD_IDX; AND; } /* 6 AND IDX */ | |
| 49 | OP(41) { int tmp; RD_IDX; EOR; } /* 6 EOR IDX */ | |
| 50 | OP(61) { int tmp; RD_IDX; ADC; } /* 6 ADC IDX */ | |
| 51 | OP(81) { int tmp; STA; WR_IDX; } /* 6 STA IDX */ | |
| 52 | OP(a1) { int tmp; RD_IDX; LDA; } /* 6 LDA IDX */ | |
| 53 | OP(c1) { int tmp; RD_IDX; CMP; } /* 6 CMP IDX */ | |
| 54 | OP(e1) { int tmp; RD_IDX; SBC; } /* 6 SBC IDX */ | |
| 55 | ||
| 56 | OP(11) { int tmp; RD_IDY_P; ORA; } /* 5 ORA IDY page penalty */ | |
| 57 | OP(31) { int tmp; RD_IDY_P; AND; } /* 5 AND IDY page penalty */ | |
| 58 | OP(51) { int tmp; RD_IDY_P; EOR; } /* 5 EOR IDY page penalty */ | |
| 59 | OP(71) { int tmp; RD_IDY_P; ADC; } /* 5 ADC IDY page penalty */ | |
| 60 | OP(91) { int tmp; STA; WR_IDY_6509; } /* 6 STA IDY */ | |
| 61 | OP(b1) { int tmp; RD_IDY_6509; LDA; } /* 5 LDA IDY page penalty */ | |
| 62 | OP(d1) { int tmp; RD_IDY_P; CMP; } /* 5 CMP IDY page penalty */ | |
| 63 | OP(f1) { int tmp; RD_IDY_P; SBC; } /* 5 SBC IDY page penalty */ | |
| 64 | ||
| 65 | OP(02) { KIL; } /* 1 KIL */ | |
| 66 | OP(22) { KIL; } /* 1 KIL */ | |
| 67 | OP(42) { KIL; } /* 1 KIL */ | |
| 68 | OP(62) { KIL; } /* 1 KIL */ | |
| 69 | OP(82) { RD_IMM_DISCARD; NOP; } /* 2 NOP IMM */ | |
| 70 | OP(a2) { int tmp; RD_IMM; LDX; } /* 2 LDX IMM */ | |
| 71 | OP(c2) { RD_IMM_DISCARD; NOP; } /* 2 NOP IMM */ | |
| 72 | OP(e2) { RD_IMM_DISCARD; NOP; } /* 2 NOP IMM */ | |
| 73 | ||
| 74 | OP(12) { KIL; } /* 1 KIL */ | |
| 75 | OP(32) { KIL; } /* 1 KIL */ | |
| 76 | OP(52) { KIL; } /* 1 KIL */ | |
| 77 | OP(72) { KIL; } /* 1 KIL */ | |
| 78 | OP(92) { KIL; } /* 1 KIL */ | |
| 79 | OP(b2) { KIL; } /* 1 KIL */ | |
| 80 | OP(d2) { KIL; } /* 1 KIL */ | |
| 81 | OP(f2) { KIL; } /* 1 KIL */ | |
| 82 | ||
| 83 | OP(03) { int tmp; RD_IDX; WB_EA; SLO; WB_EA; } /* 7 SLO IDX */ | |
| 84 | OP(23) { int tmp; RD_IDX; WB_EA; RLA; WB_EA; } /* 7 RLA IDX */ | |
| 85 | OP(43) { int tmp; RD_IDX; WB_EA; SRE; WB_EA; } /* 7 SRE IDX */ | |
| 86 | OP(63) { int tmp; RD_IDX; WB_EA; RRA; WB_EA; } /* 7 RRA IDX */ | |
| 87 | OP(83) { int tmp; SAX; WR_IDX; } /* 6 SAX IDX */ | |
| 88 | OP(a3) { int tmp; RD_IDX; LAX; } /* 6 LAX IDX */ | |
| 89 | OP(c3) { int tmp; RD_IDX; WB_EA; DCP; WB_EA; } /* 7 DCP IDX */ | |
| 90 | OP(e3) { int tmp; RD_IDX; WB_EA; ISB; WB_EA; } /* 7 ISB IDX */ | |
| 91 | ||
| 92 | OP(13) { int tmp; RD_IDY_NP; WB_EA; SLO; WB_EA; } /* 7 SLO IDY */ | |
| 93 | OP(33) { int tmp; RD_IDY_NP; WB_EA; RLA; WB_EA; } /* 7 RLA IDY */ | |
| 94 | OP(53) { int tmp; RD_IDY_NP; WB_EA; SRE; WB_EA; } /* 7 SRE IDY */ | |
| 95 | OP(73) { int tmp; RD_IDY_NP; WB_EA; RRA; WB_EA; } /* 7 RRA IDY */ | |
| 96 | OP(93) { int tmp; EA_IDY_NP; SAH; WB_EA; } /* 5 SAH IDY */ | |
| 97 | OP(b3) { int tmp; RD_IDY_P; LAX; } /* 5 LAX IDY page penalty */ | |
| 98 | OP(d3) { int tmp; RD_IDY_NP; WB_EA; DCP; WB_EA; } /* 7 DCP IDY */ | |
| 99 | OP(f3) { int tmp; RD_IDY_NP; WB_EA; ISB; WB_EA; } /* 7 ISB IDY */ | |
| 100 | ||
| 101 | OP(04) { RD_ZPG_DISCARD; NOP; } /* 3 NOP ZPG */ | |
| 102 | OP(24) { int tmp; RD_ZPG; BIT; } /* 3 BIT ZPG */ | |
| 103 | OP(44) { RD_ZPG_DISCARD; NOP; } /* 3 NOP ZPG */ | |
| 104 | OP(64) { RD_ZPG_DISCARD; NOP; } /* 3 NOP ZPG */ | |
| 105 | OP(84) { int tmp; STY; WR_ZPG; } /* 3 STY ZPG */ | |
| 106 | OP(a4) { int tmp; RD_ZPG; LDY; } /* 3 LDY ZPG */ | |
| 107 | OP(c4) { int tmp; RD_ZPG; CPY; } /* 3 CPY ZPG */ | |
| 108 | OP(e4) { int tmp; RD_ZPG; CPX; } /* 3 CPX ZPG */ | |
| 109 | ||
| 110 | OP(14) { RD_ZPX_DISCARD; NOP; } /* 4 NOP ZPX */ | |
| 111 | OP(34) { RD_ZPX_DISCARD; NOP; } /* 4 NOP ZPX */ | |
| 112 | OP(54) { RD_ZPX_DISCARD; NOP; } /* 4 NOP ZPX */ | |
| 113 | OP(74) { RD_ZPX_DISCARD; NOP; } /* 4 NOP ZPX */ | |
| 114 | OP(94) { int tmp; STY; WR_ZPX; } /* 4 STY ZPX */ | |
| 115 | OP(b4) { int tmp; RD_ZPX; LDY; } /* 4 LDY ZPX */ | |
| 116 | OP(d4) { RD_ZPX_DISCARD; NOP; } /* 4 NOP ZPX */ | |
| 117 | OP(f4) { RD_ZPX_DISCARD; NOP; } /* 4 NOP ZPX */ | |
| 118 | ||
| 119 | OP(05) { int tmp; RD_ZPG; ORA; } /* 3 ORA ZPG */ | |
| 120 | OP(25) { int tmp; RD_ZPG; AND; } /* 3 AND ZPG */ | |
| 121 | OP(45) { int tmp; RD_ZPG; EOR; } /* 3 EOR ZPG */ | |
| 122 | OP(65) { int tmp; RD_ZPG; ADC; } /* 3 ADC ZPG */ | |
| 123 | OP(85) { int tmp; STA; WR_ZPG; } /* 3 STA ZPG */ | |
| 124 | OP(a5) { int tmp; RD_ZPG; LDA; } /* 3 LDA ZPG */ | |
| 125 | OP(c5) { int tmp; RD_ZPG; CMP; } /* 3 CMP ZPG */ | |
| 126 | OP(e5) { int tmp; RD_ZPG; SBC; } /* 3 SBC ZPG */ | |
| 127 | ||
| 128 | OP(15) { int tmp; RD_ZPX; ORA; } /* 4 ORA ZPX */ | |
| 129 | OP(35) { int tmp; RD_ZPX; AND; } /* 4 AND ZPX */ | |
| 130 | OP(55) { int tmp; RD_ZPX; EOR; } /* 4 EOR ZPX */ | |
| 131 | OP(75) { int tmp; RD_ZPX; ADC; } /* 4 ADC ZPX */ | |
| 132 | OP(95) { int tmp; STA; WR_ZPX; } /* 4 STA ZPX */ | |
| 133 | OP(b5) { int tmp; RD_ZPX; LDA; } /* 4 LDA ZPX */ | |
| 134 | OP(d5) { int tmp; RD_ZPX; CMP; } /* 4 CMP ZPX */ | |
| 135 | OP(f5) { int tmp; RD_ZPX; SBC; } /* 4 SBC ZPX */ | |
| 136 | ||
| 137 | OP(06) { int tmp; RD_ZPG; WB_EA; ASL; WB_EA; } /* 5 ASL ZPG */ | |
| 138 | OP(26) { int tmp; RD_ZPG; WB_EA; ROL; WB_EA; } /* 5 ROL ZPG */ | |
| 139 | OP(46) { int tmp; RD_ZPG; WB_EA; LSR; WB_EA; } /* 5 LSR ZPG */ | |
| 140 | OP(66) { int tmp; RD_ZPG; WB_EA; ROR; WB_EA; } /* 5 ROR ZPG */ | |
| 141 | OP(86) { int tmp; STX; WR_ZPG; } /* 3 STX ZPG */ | |
| 142 | OP(a6) { int tmp; RD_ZPG; LDX; } /* 3 LDX ZPG */ | |
| 143 | OP(c6) { int tmp; RD_ZPG; WB_EA; DEC; WB_EA; } /* 5 DEC ZPG */ | |
| 144 | OP(e6) { int tmp; RD_ZPG; WB_EA; INC; WB_EA; } /* 5 INC ZPG */ | |
| 145 | ||
| 146 | OP(16) { int tmp; RD_ZPX; WB_EA; ASL; WB_EA; } /* 6 ASL ZPX */ | |
| 147 | OP(36) { int tmp; RD_ZPX; WB_EA; ROL; WB_EA; } /* 6 ROL ZPX */ | |
| 148 | OP(56) { int tmp; RD_ZPX; WB_EA; LSR; WB_EA; } /* 6 LSR ZPX */ | |
| 149 | OP(76) { int tmp; RD_ZPX; WB_EA; ROR; WB_EA; } /* 6 ROR ZPX */ | |
| 150 | OP(96) { int tmp; STX; WR_ZPY; } /* 4 STX ZPY */ | |
| 151 | OP(b6) { int tmp; RD_ZPY; LDX; } /* 4 LDX ZPY */ | |
| 152 | OP(d6) { int tmp; RD_ZPX; WB_EA; DEC; WB_EA; } /* 6 DEC ZPX */ | |
| 153 | OP(f6) { int tmp; RD_ZPX; WB_EA; INC; WB_EA; } /* 6 INC ZPX */ | |
| 154 | ||
| 155 | OP(07) { int tmp; RD_ZPG; WB_EA; SLO; WB_EA; } /* 5 SLO ZPG */ | |
| 156 | OP(27) { int tmp; RD_ZPG; WB_EA; RLA; WB_EA; } /* 5 RLA ZPG */ | |
| 157 | OP(47) { int tmp; RD_ZPG; WB_EA; SRE; WB_EA; } /* 5 SRE ZPG */ | |
| 158 | OP(67) { int tmp; RD_ZPG; WB_EA; RRA; WB_EA; } /* 5 RRA ZPG */ | |
| 159 | OP(87) { int tmp; SAX; WR_ZPG; } /* 3 SAX ZPG */ | |
| 160 | OP(a7) { int tmp; RD_ZPG; LAX; } /* 3 LAX ZPG */ | |
| 161 | OP(c7) { int tmp; RD_ZPG; WB_EA; DCP; WB_EA; } /* 5 DCP ZPG */ | |
| 162 | OP(e7) { int tmp; RD_ZPG; WB_EA; ISB; WB_EA; } /* 5 ISB ZPG */ | |
| 163 | ||
| 164 | OP(17) { int tmp; RD_ZPX; WB_EA; SLO; WB_EA; } /* 6 SLO ZPX */ | |
| 165 | OP(37) { int tmp; RD_ZPX; WB_EA; RLA; WB_EA; } /* 6 RLA ZPX */ | |
| 166 | OP(57) { int tmp; RD_ZPX; WB_EA; SRE; WB_EA; } /* 6 SRE ZPX */ | |
| 167 | OP(77) { int tmp; RD_ZPX; WB_EA; RRA; WB_EA; } /* 6 RRA ZPX */ | |
| 168 | OP(97) { int tmp; SAX; WR_ZPY; } /* 4 SAX ZPY */ | |
| 169 | OP(b7) { int tmp; RD_ZPY; LAX; } /* 4 LAX ZPY */ | |
| 170 | OP(d7) { int tmp; RD_ZPX; WB_EA; DCP; WB_EA; } /* 6 DCP ZPX */ | |
| 171 | OP(f7) { int tmp; RD_ZPX; WB_EA; ISB; WB_EA; } /* 6 ISB ZPX */ | |
| 172 | ||
| 173 | OP(08) { RD_DUM; PHP; } /* 3 PHP */ | |
| 174 | OP(28) { RD_DUM; PLP; } /* 4 PLP */ | |
| 175 | OP(48) { RD_DUM; PHA; } /* 3 PHA */ | |
| 176 | OP(68) { RD_DUM; PLA; } /* 4 PLA */ | |
| 177 | OP(88) { RD_DUM; DEY; } /* 2 DEY */ | |
| 178 | OP(a8) { RD_DUM; TAY; } /* 2 TAY */ | |
| 179 | OP(c8) { RD_DUM; INY; } /* 2 INY */ | |
| 180 | OP(e8) { RD_DUM; INX; } /* 2 INX */ | |
| 181 | ||
| 182 | OP(18) { RD_DUM; CLC; } /* 2 CLC */ | |
| 183 | OP(38) { RD_DUM; SEC; } /* 2 SEC */ | |
| 184 | OP(58) { RD_DUM; CLI; } /* 2 CLI */ | |
| 185 | OP(78) { RD_DUM; SEI; } /* 2 SEI */ | |
| 186 | OP(98) { RD_DUM; TYA; } /* 2 TYA */ | |
| 187 | OP(b8) { RD_DUM; CLV; } /* 2 CLV */ | |
| 188 | OP(d8) { RD_DUM; CLD; } /* 2 CLD */ | |
| 189 | OP(f8) { RD_DUM; SED; } /* 2 SED */ | |
| 190 | ||
| 191 | OP(09) { int tmp; RD_IMM; ORA; } /* 2 ORA IMM */ | |
| 192 | OP(29) { int tmp; RD_IMM; AND; } /* 2 AND IMM */ | |
| 193 | OP(49) { int tmp; RD_IMM; EOR; } /* 2 EOR IMM */ | |
| 194 | OP(69) { int tmp; RD_IMM; ADC; } /* 2 ADC IMM */ | |
| 195 | OP(89) { RD_IMM_DISCARD; NOP; } /* 2 NOP IMM */ | |
| 196 | OP(a9) { int tmp; RD_IMM; LDA; } /* 2 LDA IMM */ | |
| 197 | OP(c9) { int tmp; RD_IMM; CMP; } /* 2 CMP IMM */ | |
| 198 | OP(e9) { int tmp; RD_IMM; SBC; } /* 2 SBC IMM */ | |
| 199 | ||
| 200 | OP(19) { int tmp; RD_ABY_P; ORA; } /* 4 ORA ABY page penalty */ | |
| 201 | OP(39) { int tmp; RD_ABY_P; AND; } /* 4 AND ABY page penalty */ | |
| 202 | OP(59) { int tmp; RD_ABY_P; EOR; } /* 4 EOR ABY page penalty */ | |
| 203 | OP(79) { int tmp; RD_ABY_P; ADC; } /* 4 ADC ABY page penalty */ | |
| 204 | OP(99) { int tmp; STA; WR_ABY_NP; } /* 5 STA ABY */ | |
| 205 | OP(b9) { int tmp; RD_ABY_P; LDA; } /* 4 LDA ABY page penalty */ | |
| 206 | OP(d9) { int tmp; RD_ABY_P; CMP; } /* 4 CMP ABY page penalty */ | |
| 207 | OP(f9) { int tmp; RD_ABY_P; SBC; } /* 4 SBC ABY page penalty */ | |
| 208 | ||
| 209 | OP(0a) { int tmp; RD_DUM; RD_ACC; ASL; WB_ACC; } /* 2 ASL A */ | |
| 210 | OP(2a) { int tmp; RD_DUM; RD_ACC; ROL; WB_ACC; } /* 2 ROL A */ | |
| 211 | OP(4a) { int tmp; RD_DUM; RD_ACC; LSR; WB_ACC; } /* 2 LSR A */ | |
| 212 | OP(6a) { int tmp; RD_DUM; RD_ACC; ROR; WB_ACC; } /* 2 ROR A */ | |
| 213 | OP(8a) { RD_DUM; TXA; } /* 2 TXA */ | |
| 214 | OP(aa) { RD_DUM; TAX; } /* 2 TAX */ | |
| 215 | OP(ca) { RD_DUM; DEX; } /* 2 DEX */ | |
| 216 | OP(ea) { RD_DUM; NOP; } /* 2 NOP */ | |
| 217 | ||
| 218 | OP(1a) { RD_DUM; NOP; } /* 2 NOP */ | |
| 219 | OP(3a) { RD_DUM; NOP; } /* 2 NOP */ | |
| 220 | OP(5a) { RD_DUM; NOP; } /* 2 NOP */ | |
| 221 | OP(7a) { RD_DUM; NOP; } /* 2 NOP */ | |
| 222 | OP(9a) { RD_DUM; TXS; } /* 2 TXS */ | |
| 223 | OP(ba) { RD_DUM; TSX; } /* 2 TSX */ | |
| 224 | OP(da) { RD_DUM; NOP; } /* 2 NOP */ | |
| 225 | OP(fa) { RD_DUM; NOP; } /* 2 NOP */ | |
| 226 | ||
| 227 | OP(0b) { int tmp; RD_IMM; ANC; } /* 2 ANC IMM */ | |
| 228 | OP(2b) { int tmp; RD_IMM; ANC; } /* 2 ANC IMM */ | |
| 229 | OP(4b) { int tmp; RD_IMM; ASR; WB_ACC; } /* 2 ASR IMM */ | |
| 230 | OP(6b) { int tmp; RD_IMM; ARR; WB_ACC; } /* 2 ARR IMM */ | |
| 231 | OP(8b) { int tmp; RD_IMM; AXA; } /* 2 AXA IMM */ | |
| 232 | OP(ab) { int tmp; RD_IMM; OAL; } /* 2 OAL IMM */ | |
| 233 | OP(cb) { int tmp; RD_IMM; ASX; } /* 2 ASX IMM */ | |
| 234 | OP(eb) { int tmp; RD_IMM; SBC; } /* 2 SBC IMM */ | |
| 235 | ||
| 236 | OP(1b) { int tmp; RD_ABY_NP; WB_EA; SLO; WB_EA; } /* 7 SLO ABY */ | |
| 237 | OP(3b) { int tmp; RD_ABY_NP; WB_EA; RLA; WB_EA; } /* 7 RLA ABY */ | |
| 238 | OP(5b) { int tmp; RD_ABY_NP; WB_EA; SRE; WB_EA; } /* 7 SRE ABY */ | |
| 239 | OP(7b) { int tmp; RD_ABY_NP; WB_EA; RRA; WB_EA; } /* 7 RRA ABY */ | |
| 240 | OP(9b) { int tmp; EA_ABY_NP; SSH; WB_EA; } /* 5 SSH ABY */ | |
| 241 | OP(bb) { int tmp; RD_ABY_P; AST; } /* 4 AST ABY page penalty */ | |
| 242 | OP(db) { int tmp; RD_ABY_NP; WB_EA; DCP; WB_EA; } /* 7 DCP ABY */ | |
| 243 | OP(fb) { int tmp; RD_ABY_NP; WB_EA; ISB; WB_EA; } /* 7 ISB ABY */ | |
| 244 | ||
| 245 | OP(0c) { RD_ABS_DISCARD; NOP; } /* 4 NOP ABS */ | |
| 246 | OP(2c) { int tmp; RD_ABS; BIT; } /* 4 BIT ABS */ | |
| 247 | OP(4c) { EA_ABS; JMP; } /* 3 JMP ABS */ | |
| 248 | OP(6c) { int tmp; EA_IND; JMP; } /* 5 JMP IND */ | |
| 249 | OP(8c) { int tmp; STY; WR_ABS; } /* 4 STY ABS */ | |
| 250 | OP(ac) { int tmp; RD_ABS; LDY; } /* 4 LDY ABS */ | |
| 251 | OP(cc) { int tmp; RD_ABS; CPY; } /* 4 CPY ABS */ | |
| 252 | OP(ec) { int tmp; RD_ABS; CPX; } /* 4 CPX ABS */ | |
| 253 | ||
| 254 | OP(1c) { RD_ABX_P_DISCARD; NOP; } /* 4 NOP ABX page penalty */ | |
| 255 | OP(3c) { RD_ABX_P_DISCARD; NOP; } /* 4 NOP ABX page penalty */ | |
| 256 | OP(5c) { RD_ABX_P_DISCARD; NOP; } /* 4 NOP ABX page penalty */ | |
| 257 | OP(7c) { RD_ABX_P_DISCARD; NOP; } /* 4 NOP ABX page penalty */ | |
| 258 | OP(9c) { int tmp; EA_ABX_NP; SYH; WB_EA; } /* 5 SYH ABX */ | |
| 259 | OP(bc) { int tmp; RD_ABX_P; LDY; } /* 4 LDY ABX page penalty */ | |
| 260 | OP(dc) { RD_ABX_P_DISCARD; NOP; } /* 4 NOP ABX page penalty */ | |
| 261 | OP(fc) { RD_ABX_P_DISCARD; NOP; } /* 4 NOP ABX page penalty */ | |
| 262 | ||
| 263 | OP(0d) { int tmp; RD_ABS; ORA; } /* 4 ORA ABS */ | |
| 264 | OP(2d) { int tmp; RD_ABS; AND; } /* 4 AND ABS */ | |
| 265 | OP(4d) { int tmp; RD_ABS; EOR; } /* 4 EOR ABS */ | |
| 266 | OP(6d) { int tmp; RD_ABS; ADC; } /* 4 ADC ABS */ | |
| 267 | OP(8d) { int tmp; STA; WR_ABS; } /* 4 STA ABS */ | |
| 268 | OP(ad) { int tmp; RD_ABS; LDA; } /* 4 LDA ABS */ | |
| 269 | OP(cd) { int tmp; RD_ABS; CMP; } /* 4 CMP ABS */ | |
| 270 | OP(ed) { int tmp; RD_ABS; SBC; } /* 4 SBC ABS */ | |
| 271 | ||
| 272 | OP(1d) { int tmp; RD_ABX_P; ORA; } /* 4 ORA ABX page penalty */ | |
| 273 | OP(3d) { int tmp; RD_ABX_P; AND; } /* 4 AND ABX page penalty */ | |
| 274 | OP(5d) { int tmp; RD_ABX_P; EOR; } /* 4 EOR ABX page penalty */ | |
| 275 | OP(7d) { int tmp; RD_ABX_P; ADC; } /* 4 ADC ABX page penalty */ | |
| 276 | OP(9d) { int tmp; STA; WR_ABX_NP; } /* 5 STA ABX */ | |
| 277 | OP(bd) { int tmp; RD_ABX_P; LDA; } /* 4 LDA ABX page penalty */ | |
| 278 | OP(dd) { int tmp; RD_ABX_P; CMP; } /* 4 CMP ABX page penalty */ | |
| 279 | OP(fd) { int tmp; RD_ABX_P; SBC; } /* 4 SBC ABX page penalty */ | |
| 280 | ||
| 281 | OP(0e) { int tmp; RD_ABS; WB_EA; ASL; WB_EA; } /* 6 ASL ABS */ | |
| 282 | OP(2e) { int tmp; RD_ABS; WB_EA; ROL; WB_EA; } /* 6 ROL ABS */ | |
| 283 | OP(4e) { int tmp; RD_ABS; WB_EA; LSR; WB_EA; } /* 6 LSR ABS */ | |
| 284 | OP(6e) { int tmp; RD_ABS; WB_EA; ROR; WB_EA; } /* 6 ROR ABS */ | |
| 285 | OP(8e) { int tmp; STX; WR_ABS; } /* 4 STX ABS */ | |
| 286 | OP(ae) { int tmp; RD_ABS; LDX; } /* 4 LDX ABS */ | |
| 287 | OP(ce) { int tmp; RD_ABS; WB_EA; DEC; WB_EA; } /* 6 DEC ABS */ | |
| 288 | OP(ee) { int tmp; RD_ABS; WB_EA; INC; WB_EA; } /* 6 INC ABS */ | |
| 289 | ||
| 290 | OP(1e) { int tmp; RD_ABX_NP; WB_EA; ASL; WB_EA; } /* 7 ASL ABX */ | |
| 291 | OP(3e) { int tmp; RD_ABX_NP; WB_EA; ROL; WB_EA; } /* 7 ROL ABX */ | |
| 292 | OP(5e) { int tmp; RD_ABX_NP; WB_EA; LSR; WB_EA; } /* 7 LSR ABX */ | |
| 293 | OP(7e) { int tmp; RD_ABX_NP; WB_EA; ROR; WB_EA; } /* 7 ROR ABX */ | |
| 294 | OP(9e) { int tmp; EA_ABY_NP; SXH; WB_EA; } /* 5 SXH ABY */ | |
| 295 | OP(be) { int tmp; RD_ABY_P; LDX; } /* 4 LDX ABY page penalty */ | |
| 296 | OP(de) { int tmp; RD_ABX_NP; WB_EA; DEC; WB_EA; } /* 7 DEC ABX */ | |
| 297 | OP(fe) { int tmp; RD_ABX_NP; WB_EA; INC; WB_EA; } /* 7 INC ABX */ | |
| 298 | ||
| 299 | OP(0f) { int tmp; RD_ABS; WB_EA; SLO; WB_EA; } /* 6 SLO ABS */ | |
| 300 | OP(2f) { int tmp; RD_ABS; WB_EA; RLA; WB_EA; } /* 6 RLA ABS */ | |
| 301 | OP(4f) { int tmp; RD_ABS; WB_EA; SRE; WB_EA; } /* 6 SRE ABS */ | |
| 302 | OP(6f) { int tmp; RD_ABS; WB_EA; RRA; WB_EA; } /* 6 RRA ABS */ | |
| 303 | OP(8f) { int tmp; SAX; WR_ABS; } /* 4 SAX ABS */ | |
| 304 | OP(af) { int tmp; RD_ABS; LAX; } /* 4 LAX ABS */ | |
| 305 | OP(cf) { int tmp; RD_ABS; WB_EA; DCP; WB_EA; } /* 6 DCP ABS */ | |
| 306 | OP(ef) { int tmp; RD_ABS; WB_EA; ISB; WB_EA; } /* 6 ISB ABS */ | |
| 307 | ||
| 308 | OP(1f) { int tmp; RD_ABX_NP; WB_EA; SLO; WB_EA; } /* 7 SLO ABX */ | |
| 309 | OP(3f) { int tmp; RD_ABX_NP; WB_EA; RLA; WB_EA; } /* 7 RLA ABX */ | |
| 310 | OP(5f) { int tmp; RD_ABX_NP; WB_EA; SRE; WB_EA; } /* 7 SRE ABX */ | |
| 311 | OP(7f) { int tmp; RD_ABX_NP; WB_EA; RRA; WB_EA; } /* 7 RRA ABX */ | |
| 312 | OP(9f) { int tmp; EA_ABY_NP; SAH; WB_EA; } /* 5 SAH ABY */ | |
| 313 | OP(bf) { int tmp; RD_ABY_P; LAX; } /* 4 LAX ABY page penalty */ | |
| 314 | OP(df) { int tmp; RD_ABX_NP; WB_EA; DCP; WB_EA; } /* 7 DCP ABX */ | |
| 315 | OP(ff) { int tmp; RD_ABX_NP; WB_EA; ISB; WB_EA; } /* 7 ISB ABX */ | |
| 316 | ||
| 317 | static void (*const insn6509[0x100])(m6509_Regs *) = { | |
| 318 | m6509_00,m6509_01,m6509_02,m6509_03,m6509_04,m6509_05,m6509_06,m6509_07, | |
| 319 | m6509_08,m6509_09,m6509_0a,m6509_0b,m6509_0c,m6509_0d,m6509_0e,m6509_0f, | |
| 320 | m6509_10,m6509_11,m6509_12,m6509_13,m6509_14,m6509_15,m6509_16,m6509_17, | |
| 321 | m6509_18,m6509_19,m6509_1a,m6509_1b,m6509_1c,m6509_1d,m6509_1e,m6509_1f, | |
| 322 | m6509_20,m6509_21,m6509_22,m6509_23,m6509_24,m6509_25,m6509_26,m6509_27, | |
| 323 | m6509_28,m6509_29,m6509_2a,m6509_2b,m6509_2c,m6509_2d,m6509_2e,m6509_2f, | |
| 324 | m6509_30,m6509_31,m6509_32,m6509_33,m6509_34,m6509_35,m6509_36,m6509_37, | |
| 325 | m6509_38,m6509_39,m6509_3a,m6509_3b,m6509_3c,m6509_3d,m6509_3e,m6509_3f, | |
| 326 | m6509_40,m6509_41,m6509_42,m6509_43,m6509_44,m6509_45,m6509_46,m6509_47, | |
| 327 | m6509_48,m6509_49,m6509_4a,m6509_4b,m6509_4c,m6509_4d,m6509_4e,m6509_4f, | |
| 328 | m6509_50,m6509_51,m6509_52,m6509_53,m6509_54,m6509_55,m6509_56,m6509_57, | |
| 329 | m6509_58,m6509_59,m6509_5a,m6509_5b,m6509_5c,m6509_5d,m6509_5e,m6509_5f, | |
| 330 | m6509_60,m6509_61,m6509_62,m6509_63,m6509_64,m6509_65,m6509_66,m6509_67, | |
| 331 | m6509_68,m6509_69,m6509_6a,m6509_6b,m6509_6c,m6509_6d,m6509_6e,m6509_6f, | |
| 332 | m6509_70,m6509_71,m6509_72,m6509_73,m6509_74,m6509_75,m6509_76,m6509_77, | |
| 333 | m6509_78,m6509_79,m6509_7a,m6509_7b,m6509_7c,m6509_7d,m6509_7e,m6509_7f, | |
| 334 | m6509_80,m6509_81,m6509_82,m6509_83,m6509_84,m6509_85,m6509_86,m6509_87, | |
| 335 | m6509_88,m6509_89,m6509_8a,m6509_8b,m6509_8c,m6509_8d,m6509_8e,m6509_8f, | |
| 336 | m6509_90,m6509_91,m6509_92,m6509_93,m6509_94,m6509_95,m6509_96,m6509_97, | |
| 337 | m6509_98,m6509_99,m6509_9a,m6509_9b,m6509_9c,m6509_9d,m6509_9e,m6509_9f, | |
| 338 | m6509_a0,m6509_a1,m6509_a2,m6509_a3,m6509_a4,m6509_a5,m6509_a6,m6509_a7, | |
| 339 | m6509_a8,m6509_a9,m6509_aa,m6509_ab,m6509_ac,m6509_ad,m6509_ae,m6509_af, | |
| 340 | m6509_b0,m6509_b1,m6509_b2,m6509_b3,m6509_b4,m6509_b5,m6509_b6,m6509_b7, | |
| 341 | m6509_b8,m6509_b9,m6509_ba,m6509_bb,m6509_bc,m6509_bd,m6509_be,m6509_bf, | |
| 342 | m6509_c0,m6509_c1,m6509_c2,m6509_c3,m6509_c4,m6509_c5,m6509_c6,m6509_c7, | |
| 343 | m6509_c8,m6509_c9,m6509_ca,m6509_cb,m6509_cc,m6509_cd,m6509_ce,m6509_cf, | |
| 344 | m6509_d0,m6509_d1,m6509_d2,m6509_d3,m6509_d4,m6509_d5,m6509_d6,m6509_d7, | |
| 345 | m6509_d8,m6509_d9,m6509_da,m6509_db,m6509_dc,m6509_dd,m6509_de,m6509_df, | |
| 346 | m6509_e0,m6509_e1,m6509_e2,m6509_e3,m6509_e4,m6509_e5,m6509_e6,m6509_e7, | |
| 347 | m6509_e8,m6509_e9,m6509_ea,m6509_eb,m6509_ec,m6509_ed,m6509_ee,m6509_ef, | |
| 348 | m6509_f0,m6509_f1,m6509_f2,m6509_f3,m6509_f4,m6509_f5,m6509_f6,m6509_f7, | |
| 349 | m6509_f8,m6509_f9,m6509_fa,m6509_fb,m6509_fc,m6509_fd,m6509_fe,m6509_ff | |
| 350 | }; | |
| 351 | ||
| 352 |
| r18874 | r18875 | |
|---|---|---|
| 1 | /*************************************************************************** | |
| 2 | ||
| 3 | m7501.h | |
| 4 | ||
| 5 | 6510 derivative, essentially identical. Also known as the 8501. | |
| 6 | ||
| 7 | **************************************************************************** | |
| 8 | ||
| 9 | Copyright Olivier Galibert | |
| 10 | All rights reserved. | |
| 11 | ||
| 12 | Redistribution and use in source and binary forms, with or without | |
| 13 | modification, are permitted provided that the following conditions are | |
| 14 | met: | |
| 15 | ||
| 16 | * Redistributions of source code must retain the above copyright | |
| 17 | notice, this list of conditions and the following disclaimer. | |
| 18 | * Redistributions in binary form must reproduce the above copyright | |
| 19 | notice, this list of conditions and the following disclaimer in | |
| 20 | the documentation and/or other materials provided with the | |
| 21 | distribution. | |
| 22 | * Neither the name 'MAME' nor the names of its contributors may be | |
| 23 | used to endorse or promote products derived from this software | |
| 24 | without specific prior written permission. | |
| 25 | ||
| 26 | THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR | |
| 27 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 28 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 29 | DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, | |
| 30 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 31 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
| 32 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 33 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
| 34 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
| 35 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| 36 | POSSIBILITY OF SUCH DAMAGE. | |
| 37 | ||
| 38 | ***************************************************************************/ | |
| 39 | ||
| 40 | #ifndef __M7501_H__ | |
| 41 | #define __M7501_H__ | |
| 42 | ||
| 43 | #include "m6510.h" | |
| 44 | ||
| 45 | #define MCFG_M7501_PORT_CALLBACKS(_read, _write) \ | |
| 46 | downcast<m7501_device *>(device)->set_callbacks(DEVCB2_##_read, DEVCB2_##_write); | |
| 47 | ||
| 48 | #define MCFG_M7501_PORT_PULLS(_up, _down) \ | |
| 49 | downcast<m7501_device *>(device)->set_pulls(_up, _down); | |
| 50 | ||
| 51 | class m7501_device : public m6510_device { | |
| 52 | public: | |
| 53 | m7501_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 54 | }; | |
| 55 | ||
| 56 | enum { | |
| 57 | M7501_IRQ_LINE = m6502_device::IRQ_LINE, | |
| 58 | M7501_NMI_LINE = m6502_device::NMI_LINE, | |
| 59 | }; | |
| 60 | ||
| 61 | extern const device_type M7501; | |
| 62 | ||
| 63 | #endif |
| r18874 | r18875 | |
|---|---|---|
| 1 | # 6509 opcodes | |
| 2 | ||
| 3 | lda_9_idy | |
| 4 | TMP2 = read_pc(); | |
| 5 | TMP = read(TMP2); | |
| 6 | TMP = set_h(TMP, read(TMP2+1)); | |
| 7 | if(page_changing(TMP, Y)) { | |
| 8 | read_9(set_l(TMP, TMP+Y)); | |
| 9 | } | |
| 10 | A = read_9(TMP+Y); | |
| 11 | set_nz(A); | |
| 12 | prefetch(); | |
| 13 | ||
| 14 | sta_9_idy | |
| 15 | TMP2 = read_pc(); | |
| 16 | TMP = read(TMP2); | |
| 17 | TMP = set_h(TMP, read(TMP2+1)); | |
| 18 | read_9(set_l(TMP, TMP+Y)); | |
| 19 | write_9(TMP+Y, A); | |
| 20 | prefetch(); |
| r18874 | r18875 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * m65ce02.c | |
| 4 | * Portable 65ce02 emulator V1.0beta3 | |
| 5 | * | |
| 6 | * Copyright Peter Trauner, all rights reserved | |
| 7 | * documentation preliminary databook | |
| 8 | * documentation by michael steil mist@c64.org | |
| 9 | * available at ftp://ftp.funet.fi/pub/cbm/c65 | |
| 10 | * | |
| 11 | * - This source code is released as freeware for non-commercial purposes. | |
| 12 | * - You are free to use and redistribute this code in modified or | |
| 13 | * unmodified form, provided you list me in the credits. | |
| 14 | * - If you modify this source code, you must add a notice to each modified | |
| 15 | * source file that it has been changed. If you're a nice person, you | |
| 16 | * will clearly mark each change too. :) | |
| 17 | * - If you wish to use this for commercial purposes, please contact me at | |
| 18 | * pullmoll@t-online.de | |
| 19 | * - The author of this copywritten work reserves the right to change the | |
| 20 | * terms of its usage and license at any time, including retroactively | |
| 21 | * - This entire notice must remain in the source code. | |
| 22 | * | |
| 23 | *****************************************************************************/ | |
| 24 | /* 4. February 2000 PeT fixed relative word operand */ | |
| 25 | /* 4. February 2000 PeT jsr (absolut) jsr (absolut,x) inw dew */ | |
| 26 | /* 17.February 2000 PeT phw */ | |
| 27 | /* 16.March 2000 PeT fixed some instructions accordingly to databook */ | |
| 28 | /* 7. May 2000 PeT splittet into m65ce02 and m4510 */ | |
| 1 | /*************************************************************************** | |
| 29 | 2 | |
| 30 | ||
| 3 | m65ce02.c | |
| 31 | 4 | |
| 32 | ||
| 5 | 6502 with Z register and some more stuff | |
| 33 | 6 | |
| 34 | * | |
| 7 | **************************************************************************** | |
| 35 | 8 | |
| 36 | * tys txs not interruptable, not implemented | |
| 9 | Copyright Olivier Galibert | |
| 10 | All rights reserved. | |
| 37 | 11 | |
| 38 | */ | |
| 12 | Redistribution and use in source and binary forms, with or without | |
| 13 | modification, are permitted provided that the following conditions are | |
| 14 | met: | |
| 39 | 15 | |
| 40 | #include "emu.h" | |
| 41 | #include "debugger.h" | |
| 42 | #include "m65ce02.h" | |
| 16 | * Redistributions of source code must retain the above copyright | |
| 17 | notice, this list of conditions and the following disclaimer. | |
| 18 | * Redistributions in binary form must reproduce the above copyright | |
| 19 | notice, this list of conditions and the following disclaimer in | |
| 20 | the documentation and/or other materials provided with the | |
| 21 | distribution. | |
| 22 | * Neither the name 'MAME' nor the names of its contributors may be | |
| 23 | used to endorse or promote products derived from this software | |
| 24 | without specific prior written permission. | |
| 43 | 25 | |
| 44 | #include "mincce02.h" | |
| 45 | #include "opsce02.h" | |
| 26 | THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR | |
| 27 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 28 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 29 | DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, | |
| 30 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 31 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
| 32 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 33 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
| 34 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
| 35 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| 36 | POSSIBILITY OF SUCH DAMAGE. | |
| 46 | 37 | |
| 47 | #define M6502_NMI_VEC 0xfffa | |
| 48 | #define M6502_RST_VEC 0xfffc | |
| 49 | #define M6502_IRQ_VEC 0xfffe | |
| 50 | #define M65CE02_RST_VEC M6502_RST_VEC | |
| 51 | #define M65CE02_IRQ_VEC M6502_IRQ_VEC | |
| 52 | #define M65CE02_NMI_VEC M6502_NMI_VEC | |
| 38 | ***************************************************************************/ | |
| 53 | 39 | |
| 54 | #define VERBOSE 0 | |
| 40 | #include "emu.h" | |
| 41 | #include "m65ce02.h" | |
| 55 | 42 | |
| 56 | ||
| 43 | const device_type M65CE02 = &device_creator<m65ce02_device>; | |
| 57 | 44 | |
| 58 | struct m65ce02_Regs { | |
| 59 | void (*const *insn)(m65ce02_Regs *); /* pointer to the function pointer table */ | |
| 60 | PAIR ppc; /* previous program counter */ | |
| 61 | PAIR pc; /* program counter */ | |
| 62 | PAIR sp; /* stack pointer (always 100 - 1FF) */ | |
| 63 | PAIR zp; /* zero page address */ | |
| 64 | /* contains B register zp.b.h */ | |
| 65 | PAIR ea; /* effective address */ | |
| 66 | UINT8 a; /* Accumulator */ | |
| 67 | UINT8 x; /* X index register */ | |
| 68 | UINT8 y; /* Y index register */ | |
| 69 | UINT8 z; /* Z index register */ | |
| 70 | UINT8 p; /* Processor status */ | |
| 71 | UINT8 pending_irq; /* nonzero if an IRQ is pending */ | |
| 72 | UINT8 after_cli; /* pending IRQ and last insn cleared I */ | |
| 73 | UINT8 nmi_state; | |
| 74 | UINT8 irq_state; | |
| 75 | int icount; | |
| 76 | device_irq_acknowledge_callback irq_callback; | |
| 77 | legacy_cpu_device *device; | |
| 78 | address_space *space; | |
| 79 | direct_read_data *direct; | |
| 80 | devcb_resolved_read8 rdmem_id; /* readmem callback for indexed instructions */ | |
| 81 | devcb_resolved_write8 wrmem_id; /* writemem callback for indexed instructions */ | |
| 82 | }; | |
| 83 | ||
| 84 | INLINE m65ce02_Regs *get_safe_token(device_t *device) | |
| 45 | m65ce02_device::m65ce02_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : | |
| 46 | m65c02_device(mconfig, M65CE02, "M65CE02", tag, owner, clock) | |
| 85 | 47 | { |
| 86 | assert(device != NULL); | |
| 87 | assert(device->type() == M65CE02); | |
| 88 | return (m65ce02_Regs *)downcast<legacy_cpu_device *>(device)->token(); | |
| 89 | 48 | } |
| 90 | 49 | |
| 91 | /*************************************************************** | |
| 92 | * include the opcode macros, functions and tables | |
| 93 | ***************************************************************/ | |
| 94 | ||
| 95 | #include "t65ce02.c" | |
| 96 | ||
| 97 | static CPU_INIT( m65ce02 ) | |
| 50 | m65ce02_device::m65ce02_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) : | |
| 51 | m65c02_device(mconfig, type, name, tag, owner, clock) | |
| 98 | 52 | { |
| 99 | m65ce02_Regs *cpustate = get_safe_token(device); | |
| 100 | const m6502_interface *intf = (const m6502_interface *)device->static_config(); | |
| 101 | ||
| 102 | cpustate->irq_callback = irqcallback; | |
| 103 | cpustate->device = device; | |
| 104 | cpustate->space = &device->space(AS_PROGRAM); | |
| 105 | cpustate->direct = &cpustate->space->direct(); | |
| 106 | ||
| 107 | if ( intf ) | |
| 108 | { | |
| 109 | cpustate->rdmem_id.resolve(intf->read_indexed_func, *device); | |
| 110 | cpustate->wrmem_id.resolve(intf->write_indexed_func, *device); | |
| 111 | } | |
| 112 | else | |
| 113 | { | |
| 114 | devcb_read8 nullrcb = DEVCB_NULL; | |
| 115 | devcb_write8 nullwcb = DEVCB_NULL; | |
| 116 | ||
| 117 | cpustate->rdmem_id.resolve(nullrcb, *device); | |
| 118 | cpustate->wrmem_id.resolve(nullwcb, *device); | |
| 119 | } | |
| 120 | 53 | } |
| 121 | 54 | |
| 122 | sta | |
| 55 | offs_t m65ce02_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) | |
| 123 | 56 | { |
| 124 | m65ce02_Regs *cpustate = get_safe_token(device); | |
| 125 | ||
| 126 | cpustate->insn = insn65ce02; | |
| 127 | ||
| 128 | /* wipe out the rest of the m65ce02 structure */ | |
| 129 | /* read the reset vector into PC */ | |
| 130 | /* reset z index and b bank */ | |
| 131 | PCL = RDMEM(M65CE02_RST_VEC); | |
| 132 | PCH = RDMEM(M65CE02_RST_VEC+1); | |
| 133 | ||
| 134 | /* after reset in 6502 compatibility mode */ | |
| 135 | cpustate->sp.d = 0x01ff; /* high byte descriped in databook */ | |
| 136 | cpustate->z = 0; | |
| 137 | B = 0; | |
| 138 | cpustate->p = F_E|F_B|F_I|F_Z; /* set E, I and Z flags */ | |
| 139 | cpustate->pending_irq = 0; /* nonzero if an IRQ is pending */ | |
| 140 | cpustate->after_cli = 0; /* pending IRQ and last insn cleared I */ | |
| 141 | cpustate->irq_callback = NULL; | |
| 57 | return disassemble_generic(buffer, pc, oprom, opram, options, disasm_entries); | |
| 142 | 58 | } |
| 143 | 59 | |
| 144 | ||
| 60 | void m65ce02_device::init() | |
| 145 | 61 | { |
| 146 | /* nothing to do yet */ | |
| 62 | m65c02_device::init(); | |
| 63 | state_add(M65CE02_Z, "Z", Z); | |
| 64 | state_add(M65CE02_B, "B", B).callimport().formatstr("%2s"); | |
| 65 | save_item(NAME(B)); | |
| 66 | save_item(NAME(Z)); | |
| 67 | save_item(NAME(TMP3)); | |
| 68 | Z = 0x00; | |
| 69 | B = 0x0000; | |
| 70 | TMP3 = 0x0000; | |
| 147 | 71 | } |
| 148 | 72 | |
| 149 | ||
| 73 | void m65ce02_device::device_start() | |
| 150 | 74 | { |
| 151 | if( !(P & F_I) ) | |
| 152 | { | |
| 153 | EAD = M65CE02_IRQ_VEC; | |
| 154 | cpustate->icount -= 7; | |
| 155 | PUSH(PCH); | |
| 156 | PUSH(PCL); | |
| 157 | PUSH(P & ~F_B); | |
| 158 | P = (P & ~F_D) | F_I; /* knock out D and set I flag */ | |
| 159 | PCL = RDMEM(EAD); | |
| 160 | PCH = RDMEM(EAD+1); | |
| 161 | LOG(("M65ce02 '%s' takes IRQ ($%04x)\n", cpustate->device->tag(), PCD)); | |
| 162 | /* call back the cpuintrf to let it clear the line */ | |
| 163 | if (cpustate->irq_callback) (*cpustate->irq_callback)(cpustate->device, 0); | |
| 164 | } | |
| 165 | cpustate->pending_irq = 0; | |
| 75 | if(direct_disabled) | |
| 76 | mintf = new mi_default_nd; | |
| 77 | else | |
| 78 | mintf = new mi_default_normal; | |
| 79 | ||
| 80 | init(); | |
| 166 | 81 | } |
| 167 | 82 | |
| 168 | ||
| 83 | void m65ce02_device::device_reset() | |
| 169 | 84 | { |
| 170 | m65ce02_Regs *cpustate = get_safe_token(device); | |
| 171 | ||
| 172 | do | |
| 173 | { | |
| 174 | UINT8 op; | |
| 175 | PPC = PCD; | |
| 176 | ||
| 177 | debugger_instruction_hook(device, PCD); | |
| 178 | ||
| 179 | /* if an irq is pending, take it now */ | |
| 180 | if( cpustate->pending_irq ) | |
| 181 | m65ce02_take_irq(cpustate); | |
| 182 | ||
| 183 | op = RDOP(); | |
| 184 | (*insn65ce02[op])(cpustate); | |
| 185 | ||
| 186 | /* check if the I flag was just reset (interrupts enabled) */ | |
| 187 | if( cpustate->after_cli ) | |
| 188 | { | |
| 189 | LOG(("M65ce02 '%s' after_cli was >0", cpustate->device->tag())); | |
| 190 | cpustate->after_cli = 0; | |
| 191 | if (cpustate->irq_state != CLEAR_LINE) | |
| 192 | { | |
| 193 | LOG((": irq line is asserted: set pending IRQ\n")); | |
| 194 | cpustate->pending_irq = 1; | |
| 195 | } | |
| 196 | else | |
| 197 | { | |
| 198 | LOG((": irq line is clear\n")); | |
| 199 | } | |
| 200 | } | |
| 201 | else | |
| 202 | if( cpustate->pending_irq ) | |
| 203 | m65ce02_take_irq(cpustate); | |
| 204 | ||
| 205 | } while (cpustate->icount > 0); | |
| 85 | m65c02_device::device_reset(); | |
| 86 | Z = 0x00; | |
| 87 | B = 0x0000; | |
| 206 | 88 | } |
| 207 | 89 | |
| 208 | ||
| 90 | void m65ce02_device::state_import(const device_state_entry &entry) | |
| 209 | 91 | { |
| 210 | if (irqline == INPUT_LINE_NMI) | |
| 211 | { | |
| 212 | if (cpustate->nmi_state == state) return; | |
| 213 | cpustate->nmi_state = state; | |
| 214 | if( state != CLEAR_LINE ) | |
| 215 | { | |
| 216 | LOG(("M65ce02 '%s' set_nmi_line(ASSERT)\n", cpustate->device->tag())); | |
| 217 | EAD = M65CE02_NMI_VEC; | |
| 218 | cpustate->icount -= 7; | |
| 219 | PUSH(PCH); | |
| 220 | PUSH(PCL); | |
| 221 | PUSH(P & ~F_B); | |
| 222 | P = (P & ~F_D) | F_I; /* knock out D and set I flag */ | |
| 223 | PCL = RDMEM(EAD); | |
| 224 | PCH = RDMEM(EAD+1); | |
| 225 | LOG(("M65ce02 '%s' takes NMI ($%04x)\n", cpustate->device->tag(), PCD)); | |
| 226 | } | |
| 92 | switch(entry.index()) { | |
| 93 | case STATE_GENFLAGS: | |
| 94 | case M6502_P: | |
| 95 | P = P | F_B; | |
| 96 | break; | |
| 97 | case M65CE02_B: | |
| 98 | B <<= 8; | |
| 99 | break; | |
| 227 | 100 | } |
| 228 | else | |
| 229 | { | |
| 230 | cpustate->irq_state = state; | |
| 231 | if( state != CLEAR_LINE ) | |
| 232 | { | |
| 233 | LOG(("M65ce02 '%s' set_irq_line(ASSERT)\n", cpustate->device->tag())); | |
| 234 | cpustate->pending_irq = 1; | |
| 235 | } | |
| 236 | } | |
| 237 | 101 | } |
| 238 | 102 | |
| 239 | /************************************************************************** | |
| 240 | * Generic set_info | |
| 241 | **************************************************************************/ | |
| 242 | ||
| 243 | static CPU_SET_INFO( m65ce02 ) | |
| 103 | void m65ce02_device::state_export(const device_state_entry &entry) | |
| 244 | 104 | { |
| 245 | m65ce02_Regs *cpustate = get_safe_token(device); | |
| 246 | ||
| 247 | switch( state ) | |
| 248 | { | |
| 249 | /* --- the following bits of info are set as 64-bit signed integers --- */ | |
| 250 | case CPUINFO_INT_INPUT_STATE + M65CE02_IRQ_STATE: m65ce02_set_irq_line( cpustate, M65CE02_IRQ_LINE, info->i ); break; | |
| 251 | case CPUINFO_INT_INPUT_STATE + M65CE02_NMI_STATE: m65ce02_set_irq_line( cpustate, INPUT_LINE_NMI, info->i ); break; | |
| 252 | ||
| 253 | case CPUINFO_INT_PC: PCW = info->i; break; | |
| 254 | case CPUINFO_INT_REGISTER + M65CE02_PC: cpustate->pc.w.l = info->i; break; | |
| 255 | case CPUINFO_INT_SP: cpustate->sp.b.l = info->i; break; | |
| 256 | case CPUINFO_INT_REGISTER + M65CE02_S: cpustate->sp.w.l = info->i; break; | |
| 257 | case CPUINFO_INT_REGISTER + M65CE02_P: cpustate->p = info->i; break; | |
| 258 | case CPUINFO_INT_REGISTER + M65CE02_A: cpustate->a = info->i; break; | |
| 259 | case CPUINFO_INT_REGISTER + M65CE02_X: cpustate->x = info->i; break; | |
| 260 | case CPUINFO_INT_REGISTER + M65CE02_Y: cpustate->y = info->i; break; | |
| 261 | case CPUINFO_INT_REGISTER + M65CE02_Z: cpustate->z = info->i; break; | |
| 262 | case CPUINFO_INT_REGISTER + M65CE02_B: cpustate->zp.b.h = info->i; break; | |
| 263 | case CPUINFO_INT_REGISTER + M65CE02_EA: cpustate->ea.w.l = info->i; break; | |
| 264 | case CPUINFO_INT_REGISTER + M65CE02_ZP: cpustate->zp.b.l = info->i; break; | |
| 265 | } | |
| 266 | 105 | } |
| 267 | 106 | |
| 268 | /************************************************************************** | |
| 269 | * Generic get_info | |
| 270 | **************************************************************************/ | |
| 271 | ||
| 272 | CPU_GET_INFO( m65ce02 ) | |
| 107 | void m65ce02_device::state_string_export(const device_state_entry &entry, astring &string) | |
| 273 | 108 | { |
| 274 | m65ce02_Regs *cpustate = (device != NULL && device->token() != NULL) ? get_safe_token(device) : NULL; | |
| 275 | ||
| 276 | switch( state ) | |
| 277 | { | |
| 278 | /* --- the following bits of info are returned as 64-bit signed integers --- */ | |
| 279 | case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(m65ce02_Regs); break; | |
| 280 | case CPUINFO_INT_INPUT_LINES: info->i = 2; break; | |
| 281 | case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0; break; | |
| 282 | case CPUINFO_INT_ENDIANNESS: info->i = ENDIANNESS_LITTLE; break; | |
| 283 | case CPUINFO_INT_CLOCK_MULTIPLIER: info->i = 1; break; | |
| 284 | case CPUINFO_INT_CLOCK_DIVIDER: info->i = 1; break; | |
| 285 | case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 1; break; | |
| 286 | case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 3; break; | |
| 287 | case CPUINFO_INT_MIN_CYCLES: info->i = 1; break; | |
| 288 | case CPUINFO_INT_MAX_CYCLES: info->i = 10; break; | |
| 289 | ||
| 290 | case CPUINFO_INT_DATABUS_WIDTH + AS_PROGRAM: info->i = 8; break; | |
| 291 | case CPUINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 20; break; | |
| 292 | case CPUINFO_INT_ADDRBUS_SHIFT + AS_PROGRAM: info->i = 0; break; | |
| 293 | case CPUINFO_INT_LOGADDR_WIDTH_PROGRAM: info->i = 16; break; | |
| 294 | case CPUINFO_INT_PAGE_SHIFT_PROGRAM: info->i = 13; break; | |
| 295 | case CPUINFO_INT_DATABUS_WIDTH + AS_DATA: info->i = 0; break; | |
| 296 | case CPUINFO_INT_ADDRBUS_WIDTH + AS_DATA: info->i = 0; break; | |
| 297 | case CPUINFO_INT_ADDRBUS_SHIFT + AS_DATA: info->i = 0; break; | |
| 298 | case CPUINFO_INT_DATABUS_WIDTH + AS_IO: info->i = 0; break; | |
| 299 | case CPUINFO_INT_ADDRBUS_WIDTH + AS_IO: info->i = 0; break; | |
| 300 | case CPUINFO_INT_ADDRBUS_SHIFT + AS_IO: info->i = 0; break; | |
| 301 | ||
| 302 | case CPUINFO_INT_INPUT_STATE+M65CE02_NMI_STATE: info->i = cpustate->nmi_state; break; | |
| 303 | case CPUINFO_INT_INPUT_STATE+M65CE02_IRQ_STATE: info->i = cpustate->irq_state; break; | |
| 304 | ||
| 305 | case CPUINFO_INT_PREVIOUSPC: info->i = cpustate->ppc.w.l; break; | |
| 306 | ||
| 307 | case CPUINFO_INT_PC: info->i = PCD; break; | |
| 308 | case CPUINFO_INT_REGISTER+M65CE02_PC: info->i = cpustate->pc.w.l; break; | |
| 309 | case CPUINFO_INT_SP: info->i = cpustate->sp.b.l; break; | |
| 310 | case CPUINFO_INT_REGISTER+M65CE02_S: info->i = cpustate->sp.w.l; break; | |
| 311 | case CPUINFO_INT_REGISTER+M65CE02_P: info->i = cpustate->p; break; | |
| 312 | case CPUINFO_INT_REGISTER+M65CE02_A: info->i = cpustate->a; break; | |
| 313 | case CPUINFO_INT_REGISTER+M65CE02_X: info->i = cpustate->x; break; | |
| 314 | case CPUINFO_INT_REGISTER+M65CE02_Y: info->i = cpustate->y; break; | |
| 315 | case CPUINFO_INT_REGISTER+M65CE02_Z: info->i = cpustate->z; break; | |
| 316 | case CPUINFO_INT_REGISTER+M65CE02_B: info->i = cpustate->zp.b.h; break; | |
| 317 | case CPUINFO_INT_REGISTER+M65CE02_EA: info->i = cpustate->ea.w.l; break; | |
| 318 | case CPUINFO_INT_REGISTER+M65CE02_ZP: info->i = cpustate->zp.w.l; break; | |
| 319 | ||
| 320 | /* --- the following bits of info are returned as pointers to data or functions --- */ | |
| 321 | case CPUINFO_FCT_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(m65ce02); break; | |
| 322 | case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(m65ce02); break; | |
| 323 | case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(m65ce02); break; | |
| 324 | case CPUINFO_FCT_EXIT: info->exit = CPU_EXIT_NAME(m65ce02); break; | |
| 325 | case CPUINFO_FCT_EXECUTE: info->execute = CPU_EXECUTE_NAME(m65ce02); break; | |
| 326 | case CPUINFO_FCT_BURN: info->burn = NULL; break; | |
| 327 | case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(m65ce02); break; | |
| 328 | case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &cpustate->icount; break; | |
| 329 | ||
| 330 | /* --- the following bits of info are returned as NULL-terminated strings --- */ | |
| 331 | case CPUINFO_STR_NAME: strcpy(info->s, "M65CE02"); break; | |
| 332 | case CPUINFO_STR_FAMILY: strcpy(info->s,"CBM Semiconductor Group CSG 65CE02"); break; | |
| 333 | case CPUINFO_STR_VERSION: strcpy(info->s,"1.0beta"); break; | |
| 334 | case CPUINFO_STR_SOURCE_FILE: strcpy(info->s,__FILE__); | |
| 335 | case CPUINFO_STR_CREDITS: | |
| 336 | strcpy(info->s, "Copyright Juergen Buchmueller\n" | |
| 337 | "Copyright Peter Trauner\n" | |
| 338 | "all rights reserved."); break; | |
| 339 | case CPUINFO_STR_FLAGS: | |
| 340 | sprintf(info->s, "%c%c%c%c%c%c%c%c", | |
| 341 | cpustate->p & 0x80 ? 'N':'.', | |
| 342 | cpustate->p & 0x40 ? 'V':'.', | |
| 343 | cpustate->p & 0x20 ? 'E':'.', | |
| 344 | cpustate->p & 0x10 ? 'B':'.', | |
| 345 | cpustate->p & 0x08 ? 'D':'.', | |
| 346 | cpustate->p & 0x04 ? 'I':'.', | |
| 347 | cpustate->p & 0x02 ? 'Z':'.', | |
| 348 | cpustate->p & 0x01 ? 'C':'.'); | |
| 349 | break; | |
| 350 | ||
| 351 | case CPUINFO_STR_REGISTER + M65CE02_PC: sprintf(info->s, "PC:%04X", cpustate->pc.w.l); break; | |
| 352 | case CPUINFO_STR_REGISTER + M65CE02_S: sprintf(info->s, "S:%02X", cpustate->sp.b.l); break; | |
| 353 | case CPUINFO_STR_REGISTER + M65CE02_P: sprintf(info->s, "P:%02X", cpustate->p); break; | |
| 354 | case CPUINFO_STR_REGISTER + M65CE02_A: sprintf(info->s, "A:%02X", cpustate->a); break; | |
| 355 | case CPUINFO_STR_REGISTER + M65CE02_X: sprintf(info->s, "X:%02X", cpustate->x); break; | |
| 356 | case CPUINFO_STR_REGISTER + M65CE02_Y: sprintf(info->s, "Y:%02X", cpustate->y); break; | |
| 357 | case CPUINFO_STR_REGISTER + M65CE02_Z: sprintf(info->s, "Z:%02X", cpustate->z); break; | |
| 358 | case CPUINFO_STR_REGISTER + M65CE02_B: sprintf(info->s, "B:%02X", cpustate->zp.b.h); break; | |
| 359 | case CPUINFO_STR_REGISTER + M65CE02_EA: sprintf(info->s, "EA:%04X", cpustate->ea.w.l); break; | |
| 360 | case CPUINFO_STR_REGISTER + M65CE02_ZP: sprintf(info->s, "ZP:%03X", cpustate->zp.w.l); break; | |
| 109 | switch(entry.index()) { | |
| 110 | case STATE_GENFLAGS: | |
| 111 | case M6502_P: | |
| 112 | string.printf("%c%c%c%c%c%c%c", | |
| 113 | P & F_N ? 'N' : '.', | |
| 114 | P & F_V ? 'V' : '.', | |
| 115 | P & F_E ? 'E' : '.', | |
| 116 | P & F_D ? 'D' : '.', | |
| 117 | P & F_I ? 'I' : '.', | |
| 118 | P & F_Z ? 'Z' : '.', | |
| 119 | P & F_C ? 'C' : '.'); | |
| 120 | break; | |
| 121 | case M65CE02_B: | |
| 122 | string.printf("%02x", B >> 8); | |
| 123 | break; | |
| 361 | 124 | } |
| 362 | 125 | } |
| 363 | 126 | |
| 364 | ||
| 127 | #include "cpu/m6502/m65ce02.inc" |
| r18874 | r18875 | |
|---|---|---|
| 1 | /*************************************************************************** | |
| 2 | ||
| 3 | m65c02.h | |
| 4 | ||
| 5 | Mostek 6502, CMOS variant with some additional instructions (but | |
| 6 | not the bitwise ones) | |
| 7 | ||
| 8 | **************************************************************************** | |
| 9 | ||
| 10 | Copyright Olivier Galibert | |
| 11 | All rights reserved. | |
| 12 | ||
| 13 | Redistribution and use in source and binary forms, with or without | |
| 14 | modification, are permitted provided that the following conditions are | |
| 15 | met: | |
| 16 | ||
| 17 | * Redistributions of source code must retain the above copyright | |
| 18 | notice, this list of conditions and the following disclaimer. | |
| 19 | * Redistributions in binary form must reproduce the above copyright | |
| 20 | notice, this list of conditions and the following disclaimer in | |
| 21 | the documentation and/or other materials provided with the | |
| 22 | distribution. | |
| 23 | * Neither the name 'MAME' nor the names of its contributors may be | |
| 24 | used to endorse or promote products derived from this software | |
| 25 | without specific prior written permission. | |
| 26 | ||
| 27 | THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR | |
| 28 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 29 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 30 | DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, | |
| 31 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 32 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
| 33 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 34 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
| 35 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
| 36 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| 37 | POSSIBILITY OF SUCH DAMAGE. | |
| 38 | ||
| 39 | ***************************************************************************/ | |
| 40 | ||
| 41 | #ifndef __M65C02_H__ | |
| 42 | #define __M65C02_H__ | |
| 43 | ||
| 44 | #include "m6502.h" | |
| 45 | ||
| 46 | class m65c02_device : public m6502_device { | |
| 47 | public: | |
| 48 | m65c02_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 49 | m65c02_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock); | |
| 50 | ||
| 51 | static const disasm_entry disasm_entries[0x100]; | |
| 52 | ||
| 53 | virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options); | |
| 54 | virtual void do_exec_full(); | |
| 55 | virtual void do_exec_partial(); | |
| 56 | ||
| 57 | protected: | |
| 58 | #define O(o) void o ## _full(); void o ## _partial() | |
| 59 | ||
| 60 | // 65c02 opcodes | |
| 61 | O(adc_c_aba); O(adc_c_abx); O(adc_c_aby); O(adc_c_idx); O(adc_c_idy); O(adc_c_imm); O(adc_c_zpg); O(adc_c_zpi); O(adc_c_zpx); | |
| 62 | O(and_zpi); | |
| 63 | O(asl_c_abx); | |
| 64 | O(bbr_zpb); | |
| 65 | O(bbs_zpb); | |
| 66 | O(bit_abx); O(bit_imm); O(bit_zpx); | |
| 67 | O(bra_rel); | |
| 68 | O(brk_c_imp); | |
| 69 | O(cmp_zpi); | |
| 70 | O(dec_acc); | |
| 71 | O(eor_zpi); | |
| 72 | O(inc_acc); | |
| 73 | O(jmp_c_ind); O(jmp_iax); | |
| 74 | O(lda_zpi); | |
| 75 | O(lsr_c_abx); | |
| 76 | O(nop_c_aba); O(nop_c_abx); O(nop_c_imp); | |
| 77 | O(ora_zpi); | |
| 78 | O(phx_imp); | |
| 79 | O(phy_imp); | |
| 80 | O(plx_imp); | |
| 81 | O(ply_imp); | |
| 82 | O(rmb_bzp); | |
| 83 | O(rol_c_abx); | |
| 84 | O(ror_c_abx); | |
| 85 | O(sbc_c_aba); O(sbc_c_abx); O(sbc_c_aby); O(sbc_c_idx); O(sbc_c_idy); O(sbc_c_imm); O(sbc_c_zpg); O(sbc_c_zpi); O(sbc_c_zpx); | |
| 86 | O(smb_bzp); | |
| 87 | O(stp_imp); | |
| 88 | O(sta_zpi); | |
| 89 | O(stz_aba); O(stz_abx); O(stz_zpg); O(stz_zpx); | |
| 90 | O(trb_aba); O(trb_zpg); | |
| 91 | O(tsb_aba); O(tsb_zpg); | |
| 92 | O(wai_imp); | |
| 93 | ||
| 94 | #undef O | |
| 95 | }; | |
| 96 | ||
| 97 | enum { | |
| 98 | M65C02_IRQ_LINE = m6502_device::IRQ_LINE, | |
| 99 | M65C02_NMI_LINE = m6502_device::NMI_LINE, | |
| 100 | M65C02_SET_OVERFLOW = m6502_device::V_LINE, | |
| 101 | }; | |
| 102 | ||
| 103 | extern const device_type M65C02; | |
| 104 | ||
| 105 | #endif |
| r18874 | r18875 | |
|---|---|---|
| 1 | /*************************************************************************** | |
| 2 | ||
| 3 | m6502.c | |
| 4 | ||
| 5 | 6502, NES variant | |
| 6 | ||
| 7 | **************************************************************************** | |
| 8 | ||
| 9 | Copyright Olivier Galibert | |
| 10 | All rights reserved. | |
| 11 | ||
| 12 | Redistribution and use in source and binary forms, with or without | |
| 13 | modification, are permitted provided that the following conditions are | |
| 14 | met: | |
| 15 | ||
| 16 | * Redistributions of source code must retain the above copyright | |
| 17 | notice, this list of conditions and the following disclaimer. | |
| 18 | * Redistributions in binary form must reproduce the above copyright | |
| 19 | notice, this list of conditions and the following disclaimer in | |
| 20 | the documentation and/or other materials provided with the | |
| 21 | distribution. | |
| 22 | * Neither the name 'MAME' nor the names of its contributors may be | |
| 23 | used to endorse or promote products derived from this software | |
| 24 | without specific prior written permission. | |
| 25 | ||
| 26 | THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR | |
| 27 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 28 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 29 | DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, | |
| 30 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 31 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
| 32 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 33 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
| 34 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
| 35 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| 36 | POSSIBILITY OF SUCH DAMAGE. | |
| 37 | ||
| 38 | ***************************************************************************/ | |
| 39 | ||
| 40 | #include "emu.h" | |
| 41 | #include "n2a03.h" | |
| 42 | ||
| 43 | const device_type N2A03 = &device_creator<n2a03_device>; | |
| 44 | ||
| 45 | n2a03_device::n2a03_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : | |
| 46 | m6502_device(mconfig, N2A03, "N2A03", tag, owner, clock) | |
| 47 | { | |
| 48 | } | |
| 49 | ||
| 50 | offs_t n2a03_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) | |
| 51 | { | |
| 52 | return disassemble_generic(buffer, pc, oprom, opram, options, disasm_entries); | |
| 53 | } | |
| 54 | ||
| 55 | void n2a03_device::device_start() | |
| 56 | { | |
| 57 | if(direct_disabled) | |
| 58 | mintf = new mi_2a03_nd; | |
| 59 | else | |
| 60 | mintf = new mi_2a03_normal; | |
| 61 | ||
| 62 | init(); | |
| 63 | } | |
| 64 | ||
| 65 | UINT8 n2a03_device::mi_2a03_normal::read(UINT16 adr) | |
| 66 | { | |
| 67 | return program->read_byte(adr); | |
| 68 | } | |
| 69 | ||
| 70 | UINT8 n2a03_device::mi_2a03_normal::read_direct(UINT16 adr) | |
| 71 | { | |
| 72 | return direct->read_raw_byte(adr); | |
| 73 | } | |
| 74 | ||
| 75 | UINT8 n2a03_device::mi_2a03_normal::read_decrypted(UINT16 adr) | |
| 76 | { | |
| 77 | return direct->read_decrypted_byte(adr); | |
| 78 | } | |
| 79 | ||
| 80 | void n2a03_device::mi_2a03_normal::write(UINT16 adr, UINT8 val) | |
| 81 | { | |
| 82 | program->write_byte(adr, val); | |
| 83 | } | |
| 84 | ||
| 85 | UINT8 n2a03_device::mi_2a03_nd::read(UINT16 adr) | |
| 86 | { | |
| 87 | return program->read_byte(adr); | |
| 88 | } | |
| 89 | ||
| 90 | UINT8 n2a03_device::mi_2a03_nd::read_direct(UINT16 adr) | |
| 91 | { | |
| 92 | return program->read_byte(adr); | |
| 93 | } | |
| 94 | ||
| 95 | UINT8 n2a03_device::mi_2a03_nd::read_decrypted(UINT16 adr) | |
| 96 | { | |
| 97 | return program->read_byte(adr); | |
| 98 | } | |
| 99 | ||
| 100 | void n2a03_device::mi_2a03_nd::write(UINT16 adr, UINT8 val) | |
| 101 | { | |
| 102 | program->write_byte(adr, val); | |
| 103 | } | |
| 104 | ||
| 105 | #include "cpu/m6502/n2a03.inc" |
| r18874 | r18875 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * m65ce02.c | |
| 4 | * Portable 65ce02 emulator V1.0beta | |
| 5 | * | |
| 6 | * Copyright Peter Trauner, all rights reserved. | |
| 7 | * | |
| 8 | * - This source code is released as freeware for non-commercial purposes. | |
| 9 | * - You are free to use and redistribute this code in modified or | |
| 10 | * unmodified form, provided you list me in the credits. | |
| 11 | * - If you modify this source code, you must add a notice to each modified | |
| 12 | * source file that it has been changed. If you're a nice person, you | |
| 13 | * will clearly mark each change too. :) | |
| 14 | * - If you wish to use this for commercial purposes, please contact me at | |
| 15 | * pullmoll@t-online.de | |
| 16 | * - The author of this copywritten work reserves the right to change the | |
| 17 | * terms of its usage and license at any time, including retroactively | |
| 18 | * - This entire notice must remain in the source code. | |
| 19 | * | |
| 20 | *****************************************************************************/ | |
| 1 | /*************************************************************************** | |
| 21 | 2 | |
| 22 | ||
| 3 | m65ce02.h | |
| 23 | 4 | |
| 5 | 6502 with Z register and some more stuff | |
| 6 | ||
| 7 | **************************************************************************** | |
| 8 | ||
| 9 | Copyright Olivier Galibert | |
| 10 | All rights reserved. | |
| 11 | ||
| 12 | Redistribution and use in source and binary forms, with or without | |
| 13 | modification, are permitted provided that the following conditions are | |
| 14 | met: | |
| 15 | ||
| 16 | * Redistributions of source code must retain the above copyright | |
| 17 | notice, this list of conditions and the following disclaimer. | |
| 18 | * Redistributions in binary form must reproduce the above copyright | |
| 19 | notice, this list of conditions and the following disclaimer in | |
| 20 | the documentation and/or other materials provided with the | |
| 21 | distribution. | |
| 22 | * Neither the name 'MAME' nor the names of its contributors may be | |
| 23 | used to endorse or promote products derived from this software | |
| 24 | without specific prior written permission. | |
| 25 | ||
| 26 | THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR | |
| 27 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 28 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 29 | DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, | |
| 30 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 31 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
| 32 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 33 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
| 34 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
| 35 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| 36 | POSSIBILITY OF SUCH DAMAGE. | |
| 37 | ||
| 38 | ***************************************************************************/ | |
| 39 | ||
| 24 | 40 | #ifndef __M65CE02_H__ |
| 25 | 41 | #define __M65CE02_H__ |
| 26 | 42 | |
| 27 | #include "m6502.h" | |
| 43 | #include "m65c02.h" | |
| 28 | 44 | |
| 29 | enum | |
| 30 | { | |
| 31 | M65CE02_PC=1, M65CE02_S, M65CE02_P, M65CE02_A, M65CE02_X, M65CE02_Y, | |
| 32 | M65CE02_Z, M65CE02_B, M65CE02_EA, M65CE02_ZP, | |
| 33 | M65CE02_NMI_STATE, M65CE02_IRQ_STATE | |
| 45 | class m65ce02_device : public m65c02_device { | |
| 46 | public: | |
| 47 | m65ce02_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 48 | m65ce02_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock); | |
| 49 | ||
| 50 | static const disasm_entry disasm_entries[0x100]; | |
| 51 | ||
| 52 | virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options); | |
| 53 | virtual void do_exec_full(); | |
| 54 | virtual void do_exec_partial(); | |
| 55 | ||
| 56 | protected: | |
| 57 | UINT16 TMP3; /* temporary internal values */ | |
| 58 | UINT8 Z; /* Z index register */ | |
| 59 | UINT16 B; /* Zero page base address (always xx00) */ | |
| 60 | ||
| 61 | virtual void init(); | |
| 62 | virtual void device_start(); | |
| 63 | virtual void device_reset(); | |
| 64 | virtual void state_import(const device_state_entry &entry); | |
| 65 | virtual void state_export(const device_state_entry &entry); | |
| 66 | virtual void state_string_export(const device_state_entry &entry, astring &string); | |
| 67 | ||
| 68 | inline void dec_SP_ce() { if(P & F_E) SP = set_l(SP, SP-1); else SP--; } | |
| 69 | inline void inc_SP_ce() { if(P & F_E) SP = set_l(SP, SP+1); else SP++; } | |
| 70 | ||
| 71 | #define O(o) void o ## _full(); void o ## _partial() | |
| 72 | ||
| 73 | // 65ce02 opcodes | |
| 74 | O(adc_ce_aba); O(adc_ce_abx); O(adc_ce_aby); O(adc_ce_idx); O(adc_ce_idy); O(adc_idz); O(adc_ce_imm); O(adc_ce_zpg); O(adc_ce_zpx); | |
| 75 | O(and_ce_abx); O(and_ce_aby); O(and_ce_idx); O(and_ce_idy); O(and_idz); O(and_ce_zpg); O(and_ce_zpx); | |
| 76 | O(asl_ce_aba); O(asl_ce_abx); O(asl_ce_acc); O(asl_ce_zpg); O(asl_ce_zpx); | |
| 77 | O(asr_acc); O(asr_zpg); O(asr_zpx); | |
| 78 | O(asw_aba); | |
| 79 | O(aug_iw3); | |
| 80 | O(bbr_ce_zpb); | |
| 81 | O(bbs_ce_zpb); | |
| 82 | O(bcc_ce_rel); O(bcc_rw2); | |
| 83 | O(bcs_ce_rel); O(bcs_rw2); | |
| 84 | O(beq_ce_rel); O(beq_rw2); | |
| 85 | O(bit_ce_abx); O(bit_ce_imm); O(bit_ce_zpg); O(bit_ce_zpx); | |
| 86 | O(bmi_ce_rel); O(bmi_rw2); | |
| 87 | O(bne_ce_rel); O(bne_rw2); | |
| 88 | O(bpl_ce_rel); O(bpl_rw2); | |
| 89 | O(bra_ce_rel); O(bra_rw2); | |
| 90 | O(brk_ce_imp); | |
| 91 | O(bsr_rw2); | |
| 92 | O(bvc_ce_rel); O(bvc_rw2); | |
| 93 | O(bvs_ce_rel); O(bvs_rw2); | |
| 94 | O(clc_ce_imp); | |
| 95 | O(cld_ce_imp); | |
| 96 | O(cle_imp); | |
| 97 | O(cli_ce_imp); | |
| 98 | O(clv_ce_imp); | |
| 99 | O(cmp_ce_abx); O(cmp_ce_aby); O(cmp_ce_idx); O(cmp_ce_idy); O(cmp_idz); O(cmp_ce_zpg); O(cmp_ce_zpx); | |
| 100 | O(cpx_ce_zpg); | |
| 101 | O(cpy_ce_zpg); | |
| 102 | O(cpz_aba); O(cpz_imm); O(cpz_zpg); | |
| 103 | O(dec_ce_aba); O(dec_ce_abx); O(dec_ce_acc); O(dec_ce_zpg); O(dec_ce_zpx); | |
| 104 | O(dew_zpg); | |
| 105 | O(dex_ce_imp); | |
| 106 | O(dey_ce_imp); | |
| 107 | O(dez_imp); | |
| 108 | O(eor_ce_abx); O(eor_ce_aby); O(eor_ce_idx); O(eor_ce_idy); O(eor_idz); O(eor_ce_zpg); O(eor_ce_zpx); | |
| 109 | O(inc_ce_aba); O(inc_ce_abx); O(inc_ce_acc); O(inc_ce_zpg); O(inc_ce_zpx); | |
| 110 | O(inw_zpg); | |
| 111 | O(inx_ce_imp); | |
| 112 | O(iny_ce_imp); | |
| 113 | O(inz_imp); | |
| 114 | O(jmp_ce_iax); O(jmp_ce_ind); | |
| 115 | O(jsr_ce_adr); O(jsr_ind); O(jsr_iax); | |
| 116 | O(lda_ce_abx); O(lda_ce_aby); O(lda_ce_idx); O(lda_ce_idy); O(lda_idz); O(lda_isy); O(lda_ce_zpg); O(lda_ce_zpx); | |
| 117 | O(ldx_ce_aby); O(ldx_ce_zpg); O(ldx_ce_zpy); | |
| 118 | O(ldy_ce_abx); O(ldy_ce_zpg); O(ldy_ce_zpx); | |
| 119 | O(ldz_aba); O(ldz_abx); O(ldz_imm); | |
| 120 | O(lsr_ce_aba); O(lsr_ce_abx); O(lsr_ce_acc); O(lsr_ce_zpg); O(lsr_ce_zpx); | |
| 121 | O(neg_acc); | |
| 122 | O(ora_ce_abx); O(ora_ce_aby); O(ora_ce_idx); O(ora_ce_idy); O(ora_idz); O(ora_ce_zpg); O(ora_ce_zpx); | |
| 123 | O(pha_ce_imp); | |
| 124 | O(php_ce_imp); | |
| 125 | O(phw_aba); O(phw_iw2); | |
| 126 | O(phx_ce_imp); | |
| 127 | O(phy_ce_imp); | |
| 128 | O(phz_imp); | |
| 129 | O(pla_ce_imp); | |
| 130 | O(plp_ce_imp); | |
| 131 | O(plx_ce_imp); | |
| 132 | O(ply_ce_imp); | |
| 133 | O(plz_imp); | |
| 134 | O(rmb_ce_bzp); | |
| 135 | O(rol_ce_aba); O(rol_ce_abx); O(rol_ce_acc); O(rol_ce_zpg); O(rol_ce_zpx); | |
| 136 | O(ror_ce_aba); O(ror_ce_abx); O(ror_ce_acc); O(ror_ce_zpg); O(ror_ce_zpx); | |
| 137 | O(row_aba); | |
| 138 | O(rti_ce_imp); | |
| 139 | O(rtn_imm); | |
| 140 | O(rts_ce_imp); | |
| 141 | O(sbc_ce_aba); O(sbc_ce_abx); O(sbc_ce_aby); O(sbc_ce_idx); O(sbc_ce_idy); O(sbc_idz); O(sbc_ce_imm); O(sbc_ce_zpg); O(sbc_ce_zpx); | |
| 142 | O(sec_ce_imp); | |
| 143 | O(sed_ce_imp); | |
| 144 | O(see_imp); | |
| 145 | O(sei_ce_imp); | |
| 146 | O(smb_ce_bzp); | |
| 147 | O(sta_ce_abx); O(sta_ce_aby); O(sta_ce_idx); O(sta_ce_idy); O(sta_idz); O(sta_isy); O(sta_ce_zpg); O(sta_ce_zpx); | |
| 148 | O(stx_aby); O(stx_ce_zpg); O(stx_ce_zpy); | |
| 149 | O(sty_abx); O(sty_ce_zpg); O(sty_ce_zpx); | |
| 150 | O(stz_ce_aba); O(stz_ce_abx); O(stz_ce_zpg); O(stz_ce_zpx); | |
| 151 | O(tab_imp); | |
| 152 | O(tax_ce_imp); | |
| 153 | O(tay_ce_imp); | |
| 154 | O(taz_imp); | |
| 155 | O(tba_imp); | |
| 156 | O(trb_ce_aba); O(trb_ce_zpg); | |
| 157 | O(tsb_ce_aba); O(tsb_ce_zpg); | |
| 158 | O(tsx_ce_imp); | |
| 159 | O(tsy_imp); | |
| 160 | O(txa_ce_imp); | |
| 161 | O(txs_ce_imp); | |
| 162 | O(tys_imp); | |
| 163 | O(tya_ce_imp); | |
| 164 | O(tza_imp); | |
| 165 | ||
| 166 | #undef O | |
| 34 | 167 | }; |
| 35 | 168 | |
| 36 | #define M65CE02_IRQ_LINE M6502_IRQ_LINE | |
| 169 | enum { | |
| 170 | M65CE02_IRQ_LINE = m6502_device::IRQ_LINE, | |
| 171 | M65CE02_NMI_LINE = m6502_device::NMI_LINE, | |
| 172 | }; | |
| 37 | 173 | |
| 38 | DECLARE_LEGACY_CPU_DEVICE(M65CE02, m65ce02); | |
| 39 | 174 | |
| 40 | extern CPU_DISASSEMBLE( m65ce02 ); | |
| 175 | enum { | |
| 176 | M65CE02_Z = M6502_IR+1, | |
| 177 | M65CE02_B | |
| 178 | }; | |
| 41 | 179 | |
| 42 | #endif /* __M65CE02_H__ */ | |
| 180 | extern const device_type M65CE02; | |
| 181 | ||
| 182 | #endif |
| r18874 | r18875 | |
|---|---|---|
| 1 | /*************************************************************************** | |
| 2 | ||
| 3 | n2a03.h | |
| 4 | ||
| 5 | 6502, NES variant | |
| 6 | ||
| 7 | **************************************************************************** | |
| 8 | ||
| 9 | Copyright Olivier Galibert | |
| 10 | All rights reserved. | |
| 11 | ||
| 12 | Redistribution and use in source and binary forms, with or without | |
| 13 | modification, are permitted provided that the following conditions are | |
| 14 | met: | |
| 15 | ||
| 16 | * Redistributions of source code must retain the above copyright | |
| 17 | notice, this list of conditions and the following disclaimer. | |
| 18 | * Redistributions in binary form must reproduce the above copyright | |
| 19 | notice, this list of conditions and the following disclaimer in | |
| 20 | the documentation and/or other materials provided with the | |
| 21 | distribution. | |
| 22 | * Neither the name 'MAME' nor the names of its contributors may be | |
| 23 | used to endorse or promote products derived from this software | |
| 24 | without specific prior written permission. | |
| 25 | ||
| 26 | THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR | |
| 27 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 28 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 29 | DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, | |
| 30 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 31 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
| 32 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 33 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
| 34 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
| 35 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| 36 | POSSIBILITY OF SUCH DAMAGE. | |
| 37 | ||
| 38 | ***************************************************************************/ | |
| 39 | ||
| 40 | #ifndef __N2A03_H__ | |
| 41 | #define __N2A03_H__ | |
| 42 | ||
| 43 | #include "m6502.h" | |
| 44 | ||
| 45 | class n2a03_device : public m6502_device { | |
| 46 | public: | |
| 47 | n2a03_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 48 | ||
| 49 | static const disasm_entry disasm_entries[0x100]; | |
| 50 | ||
| 51 | virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options); | |
| 52 | virtual void do_exec_full(); | |
| 53 | virtual void do_exec_partial(); | |
| 54 | ||
| 55 | protected: | |
| 56 | class mi_2a03_normal : public memory_interface { | |
| 57 | public: | |
| 58 | virtual UINT8 read(UINT16 adr); | |
| 59 | virtual UINT8 read_direct(UINT16 adr); | |
| 60 | virtual UINT8 read_decrypted(UINT16 adr); | |
| 61 | virtual void write(UINT16 adr, UINT8 val); | |
| 62 | }; | |
| 63 | ||
| 64 | class mi_2a03_nd : public memory_interface { | |
| 65 | public: | |
| 66 | virtual UINT8 read(UINT16 adr); | |
| 67 | virtual UINT8 read_direct(UINT16 adr); | |
| 68 | virtual UINT8 read_decrypted(UINT16 adr); | |
| 69 | virtual void write(UINT16 adr, UINT8 val); | |
| 70 | }; | |
| 71 | ||
| 72 | virtual void device_start(); | |
| 73 | ||
| 74 | #define O(o) void o ## _full(); void o ## _partial() | |
| 75 | ||
| 76 | // n2a03 opcodes - same as 6502 with D disabled | |
| 77 | O(adc_nd_aba); O(adc_nd_abx); O(adc_nd_aby); O(adc_nd_idx); O(adc_nd_idy); O(adc_nd_imm); O(adc_nd_zpg); O(adc_nd_zpx); | |
| 78 | O(arr_nd_imm); | |
| 79 | O(isb_nd_aba); O(isb_nd_abx); O(isb_nd_aby); O(isb_nd_idx); O(isb_nd_idy); O(isb_nd_zpg); O(isb_nd_zpx); | |
| 80 | O(rra_nd_aba); O(rra_nd_abx); O(rra_nd_aby); O(rra_nd_idx); O(rra_nd_idy); O(rra_nd_zpg); O(rra_nd_zpx); | |
| 81 | O(sbc_nd_aba); O(sbc_nd_abx); O(sbc_nd_aby); O(sbc_nd_idx); O(sbc_nd_idy); O(sbc_nd_imm); O(sbc_nd_zpg); O(sbc_nd_zpx); | |
| 82 | ||
| 83 | #undef O | |
| 84 | }; | |
| 85 | ||
| 86 | #define N2A03_DEFAULTCLOCK (21477272.724 / 12) | |
| 87 | ||
| 88 | enum { | |
| 89 | N2A03_IRQ_LINE = m6502_device::IRQ_LINE, | |
| 90 | N2A03_NMI_LINE = m6502_device::NMI_LINE, | |
| 91 | N2A03_SET_OVERFLOW = m6502_device::V_LINE, | |
| 92 | }; | |
| 93 | ||
| 94 | extern const device_type N2A03; | |
| 95 | ||
| 96 | #endif |
| r18874 | r18875 | |
|---|---|---|
| 1 | /*************************************************************************** | |
| 2 | ||
| 3 | m6510t.c | |
| 4 | ||
| 5 | 6510 with the full 8 i/o pins at the expense of the NMI and RDY lines. | |
| 6 | ||
| 7 | **************************************************************************** | |
| 8 | ||
| 9 | Copyright Olivier Galibert | |
| 10 | All rights reserved. | |
| 11 | ||
| 12 | Redistribution and use in source and binary forms, with or without | |
| 13 | modification, are permitted provided that the following conditions are | |
| 14 | met: | |
| 15 | ||
| 16 | * Redistributions of source code must retain the above copyright | |
| 17 | notice, this list of conditions and the following disclaimer. | |
| 18 | * Redistributions in binary form must reproduce the above copyright | |
| 19 | notice, this list of conditions and the following disclaimer in | |
| 20 | the documentation and/or other materials provided with the | |
| 21 | distribution. | |
| 22 | * Neither the name 'MAME' nor the names of its contributors may be | |
| 23 | used to endorse or promote products derived from this software | |
| 24 | without specific prior written permission. | |
| 25 | ||
| 26 | THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR | |
| 27 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 28 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 29 | DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, | |
| 30 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 31 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
| 32 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 33 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
| 34 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
| 35 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| 36 | POSSIBILITY OF SUCH DAMAGE. | |
| 37 | ||
| 38 | ***************************************************************************/ | |
| 39 | ||
| 40 | #include "emu.h" | |
| 41 | #include "m6510t.h" | |
| 42 | ||
| 43 | const device_type M6510T = &device_creator<m6510t_device>; | |
| 44 | ||
| 45 | m6510t_device::m6510t_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : | |
| 46 | m6510_device(mconfig, M6510T, "M6510T", tag, owner, clock) | |
| 47 | { | |
| 48 | } |
| r18874 | r18875 | |
|---|---|---|
| 1 | # m6502_family_device - 6502, 6504 | |
| 2 | brk_imp ora_idx kil_non slo_idx nop_zpg ora_zpg asl_zpg slo_zpg php_imp ora_imm asl_acc anc_imm nop_aba ora_aba asl_aba slo_aba | |
| 3 | bpl_rel ora_idy kil_non slo_idy nop_zpx ora_zpx asl_zpx slo_zpx clc_imp ora_aby nop_imp slo_aby nop_abx ora_abx asl_abx slo_abx | |
| 4 | jsr_adr and_idx kil_non rla_idx bit_zpg and_zpg rol_zpg rla_zpg plp_imp and_imm rol_acc anc_imm bit_aba and_aba rol_aba rla_aba | |
| 5 | bmi_rel and_idy kil_non rla_idy nop_zpx and_zpx rol_zpx rla_zpx sec_imp and_aby nop_imp rla_aby nop_abx and_abx rol_abx rla_abx | |
| 6 | rti_imp eor_idx kil_non sre_idx nop_zpg eor_zpg lsr_zpg sre_zpg pha_imp eor_imm lsr_acc asr_imm jmp_adr eor_aba lsr_aba sre_aba | |
| 7 | bvc_rel eor_idy kil_non sre_idy nop_zpx eor_zpx lsr_zpx sre_zpx cli_imp eor_aby nop_imp sre_aby nop_abx eor_abx lsr_abx sre_abx | |
| 8 | rts_imp adc_idx kil_non rra_idx nop_zpg adc_zpg ror_zpg rra_zpg pla_imp adc_imm ror_acc arr_imm jmp_ind adc_aba ror_aba rra_aba | |
| 9 | bvs_rel adc_idy kil_non rra_idy nop_zpx adc_zpx ror_zpx rra_zpx sei_imp adc_aby nop_imp rra_aby nop_abx adc_abx ror_abx rra_abx | |
| 10 | nop_imp sta_idx nop_imm sax_idx sty_zpg sta_zpg stx_zpg sax_zpg dey_imp nop_imm txa_imp ane_imm sty_aba sta_aba stx_aba sax_aba | |
| 11 | bcc_rel sta_idy kil_non sha_idy sty_zpx sta_zpx stx_zpy sax_zpy tya_imp sta_aby txs_imp shs_aby shy_abx sta_abx shx_aby sha_aby | |
| 12 | ldy_imm lda_idx ldx_imm lax_idx ldy_zpg lda_zpg ldx_zpg lax_zpg tay_imp lda_imm tax_imp lxa_imm ldy_aba lda_aba ldx_aba lax_aba | |
| 13 | bcs_rel lda_idy kil_non lax_idy ldy_zpx lda_zpx ldx_zpy lax_zpy clv_imp lda_aby tsx_imp las_aby ldy_abx lda_abx ldx_aby lax_aby | |
| 14 | cpy_imm cmp_idx nop_imm dcp_idx cpy_zpg cmp_zpg dec_zpg dcp_zpg iny_imp cmp_imm dex_imp sbx_imm cpy_aba cmp_aba dec_aba dcp_aba | |
| 15 | bne_rel cmp_idy kil_non dcp_idy nop_zpx cmp_zpx dec_zpx dcp_zpx cld_imp cmp_aby nop_imp dcp_aby nop_abx cmp_abx dec_abx dcp_abx | |
| 16 | cpx_imm sbc_idx nop_imm isb_idx cpx_zpg sbc_zpg inc_zpg isb_zpg inx_imp sbc_imm nop_imp sbc_imm cpx_aba sbc_aba inc_aba isb_aba | |
| 17 | beq_rel sbc_idy kil_non isb_idy nop_zpx sbc_zpx inc_zpx isb_zpx sed_imp sbc_aby nop_imp isb_aby nop_abx sbc_abx inc_abx isb_abx | |
| 18 | reset |
| r18874 | r18875 | |
|---|---|---|
| 1 | /*************************************************************************** | |
| 2 | ||
| 3 | m65sc02.c | |
| 4 | ||
| 5 | Rockwell-class 65c02 with internal static registers, making clock stoppable? | |
| 6 | ||
| 7 | **************************************************************************** | |
| 8 | ||
| 9 | Copyright Olivier Galibert | |
| 10 | All rights reserved. | |
| 11 | ||
| 12 | Redistribution and use in source and binary forms, with or without | |
| 13 | modification, are permitted provided that the following conditions are | |
| 14 | met: | |
| 15 | ||
| 16 | * Redistributions of source code must retain the above copyright | |
| 17 | notice, this list of conditions and the following disclaimer. | |
| 18 | * Redistributions in binary form must reproduce the above copyright | |
| 19 | notice, this list of conditions and the following disclaimer in | |
| 20 | the documentation and/or other materials provided with the | |
| 21 | distribution. | |
| 22 | * Neither the name 'MAME' nor the names of its contributors may be | |
| 23 | used to endorse or promote products derived from this software | |
| 24 | without specific prior written permission. | |
| 25 | ||
| 26 | THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR | |
| 27 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 28 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 29 | DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, | |
| 30 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 31 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
| 32 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 33 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
| 34 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
| 35 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| 36 | POSSIBILITY OF SUCH DAMAGE. | |
| 37 | ||
| 38 | ***************************************************************************/ | |
| 39 | ||
| 40 | #include "emu.h" | |
| 41 | #include "m65sc02.h" | |
| 42 | ||
| 43 | const device_type M65SC02 = &device_creator<m65sc02_device>; | |
| 44 | ||
| 45 | m65sc02_device::m65sc02_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : | |
| 46 | r65c02_device(mconfig, M65SC02, "M65SC02", tag, owner, clock) | |
| 47 | { | |
| 48 | } |
| r18874 | r18875 | |
|---|---|---|
| 1 | /*************************************************************************** | |
| 2 | ||
| 3 | m6510t.h | |
| 4 | ||
| 5 | 6510 with the full 8 i/o pins at the expense of the NMI and RDY lines. | |
| 6 | ||
| 7 | **************************************************************************** | |
| 8 | ||
| 9 | Copyright Olivier Galibert | |
| 10 | All rights reserved. | |
| 11 | ||
| 12 | Redistribution and use in source and binary forms, with or without | |
| 13 | modification, are permitted provided that the following conditions are | |
| 14 | met: | |
| 15 | ||
| 16 | * Redistributions of source code must retain the above copyright | |
| 17 | notice, this list of conditions and the following disclaimer. | |
| 18 | * Redistributions in binary form must reproduce the above copyright | |
| 19 | notice, this list of conditions and the following disclaimer in | |
| 20 | the documentation and/or other materials provided with the | |
| 21 | distribution. | |
| 22 | * Neither the name 'MAME' nor the names of its contributors may be | |
| 23 | used to endorse or promote products derived from this software | |
| 24 | without specific prior written permission. | |
| 25 | ||
| 26 | THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR | |
| 27 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 28 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 29 | DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, | |
| 30 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 31 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
| 32 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 33 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
| 34 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
| 35 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| 36 | POSSIBILITY OF SUCH DAMAGE. | |
| 37 | ||
| 38 | ***************************************************************************/ | |
| 39 | ||
| 40 | #ifndef __M6510T_H__ | |
| 41 | #define __M6510T_H__ | |
| 42 | ||
| 43 | #include "m6510.h" | |
| 44 | ||
| 45 | #define MCFG_M6510T_PORT_CALLBACKS(_read, _write) \ | |
| 46 | downcast<m6510t_device *>(device)->set_callbacks(DEVCB2_##_read, DEVCB2_##_write); | |
| 47 | ||
| 48 | #define MCFG_M6510T_PORT_PULLS(_up, _down) \ | |
| 49 | downcast<m6510t_device *>(device)->set_pulls(_up, _down); | |
| 50 | ||
| 51 | class m6510t_device : public m6510_device { | |
| 52 | public: | |
| 53 | m6510t_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 54 | }; | |
| 55 | ||
| 56 | enum { | |
| 57 | M6510T_IRQ_LINE = m6502_device::IRQ_LINE, | |
| 58 | M6510T_SET_OVERFLOW = m6502_device::V_LINE, | |
| 59 | }; | |
| 60 | ||
| 61 | extern const device_type M6510T; | |
| 62 | ||
| 63 | #endif |
| r18874 | r18875 | |
|---|---|---|
| 1 | /*************************************************************************** | |
| 2 | ||
| 3 | m65sc02.h | |
| 4 | ||
| 5 | Rockwell-class 65c02 with internal static registers, making clock stoppable? | |
| 6 | ||
| 7 | **************************************************************************** | |
| 8 | ||
| 9 | Copyright Olivier Galibert | |
| 10 | All rights reserved. | |
| 11 | ||
| 12 | Redistribution and use in source and binary forms, with or without | |
| 13 | modification, are permitted provided that the following conditions are | |
| 14 | met: | |
| 15 | ||
| 16 | * Redistributions of source code must retain the above copyright | |
| 17 | notice, this list of conditions and the following disclaimer. | |
| 18 | * Redistributions in binary form must reproduce the above copyright | |
| 19 | notice, this list of conditions and the following disclaimer in | |
| 20 | the documentation and/or other materials provided with the | |
| 21 | distribution. | |
| 22 | * Neither the name 'MAME' nor the names of its contributors may be | |
| 23 | used to endorse or promote products derived from this software | |
| 24 | without specific prior written permission. | |
| 25 | ||
| 26 | THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR | |
| 27 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 28 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 29 | DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, | |
| 30 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 31 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
| 32 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 33 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
| 34 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
| 35 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| 36 | POSSIBILITY OF SUCH DAMAGE. | |
| 37 | ||
| 38 | ***************************************************************************/ | |
| 39 | ||
| 40 | #ifndef __M65SC02_H__ | |
| 41 | #define __M65SC02_H__ | |
| 42 | ||
| 43 | #include "r65c02.h" | |
| 44 | ||
| 45 | class m65sc02_device : public r65c02_device { | |
| 46 | public: | |
| 47 | m65sc02_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 48 | }; | |
| 49 | ||
| 50 | enum { | |
| 51 | M65SC02_IRQ_LINE = m6502_device::IRQ_LINE, | |
| 52 | M65SC02_NMI_LINE = m6502_device::NMI_LINE, | |
| 53 | M65SC02_SET_OVERFLOW = m6502_device::V_LINE, | |
| 54 | }; | |
| 55 | ||
| 56 | extern const device_type M65SC02; | |
| 57 | ||
| 58 | #endif |
| r18874 | r18875 | |
|---|---|---|
| 1 | # m6509 - special banking on two specific instructions, and banking in general | |
| 2 | brk_imp ora_idx kil_non slo_idx nop_zpg ora_zpg asl_zpg slo_zpg php_imp ora_imm asl_acc anc_imm nop_aba ora_aba asl_aba slo_aba | |
| 3 | bpl_rel ora_idy kil_non slo_idy nop_zpx ora_zpx asl_zpx slo_zpx clc_imp ora_aby nop_imp slo_aby nop_abx ora_abx asl_abx slo_abx | |
| 4 | jsr_adr and_idx kil_non rla_idx bit_zpg and_zpg rol_zpg rla_zpg plp_imp and_imm rol_acc anc_imm bit_aba and_aba rol_aba rla_aba | |
| 5 | bmi_rel and_idy kil_non rla_idy nop_zpx and_zpx rol_zpx rla_zpx sec_imp and_aby nop_imp rla_aby nop_abx and_abx rol_abx rla_abx | |
| 6 | rti_imp eor_idx kil_non sre_idx nop_zpg eor_zpg lsr_zpg sre_zpg pha_imp eor_imm lsr_acc asr_imm jmp_adr eor_aba lsr_aba sre_aba | |
| 7 | bvc_rel eor_idy kil_non sre_idy nop_zpx eor_zpx lsr_zpx sre_zpx cli_imp eor_aby nop_imp sre_aby nop_abx eor_abx lsr_abx sre_abx | |
| 8 | rts_imp adc_idx kil_non rra_idx nop_zpg adc_zpg ror_zpg rra_zpg pla_imp adc_imm ror_acc arr_imm jmp_ind adc_aba ror_aba rra_aba | |
| 9 | bvs_rel adc_idy kil_non rra_idy nop_zpx adc_zpx ror_zpx rra_zpx sei_imp adc_aby nop_imp rra_aby nop_abx adc_abx ror_abx rra_abx | |
| 10 | nop_imp sta_idx nop_imm sax_idx sty_zpg sta_zpg stx_zpg sax_zpg dey_imp nop_imm txa_imp ane_imm sty_aba sta_aba stx_aba sax_aba | |
| 11 | bcc_rel sta_9_idy kil_non sha_idy sty_zpx sta_zpx stx_zpy sax_zpy tya_imp sta_aby txs_imp shs_aby shy_abx sta_abx shx_aby sha_aby | |
| 12 | ldy_imm lda_idx ldx_imm lax_idx ldy_zpg lda_zpg ldx_zpg lax_zpg tay_imp lda_imm tax_imp lxa_imm ldy_aba lda_aba ldx_aba lax_aba | |
| 13 | bcs_rel lda_9_idy kil_non lax_idy ldy_zpx lda_zpx ldx_zpy lax_zpy clv_imp lda_aby tsx_imp las_aby ldy_abx lda_abx ldx_aby lax_aby | |
| 14 | cpy_imm cmp_idx nop_imm dcp_idx cpy_zpg cmp_zpg dec_zpg dcp_zpg iny_imp cmp_imm dex_imp sbx_imm cpy_aba cmp_aba dec_aba dcp_aba | |
| 15 | bne_rel cmp_idy kil_non dcp_idy nop_zpx cmp_zpx dec_zpx dcp_zpx cld_imp cmp_aby nop_imp dcp_aby nop_abx cmp_abx dec_abx dcp_abx | |
| 16 | cpx_imm sbc_idx nop_imm isb_idx cpx_zpg sbc_zpg inc_zpg isb_zpg inx_imp sbc_imm nop_imp sbc_imm cpx_aba sbc_aba inc_aba isb_aba | |
| 17 | beq_rel sbc_idy kil_non isb_idy nop_zpx sbc_zpx inc_zpx isb_zpx sed_imp sbc_aby nop_imp isb_aby nop_abx sbc_abx inc_abx isb_abx | |
| 18 | reset |
| r18874 | r18875 | |
|---|---|---|
| 1 | # r65c02 - rockwell variant, with the bitwise instructions and stp/wai | |
| 2 | brk_c_imp ora_idx nop_imm nop_c_imp tsb_zpg ora_zpg asl_zpg rmb_bzp php_imp ora_imm asl_acc nop_c_imp tsb_aba ora_aba asl_aba bbr_zpb | |
| 3 | bpl_rel ora_idy ora_zpi nop_c_imp trb_zpg ora_zpx asl_zpx rmb_bzp clc_imp ora_aby inc_acc nop_c_imp trb_aba ora_abx asl_c_abx bbr_zpb | |
| 4 | jsr_adr and_idx nop_imm nop_c_imp bit_zpg and_zpg rol_zpg rmb_bzp plp_imp and_imm rol_acc nop_c_imp bit_aba and_aba rol_aba bbr_zpb | |
| 5 | bmi_rel and_idy and_zpi nop_c_imp bit_zpx and_zpx rol_zpx rmb_bzp sec_imp and_aby dec_acc nop_c_imp bit_abx and_abx rol_c_abx bbr_zpb | |
| 6 | rti_imp eor_idx nop_imm nop_c_imp nop_zpg eor_zpg lsr_zpg rmb_bzp pha_imp eor_imm lsr_acc nop_c_imp jmp_adr eor_aba lsr_aba bbr_zpb | |
| 7 | bvc_rel eor_idy eor_zpi nop_c_imp nop_zpx eor_zpx lsr_zpx rmb_bzp cli_imp eor_aby phy_imp nop_c_imp nop_c_aba eor_abx lsr_c_abx bbr_zpb | |
| 8 | rts_imp adc_c_idx nop_imm nop_c_imp stz_zpg adc_c_zpg ror_zpg rmb_bzp pla_imp adc_c_imm ror_acc nop_c_imp jmp_c_ind adc_c_aba ror_aba bbr_zpb | |
| 9 | bvs_rel adc_c_idy adc_c_zpi nop_c_imp stz_zpx adc_c_zpx ror_zpx rmb_bzp sei_imp adc_c_aby ply_imp nop_c_imp jmp_iax adc_c_abx ror_c_abx bbr_zpb | |
| 10 | bra_rel sta_idx nop_imm nop_c_imp sty_zpg sta_zpg stx_zpg smb_bzp dey_imp bit_imm txa_imp nop_c_imp sty_aba sta_aba stx_aba bbs_zpb | |
| 11 | bcc_rel sta_idy sta_zpi nop_c_imp sty_zpx sta_zpx stx_zpy smb_bzp tya_imp sta_aby txs_imp nop_c_imp stz_aba sta_abx stz_abx bbs_zpb | |
| 12 | ldy_imm lda_idx ldx_imm nop_c_imp ldy_zpg lda_zpg ldx_zpg smb_bzp tay_imp lda_imm tax_imp nop_c_imp ldy_aba lda_aba ldx_aba bbs_zpb | |
| 13 | bcs_rel lda_idy lda_zpi nop_c_imp ldy_zpx lda_zpx ldx_zpy smb_bzp clv_imp lda_aby tsx_imp nop_c_imp ldy_abx lda_abx ldx_aby bbs_zpb | |
| 14 | cpy_imm cmp_idx nop_imm nop_c_imp cpy_zpg cmp_zpg dec_zpg smb_bzp iny_imp cmp_imm dex_imp wai_imp cpy_aba cmp_aba dec_aba bbs_zpb | |
| 15 | bne_rel cmp_idy cmp_zpi nop_c_imp nop_zpx cmp_zpx dec_zpx smb_bzp cld_imp cmp_aby phx_imp stp_imp nop_c_abx cmp_abx dec_abx bbs_zpb | |
| 16 | cpx_imm sbc_c_idx nop_imm nop_c_imp cpx_zpg sbc_c_zpg inc_zpg smb_bzp inx_imp sbc_c_imm nop_imp nop_c_imp cpx_aba sbc_c_aba inc_aba bbs_zpb | |
| 17 | beq_rel sbc_c_idy sbc_c_zpi nop_c_imp nop_zpx sbc_c_zpx inc_zpx smb_bzp sed_imp sbc_c_aby plx_imp nop_c_imp nop_c_abx sbc_c_abx inc_abx bbs_zpb | |
| 18 | reset |
| r18874 | r18875 | |
|---|---|---|
| 1 | # deco16 - deco variant | |
| 2 | brk_imp ora_idx ill_non ill_non ill_non ora_zpg asl_zpg ill_non php_imp ora_imm asl_acc u0B_zpg ill_non ora_aba asl_aba ill_non | |
| 3 | bpl_rel ora_idy ill_non u13_zpg ill_non ora_zpx asl_zpx ill_non clc_imp ora_aby ill_non ill_non ill_non ora_abx asl_abx ill_non | |
| 4 | jsr_adr and_idx ill_non u23_zpg bit_zpg and_zpg rol_zpg ill_non plp_imp and_imm rol_acc ill_non bit_aba and_aba rol_aba ill_non | |
| 5 | bmi_rel and_idy ill_non ill_non ill_non and_zpx rol_zpx ill_non sec_imp and_aby ill_non ill_non ill_non and_abx rol_abx u3F_zpg | |
| 6 | rti_imp eor_idx ill_non ill_non ill_non eor_zpg lsr_zpg ill_non pha_imp eor_imm lsr_acc u4B_zpg jmp_adr eor_aba lsr_aba ill_non | |
| 7 | bvc_rel eor_idy ill_non ill_non ill_non eor_zpx lsr_zpx ill_non cli_imp eor_aby ill_non ill_non ill_non eor_abx lsr_abx ill_non | |
| 8 | rts_imp adc_idx ill_non ill_non ill_non adc_zpg ror_zpg vbl_zpg pla_imp adc_imm ror_acc ill_non jmp_ind adc_aba ror_aba ill_non | |
| 9 | bvs_rel adc_idy ill_non ill_non ill_non adc_zpx ror_zpx ill_non sei_imp adc_aby ill_non ill_non ill_non adc_abx ror_abx ill_non | |
| 10 | ill_non sta_idx ill_non ill_non sty_zpg sta_zpg stx_zpg u87_zpg dey_imp ill_non txa_imp ill_non sty_aba sta_aba stx_aba u8F_zpg | |
| 11 | bcc_rel sta_idy ill_non ill_non sty_zpx sta_zpx stx_zpy ill_non tya_imp sta_aby txs_imp ill_non ill_non sta_abx ill_non ill_non | |
| 12 | ldy_imm lda_idx ldx_imm uA3_zpg ldy_zpg lda_zpg ldx_zpg ill_non tay_imp lda_imm tax_imp ill_non ldy_aba lda_aba ldx_aba ill_non | |
| 13 | bcs_rel lda_idy ill_non ill_non ldy_zpx lda_zpx ldx_zpy ill_non clv_imp lda_aby tsx_imp uBB_zpg ldy_abx lda_abx ldx_aby ill_non | |
| 14 | cpy_imm cmp_idx ill_non ill_non cpy_zpg cmp_zpg dec_zpg ill_non iny_imp cmp_imm dex_imp ill_non cpy_aba cmp_aba dec_aba ill_non | |
| 15 | bne_rel cmp_idy ill_non ill_non ill_non cmp_zpx dec_zpx ill_non cld_imp cmp_aby ill_non ill_non ill_non cmp_abx dec_abx ill_non | |
| 16 | cpx_imm sbc_idx ill_non ill_non cpx_zpg sbc_zpg inc_zpg ill_non inx_imp sbc_imm nop_imp ill_non cpx_aba sbc_aba inc_aba ill_non | |
| 17 | beq_rel sbc_idy ill_non ill_non ill_non sbc_zpx inc_zpx ill_non sed_imp sbc_aby ill_non ill_non ill_non sbc_abx inc_abx ill_non | |
| 18 | reset |
| r18874 | r18875 | |
|---|---|---|
| 1 | # 4510 opcodes | |
| 2 | ||
| 3 | eom_imp | |
| 4 | inhibit_interrupts = false; // before or after prefetch? | |
| 5 | prefetch(); | |
| 6 | ||
| 7 | map_imp | |
| 8 | inhibit_interrupts = true; | |
| 9 | map_offset[0] = (A<<8) | ((X & 0xf) << 16); | |
| 10 | map_offset[1] = (Y<<8) | ((Z & 0xf) << 16); | |
| 11 | map_enable = ((X & 0xf0) >> 4) | (Z & 0xf0); | |
| 12 | prefetch(); |
| r18874 | r18875 | |
|---|---|---|
| 1 | # 6510 undocumented instructions in a C64 context | |
| 2 | anc_10_imm | |
| 3 | TMP2 = read_pc(); | |
| 4 | A &= TMP2; | |
| 5 | set_nz(A); | |
| 6 | if(A & 0x80) | |
| 7 | P |= F_C; | |
| 8 | else | |
| 9 | P &= ~F_C; | |
| 10 | prefetch(); | |
| 11 | ||
| 12 | ane_10_imm | |
| 13 | TMP2 = read_pc(); | |
| 14 | A = (A | 0xee) & TMP2 & X; | |
| 15 | set_nz(A); | |
| 16 | prefetch(); | |
| 17 | ||
| 18 | asr_10_imm | |
| 19 | TMP2 = read_pc(); | |
| 20 | A = do_lsr(A & TMP2); | |
| 21 | set_nz(A); | |
| 22 | prefetch(); | |
| 23 | ||
| 24 | arr_10_imm | |
| 25 | TMP2 = read_pc(); | |
| 26 | A &= TMP2; | |
| 27 | do_arr(); | |
| 28 | prefetch(); | |
| 29 | ||
| 30 | las_10_aby | |
| 31 | TMP = read_pc(); | |
| 32 | TMP = set_h(TMP, read_pc()); | |
| 33 | if(page_changing(TMP, Y)) { | |
| 34 | read(set_l(TMP, TMP+Y)); | |
| 35 | } | |
| 36 | TMP2 = read(TMP+Y); | |
| 37 | A = X = TMP2 & SP; | |
| 38 | SP = set_l(SP, A); | |
| 39 | set_nz(A); | |
| 40 | prefetch(); | |
| 41 | ||
| 42 | lxa_10_imm | |
| 43 | TMP2 = read_pc(); | |
| 44 | A = X = (A | 0xee) & TMP2; | |
| 45 | set_nz(A); | |
| 46 | prefetch(); |
| r18874 | r18875 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * m6502.c | |
| 4 | * Portable 6502/65c02/65sc02/6510/n2a03 emulator V1.2 | |
| 5 | * | |
| 6 | * Copyright Juergen Buchmueller, all rights reserved. | |
| 7 | * 65sc02 core Copyright Peter Trauner. | |
| 8 | * Deco16 portions Copyright Bryan McPhail. | |
| 9 | * | |
| 10 | * - This source code is released as freeware for non-commercial purposes. | |
| 11 | * - You are free to use and redistribute this code in modified or | |
| 12 | * unmodified form, provided you list me in the credits. | |
| 13 | * - If you modify this source code, you must add a notice to each modified | |
| 14 | * source file that it has been changed. If you're a nice person, you | |
| 15 | * will clearly mark each change too. :) | |
| 16 | * - If you wish to use this for commercial purposes, please contact me at | |
| 17 | * pullmoll@t-online.de | |
| 18 | * - The author of this copywritten work reserves the right to change the | |
| 19 | * terms of its usage and license at any time, including retroactively | |
| 20 | * - This entire notice must remain in the source code. | |
| 21 | * | |
| 22 | *****************************************************************************/ | |
| 23 | /* 2.February 2000 PeT added 65sc02 subtype */ | |
| 24 | /* 10.March 2000 PeT added 6502 set overflow input line */ | |
| 25 | /* 13.September 2000 PeT N2A03 jmp indirect */ | |
| 1 | /*************************************************************************** | |
| 26 | 2 | |
| 27 | #include "emu.h" | |
| 28 | #include "debugger.h" | |
| 29 | #include "m6502.h" | |
| 30 | #include "ops02.h" | |
| 31 | #include "ill02.h" | |
| 3 | m6502.c | |
| 32 | 4 | |
| 5 | Mostek 6502, original NMOS variant | |
| 33 | 6 | |
| 34 | #define M6502_NMI_VEC 0xfffa | |
| 35 | #define M6502_RST_VEC 0xfffc | |
| 36 | #define M6502_IRQ_VEC 0xfffe | |
| 7 | **************************************************************************** | |
| 37 | 8 | |
| 38 | #define DECO16_RST_VEC 0xfff0 | |
| 39 | #define DECO16_IRQ_VEC 0xfff2 | |
| 40 | #define DECO16_NMI_VEC 0xfff4 | |
| 9 | Copyright Olivier Galibert | |
| 10 | All rights reserved. | |
| 41 | 11 | |
| 42 | #define VERBOSE 0 | |
| 12 | Redistribution and use in source and binary forms, with or without | |
| 13 | modification, are permitted provided that the following conditions are | |
| 14 | met: | |
| 43 | 15 | |
| 44 | #define LOG(x) do { if (VERBOSE) logerror x; } while (0) | |
| 16 | * Redistributions of source code must retain the above copyright | |
| 17 | notice, this list of conditions and the following disclaimer. | |
| 18 | * Redistributions in binary form must reproduce the above copyright | |
| 19 | notice, this list of conditions and the following disclaimer in | |
| 20 | the documentation and/or other materials provided with the | |
| 21 | distribution. | |
| 22 | * Neither the name 'MAME' nor the names of its contributors may be | |
| 23 | used to endorse or promote products derived from this software | |
| 24 | without specific prior written permission. | |
| 45 | 25 | |
| 26 | THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR | |
| 27 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 28 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 29 | DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, | |
| 30 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 31 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
| 32 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 33 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
| 34 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
| 35 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| 36 | POSSIBILITY OF SUCH DAMAGE. | |
| 46 | 37 | |
| 38 | ***************************************************************************/ | |
| 47 | 39 | |
| 48 | /**************************************************************************** | |
| 49 | * The 6502 registers. | |
| 50 | ****************************************************************************/ | |
| 51 | struct m6502_Regs | |
| 52 | { | |
| 53 | UINT8 subtype; /* currently selected cpu sub type */ | |
| 54 | void (*const *insn)(m6502_Regs *); /* pointer to the function pointer table */ | |
| 55 | PAIR ppc; /* previous program counter */ | |
| 56 | PAIR pc; /* program counter */ | |
| 57 | PAIR sp; /* stack pointer (always 100 - 1FF) */ | |
| 58 | PAIR zp; /* zero page address */ | |
| 59 | PAIR ea; /* effective address */ | |
| 60 | UINT8 a; /* Accumulator */ | |
| 61 | UINT8 x; /* X index register */ | |
| 62 | UINT8 y; /* Y index register */ | |
| 63 | UINT8 p; /* Processor status */ | |
| 64 | UINT8 pending_irq; /* nonzero if an IRQ is pending */ | |
| 65 | UINT8 after_cli; /* pending IRQ and last insn cleared I */ | |
| 66 | UINT8 nmi_state; | |
| 67 | UINT8 irq_state; | |
| 68 | UINT8 so_state; | |
| 40 | #include "emu.h" | |
| 41 | #include "debugger.h" | |
| 42 | #include "m6502.h" | |
| 69 | 43 | |
| 70 | device_irq_acknowledge_callback irq_callback; | |
| 71 | legacy_cpu_device *device; | |
| 72 | address_space *space; | |
| 73 | direct_read_data *direct; | |
| 74 | address_space *io; | |
| 75 | int int_occured; | |
| 76 | int icount; | |
| 44 | const device_type M6502 = &device_creator<m6502_device>; | |
| 77 | 45 | |
| 78 | devcb_resolved_read8 rdmem_id; /* readmem callback for indexed instructions */ | |
| 79 | devcb_resolved_write8 wrmem_id; /* writemem callback for indexed instructions */ | |
| 46 | m6502_device::m6502_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : | |
| 47 | cpu_device(mconfig, M6502, "M6502", tag, owner, clock), | |
| 48 | program_config("program", ENDIANNESS_LITTLE, 8, 16) | |
| 49 | { | |
| 50 | direct_disabled = false; | |
| 51 | } | |
| 80 | 52 | |
| 81 | UINT8 ddr; | |
| 82 | UINT8 port; | |
| 83 | UINT8 mask; | |
| 84 | UINT8 pullup; | |
| 85 | UINT8 pulldown; | |
| 86 | ||
| 87 | devcb_resolved_read8 in_port_func; | |
| 88 | devcb_resolved_write8 out_port_func; | |
| 89 | }; | |
| 90 | ||
| 91 | INLINE m6502_Regs *get_safe_token(device_t *device) | |
| 53 | m6502_device::m6502_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) : | |
| 54 | cpu_device(mconfig, type, name, tag, owner, clock), | |
| 55 | program_config("program", ENDIANNESS_LITTLE, 8, 16) | |
| 92 | 56 | { |
| 93 | assert(device != NULL); | |
| 94 | assert(device->type() == M6502 || | |
| 95 | device->type() == M6504 || | |
| 96 | device->type() == M6510 || | |
| 97 | device->type() == M6510T || | |
| 98 | device->type() == M7501 || | |
| 99 | device->type() == M8502 || | |
| 100 | device->type() == N2A03 || | |
| 101 | device->type() == M65C02 || | |
| 102 | device->type() == M65SC02 || | |
| 103 | device->type() == DECO16); | |
| 104 | return (m6502_Regs *)downcast<legacy_cpu_device *>(device)->token(); | |
| 57 | direct_disabled = false; | |
| 105 | 58 | } |
| 106 | 59 | |
| 107 | /*************************************************************** | |
| 108 | * include the opcode macros, functions and tables | |
| 109 | ***************************************************************/ | |
| 110 | #include "t6502.c" | |
| 60 | void m6502_device::device_start() | |
| 61 | { | |
| 62 | if(direct_disabled) | |
| 63 | mintf = new mi_default_nd; | |
| 64 | else | |
| 65 | mintf = new mi_default_normal; | |
| 111 | 66 | |
| 112 | #include "t6510.c" | |
| 67 | init(); | |
| 68 | } | |
| 113 | 69 | |
| 114 | #include "opsn2a03.h" | |
| 70 | void m6502_device::init() | |
| 71 | { | |
| 72 | mintf->program = &space(AS_PROGRAM); | |
| 73 | mintf->direct = &mintf->program->direct(); | |
| 115 | 74 | |
| 116 | #include "tn2a03.c" | |
| 75 | state_add(STATE_GENPC, "GENPC", NPC).noshow(); | |
| 76 | state_add(STATE_GENPCBASE, "GENPCBASE", PPC).noshow(); | |
| 77 | state_add(STATE_GENSP, "GENSP", SP).noshow(); | |
| 78 | state_add(STATE_GENFLAGS, "GENFLAGS", P).callimport().formatstr("%6s").noshow(); | |
| 79 | state_add(M6502_PC, "PC", NPC); | |
| 80 | state_add(M6502_A, "A", A); | |
| 81 | state_add(M6502_X, "X", X); | |
| 82 | state_add(M6502_Y, "Y", Y); | |
| 83 | state_add(M6502_P, "P", P).callimport(); | |
| 84 | state_add(M6502_S, "SP", SP); | |
| 85 | state_add(M6502_IR, "IR", IR); | |
| 117 | 86 | |
| 118 | #include "opsc02.h" | |
| 87 | save_item(NAME(PC)); | |
| 88 | save_item(NAME(NPC)); | |
| 89 | save_item(NAME(A)); | |
| 90 | save_item(NAME(X)); | |
| 91 | save_item(NAME(Y)); | |
| 92 | save_item(NAME(P)); | |
| 93 | save_item(NAME(SP)); | |
| 94 | save_item(NAME(TMP)); | |
| 95 | save_item(NAME(TMP2)); | |
| 96 | save_item(NAME(IR)); | |
| 97 | save_item(NAME(nmi_state)); | |
| 98 | save_item(NAME(irq_state)); | |
| 99 | save_item(NAME(v_state)); | |
| 100 | save_item(NAME(inst_state)); | |
| 101 | save_item(NAME(inst_substate)); | |
| 102 | save_item(NAME(irq_taken)); | |
| 103 | save_item(NAME(inhibit_interrupts)); | |
| 119 | 104 | |
| 120 | ||
| 105 | m_icountptr = &icount; | |
| 121 | 106 | |
| 122 | #include "t65sc02.c" | |
| 107 | PC = 0x0000; | |
| 108 | NPC = 0x0000; | |
| 109 | A = 0x00; | |
| 110 | X = 0x80; | |
| 111 | Y = 0x00; | |
| 112 | P = 0x36; | |
| 113 | SP = 0x01bd; | |
| 114 | TMP = 0x0000; | |
| 115 | TMP2 = 0x00; | |
| 116 | IR = 0x00; | |
| 117 | nmi_state = false; | |
| 118 | irq_state = false; | |
| 119 | irq_taken = false; | |
| 120 | v_state = false; | |
| 121 | inst_state = STATE_RESET; | |
| 122 | inst_substate = 0; | |
| 123 | sync = false; | |
| 124 | end_cycles = 0; | |
| 125 | } | |
| 123 | 126 | |
| 124 | #include "tdeco16.c" | |
| 127 | void m6502_device::device_reset() | |
| 128 | { | |
| 129 | inst_state = STATE_RESET; | |
| 130 | inst_substate = 0; | |
| 131 | nmi_state = false; | |
| 132 | irq_state = false; | |
| 133 | irq_taken = false; | |
| 134 | v_state = false; | |
| 135 | end_cycles = 0; | |
| 136 | sync = false; | |
| 137 | inhibit_interrupts = false; | |
| 138 | } | |
| 125 | 139 | |
| 126 | /***************************************************************************** | |
| 127 | * | |
| 128 | * 6502 CPU interface functions | |
| 129 | * | |
| 130 | *****************************************************************************/ | |
| 131 | 140 | |
| 132 | ||
| 141 | UINT32 m6502_device::execute_min_cycles() const | |
| 133 | 142 | { |
| 134 | m6502_Regs *cpustate = get_safe_token(device); | |
| 135 | const m6502_interface *intf = (const m6502_interface *)device->static_config(); | |
| 143 | return 1; | |
| 144 | } | |
| 136 | 145 | |
| 137 | cpustate->irq_callback = irqcallback; | |
| 138 | cpustate->device = device; | |
| 139 | cpustate->space = &device->space(AS_PROGRAM); | |
| 140 | cpustate->direct = &cpustate->space->direct(); | |
| 141 | cpustate->subtype = subtype; | |
| 142 | cpustate->insn = insn; | |
| 143 | ||
| 144 | if ( intf ) | |
| 145 | { | |
| 146 | cpustate->rdmem_id.resolve(intf->read_indexed_func, *device); | |
| 147 | cpustate->wrmem_id.resolve(intf->write_indexed_func, *device); | |
| 148 | cpustate->in_port_func.resolve(intf->in_port_func, *device); | |
| 149 | cpustate->out_port_func.resolve(intf->out_port_func, *device); | |
| 150 | ||
| 151 | cpustate->pullup = intf->external_port_pullup; | |
| 152 | cpustate->pulldown = intf->external_port_pulldown; | |
| 153 | } | |
| 154 | else | |
| 155 | { | |
| 156 | devcb_read8 nullrcb = DEVCB_NULL; | |
| 157 | devcb_write8 nullwcb = DEVCB_NULL; | |
| 158 | ||
| 159 | cpustate->rdmem_id.resolve(nullrcb, *device); | |
| 160 | cpustate->wrmem_id.resolve(nullwcb, *device); | |
| 161 | cpustate->in_port_func.resolve(nullrcb, *device); | |
| 162 | cpustate->out_port_func.resolve(nullwcb, *device); | |
| 163 | ||
| 164 | cpustate->pullup = 0; | |
| 165 | cpustate->pulldown = 0; | |
| 166 | } | |
| 167 | ||
| 168 | device->save_item(NAME(cpustate->pc.w.l)); | |
| 169 | device->save_item(NAME(cpustate->sp.w.l)); | |
| 170 | device->save_item(NAME(cpustate->p)); | |
| 171 | device->save_item(NAME(cpustate->a)); | |
| 172 | device->save_item(NAME(cpustate->x)); | |
| 173 | device->save_item(NAME(cpustate->y)); | |
| 174 | device->save_item(NAME(cpustate->pending_irq)); | |
| 175 | device->save_item(NAME(cpustate->after_cli)); | |
| 176 | device->save_item(NAME(cpustate->nmi_state)); | |
| 177 | device->save_item(NAME(cpustate->irq_state)); | |
| 178 | device->save_item(NAME(cpustate->so_state)); | |
| 179 | ||
| 180 | if (subtype == SUBTYPE_6510) | |
| 181 | { | |
| 182 | device->save_item(NAME(cpustate->port)); | |
| 183 | device->save_item(NAME(cpustate->mask)); | |
| 184 | device->save_item(NAME(cpustate->ddr)); | |
| 185 | device->save_item(NAME(cpustate->pullup)); | |
| 186 | device->save_item(NAME(cpustate->pulldown)); | |
| 187 | } | |
| 146 | UINT32 m6502_device::execute_max_cycles() const | |
| 147 | { | |
| 148 | return 10; | |
| 188 | 149 | } |
| 189 | 150 | |
| 190 | ||
| 151 | UINT32 m6502_device::execute_input_lines() const | |
| 191 | 152 | { |
| 192 | | |
| 153 | return 3; | |
| 193 | 154 | } |
| 194 | 155 | |
| 195 | ||
| 156 | void m6502_device::do_adc_d(UINT8 val) | |
| 196 | 157 | { |
| 197 | m6502_Regs *cpustate = get_safe_token(device); | |
| 198 | /* wipe out the rest of the m6502 structure */ | |
| 199 | /* read the reset vector into PC */ | |
| 200 | PCL = RDMEM(M6502_RST_VEC); | |
| 201 | PCH = RDMEM(M6502_RST_VEC+1); | |
| 158 | UINT8 c = P & F_C ? 1 : 0; | |
| 159 | P &= ~(F_N|F_V|F_Z|F_C); | |
| 160 | UINT8 al = (A & 15) + (val & 15) + c; | |
| 161 | if(al > 9) | |
| 162 | al += 6; | |
| 163 | UINT8 ah = (A >> 4) + (val >> 4) + (al > 15); | |
| 164 | if(!UINT8(A + val + c)) | |
| 165 | P |= F_Z; | |
| 166 | else if(ah & 8) | |
| 167 | P |= F_N; | |
| 168 | if(~(A^val) & (A^(ah << 4)) & 0x80) | |
| 169 | P |= F_V; | |
| 170 | if(ah > 9) | |
| 171 | ah += 6; | |
| 172 | if(ah > 15) | |
| 173 | P |= F_C; | |
| 174 | A = (ah << 4) | (al & 15); | |
| 175 | } | |
| 202 | 176 | |
| 203 | cpustate->sp.d = 0x01ff; /* stack pointer starts at page 1 offset FF */ | |
| 204 | cpustate->p = F_T|F_I|F_Z|F_B|(P&F_D); /* set T, I and Z flags */ | |
| 205 | cpustate->pending_irq = 0; /* nonzero if an IRQ is pending */ | |
| 206 | cpustate->after_cli = 0; /* pending IRQ and last insn cleared I */ | |
| 207 | cpustate->irq_state = 0; | |
| 208 | cpustate->nmi_state = 0; | |
| 177 | void m6502_device::do_adc_nd(UINT8 val) | |
| 178 | { | |
| 179 | UINT16 sum; | |
| 180 | sum = A + val + (P & F_C ? 1 : 0); | |
| 181 | P &= ~(F_N|F_V|F_Z|F_C); | |
| 182 | if(!UINT8(sum)) | |
| 183 | P |= F_Z; | |
| 184 | else if(INT8(sum) < 0) | |
| 185 | P |= F_N; | |
| 186 | if(~(A^val) & (A^sum) & 0x80) | |
| 187 | P |= F_V; | |
| 188 | if(sum & 0xff00) | |
| 189 | P |= F_C; | |
| 190 | A = sum; | |
| 209 | 191 | } |
| 210 | 192 | |
| 211 | ||
| 193 | void m6502_device::do_adc(UINT8 val) | |
| 212 | 194 | { |
| 213 | /* nothing to do yet */ | |
| 195 | if(P & F_D) | |
| 196 | do_adc_d(val); | |
| 197 | else | |
| 198 | do_adc_nd(val); | |
| 214 | 199 | } |
| 215 | 200 | |
| 216 | ||
| 201 | void m6502_device::do_arr_nd() | |
| 217 | 202 | { |
| 218 | if( !(P & F_I) ) | |
| 219 | { | |
| 220 | EAD = M6502_IRQ_VEC; | |
| 221 | cpustate->icount -= 2; | |
| 222 | PUSH(PCH); | |
| 223 | PUSH(PCL); | |
| 224 | PUSH(P & ~F_B); | |
| 225 | P |= F_I; /* set I flag */ | |
| 226 | PCL = RDMEM(EAD); | |
| 227 | PCH = RDMEM(EAD+1); | |
| 228 | LOG(("M6502 '%s' takes IRQ ($%04x)\n", cpustate->device->tag(), PCD)); | |
| 229 | /* call back the cpuintrf to let it clear the line */ | |
| 230 | if (cpustate->irq_callback) (*cpustate->irq_callback)(cpustate->device, 0); | |
| 231 | } | |
| 232 | cpustate->pending_irq = 0; | |
| 203 | bool c = P & F_C; | |
| 204 | P &= ~(F_N|F_Z|F_C|F_V); | |
| 205 | A >>= 1; | |
| 206 | if(c) | |
| 207 | A |= 0x80; | |
| 208 | if(!A) | |
| 209 | P |= F_Z; | |
| 210 | else if(INT8(A)<0) | |
| 211 | P |= F_N; | |
| 212 | if(A & 0x40) | |
| 213 | P |= F_V|F_C; | |
| 214 | if(A & 0x20) | |
| 215 | P ^= F_V; | |
| 233 | 216 | } |
| 234 | 217 | |
| 235 | ||
| 218 | void m6502_device::do_arr_d() | |
| 236 | 219 | { |
| 237 | m6502_Regs *cpustate = get_safe_token(device); | |
| 220 | // The adc/ror interaction gives an extremely weird result | |
| 221 | bool c = P & F_C; | |
| 222 | P &= ~(F_N|F_Z|F_C|F_V); | |
| 223 | UINT8 a = A >> 1; | |
| 224 | if(c) | |
| 225 | a |= 0x80; | |
| 226 | if(!a) | |
| 227 | P |= F_Z; | |
| 228 | else if(INT8(a) < 0) | |
| 229 | P |= F_N; | |
| 230 | if((a ^ A) & 0x40) | |
| 231 | P |= F_V; | |
| 238 | 232 | |
| 239 | do | |
| 240 | { | |
| 241 | UINT8 op; | |
| 242 | PPC = PCD; | |
| 233 | if((A & 0x0f) >= 0x05) | |
| 234 | a = ((a + 6) & 0x0f) | (a & 0xf0); | |
| 243 | 235 | |
| 244 | debugger_instruction_hook(device, PCD); | |
| 245 | ||
| 246 | /* if an irq is pending, take it now */ | |
| 247 | if( cpustate->pending_irq ) | |
| 248 | m6502_take_irq(cpustate); | |
| 249 | ||
| 250 | op = RDOP(); | |
| 251 | (*cpustate->insn[op])(cpustate); | |
| 252 | ||
| 253 | /* check if the I flag was just reset (interrupts enabled) */ | |
| 254 | if( cpustate->after_cli ) | |
| 255 | { | |
| 256 | LOG(("M6502 '%s' after_cli was >0", cpustate->device->tag())); | |
| 257 | cpustate->after_cli = 0; | |
| 258 | if (cpustate->irq_state != CLEAR_LINE) | |
| 259 | { | |
| 260 | LOG((": irq line is asserted: set pending IRQ\n")); | |
| 261 | cpustate->pending_irq = 1; | |
| 262 | } | |
| 263 | else | |
| 264 | { | |
| 265 | LOG((": irq line is clear\n")); | |
| 266 | } | |
| 267 | } | |
| 268 | else { | |
| 269 | if ( cpustate->pending_irq == 2 ) { | |
| 270 | if ( cpustate->int_occured - cpustate->icount > 1 ) { | |
| 271 | cpustate->pending_irq = 1; | |
| 272 | } | |
| 273 | } | |
| 274 | if( cpustate->pending_irq == 1 ) | |
| 275 | m6502_take_irq(cpustate); | |
| 276 | if ( cpustate->pending_irq == 2 ) { | |
| 277 | cpustate->pending_irq = 1; | |
| 278 | } | |
| 279 | } | |
| 280 | ||
| 281 | } while (cpustate->icount > 0); | |
| 236 | if((A & 0xf0) >= 0x50) { | |
| 237 | a += 0x60; | |
| 238 | P |= F_C; | |
| 239 | } | |
| 240 | A = a; | |
| 282 | 241 | } |
| 283 | 242 | |
| 284 | ||
| 243 | void m6502_device::do_arr() | |
| 285 | 244 | { |
| 286 | if (irqline == INPUT_LINE_NMI) | |
| 287 | { | |
| 288 | if (cpustate->nmi_state == state) return; | |
| 289 | cpustate->nmi_state = state; | |
| 290 | if( state != CLEAR_LINE ) | |
| 291 | { | |
| 292 | LOG(( "M6502 '%s' set_nmi_line(ASSERT)\n", cpustate->device->tag())); | |
| 293 | EAD = M6502_NMI_VEC; | |
| 294 | cpustate->icount -= 2; | |
| 295 | PUSH(PCH); | |
| 296 | PUSH(PCL); | |
| 297 | PUSH(P & ~F_B); | |
| 298 | P |= F_I; /* set I flag */ | |
| 299 | PCL = RDMEM(EAD); | |
| 300 | PCH = RDMEM(EAD+1); | |
| 301 | LOG(("M6502 '%s' takes NMI ($%04x)\n", cpustate->device->tag(), PCD)); | |
| 302 | } | |
| 303 | } | |
| 245 | if(P & F_D) | |
| 246 | do_arr_d(); | |
| 304 | 247 | else |
| 305 | { | |
| 306 | if( irqline == M6502_SET_OVERFLOW ) | |
| 307 | { | |
| 308 | if( cpustate->so_state && !state ) | |
| 309 | { | |
| 310 | LOG(( "M6502 '%s' set overflow\n", cpustate->device->tag())); | |
| 311 | P|=F_V; | |
| 312 | } | |
| 313 | cpustate->so_state=state; | |
| 314 | return; | |
| 315 | } | |
| 316 | cpustate->irq_state = state; | |
| 317 | if( state != CLEAR_LINE ) | |
| 318 | { | |
| 319 | LOG(( "M6502 '%s' set_irq_line(ASSERT)\n", cpustate->device->tag())); | |
| 320 | cpustate->pending_irq = 1; | |
| 321 | // cpustate->pending_irq = 2; | |
| 322 | cpustate->int_occured = cpustate->icount; | |
| 323 | } | |
| 324 | } | |
| 248 | do_arr_nd(); | |
| 325 | 249 | } |
| 326 | 250 | |
| 327 | ||
| 328 | ||
| 329 | /**************************************************************************** | |
| 330 | * 2A03 section | |
| 331 | ****************************************************************************/ | |
| 332 | ||
| 333 | static CPU_INIT( n2a03 ) | |
| 251 | void m6502_device::do_cmp(UINT8 val1, UINT8 val2) | |
| 334 | 252 | { |
| 335 | m6502_common_init(device, irqcallback, SUBTYPE_2A03, insn2a03, "n2a03"); | |
| 253 | P &= ~(F_N|F_Z|F_C); | |
| 254 | UINT16 r = val1-val2; | |
| 255 | if(!r) | |
| 256 | P |= F_Z; | |
| 257 | else if(INT8(r) < 0) | |
| 258 | P |= F_N; | |
| 259 | if(!(r & 0xff00)) | |
| 260 | P |= F_C; | |
| 336 | 261 | } |
| 337 | 262 | |
| 338 | /* The N2A03 is integrally tied to its PSG (they're on the same die). | |
| 339 | Bit 7 of address $4011 (the PSG's DPCM control register), when set, | |
| 340 | causes an IRQ to be generated. This function allows the IRQ to be called | |
| 341 | from the PSG core when such an occasion arises. */ | |
| 342 | void n2a03_irq(device_t *device) | |
| 263 | void m6502_device::do_sbc_d(UINT8 val) | |
| 343 | 264 | { |
| 344 | m6502_Regs *cpustate = get_safe_token(device); | |
| 345 | ||
| 346 | m6502_take_irq(cpustate); | |
| 265 | UINT8 c = P & F_C ? 0 : 1; | |
| 266 | P &= ~(F_N|F_V|F_Z|F_C); | |
| 267 | UINT16 diff = A - val - c; | |
| 268 | UINT8 al = (A & 15) - (val & 15) - c; | |
| 269 | if(INT8(al) < 0) | |
| 270 | al -= 6; | |
| 271 | UINT8 ah = (A >> 4) - (val >> 4) - (INT8(al) < 0); | |
| 272 | if(!UINT8(diff)) | |
| 273 | P |= F_Z; | |
| 274 | else if(diff & 0x80) | |
| 275 | P |= F_N; | |
| 276 | if((A^val) & (A^diff) & 0x80) | |
| 277 | P |= F_V; | |
| 278 | if(!(diff & 0xff00)) | |
| 279 | P |= F_C; | |
| 280 | if(INT8(ah) < 0) | |
| 281 | ah -= 6; | |
| 282 | A = (ah << 4) | (al & 15); | |
| 347 | 283 | } |
| 348 | 284 | |
| 349 | ||
| 350 | /**************************************************************************** | |
| 351 | * 6510 section | |
| 352 | ****************************************************************************/ | |
| 353 | ||
| 354 | static CPU_INIT( m6510 ) | |
| 285 | void m6502_device::do_sbc_nd(UINT8 val) | |
| 355 | 286 | { |
| 356 | m6502_common_init(device, irqcallback, SUBTYPE_6510, insn6510, "m6510"); | |
| 287 | UINT16 diff = A - val - (P & F_C ? 0 : 1); | |
| 288 | P &= ~(F_N|F_V|F_Z|F_C); | |
| 289 | if(!UINT8(diff)) | |
| 290 | P |= F_Z; | |
| 291 | else if(INT8(diff) < 0) | |
| 292 | P |= F_N; | |
| 293 | if((A^val) & (A^diff) & 0x80) | |
| 294 | P |= F_V; | |
| 295 | if(!(diff & 0xff00)) | |
| 296 | P |= F_C; | |
| 297 | A = diff; | |
| 357 | 298 | } |
| 358 | 299 | |
| 359 | ||
| 300 | void m6502_device::do_sbc(UINT8 val) | |
| 360 | 301 | { |
| 361 | m6502_Regs *cpustate = get_safe_token(device); | |
| 362 | ||
| 363 | CPU_RESET_CALL(m6502); | |
| 364 | cpustate->port = 0xff; | |
| 365 | cpustate->mask = 0xff; | |
| 366 | cpustate->ddr = 0x00; | |
| 302 | if(P & F_D) | |
| 303 | do_sbc_d(val); | |
| 304 | else | |
| 305 | do_sbc_nd(val); | |
| 367 | 306 | } |
| 368 | 307 | |
| 369 | ||
| 308 | void m6502_device::do_bit(UINT8 val) | |
| 370 | 309 | { |
| 371 | m6502_Regs *cpustate = get_safe_token(device); | |
| 372 | return (cpustate->port & cpustate->ddr) | (cpustate->ddr ^ 0xff); | |
| 310 | P &= ~(F_N|F_Z|F_V); | |
| 311 | UINT8 r = A & val; | |
| 312 | if(!r) | |
| 313 | P |= F_Z; | |
| 314 | if(val & 0x80) | |
| 315 | P |= F_N; | |
| 316 | if(val & 0x40) | |
| 317 | P |= F_V; | |
| 373 | 318 | } |
| 374 | 319 | |
| 375 | ||
| 320 | UINT8 m6502_device::do_asl(UINT8 v) | |
| 376 | 321 | { |
| 377 | m6502_Regs *cpustate = get_safe_token(&space.device()); | |
| 378 | UINT8 result = 0x00; | |
| 379 | ||
| 380 | switch(offset) | |
| 381 | { | |
| 382 | case 0x0000: /* DDR */ | |
| 383 | result = cpustate->ddr; | |
| 384 | break; | |
| 385 | ||
| 386 | case 0x0001: /* Data Port */ | |
| 387 | { | |
| 388 | UINT8 input = cpustate->in_port_func(0) & ~cpustate->ddr; | |
| 389 | UINT8 mask = cpustate->mask & ~cpustate->ddr; | |
| 390 | UINT8 output = cpustate->port & cpustate->ddr; | |
| 391 | UINT8 pulldown = ~(cpustate->pulldown & ~cpustate->ddr); | |
| 392 | ||
| 393 | result = (input | mask | output) & (input | pulldown); | |
| 394 | } | |
| 395 | break; | |
| 396 | } | |
| 397 | ||
| 398 | return result; | |
| 322 | P &= ~(F_N|F_Z|F_C); | |
| 323 | UINT8 r = v<<1; | |
| 324 | if(!r) | |
| 325 | P |= F_Z; | |
| 326 | else if(INT8(r) < 0) | |
| 327 | P |= F_N; | |
| 328 | if(v & 0x80) | |
| 329 | P |= F_C; | |
| 330 | return r; | |
| 399 | 331 | } |
| 400 | 332 | |
| 401 | ||
| 333 | UINT8 m6502_device::do_lsr(UINT8 v) | |
| 402 | 334 | { |
| 403 | m6502_Regs *cpustate = get_safe_token(&space.device()); | |
| 404 | ||
| 405 | switch(offset) | |
| 406 | { | |
| 407 | case 0x0000: /* DDR */ | |
| 408 | if (cpustate->ddr != data) | |
| 409 | { | |
| 410 | cpustate->ddr = data; | |
| 411 | cpustate->mask = cpustate->port; | |
| 412 | } | |
| 413 | break; | |
| 414 | ||
| 415 | case 0x0001: /* Data Port */ | |
| 416 | cpustate->port = data; | |
| 417 | break; | |
| 418 | } | |
| 419 | ||
| 420 | UINT8 output = (cpustate->port & cpustate->ddr) | (cpustate->pullup & ~cpustate->ddr); | |
| 421 | ||
| 422 | cpustate->out_port_func(0, output); | |
| 423 | ||
| 424 | // TODO assert write with floating data lines | |
| 425 | //WRMEM(offset, 0xff); | |
| 335 | P &= ~(F_N|F_Z|F_C); | |
| 336 | if(v & 1) | |
| 337 | P |= F_C; | |
| 338 | v >>= 1; | |
| 339 | if(!v) | |
| 340 | P |= F_Z; | |
| 341 | return v; | |
| 426 | 342 | } |
| 427 | 343 | |
| 428 | static ADDRESS_MAP_START(m6510_mem, AS_PROGRAM, 8, legacy_cpu_device) | |
| 429 | AM_RANGE(0x0000, 0x0001) AM_READWRITE_LEGACY(m6510_read_0000, m6510_write_0000) | |
| 430 | ADDRESS_MAP_END | |
| 431 | ||
| 432 | ||
| 433 | ||
| 434 | /**************************************************************************** | |
| 435 | * 65C02 section | |
| 436 | ****************************************************************************/ | |
| 437 | ||
| 438 | static CPU_INIT( m65c02 ) | |
| 344 | UINT8 m6502_device::do_ror(UINT8 v) | |
| 439 | 345 | { |
| 440 | m6502_common_init(device, irqcallback, SUBTYPE_65C02, insn65c02, "m65c02"); | |
| 346 | bool c = P & F_C; | |
| 347 | P &= ~(F_N|F_Z|F_C); | |
| 348 | if(v & 1) | |
| 349 | P |= F_C; | |
| 350 | v >>= 1; | |
| 351 | if(c) | |
| 352 | v |= 0x80; | |
| 353 | if(!v) | |
| 354 | P |= F_Z; | |
| 355 | else if(INT8(v)<0) | |
| 356 | P |= F_N; | |
| 357 | return v; | |
| 441 | 358 | } |
| 442 | 359 | |
| 443 | ||
| 360 | UINT8 m6502_device::do_rol(UINT8 v) | |
| 444 | 361 | { |
| 445 | m6502_Regs *cpustate = get_safe_token(device); | |
| 446 | ||
| 447 | CPU_RESET_CALL(m6502); | |
| 448 | P &=~F_D; | |
| 362 | bool c = P & F_C; | |
| 363 | P &= ~(F_N|F_Z|F_C); | |
| 364 | if(v & 0x80) | |
| 365 | P |= F_C; | |
| 366 | v <<= 1; | |
| 367 | if(c) | |
| 368 | v |= 0x01; | |
| 369 | if(!v) | |
| 370 | P |= F_Z; | |
| 371 | else if(INT8(v)<0) | |
| 372 | P |= F_N; | |
| 373 | return v; | |
| 449 | 374 | } |
| 450 | 375 | |
| 451 | IN | |
| 376 | UINT8 m6502_device::do_asr(UINT8 v) | |
| 452 | 377 | { |
| 453 | if( !(P & F_I) ) | |
| 454 | { | |
| 455 | EAD = M6502_IRQ_VEC; | |
| 456 | cpustate->icount -= 2; | |
| 457 | PUSH(PCH); | |
| 458 | PUSH(PCL); | |
| 459 | PUSH(P & ~F_B); | |
| 460 | P = (P & ~F_D) | F_I; /* knock out D and set I flag */ | |
| 461 | PCL = RDMEM(EAD); | |
| 462 | PCH = RDMEM(EAD+1); | |
| 463 | LOG(("M65c02 '%s' takes IRQ ($%04x)\n", cpustate->device->tag(), PCD)); | |
| 464 | /* call back the cpuintrf to let it clear the line */ | |
| 465 | if (cpustate->irq_callback) (*cpustate->irq_callback)(cpustate->device, 0); | |
| 378 | P &= ~(F_N|F_Z|F_C); | |
| 379 | if(v & 1) | |
| 380 | P |= F_C; | |
| 381 | v >>= 1; | |
| 382 | if(!v) | |
| 383 | P |= F_Z; | |
| 384 | else if(v & 0x40) { | |
| 385 | P |= F_N; | |
| 386 | v |= 0x80; | |
| 466 | 387 | } |
| 467 | | |
| 388 | return v; | |
| 468 | 389 | } |
| 469 | 390 | |
| 470 | ||
| 391 | UINT64 m6502_device::get_cycle() | |
| 471 | 392 | { |
| 472 | m6502_Regs *cpustate = get_safe_token(device); | |
| 473 | ||
| 474 | do | |
| 475 | { | |
| 476 | UINT8 op; | |
| 477 | PPC = PCD; | |
| 478 | ||
| 479 | debugger_instruction_hook(device, PCD); | |
| 480 | ||
| 481 | op = RDOP(); | |
| 482 | (*cpustate->insn[op])(cpustate); | |
| 483 | ||
| 484 | /* if an irq is pending, take it now */ | |
| 485 | if( cpustate->pending_irq ) | |
| 486 | m65c02_take_irq(cpustate); | |
| 487 | ||
| 488 | ||
| 489 | /* check if the I flag was just reset (interrupts enabled) */ | |
| 490 | if( cpustate->after_cli ) | |
| 491 | { | |
| 492 | LOG(("M6502 '%s' after_cli was >0", cpustate->device->tag())); | |
| 493 | cpustate->after_cli = 0; | |
| 494 | if (cpustate->irq_state != CLEAR_LINE) | |
| 495 | { | |
| 496 | LOG((": irq line is asserted: set pending IRQ\n")); | |
| 497 | cpustate->pending_irq = 1; | |
| 498 | } | |
| 499 | else | |
| 500 | { | |
| 501 | LOG((": irq line is clear\n")); | |
| 502 | } | |
| 503 | } | |
| 504 | else | |
| 505 | if( cpustate->pending_irq ) | |
| 506 | m65c02_take_irq(cpustate); | |
| 507 | ||
| 508 | } while (cpustate->icount > 0); | |
| 393 | return end_cycles == 0 || icount <= 0 ? machine().time().as_ticks(clock()) : end_cycles - icount; | |
| 509 | 394 | } |
| 510 | 395 | |
| 511 | ||
| 396 | void m6502_device::execute_run() | |
| 512 | 397 | { |
| 513 | if (irqline == INPUT_LINE_NMI) | |
| 514 | { | |
| 515 | if (cpustate->nmi_state == state) return; | |
| 516 | cpustate->nmi_state = state; | |
| 517 | if( state != CLEAR_LINE ) | |
| 518 | { | |
| 519 | LOG(( "M6502 '%s' set_nmi_line(ASSERT)\n", cpustate->device->tag())); | |
| 520 | EAD = M6502_NMI_VEC; | |
| 521 | cpustate->icount -= 2; | |
| 522 | PUSH(PCH); | |
| 523 | PUSH(PCL); | |
| 524 | PUSH(P & ~F_B); | |
| 525 | P = (P & ~F_D) | F_I; /* knock out D and set I flag */ | |
| 526 | PCL = RDMEM(EAD); | |
| 527 | PCH = RDMEM(EAD+1); | |
| 528 | LOG(("M6502 '%s' takes NMI ($%04x)\n", cpustate->device->tag(), PCD)); | |
| 398 | end_cycles = machine().time().as_ticks(clock()) + icount; | |
| 399 | if(inst_substate) | |
| 400 | do_exec_partial(); | |
| 401 | ||
| 402 | while(icount > 0) { | |
| 403 | if(inst_state < 0x100) { | |
| 404 | PPC = NPC; | |
| 405 | inst_state = IR; | |
| 406 | if(machine().debug_flags & DEBUG_FLAG_ENABLED) | |
| 407 | debugger_instruction_hook(this, NPC); | |
| 529 | 408 | } |
| 409 | do_exec_full(); | |
| 530 | 410 | } |
| 531 | else | |
| 532 | m6502_set_irq_line(cpustate, irqline,state); | |
| 411 | end_cycles = 0; | |
| 533 | 412 | } |
| 534 | 413 | |
| 535 | /**************************************************************************** | |
| 536 | * 65SC02 section | |
| 537 | ****************************************************************************/ | |
| 538 | static CPU_INIT( m65sc02 ) | |
| 414 | void m6502_device::execute_set_input(int inputnum, int state) | |
| 539 | 415 | { |
| 540 | m6502_common_init(device, irqcallback, SUBTYPE_65SC02, insn65sc02, "m65sc02"); | |
| 416 | switch(inputnum) { | |
| 417 | case IRQ_LINE: irq_state = state == ASSERT_LINE; break; | |
| 418 | case NMI_LINE: nmi_state = nmi_state || (state == ASSERT_LINE); break; | |
| 419 | case V_LINE: | |
| 420 | if(!v_state && state == ASSERT_LINE) | |
| 421 | P |= F_V; | |
| 422 | v_state = state == ASSERT_LINE; | |
| 423 | break; | |
| 424 | } | |
| 541 | 425 | } |
| 542 | 426 | |
| 543 | /**************************************************************************** | |
| 544 | * DECO16 section | |
| 545 | ****************************************************************************/ | |
| 546 | 427 | |
| 547 | sta | |
| 428 | const address_space_config *m6502_device::memory_space_config(address_spacenum spacenum) const | |
| 548 | 429 | { |
| 549 | m6502_Regs *cpustate = get_safe_token(device); | |
| 550 | m6502_common_init(device, irqcallback, SUBTYPE_DECO16, insndeco16, "deco16"); | |
| 551 | cpustate->io = &device->space(AS_IO); | |
| 430 | return (spacenum == AS_PROGRAM) ? &program_config : NULL; | |
| 552 | 431 | } |
| 553 | 432 | |
| 554 | 433 | |
| 555 | static | |
| 434 | void m6502_device::state_import(const device_state_entry &entry) | |
| 556 | 435 | { |
| 557 | m6502_Regs *cpustate = get_safe_token(device); | |
| 436 | switch(entry.index()) { | |
| 437 | case STATE_GENFLAGS: | |
| 438 | case M6502_P: | |
| 439 | P = P | (F_B|F_E); | |
| 440 | break; | |
| 441 | } | |
| 442 | } | |
| 558 | 443 | |
| 559 | CPU_RESET_CALL(m6502); | |
| 560 | cpustate->subtype = SUBTYPE_DECO16; | |
| 561 | cpustate->insn = insndeco16; | |
| 562 | ||
| 563 | PCL = RDMEM(DECO16_RST_VEC+1); | |
| 564 | PCH = RDMEM(DECO16_RST_VEC); | |
| 565 | ||
| 566 | cpustate->sp.d = 0x01ff; /* stack pointer starts at page 1 offset FF */ | |
| 567 | cpustate->p = F_T|F_I|F_Z|F_B|(P&F_D); /* set T, I and Z flags */ | |
| 568 | cpustate->pending_irq = 0; /* nonzero if an IRQ is pending */ | |
| 569 | cpustate->after_cli = 0; /* pending IRQ and last insn cleared I */ | |
| 444 | void m6502_device::state_export(const device_state_entry &entry) | |
| 445 | { | |
| 570 | 446 | } |
| 571 | 447 | |
| 572 | ||
| 448 | void m6502_device::state_string_export(const device_state_entry &entry, astring &string) | |
| 573 | 449 | { |
| 574 | if( !(P & F_I) ) | |
| 575 | { | |
| 576 | EAD = DECO16_IRQ_VEC; | |
| 577 | cpustate->icount -= 2; | |
| 578 | PUSH(PCH); | |
| 579 | PUSH(PCL); | |
| 580 | PUSH(P & ~F_B); | |
| 581 | P |= F_I; /* set I flag */ | |
| 582 | PCL = RDMEM(EAD+1); | |
| 583 | PCH = RDMEM(EAD); | |
| 584 | LOG(("M6502 '%s' takes IRQ ($%04x)\n", cpustate->device->tag(), PCD)); | |
| 585 | /* call back the cpuintrf to let it clear the line */ | |
| 586 | if (cpustate->irq_callback) (*cpustate->irq_callback)(cpustate->device, 0); | |
| 450 | switch(entry.index()) { | |
| 451 | case STATE_GENFLAGS: | |
| 452 | case M6502_P: | |
| 453 | string.printf("%c%c%c%c%c%c", | |
| 454 | P & F_N ? 'N' : '.', | |
| 455 | P & F_V ? 'V' : '.', | |
| 456 | P & F_D ? 'D' : '.', | |
| 457 | P & F_I ? 'I' : '.', | |
| 458 | P & F_Z ? 'Z' : '.', | |
| 459 | P & F_C ? 'C' : '.'); | |
| 460 | break; | |
| 587 | 461 | } |
| 588 | cpustate->pending_irq = 0; | |
| 589 | 462 | } |
| 590 | 463 | |
| 591 | static void deco16_set_irq_line(m6502_Regs *cpustate, int irqline, int state) | |
| 464 | ||
| 465 | UINT32 m6502_device::disasm_min_opcode_bytes() const | |
| 592 | 466 | { |
| 593 | if (irqline == INPUT_LINE_NMI) | |
| 594 | { | |
| 595 | if (cpustate->nmi_state == state) return; | |
| 596 | cpustate->nmi_state = state; | |
| 597 | if( state != CLEAR_LINE ) | |
| 598 | { | |
| 599 | LOG(( "M6502 '%s' set_nmi_line(ASSERT)\n", cpustate->device->tag())); | |
| 600 | EAD = DECO16_NMI_VEC; | |
| 601 | cpustate->icount -= 7; | |
| 602 | PUSH(PCH); | |
| 603 | PUSH(PCL); | |
| 604 | PUSH(P & ~F_B); | |
| 605 | P |= F_I; /* set I flag */ | |
| 606 | PCL = RDMEM(EAD+1); | |
| 607 | PCH = RDMEM(EAD); | |
| 608 | LOG(("M6502 '%s' takes NMI ($%04x)\n", cpustate->device->tag(), PCD)); | |
| 609 | } | |
| 610 | } | |
| 611 | else | |
| 612 | { | |
| 613 | if( irqline == M6502_SET_OVERFLOW ) | |
| 614 | { | |
| 615 | if( cpustate->so_state && !state ) | |
| 616 | { | |
| 617 | LOG(( "M6502 '%s' set overflow\n", cpustate->device->tag())); | |
| 618 | P|=F_V; | |
| 619 | } | |
| 620 | cpustate->so_state=state; | |
| 621 | return; | |
| 622 | } | |
| 623 | cpustate->irq_state = state; | |
| 624 | if( state != CLEAR_LINE ) | |
| 625 | { | |
| 626 | LOG(( "M6502 '%s' set_irq_line(ASSERT)\n", cpustate->device->tag())); | |
| 627 | cpustate->pending_irq = 1; | |
| 628 | } | |
| 629 | } | |
| 467 | return 1; | |
| 630 | 468 | } |
| 631 | 469 | |
| 632 | ||
| 470 | UINT32 m6502_device::disasm_max_opcode_bytes() const | |
| 633 | 471 | { |
| 634 | m6502_Regs *cpustate = get_safe_token(device); | |
| 472 | return 4; | |
| 473 | } | |
| 635 | 474 | |
| 636 | do | |
| 637 | { | |
| 638 | UINT8 op; | |
| 639 | PPC = PCD; | |
| 475 | offs_t m6502_device::disassemble_generic(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options, const disasm_entry *table) | |
| 476 | { | |
| 477 | const disasm_entry &e = table[oprom[0]]; | |
| 478 | UINT32 flags = e.flags | DASMFLAG_SUPPORTED; | |
| 479 | buffer += sprintf(buffer, "%-5s", e.opcode); | |
| 480 | if(e.per_bit) | |
| 481 | buffer += sprintf(buffer, "%d, ", (oprom[0] >> 4) & 7); | |
| 640 | 482 | |
| 641 | debugger_instruction_hook(device, PCD); | |
| 483 | switch(table[oprom[0]].mode) { | |
| 484 | case DASM_non: | |
| 485 | flags |= 1; | |
| 486 | break; | |
| 642 | 487 | |
| 643 | op = RDOP(); | |
| 644 | (*cpustate->insn[op])(cpustate); | |
| 488 | case DASM_aba: | |
| 489 | sprintf(buffer, " $%02x%02x", opram[2], opram[1]); | |
| 490 | flags |= 3; | |
| 491 | break; | |
| 645 | 492 | |
| 646 | /* if an irq is pending, take it now */ | |
| 647 | if( cpustate->pending_irq ) | |
| 648 | deco16_take_irq(cpustate); | |
| 493 | case DASM_abx: | |
| 494 | sprintf(buffer, " $%02x%02x, x", opram[2], opram[1]); | |
| 495 | flags |= 3; | |
| 496 | break; | |
| 649 | 497 | |
| 498 | case DASM_aby: | |
| 499 | sprintf(buffer, " $%02x%02x, y", opram[2], opram[1]); | |
| 500 | flags |= 3; | |
| 501 | break; | |
| 650 | 502 | |
| 651 | /* check if the I flag was just reset (interrupts enabled) */ | |
| 652 | if( cpustate->after_cli ) | |
| 653 | { | |
| 654 | LOG(("M6502 %s after_cli was >0", cpustate->device->tag())); | |
| 655 | cpustate->after_cli = 0; | |
| 656 | if (cpustate->irq_state != CLEAR_LINE) | |
| 657 | { | |
| 658 | LOG((": irq line is asserted: set pending IRQ\n")); | |
| 659 | cpustate->pending_irq = 1; | |
| 660 | } | |
| 661 | else | |
| 662 | { | |
| 663 | LOG((": irq line is clear\n")); | |
| 664 | } | |
| 665 | } | |
| 666 | else | |
| 667 | if( cpustate->pending_irq ) | |
| 668 | deco16_take_irq(cpustate); | |
| 503 | case DASM_acc: | |
| 504 | sprintf(buffer, " a"); | |
| 505 | flags |= 1; | |
| 506 | break; | |
| 669 | 507 | |
| 670 | } while (cpustate->icount > 0); | |
| 671 | } | |
| 508 | case DASM_adr: | |
| 509 | sprintf(buffer, " $%02x%02x", opram[2], opram[1]); | |
| 510 | flags |= 3; | |
| 511 | break; | |
| 672 | 512 | |
| 513 | case DASM_bzp: | |
| 514 | sprintf(buffer, "%d $%02x", oprom[0] & 7, opram[1]); | |
| 515 | flags |= 2; | |
| 516 | break; | |
| 673 | 517 | |
| 674 | /************************************************************************** | |
| 675 | * Generic set_info | |
| 676 | **************************************************************************/ | |
| 518 | case DASM_iax: | |
| 519 | sprintf(buffer, " ($%02x%02x, x)", opram[2], opram[1]); | |
| 520 | flags |= 3; | |
| 521 | break; | |
| 677 | 522 | |
| 678 | static CPU_SET_INFO( m6502 ) | |
| 679 | { | |
| 680 | m6502_Regs *cpustate = get_safe_token(device); | |
| 523 | case DASM_idx: | |
| 524 | sprintf(buffer, " ($%02x, x)", opram[1]); | |
| 525 | flags |= 2; | |
| 526 | break; | |
| 681 | 527 | |
| 682 | switch (state) | |
| 683 | { | |
| 684 | /* --- the following bits of info are set as 64-bit signed integers --- */ | |
| 685 | case CPUINFO_INT_INPUT_STATE + M6502_IRQ_LINE: m6502_set_irq_line(cpustate, M6502_IRQ_LINE, info->i); break; | |
| 686 | case CPUINFO_INT_INPUT_STATE + M6502_SET_OVERFLOW: m6502_set_irq_line(cpustate, M6502_SET_OVERFLOW, info->i); break; | |
| 687 | case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI: m6502_set_irq_line(cpustate, INPUT_LINE_NMI, info->i); break; | |
| 528 | case DASM_idy: | |
| 529 | sprintf(buffer, " ($%02x), y", opram[1]); | |
| 530 | flags |= 2; | |
| 531 | break; | |
| 688 | 532 | |
| 689 | case CPUINFO_INT_PC: PCW = info->i; break; | |
| 690 | case CPUINFO_INT_REGISTER + M6502_PC: cpustate->pc.w.l = info->i; break; | |
| 691 | case CPUINFO_INT_SP: S = info->i; break; | |
| 692 | case CPUINFO_INT_REGISTER + M6502_S: cpustate->sp.b.l = info->i; break; | |
| 693 | case CPUINFO_INT_REGISTER + M6502_P: cpustate->p = info->i; break; | |
| 694 | case CPUINFO_INT_REGISTER + M6502_A: cpustate->a = info->i; break; | |
| 695 | case CPUINFO_INT_REGISTER + M6502_X: cpustate->x = info->i; break; | |
| 696 | case CPUINFO_INT_REGISTER + M6502_Y: cpustate->y = info->i; break; | |
| 697 | case CPUINFO_INT_REGISTER + M6502_EA: cpustate->ea.w.l = info->i; break; | |
| 698 | case CPUINFO_INT_REGISTER + M6502_ZP: cpustate->zp.w.l = info->i; break; | |
| 699 | } | |
| 700 | } | |
| 533 | case DASM_idz: | |
| 534 | sprintf(buffer, " ($%02x), z", opram[1]); | |
| 535 | flags |= 2; | |
| 536 | break; | |
| 701 | 537 | |
| 538 | case DASM_imm: | |
| 539 | sprintf(buffer, " #$%02x", opram[1]); | |
| 540 | flags |= 2; | |
| 541 | break; | |
| 702 | 542 | |
| 543 | case DASM_imp: | |
| 544 | flags |= 1; | |
| 545 | break; | |
| 703 | 546 | |
| 704 | /************************************************************************** | |
| 705 | * Generic get_info | |
| 706 | **************************************************************************/ | |
| 547 | case DASM_ind: | |
| 548 | sprintf(buffer, " ($%02x%02x)", opram[2], opram[1]); | |
| 549 | flags |= 3; | |
| 550 | break; | |
| 707 | 551 | |
| 708 | CPU_GET_INFO( m6502 ) | |
| 709 | { | |
| 710 | m6502_Regs *cpustate = (device != NULL && device->token() != NULL) ? get_safe_token(device) : NULL; | |
| 552 | case DASM_isy: | |
| 553 | sprintf(buffer, " ($%02x, s), y", opram[1]); | |
| 554 | flags |= 2; | |
| 555 | break; | |
| 711 | 556 | |
| 712 | switch (state) | |
| 713 | { | |
| 714 | /* --- the following bits of info are returned as 64-bit signed integers --- */ | |
| 715 | case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(m6502_Regs); break; | |
| 716 | case CPUINFO_INT_INPUT_LINES: info->i = 2; break; | |
| 717 | case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0; break; | |
| 718 | case CPUINFO_INT_ENDIANNESS: info->i = ENDIANNESS_LITTLE; break; | |
| 719 | case CPUINFO_INT_CLOCK_MULTIPLIER: info->i = 1; break; | |
| 720 | case CPUINFO_INT_CLOCK_DIVIDER: info->i = 1; break; | |
| 721 | case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 1; break; | |
| 722 | case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 4; break; | |
| 723 | case CPUINFO_INT_MIN_CYCLES: info->i = 1; break; | |
| 724 | case CPUINFO_INT_MAX_CYCLES: info->i = 10; break; | |
| 557 | case DASM_iw2: | |
| 558 | sprintf(buffer, " #$%02x%02x", opram[2], opram[1]); | |
| 559 | flags |= 3; | |
| 560 | break; | |
| 725 | 561 | |
| 726 | case CPUINFO_INT_DATABUS_WIDTH + AS_PROGRAM: info->i = 8; break; | |
| 727 | case CPUINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 16; break; | |
| 728 | case CPUINFO_INT_ADDRBUS_SHIFT + AS_PROGRAM: info->i = 0; break; | |
| 729 | case CPUINFO_INT_DATABUS_WIDTH + AS_DATA: info->i = 0; break; | |
| 730 | case CPUINFO_INT_ADDRBUS_WIDTH + AS_DATA: info->i = 0; break; | |
| 731 | case CPUINFO_INT_ADDRBUS_SHIFT + AS_DATA: info->i = 0; break; | |
| 732 | case CPUINFO_INT_DATABUS_WIDTH + AS_IO: info->i = 0; break; | |
| 733 | case CPUINFO_INT_ADDRBUS_WIDTH + AS_IO: info->i = 0; break; | |
| 734 | case CPUINFO_INT_ADDRBUS_SHIFT + AS_IO: info->i = 0; break; | |
| 562 | case DASM_iw3: | |
| 563 | sprintf(buffer, " #$%02x%02x%02x", opram[3], opram[2], opram[1]); | |
| 564 | flags |= 4; | |
| 565 | break; | |
| 735 | 566 | |
| 736 | case CPUINFO_INT_INPUT_STATE + M6502_IRQ_LINE: info->i = cpustate->irq_state; break; | |
| 737 | case CPUINFO_INT_INPUT_STATE + M6502_SET_OVERFLOW: info->i = cpustate->so_state; break; | |
| 738 | case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI: info->i = cpustate->nmi_state; break; | |
| 567 | case DASM_rel: | |
| 568 | sprintf(buffer, " $%04x", (pc & 0xf0000) | UINT16(pc + 2 + INT8(opram[1]))); | |
| 569 | flags |= 2; | |
| 570 | break; | |
| 739 | 571 | |
| 740 | case CPUINFO_INT_PREVIOUSPC: info->i = cpustate->ppc.w.l; break; | |
| 572 | case DASM_rw2: | |
| 573 | sprintf(buffer, " $%04x", (pc & 0xf0000) | UINT16(pc + 3 + INT16((opram[2] << 8) | opram[1]))); | |
| 574 | flags |= 3; | |
| 575 | break; | |
| 741 | 576 | |
| 742 | case CPUINFO_INT_PC: info->i = PCD; break; | |
| 743 | case CPUINFO_INT_REGISTER + M6502_PC: info->i = cpustate->pc.w.l; break; | |
| 744 | case CPUINFO_INT_SP: info->i = S; break; | |
| 745 | case CPUINFO_INT_REGISTER + M6502_S: info->i = cpustate->sp.b.l; break; | |
| 746 | case CPUINFO_INT_REGISTER + M6502_P: info->i = cpustate->p; break; | |
| 747 | case CPUINFO_INT_REGISTER + M6502_A: info->i = cpustate->a; break; | |
| 748 | case CPUINFO_INT_REGISTER + M6502_X: info->i = cpustate->x; break; | |
| 749 | case CPUINFO_INT_REGISTER + M6502_Y: info->i = cpustate->y; break; | |
| 750 | case CPUINFO_INT_REGISTER + M6502_EA: info->i = cpustate->ea.w.l; break; | |
| 751 | case CPUINFO_INT_REGISTER + M6502_ZP: info->i = cpustate->zp.w.l; break; | |
| 752 | case CPUINFO_INT_REGISTER + M6502_SUBTYPE: info->i = cpustate->subtype; break; | |
| 577 | case DASM_zpb: | |
| 578 | sprintf(buffer, "%d $%02x, $%04x", oprom[0] & 7, opram[1], (pc & 0xf0000) | UINT16(pc + 3 + INT8(opram[2]))); | |
| 579 | flags |= 3; | |
| 580 | break; | |
| 753 | 581 | |
| 754 | /* --- the following bits of info are returned as pointers to data or functions --- */ | |
| 755 | case CPUINFO_FCT_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(m6502); break; | |
| 756 | case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(m6502); break; | |
| 757 | case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(m6502); break; | |
| 758 | case CPUINFO_FCT_EXIT: info->exit = CPU_EXIT_NAME(m6502); break; | |
| 759 | case CPUINFO_FCT_EXECUTE: info->execute = CPU_EXECUTE_NAME(m6502); break; | |
| 760 | case CPUINFO_FCT_BURN: info->burn = NULL; break; | |
| 761 | case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(m6502); break; | |
| 762 | case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &cpustate->icount; break; | |
| 582 | case DASM_zpg: | |
| 583 | sprintf(buffer, " $%02x", opram[1]); | |
| 584 | flags |= 2; | |
| 585 | break; | |
| 763 | 586 | |
| 764 | /* --- the following bits of info are returned as NULL-terminated strings --- */ | |
| 765 | case CPUINFO_STR_NAME: strcpy(info->s, "M6502"); break; | |
| 766 | case CPUINFO_STR_FAMILY: strcpy(info->s, "Mostek 6502"); break; | |
| 767 | case CPUINFO_STR_VERSION: strcpy(info->s, "1.2"); break; | |
| 768 | case CPUINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break; | |
| 769 | case CPUINFO_STR_CREDITS: strcpy(info->s, "Copyright Juergen Buchmueller, all rights reserved."); break; | |
| 587 | case DASM_zpi: | |
| 588 | sprintf(buffer, " ($%02x)", opram[1]); | |
| 589 | flags |= 2; | |
| 590 | break; | |
| 770 | 591 | |
| 771 | case CPUINFO_STR_FLAGS: | |
| 772 | sprintf(info->s, "%c%c%c%c%c%c%c%c", | |
| 773 | cpustate->p & 0x80 ? 'N':'.', | |
| 774 | cpustate->p & 0x40 ? 'V':'.', | |
| 775 | cpustate->p & 0x20 ? 'R':'.', | |
| 776 | cpustate->p & 0x10 ? 'B':'.', | |
| 777 | cpustate->p & 0x08 ? 'D':'.', | |
| 778 | cpustate->p & 0x04 ? 'I':'.', | |
| 779 | cpustate->p & 0x02 ? 'Z':'.', | |
| 780 | cpustate->p & 0x01 ? 'C':'.'); | |
| 781 | break; | |
| 592 | case DASM_zpx: | |
| 593 | sprintf(buffer, " $%02x, x", opram[1]); | |
| 594 | flags |= 2; | |
| 595 | break; | |
| 782 | 596 | |
| 783 | case CPUINFO_STR_REGISTER + M6502_PC: sprintf(info->s, "PC:%04X", cpustate->pc.w.l); break; | |
| 784 | case CPUINFO_STR_REGISTER + M6502_S: sprintf(info->s, "S:%02X", cpustate->sp.b.l); break; | |
| 785 | case CPUINFO_STR_REGISTER + M6502_P: sprintf(info->s, "P:%02X", cpustate->p); break; | |
| 786 | case CPUINFO_STR_REGISTER + M6502_A: sprintf(info->s, "A:%02X", cpustate->a); break; | |
| 787 | case CPUINFO_STR_REGISTER + M6502_X: sprintf(info->s, "X:%02X", cpustate->x); break; | |
| 788 | case CPUINFO_STR_REGISTER + M6502_Y: sprintf(info->s, "Y:%02X", cpustate->y); break; | |
| 789 | case CPUINFO_STR_REGISTER + M6502_EA: sprintf(info->s, "EA:%04X", cpustate->ea.w.l); break; | |
| 790 | case CPUINFO_STR_REGISTER + M6502_ZP: sprintf(info->s, "ZP:%03X", cpustate->zp.w.l); break; | |
| 597 | case DASM_zpy: | |
| 598 | sprintf(buffer, " $%02x, y", opram[1]); | |
| 599 | flags |= 2; | |
| 600 | break; | |
| 601 | ||
| 602 | default: | |
| 603 | fprintf(stderr, "Unhandled dasm mode %d\n", table[oprom[0]].mode); | |
| 604 | abort(); | |
| 791 | 605 | } |
| 606 | return flags; | |
| 792 | 607 | } |
| 793 | 608 | |
| 794 | /************************************************************************** | |
| 795 | * CPU-specific set_info | |
| 796 | **************************************************************************/ | |
| 797 | ||
| 798 | CPU_GET_INFO( m6504 ) | |
| 609 | void m6502_device::prefetch() | |
| 799 | 610 | { |
| 800 | switch (state) | |
| 801 | { | |
| 802 | /* --- the following bits of info are returned as NULL-terminated strings --- */ | |
| 803 | case CPUINFO_STR_NAME: strcpy(info->s, "M6504"); break; | |
| 804 | case CPUINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 13; break; | |
| 611 | sync = true; | |
| 612 | NPC = PC; | |
| 613 | IR = mintf->read_decrypted(PC); | |
| 614 | sync = false; | |
| 805 | 615 | |
| 806 | default: CPU_GET_INFO_CALL(m6502); break; | |
| 807 | } | |
| 616 | if((nmi_state || (irq_state && !(P & F_I))) && !inhibit_interrupts) { | |
| 617 | irq_taken = true; | |
| 618 | IR = 0x00; | |
| 619 | } else | |
| 620 | PC++; | |
| 808 | 621 | } |
| 809 | 622 | |
| 810 | /************************************************************************** | |
| 811 | * CPU-specific set_info | |
| 812 | **************************************************************************/ | |
| 813 | ||
| 814 | CPU_GET_INFO( n2a03 ) | |
| 623 | void m6502_device::prefetch_noirq() | |
| 815 | 624 | { |
| 816 | switch (state) | |
| 817 | { | |
| 818 | /* --- the following bits of info are returned as pointers to data or functions --- */ | |
| 819 | case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(n2a03); break; | |
| 820 | ||
| 821 | /* --- the following bits of info are returned as NULL-terminated strings --- */ | |
| 822 | case CPUINFO_STR_NAME: strcpy(info->s, "N2A03"); break; | |
| 823 | ||
| 824 | default: CPU_GET_INFO_CALL(m6502); break; | |
| 825 | } | |
| 625 | sync = true; | |
| 626 | NPC = PC; | |
| 627 | IR = mintf->read_decrypted(PC); | |
| 628 | sync = false; | |
| 629 | PC++; | |
| 826 | 630 | } |
| 827 | 631 | |
| 828 | ||
| 829 | /************************************************************************** | |
| 830 | * CPU-specific set_info | |
| 831 | **************************************************************************/ | |
| 832 | ||
| 833 | static CPU_SET_INFO( m6510 ) | |
| 632 | void m6502_device::set_nz(UINT8 v) | |
| 834 | 633 | { |
| 835 | switch (state) | |
| 836 | { | |
| 837 | default: CPU_SET_INFO_CALL(m6502); break; | |
| 838 | } | |
| 634 | P &= ~(F_Z|F_N); | |
| 635 | if(v & 0x80) | |
| 636 | P |= F_N; | |
| 637 | if(!v) | |
| 638 | P |= F_Z; | |
| 839 | 639 | } |
| 840 | 640 | |
| 841 | ||
| 641 | offs_t m6502_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) | |
| 842 | 642 | { |
| 843 | switch (state) | |
| 844 | { | |
| 845 | /* --- the following bits of info are returned as pointers to data or functions --- */ | |
| 846 | case CPUINFO_FCT_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(m6510); break; | |
| 847 | case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(m6510); break; | |
| 848 | case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(m6510); break; | |
| 849 | case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(m6510); break; | |
| 850 | case CPUINFO_PTR_INTERNAL_MEMORY_MAP + AS_PROGRAM: info->internal_map8 = ADDRESS_MAP_NAME(m6510_mem); break; | |
| 851 | ||
| 852 | /* --- the following bits of info are returned as NULL-terminated strings --- */ | |
| 853 | case CPUINFO_STR_NAME: strcpy(info->s, "M6510"); break; | |
| 854 | ||
| 855 | default: CPU_GET_INFO_CALL(m6502); break; | |
| 856 | } | |
| 643 | return disassemble_generic(buffer, pc, oprom, opram, options, disasm_entries); | |
| 857 | 644 | } |
| 858 | 645 | |
| 859 | 646 | |
| 860 | /************************************************************************** | |
| 861 | * CPU-specific set_info | |
| 862 | **************************************************************************/ | |
| 863 | ||
| 864 | CPU_GET_INFO( m6510t ) | |
| 647 | UINT8 m6502_device::memory_interface::read_9(UINT16 adr) | |
| 865 | 648 | { |
| 866 | switch (state) | |
| 867 | { | |
| 868 | /* --- the following bits of info are returned as NULL-terminated strings --- */ | |
| 869 | case CPUINFO_STR_NAME: strcpy(info->s, "M6510T"); break; | |
| 870 | ||
| 871 | default: CPU_GET_INFO_CALL(m6510); break; | |
| 872 | } | |
| 649 | return read(adr); | |
| 873 | 650 | } |
| 874 | 651 | |
| 875 | ||
| 876 | /************************************************************************** | |
| 877 | * CPU-specific set_info | |
| 878 | **************************************************************************/ | |
| 879 | ||
| 880 | CPU_GET_INFO( m7501 ) | |
| 652 | void m6502_device::memory_interface::write_9(UINT16 adr, UINT8 val) | |
| 881 | 653 | { |
| 882 | switch (state) | |
| 883 | { | |
| 884 | /* --- the following bits of info are returned as NULL-terminated strings --- */ | |
| 885 | case CPUINFO_STR_NAME: strcpy(info->s, "M7501"); break; | |
| 886 | ||
| 887 | default: CPU_GET_INFO_CALL(m6510); break; | |
| 888 | } | |
| 654 | write(adr, val); | |
| 889 | 655 | } |
| 890 | 656 | |
| 891 | 657 | |
| 892 | /************************************************************************** | |
| 893 | * CPU-specific set_info | |
| 894 | **************************************************************************/ | |
| 895 | ||
| 896 | CPU_GET_INFO( m8502 ) | |
| 658 | UINT8 m6502_device::mi_default_normal::read(UINT16 adr) | |
| 897 | 659 | { |
| 898 | switch (state) | |
| 899 | { | |
| 900 | /* --- the following bits of info are returned as NULL-terminated strings --- */ | |
| 901 | case CPUINFO_STR_NAME: strcpy(info->s, "M8502"); break; | |
| 902 | ||
| 903 | default: CPU_GET_INFO_CALL(m6510); break; | |
| 904 | } | |
| 660 | return program->read_byte(adr); | |
| 905 | 661 | } |
| 906 | 662 | |
| 907 | ||
| 908 | /************************************************************************** | |
| 909 | * CPU-specific set_info | |
| 910 | **************************************************************************/ | |
| 911 | ||
| 912 | static CPU_SET_INFO( m65c02 ) | |
| 663 | UINT8 m6502_device::mi_default_normal::read_direct(UINT16 adr) | |
| 913 | 664 | { |
| 914 | m6502_Regs *cpustate = get_safe_token(device); | |
| 915 | ||
| 916 | switch (state) | |
| 917 | { | |
| 918 | /* --- the following bits of info are set as 64-bit signed integers --- */ | |
| 919 | case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI: m65c02_set_irq_line(cpustate, INPUT_LINE_NMI, info->i); break; | |
| 920 | ||
| 921 | default: CPU_SET_INFO_CALL(m6502); break; | |
| 922 | } | |
| 665 | return direct->read_raw_byte(adr); | |
| 923 | 666 | } |
| 924 | 667 | |
| 925 | ||
| 668 | UINT8 m6502_device::mi_default_normal::read_decrypted(UINT16 adr) | |
| 926 | 669 | { |
| 927 | switch (state) | |
| 928 | { | |
| 929 | /* --- the following bits of info are returned as pointers to data or functions --- */ | |
| 930 | case CPUINFO_FCT_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(m65c02); break; | |
| 931 | case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(m65c02); break; | |
| 932 | case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(m65c02); break; | |
| 933 | case CPUINFO_FCT_EXECUTE: info->execute = CPU_EXECUTE_NAME(m65c02); break; | |
| 934 | case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(m65c02); break; | |
| 935 | ||
| 936 | /* --- the following bits of info are returned as NULL-terminated strings --- */ | |
| 937 | case CPUINFO_STR_NAME: strcpy(info->s, "M65C02"); break; | |
| 938 | ||
| 939 | default: CPU_GET_INFO_CALL(m6502); break; | |
| 940 | } | |
| 670 | return direct->read_decrypted_byte(adr); | |
| 941 | 671 | } |
| 942 | 672 | |
| 943 | ||
| 944 | /************************************************************************** | |
| 945 | * CPU-specific set_info | |
| 946 | **************************************************************************/ | |
| 947 | ||
| 948 | CPU_GET_INFO( m65sc02 ) | |
| 673 | void m6502_device::mi_default_normal::write(UINT16 adr, UINT8 val) | |
| 949 | 674 | { |
| 950 | switch (state) | |
| 951 | { | |
| 952 | /* --- the following bits of info are returned as pointers to data or functions --- */ | |
| 953 | case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(m65sc02); break; | |
| 954 | case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(m65sc02); break; | |
| 955 | ||
| 956 | /* --- the following bits of info are returned as NULL-terminated strings --- */ | |
| 957 | case CPUINFO_STR_NAME: strcpy(info->s, "M65SC02"); break; | |
| 958 | case CPUINFO_STR_FAMILY: strcpy(info->s, "Metal Oxid Semiconductor MOS 6502"); break; | |
| 959 | case CPUINFO_STR_VERSION: strcpy(info->s, "1.0beta"); break; | |
| 960 | case CPUINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break; | |
| 961 | case CPUINFO_STR_CREDITS: strcpy(info->s, "Copyright Juergen Buchmueller\nCopyright Peter Trauner\nall rights reserved."); break; | |
| 962 | ||
| 963 | default: CPU_GET_INFO_CALL(m65c02); break; | |
| 964 | } | |
| 675 | program->write_byte(adr, val); | |
| 965 | 676 | } |
| 966 | 677 | |
| 967 | ||
| 968 | /************************************************************************** | |
| 969 | * CPU-specific set_info | |
| 970 | **************************************************************************/ | |
| 971 | ||
| 972 | static CPU_SET_INFO( deco16 ) | |
| 678 | UINT8 m6502_device::mi_default_nd::read_direct(UINT16 adr) | |
| 973 | 679 | { |
| 974 | m6502_Regs *cpustate = get_safe_token(device); | |
| 975 | ||
| 976 | switch (state) | |
| 977 | { | |
| 978 | /* --- the following bits of info are set as 64-bit signed integers --- */ | |
| 979 | case CPUINFO_INT_INPUT_STATE + M6502_IRQ_LINE: deco16_set_irq_line(cpustate, M6502_IRQ_LINE, info->i); break; | |
| 980 | case CPUINFO_INT_INPUT_STATE + M6502_SET_OVERFLOW: deco16_set_irq_line(cpustate, M6502_SET_OVERFLOW, info->i); break; | |
| 981 | case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI: deco16_set_irq_line(cpustate, INPUT_LINE_NMI, info->i); break; | |
| 982 | ||
| 983 | default: CPU_SET_INFO_CALL(m6502); break; | |
| 984 | } | |
| 680 | return read(adr); | |
| 985 | 681 | } |
| 986 | 682 | |
| 987 | ||
| 683 | UINT8 m6502_device::mi_default_nd::read_decrypted(UINT16 adr) | |
| 988 | 684 | { |
| 989 | switch (state) | |
| 990 | { | |
| 991 | /* --- the following bits of info are returned as 64-bit signed integers --- */ | |
| 992 | case CPUINFO_INT_DATABUS_WIDTH + AS_IO: info->i = 8; break; | |
| 993 | case CPUINFO_INT_ADDRBUS_WIDTH + AS_IO: info->i = 8; break; | |
| 994 | ||
| 995 | /* --- the following bits of info are returned as pointers to data or functions --- */ | |
| 996 | case CPUINFO_FCT_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(deco16); break; | |
| 997 | case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(deco16); break; | |
| 998 | case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(deco16); break; | |
| 999 | case CPUINFO_FCT_EXECUTE: info->execute = CPU_EXECUTE_NAME(deco16); break; | |
| 1000 | case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(deco16); break; | |
| 1001 | ||
| 1002 | /* --- the following bits of info are returned as NULL-terminated strings --- */ | |
| 1003 | case CPUINFO_STR_NAME: strcpy(info->s, "DECO CPU16"); break; | |
| 1004 | case CPUINFO_STR_FAMILY: strcpy(info->s, "DECO"); break; | |
| 1005 | case CPUINFO_STR_VERSION: strcpy(info->s, "0.1"); break; | |
| 1006 | case CPUINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break; | |
| 1007 | case CPUINFO_STR_CREDITS: strcpy(info->s, "Copyright Juergen Buchmueller\nCopyright Bryan McPhail\nall rights reserved."); break; | |
| 1008 | ||
| 1009 | default: CPU_GET_INFO_CALL(m6502); break; | |
| 1010 | } | |
| 685 | return read(adr); | |
| 1011 | 686 | } |
| 1012 | 687 | |
| 1013 | DEFINE_LEGACY_CPU_DEVICE(M6502, m6502); | |
| 1014 | DEFINE_LEGACY_CPU_DEVICE(M6504, m6504); | |
| 1015 | DEFINE_LEGACY_CPU_DEVICE(M6510, m6510); | |
| 1016 | DEFINE_LEGACY_CPU_DEVICE(M6510T, m6510t); | |
| 1017 | DEFINE_LEGACY_CPU_DEVICE(M7501, m7501); | |
| 1018 | DEFINE_LEGACY_CPU_DEVICE(M8502, m8502); | |
| 1019 | DEFINE_LEGACY_CPU_DEVICE(N2A03, n2a03); | |
| 1020 | DEFINE_LEGACY_CPU_DEVICE(M65C02, m65c02); | |
| 1021 | DEFINE_LEGACY_CPU_DEVICE(M65SC02, m65sc02); | |
| 1022 | DEFINE_LEGACY_CPU_DEVICE(DECO16, deco16); | |
| 688 | #include "cpu/m6502/m6502.inc" |
| r18874 | r18875 | |
|---|---|---|
| 1 | /*************************************************************************** | |
| 2 | ||
| 3 | m8502.c | |
| 4 | ||
| 5 | 6510 derivative, capable of running at 2MHz. | |
| 6 | ||
| 7 | **************************************************************************** | |
| 8 | ||
| 9 | Copyright Olivier Galibert | |
| 10 | All rights reserved. | |
| 11 | ||
| 12 | Redistribution and use in source and binary forms, with or without | |
| 13 | modification, are permitted provided that the following conditions are | |
| 14 | met: | |
| 15 | ||
| 16 | * Redistributions of source code must retain the above copyright | |
| 17 | notice, this list of conditions and the following disclaimer. | |
| 18 | * Redistributions in binary form must reproduce the above copyright | |
| 19 | notice, this list of conditions and the following disclaimer in | |
| 20 | the documentation and/or other materials provided with the | |
| 21 | distribution. | |
| 22 | * Neither the name 'MAME' nor the names of its contributors may be | |
| 23 | used to endorse or promote products derived from this software | |
| 24 | without specific prior written permission. | |
| 25 | ||
| 26 | THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR | |
| 27 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 28 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 29 | DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, | |
| 30 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 31 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
| 32 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 33 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
| 34 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
| 35 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| 36 | POSSIBILITY OF SUCH DAMAGE. | |
| 37 | ||
| 38 | ***************************************************************************/ | |
| 39 | ||
| 40 | #include "emu.h" | |
| 41 | #include "m8502.h" | |
| 42 | ||
| 43 | const device_type M8502 = &device_creator<m8502_device>; | |
| 44 | ||
| 45 | m8502_device::m8502_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : | |
| 46 | m6510_device(mconfig, M8502, "M8502", tag, owner, clock) | |
| 47 | { | |
| 48 | } |
| r18874 | r18875 | |
|---|---|---|
| 1 | /*************************************************************************** | |
| 2 | ||
| 3 | m6504.c | |
| 4 | ||
| 5 | Mostek 6502, NMOS variant with reduced address bus | |
| 6 | ||
| 7 | **************************************************************************** | |
| 8 | ||
| 9 | Copyright Olivier Galibert | |
| 10 | All rights reserved. | |
| 11 | ||
| 12 | Redistribution and use in source and binary forms, with or without | |
| 13 | modification, are permitted provided that the following conditions are | |
| 14 | met: | |
| 15 | ||
| 16 | * Redistributions of source code must retain the above copyright | |
| 17 | notice, this list of conditions and the following disclaimer. | |
| 18 | * Redistributions in binary form must reproduce the above copyright | |
| 19 | notice, this list of conditions and the following disclaimer in | |
| 20 | the documentation and/or other materials provided with the | |
| 21 | distribution. | |
| 22 | * Neither the name 'MAME' nor the names of its contributors may be | |
| 23 | used to endorse or promote products derived from this software | |
| 24 | without specific prior written permission. | |
| 25 | ||
| 26 | THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR | |
| 27 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 28 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 29 | DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, | |
| 30 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 31 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
| 32 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 33 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
| 34 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
| 35 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| 36 | POSSIBILITY OF SUCH DAMAGE. | |
| 37 | ||
| 38 | ***************************************************************************/ | |
| 39 | ||
| 40 | #include "emu.h" | |
| 41 | #include "m6504.h" | |
| 42 | ||
| 43 | const device_type M6504 = &device_creator<m6504_device>; | |
| 44 | ||
| 45 | m6504_device::m6504_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : | |
| 46 | m6502_device(mconfig, M6504, "M6504", tag, owner, clock) | |
| 47 | { | |
| 48 | program_config.m_addrbus_width = 13; | |
| 49 | } | |
| 50 | ||
| 51 | void m6504_device::device_start() | |
| 52 | { | |
| 53 | if(direct_disabled) | |
| 54 | mintf = new mi_6504_nd; | |
| 55 | else | |
| 56 | mintf = new mi_6504_normal; | |
| 57 | ||
| 58 | init(); | |
| 59 | } | |
| 60 | ||
| 61 | UINT8 m6504_device::mi_6504_normal::read(UINT16 adr) | |
| 62 | { | |
| 63 | return program->read_byte(adr & 0x1fff); | |
| 64 | } | |
| 65 | ||
| 66 | UINT8 m6504_device::mi_6504_normal::read_direct(UINT16 adr) | |
| 67 | { | |
| 68 | return direct->read_raw_byte(adr & 0x1fff); | |
| 69 | } | |
| 70 | ||
| 71 | UINT8 m6504_device::mi_6504_normal::read_decrypted(UINT16 adr) | |
| 72 | { | |
| 73 | return direct->read_decrypted_byte(adr & 0x1fff); | |
| 74 | } | |
| 75 | ||
| 76 | void m6504_device::mi_6504_normal::write(UINT16 adr, UINT8 val) | |
| 77 | { | |
| 78 | program->write_byte(adr & 0x1fff, val); | |
| 79 | } | |
| 80 | ||
| 81 | UINT8 m6504_device::mi_6504_nd::read_direct(UINT16 adr) | |
| 82 | { | |
| 83 | return read(adr); | |
| 84 | } | |
| 85 | ||
| 86 | UINT8 m6504_device::mi_6504_nd::read_decrypted(UINT16 adr) | |
| 87 | { | |
| 88 | return read(adr); | |
| 89 | } |
| r18874 | r18875 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * m6502.h | |
| 4 | * Portable 6502/65c02/65sc02/6510/n2a03 emulator interface | |
| 5 | * | |
| 6 | * Copyright Juergen Buchmueller, all rights reserved. | |
| 7 | * 65sc02 core Copyright Peter Trauner. | |
| 8 | * Deco16 portions Copyright Bryan McPhail. | |
| 9 | * | |
| 10 | * - This source code is released as freeware for non-commercial purposes. | |
| 11 | * - You are free to use and redistribute this code in modified or | |
| 12 | * unmodified form, provided you list me in the credits. | |
| 13 | * - If you modify this source code, you must add a notice to each modified | |
| 14 | * source file that it has been changed. If you're a nice person, you | |
| 15 | * will clearly mark each change too. :) | |
| 16 | * - If you wish to use this for commercial purposes, please contact me at | |
| 17 | * pullmoll@t-online.de | |
| 18 | * - The author of this copywritten work reserves the right to change the | |
| 19 | * terms of its usage and license at any time, including retroactively | |
| 20 | * - This entire notice must remain in the source code. | |
| 21 | * | |
| 22 | *****************************************************************************/ | |
| 23 | /* 2.February 2000 PeT added 65sc02 subtype */ | |
| 1 | /*************************************************************************** | |
| 24 | 2 | |
| 25 | ||
| 3 | m6502.h | |
| 26 | 4 | |
| 27 | #ifndef __M6502_H__ | |
| 28 | #define __M6502_H__ | |
| 5 | Mostek 6502, original NMOS variant | |
| 29 | 6 | |
| 7 | **************************************************************************** | |
| 30 | 8 | |
| 31 | /* set to 1 to test cur_mrhard/cur_wmhard to avoid calls */ | |
| 32 | #define FAST_MEMORY 0 | |
| 9 | Copyright Olivier Galibert | |
| 10 | All rights reserved. | |
| 33 | 11 | |
| 34 | #define SUBTYPE_6502 0 | |
| 35 | #define SUBTYPE_65C02 1 | |
| 36 | #define SUBTYPE_6510 2 | |
| 37 | #define SUBTYPE_2A03 3 | |
| 38 | #define SUBTYPE_65SC02 4 | |
| 39 | #define SUBTYPE_DECO16 5 | |
| 12 | Redistribution and use in source and binary forms, with or without | |
| 13 | modification, are permitted provided that the following conditions are | |
| 14 | met: | |
| 40 | 15 | |
| 41 | enum | |
| 42 | { | |
| 43 | M6502_PC=1, M6502_S, M6502_P, M6502_A, M6502_X, M6502_Y, | |
| 44 | M6502_EA, M6502_ZP, | |
| 45 | M6502_SUBTYPE | |
| 46 | }; | |
| 16 | * Redistributions of source code must retain the above copyright | |
| 17 | notice, this list of conditions and the following disclaimer. | |
| 18 | * Redistributions in binary form must reproduce the above copyright | |
| 19 | notice, this list of conditions and the following disclaimer in | |
| 20 | the documentation and/or other materials provided with the | |
| 21 | distribution. | |
| 22 | * Neither the name 'MAME' nor the names of its contributors may be | |
| 23 | used to endorse or promote products derived from this software | |
| 24 | without specific prior written permission. | |
| 47 | 25 | |
| 48 | #define M6502_IRQ_LINE 0 | |
| 49 | /* use cpudevice->execute().set_input_line(M6502_SET_OVERFLOW, level) | |
| 50 | to change level of the so input line | |
| 51 | positiv edge sets overflow flag */ | |
| 52 | #define M6502_SET_OVERFLOW 1 | |
| 26 | THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR | |
| 27 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 28 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 29 | DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, | |
| 30 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 31 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
| 32 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 33 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
| 34 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
| 35 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| 36 | POSSIBILITY OF SUCH DAMAGE. | |
| 53 | 37 | |
| 38 | ***************************************************************************/ | |
| 54 | 39 | |
| 55 | /* Optional interface to set callbacks */ | |
| 56 | #define M6510_INTERFACE(name) \ | |
| 57 | const m6502_interface (name) = | |
| 40 | #ifndef __M6502FAM_H__ | |
| 41 | #define __M6502FAM_H__ | |
| 58 | 42 | |
| 59 | struct m6502_interface | |
| 60 | { | |
| 61 | devcb_read8 read_indexed_func; | |
| 62 | devcb_write8 write_indexed_func; | |
| 63 | devcb_read8 in_port_func; | |
| 64 | devcb_write8 out_port_func; | |
| 65 | UINT8 external_port_pullup; | |
| 66 | UINT8 external_port_pulldown; | |
| 67 | }; | |
| 43 | #define MCFG_M6502_DISABLE_DIRECT() \ | |
| 44 | downcast<m6502_device *>(device)->disable_direct(); | |
| 68 | 45 | |
| 69 | DECLARE_LEGACY_CPU_DEVICE(M6502, m6502); | |
| 70 | DECLARE_LEGACY_CPU_DEVICE(M6504, m6504); | |
| 71 | extern CPU_DISASSEMBLE( m6502 ); | |
| 46 | class m6502_device : public cpu_device { | |
| 47 | public: | |
| 48 | enum { | |
| 49 | IRQ_LINE, NMI_LINE, V_LINE | |
| 50 | }; | |
| 72 | 51 | |
| 73 | /**************************************************************************** | |
| 74 | * The 6510 | |
| 75 | ****************************************************************************/ | |
| 76 | #define M6510_A M6502_A | |
| 77 | #define M6510_X M6502_X | |
| 78 | #define M6510_Y M6502_Y | |
| 79 | #define M6510_S M6502_S | |
| 80 | #define M6510_PC M6502_PC | |
| 81 | #define M6510_P M6502_P | |
| 82 | #define M6510_EA M6502_EA | |
| 83 | #define M6510_ZP M6502_ZP | |
| 84 | #define M6510_NMI_STATE M6502_NMI_STATE | |
| 85 | #define M6510_IRQ_STATE M6502_IRQ_STATE | |
| 52 | m6502_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 53 | m6502_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock); | |
| 86 | 54 | |
| 87 | #define M6510_IRQ_LINE M6502_IRQ_LINE | |
| 55 | UINT64 get_cycle(); | |
| 56 | bool get_sync() const { return sync; } | |
| 88 | 57 | |
| 89 | DECLARE_LEGACY_CPU_DEVICE(M6510, m6510); | |
| 58 | protected: | |
| 59 | class memory_interface { | |
| 60 | public: | |
| 61 | address_space *program; | |
| 62 | direct_read_data *direct; | |
| 90 | 63 | |
| 91 | extern CPU_DISASSEMBLE( m6510 ); | |
| 64 | virtual UINT8 read(UINT16 adr) = 0; | |
| 65 | virtual UINT8 read_9(UINT16 adr); | |
| 66 | virtual UINT8 read_direct(UINT16 adr) = 0; | |
| 67 | virtual UINT8 read_decrypted(UINT16 adr) = 0; | |
| 68 | virtual void write(UINT16 adr, UINT8 val) = 0; | |
| 69 | virtual void write_9(UINT16 adr, UINT8 val); | |
| 70 | }; | |
| 92 | 71 | |
| 93 | UINT8 m6510_get_port(legacy_cpu_device *device); | |
| 72 | class mi_default_normal : public memory_interface { | |
| 73 | public: | |
| 74 | virtual UINT8 read(UINT16 adr); | |
| 75 | virtual UINT8 read_direct(UINT16 adr); | |
| 76 | virtual UINT8 read_decrypted(UINT16 adr); | |
| 77 | virtual void write(UINT16 adr, UINT8 val); | |
| 78 | }; | |
| 94 | 79 | |
| 95 | #define M6510T_A M6502_A | |
| 96 | #define M6510T_X M6502_X | |
| 97 | #define M6510T_Y M6502_Y | |
| 98 | #define M6510T_S M6502_S | |
| 99 | #define M6510T_PC M6502_PC | |
| 100 | #define M6510T_P M6502_P | |
| 101 | #define M6510T_EA M6502_EA | |
| 102 | #define M6510T_ZP M6502_ZP | |
| 103 | #define M6510T_NMI_STATE M6502_NMI_STATE | |
| 104 | #define M6510T_IRQ_STATE M6502_IRQ_STATE | |
| 80 | class mi_default_nd : public mi_default_normal { | |
| 81 | public: | |
| 82 | virtual UINT8 read_direct(UINT16 adr); | |
| 83 | virtual UINT8 read_decrypted(UINT16 adr); | |
| 84 | }; | |
| 105 | 85 | |
| 106 | #define M6510T_IRQ_LINE M6502_IRQ_LINE | |
| 86 | struct disasm_entry { | |
| 87 | const char *opcode; | |
| 88 | int mode; | |
| 89 | offs_t flags; | |
| 90 | bool per_bit; | |
| 91 | }; | |
| 107 | 92 | |
| 108 | DECLARE_LEGACY_CPU_DEVICE(M6510T, m6510t); | |
| 93 | enum { | |
| 94 | STATE_RESET = 0x100, | |
| 95 | }; | |
| 109 | 96 | |
| 97 | enum { | |
| 98 | DASM_non, /* no additional arguments */ | |
| 99 | DASM_aba, /* absolute */ | |
| 100 | DASM_abx, /* absolute + X */ | |
| 101 | DASM_aby, /* absolute + Y */ | |
| 102 | DASM_acc, /* accumulator */ | |
| 103 | DASM_adr, /* absolute address (jmp,jsr) */ | |
| 104 | DASM_bzp, /* zero page with bit selection */ | |
| 105 | DASM_iax, /* indirect + X (65c02 jmp) */ | |
| 106 | DASM_idx, /* zero page pre indexed */ | |
| 107 | DASM_idy, /* zero page post indexed */ | |
| 108 | DASM_idz, /* zero page post indexed (65ce02) */ | |
| 109 | DASM_imm, /* immediate */ | |
| 110 | DASM_imp, /* implicit */ | |
| 111 | DASM_ind, /* indirect (jmp) */ | |
| 112 | DASM_isy, /* zero page pre indexed sp and post indexed Y (65ce02) */ | |
| 113 | DASM_iw2, /* immediate word (65ce02) */ | |
| 114 | DASM_iw3, /* augment (65ce02) */ | |
| 115 | DASM_rel, /* relative */ | |
| 116 | DASM_rw2, /* relative word (65cs02, 65ce02) */ | |
| 117 | DASM_zpb, /* zero page and branch (65c02 bbr, bbs) */ | |
| 118 | DASM_zpg, /* zero page */ | |
| 119 | DASM_zpi, /* zero page indirect (65c02) */ | |
| 120 | DASM_zpx, /* zero page + X */ | |
| 121 | DASM_zpy, /* zero page + Y */ | |
| 122 | }; | |
| 110 | 123 | |
| 111 | #define M7501_A M6502_A | |
| 112 | #define M7501_X M6502_X | |
| 113 | #define M7501_Y M6502_Y | |
| 114 | #define M7501_S M6502_S | |
| 115 | #define M7501_PC M6502_PC | |
| 116 | #define M7501_P M6502_P | |
| 117 | #define M7501_EA M6502_EA | |
| 118 | #define M7501_ZP M6502_ZP | |
| 119 | #define M7501_NMI_STATE M6502_NMI_STATE | |
| 120 | #define M7501_IRQ_STATE M6502_IRQ_STATE | |
| 124 | enum { | |
| 125 | F_N = 0x80, | |
| 126 | F_V = 0x40, | |
| 127 | F_E = 0x20, // 65ce02 | |
| 128 | F_B = 0x10, | |
| 129 | F_D = 0x08, | |
| 130 | F_I = 0x04, | |
| 131 | F_Z = 0x02, | |
| 132 | F_C = 0x01 | |
| 133 | }; | |
| 121 | 134 | |
| 122 | ||
| 135 | virtual void init(); | |
| 123 | 136 | |
| 124 | DECLARE_LEGACY_CPU_DEVICE(M7501, m7501); | |
| 137 | // device-level overrides | |
| 138 | virtual void device_start(); | |
| 139 | virtual void device_reset(); | |
| 125 | 140 | |
| 126 | #define M8502_A M6502_A | |
| 127 | #define M8502_X M6502_X | |
| 128 | #define M8502_Y M6502_Y | |
| 129 | #define M8502_S M6502_S | |
| 130 | #define M8502_PC M6502_PC | |
| 131 | #define M8502_P M6502_P | |
| 132 | #define M8502_EA M6502_EA | |
| 133 | #define M8502_ZP M6502_ZP | |
| 134 | #define M8502_NMI_STATE M6502_NMI_STATE | |
| 135 | #define M8502_IRQ_STATE M6502_IRQ_STATE | |
| 141 | // device_execute_interface overrides | |
| 142 | virtual UINT32 execute_min_cycles() const; | |
| 143 | virtual UINT32 execute_max_cycles() const; | |
| 144 | virtual UINT32 execute_input_lines() const; | |
| 145 | virtual void execute_run(); | |
| 146 | virtual void execute_set_input(int inputnum, int state); | |
| 136 | 147 | |
| 137 | #define M8502_IRQ_LINE M6502_IRQ_LINE | |
| 148 | // device_memory_interface overrides | |
| 149 | virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const; | |
| 138 | 150 | |
| 139 | DECLARE_LEGACY_CPU_DEVICE(M8502, m8502); | |
| 151 | // device_state_interface overrides | |
| 152 | virtual void state_import(const device_state_entry &entry); | |
| 153 | virtual void state_export(const device_state_entry &entry); | |
| 154 | virtual void state_string_export(const device_state_entry &entry, astring &string); | |
| 140 | 155 | |
| 156 | // device_disasm_interface overrides | |
| 157 | virtual UINT32 disasm_min_opcode_bytes() const; | |
| 158 | virtual UINT32 disasm_max_opcode_bytes() const; | |
| 159 | virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options); | |
| 141 | 160 | |
| 142 | /**************************************************************************** | |
| 143 | * The 2A03 (NES 6502 without decimal mode ADC/SBC) | |
| 144 | ****************************************************************************/ | |
| 145 | #define N2A03_A M6502_A | |
| 146 | #define N2A03_X M6502_X | |
| 147 | #define N2A03_Y M6502_Y | |
| 148 | #define N2A03_S M6502_S | |
| 149 | #define N2A03_PC M6502_PC | |
| 150 | #define N2A03_P M6502_P | |
| 151 | #define N2A03_EA M6502_EA | |
| 152 | #define N2A03_ZP M6502_ZP | |
| 153 | #define N2A03_NMI_STATE M6502_NMI_STATE | |
| 154 | #define N2A03_IRQ_STATE M6502_IRQ_STATE | |
| 161 | address_space_config program_config; | |
| 155 | 162 | |
| 156 | #define N2A03_IRQ_LINE M6502_IRQ_LINE | |
| 163 | UINT16 PPC; /* previous program counter */ | |
| 164 | UINT16 NPC; /* next start-of-instruction program counter */ | |
| 165 | UINT16 PC; /* program counter */ | |
| 166 | UINT16 SP; /* stack pointer (always 100 - 1FF) */ | |
| 167 | UINT16 TMP; /* temporary internal values */ | |
| 168 | UINT8 TMP2; /* another temporary internal value, 8 bits this time */ | |
| 169 | UINT8 A; /* Accumulator */ | |
| 170 | UINT8 X; /* X index register */ | |
| 171 | UINT8 Y; /* Y index register */ | |
| 172 | UINT8 P; /* Processor status */ | |
| 173 | UINT8 IR; /* Prefetched instruction register */ | |
| 157 | 174 | |
| 158 | DECLARE_LEGACY_CPU_DEVICE(N2A03, n2a03); | |
| 175 | memory_interface *mintf; | |
| 176 | int inst_state, inst_substate; | |
| 177 | int icount; | |
| 178 | bool nmi_state, irq_state, v_state; | |
| 179 | bool irq_taken, sync, direct_disabled, inhibit_interrupts; | |
| 180 | UINT64 end_cycles; | |
| 159 | 181 | |
| 160 | ||
| 182 | static const disasm_entry disasm_entries[0x100]; | |
| 161 | 183 | |
| 162 | /* The N2A03 is integrally tied to its PSG (they're on the same die). | |
| 163 | Bit 7 of address $4011 (the PSG's DPCM control register), when set, | |
| 164 | causes an IRQ to be generated. This function allows the IRQ to be called | |
| 165 | from the PSG core when such an occasion arises. */ | |
| 166 | extern void n2a03_irq(device_t *device); | |
| 184 | offs_t disassemble_generic(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options, const disasm_entry *table); | |
| 185 | UINT8 read(UINT16 adr) { return mintf->read(adr); } | |
| 186 | UINT8 read_9(UINT16 adr) { return mintf->read_9(adr); } | |
| 187 | void write(UINT16 adr, UINT8 val) { mintf->write(adr, val); } | |
| 188 | void write_9(UINT16 adr, UINT8 val) { mintf->write_9(adr, val); } | |
| 189 | UINT8 read_direct(UINT16 adr) { return mintf->read_direct(adr); } | |
| 190 | UINT8 read_pc() { return mintf->read_direct(PC++); } | |
| 191 | UINT8 read_pc_noinc() { return mintf->read_direct(PC); } | |
| 192 | void prefetch(); | |
| 193 | void prefetch_noirq(); | |
| 194 | void set_nz(UINT8 v); | |
| 167 | 195 | |
| 196 | virtual void do_exec_full(); | |
| 197 | virtual void do_exec_partial(); | |
| 168 | 198 | |
| 169 | /**************************************************************************** | |
| 170 | * The 65C02 | |
| 171 | ****************************************************************************/ | |
| 172 | #define M65C02_A M6502_A | |
| 173 | #define M65C02_X M6502_X | |
| 174 | #define M65C02_Y M6502_Y | |
| 175 | #define M65C02_S M6502_S | |
| 176 | #define M65C02_PC M6502_PC | |
| 177 | #define M65C02_P M6502_P | |
| 178 | #define M65C02_EA M6502_EA | |
| 179 | #define M65C02_ZP M6502_ZP | |
| 180 | #define M65C02_NMI_STATE M6502_NMI_STATE | |
| 181 | #define M65C02_IRQ_STATE M6502_IRQ_STATE | |
| 199 | // inline helpers | |
| 200 | static inline bool page_changing(UINT16 base, int delta) { return ((base + delta) ^ base) & 0xff00; } | |
| 201 | static inline UINT16 set_l(UINT16 base, UINT8 val) { return (base & 0xff00) | val; } | |
| 202 | static inline UINT16 set_h(UINT16 base, UINT8 val) { return (base & 0x00ff) | (val << 8); } | |
| 182 | 203 | |
| 183 | #define M65C02_IRQ_LINE M6502_IRQ_LINE | |
| 204 | inline void dec_SP() { SP = set_l(SP, SP-1); } | |
| 205 | inline void inc_SP() { SP = set_l(SP, SP+1); } | |
| 184 | 206 | |
| 185 | DECLARE_LEGACY_CPU_DEVICE(M65C02, m65c02); | |
| 207 | void do_adc_d(UINT8 val); | |
| 208 | void do_adc_nd(UINT8 val); | |
| 209 | void do_sbc_d(UINT8 val); | |
| 210 | void do_sbc_nd(UINT8 val); | |
| 211 | void do_arr_d(); | |
| 212 | void do_arr_nd(); | |
| 186 | 213 | |
| 187 | extern CPU_DISASSEMBLE( m65c02 ); | |
| 214 | void do_adc(UINT8 val); | |
| 215 | void do_cmp(UINT8 val1, UINT8 val2); | |
| 216 | void do_sbc(UINT8 val); | |
| 217 | void do_bit(UINT8 val); | |
| 218 | void do_arr(); | |
| 219 | UINT8 do_asl(UINT8 v); | |
| 220 | UINT8 do_lsr(UINT8 v); | |
| 221 | UINT8 do_ror(UINT8 v); | |
| 222 | UINT8 do_rol(UINT8 v); | |
| 223 | UINT8 do_asr(UINT8 v); | |
| 188 | 224 | |
| 225 | #define O(o) void o ## _full(); void o ## _partial() | |
| 189 | 226 | |
| 190 | /**************************************************************************** | |
| 191 | * The 65SC02 | |
| 192 | ****************************************************************************/ | |
| 193 | #define M65SC02_A M6502_A | |
| 194 | #define M65SC02_X M6502_X | |
| 195 | #define M65SC02_Y M6502_Y | |
| 196 | #define M65SC02_S M6502_S | |
| 197 | #define M65SC02_PC M6502_PC | |
| 198 | #define M65SC02_P M6502_P | |
| 199 | #define M65SC02_EA M6502_EA | |
| 200 | #define M65SC02_ZP M6502_ZP | |
| 201 | #define M65SC02_NMI_STATE M6502_NMI_STATE | |
| 202 | #define M65SC02_IRQ_STATE M6502_IRQ_STATE | |
| 227 | // NMOS 6502 opcodes | |
| 228 | // documented opcodes | |
| 229 | O(adc_aba); O(adc_abx); O(adc_aby); O(adc_idx); O(adc_idy); O(adc_imm); O(adc_zpg); O(adc_zpx); | |
| 230 | O(and_aba); O(and_abx); O(and_aby); O(and_imm); O(and_idx); O(and_idy); O(and_zpg); O(and_zpx); | |
| 231 | O(asl_aba); O(asl_abx); O(asl_acc); O(asl_zpg); O(asl_zpx); | |
| 232 | O(bcc_rel); | |
| 233 | O(bcs_rel); | |
| 234 | O(beq_rel); | |
| 235 | O(bit_aba); O(bit_zpg); | |
| 236 | O(bmi_rel); | |
| 237 | O(bne_rel); | |
| 238 | O(bpl_rel); | |
| 239 | O(brk_imp); | |
| 240 | O(bvc_rel); | |
| 241 | O(bvs_rel); | |
| 242 | O(clc_imp); | |
| 243 | O(cld_imp); | |
| 244 | O(cli_imp); | |
| 245 | O(clv_imp); | |
| 246 | O(cmp_aba); O(cmp_abx); O(cmp_aby); O(cmp_idx); O(cmp_idy); O(cmp_imm); O(cmp_zpg); O(cmp_zpx); | |
| 247 | O(cpx_aba); O(cpx_imm); O(cpx_zpg); | |
| 248 | O(cpy_aba); O(cpy_imm); O(cpy_zpg); | |
| 249 | O(dec_aba); O(dec_abx); O(dec_zpg); O(dec_zpx); | |
| 250 | O(dex_imp); | |
| 251 | O(dey_imp); | |
| 252 | O(eor_aba); O(eor_abx); O(eor_aby); O(eor_idx); O(eor_idy); O(eor_imm); O(eor_zpg); O(eor_zpx); | |
| 253 | O(inc_aba); O(inc_abx); O(inc_zpg); O(inc_zpx); | |
| 254 | O(inx_imp); | |
| 255 | O(iny_imp); | |
| 256 | O(jmp_adr); O(jmp_ind); | |
| 257 | O(jsr_adr); | |
| 258 | O(lda_aba); O(lda_abx); O(lda_aby); O(lda_idx); O(lda_idy); O(lda_imm); O(lda_zpg); O(lda_zpx); | |
| 259 | O(ldx_aba); O(ldx_aby); O(ldx_imm); O(ldx_zpg); O(ldx_zpy); | |
| 260 | O(ldy_aba); O(ldy_abx); O(ldy_imm); O(ldy_zpg); O(ldy_zpx); | |
| 261 | O(lsr_aba); O(lsr_abx); O(lsr_acc); O(lsr_zpg); O(lsr_zpx); | |
| 262 | O(nop_imp); | |
| 263 | O(ora_aba); O(ora_abx); O(ora_aby); O(ora_imm); O(ora_idx); O(ora_idy); O(ora_zpg); O(ora_zpx); | |
| 264 | O(pha_imp); | |
| 265 | O(php_imp); | |
| 266 | O(pla_imp); | |
| 267 | O(plp_imp); | |
| 268 | O(rol_aba); O(rol_abx); O(rol_acc); O(rol_zpg); O(rol_zpx); | |
| 269 | O(ror_aba); O(ror_abx); O(ror_acc); O(ror_zpg); O(ror_zpx); | |
| 270 | O(rti_imp); | |
| 271 | O(rts_imp); | |
| 272 | O(sbc_aba); O(sbc_abx); O(sbc_aby); O(sbc_idx); O(sbc_idy); O(sbc_imm); O(sbc_zpg); O(sbc_zpx); | |
| 273 | O(sec_imp); | |
| 274 | O(sed_imp); | |
| 275 | O(sei_imp); | |
| 276 | O(sta_aba); O(sta_abx); O(sta_aby); O(sta_idx); O(sta_idy); O(sta_zpg); O(sta_zpx); | |
| 277 | O(stx_aba); O(stx_zpg); O(stx_zpy); | |
| 278 | O(sty_aba); O(sty_zpg); O(sty_zpx); | |
| 279 | O(tax_imp); | |
| 280 | O(tay_imp); | |
| 281 | O(tsx_imp); | |
| 282 | O(txa_imp); | |
| 283 | O(txs_imp); | |
| 284 | O(tya_imp); | |
| 203 | 285 | |
| 204 | #define M65SC02_IRQ_LINE M6502_IRQ_LINE | |
| 286 | // exceptions | |
| 287 | O(reset); | |
| 205 | 288 | |
| 206 | DECLARE_LEGACY_CPU_DEVICE(M65SC02, m65sc02); | |
| 289 | // undocumented reliable instructions | |
| 290 | O(dcp_aba); O(dcp_abx); O(dcp_aby); O(dcp_idx); O(dcp_idy); O(dcp_zpg); O(dcp_zpx); | |
| 291 | O(isb_aba); O(isb_abx); O(isb_aby); O(isb_idx); O(isb_idy); O(isb_zpg); O(isb_zpx); | |
| 292 | O(lax_aba); O(lax_aby); O(lax_idx); O(lax_idy); O(lax_zpg); O(lax_zpy); | |
| 293 | O(rla_aba); O(rla_abx); O(rla_aby); O(rla_idx); O(rla_idy); O(rla_zpg); O(rla_zpx); | |
| 294 | O(rra_aba); O(rra_abx); O(rra_aby); O(rra_idx); O(rra_idy); O(rra_zpg); O(rra_zpx); | |
| 295 | O(sax_aba); O(sax_idx); O(sax_zpg); O(sax_zpy); | |
| 296 | O(sbx_imm); | |
| 297 | O(sha_aby); O(sha_idy); | |
| 298 | O(shs_aby); | |
| 299 | O(shx_aby); | |
| 300 | O(shy_abx); | |
| 301 | O(slo_aba); O(slo_abx); O(slo_aby); O(slo_idx); O(slo_idy); O(slo_zpg); O(slo_zpx); | |
| 302 | O(sre_aba); O(sre_abx); O(sre_aby); O(sre_idx); O(sre_idy); O(sre_zpg); O(sre_zpx); | |
| 207 | 303 | |
| 208 | extern CPU_DISASSEMBLE( m65sc02 ); | |
| 304 | // undocumented unreliable instructions | |
| 305 | // behaviour differs between visual6502 and online docs, which | |
| 306 | // is a clear sign reliability is not to be expected | |
| 307 | // implemented version follows visual6502 | |
| 308 | O(anc_imm); | |
| 309 | O(ane_imm); | |
| 310 | O(arr_imm); | |
| 311 | O(asr_imm); | |
| 312 | O(las_aby); | |
| 313 | O(lxa_imm); | |
| 209 | 314 | |
| 210 | /**************************************************************************** | |
| 211 | * The DECO CPU16 | |
| 212 | ****************************************************************************/ | |
| 213 | #define DECO16_A M6502_A | |
| 214 | #define DECO16_X M6502_X | |
| 215 | #define DECO16_Y M6502_Y | |
| 216 | #define DECO16_S M6502_S | |
| 217 | #define DECO16_PC M6502_PC | |
| 218 | #define DECO16_P M6502_P | |
| 219 | #define DECO16_EA M6502_EA | |
| 220 | #define DECO16_ZP M6502_ZP | |
| 221 | #define DECO16_NMI_STATE M6502_NMI_STATE | |
| 222 | #define DECO16_IRQ_STATE M6502_IRQ_STATE | |
| 315 | // nop variants | |
| 316 | O(nop_imm); O(nop_aba); O(nop_abx); O(nop_zpg); O(nop_zpx); | |
| 223 | 317 | |
| 224 | #define DECO16_IRQ_LINE M6502_IRQ_LINE | |
| 318 | // system killers | |
| 319 | O(kil_non); | |
| 225 | 320 | |
| 226 | DECLARE_LEGACY_CPU_DEVICE(DECO16, deco16); | |
| 321 | #undef O | |
| 322 | }; | |
| 227 | 323 | |
| 228 | extern CPU_DISASSEMBLE( deco16 ); | |
| 324 | enum { | |
| 325 | M6502_PC = 1, | |
| 326 | M6502_A, | |
| 327 | M6502_X, | |
| 328 | M6502_Y, | |
| 329 | M6502_P, | |
| 330 | M6502_S, | |
| 331 | M6502_IR | |
| 332 | }; | |
| 229 | 333 | |
| 230 | #endif /* __M6502_H__ */ | |
| 334 | enum { | |
| 335 | M6502_IRQ_LINE = m6502_device::IRQ_LINE, | |
| 336 | M6502_NMI_LINE = m6502_device::NMI_LINE, | |
| 337 | M6502_SET_OVERFLOW = m6502_device::V_LINE, | |
| 338 | }; | |
| 339 | ||
| 340 | extern const device_type M6502; | |
| 341 | ||
| 342 | #endif |
| r18874 | r18875 | |
|---|---|---|
| 1 | /*************************************************************************** | |
| 2 | ||
| 3 | m6504.h | |
| 4 | ||
| 5 | Mostek 6502, NMOS variant with reduced address bus | |
| 6 | ||
| 7 | **************************************************************************** | |
| 8 | ||
| 9 | Copyright Olivier Galibert | |
| 10 | All rights reserved. | |
| 11 | ||
| 12 | Redistribution and use in source and binary forms, with or without | |
| 13 | modification, are permitted provided that the following conditions are | |
| 14 | met: | |
| 15 | ||
| 16 | * Redistributions of source code must retain the above copyright | |
| 17 | notice, this list of conditions and the following disclaimer. | |
| 18 | * Redistributions in binary form must reproduce the above copyright | |
| 19 | notice, this list of conditions and the following disclaimer in | |
| 20 | the documentation and/or other materials provided with the | |
| 21 | distribution. | |
| 22 | * Neither the name 'MAME' nor the names of its contributors may be | |
| 23 | used to endorse or promote products derived from this software | |
| 24 | without specific prior written permission. | |
| 25 | ||
| 26 | THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR | |
| 27 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 28 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 29 | DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, | |
| 30 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 31 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
| 32 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 33 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
| 34 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
| 35 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| 36 | POSSIBILITY OF SUCH DAMAGE. | |
| 37 | ||
| 38 | ***************************************************************************/ | |
| 39 | ||
| 40 | #ifndef __M6504_H__ | |
| 41 | #define __M6504_H__ | |
| 42 | ||
| 43 | #include "m6502.h" | |
| 44 | ||
| 45 | class m6504_device : public m6502_device { | |
| 46 | public: | |
| 47 | m6504_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 48 | ||
| 49 | protected: | |
| 50 | class mi_6504_normal : public memory_interface { | |
| 51 | public: | |
| 52 | virtual UINT8 read(UINT16 adr); | |
| 53 | virtual UINT8 read_direct(UINT16 adr); | |
| 54 | virtual UINT8 read_decrypted(UINT16 adr); | |
| 55 | virtual void write(UINT16 adr, UINT8 val); | |
| 56 | }; | |
| 57 | ||
| 58 | class mi_6504_nd : public mi_6504_normal { | |
| 59 | public: | |
| 60 | virtual UINT8 read_direct(UINT16 adr); | |
| 61 | virtual UINT8 read_decrypted(UINT16 adr); | |
| 62 | }; | |
| 63 | ||
| 64 | virtual void device_start(); | |
| 65 | }; | |
| 66 | ||
| 67 | ||
| 68 | enum { | |
| 69 | M6504_IRQ_LINE = m6502_device::IRQ_LINE, | |
| 70 | M6504_NMI_LINE = m6502_device::NMI_LINE, | |
| 71 | M6504_SET_OVERFLOW = m6502_device::V_LINE, | |
| 72 | }; | |
| 73 | ||
| 74 | extern const device_type M6504; | |
| 75 | ||
| 76 | #endif |
| r18874 | r18875 | |
|---|---|---|
| 1 | # 65ce02 opcodes, a lot only remove dummy read/write cycles, some are new, some use the B register | |
| 2 | ||
| 3 | adc_ce_aba | |
| 4 | TMP = read_pc(); | |
| 5 | TMP = set_h(TMP, read_pc()); | |
| 6 | TMP = read(TMP); | |
| 7 | do_adc(TMP); | |
| 8 | if(P & F_D) | |
| 9 | set_nz(A); | |
| 10 | prefetch(); | |
| 11 | ||
| 12 | adc_ce_abx | |
| 13 | TMP = read_pc(); | |
| 14 | TMP = set_h(TMP, read_pc()); | |
| 15 | TMP += X; | |
| 16 | TMP = read(TMP); | |
| 17 | do_adc(TMP); | |
| 18 | if(P & F_D) | |
| 19 | set_nz(A); | |
| 20 | prefetch(); | |
| 21 | ||
| 22 | adc_ce_aby | |
| 23 | TMP = read_pc(); | |
| 24 | TMP = set_h(TMP, read_pc()); | |
| 25 | TMP += Y; | |
| 26 | TMP = read(TMP); | |
| 27 | do_adc(TMP); | |
| 28 | if(P & F_D) | |
| 29 | set_nz(A); | |
| 30 | prefetch(); | |
| 31 | ||
| 32 | adc_ce_idx | |
| 33 | TMP2 = read_pc(); | |
| 34 | TMP2 += X; | |
| 35 | TMP = read(B|TMP2); | |
| 36 | TMP2++; | |
| 37 | TMP = set_h(TMP, read(B|TMP2)); | |
| 38 | do_adc(read(TMP)); | |
| 39 | if(P & F_D) | |
| 40 | set_nz(A); | |
| 41 | prefetch(); | |
| 42 | ||
| 43 | adc_ce_idy | |
| 44 | TMP2 = read_pc(); | |
| 45 | TMP = read(B|TMP2); | |
| 46 | TMP2++; | |
| 47 | TMP = set_h(TMP, read(B|TMP2)); | |
| 48 | do_adc(read(TMP+Y)); | |
| 49 | if(P & F_D) | |
| 50 | set_nz(A); | |
| 51 | prefetch(); | |
| 52 | ||
| 53 | adc_idz | |
| 54 | TMP2 = read_pc(); | |
| 55 | TMP = read(B|TMP2); | |
| 56 | TMP2++; | |
| 57 | TMP = set_h(TMP, read(B|TMP2)); | |
| 58 | do_adc(read(TMP+Z)); | |
| 59 | if(P & F_D) | |
| 60 | set_nz(A); | |
| 61 | prefetch(); | |
| 62 | ||
| 63 | adc_ce_imm | |
| 64 | TMP = read_pc(); | |
| 65 | do_adc(TMP); | |
| 66 | if(P & F_D) | |
| 67 | set_nz(A); | |
| 68 | prefetch(); | |
| 69 | ||
| 70 | adc_ce_zpg | |
| 71 | TMP = read_pc(); | |
| 72 | TMP = read(B|TMP); | |
| 73 | do_adc(TMP); | |
| 74 | if(P & F_D) | |
| 75 | set_nz(A); | |
| 76 | prefetch(); | |
| 77 | ||
| 78 | adc_ce_zpx | |
| 79 | TMP = read_pc(); | |
| 80 | TMP = read(B|UINT8(TMP+X)); | |
| 81 | do_adc(TMP); | |
| 82 | if(P & F_D) | |
| 83 | set_nz(A); | |
| 84 | prefetch(); | |
| 85 | ||
| 86 | and_ce_abx | |
| 87 | TMP = read_pc(); | |
| 88 | TMP = set_h(TMP, read_pc()); | |
| 89 | TMP += X; | |
| 90 | A &= read(TMP); | |
| 91 | set_nz(A); | |
| 92 | prefetch(); | |
| 93 | ||
| 94 | and_ce_aby | |
| 95 | TMP = read_pc(); | |
| 96 | TMP = set_h(TMP, read_pc()); | |
| 97 | TMP += Y; | |
| 98 | A &= read(TMP); | |
| 99 | set_nz(A); | |
| 100 | prefetch(); | |
| 101 | ||
| 102 | and_ce_idx | |
| 103 | TMP2 = read_pc(); | |
| 104 | TMP2 += X; | |
| 105 | TMP = read(B|TMP2); | |
| 106 | TMP2++; | |
| 107 | TMP = set_h(TMP, read(B|TMP2)); | |
| 108 | A &= read(TMP); | |
| 109 | set_nz(A); | |
| 110 | prefetch(); | |
| 111 | ||
| 112 | and_ce_idy | |
| 113 | TMP2 = read_pc(); | |
| 114 | TMP = read(B|TMP2); | |
| 115 | TMP2++; | |
| 116 | TMP = set_h(TMP, read(B|TMP2)); | |
| 117 | A &= read(TMP+Y); | |
| 118 | set_nz(A); | |
| 119 | prefetch(); | |
| 120 | ||
| 121 | and_idz | |
| 122 | TMP2 = read_pc(); | |
| 123 | TMP = read(B|TMP2); | |
| 124 | TMP2++; | |
| 125 | TMP = set_h(TMP, read(B|TMP2)); | |
| 126 | A &= read(TMP+Z); | |
| 127 | set_nz(A); | |
| 128 | prefetch(); | |
| 129 | ||
| 130 | and_ce_zpg | |
| 131 | TMP = read_pc(); | |
| 132 | A &= read(B|TMP); | |
| 133 | set_nz(A); | |
| 134 | prefetch(); | |
| 135 | ||
| 136 | and_ce_zpx | |
| 137 | TMP = read_pc(); | |
| 138 | A &= read(B|UINT8(TMP+X)); | |
| 139 | set_nz(A); | |
| 140 | prefetch(); | |
| 141 | ||
| 142 | asl_ce_aba | |
| 143 | TMP = read_pc(); | |
| 144 | TMP = set_h(TMP, read_pc()); | |
| 145 | TMP2 = read(TMP); | |
| 146 | TMP2 = do_asl(TMP2); | |
| 147 | write(TMP, TMP2); | |
| 148 | prefetch(); | |
| 149 | ||
| 150 | asl_ce_abx | |
| 151 | TMP = read_pc(); | |
| 152 | TMP = set_h(TMP, read_pc()); | |
| 153 | TMP += X; | |
| 154 | TMP2 = read(TMP); | |
| 155 | TMP2 = do_asl(TMP2); | |
| 156 | write(TMP, TMP2); | |
| 157 | prefetch(); | |
| 158 | ||
| 159 | asl_ce_acc | |
| 160 | A = do_asl(A); | |
| 161 | prefetch(); | |
| 162 | ||
| 163 | asl_ce_zpg | |
| 164 | TMP = B|read_pc(); | |
| 165 | TMP2 = read(TMP); | |
| 166 | TMP2 = do_asl(TMP2); | |
| 167 | write(TMP, TMP2); | |
| 168 | prefetch(); | |
| 169 | ||
| 170 | asl_ce_zpx | |
| 171 | TMP = read_pc(); | |
| 172 | TMP = B|UINT8(TMP+X); | |
| 173 | TMP2 = read(TMP); | |
| 174 | TMP2 = do_asl(TMP2); | |
| 175 | write(TMP, TMP2); | |
| 176 | prefetch(); | |
| 177 | ||
| 178 | asr_acc | |
| 179 | A = do_asr(A); | |
| 180 | prefetch(); | |
| 181 | ||
| 182 | asr_zpg | |
| 183 | TMP = B|read_pc(); | |
| 184 | TMP2 = read(TMP); | |
| 185 | TMP2 = do_asr(TMP2); | |
| 186 | write(TMP, TMP2); | |
| 187 | prefetch(); | |
| 188 | ||
| 189 | asr_zpx | |
| 190 | TMP = read_pc(); | |
| 191 | TMP = B|UINT8(TMP+X); | |
| 192 | TMP2 = read(TMP); | |
| 193 | TMP2 = do_asr(TMP2); | |
| 194 | write(TMP, TMP2); | |
| 195 | prefetch(); | |
| 196 | ||
| 197 | asw_aba | |
| 198 | TMP = read_pc(); | |
| 199 | TMP = set_h(TMP, read_pc()); | |
| 200 | TMP3 = read(TMP); | |
| 201 | TMP3 = set_h(TMP3, read(TMP+1)); | |
| 202 | P &= ~(F_C|F_N|F_Z); | |
| 203 | if(TMP3 & 0x8000) | |
| 204 | P |= F_C; | |
| 205 | TMP3 <<= 1; | |
| 206 | if(!TMP3) | |
| 207 | P |= F_Z; | |
| 208 | else if(TMP3 & 0x8000) | |
| 209 | P |= F_N; | |
| 210 | write(TMP, TMP3); | |
| 211 | write(TMP, TMP3 >> 8); | |
| 212 | prefetch(); | |
| 213 | ||
| 214 | aug_iw3 | |
| 215 | read_pc(); | |
| 216 | read_pc(); | |
| 217 | read_pc(); | |
| 218 | prefetch(); | |
| 219 | ||
| 220 | bbr_ce_zpb | |
| 221 | // Access pattern uncertain | |
| 222 | TMP = read_pc(); | |
| 223 | TMP2 = read(TMP); | |
| 224 | TMP = read_pc(); | |
| 225 | if(!(TMP2 & (1 << (inst_state & 7)))) | |
| 226 | PC += INT8(TMP); | |
| 227 | prefetch(); | |
| 228 | ||
| 229 | bbs_ce_zpb | |
| 230 | // Access pattern uncertain | |
| 231 | TMP = read_pc(); | |
| 232 | TMP2 = read(TMP); | |
| 233 | TMP = read_pc(); | |
| 234 | if(TMP2 & (1 << (inst_state & 7))) | |
| 235 | PC += INT8(TMP); | |
| 236 | prefetch(); | |
| 237 | ||
| 238 | bcc_ce_rel | |
| 239 | TMP = read_pc(); | |
| 240 | if(!(P & F_C)) | |
| 241 | PC += INT8(TMP); | |
| 242 | prefetch(); | |
| 243 | ||
| 244 | bcc_rw2 | |
| 245 | TMP = read_pc(); | |
| 246 | TMP = set_h(TMP, read_pc()); | |
| 247 | if(!(P & F_C)) | |
| 248 | PC += TMP; | |
| 249 | prefetch(); | |
| 250 | ||
| 251 | bcs_ce_rel | |
| 252 | TMP = read_pc(); | |
| 253 | if(P & F_C) | |
| 254 | PC += INT8(TMP); | |
| 255 | prefetch(); | |
| 256 | ||
| 257 | bcs_rw2 | |
| 258 | TMP = read_pc(); | |
| 259 | TMP = set_h(TMP, read_pc()); | |
| 260 | if(P & F_C) | |
| 261 | PC += TMP; | |
| 262 | prefetch(); | |
| 263 | ||
| 264 | beq_ce_rel | |
| 265 | TMP = read_pc(); | |
| 266 | if(P & F_Z) | |
| 267 | PC += INT8(TMP); | |
| 268 | prefetch(); | |
| 269 | ||
| 270 | beq_rw2 | |
| 271 | TMP = read_pc(); | |
| 272 | TMP = set_h(TMP, read_pc()); | |
| 273 | if(P & F_Z) | |
| 274 | PC += TMP; | |
| 275 | prefetch(); | |
| 276 | ||
| 277 | bit_ce_abx | |
| 278 | TMP = read_pc(); | |
| 279 | TMP = set_h(TMP, read_pc()); | |
| 280 | TMP += X; | |
| 281 | do_bit(read(TMP)); | |
| 282 | prefetch(); | |
| 283 | ||
| 284 | bit_ce_imm | |
| 285 | TMP = read_pc(); | |
| 286 | do_bit(TMP); | |
| 287 | prefetch(); | |
| 288 | ||
| 289 | bit_ce_zpg | |
| 290 | TMP = B|read_pc(); | |
| 291 | do_bit(read(TMP)); | |
| 292 | prefetch(); | |
| 293 | ||
| 294 | bit_ce_zpx | |
| 295 | TMP = read_pc(); | |
| 296 | TMP = read(B|UINT8(TMP+X)); | |
| 297 | do_bit(TMP); | |
| 298 | prefetch(); | |
| 299 | ||
| 300 | bmi_ce_rel | |
| 301 | TMP = read_pc(); | |
| 302 | if(P & F_N) | |
| 303 | PC += INT8(TMP); | |
| 304 | prefetch(); | |
| 305 | ||
| 306 | bmi_rw2 | |
| 307 | TMP = read_pc(); | |
| 308 | TMP = set_h(TMP, read_pc()); | |
| 309 | if(P & F_N) | |
| 310 | PC += TMP; | |
| 311 | prefetch(); | |
| 312 | ||
| 313 | bne_ce_rel | |
| 314 | TMP = read_pc(); | |
| 315 | if(!(P & F_Z)) | |
| 316 | PC += INT8(TMP); | |
| 317 | prefetch(); | |
| 318 | ||
| 319 | bne_rw2 | |
| 320 | TMP = read_pc(); | |
| 321 | TMP = set_h(TMP, read_pc()); | |
| 322 | if(!(P & F_Z)) | |
| 323 | PC += TMP; | |
| 324 | prefetch(); | |
| 325 | ||
| 326 | bpl_ce_rel | |
| 327 | TMP = read_pc(); | |
| 328 | if(!(P & F_N)) | |
| 329 | PC += INT8(TMP); | |
| 330 | prefetch(); | |
| 331 | ||
| 332 | bpl_rw2 | |
| 333 | TMP = read_pc(); | |
| 334 | TMP = set_h(TMP, read_pc()); | |
| 335 | if(!(P & F_N)) | |
| 336 | PC += TMP; | |
| 337 | prefetch(); | |
| 338 | ||
| 339 | bra_ce_rel | |
| 340 | TMP = read_pc(); | |
| 341 | PC += INT8(TMP); | |
| 342 | prefetch(); | |
| 343 | ||
| 344 | bra_rw2 | |
| 345 | TMP = read_pc(); | |
| 346 | TMP = set_h(TMP, read_pc()); | |
| 347 | PC += TMP; | |
| 348 | prefetch(); | |
| 349 | ||
| 350 | brk_ce_imp | |
| 351 | if(irq_taken) { | |
| 352 | read_pc_noinc(); | |
| 353 | } else { | |
| 354 | read_pc(); | |
| 355 | } | |
| 356 | write(SP, PC >> 8); | |
| 357 | dec_SP_ce(); | |
| 358 | write(SP, PC); | |
| 359 | dec_SP_ce(); | |
| 360 | write(SP, irq_taken || nmi_state ? P & ~F_B : P); | |
| 361 | dec_SP_ce(); | |
| 362 | if(nmi_state) { | |
| 363 | PC = read_direct(0xfffa); | |
| 364 | PC = set_h(PC, read_direct(0xfffb)); | |
| 365 | nmi_state = false; | |
| 366 | } else { | |
| 367 | PC = read_direct(0xfffe); | |
| 368 | PC = set_h(PC, read_direct(0xffff)); | |
| 369 | } | |
| 370 | irq_taken = false; | |
| 371 | P = (P | F_I) & ~F_D; // Do *not* move after the prefetch | |
| 372 | prefetch(); | |
| 373 | inst_state = -1; | |
| 374 | ||
| 375 | bsr_rw2 | |
| 376 | TMP = read_pc(); | |
| 377 | write(SP, PC>>8); | |
| 378 | dec_SP_ce(); | |
| 379 | write(SP, PC); | |
| 380 | dec_SP_ce(); | |
| 381 | TMP = set_h(TMP, read_pc()); | |
| 382 | PC += TMP; | |
| 383 | prefetch(); | |
| 384 | ||
| 385 | bvc_ce_rel | |
| 386 | TMP = read_pc(); | |
| 387 | if(!(P & F_V)) | |
| 388 | PC += INT8(TMP); | |
| 389 | prefetch(); | |
| 390 | ||
| 391 | bvc_rw2 | |
| 392 | TMP = read_pc(); | |
| 393 | TMP = set_h(TMP, read_pc()); | |
| 394 | if(!(P & F_V)) | |
| 395 | PC += TMP; | |
| 396 | prefetch(); | |
| 397 | ||
| 398 | bvs_ce_rel | |
| 399 | TMP = read_pc(); | |
| 400 | if(P & F_V) | |
| 401 | PC += INT8(TMP); | |
| 402 | prefetch(); | |
| 403 | ||
| 404 | bvs_rw2 | |
| 405 | TMP = read_pc(); | |
| 406 | TMP = set_h(TMP, read_pc()); | |
| 407 | if(P & F_V) | |
| 408 | PC += TMP; | |
| 409 | prefetch(); | |
| 410 | ||
| 411 | clc_ce_imp | |
| 412 | P &= ~F_C; | |
| 413 | prefetch(); | |
| 414 | ||
| 415 | cld_ce_imp | |
| 416 | P &= ~F_D; | |
| 417 | prefetch(); | |
| 418 | ||
| 419 | cle_imp | |
| 420 | read_pc_noinc(); | |
| 421 | P &= ~F_E; | |
| 422 | prefetch(); | |
| 423 | ||
| 424 | cli_ce_imp | |
| 425 | prefetch(); | |
| 426 | P &= ~F_I; // Do *not* move it before the prefetch | |
| 427 | ||
| 428 | clv_ce_imp | |
| 429 | P &= ~F_V; | |
| 430 | prefetch(); | |
| 431 | ||
| 432 | cmp_ce_abx | |
| 433 | TMP = read_pc(); | |
| 434 | TMP = set_h(TMP, read_pc()); | |
| 435 | TMP += X; | |
| 436 | TMP = read(TMP); | |
| 437 | do_cmp(A, TMP); | |
| 438 | prefetch(); | |
| 439 | ||
| 440 | cmp_ce_aby | |
| 441 | TMP = read_pc(); | |
| 442 | TMP = set_h(TMP, read_pc()); | |
| 443 | TMP += Y; | |
| 444 | TMP = read(TMP); | |
| 445 | do_cmp(A, TMP); | |
| 446 | prefetch(); | |
| 447 | ||
| 448 | cmp_ce_idx | |
| 449 | TMP2 = read_pc(); | |
| 450 | TMP2 += X; | |
| 451 | TMP = read(B|TMP2); | |
| 452 | TMP2++; | |
| 453 | TMP = set_h(TMP, read(B|TMP2)); | |
| 454 | do_cmp(A, read(TMP)); | |
| 455 | prefetch(); | |
| 456 | ||
| 457 | cmp_ce_idy | |
| 458 | TMP2 = read_pc(); | |
| 459 | TMP = read(B|TMP2); | |
| 460 | TMP2++; | |
| 461 | TMP = set_h(TMP, read(B|TMP2)); | |
| 462 | do_cmp(A, read(TMP+Y)); | |
| 463 | prefetch(); | |
| 464 | ||
| 465 | cmp_idz | |
| 466 | TMP2 = read_pc(); | |
| 467 | TMP = read(B|TMP2); | |
| 468 | TMP2++; | |
| 469 | TMP = set_h(TMP, read(B|TMP2)); | |
| 470 | do_cmp(A, read(TMP+Z)); | |
| 471 | prefetch(); | |
| 472 | ||
| 473 | cmp_ce_zpg | |
| 474 | TMP = read_pc(); | |
| 475 | TMP = read(B|TMP); | |
| 476 | do_cmp(A, TMP); | |
| 477 | prefetch(); | |
| 478 | ||
| 479 | cmp_ce_zpx | |
| 480 | TMP = read_pc(); | |
| 481 | read(TMP); | |
| 482 | TMP = read(B|UINT8(TMP+X)); | |
| 483 | do_cmp(A, TMP); | |
| 484 | prefetch(); | |
| 485 | ||
| 486 | cpx_ce_zpg | |
| 487 | TMP = read_pc(); | |
| 488 | TMP = read(B|TMP); | |
| 489 | do_cmp(X, TMP); | |
| 490 | prefetch(); | |
| 491 | ||
| 492 | cpy_ce_zpg | |
| 493 | TMP = read_pc(); | |
| 494 | TMP = read(B|TMP); | |
| 495 | do_cmp(Y, TMP); | |
| 496 | prefetch(); | |
| 497 | ||
| 498 | cpz_aba | |
| 499 | TMP = read_pc(); | |
| 500 | TMP = set_h(TMP, read_pc()); | |
| 501 | TMP = read(TMP); | |
| 502 | do_cmp(Z, TMP); | |
| 503 | prefetch(); | |
| 504 | ||
| 505 | cpz_imm | |
| 506 | TMP = read_pc(); | |
| 507 | do_cmp(Z, TMP); | |
| 508 | prefetch(); | |
| 509 | ||
| 510 | cpz_zpg | |
| 511 | TMP = read_pc(); | |
| 512 | TMP = read(B|TMP); | |
| 513 | do_cmp(Z, TMP); | |
| 514 | prefetch(); | |
| 515 | ||
| 516 | dec_ce_aba | |
| 517 | TMP = read_pc(); | |
| 518 | TMP = set_h(TMP, read_pc()); | |
| 519 | TMP2 = read(TMP); | |
| 520 | TMP2--; | |
| 521 | set_nz(TMP2); | |
| 522 | write(TMP, TMP2); | |
| 523 | prefetch(); | |
| 524 | ||
| 525 | dec_ce_abx | |
| 526 | TMP = read_pc(); | |
| 527 | TMP = set_h(TMP, read_pc()); | |
| 528 | TMP += X; | |
| 529 | TMP2 = read(TMP); | |
| 530 | TMP2--; | |
| 531 | set_nz(TMP2); | |
| 532 | write(TMP, TMP2); | |
| 533 | prefetch(); | |
| 534 | ||
| 535 | dec_ce_acc | |
| 536 | A--; | |
| 537 | set_nz(A); | |
| 538 | prefetch(); | |
| 539 | ||
| 540 | dec_ce_zpg | |
| 541 | TMP = B|read_pc(); | |
| 542 | TMP2 = read(TMP); | |
| 543 | TMP2--; | |
| 544 | set_nz(TMP2); | |
| 545 | write(TMP, TMP2); | |
| 546 | prefetch(); | |
| 547 | ||
| 548 | dec_ce_zpx | |
| 549 | TMP = read_pc(); | |
| 550 | TMP = B|UINT8(TMP+X); | |
| 551 | TMP2 = read(TMP); | |
| 552 | TMP2--; | |
| 553 | set_nz(TMP2); | |
| 554 | write(TMP, TMP2); | |
| 555 | prefetch(); | |
| 556 | ||
| 557 | dew_zpg | |
| 558 | TMP2 = read_pc(); | |
| 559 | TMP = read(B|TMP2); | |
| 560 | TMP2++; | |
| 561 | TMP = set_h(TMP, read(B|TMP2)); | |
| 562 | P &= ~(F_N|F_Z); | |
| 563 | TMP++; | |
| 564 | if(!TMP) | |
| 565 | P |= F_Z; | |
| 566 | else if(TMP & 0x8000) | |
| 567 | P |= F_N; | |
| 568 | TMP2++; | |
| 569 | write(B|TMP2, TMP); | |
| 570 | TMP2++; | |
| 571 | write(B|TMP2, TMP >> 8); | |
| 572 | prefetch(); | |
| 573 | ||
| 574 | dex_ce_imp | |
| 575 | X--; | |
| 576 | set_nz(X); | |
| 577 | prefetch(); | |
| 578 | ||
| 579 | dey_ce_imp | |
| 580 | Y--; | |
| 581 | set_nz(Y); | |
| 582 | prefetch(); | |
| 583 | ||
| 584 | dez_imp | |
| 585 | Z--; | |
| 586 | set_nz(Z); | |
| 587 | prefetch(); | |
| 588 | ||
| 589 | eor_ce_abx | |
| 590 | TMP = read_pc(); | |
| 591 | TMP = set_h(TMP, read_pc()); | |
| 592 | TMP += X; | |
| 593 | A ^= read(TMP); | |
| 594 | set_nz(A); | |
| 595 | prefetch(); | |
| 596 | ||
| 597 | eor_ce_aby | |
| 598 | TMP = read_pc(); | |
| 599 | TMP = set_h(TMP, read_pc()); | |
| 600 | TMP += Y; | |
| 601 | A ^= read(TMP); | |
| 602 | set_nz(A); | |
| 603 | prefetch(); | |
| 604 | ||
| 605 | eor_ce_idx | |
| 606 | TMP2 = read_pc(); | |
| 607 | TMP2 += X; | |
| 608 | TMP = read(B|TMP2); | |
| 609 | TMP2++; | |
| 610 | TMP = set_h(TMP, read(B|TMP2)); | |
| 611 | A ^= read(TMP); | |
| 612 | set_nz(A); | |
| 613 | prefetch(); | |
| 614 | ||
| 615 | eor_ce_idy | |
| 616 | TMP2 = read_pc(); | |
| 617 | TMP = read(B|TMP2); | |
| 618 | TMP2++; | |
| 619 | TMP = set_h(TMP, read(B|TMP2)); | |
| 620 | A ^= read(TMP+Y); | |
| 621 | set_nz(A); | |
| 622 | prefetch(); | |
| 623 | ||
| 624 | eor_idz | |
| 625 | TMP2 = read_pc(); | |
| 626 | TMP = read(B|TMP2); | |
| 627 | TMP2++; | |
| 628 | TMP = set_h(TMP, read(B|TMP2)); | |
| 629 | A ^= read(TMP+Z); | |
| 630 | set_nz(A); | |
| 631 | prefetch(); | |
| 632 | ||
| 633 | eor_ce_zpg | |
| 634 | TMP = read_pc(); | |
| 635 | A ^= read(B|TMP); | |
| 636 | set_nz(A); | |
| 637 | prefetch(); | |
| 638 | ||
| 639 | eor_ce_zpx | |
| 640 | TMP = read_pc(); | |
| 641 | A ^= read(B|UINT8(TMP+X)); | |
| 642 | set_nz(A); | |
| 643 | prefetch(); | |
| 644 | ||
| 645 | inc_ce_aba | |
| 646 | TMP = read_pc(); | |
| 647 | TMP = set_h(TMP, read_pc()); | |
| 648 | TMP2 = read(TMP); | |
| 649 | TMP2++; | |
| 650 | set_nz(TMP2); | |
| 651 | write(TMP, TMP2); | |
| 652 | prefetch(); | |
| 653 | ||
| 654 | inc_ce_abx | |
| 655 | TMP = read_pc(); | |
| 656 | TMP = set_h(TMP, read_pc()); | |
| 657 | TMP += X; | |
| 658 | TMP2 = read(TMP); | |
| 659 | TMP2++; | |
| 660 | set_nz(TMP2); | |
| 661 | write(TMP, TMP2); | |
| 662 | prefetch(); | |
| 663 | ||
| 664 | inc_ce_acc | |
| 665 | A++; | |
| 666 | set_nz(A); | |
| 667 | prefetch(); | |
| 668 | ||
| 669 | inc_ce_zpg | |
| 670 | TMP = B|read_pc(); | |
| 671 | TMP2 = read(TMP); | |
| 672 | TMP2++; | |
| 673 | set_nz(TMP2); | |
| 674 | write(TMP, TMP2); | |
| 675 | prefetch(); | |
| 676 | ||
| 677 | inc_ce_zpx | |
| 678 | TMP = read_pc(); | |
| 679 | TMP = B|UINT8(TMP+X); | |
| 680 | TMP2 = read(TMP); | |
| 681 | TMP2++; | |
| 682 | set_nz(TMP2); | |
| 683 | write(TMP, TMP2); | |
| 684 | prefetch(); | |
| 685 | ||
| 686 | inw_zpg | |
| 687 | TMP2 = read_pc(); | |
| 688 | TMP = read(B|TMP2); | |
| 689 | TMP2++; | |
| 690 | TMP = set_h(TMP, read(B|TMP2)); | |
| 691 | P &= ~(F_N|F_Z); | |
| 692 | TMP++; | |
| 693 | if(!TMP) | |
| 694 | P |= F_Z; | |
| 695 | else if(TMP & 0x8000) | |
| 696 | P |= F_N; | |
| 697 | TMP2--; | |
| 698 | write(B|TMP2, TMP); | |
| 699 | TMP2++; | |
| 700 | write(B|TMP2, TMP >> 8); | |
| 701 | prefetch(); | |
| 702 | ||
| 703 | inx_ce_imp | |
| 704 | X++; | |
| 705 | set_nz(X); | |
| 706 | prefetch(); | |
| 707 | ||
| 708 | iny_ce_imp | |
| 709 | Y++; | |
| 710 | set_nz(Y); | |
| 711 | prefetch(); | |
| 712 | ||
| 713 | inz_imp | |
| 714 | Z++; | |
| 715 | set_nz(Z); | |
| 716 | prefetch(); | |
| 717 | ||
| 718 | jmp_ce_iax | |
| 719 | TMP = read_pc(); | |
| 720 | TMP = set_h(TMP, read_pc()); | |
| 721 | TMP += X; | |
| 722 | PC = read(TMP); | |
| 723 | PC = set_h(PC, read(TMP+1)); | |
| 724 | prefetch(); | |
| 725 | ||
| 726 | jmp_ce_ind | |
| 727 | TMP = read_pc(); | |
| 728 | TMP = set_h(TMP, read_pc()); | |
| 729 | PC = read(TMP); | |
| 730 | PC = set_h(PC, read(TMP+1)); | |
| 731 | prefetch(); | |
| 732 | ||
| 733 | jsr_ce_adr | |
| 734 | TMP = read_pc(); | |
| 735 | write(SP, PC>>8); | |
| 736 | dec_SP_ce(); | |
| 737 | write(SP, PC); | |
| 738 | dec_SP_ce(); | |
| 739 | TMP = set_h(TMP, read_pc()); | |
| 740 | PC = TMP; | |
| 741 | prefetch(); | |
| 742 | ||
| 743 | jsr_iax | |
| 744 | TMP = read_pc(); | |
| 745 | write(SP, PC>>8); | |
| 746 | dec_SP_ce(); | |
| 747 | write(SP, PC); | |
| 748 | dec_SP_ce(); | |
| 749 | TMP = set_h(TMP, read_pc()); | |
| 750 | PC = read(TMP); | |
| 751 | PC = set_h(PC, read(TMP+1)); | |
| 752 | PC += X; | |
| 753 | prefetch(); | |
| 754 | ||
| 755 | jsr_ind | |
| 756 | TMP = read_pc(); | |
| 757 | write(SP, PC>>8); | |
| 758 | dec_SP_ce(); | |
| 759 | write(SP, PC); | |
| 760 | dec_SP_ce(); | |
| 761 | TMP = set_h(TMP, read_pc()); | |
| 762 | PC = read(TMP); | |
| 763 | PC = set_h(PC, read(TMP+1)); | |
| 764 | prefetch(); | |
| 765 | ||
| 766 | lda_ce_abx | |
| 767 | TMP = read_pc(); | |
| 768 | TMP = set_h(TMP, read_pc()); | |
| 769 | A = read(TMP + X); | |
| 770 | set_nz(A); | |
| 771 | prefetch(); | |
| 772 | ||
| 773 | lda_ce_aby | |
| 774 | TMP = read_pc(); | |
| 775 | TMP = set_h(TMP, read_pc()); | |
| 776 | A = read(TMP + Y); | |
| 777 | set_nz(A); | |
| 778 | prefetch(); | |
| 779 | ||
| 780 | lda_ce_idx | |
| 781 | TMP2 = read_pc(); | |
| 782 | TMP2 += X; | |
| 783 | TMP = read(B|TMP2); | |
| 784 | TMP2++; | |
| 785 | TMP = set_h(TMP, read(B|TMP2)); | |
| 786 | A = read(TMP); | |
| 787 | set_nz(A); | |
| 788 | prefetch(); | |
| 789 | ||
| 790 | lda_ce_idy | |
| 791 | TMP2 = read_pc(); | |
| 792 | TMP = read(B|TMP2); | |
| 793 | TMP2++; | |
| 794 | TMP = set_h(TMP, read(B|TMP2)); | |
| 795 | A = read(TMP+Y); | |
| 796 | set_nz(A); | |
| 797 | prefetch(); | |
| 798 | ||
| 799 | lda_idz | |
| 800 | TMP2 = read_pc(); | |
| 801 | TMP = read(B|TMP2); | |
| 802 | TMP2++; | |
| 803 | TMP = set_h(TMP, read(B|TMP2)); | |
| 804 | A = read(TMP+Z); | |
| 805 | set_nz(A); | |
| 806 | prefetch(); | |
| 807 | ||
| 808 | lda_isy | |
| 809 | read_pc_noinc(); | |
| 810 | TMP = read_pc(); | |
| 811 | if(P & F_E) | |
| 812 | TMP = set_l(SP, SP+TMP); | |
| 813 | else | |
| 814 | TMP = SP + TMP; | |
| 815 | TMP2 = read(TMP); | |
| 816 | TMP++; | |
| 817 | TMP = TMP2 | (read(TMP) << 8); | |
| 818 | A = read(TMP+Y); | |
| 819 | set_nz(A); | |
| 820 | prefetch(); | |
| 821 | ||
| 822 | lda_ce_zpg | |
| 823 | TMP = read_pc(); | |
| 824 | A = read(B|TMP); | |
| 825 | set_nz(A); | |
| 826 | prefetch(); | |
| 827 | ||
| 828 | lda_ce_zpx | |
| 829 | TMP = read_pc(); | |
| 830 | A = read(B|UINT8(TMP+X)); | |
| 831 | set_nz(A); | |
| 832 | prefetch(); | |
| 833 | ||
| 834 | ldx_ce_aby | |
| 835 | TMP = read_pc(); | |
| 836 | TMP = set_h(TMP, read_pc()); | |
| 837 | X = read(TMP + Y); | |
| 838 | set_nz(X); | |
| 839 | prefetch(); | |
| 840 | ||
| 841 | ldx_ce_zpg | |
| 842 | TMP = read_pc(); | |
| 843 | X = read(B|TMP); | |
| 844 | set_nz(X); | |
| 845 | prefetch(); | |
| 846 | ||
| 847 | ldx_ce_zpy | |
| 848 | TMP = read_pc(); | |
| 849 | X = read(B|UINT8(TMP+Y)); | |
| 850 | set_nz(X); | |
| 851 | prefetch(); | |
| 852 | ||
| 853 | ldy_ce_abx | |
| 854 | TMP = read_pc(); | |
| 855 | TMP = set_h(TMP, read_pc()); | |
| 856 | TMP += X; | |
| 857 | Y = read(TMP); | |
| 858 | set_nz(Y); | |
| 859 | prefetch(); | |
| 860 | ||
| 861 | ldy_ce_zpg | |
| 862 | TMP = read_pc(); | |
| 863 | Y = read(B|TMP); | |
| 864 | set_nz(Y); | |
| 865 | prefetch(); | |
| 866 | ||
| 867 | ldy_ce_zpx | |
| 868 | TMP = read_pc(); | |
| 869 | Y = read(B|UINT8(TMP+X)); | |
| 870 | set_nz(Y); | |
| 871 | prefetch(); | |
| 872 | ||
| 873 | ldz_aba | |
| 874 | TMP = read_pc(); | |
| 875 | TMP = set_h(TMP, read_pc()); | |
| 876 | Z = read(TMP); | |
| 877 | set_nz(Z); | |
| 878 | prefetch(); | |
| 879 | ||
| 880 | ldz_abx | |
| 881 | TMP = read_pc(); | |
| 882 | TMP = set_h(TMP, read_pc()); | |
| 883 | Z = read(TMP + X); | |
| 884 | set_nz(Z); | |
| 885 | prefetch(); | |
| 886 | ||
| 887 | ldz_imm | |
| 888 | Z = read_pc(); | |
| 889 | set_nz(Z); | |
| 890 | prefetch(); | |
| 891 | ||
| 892 | lsr_ce_aba | |
| 893 | TMP = read_pc(); | |
| 894 | TMP = set_h(TMP, read_pc()); | |
| 895 | TMP2 = read(TMP); | |
| 896 | TMP2 = do_lsr(TMP2); | |
| 897 | write(TMP, TMP2); | |
| 898 | prefetch(); | |
| 899 | ||
| 900 | lsr_ce_abx | |
| 901 | TMP = read_pc(); | |
| 902 | TMP = set_h(TMP, read_pc()); | |
| 903 | read(set_l(TMP, TMP+X)); | |
| 904 | TMP += X; | |
| 905 | TMP2 = read(TMP); | |
| 906 | TMP2 = do_lsr(TMP2); | |
| 907 | write(TMP, TMP2); | |
| 908 | prefetch(); | |
| 909 | ||
| 910 | lsr_ce_acc | |
| 911 | A = do_lsr(A); | |
| 912 | prefetch(); | |
| 913 | ||
| 914 | lsr_ce_zpg | |
| 915 | TMP = B|read_pc(); | |
| 916 | TMP2 = read(TMP); | |
| 917 | TMP2 = do_lsr(TMP2); | |
| 918 | write(TMP, TMP2); | |
| 919 | prefetch(); | |
| 920 | ||
| 921 | lsr_ce_zpx | |
| 922 | TMP = read_pc(); | |
| 923 | TMP = B|UINT8(TMP+X); | |
| 924 | TMP2 = read(TMP); | |
| 925 | TMP2 = do_lsr(TMP2); | |
| 926 | write(TMP, TMP2); | |
| 927 | prefetch(); | |
| 928 | ||
| 929 | neg_acc | |
| 930 | read_pc_noinc(); | |
| 931 | A = -A; | |
| 932 | set_nz(A); | |
| 933 | prefetch(); | |
| 934 | ||
| 935 | ora_ce_abx | |
| 936 | TMP = read_pc(); | |
| 937 | TMP = set_h(TMP, read_pc()); | |
| 938 | TMP += X; | |
| 939 | A |= read(TMP); | |
| 940 | set_nz(A); | |
| 941 | prefetch(); | |
| 942 | ||
| 943 | ora_ce_aby | |
| 944 | TMP = read_pc(); | |
| 945 | TMP = set_h(TMP, read_pc()); | |
| 946 | TMP += Y; | |
| 947 | A |= read(TMP); | |
| 948 | set_nz(A); | |
| 949 | prefetch(); | |
| 950 | ||
| 951 | ora_ce_idx | |
| 952 | TMP2 = read_pc(); | |
| 953 | TMP2 += X; | |
| 954 | TMP = read(B|TMP2); | |
| 955 | TMP2++; | |
| 956 | TMP = set_h(TMP, read(B|TMP2)); | |
| 957 | A |= read(TMP); | |
| 958 | set_nz(A); | |
| 959 | prefetch(); | |
| 960 | ||
| 961 | ora_ce_idy | |
| 962 | TMP2 = read_pc(); | |
| 963 | TMP = read(B|TMP2); | |
| 964 | TMP2++; | |
| 965 | TMP = set_h(TMP, read(B|TMP2)); | |
| 966 | A |= read(TMP+Y); | |
| 967 | set_nz(A); | |
| 968 | prefetch(); | |
| 969 | ||
| 970 | ora_idz | |
| 971 | TMP2 = read_pc(); | |
| 972 | TMP = read(B|TMP2); | |
| 973 | TMP2++; | |
| 974 | TMP = set_h(TMP, read(B|TMP2)); | |
| 975 | A |= read(TMP+Z); | |
| 976 | set_nz(A); | |
| 977 | prefetch(); | |
| 978 | ||
| 979 | ora_ce_zpg | |
| 980 | TMP = read_pc(); | |
| 981 | A |= read(B|TMP); | |
| 982 | set_nz(A); | |
| 983 | prefetch(); | |
| 984 | ||
| 985 | ora_ce_zpx | |
| 986 | TMP = read_pc(); | |
| 987 | A |= read(B|UINT8(TMP+X)); | |
| 988 | set_nz(A); | |
| 989 | prefetch(); | |
| 990 | ||
| 991 | # push/pop instructions and rti/rtn/rts are not fully streamlined | |
| 992 | pha_ce_imp | |
| 993 | read_pc_noinc(); | |
| 994 | write(SP, A); | |
| 995 | dec_SP_ce(); | |
| 996 | prefetch(); | |
| 997 | ||
| 998 | php_ce_imp | |
| 999 | read_pc_noinc(); | |
| 1000 | write(SP, P); | |
| 1001 | dec_SP_ce(); | |
| 1002 | prefetch(); | |
| 1003 | ||
| 1004 | phw_aba | |
| 1005 | TMP = read_pc(); | |
| 1006 | TMP = set_h(TMP, read_pc()); | |
| 1007 | TMP3 = read(TMP); | |
| 1008 | TMP3 = set_h(TMP3, read(TMP+1)); | |
| 1009 | dec_SP_ce(); | |
| 1010 | write(SP, TMP3); | |
| 1011 | dec_SP_ce(); | |
| 1012 | write(SP, TMP3 >> 8); | |
| 1013 | prefetch(); | |
| 1014 | ||
| 1015 | phw_iw2 | |
| 1016 | TMP = read_pc(); | |
| 1017 | TMP = set_h(TMP, read_pc()); | |
| 1018 | dec_SP_ce(); | |
| 1019 | write(SP, TMP); | |
| 1020 | dec_SP_ce(); | |
| 1021 | write(SP, TMP >> 8); | |
| 1022 | prefetch(); | |
| 1023 | ||
| 1024 | phx_ce_imp | |
| 1025 | read_pc_noinc(); | |
| 1026 | write(SP, X); | |
| 1027 | dec_SP_ce(); | |
| 1028 | prefetch(); | |
| 1029 | ||
| 1030 | phy_ce_imp | |
| 1031 | read_pc_noinc(); | |
| 1032 | write(SP, Y); | |
| 1033 | dec_SP_ce(); | |
| 1034 | prefetch(); | |
| 1035 | ||
| 1036 | phz_imp | |
| 1037 | read_pc_noinc(); | |
| 1038 | write(SP, Z); | |
| 1039 | dec_SP_ce(); | |
| 1040 | prefetch(); | |
| 1041 | ||
| 1042 | pla_ce_imp | |
| 1043 | read_pc_noinc(); | |
| 1044 | inc_SP_ce(); | |
| 1045 | A = read(SP); | |
| 1046 | set_nz(A); | |
| 1047 | prefetch(); | |
| 1048 | ||
| 1049 | plp_ce_imp | |
| 1050 | read_pc_noinc(); | |
| 1051 | inc_SP_ce(); | |
| 1052 | TMP = read(SP) | F_B; | |
| 1053 | prefetch(); | |
| 1054 | P = TMP; // Do *not* move it before the prefetch | |
| 1055 | ||
| 1056 | plx_ce_imp | |
| 1057 | read_pc_noinc(); | |
| 1058 | inc_SP_ce(); | |
| 1059 | X = read(SP); | |
| 1060 | set_nz(X); | |
| 1061 | prefetch(); | |
| 1062 | ||
| 1063 | ply_ce_imp | |
| 1064 | read_pc_noinc(); | |
| 1065 | inc_SP_ce(); | |
| 1066 | Y = read(SP); | |
| 1067 | set_nz(Y); | |
| 1068 | prefetch(); | |
| 1069 | ||
| 1070 | plz_imp | |
| 1071 | read_pc_noinc(); | |
| 1072 | inc_SP_ce(); | |
| 1073 | Z = read(SP); | |
| 1074 | set_nz(Z); | |
| 1075 | prefetch(); | |
| 1076 | ||
| 1077 | rmb_ce_bzp | |
| 1078 | TMP = read_pc(); | |
| 1079 | TMP2 = read(TMP); | |
| 1080 | TMP2 &= ~(1 << (inst_state & 7)); | |
| 1081 | write(TMP, TMP2); | |
| 1082 | prefetch(); | |
| 1083 | ||
| 1084 | rol_ce_aba | |
| 1085 | TMP = read_pc(); | |
| 1086 | TMP = set_h(TMP, read_pc()); | |
| 1087 | TMP2 = read(TMP); | |
| 1088 | TMP2 = do_rol(TMP2); | |
| 1089 | write(TMP, TMP2); | |
| 1090 | prefetch(); | |
| 1091 | ||
| 1092 | rol_ce_abx | |
| 1093 | TMP = read_pc(); | |
| 1094 | TMP = set_h(TMP, read_pc()); | |
| 1095 | TMP += X; | |
| 1096 | TMP2 = read(TMP); | |
| 1097 | TMP2 = do_rol(TMP2); | |
| 1098 | write(TMP, TMP2); | |
| 1099 | prefetch(); | |
| 1100 | ||
| 1101 | rol_ce_acc | |
| 1102 | A = do_rol(A); | |
| 1103 | prefetch(); | |
| 1104 | ||
| 1105 | rol_ce_zpg | |
| 1106 | TMP = B|read_pc(); | |
| 1107 | TMP2 = read(TMP); | |
| 1108 | TMP2 = do_rol(TMP2); | |
| 1109 | write(TMP, TMP2); | |
| 1110 | prefetch(); | |
| 1111 | ||
| 1112 | rol_ce_zpx | |
| 1113 | TMP = read_pc(); | |
| 1114 | TMP = B|UINT8(TMP+X); | |
| 1115 | TMP2 = read(TMP); | |
| 1116 | TMP2 = do_rol(TMP2); | |
| 1117 | write(TMP, TMP2); | |
| 1118 | prefetch(); | |
| 1119 | ||
| 1120 | ror_ce_aba | |
| 1121 | TMP = read_pc(); | |
| 1122 | TMP = set_h(TMP, read_pc()); | |
| 1123 | TMP2 = read(TMP); | |
| 1124 | TMP2 = do_ror(TMP2); | |
| 1125 | write(TMP, TMP2); | |
| 1126 | prefetch(); | |
| 1127 | ||
| 1128 | ror_ce_abx | |
| 1129 | TMP = read_pc(); | |
| 1130 | TMP = set_h(TMP, read_pc()); | |
| 1131 | TMP += X; | |
| 1132 | TMP2 = read(TMP); | |
| 1133 | TMP2 = do_ror(TMP2); | |
| 1134 | write(TMP, TMP2); | |
| 1135 | prefetch(); | |
| 1136 | ||
| 1137 | ror_ce_acc | |
| 1138 | A = do_ror(A); | |
| 1139 | prefetch(); | |
| 1140 | ||
| 1141 | ror_ce_zpg | |
| 1142 | TMP = B|read_pc(); | |
| 1143 | TMP2 = read(TMP); | |
| 1144 | TMP2 = do_ror(TMP2); | |
| 1145 | write(TMP, TMP2); | |
| 1146 | prefetch(); | |
| 1147 | ||
| 1148 | ror_ce_zpx | |
| 1149 | TMP = read_pc(); | |
| 1150 | TMP = B|UINT8(TMP+X); | |
| 1151 | TMP2 = read(TMP); | |
| 1152 | TMP2 = do_ror(TMP2); | |
| 1153 | write(TMP, TMP2); | |
| 1154 | prefetch(); | |
| 1155 | ||
| 1156 | row_aba | |
| 1157 | TMP = read_pc(); | |
| 1158 | TMP = set_h(TMP, read_pc()); | |
| 1159 | TMP3 = read(TMP); | |
| 1160 | TMP3 = set_h(TMP3, read(TMP+1)); | |
| 1161 | TMP2 = P; | |
| 1162 | P &= ~(F_C|F_N|F_Z); | |
| 1163 | if(TMP3 & 0x8000) | |
| 1164 | P |= F_C; | |
| 1165 | TMP3 <<= 1; | |
| 1166 | if(TMP2 & F_C) | |
| 1167 | TMP3 |= 0x0001; | |
| 1168 | if(!TMP3) | |
| 1169 | P |= F_Z; | |
| 1170 | else if(TMP3 & 0x8000) | |
| 1171 | P |= F_N; | |
| 1172 | write(TMP, TMP3); | |
| 1173 | write(TMP, TMP3 >> 8); | |
| 1174 | prefetch(); | |
| 1175 | ||
| 1176 | rti_ce_imp | |
| 1177 | read_pc_noinc(); | |
| 1178 | inc_SP_ce(); | |
| 1179 | P = read(SP) | F_B; | |
| 1180 | inc_SP_ce(); | |
| 1181 | PC = read(SP); | |
| 1182 | inc_SP_ce(); | |
| 1183 | PC = set_h(PC, read(SP)); | |
| 1184 | prefetch(); | |
| 1185 | ||
| 1186 | rtn_imm | |
| 1187 | TMP = read_pc(); | |
| 1188 | if(P & F_E) | |
| 1189 | SP = set_l(SP, SP+TMP); | |
| 1190 | else | |
| 1191 | SP += TMP; | |
| 1192 | read_pc_noinc(); | |
| 1193 | read(SP); | |
| 1194 | inc_SP(); | |
| 1195 | PC = read(SP); | |
| 1196 | inc_SP(); | |
| 1197 | PC = set_h(PC, read(SP)); | |
| 1198 | read_pc(); | |
| 1199 | prefetch(); | |
| 1200 | ||
| 1201 | rts_ce_imp | |
| 1202 | inc_SP_ce(); | |
| 1203 | PC = read(SP); | |
| 1204 | inc_SP_ce(); | |
| 1205 | PC = set_h(PC, read(SP)); | |
| 1206 | read_pc(); | |
| 1207 | prefetch(); | |
| 1208 | ||
| 1209 | sbc_ce_aba | |
| 1210 | TMP = read_pc(); | |
| 1211 | TMP = set_h(TMP, read_pc()); | |
| 1212 | TMP = read(TMP); | |
| 1213 | do_sbc(TMP); | |
| 1214 | if(P & F_D) | |
| 1215 | set_nz(A); | |
| 1216 | prefetch(); | |
| 1217 | ||
| 1218 | sbc_ce_abx | |
| 1219 | TMP = read_pc(); | |
| 1220 | TMP = set_h(TMP, read_pc()); | |
| 1221 | TMP += X; | |
| 1222 | TMP = read(TMP); | |
| 1223 | do_sbc(TMP); | |
| 1224 | if(P & F_D) | |
| 1225 | set_nz(A); | |
| 1226 | prefetch(); | |
| 1227 | ||
| 1228 | sbc_ce_aby | |
| 1229 | TMP = read_pc(); | |
| 1230 | TMP = set_h(TMP, read_pc()); | |
| 1231 | TMP += Y; | |
| 1232 | TMP = read(TMP); | |
| 1233 | do_sbc(TMP); | |
| 1234 | if(P & F_D) | |
| 1235 | set_nz(A); | |
| 1236 | prefetch(); | |
| 1237 | ||
| 1238 | sbc_ce_idx | |
| 1239 | TMP2 = read_pc(); | |
| 1240 | TMP2 += X; | |
| 1241 | TMP = read(B|TMP2); | |
| 1242 | TMP2++; | |
| 1243 | TMP = set_h(TMP, read(B|TMP2)); | |
| 1244 | do_sbc(read(TMP)); | |
| 1245 | if(P & F_D) | |
| 1246 | set_nz(A); | |
| 1247 | prefetch(); | |
| 1248 | ||
| 1249 | sbc_ce_idy | |
| 1250 | TMP2 = read_pc(); | |
| 1251 | TMP = read(B|TMP2); | |
| 1252 | TMP2++; | |
| 1253 | TMP = set_h(TMP, read(B|TMP2)); | |
| 1254 | do_sbc(read(TMP+Y)); | |
| 1255 | if(P & F_D) | |
| 1256 | set_nz(A); | |
| 1257 | prefetch(); | |
| 1258 | ||
| 1259 | sbc_idz | |
| 1260 | TMP2 = read_pc(); | |
| 1261 | TMP = read(B|TMP2); | |
| 1262 | TMP2++; | |
| 1263 | TMP = set_h(TMP, read(B|TMP2)); | |
| 1264 | do_sbc(read(TMP+Z)); | |
| 1265 | if(P & F_D) | |
| 1266 | set_nz(A); | |
| 1267 | prefetch(); | |
| 1268 | ||
| 1269 | sbc_ce_imm | |
| 1270 | TMP = read_pc(); | |
| 1271 | do_sbc(TMP); | |
| 1272 | if(P & F_D) | |
| 1273 | set_nz(A); | |
| 1274 | prefetch(); | |
| 1275 | ||
| 1276 | sbc_ce_zpg | |
| 1277 | TMP = read_pc(); | |
| 1278 | TMP = read(B|TMP); | |
| 1279 | do_sbc(TMP); | |
| 1280 | if(P & F_D) | |
| 1281 | set_nz(A); | |
| 1282 | prefetch(); | |
| 1283 | ||
| 1284 | sbc_ce_zpx | |
| 1285 | TMP = read_pc(); | |
| 1286 | read(TMP); | |
| 1287 | TMP = read(B|UINT8(TMP+X)); | |
| 1288 | do_sbc(TMP); | |
| 1289 | if(P & F_D) | |
| 1290 | set_nz(A); | |
| 1291 | prefetch(); | |
| 1292 | ||
| 1293 | sec_ce_imp | |
| 1294 | P |= F_C; | |
| 1295 | prefetch(); | |
| 1296 | ||
| 1297 | sed_ce_imp | |
| 1298 | P |= F_D; | |
| 1299 | prefetch(); | |
| 1300 | ||
| 1301 | see_imp | |
| 1302 | read_pc_noinc(); | |
| 1303 | P |= F_E; | |
| 1304 | prefetch(); | |
| 1305 | ||
| 1306 | sei_ce_imp | |
| 1307 | prefetch(); | |
| 1308 | P |= F_I; // Do *not* move it before the prefetch | |
| 1309 | ||
| 1310 | smb_ce_bzp | |
| 1311 | TMP = read_pc(); | |
| 1312 | TMP2 = read(TMP); | |
| 1313 | TMP2 |= 1 << (inst_state & 7); | |
| 1314 | write(TMP, TMP2); | |
| 1315 | prefetch(); | |
| 1316 | ||
| 1317 | sta_ce_abx | |
| 1318 | TMP = read_pc(); | |
| 1319 | TMP = set_h(TMP, read_pc()); | |
| 1320 | write(TMP+X, A); | |
| 1321 | prefetch(); | |
| 1322 | ||
| 1323 | sta_ce_aby | |
| 1324 | TMP = read_pc(); | |
| 1325 | TMP = set_h(TMP, read_pc()); | |
| 1326 | write(TMP+Y, A); | |
| 1327 | prefetch(); | |
| 1328 | ||
| 1329 | sta_ce_idx | |
| 1330 | TMP2 = read_pc(); | |
| 1331 | TMP2 += X; | |
| 1332 | TMP = read(B|TMP2); | |
| 1333 | TMP2++; | |
| 1334 | TMP = set_h(TMP, read(B|TMP2)); | |
| 1335 | write(TMP, A); | |
| 1336 | prefetch(); | |
| 1337 | ||
| 1338 | sta_ce_idy | |
| 1339 | TMP2 = read_pc(); | |
| 1340 | TMP = read(B|TMP2); | |
| 1341 | TMP2++; | |
| 1342 | TMP = set_h(TMP, read(B|TMP2)); | |
| 1343 | write(TMP+Y, A); | |
| 1344 | prefetch(); | |
| 1345 | ||
| 1346 | sta_idz | |
| 1347 | TMP2 = read_pc(); | |
| 1348 | TMP = read(B|TMP2); | |
| 1349 | TMP2++; | |
| 1350 | TMP = set_h(TMP, read(B|TMP2)); | |
| 1351 | write(TMP+Z, A); | |
| 1352 | prefetch(); | |
| 1353 | ||
| 1354 | sta_isy | |
| 1355 | read_pc_noinc(); | |
| 1356 | TMP = read_pc(); | |
| 1357 | if(P & F_E) | |
| 1358 | TMP = set_l(SP, SP+TMP); | |
| 1359 | else | |
| 1360 | TMP = SP + TMP; | |
| 1361 | TMP2 = read(TMP); | |
| 1362 | TMP++; | |
| 1363 | TMP = TMP2 | (read(TMP) << 8); | |
| 1364 | write(TMP+Y, A); | |
| 1365 | prefetch(); | |
| 1366 | ||
| 1367 | sta_ce_zpg | |
| 1368 | TMP = read_pc(); | |
| 1369 | write(B|TMP, A); | |
| 1370 | prefetch(); | |
| 1371 | ||
| 1372 | sta_ce_zpx | |
| 1373 | TMP = read_pc(); | |
| 1374 | write(B|UINT8(TMP+X), A); | |
| 1375 | prefetch(); | |
| 1376 | ||
| 1377 | stx_aby | |
| 1378 | TMP = read_pc(); | |
| 1379 | TMP = set_h(TMP, read_pc()); | |
| 1380 | write(TMP+Y, X); | |
| 1381 | prefetch(); | |
| 1382 | ||
| 1383 | stx_ce_zpg | |
| 1384 | TMP = read_pc(); | |
| 1385 | write(B|TMP, X); | |
| 1386 | prefetch(); | |
| 1387 | ||
| 1388 | stx_ce_zpy | |
| 1389 | TMP = read_pc(); | |
| 1390 | write(B|UINT8(TMP+Y), X); | |
| 1391 | prefetch(); | |
| 1392 | ||
| 1393 | sty_abx | |
| 1394 | TMP = read_pc(); | |
| 1395 | TMP = set_h(TMP, read_pc()); | |
| 1396 | write(TMP+X, Y); | |
| 1397 | prefetch(); | |
| 1398 | ||
| 1399 | sty_ce_zpg | |
| 1400 | TMP = read_pc(); | |
| 1401 | write(B|TMP, Y); | |
| 1402 | prefetch(); | |
| 1403 | ||
| 1404 | sty_ce_zpx | |
| 1405 | TMP = read_pc(); | |
| 1406 | write(B|UINT8(TMP+X), Y); | |
| 1407 | prefetch(); | |
| 1408 | ||
| 1409 | stz_ce_aba | |
| 1410 | TMP = read_pc(); | |
| 1411 | TMP = set_h(TMP, read_pc()); | |
| 1412 | write(TMP, A); | |
| 1413 | prefetch(); | |
| 1414 | ||
| 1415 | stz_ce_abx | |
| 1416 | TMP = read_pc(); | |
| 1417 | TMP = set_h(TMP, read_pc()); | |
| 1418 | write(TMP+X, A); | |
| 1419 | prefetch(); | |
| 1420 | ||
| 1421 | stz_ce_zpg | |
| 1422 | TMP = read_pc(); | |
| 1423 | write(B|TMP, Z); | |
| 1424 | prefetch(); | |
| 1425 | ||
| 1426 | stz_ce_zpx | |
| 1427 | TMP = read_pc(); | |
| 1428 | write(B|UINT8(TMP+X), Z); | |
| 1429 | prefetch(); | |
| 1430 | ||
| 1431 | tab_imp | |
| 1432 | B = A << 8; | |
| 1433 | prefetch(); | |
| 1434 | ||
| 1435 | tax_ce_imp | |
| 1436 | X = A; | |
| 1437 | set_nz(X); | |
| 1438 | prefetch(); | |
| 1439 | ||
| 1440 | tay_ce_imp | |
| 1441 | Y = A; | |
| 1442 | set_nz(Y); | |
| 1443 | prefetch(); | |
| 1444 | ||
| 1445 | taz_imp | |
| 1446 | Z = A; | |
| 1447 | set_nz(Z); | |
| 1448 | prefetch(); | |
| 1449 | ||
| 1450 | tba_imp | |
| 1451 | A = B >> 8; | |
| 1452 | set_nz(A); | |
| 1453 | prefetch(); | |
| 1454 | ||
| 1455 | trb_ce_aba | |
| 1456 | TMP = read_pc(); | |
| 1457 | TMP = set_h(TMP, read_pc()); | |
| 1458 | TMP2 = read(TMP); | |
| 1459 | if(A & TMP2) | |
| 1460 | P &= ~F_Z; | |
| 1461 | else | |
| 1462 | P |= F_Z; | |
| 1463 | TMP2 &= ~A; | |
| 1464 | write(TMP, TMP2); | |
| 1465 | prefetch(); | |
| 1466 | ||
| 1467 | trb_ce_zpg | |
| 1468 | TMP = read_pc(); | |
| 1469 | TMP2 = read(TMP); | |
| 1470 | if(A & TMP2) | |
| 1471 | P &= ~F_Z; | |
| 1472 | else | |
| 1473 | P |= F_Z; | |
| 1474 | TMP2 &= ~A; | |
| 1475 | write(TMP, TMP2); | |
| 1476 | prefetch(); | |
| 1477 | ||
| 1478 | tsb_ce_aba | |
| 1479 | TMP = read_pc(); | |
| 1480 | TMP = set_h(TMP, read_pc()); | |
| 1481 | TMP2 = read(TMP); | |
| 1482 | if(A & TMP2) | |
| 1483 | P &= ~F_Z; | |
| 1484 | else | |
| 1485 | P |= F_Z; | |
| 1486 | TMP2 |= A; | |
| 1487 | write(TMP, TMP2); | |
| 1488 | prefetch(); | |
| 1489 | ||
| 1490 | tsb_ce_zpg | |
| 1491 | TMP = read_pc(); | |
| 1492 | TMP2 = read(TMP); | |
| 1493 | if(A & TMP2) | |
| 1494 | P &= ~F_Z; | |
| 1495 | else | |
| 1496 | P |= F_Z; | |
| 1497 | TMP2 |= A; | |
| 1498 | write(TMP, TMP2); | |
| 1499 | prefetch(); | |
| 1500 | ||
| 1501 | tsx_ce_imp | |
| 1502 | X = SP; | |
| 1503 | set_nz(X); | |
| 1504 | prefetch(); | |
| 1505 | ||
| 1506 | tsy_imp | |
| 1507 | Y = SP >> 8; | |
| 1508 | set_nz(Y); | |
| 1509 | prefetch(); | |
| 1510 | ||
| 1511 | txa_ce_imp | |
| 1512 | A = X; | |
| 1513 | set_nz(A); | |
| 1514 | prefetch(); | |
| 1515 | ||
| 1516 | txs_ce_imp | |
| 1517 | SP = set_l(SP, X); | |
| 1518 | prefetch_noirq(); | |
| 1519 | ||
| 1520 | tys_imp | |
| 1521 | SP = set_h(SP, Y); | |
| 1522 | prefetch(); | |
| 1523 | ||
| 1524 | tya_ce_imp | |
| 1525 | A = Y; | |
| 1526 | set_nz(A); | |
| 1527 | prefetch(); | |
| 1528 | ||
| 1529 | tza_imp | |
| 1530 | A = Z; | |
| 1531 | set_nz(A); | |
| 1532 | prefetch(); |
| r18874 | r18875 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * m6509.c | |
| 4 | * Portable 6509 emulator V1.0beta1 | |
| 5 | * | |
| 6 | * Copyright Peter Trauner, all rights reserved. | |
| 7 | * documentation by vice emulator team | |
| 8 | * | |
| 9 | * - This source code is released as freeware for non-commercial purposes. | |
| 10 | * - You are free to use and redistribute this code in modified or | |
| 11 | * unmodified form, provided you list me in the credits. | |
| 12 | * - If you modify this source code, you must add a notice to each modified | |
| 13 | * source file that it has been changed. If you're a nice person, you | |
| 14 | * will clearly mark each change too. :) | |
| 15 | * - If you wish to use this for commercial purposes, please contact me at | |
| 16 | * pullmoll@t-online.de | |
| 17 | * - The author of this copywritten work reserves the right to change the | |
| 18 | * terms of its usage and license at any time, including retroactively | |
| 19 | * - This entire notice must remain in the source code. | |
| 20 | * | |
| 21 | *****************************************************************************/ | |
| 22 | /* | |
| 23 | 2000 March 10 PeT added SO input line | |
| 1 | /*************************************************************************** | |
| 24 | 2 | |
| 25 | The basic difference is the amount of RAM these machines have been supplied with. The B128 and the CBM *10 | |
| 26 | models had 128k RAM, the others 256k. This implies some banking scheme, as the 6502 can only address 64k. And | |
| 27 | indeed those machines use a 6509, that can address 1 MByte of RAM. It has 2 registers at addresses 0 and 1. The | |
| 28 | indirect bank register at address 1 determines the bank (0-15) where the opcodes LDA (zp),Y and STA (zp),Y | |
| 29 | take the data from. The exec bank register at address 0 determines the bank where all other read and write | |
| 30 | addresses take place. | |
| 3 | m6509.c | |
| 31 | 4 | |
| 32 | vice writes to bank register only with zeropage operand | |
| 33 | 0, 1 are bank register in all banks | |
| 5 | 6502 with banking and extended address bus | |
| 34 | 6 | |
| 35 | lda (zp),y | |
| 36 | sta (zp),y | |
| 7 | **************************************************************************** | |
| 37 | 8 | |
| 38 | */ | |
| 9 | Copyright Olivier Galibert | |
| 10 | All rights reserved. | |
| 39 | 11 | |
| 40 | #include "emu.h" | |
| 41 | #include "debugger.h" | |
| 42 | #include "m6509.h" | |
| 12 | Redistribution and use in source and binary forms, with or without | |
| 13 | modification, are permitted provided that the following conditions are | |
| 14 | met: | |
| 43 | 15 | |
| 44 | #include "ops02.h" | |
| 45 | #include "ill02.h" | |
| 46 | #include "ops09.h" | |
| 16 | * Redistributions of source code must retain the above copyright | |
| 17 | notice, this list of conditions and the following disclaimer. | |
| 18 | * Redistributions in binary form must reproduce the above copyright | |
| 19 | notice, this list of conditions and the following disclaimer in | |
| 20 | the documentation and/or other materials provided with the | |
| 21 | distribution. | |
| 22 | * Neither the name 'MAME' nor the names of its contributors may be | |
| 23 | used to endorse or promote products derived from this software | |
| 24 | without specific prior written permission. | |
| 47 | 25 | |
| 48 | #define M6502_NMI_VEC 0xfffa | |
| 49 | #define M6502_RST_VEC 0xfffc | |
| 50 | #define M6502_IRQ_VEC 0xfffe | |
| 51 | #define M6509_RST_VEC M6502_RST_VEC | |
| 52 | #define M6509_IRQ_VEC M6502_IRQ_VEC | |
| 53 | #define M6509_NMI_VEC M6502_NMI_VEC | |
| 26 | THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR | |
| 27 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 28 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 29 | DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, | |
| 30 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 31 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
| 32 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 33 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
| 34 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
| 35 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| 36 | POSSIBILITY OF SUCH DAMAGE. | |
| 54 | 37 | |
| 55 | ||
| 38 | ***************************************************************************/ | |
| 56 | 39 | |
| 57 | #define LOG(x) do { if (VERBOSE) logerror x; } while (0) | |
| 40 | #include "emu.h" | |
| 41 | #include "m6509.h" | |
| 58 | 42 | |
| 59 | struct m6509_Regs { | |
| 60 | UINT8 subtype; /* currently selected cpu sub type */ | |
| 61 | void (*const *insn)(m6509_Regs *); /* pointer to the function pointer table */ | |
| 62 | PAIR ppc; /* previous program counter */ | |
| 63 | /* pc.w.h contains the current page pc_bank.w.h for better speed */ | |
| 64 | PAIR pc; /* program counter */ | |
| 65 | PAIR sp; /* stack pointer (always 100 - 1FF) */ | |
| 66 | PAIR zp; /* zero page address */ | |
| 67 | PAIR ea; /* effective address */ | |
| 68 | UINT8 a; /* Accumulator */ | |
| 69 | UINT8 x; /* X index register */ | |
| 70 | UINT8 y; /* Y index register */ | |
| 71 | PAIR pc_bank; /* 4 bits, addressed over address 0 */ | |
| 72 | PAIR ind_bank; /* 4 bits, addressed over address 1 */ | |
| 73 | UINT8 p; /* Processor status */ | |
| 74 | UINT8 pending_irq; /* nonzero if an IRQ is pending */ | |
| 75 | UINT8 after_cli; /* pending IRQ and last insn cleared I */ | |
| 76 | UINT8 nmi_state; | |
| 77 | UINT8 irq_state; | |
| 78 | UINT8 so_state; | |
| 79 | device_irq_acknowledge_callback irq_callback; | |
| 80 | legacy_cpu_device *device; | |
| 81 | address_space *space; | |
| 82 | direct_read_data *direct; | |
| 43 | const device_type M6509 = &device_creator<m6509_device>; | |
| 83 | 44 | |
| 84 | int int_occured; | |
| 85 | int icount; | |
| 86 | ||
| 87 | devcb_resolved_read8 rdmem_id; /* readmem callback for indexed instructions */ | |
| 88 | devcb_resolved_write8 wrmem_id; /* writemem callback for indexed instructions */ | |
| 89 | }; | |
| 90 | ||
| 91 | INLINE m6509_Regs *get_safe_token(device_t *device) | |
| 45 | m6509_device::m6509_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : | |
| 46 | m6502_device(mconfig, M6509, "M6509", tag, owner, clock) | |
| 92 | 47 | { |
| 93 | assert(device != NULL); | |
| 94 | assert(device->type() == M6509); | |
| 95 | return (m6509_Regs *)downcast<legacy_cpu_device *>(device)->token(); | |
| 48 | program_config.m_addrbus_width = 20; | |
| 49 | program_config.m_logaddr_width = 16; | |
| 50 | program_config.m_page_shift = 13; | |
| 96 | 51 | } |
| 97 | 52 | |
| 98 | /*************************************************************** | |
| 99 | * include the opcode macros, functions and tables | |
| 100 | ***************************************************************/ | |
| 101 | ||
| 102 | #include "t6509.c" | |
| 103 | ||
| 104 | static READ8_HANDLER( m6509_read_00000 ) | |
| 53 | void m6509_device::device_start() | |
| 105 | 54 | { |
| 106 | m6509_Regs *cpustate = get_safe_token(&space.device()); | |
| 55 | if(direct_disabled) | |
| 56 | mintf = new mi_6509_nd(this); | |
| 57 | else | |
| 58 | mintf = new mi_6509_normal(this); | |
| 107 | 59 | |
| 108 | return cpustate->pc_bank.b.h2; | |
| 109 | } | |
| 60 | init(); | |
| 110 | 61 | |
| 111 | static READ8_HANDLER( m6509_read_00001 ) | |
| 112 | { | |
| 113 | m6509_Regs *cpustate = get_safe_token(&space.device()); | |
| 114 | ||
| 115 | return cpustate->ind_bank.b.h2; | |
| 62 | state_add(M6509_BI, "BI", bank_i); | |
| 63 | state_add(M6509_BY, "BY", bank_y); | |
| 116 | 64 | } |
| 117 | 65 | |
| 118 | ||
| 66 | void m6509_device::device_reset() | |
| 119 | 67 | { |
| 120 | m6509_Regs *cpustate = get_safe_token(&space.device()); | |
| 121 | ||
| 122 | cpustate->pc_bank.b.h2=data&0xf; | |
| 123 | cpustate->pc.w.h=cpustate->pc_bank.w.h; | |
| 68 | bank_i = 0x0f; | |
| 69 | bank_y = 0x0f; | |
| 124 | 70 | } |
| 125 | 71 | |
| 126 | st | |
| 72 | offs_t m6509_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) | |
| 127 | 73 | { |
| 128 | m6509_Regs *cpustate = get_safe_token(&space.device()); | |
| 129 | ||
| 130 | cpustate->ind_bank.b.h2=data&0xf; | |
| 74 | return disassemble_generic(buffer, pc, oprom, opram, options, disasm_entries); | |
| 131 | 75 | } |
| 132 | 76 | |
| 133 | static ADDRESS_MAP_START(m6509_mem, AS_PROGRAM, 8, legacy_cpu_device) | |
| 134 | AM_RANGE(0x00000, 0x00000) AM_MIRROR(0xF0000) AM_READWRITE_LEGACY(m6509_read_00000, m6509_write_00000) | |
| 135 | AM_RANGE(0x00001, 0x00001) AM_MIRROR(0xF0000) AM_READWRITE_LEGACY(m6509_read_00001, m6509_write_00001) | |
| 136 | ADDRESS_MAP_END | |
| 137 | 77 | |
| 138 | ||
| 78 | m6509_device::mi_6509_normal::mi_6509_normal(m6509_device *_base) | |
| 139 | 79 | { |
| 140 | m6509_Regs *cpustate = get_safe_token(device); | |
| 141 | const m6502_interface *intf = (const m6502_interface *)device->static_config(); | |
| 142 | ||
| 143 | cpustate->irq_callback = irqcallback; | |
| 144 | cpustate->device = device; | |
| 145 | cpustate->space = &device->space(AS_PROGRAM); | |
| 146 | cpustate->direct = &cpustate->space->direct(); | |
| 147 | ||
| 148 | if ( intf ) | |
| 149 | { | |
| 150 | cpustate->rdmem_id.resolve(intf->read_indexed_func, *device); | |
| 151 | cpustate->wrmem_id.resolve(intf->write_indexed_func, *device); | |
| 152 | } | |
| 153 | else | |
| 154 | { | |
| 155 | devcb_read8 nullrcb = DEVCB_NULL; | |
| 156 | devcb_write8 nullwcb = DEVCB_NULL; | |
| 157 | ||
| 158 | cpustate->rdmem_id.resolve(nullrcb, *device); | |
| 159 | cpustate->wrmem_id.resolve(nullwcb, *device); | |
| 160 | } | |
| 161 | ||
| 162 | device->save_item(NAME(cpustate->pc.w.l)); | |
| 163 | device->save_item(NAME(cpustate->sp.w.l)); | |
| 164 | device->save_item(NAME(cpustate->p)); | |
| 165 | device->save_item(NAME(cpustate->a)); | |
| 166 | device->save_item(NAME(cpustate->x)); | |
| 167 | device->save_item(NAME(cpustate->y)); | |
| 168 | device->save_item(NAME(cpustate->pending_irq)); | |
| 169 | device->save_item(NAME(cpustate->after_cli)); | |
| 170 | device->save_item(NAME(cpustate->nmi_state)); | |
| 171 | device->save_item(NAME(cpustate->irq_state)); | |
| 172 | device->save_item(NAME(cpustate->so_state)); | |
| 80 | base = _base; | |
| 173 | 81 | } |
| 174 | 82 | |
| 175 | ||
| 83 | UINT8 m6509_device::mi_6509_normal::read(UINT16 adr) | |
| 176 | 84 | { |
| 177 | m6509_Regs *cpustate = get_safe_token(device); | |
| 178 | ||
| 179 | cpustate->insn = insn6509; | |
| 180 | ||
| 181 | cpustate->pc_bank.d=cpustate->ind_bank.d=0; | |
| 182 | cpustate->pc_bank.b.h2=cpustate->ind_bank.b.h2=0xf; /* cbm500 needs this */ | |
| 183 | cpustate->pc.w.h=cpustate->pc_bank.w.h; | |
| 184 | /* wipe out the rest of the m6509 structure */ | |
| 185 | /* read the reset vector into PC */ | |
| 186 | PCL = RDMEM(M6509_RST_VEC|PB); | |
| 187 | PCH = RDMEM((M6509_RST_VEC+1)|PB); | |
| 188 | ||
| 189 | cpustate->sp.d = 0x01ff; | |
| 190 | cpustate->p = F_T|F_B|F_I|F_Z|(P&F_D); /* set T, I and Z flags */ | |
| 191 | cpustate->pending_irq = 0; /* nonzero if an IRQ is pending */ | |
| 192 | cpustate->after_cli = 0; /* pending IRQ and last insn cleared I */ | |
| 193 | cpustate->irq_state = 0; | |
| 194 | cpustate->nmi_state = 0; | |
| 85 | UINT8 res = program->read_byte(adr); | |
| 86 | if(adr == 0x0000) | |
| 87 | res = base->bank_i_r(); | |
| 88 | else if(adr == 0x0001) | |
| 89 | res = base->bank_y_r(); | |
| 90 | return res; | |
| 195 | 91 | } |
| 196 | 92 | |
| 197 | ||
| 93 | UINT8 m6509_device::mi_6509_normal::read_direct(UINT16 adr) | |
| 198 | 94 | { |
| 199 | /* nothing to do yet */ | |
| 95 | UINT8 res = direct->read_raw_byte(base->adr_in_bank_i(adr)); | |
| 96 | if(adr == 0x0000) | |
| 97 | res = base->bank_i_r(); | |
| 98 | else if(adr == 0x0001) | |
| 99 | res = base->bank_y_r(); | |
| 100 | return res; | |
| 200 | 101 | } |
| 201 | 102 | |
| 202 | IN | |
| 103 | UINT8 m6509_device::mi_6509_normal::read_decrypted(UINT16 adr) | |
| 203 | 104 | { |
| 204 | ||
| 205 | if( !(P & F_I) ) | |
| 206 | { | |
| 207 | EAD = M6509_IRQ_VEC; | |
| 208 | EAWH = PBWH; | |
| 209 | cpustate->icount -= 2; | |
| 210 | PUSH(PCH); | |
| 211 | PUSH(PCL); | |
| 212 | PUSH(P & ~F_B); | |
| 213 | P |= F_I; /* knock out D and set I flag */ | |
| 214 | PCL = RDMEM(EAD); | |
| 215 | PCH = RDMEM(EAD+1); | |
| 216 | LOG(("M6509 '%s' takes IRQ ($%04x)\n", cpustate->device->tag(), PCD)); | |
| 217 | /* call back the cpuintrf to let it clear the line */ | |
| 218 | if (cpustate->irq_callback) (*cpustate->irq_callback)(cpustate->device, 0); | |
| 219 | } | |
| 220 | cpustate->pending_irq = 0; | |
| 105 | UINT8 res = direct->read_decrypted_byte(base->adr_in_bank_i(adr)); | |
| 106 | if(adr == 0x0000) | |
| 107 | res = base->bank_i_r(); | |
| 108 | else if(adr == 0x0001) | |
| 109 | res = base->bank_y_r(); | |
| 110 | return res; | |
| 221 | 111 | } |
| 222 | 112 | |
| 223 | ||
| 113 | UINT8 m6509_device::mi_6509_normal::read_9(UINT16 adr) | |
| 224 | 114 | { |
| 225 | m6509_Regs *cpustate = get_safe_token(device); | |
| 226 | ||
| 227 | do | |
| 228 | { | |
| 229 | UINT8 op; | |
| 230 | PPC = PCD; | |
| 231 | ||
| 232 | debugger_instruction_hook(device, PCD); | |
| 233 | ||
| 234 | /* if an irq is pending, take it now */ | |
| 235 | if( cpustate->pending_irq ) | |
| 236 | m6509_take_irq(cpustate); | |
| 237 | ||
| 238 | op = RDOP(); | |
| 239 | (*cpustate->insn[op])(cpustate); | |
| 240 | ||
| 241 | /* check if the I flag was just reset (interrupts enabled) */ | |
| 242 | if( cpustate->after_cli ) | |
| 243 | { | |
| 244 | LOG(("M6509 '%s' after_cli was >0", cpustate->device->tag())); | |
| 245 | cpustate->after_cli = 0; | |
| 246 | if (cpustate->irq_state != CLEAR_LINE) | |
| 247 | { | |
| 248 | LOG((": irq line is asserted: set pending IRQ\n")); | |
| 249 | cpustate->pending_irq = 1; | |
| 250 | } | |
| 251 | else | |
| 252 | { | |
| 253 | LOG((": irq line is clear\n")); | |
| 254 | } | |
| 255 | } | |
| 256 | else { | |
| 257 | if ( cpustate->pending_irq == 2 ) { | |
| 258 | if ( cpustate->int_occured - cpustate->icount > 1 ) { | |
| 259 | cpustate->pending_irq = 1; | |
| 260 | } | |
| 261 | } | |
| 262 | if( cpustate->pending_irq == 1 ) | |
| 263 | m6509_take_irq(cpustate); | |
| 264 | if ( cpustate->pending_irq == 2 ) { | |
| 265 | cpustate->pending_irq = 1; | |
| 266 | } | |
| 267 | } | |
| 268 | ||
| 269 | } while (cpustate->icount > 0); | |
| 115 | UINT8 res = program->read_byte(base->adr_in_bank_y(adr)); | |
| 116 | if(adr == 0x0000) | |
| 117 | res = base->bank_i_r(); | |
| 118 | else if(adr == 0x0001) | |
| 119 | res = base->bank_y_r(); | |
| 120 | return res; | |
| 270 | 121 | } |
| 271 | 122 | |
| 272 | ||
| 123 | void m6509_device::mi_6509_normal::write(UINT16 adr, UINT8 val) | |
| 273 | 124 | { |
| 274 | if (irqline == INPUT_LINE_NMI) | |
| 275 | { | |
| 276 | if (cpustate->nmi_state == state) return; | |
| 277 | cpustate->nmi_state = state; | |
| 278 | if( state != CLEAR_LINE ) | |
| 279 | { | |
| 280 | LOG(( "M6509 '%s' set_nmi_line(ASSERT)\n", cpustate->device->tag())); | |
| 281 | EAD = M6509_NMI_VEC; | |
| 282 | EAWH = PBWH; | |
| 283 | cpustate->icount -= 2; | |
| 284 | PUSH(PCH); | |
| 285 | PUSH(PCL); | |
| 286 | PUSH(P & ~F_B); | |
| 287 | P |= F_I; /* knock out D and set I flag */ | |
| 288 | PCL = RDMEM(EAD); | |
| 289 | PCH = RDMEM(EAD+1); | |
| 290 | LOG(("M6509 '%s' takes NMI ($%04x)\n", cpustate->device->tag(), PCD)); | |
| 291 | } | |
| 292 | } | |
| 293 | else | |
| 294 | { | |
| 295 | if( irqline == M6509_SET_OVERFLOW ) | |
| 296 | { | |
| 297 | if( cpustate->so_state && !state ) | |
| 298 | { | |
| 299 | LOG(( "M6509 '%s' set overflow\n", cpustate->device->tag())); | |
| 300 | P|=F_V; | |
| 301 | } | |
| 302 | cpustate->so_state=state; | |
| 303 | return; | |
| 304 | } | |
| 305 | cpustate->irq_state = state; | |
| 306 | if( state != CLEAR_LINE ) | |
| 307 | { | |
| 308 | LOG(( "M6509 '%s' set_irq_line(ASSERT)\n", cpustate->device->tag())); | |
| 309 | cpustate->pending_irq = 1; | |
| 310 | cpustate->int_occured = cpustate->icount; | |
| 311 | } | |
| 312 | } | |
| 125 | program->write_byte(adr, val); | |
| 126 | if(adr == 0x0000) | |
| 127 | base->bank_i_w(val); | |
| 128 | else if(adr == 0x0001) | |
| 129 | base->bank_y_w(val); | |
| 313 | 130 | } |
| 314 | 131 | |
| 315 | /************************************************************************** | |
| 316 | * Generic set_info | |
| 317 | **************************************************************************/ | |
| 318 | ||
| 319 | static CPU_SET_INFO( m6509 ) | |
| 132 | void m6509_device::mi_6509_normal::write_9(UINT16 adr, UINT8 val) | |
| 320 | 133 | { |
| 321 | m6509_Regs *cpustate = get_safe_token(device); | |
| 134 | program->write_byte(base->adr_in_bank_y(adr), val); | |
| 135 | if(adr == 0x0000) | |
| 136 | base->bank_i_w(val); | |
| 137 | else if(adr == 0x0001) | |
| 138 | base->bank_y_w(val); | |
| 139 | } | |
| 322 | 140 | |
| 323 | switch (state) | |
| 324 | { | |
| 325 | /* --- the following bits of info are set as 64-bit signed integers --- */ | |
| 326 | case CPUINFO_INT_INPUT_STATE + M6509_IRQ_LINE: m6509_set_irq_line(cpustate, M6509_IRQ_LINE, info->i); break; | |
| 327 | case CPUINFO_INT_INPUT_STATE + M6509_SET_OVERFLOW:m6509_set_irq_line(cpustate, M6509_SET_OVERFLOW, info->i); break; | |
| 328 | case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI: m6509_set_irq_line(cpustate, INPUT_LINE_NMI, info->i); break; | |
| 329 | ||
| 330 | case CPUINFO_INT_PC: PCW = info->i; break; | |
| 331 | case CPUINFO_INT_REGISTER + M6509_PC: cpustate->pc.w.l = info->i; break; | |
| 332 | case CPUINFO_INT_SP: S = info->i; break; | |
| 333 | case CPUINFO_INT_REGISTER + M6509_S: cpustate->sp.b.l = info->i; break; | |
| 334 | case CPUINFO_INT_REGISTER + M6509_P: cpustate->p = info->i; break; | |
| 335 | case CPUINFO_INT_REGISTER + M6509_A: cpustate->a = info->i; break; | |
| 336 | case CPUINFO_INT_REGISTER + M6509_X: cpustate->x = info->i; break; | |
| 337 | case CPUINFO_INT_REGISTER + M6509_Y: cpustate->y = info->i; break; | |
| 338 | case CPUINFO_INT_REGISTER + M6509_PC_BANK: cpustate->pc_bank.b.h2 = info->i; break; | |
| 339 | case CPUINFO_INT_REGISTER + M6509_IND_BANK: cpustate->ind_bank.b.h2 = info->i; break; | |
| 340 | case CPUINFO_INT_REGISTER + M6509_EA: cpustate->ea.w.l = info->i; break; | |
| 341 | case CPUINFO_INT_REGISTER + M6509_ZP: cpustate->zp.w.l = info->i; break; | |
| 342 | } | |
| 141 | m6509_device::mi_6509_nd::mi_6509_nd(m6509_device *_base) : mi_6509_normal(_base) | |
| 142 | { | |
| 343 | 143 | } |
| 344 | 144 | |
| 345 | ||
| 346 | ||
| 347 | /************************************************************************** | |
| 348 | * Generic get_info | |
| 349 | **************************************************************************/ | |
| 350 | ||
| 351 | CPU_GET_INFO( m6509 ) | |
| 145 | UINT8 m6509_device::mi_6509_nd::read_direct(UINT16 adr) | |
| 352 | 146 | { |
| 353 | m6509_Regs *cpustate = (device != NULL && device->token() != NULL) ? get_safe_token(device) : NULL; | |
| 147 | UINT8 res = program->read_byte(base->adr_in_bank_i(adr)); | |
| 148 | if(adr == 0x0000) | |
| 149 | res = base->bank_i_r(); | |
| 150 | else if(adr == 0x0001) | |
| 151 | res = base->bank_y_r(); | |
| 152 | return res; | |
| 153 | } | |
| 354 | 154 | |
| 355 | switch (state) | |
| 356 | { | |
| 357 | /* --- the following bits of info are returned as 64-bit signed integers --- */ | |
| 358 | case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(m6509_Regs); break; | |
| 359 | case CPUINFO_INT_INPUT_LINES: info->i = 2; break; | |
| 360 | case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0; break; | |
| 361 | case CPUINFO_INT_ENDIANNESS: info->i = ENDIANNESS_LITTLE; break; | |
| 362 | case CPUINFO_INT_CLOCK_MULTIPLIER: info->i = 1; break; | |
| 363 | case CPUINFO_INT_CLOCK_DIVIDER: info->i = 1; break; | |
| 364 | case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 1; break; | |
| 365 | case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 3; break; | |
| 366 | case CPUINFO_INT_MIN_CYCLES: info->i = 1; break; | |
| 367 | case CPUINFO_INT_MAX_CYCLES: info->i = 10; break; | |
| 368 | ||
| 369 | case CPUINFO_INT_DATABUS_WIDTH + AS_PROGRAM: info->i = 8; break; | |
| 370 | case CPUINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 20; break; | |
| 371 | case CPUINFO_INT_ADDRBUS_SHIFT + AS_PROGRAM: info->i = 0; break; | |
| 372 | case CPUINFO_INT_DATABUS_WIDTH + AS_DATA: info->i = 0; break; | |
| 373 | case CPUINFO_INT_ADDRBUS_WIDTH + AS_DATA: info->i = 0; break; | |
| 374 | case CPUINFO_INT_ADDRBUS_SHIFT + AS_DATA: info->i = 0; break; | |
| 375 | case CPUINFO_INT_DATABUS_WIDTH + AS_IO: info->i = 0; break; | |
| 376 | case CPUINFO_INT_ADDRBUS_WIDTH + AS_IO: info->i = 0; break; | |
| 377 | case CPUINFO_INT_ADDRBUS_SHIFT + AS_IO: info->i = 0; break; | |
| 378 | ||
| 379 | case CPUINFO_INT_INPUT_STATE + M6509_IRQ_LINE: info->i = cpustate->irq_state; break; | |
| 380 | case CPUINFO_INT_INPUT_STATE + M6509_SET_OVERFLOW:info->i = cpustate->so_state; break; | |
| 381 | case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI: info->i = cpustate->nmi_state; break; | |
| 382 | ||
| 383 | case CPUINFO_INT_PREVIOUSPC: info->i = cpustate->ppc.w.l; break; | |
| 384 | ||
| 385 | case CPUINFO_INT_PC: info->i = PCD; break; | |
| 386 | case CPUINFO_INT_REGISTER + M6509_PC: info->i = cpustate->pc.w.l; break; | |
| 387 | case CPUINFO_INT_SP: info->i = S; break; | |
| 388 | case CPUINFO_INT_REGISTER + M6509_S: info->i = cpustate->sp.b.l; break; | |
| 389 | case CPUINFO_INT_REGISTER + M6509_P: info->i = cpustate->p; break; | |
| 390 | case CPUINFO_INT_REGISTER + M6509_A: info->i = cpustate->a; break; | |
| 391 | case CPUINFO_INT_REGISTER + M6509_X: info->i = cpustate->x; break; | |
| 392 | case CPUINFO_INT_REGISTER + M6509_Y: info->i = cpustate->y; break; | |
| 393 | case CPUINFO_INT_REGISTER + M6509_PC_BANK: info->i = cpustate->pc_bank.b.h2; break; | |
| 394 | case CPUINFO_INT_REGISTER + M6509_IND_BANK: info->i = cpustate->ind_bank.b.h2; break; | |
| 395 | case CPUINFO_INT_REGISTER + M6509_EA: info->i = cpustate->ea.w.l; break; | |
| 396 | case CPUINFO_INT_REGISTER + M6509_ZP: info->i = cpustate->zp.w.l; break; | |
| 397 | ||
| 398 | /* --- the following bits of info are returned as pointers to data or functions --- */ | |
| 399 | case CPUINFO_FCT_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(m6509); break; | |
| 400 | case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(m6509); break; | |
| 401 | case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(m6509); break; | |
| 402 | case CPUINFO_FCT_EXIT: info->exit = CPU_EXIT_NAME(m6509); break; | |
| 403 | case CPUINFO_FCT_EXECUTE: info->execute = CPU_EXECUTE_NAME(m6509); break; | |
| 404 | case CPUINFO_FCT_BURN: info->burn = NULL; break; | |
| 405 | case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(m6502); break; | |
| 406 | case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &cpustate->icount; break; | |
| 407 | case CPUINFO_PTR_INTERNAL_MEMORY_MAP + AS_PROGRAM: info->internal_map8 = ADDRESS_MAP_NAME(m6509_mem); break; | |
| 408 | ||
| 409 | /* --- the following bits of info are returned as NULL-terminated strings --- */ | |
| 410 | case CPUINFO_STR_NAME: strcpy(info->s, "M6509"); break; | |
| 411 | case CPUINFO_STR_FAMILY: strcpy(info->s, "MOS Technology 6509"); break; | |
| 412 | case CPUINFO_STR_VERSION: strcpy(info->s, "1.0beta"); break; | |
| 413 | case CPUINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break; | |
| 414 | case CPUINFO_STR_CREDITS: strcpy(info->s, "Copyright Juergen Buchmueller\nCopyright Peter Trauner\nall rights reserved."); break; | |
| 415 | ||
| 416 | case CPUINFO_STR_FLAGS: | |
| 417 | sprintf(info->s, "%c%c%c%c%c%c%c%c", | |
| 418 | cpustate->p & 0x80 ? 'N':'.', | |
| 419 | cpustate->p & 0x40 ? 'V':'.', | |
| 420 | cpustate->p & 0x20 ? 'R':'.', | |
| 421 | cpustate->p & 0x10 ? 'B':'.', | |
| 422 | cpustate->p & 0x08 ? 'D':'.', | |
| 423 | cpustate->p & 0x04 ? 'I':'.', | |
| 424 | cpustate->p & 0x02 ? 'Z':'.', | |
| 425 | cpustate->p & 0x01 ? 'C':'.'); | |
| 426 | break; | |
| 427 | ||
| 428 | case CPUINFO_STR_REGISTER + M6509_PC: sprintf(info->s, "PC:%05X", cpustate->pc.d); break; | |
| 429 | case CPUINFO_STR_REGISTER + M6509_S: sprintf(info->s, "S:%02X", cpustate->sp.b.l); break; | |
| 430 | case CPUINFO_STR_REGISTER + M6509_P: sprintf(info->s, "P:%02X", cpustate->p); break; | |
| 431 | case CPUINFO_STR_REGISTER + M6509_A: sprintf(info->s, "A:%02X", cpustate->a); break; | |
| 432 | case CPUINFO_STR_REGISTER + M6509_X: sprintf(info->s, "X:%02X", cpustate->x); break; | |
| 433 | case CPUINFO_STR_REGISTER + M6509_Y: sprintf(info->s, "Y:%02X", cpustate->y); break; | |
| 434 | case CPUINFO_STR_REGISTER + M6509_PC_BANK: sprintf(info->s, "M0:%01X", cpustate->pc_bank.b.h2); break; | |
| 435 | case CPUINFO_STR_REGISTER + M6509_IND_BANK: sprintf(info->s, "M1:%01X", cpustate->ind_bank.b.h2); break; | |
| 436 | case CPUINFO_STR_REGISTER + M6509_EA: sprintf(info->s, "EA:%05X", cpustate->ea.d); break; | |
| 437 | case CPUINFO_STR_REGISTER + M6509_ZP: sprintf(info->s, "ZP:%03X", cpustate->zp.w.l); break; | |
| 438 | } | |
| 155 | UINT8 m6509_device::mi_6509_nd::read_decrypted(UINT16 adr) | |
| 156 | { | |
| 157 | UINT8 res = program->read_byte(base->adr_in_bank_i(adr)); | |
| 158 | if(adr == 0x0000) | |
| 159 | res = base->bank_i_r(); | |
| 160 | else if(adr == 0x0001) | |
| 161 | res = base->bank_y_r(); | |
| 162 | return res; | |
| 439 | 163 | } |
| 440 | 164 | |
| 441 | ||
| 165 | #include "cpu/m6502/m6509.inc" |
| r18874 | r18875 | |
|---|---|---|
| 1 | # deco 16 opcodes | |
| 2 | ill_non | |
| 3 | logerror("%s: Unimplemented instruction %02x\n", tag(), inst_state); | |
| 4 | prefetch(); | |
| 5 | ||
| 6 | u0B_zpg | |
| 7 | TMP2 = read_pc(); | |
| 8 | if(DECO16_VERBOSE) | |
| 9 | logerror("%s: OP0B %02x (%04x)\n", tag(), NPC, TMP2); | |
| 10 | prefetch(); | |
| 11 | ||
| 12 | u13_zpg | |
| 13 | TMP2 = read_pc(); | |
| 14 | if(DECO16_VERBOSE) | |
| 15 | logerror("%s: OP13 %02x (%04x)\n", tag(), NPC, TMP2); | |
| 16 | prefetch(); | |
| 17 | ||
| 18 | u23_zpg | |
| 19 | TMP2 = read_pc(); | |
| 20 | if(DECO16_VERBOSE) | |
| 21 | logerror("%s: OP23 %02x (%04x)\n", tag(), NPC, TMP2); | |
| 22 | prefetch(); | |
| 23 | ||
| 24 | u3F_zpg | |
| 25 | TMP2 = read_pc(); | |
| 26 | if(DECO16_VERBOSE) | |
| 27 | logerror("%s: OPBB %02x (%04x)\n", tag(), NPC, TMP2); | |
| 28 | prefetch(); | |
| 29 | ||
| 30 | u4B_zpg | |
| 31 | TMP2 = read_pc(); | |
| 32 | A = io->read_byte(1); | |
| 33 | prefetch(); | |
| 34 | ||
| 35 | u87_zpg | |
| 36 | TMP2 = read_pc(); | |
| 37 | if(DECO16_VERBOSE) | |
| 38 | logerror("%s: OP87 %02x (%04x)\n", tag(), NPC, TMP2); | |
| 39 | prefetch(); | |
| 40 | ||
| 41 | u8F_zpg | |
| 42 | TMP2 = read_pc(); | |
| 43 | if(DECO16_VERBOSE) | |
| 44 | logerror("%s: OP8F (BANK) %02x (%04x)\n", tag(), NPC, TMP2); | |
| 45 | io->write_byte(0, TMP2); | |
| 46 | prefetch(); | |
| 47 | ||
| 48 | uA3_zpg | |
| 49 | TMP2 = read_pc(); | |
| 50 | if(DECO16_VERBOSE) | |
| 51 | logerror("%s: OPA3 %02x (%04x)\n", tag(), NPC, TMP2); | |
| 52 | prefetch(); | |
| 53 | ||
| 54 | uBB_zpg | |
| 55 | TMP2 = read_pc(); | |
| 56 | if(DECO16_VERBOSE) | |
| 57 | logerror("%s: OPBB %02x (%04x)\n", tag(), NPC, TMP2); | |
| 58 | prefetch(); | |
| 59 | ||
| 60 | vbl_zpg | |
| 61 | TMP2 = read_pc(); | |
| 62 | A = io->read_byte(0); | |
| 63 | if(DECO16_VERBOSE) | |
| 64 | logerror("%s: VBL %02x (%04x)\n", tag(), NPC, TMP2); | |
| 65 | prefetch(); |
| r18874 | r18875 | |
|---|---|---|
| 1 | /*************************************************************************** | |
| 2 | ||
| 3 | m8502.h | |
| 4 | ||
| 5 | 6510 derivative, capable of running at 2MHz. | |
| 6 | ||
| 7 | **************************************************************************** | |
| 8 | ||
| 9 | Copyright Olivier Galibert | |
| 10 | All rights reserved. | |
| 11 | ||
| 12 | Redistribution and use in source and binary forms, with or without | |
| 13 | modification, are permitted provided that the following conditions are | |
| 14 | met: | |
| 15 | ||
| 16 | * Redistributions of source code must retain the above copyright | |
| 17 | notice, this list of conditions and the following disclaimer. | |
| 18 | * Redistributions in binary form must reproduce the above copyright | |
| 19 | notice, this list of conditions and the following disclaimer in | |
| 20 | the documentation and/or other materials provided with the | |
| 21 | distribution. | |
| 22 | * Neither the name 'MAME' nor the names of its contributors may be | |
| 23 | used to endorse or promote products derived from this software | |
| 24 | without specific prior written permission. | |
| 25 | ||
| 26 | THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR | |
| 27 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 28 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 29 | DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, | |
| 30 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 31 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
| 32 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 33 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
| 34 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
| 35 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| 36 | POSSIBILITY OF SUCH DAMAGE. | |
| 37 | ||
| 38 | ***************************************************************************/ | |
| 39 | ||
| 40 | #ifndef __M8502_H__ | |
| 41 | #define __M8502_H__ | |
| 42 | ||
| 43 | #include "m6510.h" | |
| 44 | ||
| 45 | #define MCFG_M8502_PORT_CALLBACKS(_read, _write) \ | |
| 46 | downcast<m8502_device *>(device)->set_callbacks(DEVCB2_##_read, DEVCB2_##_write); | |
| 47 | ||
| 48 | #define MCFG_M8502_PORT_PULLS(_up, _down) \ | |
| 49 | downcast<m8502_device *>(device)->set_pulls(_up, _down); | |
| 50 | ||
| 51 | class m8502_device : public m6510_device { | |
| 52 | public: | |
| 53 | m8502_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 54 | }; | |
| 55 | ||
| 56 | enum { | |
| 57 | M8502_IRQ_LINE = m6502_device::IRQ_LINE, | |
| 58 | M8502_NMI_LINE = m6502_device::NMI_LINE, | |
| 59 | }; | |
| 60 | ||
| 61 | extern const device_type M8502; | |
| 62 | ||
| 63 | #endif |
| r18874 | r18875 | |
|---|---|---|
| 1 | /*************************************************************************** | |
| 2 | ||
| 3 | r65c02.c | |
| 4 | ||
| 5 | Rockwell 65c02, CMOS variant with bitwise instructions | |
| 6 | ||
| 7 | **************************************************************************** | |
| 8 | ||
| 9 | Copyright Olivier Galibert | |
| 10 | All rights reserved. | |
| 11 | ||
| 12 | Redistribution and use in source and binary forms, with or without | |
| 13 | modification, are permitted provided that the following conditions are | |
| 14 | met: | |
| 15 | ||
| 16 | * Redistributions of source code must retain the above copyright | |
| 17 | notice, this list of conditions and the following disclaimer. | |
| 18 | * Redistributions in binary form must reproduce the above copyright | |
| 19 | notice, this list of conditions and the following disclaimer in | |
| 20 | the documentation and/or other materials provided with the | |
| 21 | distribution. | |
| 22 | * Neither the name 'MAME' nor the names of its contributors may be | |
| 23 | used to endorse or promote products derived from this software | |
| 24 | without specific prior written permission. | |
| 25 | ||
| 26 | THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR | |
| 27 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 28 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 29 | DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, | |
| 30 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 31 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
| 32 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 33 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
| 34 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
| 35 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| 36 | POSSIBILITY OF SUCH DAMAGE. | |
| 37 | ||
| 38 | ***************************************************************************/ | |
| 39 | ||
| 40 | #include "emu.h" | |
| 41 | #include "r65c02.h" | |
| 42 | ||
| 43 | const device_type R65C02 = &device_creator<r65c02_device>; | |
| 44 | ||
| 45 | r65c02_device::r65c02_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : | |
| 46 | m65c02_device(mconfig, R65C02, "R65C02", tag, owner, clock) | |
| 47 | { | |
| 48 | } | |
| 49 | ||
| 50 | r65c02_device::r65c02_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) : | |
| 51 | m65c02_device(mconfig, type, name, tag, owner, clock) | |
| 52 | { | |
| 53 | } | |
| 54 | ||
| 55 | offs_t r65c02_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) | |
| 56 | { | |
| 57 | return disassemble_generic(buffer, pc, oprom, opram, options, disasm_entries); | |
| 58 | } | |
| 59 | ||
| 60 | #include "cpu/m6502/r65c02.inc" |
| r18874 | r18875 | |
|---|---|---|
| 1 | /*************************************************************************** | |
| 2 | ||
| 3 | deco16.c | |
| 4 | ||
| 5 | 6502, reverse-engineered DECO variant | |
| 6 | ||
| 7 | **************************************************************************** | |
| 8 | ||
| 9 | Copyright Olivier Galibert | |
| 10 | All rights reserved. | |
| 11 | ||
| 12 | Redistribution and use in source and binary forms, with or without | |
| 13 | modification, are permitted provided that the following conditions are | |
| 14 | met: | |
| 15 | ||
| 16 | * Redistributions of source code must retain the above copyright | |
| 17 | notice, this list of conditions and the following disclaimer. | |
| 18 | * Redistributions in binary form must reproduce the above copyright | |
| 19 | notice, this list of conditions and the following disclaimer in | |
| 20 | the documentation and/or other materials provided with the | |
| 21 | distribution. | |
| 22 | * Neither the name 'MAME' nor the names of its contributors may be | |
| 23 | used to endorse or promote products derived from this software | |
| 24 | without specific prior written permission. | |
| 25 | ||
| 26 | THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR | |
| 27 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 28 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 29 | DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, | |
| 30 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 31 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
| 32 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 33 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
| 34 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
| 35 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| 36 | POSSIBILITY OF SUCH DAMAGE. | |
| 37 | ||
| 38 | ***************************************************************************/ | |
| 39 | ||
| 40 | #include "emu.h" | |
| 41 | #include "deco16.h" | |
| 42 | ||
| 43 | #define DECO16_VERBOSE 1 | |
| 44 | ||
| 45 | const device_type DECO16 = &device_creator<deco16_device>; | |
| 46 | ||
| 47 | deco16_device::deco16_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : | |
| 48 | m6502_device(mconfig, DECO16, "DECO16", tag, owner, clock), | |
| 49 | io_config("io", ENDIANNESS_LITTLE, 8, 16) | |
| 50 | { | |
| 51 | } | |
| 52 | ||
| 53 | offs_t deco16_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) | |
| 54 | { | |
| 55 | return disassemble_generic(buffer, pc, oprom, opram, options, disasm_entries); | |
| 56 | } | |
| 57 | ||
| 58 | ||
| 59 | void deco16_device::device_start() | |
| 60 | { | |
| 61 | if(direct_disabled) | |
| 62 | mintf = new mi_default_nd; | |
| 63 | else | |
| 64 | mintf = new mi_default_normal; | |
| 65 | ||
| 66 | init(); | |
| 67 | ||
| 68 | io = &space(AS_IO); | |
| 69 | } | |
| 70 | ||
| 71 | const address_space_config *deco16_device::memory_space_config(address_spacenum spacenum) const | |
| 72 | { | |
| 73 | return spacenum == AS_PROGRAM ? &program_config : spacenum == AS_IO ? &io_config : NULL; | |
| 74 | } | |
| 75 | ||
| 76 | #include "cpu/m6502/deco16.inc" |
| r18874 | r18875 | |
|---|---|---|
| 1 | # n2a03 opcodes - same as 6502 but with d disabled | |
| 2 | adc_nd_aba | |
| 3 | TMP = read_pc(); | |
| 4 | TMP = set_h(TMP, read_pc()); | |
| 5 | TMP = read(TMP); | |
| 6 | do_adc_nd(TMP); | |
| 7 | prefetch(); | |
| 8 | ||
| 9 | adc_nd_abx | |
| 10 | TMP = read_pc(); | |
| 11 | TMP = set_h(TMP, read_pc()); | |
| 12 | if(page_changing(TMP, X)) { | |
| 13 | read(set_l(TMP, TMP+X)); | |
| 14 | } | |
| 15 | TMP += X; | |
| 16 | TMP = read(TMP); | |
| 17 | do_adc_nd(TMP); | |
| 18 | prefetch(); | |
| 19 | ||
| 20 | adc_nd_aby | |
| 21 | TMP = read_pc(); | |
| 22 | TMP = set_h(TMP, read_pc()); | |
| 23 | if(page_changing(TMP, Y)) { | |
| 24 | read(set_l(TMP, TMP+Y)); | |
| 25 | } | |
| 26 | TMP += Y; | |
| 27 | TMP = read(TMP); | |
| 28 | do_adc_nd(TMP); | |
| 29 | prefetch(); | |
| 30 | ||
| 31 | adc_nd_idx | |
| 32 | TMP2 = read_pc(); | |
| 33 | read(TMP2); | |
| 34 | TMP2 += X; | |
| 35 | TMP = read(TMP2 & 0xff); | |
| 36 | TMP = set_h(TMP, read((TMP2+1) & 0xff)); | |
| 37 | do_adc_nd(read(TMP)); | |
| 38 | prefetch(); | |
| 39 | ||
| 40 | adc_nd_idy | |
| 41 | TMP2 = read_pc(); | |
| 42 | TMP = read(TMP2); | |
| 43 | TMP = set_h(TMP, read(TMP2+1)); | |
| 44 | if(page_changing(TMP, Y)) { | |
| 45 | read(set_l(TMP, TMP+Y)); | |
| 46 | } | |
| 47 | do_adc_nd(read(TMP+Y)); | |
| 48 | prefetch(); | |
| 49 | ||
| 50 | adc_nd_imm | |
| 51 | TMP = read_pc(); | |
| 52 | do_adc_nd(TMP); | |
| 53 | prefetch(); | |
| 54 | ||
| 55 | adc_nd_zpg | |
| 56 | TMP = read_pc(); | |
| 57 | TMP = read(TMP); | |
| 58 | do_adc_nd(TMP); | |
| 59 | prefetch(); | |
| 60 | ||
| 61 | adc_nd_zpx | |
| 62 | TMP = read_pc(); | |
| 63 | read(TMP); | |
| 64 | TMP = read(UINT8(TMP+X)); | |
| 65 | do_adc_nd(TMP); | |
| 66 | prefetch(); | |
| 67 | ||
| 68 | arr_nd_imm | |
| 69 | read_pc(); | |
| 70 | do_arr_nd(); | |
| 71 | prefetch(); | |
| 72 | ||
| 73 | rra_nd_aba | |
| 74 | TMP = read_pc(); | |
| 75 | TMP = set_h(TMP, read_pc()); | |
| 76 | TMP2 = read(TMP); | |
| 77 | write(TMP, TMP2); | |
| 78 | TMP2 = do_ror(TMP2); | |
| 79 | write(TMP, TMP2); | |
| 80 | do_adc_nd(TMP2); | |
| 81 | prefetch(); | |
| 82 | ||
| 83 | rra_nd_abx | |
| 84 | TMP = read_pc(); | |
| 85 | TMP = set_h(TMP, read_pc()); | |
| 86 | read(set_l(TMP, TMP+X)); | |
| 87 | TMP += X; | |
| 88 | TMP2 = read(TMP); | |
| 89 | write(TMP, TMP2); | |
| 90 | TMP2 = do_ror(TMP2); | |
| 91 | write(TMP, TMP2); | |
| 92 | do_adc_nd(TMP2); | |
| 93 | prefetch(); | |
| 94 | ||
| 95 | rra_nd_aby | |
| 96 | TMP = read_pc(); | |
| 97 | TMP = set_h(TMP, read_pc()); | |
| 98 | read(set_l(TMP, TMP+Y)); | |
| 99 | TMP += Y; | |
| 100 | TMP2 = read(TMP); | |
| 101 | write(TMP, TMP2); | |
| 102 | TMP2 = do_ror(TMP2); | |
| 103 | write(TMP, TMP2); | |
| 104 | do_adc_nd(TMP2); | |
| 105 | prefetch(); | |
| 106 | ||
| 107 | rra_nd_idx | |
| 108 | TMP2 = read_pc(); | |
| 109 | read(TMP2); | |
| 110 | TMP2 += X; | |
| 111 | TMP = read(TMP2 & 0xff); | |
| 112 | TMP = set_h(TMP, read((TMP2+1) & 0xff)); | |
| 113 | TMP2 = read(TMP); | |
| 114 | write(TMP, TMP2); | |
| 115 | TMP2 = do_ror(TMP2); | |
| 116 | write(TMP, TMP2); | |
| 117 | do_adc_nd(TMP2); | |
| 118 | prefetch(); | |
| 119 | ||
| 120 | rra_nd_idy | |
| 121 | TMP2 = read_pc(); | |
| 122 | TMP = read(TMP2); | |
| 123 | TMP = set_h(TMP, read(TMP2+1)); | |
| 124 | read(set_l(TMP, TMP+Y)); | |
| 125 | TMP += Y; | |
| 126 | TMP2 = read(TMP); | |
| 127 | write(TMP, TMP2); | |
| 128 | TMP2 = do_ror(TMP2); | |
| 129 | write(TMP, TMP2); | |
| 130 | do_adc_nd(TMP2); | |
| 131 | prefetch(); | |
| 132 | ||
| 133 | rra_nd_zpg | |
| 134 | TMP = read_pc(); | |
| 135 | TMP2 = read(TMP); | |
| 136 | write(TMP, TMP2); | |
| 137 | TMP2 = do_ror(TMP2); | |
| 138 | write(TMP, TMP2); | |
| 139 | do_adc_nd(TMP2); | |
| 140 | prefetch(); | |
| 141 | ||
| 142 | rra_nd_zpx | |
| 143 | TMP = read_pc(); | |
| 144 | read(TMP); | |
| 145 | TMP = UINT8(TMP+X); | |
| 146 | TMP2 = read(TMP); | |
| 147 | write(TMP, TMP2); | |
| 148 | TMP2 = do_ror(TMP2); | |
| 149 | write(TMP, TMP2); | |
| 150 | do_adc_nd(TMP2); | |
| 151 | prefetch(); | |
| 152 | ||
| 153 | sbc_nd_aba | |
| 154 | TMP = read_pc(); | |
| 155 | TMP = set_h(TMP, read_pc()); | |
| 156 | TMP = read(TMP); | |
| 157 | do_sbc_nd(TMP); | |
| 158 | prefetch(); | |
| 159 | ||
| 160 | sbc_nd_abx | |
| 161 | TMP = read_pc(); | |
| 162 | TMP = set_h(TMP, read_pc()); | |
| 163 | if(page_changing(TMP, X)) { | |
| 164 | read(set_l(TMP, TMP+X)); | |
| 165 | } | |
| 166 | TMP += X; | |
| 167 | TMP = read(TMP); | |
| 168 | do_sbc_nd(TMP); | |
| 169 | prefetch(); | |
| 170 | ||
| 171 | sbc_nd_aby | |
| 172 | TMP = read_pc(); | |
| 173 | TMP = set_h(TMP, read_pc()); | |
| 174 | if(page_changing(TMP, Y)) { | |
| 175 | read(set_l(TMP, TMP+Y)); | |
| 176 | } | |
| 177 | TMP += Y; | |
| 178 | TMP = read(TMP); | |
| 179 | do_sbc_nd(TMP); | |
| 180 | prefetch(); | |
| 181 | ||
| 182 | sbc_nd_idx | |
| 183 | TMP2 = read_pc(); | |
| 184 | read(TMP2); | |
| 185 | TMP2 += X; | |
| 186 | TMP = read(TMP2 & 0xff); | |
| 187 | TMP = set_h(TMP, read((TMP2+1) & 0xff)); | |
| 188 | do_sbc_nd(read(TMP)); | |
| 189 | prefetch(); | |
| 190 | ||
| 191 | sbc_nd_idy | |
| 192 | TMP2 = read_pc(); | |
| 193 | TMP = read(TMP2); | |
| 194 | TMP = set_h(TMP, read(TMP2+1)); | |
| 195 | if(page_changing(TMP, Y)) { | |
| 196 | read(set_l(TMP, TMP+Y)); | |
| 197 | } | |
| 198 | do_sbc_nd(read(TMP+Y)); | |
| 199 | prefetch(); | |
| 200 | ||
| 201 | sbc_nd_imm | |
| 202 | TMP = read_pc(); | |
| 203 | do_sbc_nd(TMP); | |
| 204 | prefetch(); | |
| 205 | ||
| 206 | sbc_nd_zpg | |
| 207 | TMP = read_pc(); | |
| 208 | TMP = read(TMP); | |
| 209 | do_sbc_nd(TMP); | |
| 210 | prefetch(); | |
| 211 | ||
| 212 | sbc_nd_zpx | |
| 213 | TMP = read_pc(); | |
| 214 | read(TMP); | |
| 215 | TMP = read(UINT8(TMP+X)); | |
| 216 | do_sbc_nd(TMP); | |
| 217 | prefetch(); | |
| 218 | ||
| 219 | isb_nd_aba | |
| 220 | TMP = read_pc(); | |
| 221 | TMP = set_h(TMP, read_pc()); | |
| 222 | TMP2 = read(TMP); | |
| 223 | write(TMP, TMP2); | |
| 224 | TMP2++; | |
| 225 | write(TMP, TMP2); | |
| 226 | do_sbc_nd(TMP2); | |
| 227 | prefetch(); | |
| 228 | ||
| 229 | isb_nd_abx | |
| 230 | TMP = read_pc(); | |
| 231 | TMP = set_h(TMP, read_pc()); | |
| 232 | read(set_l(TMP, TMP+X)); | |
| 233 | TMP += X; | |
| 234 | TMP2 = read(TMP); | |
| 235 | write(TMP, TMP2); | |
| 236 | TMP2++; | |
| 237 | write(TMP, TMP2); | |
| 238 | do_sbc_nd(TMP2); | |
| 239 | prefetch(); | |
| 240 | ||
| 241 | isb_nd_aby | |
| 242 | TMP = read_pc(); | |
| 243 | TMP = set_h(TMP, read_pc()); | |
| 244 | read(set_l(TMP, TMP+Y)); | |
| 245 | TMP += Y; | |
| 246 | TMP2 = read(TMP); | |
| 247 | write(TMP, TMP2); | |
| 248 | TMP2++; | |
| 249 | write(TMP, TMP2); | |
| 250 | do_sbc_nd(TMP2); | |
| 251 | prefetch(); | |
| 252 | ||
| 253 | isb_nd_idx | |
| 254 | TMP2 = read_pc(); | |
| 255 | read(TMP2); | |
| 256 | TMP2 += X; | |
| 257 | TMP = read(TMP2 & 0xff); | |
| 258 | TMP = set_h(TMP, read((TMP2+1) & 0xff)); | |
| 259 | TMP2 = read(TMP); | |
| 260 | write(TMP, TMP2); | |
| 261 | TMP2++; | |
| 262 | write(TMP, TMP2); | |
| 263 | do_sbc_nd(TMP2); | |
| 264 | prefetch(); | |
| 265 | ||
| 266 | isb_nd_idy | |
| 267 | TMP2 = read_pc(); | |
| 268 | TMP = read(TMP2); | |
| 269 | TMP = set_h(TMP, read(TMP2+1)); | |
| 270 | read(set_l(TMP, TMP+Y)); | |
| 271 | TMP += Y; | |
| 272 | TMP2 = read(TMP); | |
| 273 | write(TMP, TMP2); | |
| 274 | TMP2++; | |
| 275 | write(TMP, TMP2); | |
| 276 | do_sbc_nd(TMP2); | |
| 277 | prefetch(); | |
| 278 | ||
| 279 | isb_nd_zpg | |
| 280 | TMP = read_pc(); | |
| 281 | TMP2 = read(TMP); | |
| 282 | write(TMP, TMP2); | |
| 283 | TMP2++; | |
| 284 | write(TMP, TMP2); | |
| 285 | do_sbc_nd(TMP2); | |
| 286 | prefetch(); | |
| 287 | ||
| 288 | isb_nd_zpx | |
| 289 | TMP = read_pc(); | |
| 290 | read(TMP); | |
| 291 | TMP = UINT8(TMP+X); | |
| 292 | TMP2 = read(TMP); | |
| 293 | write(TMP, TMP2); | |
| 294 | TMP2++; | |
| 295 | write(TMP, TMP2); | |
| 296 | do_sbc_nd(TMP2); | |
| 297 | prefetch(); |
| r18874 | r18875 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * m6509.h | |
| 4 | * Portable 6509 emulator V1.0beta | |
| 5 | * | |
| 6 | * Copyright Peter Trauner, all rights reserved. | |
| 7 | * | |
| 8 | * - This source code is released as freeware for non-commercial purposes. | |
| 9 | * - You are free to use and redistribute this code in modified or | |
| 10 | * unmodified form, provided you list me in the credits. | |
| 11 | * - If you modify this source code, you must add a notice to each modified | |
| 12 | * source file that it has been changed. If you're a nice person, you | |
| 13 | * will clearly mark each change too. :) | |
| 14 | * - If you wish to use this for commercial purposes, please contact me at | |
| 15 | * pullmoll@t-online.de | |
| 16 | * - The author of this copywritten work reserves the right to change the | |
| 17 | * terms of its usage and license at any time, including retroactively | |
| 18 | * - This entire notice must remain in the source code. | |
| 19 | * | |
| 20 | *****************************************************************************/ | |
| 1 | /*************************************************************************** | |
| 21 | 2 | |
| 22 | ||
| 3 | m6509.h | |
| 23 | 4 | |
| 5 | 6502 with banking and extended address bus | |
| 6 | ||
| 7 | **************************************************************************** | |
| 8 | ||
| 9 | Copyright Olivier Galibert | |
| 10 | All rights reserved. | |
| 11 | ||
| 12 | Redistribution and use in source and binary forms, with or without | |
| 13 | modification, are permitted provided that the following conditions are | |
| 14 | met: | |
| 15 | ||
| 16 | * Redistributions of source code must retain the above copyright | |
| 17 | notice, this list of conditions and the following disclaimer. | |
| 18 | * Redistributions in binary form must reproduce the above copyright | |
| 19 | notice, this list of conditions and the following disclaimer in | |
| 20 | the documentation and/or other materials provided with the | |
| 21 | distribution. | |
| 22 | * Neither the name 'MAME' nor the names of its contributors may be | |
| 23 | used to endorse or promote products derived from this software | |
| 24 | without specific prior written permission. | |
| 25 | ||
| 26 | THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR | |
| 27 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 28 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 29 | DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, | |
| 30 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 31 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
| 32 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 33 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
| 34 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
| 35 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| 36 | POSSIBILITY OF SUCH DAMAGE. | |
| 37 | ||
| 38 | ***************************************************************************/ | |
| 39 | ||
| 24 | 40 | #ifndef __M6509_H__ |
| 25 | #define _M6509_H | |
| 41 | #define __M6509_H__ | |
| 26 | 42 | |
| 27 | 43 | #include "m6502.h" |
| 28 | 44 | |
| 29 | enum | |
| 30 | { | |
| 31 | M6509_PC=1, M6509_S, M6509_P, M6509_A, M6509_X, M6509_Y, | |
| 32 | M6509_EA, M6509_ZP, M6509_NMI_STATE, M6509_IRQ_STATE, M6509_SO_STATE, | |
| 33 | M6509_PC_BANK, M6509_IND_BANK | |
| 45 | class m6509_device : public m6502_device { | |
| 46 | public: | |
| 47 | m6509_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 48 | ||
| 49 | static const disasm_entry disasm_entries[0x100]; | |
| 50 | ||
| 51 | virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options); | |
| 52 | virtual void do_exec_full(); | |
| 53 | virtual void do_exec_partial(); | |
| 54 | ||
| 55 | protected: | |
| 56 | class mi_6509_normal : public memory_interface { | |
| 57 | public: | |
| 58 | m6509_device *base; | |
| 59 | ||
| 60 | mi_6509_normal(m6509_device *base); | |
| 61 | virtual UINT8 read(UINT16 adr); | |
| 62 | virtual UINT8 read_9(UINT16 adr); | |
| 63 | virtual UINT8 read_direct(UINT16 adr); | |
| 64 | virtual UINT8 read_decrypted(UINT16 adr); | |
| 65 | virtual void write(UINT16 adr, UINT8 val); | |
| 66 | virtual void write_9(UINT16 adr, UINT8 val); | |
| 67 | }; | |
| 68 | ||
| 69 | class mi_6509_nd : public mi_6509_normal { | |
| 70 | public: | |
| 71 | mi_6509_nd(m6509_device *base); | |
| 72 | virtual UINT8 read_direct(UINT16 adr); | |
| 73 | virtual UINT8 read_decrypted(UINT16 adr); | |
| 74 | }; | |
| 75 | ||
| 76 | virtual void device_start(); | |
| 77 | virtual void device_reset(); | |
| 78 | ||
| 79 | UINT8 bank_i, bank_y; | |
| 80 | ||
| 81 | UINT8 bank_i_r() { return bank_i; } | |
| 82 | UINT8 bank_y_r() { return bank_y; } | |
| 83 | void bank_i_w(UINT8 data) { bank_i = data; } | |
| 84 | void bank_y_w(UINT8 data) { bank_y = data; } | |
| 85 | ||
| 86 | UINT32 adr_in_bank_i(UINT16 adr) { return adr | ((bank_i & 0xf) << 16); } | |
| 87 | UINT32 adr_in_bank_y(UINT16 adr) { return adr | ((bank_y & 0xf) << 16); } | |
| 88 | ||
| 89 | #define O(o) void o ## _full(); void o ## _partial() | |
| 90 | ||
| 91 | // 6509 opcodes | |
| 92 | O(lda_9_idy); | |
| 93 | O(sta_9_idy); | |
| 94 | ||
| 95 | #undef O | |
| 34 | 96 | }; |
| 35 | 97 | |
| 36 | #define M6509_IRQ_LINE M6502_IRQ_LINE | |
| 37 | /* use cpudevice->execute().set_input_line(M6509_SET_OVERFLOW, level) | |
| 38 | to change level of the so input line | |
| 39 | positiv edge sets overflow flag */ | |
| 40 | #define M6509_SET_OVERFLOW 3 | |
| 98 | enum { | |
| 99 | M6509_IRQ_LINE = m6502_device::IRQ_LINE, | |
| 100 | M6509_NMI_LINE = m6502_device::NMI_LINE, | |
| 101 | M6509_SET_OVERFLOW = m6502_device::V_LINE, | |
| 102 | }; | |
| 41 | 103 | |
| 42 | DECLARE_LEGACY_CPU_DEVICE(M6509, m6509); | |
| 104 | enum { | |
| 105 | M6509_BI = M6502_IR+1, | |
| 106 | M6509_BY | |
| 107 | }; | |
| 43 | 108 | |
| 44 | #endif /* __M6509_H__ */ | |
| 109 | extern const device_type M6509; | |
| 110 | ||
| 111 | #endif |
| r18874 | r18875 | |
|---|---|---|
| 1 | /*************************************************************************** | |
| 2 | ||
| 3 | deco16.h | |
| 4 | ||
| 5 | 6502, reverse-engineered DECO variant | |
| 6 | ||
| 7 | **************************************************************************** | |
| 8 | ||
| 9 | Copyright Olivier Galibert | |
| 10 | All rights reserved. | |
| 11 | ||
| 12 | Redistribution and use in source and binary forms, with or without | |
| 13 | modification, are permitted provided that the following conditions are | |
| 14 | met: | |
| 15 | ||
| 16 | * Redistributions of source code must retain the above copyright | |
| 17 | notice, this list of conditions and the following disclaimer. | |
| 18 | * Redistributions in binary form must reproduce the above copyright | |
| 19 | notice, this list of conditions and the following disclaimer in | |
| 20 | the documentation and/or other materials provided with the | |
| 21 | distribution. | |
| 22 | * Neither the name 'MAME' nor the names of its contributors may be | |
| 23 | used to endorse or promote products derived from this software | |
| 24 | without specific prior written permission. | |
| 25 | ||
| 26 | THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR | |
| 27 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 28 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 29 | DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, | |
| 30 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 31 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
| 32 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 33 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
| 34 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
| 35 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| 36 | POSSIBILITY OF SUCH DAMAGE. | |
| 37 | ||
| 38 | ***************************************************************************/ | |
| 39 | ||
| 40 | #ifndef __DECO16_H__ | |
| 41 | #define __DECO16_H__ | |
| 42 | ||
| 43 | #include "m6502.h" | |
| 44 | ||
| 45 | class deco16_device : public m6502_device { | |
| 46 | public: | |
| 47 | deco16_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 48 | ||
| 49 | static const disasm_entry disasm_entries[0x100]; | |
| 50 | ||
| 51 | virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options); | |
| 52 | virtual void do_exec_full(); | |
| 53 | virtual void do_exec_partial(); | |
| 54 | ||
| 55 | protected: | |
| 56 | address_space *io; | |
| 57 | address_space_config io_config; | |
| 58 | ||
| 59 | virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const; | |
| 60 | virtual void device_start(); | |
| 61 | ||
| 62 | #define O(o) void o ## _full(); void o ## _partial() | |
| 63 | ||
| 64 | O(ill_non); | |
| 65 | O(u0B_zpg); | |
| 66 | O(u13_zpg); | |
| 67 | O(u23_zpg); | |
| 68 | O(u3F_zpg); | |
| 69 | O(u4B_zpg); | |
| 70 | O(u87_zpg); | |
| 71 | O(u8F_zpg); | |
| 72 | O(uA3_zpg); | |
| 73 | O(uAB_zpg); | |
| 74 | O(uBB_zpg); | |
| 75 | O(vbl_zpg); | |
| 76 | ||
| 77 | #undef O | |
| 78 | }; | |
| 79 | ||
| 80 | enum { | |
| 81 | DECO16_IRQ_LINE = m6502_device::IRQ_LINE, | |
| 82 | DECO16_NMI_LINE = m6502_device::NMI_LINE, | |
| 83 | DECO16_SET_OVERFLOW = m6502_device::V_LINE, | |
| 84 | }; | |
| 85 | ||
| 86 | extern const device_type DECO16; | |
| 87 | ||
| 88 | #endif |
| r18874 | r18875 | |
|---|---|---|
| 1 | /*************************************************************************** | |
| 2 | ||
| 3 | r65c02.h | |
| 4 | ||
| 5 | Rockwell 65c02, CMOS variant with bitwise instructions | |
| 6 | ||
| 7 | **************************************************************************** | |
| 8 | ||
| 9 | Copyright Olivier Galibert | |
| 10 | All rights reserved. | |
| 11 | ||
| 12 | Redistribution and use in source and binary forms, with or without | |
| 13 | modification, are permitted provided that the following conditions are | |
| 14 | met: | |
| 15 | ||
| 16 | * Redistributions of source code must retain the above copyright | |
| 17 | notice, this list of conditions and the following disclaimer. | |
| 18 | * Redistributions in binary form must reproduce the above copyright | |
| 19 | notice, this list of conditions and the following disclaimer in | |
| 20 | the documentation and/or other materials provided with the | |
| 21 | distribution. | |
| 22 | * Neither the name 'MAME' nor the names of its contributors may be | |
| 23 | used to endorse or promote products derived from this software | |
| 24 | without specific prior written permission. | |
| 25 | ||
| 26 | THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR | |
| 27 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 28 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 29 | DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, | |
| 30 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 31 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
| 32 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 33 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
| 34 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
| 35 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| 36 | POSSIBILITY OF SUCH DAMAGE. | |
| 37 | ||
| 38 | ***************************************************************************/ | |
| 39 | ||
| 40 | #ifndef __R65C02_H__ | |
| 41 | #define __R65C02_H__ | |
| 42 | ||
| 43 | #include "m65c02.h" | |
| 44 | ||
| 45 | class r65c02_device : public m65c02_device { | |
| 46 | public: | |
| 47 | r65c02_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 48 | r65c02_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock); | |
| 49 | ||
| 50 | static const disasm_entry disasm_entries[0x100]; | |
| 51 | ||
| 52 | virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options); | |
| 53 | virtual void do_exec_full(); | |
| 54 | virtual void do_exec_partial(); | |
| 55 | }; | |
| 56 | ||
| 57 | enum { | |
| 58 | R65C02_IRQ_LINE = m6502_device::IRQ_LINE, | |
| 59 | R65C02_NMI_LINE = m6502_device::NMI_LINE, | |
| 60 | R65C02_SET_OVERFLOW = m6502_device::V_LINE, | |
| 61 | }; | |
| 62 | ||
| 63 | extern const device_type R65C02; | |
| 64 | ||
| 65 | #endif |
| r18874 | r18875 | |
|---|---|---|
| 1 | # m4510 - 65ce02 with a mmu | |
| 2 | brk_ce_imp ora_ce_idx cle_imp see_imp tsb_ce_zpg ora_ce_zpg asl_ce_zpg rmb_ce_bzp php_ce_imp ora_imm asl_ce_acc tsy_imp tsb_ce_aba ora_aba asl_ce_aba bbr_ce_zpb | |
| 3 | bpl_ce_rel ora_ce_idy ora_idz bpl_rw2 trb_ce_zpg ora_ce_zpx asl_ce_zpx rmb_ce_bzp clc_ce_imp ora_ce_aby inc_ce_acc inz_imp trb_ce_aba ora_ce_abx asl_ce_abx bbr_ce_zpb | |
| 4 | jsr_ce_adr and_ce_idx jsr_ind jsr_iax bit_ce_zpg and_ce_zpg rol_ce_zpg rmb_ce_bzp plp_ce_imp and_imm rol_ce_acc tys_imp bit_aba and_aba rol_ce_aba bbr_ce_zpb | |
| 5 | bmi_ce_rel and_ce_idy and_idz bmi_rw2 bit_ce_zpx and_ce_zpx rol_ce_zpx rmb_ce_bzp sec_ce_imp and_ce_aby dec_ce_acc dez_imp bit_ce_abx and_ce_abx rol_ce_abx bbr_ce_zpb | |
| 6 | rti_ce_imp eor_ce_idx neg_acc asr_acc asr_zpg eor_ce_zpg lsr_ce_zpg rmb_ce_bzp pha_ce_imp eor_imm lsr_ce_acc taz_imp jmp_adr eor_aba lsr_ce_aba bbr_ce_zpb | |
| 7 | bvc_ce_rel eor_ce_idy eor_idz bvc_rw2 asr_zpx eor_ce_zpx lsr_ce_zpx rmb_ce_bzp cli_ce_imp eor_ce_aby phy_ce_imp tab_imp map_imp eor_ce_abx lsr_ce_abx bbr_ce_zpb | |
| 8 | rts_ce_imp adc_ce_idx rtn_imm bsr_rw2 stz_ce_zpg adc_ce_zpg ror_ce_zpg rmb_ce_bzp pla_ce_imp adc_ce_imm ror_ce_acc tza_imp jmp_ce_ind adc_ce_aba ror_ce_aba bbr_ce_zpb | |
| 9 | bvs_ce_rel adc_ce_idy adc_idz bvs_rw2 stz_ce_zpx adc_ce_zpx ror_ce_zpx rmb_ce_bzp sei_ce_imp adc_ce_aby ply_ce_imp tba_imp jmp_ce_iax adc_ce_abx ror_ce_abx bbr_ce_zpb | |
| 10 | bra_ce_rel sta_ce_idx sta_isy bra_rw2 sty_ce_zpg sta_ce_zpg stx_ce_zpg smb_ce_bzp dey_ce_imp bit_ce_imm txa_ce_imp sty_abx sty_aba sta_aba stx_aba bbs_ce_zpb | |
| 11 | bcc_ce_rel sta_ce_idy sta_idz bcc_rw2 sty_ce_zpx sta_ce_zpx stx_ce_zpy smb_ce_bzp tya_ce_imp sta_ce_aby txs_ce_imp stx_aby stz_ce_aba sta_ce_abx stz_ce_abx bbs_ce_zpb | |
| 12 | ldy_imm lda_ce_idx ldx_imm ldz_imm ldy_ce_zpg lda_ce_zpg ldx_ce_zpg smb_ce_bzp tay_ce_imp lda_imm tax_ce_imp ldz_aba ldy_aba lda_aba ldx_aba bbs_ce_zpb | |
| 13 | bcs_ce_rel lda_ce_idy lda_idz bcs_rw2 ldy_ce_zpx lda_ce_zpx ldx_ce_zpy smb_ce_bzp clv_ce_imp lda_ce_aby tsx_ce_imp ldz_abx ldy_ce_abx lda_ce_abx ldx_ce_aby bbs_ce_zpb | |
| 14 | cpy_imm cmp_ce_idx cpz_imm dew_zpg cpy_ce_zpg cmp_ce_zpg dec_ce_zpg smb_ce_bzp iny_ce_imp cmp_imm dex_ce_imp asw_aba cpy_aba cmp_aba dec_ce_aba bbs_ce_zpb | |
| 15 | bne_ce_rel cmp_ce_idy cmp_idz bne_rw2 cpz_zpg cmp_ce_zpx dec_ce_zpx smb_ce_bzp cld_ce_imp cmp_ce_aby phx_ce_imp phz_imp cpz_aba cmp_ce_abx dec_ce_abx bbs_ce_zpb | |
| 16 | cpx_imm sbc_ce_idx lda_isy inw_zpg cpx_ce_zpg sbc_ce_zpg inc_ce_zpg smb_ce_bzp inx_ce_imp sbc_ce_imm eom_imp row_aba cpx_aba sbc_ce_aba inc_ce_aba bbs_ce_zpb | |
| 17 | beq_ce_rel sbc_ce_idy sbc_idz beq_rw2 phw_iw2 sbc_ce_zpx inc_ce_zpx smb_ce_bzp sed_ce_imp sbc_ce_aby plx_ce_imp plz_imp phw_aba sbc_ce_abx inc_ce_abx bbs_ce_zpb | |
| 18 | reset |
| r18874 | r18875 | |
|---|---|---|
| 1 | # m6510_family - identical to 6502, except for some undocumented instructions that have to be handled specifically | |
| 2 | brk_imp ora_idx kil_non slo_idx nop_zpg ora_zpg asl_zpg slo_zpg php_imp ora_imm asl_acc anc_10_imm nop_aba ora_aba asl_aba slo_aba | |
| 3 | bpl_rel ora_idy kil_non slo_idy nop_zpx ora_zpx asl_zpx slo_zpx clc_imp ora_aby nop_imp slo_aby nop_abx ora_abx asl_abx slo_abx | |
| 4 | jsr_adr and_idx kil_non rla_idx bit_zpg and_zpg rol_zpg rla_zpg plp_imp and_imm rol_acc anc_10_imm bit_aba and_aba rol_aba rla_aba | |
| 5 | bmi_rel and_idy kil_non rla_idy nop_zpx and_zpx rol_zpx rla_zpx sec_imp and_aby nop_imp rla_aby nop_abx and_abx rol_abx rla_abx | |
| 6 | rti_imp eor_idx kil_non sre_idx nop_zpg eor_zpg lsr_zpg sre_zpg pha_imp eor_imm lsr_acc asr_10_imm jmp_adr eor_aba lsr_aba sre_aba | |
| 7 | bvc_rel eor_idy kil_non sre_idy nop_zpx eor_zpx lsr_zpx sre_zpx cli_imp eor_aby nop_imp sre_aby nop_abx eor_abx lsr_abx sre_abx | |
| 8 | rts_imp adc_idx kil_non rra_idx nop_zpg adc_zpg ror_zpg rra_zpg pla_imp adc_imm ror_acc arr_10_imm jmp_ind adc_aba ror_aba rra_aba | |
| 9 | bvs_rel adc_idy kil_non rra_idy nop_zpx adc_zpx ror_zpx rra_zpx sei_imp adc_aby nop_imp rra_aby nop_abx adc_abx ror_abx rra_abx | |
| 10 | nop_imp sta_idx nop_imm sax_idx sty_zpg sta_zpg stx_zpg sax_zpg dey_imp nop_imm txa_imp ane_10_imm sty_aba sta_aba stx_aba sax_aba | |
| 11 | bcc_rel sta_idy kil_non sha_idy sty_zpx sta_zpx stx_zpy sax_zpy tya_imp sta_aby txs_imp shs_aby shy_abx sta_abx shx_aby sha_aby | |
| 12 | ldy_imm lda_idx ldx_imm lax_idx ldy_zpg lda_zpg ldx_zpg lax_zpg tay_imp lda_imm tax_imp lxa_10_imm ldy_aba lda_aba ldx_aba lax_aba | |
| 13 | bcs_rel lda_idy kil_non lax_idy ldy_zpx lda_zpx ldx_zpy lax_zpy clv_imp lda_aby tsx_imp las_10_aby ldy_abx lda_abx ldx_aby lax_aby | |
| 14 | cpy_imm cmp_idx nop_imm dcp_idx cpy_zpg cmp_zpg dec_zpg dcp_zpg iny_imp cmp_imm dex_imp sbx_imm cpy_aba cmp_aba dec_aba dcp_aba | |
| 15 | bne_rel cmp_idy kil_non dcp_idy nop_zpx cmp_zpx dec_zpx dcp_zpx cld_imp cmp_aby nop_imp dcp_aby nop_abx cmp_abx dec_abx dcp_abx | |
| 16 | cpx_imm sbc_idx nop_imm isb_idx cpx_zpg sbc_zpg inc_zpg isb_zpg inx_imp sbc_imm nop_imp sbc_imm cpx_aba sbc_aba inc_aba isb_aba | |
| 17 | beq_rel sbc_idy kil_non isb_idy nop_zpx sbc_zpx inc_zpx isb_zpx sed_imp sbc_aby nop_imp isb_aby nop_abx sbc_abx inc_abx isb_abx | |
| 18 | reset |
| r18874 | r18875 | |
|---|---|---|
| 1 | # m65c02 | |
| 2 | brk_c_imp ora_idx nop_imm nop_c_imp tsb_zpg ora_zpg asl_zpg nop_c_imp php_imp ora_imm asl_acc nop_c_imp tsb_aba ora_aba asl_aba nop_c_imp | |
| 3 | bpl_rel ora_idy ora_zpi nop_c_imp trb_zpg ora_zpx asl_zpx nop_c_imp clc_imp ora_aby inc_acc nop_c_imp trb_aba ora_abx asl_c_abx nop_c_imp | |
| 4 | jsr_adr and_idx nop_imm nop_c_imp bit_zpg and_zpg rol_zpg nop_c_imp plp_imp and_imm rol_acc nop_c_imp bit_aba and_aba rol_aba nop_c_imp | |
| 5 | bmi_rel and_idy and_zpi nop_c_imp bit_zpx and_zpx rol_zpx nop_c_imp sec_imp and_aby dec_acc nop_c_imp bit_abx and_abx rol_c_abx nop_c_imp | |
| 6 | rti_imp eor_idx nop_imm nop_c_imp nop_zpg eor_zpg lsr_zpg nop_c_imp pha_imp eor_imm lsr_acc nop_c_imp jmp_adr eor_aba lsr_aba nop_c_imp | |
| 7 | bvc_rel eor_idy eor_zpi nop_c_imp nop_zpx eor_zpx lsr_zpx nop_c_imp cli_imp eor_aby phy_imp nop_c_imp nop_c_aba eor_abx lsr_c_abx nop_c_imp | |
| 8 | rts_imp adc_c_idx nop_imm nop_c_imp stz_zpg adc_c_zpg ror_zpg nop_c_imp pla_imp adc_c_imm ror_acc nop_c_imp jmp_c_ind adc_c_aba ror_aba nop_c_imp | |
| 9 | bvs_rel adc_c_idy adc_c_zpi nop_c_imp stz_zpx adc_c_zpx ror_zpx nop_c_imp sei_imp adc_c_aby ply_imp nop_c_imp jmp_iax adc_c_abx ror_c_abx nop_c_imp | |
| 10 | bra_rel sta_idx nop_imm nop_c_imp sty_zpg sta_zpg stx_zpg nop_c_imp dey_imp bit_imm txa_imp nop_c_imp sty_aba sta_aba stx_aba nop_c_imp | |
| 11 | bcc_rel sta_idy sta_zpi nop_c_imp sty_zpx sta_zpx stx_zpy nop_c_imp tya_imp sta_aby txs_imp nop_c_imp stz_aba sta_abx stz_abx nop_c_imp | |
| 12 | ldy_imm lda_idx ldx_imm nop_c_imp ldy_zpg lda_zpg ldx_zpg nop_c_imp tay_imp lda_imm tax_imp nop_c_imp ldy_aba lda_aba ldx_aba nop_c_imp | |
| 13 | bcs_rel lda_idy lda_zpi nop_c_imp ldy_zpx lda_zpx ldx_zpy nop_c_imp clv_imp lda_aby tsx_imp nop_c_imp ldy_abx lda_abx ldx_aby nop_c_imp | |
| 14 | cpy_imm cmp_idx nop_imm nop_c_imp cpy_zpg cmp_zpg dec_zpg nop_c_imp iny_imp cmp_imm dex_imp nop_c_imp cpy_aba cmp_aba dec_aba nop_c_imp | |
| 15 | bne_rel cmp_idy cmp_zpi nop_c_imp nop_zpx cmp_zpx dec_zpx nop_c_imp cld_imp cmp_aby phx_imp nop_c_imp nop_c_abx cmp_abx dec_abx nop_c_imp | |
| 16 | cpx_imm sbc_c_idx nop_imm nop_c_imp cpx_zpg sbc_c_zpg inc_zpg nop_c_imp inx_imp sbc_c_imm nop_imp nop_c_imp cpx_aba sbc_c_aba inc_aba nop_c_imp | |
| 17 | beq_rel sbc_c_idy sbc_c_zpi nop_c_imp nop_zpx sbc_c_zpx inc_zpx nop_c_imp sed_imp sbc_c_aby plx_imp nop_c_imp nop_c_abx sbc_c_abx inc_abx nop_c_imp | |
| 18 | reset |
| r18874 | r18875 | |
|---|---|---|
| 1 | # m65ce02 - Adds the B and Z registers to the r65c02, a bunch of instructions, and changes most of the timings | |
| 2 | brk_ce_imp ora_ce_idx cle_imp see_imp tsb_ce_zpg ora_ce_zpg asl_ce_zpg rmb_ce_bzp php_ce_imp ora_imm asl_ce_acc tsy_imp tsb_ce_aba ora_aba asl_ce_aba bbr_ce_zpb | |
| 3 | bpl_ce_rel ora_ce_idy ora_idz bpl_rw2 trb_ce_zpg ora_ce_zpx asl_ce_zpx rmb_ce_bzp clc_ce_imp ora_ce_aby inc_ce_acc inz_imp trb_ce_aba ora_ce_abx asl_ce_abx bbr_ce_zpb | |
| 4 | jsr_ce_adr and_ce_idx jsr_ind jsr_iax bit_ce_zpg and_ce_zpg rol_ce_zpg rmb_ce_bzp plp_ce_imp and_imm rol_ce_acc tys_imp bit_aba and_aba rol_ce_aba bbr_ce_zpb | |
| 5 | bmi_ce_rel and_ce_idy and_idz bmi_rw2 bit_ce_zpx and_ce_zpx rol_ce_zpx rmb_ce_bzp sec_ce_imp and_ce_aby dec_ce_acc dez_imp bit_ce_abx and_ce_abx rol_ce_abx bbr_ce_zpb | |
| 6 | rti_ce_imp eor_ce_idx neg_acc asr_acc asr_zpg eor_ce_zpg lsr_ce_zpg rmb_ce_bzp pha_ce_imp eor_imm lsr_ce_acc taz_imp jmp_adr eor_aba lsr_ce_aba bbr_ce_zpb | |
| 7 | bvc_ce_rel eor_ce_idy eor_idz bvc_rw2 asr_zpx eor_ce_zpx lsr_ce_zpx rmb_ce_bzp cli_ce_imp eor_ce_aby phy_ce_imp tab_imp aug_iw3 eor_ce_abx lsr_ce_abx bbr_ce_zpb | |
| 8 | rts_ce_imp adc_ce_idx rtn_imm bsr_rw2 stz_ce_zpg adc_ce_zpg ror_ce_zpg rmb_ce_bzp pla_ce_imp adc_ce_imm ror_ce_acc tza_imp jmp_ce_ind adc_ce_aba ror_ce_aba bbr_ce_zpb | |
| 9 | bvs_ce_rel adc_ce_idy adc_idz bvs_rw2 stz_ce_zpx adc_ce_zpx ror_ce_zpx rmb_ce_bzp sei_ce_imp adc_ce_aby ply_ce_imp tba_imp jmp_ce_iax adc_ce_abx ror_ce_abx bbr_ce_zpb | |
| 10 | bra_ce_rel sta_ce_idx sta_isy bra_rw2 sty_ce_zpg sta_ce_zpg stx_ce_zpg smb_ce_bzp dey_ce_imp bit_ce_imm txa_ce_imp sty_abx sty_aba sta_aba stx_aba bbs_ce_zpb | |
| 11 | bcc_ce_rel sta_ce_idy sta_idz bcc_rw2 sty_ce_zpx sta_ce_zpx stx_ce_zpy smb_ce_bzp tya_ce_imp sta_ce_aby txs_ce_imp stx_aby stz_ce_aba sta_ce_abx stz_ce_abx bbs_ce_zpb | |
| 12 | ldy_imm lda_ce_idx ldx_imm ldz_imm ldy_ce_zpg lda_ce_zpg ldx_ce_zpg smb_ce_bzp tay_ce_imp lda_imm tax_ce_imp ldz_aba ldy_aba lda_aba ldx_aba bbs_ce_zpb | |
| 13 | bcs_ce_rel lda_ce_idy lda_idz bcs_rw2 ldy_ce_zpx lda_ce_zpx ldx_ce_zpy smb_ce_bzp clv_ce_imp lda_ce_aby tsx_ce_imp ldz_abx ldy_ce_abx lda_ce_abx ldx_ce_aby bbs_ce_zpb | |
| 14 | cpy_imm cmp_ce_idx cpz_imm dew_zpg cpy_ce_zpg cmp_ce_zpg dec_ce_zpg smb_ce_bzp iny_ce_imp cmp_imm dex_ce_imp asw_aba cpy_aba cmp_aba dec_ce_aba bbs_ce_zpb | |
| 15 | bne_ce_rel cmp_ce_idy cmp_idz bne_rw2 cpz_zpg cmp_ce_zpx dec_ce_zpx smb_ce_bzp cld_ce_imp cmp_ce_aby phx_ce_imp phz_imp cpz_aba cmp_ce_abx dec_ce_abx bbs_ce_zpb | |
| 16 | cpx_imm sbc_ce_idx lda_isy inw_zpg cpx_ce_zpg sbc_ce_zpg inc_ce_zpg smb_ce_bzp inx_ce_imp sbc_ce_imm nop_c_imp row_aba cpx_aba sbc_ce_aba inc_ce_aba bbs_ce_zpb | |
| 17 | beq_ce_rel sbc_ce_idy sbc_idz beq_rw2 phw_iw2 sbc_ce_zpx inc_ce_zpx smb_ce_bzp sed_ce_imp sbc_ce_aby plx_ce_imp plz_imp phw_aba sbc_ce_abx inc_ce_abx bbs_ce_zpb | |
| 18 | reset |
| r18874 | r18875 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * m4510.c | |
| 4 | * Portable 4510 emulator V1.0beta1 | |
| 5 | * | |
| 6 | * Copyright Peter Trauner, all rights reserved | |
| 7 | * documentation preliminary databook | |
| 8 | * documentation by michael steil mist@c64.org | |
| 9 | * available at ftp://ftp.funet.fi/pub/cbm/c65 | |
| 10 | * | |
| 11 | * - This source code is released as freeware for non-commercial purposes. | |
| 12 | * - You are free to use and redistribute this code in modified or | |
| 13 | * unmodified form, provided you list me in the credits. | |
| 14 | * - If you modify this source code, you must add a notice to each modified | |
| 15 | * source file that it has been changed. If you're a nice person, you | |
| 16 | * will clearly mark each change too. :) | |
| 17 | * - If you wish to use this for commercial purposes, please contact me at | |
| 18 | * pullmoll@t-online.de | |
| 19 | * - The author of this copywritten work reserves the right to change the | |
| 20 | * terms of its usage and license at any time, including retroactively | |
| 21 | * - This entire notice must remain in the source code. | |
| 22 | * | |
| 23 | *****************************************************************************/ | |
| 1 | /*************************************************************************** | |
| 24 | 2 | |
| 25 | /* | |
| 26 | c65 memory management | |
| 27 | (reset) | |
| 28 | c64 ff | |
| 29 | c65 20 (interface) | |
| 3 | m4510.c | |
| 30 | 4 | |
| 31 | a (c65 mode) | |
| 32 | a:00 x:e3 y:00 z:b3 | |
| 33 | c65 64 (interface) | |
| 34 | c64 ff | |
| 5 | 65ce02 with a mmu and a cia integrated | |
| 35 | 6 | |
| 36 | b (c65 dosmode?) | |
| 37 | c65 65 (interface, full colorram) | |
| 38 | a:00 x:11 y:80 z:31 | |
| 39 | c64 ff | |
| 7 | **************************************************************************** | |
| 40 | 8 | |
| 41 | c (?) | |
| 42 | c64 07 | |
| 43 | a:00 x:00 y:00 z:00 | |
| 9 | Copyright Olivier Galibert | |
| 10 | All rights reserved. | |
| 44 | 11 | |
| 45 | a c65 mode | |
| 12 | Redistribution and use in source and binary forms, with or without | |
| 13 | modification, are permitted provided that the following conditions are | |
| 14 | met: | |
| 46 | 15 | |
| 47 | diskcontroller accesses | |
| 16 | * Redistributions of source code must retain the above copyright | |
| 17 | notice, this list of conditions and the following disclaimer. | |
| 18 | * Redistributions in binary form must reproduce the above copyright | |
| 19 | notice, this list of conditions and the following disclaimer in | |
| 20 | the documentation and/or other materials provided with the | |
| 21 | distribution. | |
| 22 | * Neither the name 'MAME' nor the names of its contributors may be | |
| 23 | used to endorse or promote products derived from this software | |
| 24 | without specific prior written permission. | |
| 48 | 25 | |
| 26 | THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR | |
| 27 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 28 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 29 | DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, | |
| 30 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 31 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
| 32 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 33 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
| 34 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
| 35 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| 36 | POSSIBILITY OF SUCH DAMAGE. | |
| 49 | 37 | |
| 50 | monitor | |
| 51 | c64 ff | |
| 52 | a:a0 x:82 y:00 z:83 | |
| 38 | ***************************************************************************/ | |
| 53 | 39 | |
| 54 | c64 mode | |
| 55 | c65 0 | |
| 56 | c65 2f:0 ! | |
| 57 | c64 ff | |
| 58 | a:00 x:00 y:00 z:00 | |
| 59 | ||
| 60 | internal 8 mb to 64k switching (jmp routine in rom) | |
| 61 | ( seams to be incomplete, in chapter 1 1megabyte memory mapper ) | |
| 62 | a x y z | |
| 63 | g 0 00 e0 00 f0 | |
| 64 | g 10000 00 e1 00 f1 | |
| 65 | g 20000 00 e2 00 f2 | |
| 66 | g 30000 00 e3 00 f3 | |
| 67 | g 40000 00 e4 00 f4 | |
| 68 | g 50000 00 e5 00 f5 | |
| 69 | g 60000 00 e6 00 f6 | |
| 70 | . | |
| 71 | . | |
| 72 | g f0000 00 ef 00 ff | |
| 73 | the same for 100000 .. 700000 | |
| 74 | g 800000 00 e3 00 b3 | |
| 75 | ||
| 76 | thesis: | |
| 77 | a: ?0?0 0000 | |
| 78 | ? ? only in monitor mode set | |
| 79 | x: xxxx address bits a19 .. a16 for memory accesses with a15 0 ? | |
| 80 | 0000 c64 mode | |
| 81 | 0001 dosmode | |
| 82 | 1110 c65 mode, plain ram access | |
| 83 | (0000-1fff contains the switching code, so not switchable!?) | |
| 84 | 1000 monitor | |
| 85 | 1 map 6000-7fff | |
| 86 | 1 map 4000-5fff | |
| 87 | 1 map 2000-3fff | |
| 88 | 1 map 0000-1fff | |
| 89 | y: ?000 0000 | |
| 90 | ? only in dos mode set | |
| 91 | z: xxxx address bits a19 .. a16 for memory accesses with a15 1 ? | |
| 92 | 0000 c64 mode | |
| 93 | 0011 dosmode | |
| 94 | 1000 monitor | |
| 95 | 1011 c65 mode | |
| 96 | 1111 plain ram access | |
| 97 | 1 map e000-ffff | |
| 98 | 1 map c000-dfff | |
| 99 | 1 map a000-bfff | |
| 100 | 1 map 8000-9fff | |
| 101 | */ | |
| 102 | ||
| 103 | 40 | #include "emu.h" |
| 104 | #include "debugger.h" | |
| 105 | #include "m6502.h" | |
| 106 | 41 | #include "m4510.h" |
| 107 | 42 | |
| 108 | #include "minc4510.h" | |
| 109 | #include "opsce02.h" | |
| 110 | #include "ops4510.h" | |
| 43 | const device_type M4510 = &device_creator<m4510_device>; | |
| 111 | 44 | |
| 112 | #define M6502_NMI_VEC 0xfffa | |
| 113 | #define M6502_RST_VEC 0xfffc | |
| 114 | #define M6502_IRQ_VEC 0xfffe | |
| 115 | #define M4510_RST_VEC M6502_RST_VEC | |
| 116 | #define M4510_IRQ_VEC M6502_IRQ_VEC | |
| 117 | #define M4510_NMI_VEC M6502_NMI_VEC | |
| 118 | ||
| 119 | #define VERBOSE 0 | |
| 120 | ||
| 121 | #define LOG(x) do { if (VERBOSE) logerror x; } while (0) | |
| 122 | ||
| 123 | struct m4510_Regs { | |
| 124 | void (*const *insn)(m4510_Regs *); /* pointer to the function pointer table */ | |
| 125 | PAIR ppc; /* previous program counter */ | |
| 126 | PAIR pc; /* program counter */ | |
| 127 | PAIR sp; /* stack pointer (always 100 - 1FF) */ | |
| 128 | PAIR zp; /* zero page address */ | |
| 129 | /* contains B register zp.b.h */ | |
| 130 | PAIR ea; /* effective address */ | |
| 131 | UINT8 a; /* Accumulator */ | |
| 132 | UINT8 x; /* X index register */ | |
| 133 | UINT8 y; /* Y index register */ | |
| 134 | UINT8 z; /* Z index register */ | |
| 135 | UINT8 p; /* Processor status */ | |
| 136 | UINT8 interrupt_inhibit; /* Some instructions, like MAP, inhibit interrupt */ | |
| 137 | UINT8 pending_irq; /* nonzero if an IRQ is pending */ | |
| 138 | UINT8 after_cli; /* pending IRQ and last insn cleared I */ | |
| 139 | UINT8 nmi_state; | |
| 140 | UINT8 irq_state; | |
| 141 | UINT16 low, high; | |
| 142 | UINT32 mem[8]; | |
| 143 | ||
| 144 | device_irq_acknowledge_callback irq_callback; | |
| 145 | legacy_cpu_device *device; | |
| 146 | address_space *space; | |
| 147 | direct_read_data *direct; | |
| 148 | int icount; | |
| 149 | ||
| 150 | devcb_resolved_read8 rdmem_id; /* readmem callback for indexed instructions */ | |
| 151 | devcb_resolved_write8 wrmem_id; /* writemem callback for indexed instructions */ | |
| 152 | ||
| 153 | UINT8 ddr; | |
| 154 | UINT8 port; | |
| 155 | ||
| 156 | devcb_resolved_read8 in_port_func; | |
| 157 | devcb_resolved_write8 out_port_func; | |
| 158 | }; | |
| 159 | ||
| 160 | INLINE m4510_Regs *get_safe_token(device_t *device) | |
| 45 | m4510_device::m4510_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : | |
| 46 | m65ce02_device(mconfig, M4510, "M4510", tag, owner, clock) | |
| 161 | 47 | { |
| 162 | assert(device != NULL); | |
| 163 | assert(device->type() == M4510); | |
| 164 | return (m4510_Regs *)downcast<legacy_cpu_device *>(device)->token(); | |
| 48 | program_config.m_addrbus_width = 20; | |
| 49 | program_config.m_logaddr_width = 16; | |
| 50 | program_config.m_page_shift = 13; | |
| 165 | 51 | } |
| 166 | 52 | |
| 167 | /*************************************************************** | |
| 168 | * include the opcode macros, functions and tables | |
| 169 | ***************************************************************/ | |
| 170 | ||
| 171 | INLINE int m4510_cpu_readop(m4510_Regs *cpustate) | |
| 53 | offs_t m4510_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) | |
| 172 | 54 | { |
| 173 | register UINT16 t=cpustate->pc.w.l++; | |
| 174 | return cpustate->direct->read_decrypted_byte(M4510_MEM(t)); | |
| 55 | return disassemble_generic(buffer, pc, oprom, opram, options, disasm_entries); | |
| 175 | 56 | } |
| 176 | 57 | |
| 177 | ||
| 58 | void m4510_device::device_start() | |
| 178 | 59 | { |
| 179 | register UINT16 t=cpustate->pc.w.l++; | |
| 180 | return cpustate->direct->read_raw_byte(M4510_MEM(t)); | |
| 181 | } | |
| 182 | ||
| 183 | #define M4510 | |
| 184 | #include "t65ce02.c" | |
| 185 | ||
| 186 | static CPU_INIT( m4510 ) | |
| 187 | { | |
| 188 | m4510_Regs *cpustate = get_safe_token(device); | |
| 189 | const m6502_interface *intf = (const m6502_interface *)device->static_config(); | |
| 190 | ||
| 191 | cpustate->interrupt_inhibit = 0; | |
| 192 | cpustate->irq_callback = irqcallback; | |
| 193 | cpustate->device = device; | |
| 194 | cpustate->space = &device->space(AS_PROGRAM); | |
| 195 | cpustate->direct = &cpustate->space->direct(); | |
| 196 | ||
| 197 | if ( intf ) | |
| 198 | { | |
| 199 | cpustate->rdmem_id.resolve(intf->read_indexed_func, *device); | |
| 200 | cpustate->wrmem_id.resolve(intf->write_indexed_func, *device); | |
| 201 | cpustate->in_port_func.resolve(intf->in_port_func, *device); | |
| 202 | cpustate->out_port_func.resolve(intf->out_port_func, *device); | |
| 203 | } | |
| 60 | if(direct_disabled) | |
| 61 | mintf = new mi_4510_nd(this); | |
| 204 | 62 | else |
| 205 | { | |
| 206 | devcb_read8 nullrcb = DEVCB_NULL; | |
| 207 | devcb_write8 nullwcb = DEVCB_NULL; | |
| 63 | mintf = new mi_4510_normal(this); | |
| 208 | 64 | |
| 209 | cpustate->rdmem_id.resolve(nullrcb, *device); | |
| 210 | cpustate->wrmem_id.resolve(nullwcb, *device); | |
| 211 | cpustate->in_port_func.resolve(nullrcb, *device); | |
| 212 | cpustate->out_port_func.resolve(nullwcb, *device); | |
| 213 | } | |
| 214 | } | |
| 65 | m65ce02_device::device_start(); | |
| 215 | 66 | |
| 216 | static CPU_RESET( m4510 ) | |
| 217 | { | |
| 218 | m4510_Regs *cpustate = get_safe_token(device); | |
| 219 | ||
| 220 | cpustate->insn = insn4510; | |
| 221 | ||
| 222 | /* wipe out the rest of the m65ce02 structure */ | |
| 223 | /* read the reset vector into PC */ | |
| 224 | /* reset z index and b bank */ | |
| 225 | PCL = RDMEM(M4510_RST_VEC); | |
| 226 | PCH = RDMEM(M4510_RST_VEC+1); | |
| 227 | ||
| 228 | /* after reset in 6502 compatibility mode */ | |
| 229 | cpustate->sp.d = 0x01ff; /* high byte descriped in databook */ | |
| 230 | cpustate->z = 0; | |
| 231 | B = 0; | |
| 232 | cpustate->p = F_E|F_B|F_I|F_Z; /* set E, I and Z flags */ | |
| 233 | cpustate->interrupt_inhibit = 0; | |
| 234 | cpustate->pending_irq = 0; /* nonzero if an IRQ is pending */ | |
| 235 | cpustate->after_cli = 0; /* pending IRQ and last insn cleared I */ | |
| 236 | cpustate->irq_callback = NULL; | |
| 237 | ||
| 238 | /* don't know */ | |
| 239 | cpustate->high=0x8200; | |
| 240 | cpustate->mem[7]=0x20000; | |
| 241 | ||
| 242 | cpustate->port = 0xff; | |
| 243 | cpustate->ddr = 0x00; | |
| 67 | save_item(NAME(map_offset)); | |
| 68 | save_item(NAME(map_enable)); | |
| 244 | 69 | } |
| 245 | 70 | |
| 246 | ||
| 71 | void m4510_device::device_reset() | |
| 247 | 72 | { |
| 248 | /* nothing to do yet */ | |
| 73 | map_offset[0] = map_offset[1] = 0; | |
| 74 | map_enable = 0; | |
| 75 | nomap = true; | |
| 249 | 76 | } |
| 250 | 77 | |
| 251 | ||
| 78 | m4510_device::mi_4510_normal::mi_4510_normal(m4510_device *_base) | |
| 252 | 79 | { |
| 253 | if(( !(P & F_I) ) && (cpustate->interrupt_inhibit == 0)) | |
| 254 | { | |
| 255 | EAD = M4510_IRQ_VEC; | |
| 256 | cpustate->icount -= 7; | |
| 257 | PUSH(PCH); | |
| 258 | PUSH(PCL); | |
| 259 | PUSH(P & ~F_B); | |
| 260 | P = (P & ~F_D) | F_I; /* knock out D and set I flag */ | |
| 261 | PCL = RDMEM(EAD); | |
| 262 | PCH = RDMEM(EAD+1); | |
| 263 | LOG(("M4510 '%s' takes IRQ ($%04x)\n", cpustate->device->tag(), PCD)); | |
| 264 | /* call back the cpuintrf to let it clear the line */ | |
| 265 | if (cpustate->irq_callback) (*cpustate->irq_callback)(cpustate->device, 0); | |
| 266 | } | |
| 267 | cpustate->pending_irq = 0; | |
| 80 | base = _base; | |
| 268 | 81 | } |
| 269 | 82 | |
| 270 | ||
| 83 | UINT8 m4510_device::mi_4510_normal::read(UINT16 adr) | |
| 271 | 84 | { |
| 272 | m4510_Regs *cpustate = get_safe_token(device); | |
| 273 | ||
| 274 | do | |
| 275 | { | |
| 276 | UINT8 op; | |
| 277 | PPC = PCD; | |
| 278 | ||
| 279 | debugger_instruction_hook(device, PCD); | |
| 280 | ||
| 281 | /* if an irq is pending, take it now */ | |
| 282 | if( cpustate->pending_irq ) | |
| 283 | m4510_take_irq(cpustate); | |
| 284 | ||
| 285 | op = RDOP(); | |
| 286 | (*insn4510[op])(cpustate); | |
| 287 | ||
| 288 | /* check if the I flag was just reset (interrupts enabled) */ | |
| 289 | if( cpustate->after_cli ) | |
| 290 | { | |
| 291 | LOG(("M4510 '%s' after_cli was >0", cpustate->device->tag())); | |
| 292 | cpustate->after_cli = 0; | |
| 293 | if (cpustate->irq_state != CLEAR_LINE) | |
| 294 | { | |
| 295 | LOG((": irq line is asserted: set pending IRQ\n")); | |
| 296 | cpustate->pending_irq = 1; | |
| 297 | } | |
| 298 | else | |
| 299 | { | |
| 300 | LOG((": irq line is clear\n")); | |
| 301 | } | |
| 302 | } | |
| 303 | else | |
| 304 | if( cpustate->pending_irq ) | |
| 305 | m4510_take_irq(cpustate); | |
| 306 | ||
| 307 | } while (cpustate->icount > 0); | |
| 85 | return program->read_byte(base->map(adr)); | |
| 308 | 86 | } |
| 309 | 87 | |
| 310 | ||
| 88 | UINT8 m4510_device::mi_4510_normal::read_direct(UINT16 adr) | |
| 311 | 89 | { |
| 312 | if (irqline == INPUT_LINE_NMI) | |
| 313 | { | |
| 314 | if (cpustate->nmi_state == state) return; | |
| 315 | cpustate->nmi_state = state; | |
| 316 | if( state != CLEAR_LINE ) | |
| 317 | { | |
| 318 | LOG(("M4510 '%s' set_nmi_line(ASSERT)\n", cpustate->device->tag())); | |
| 319 | EAD = M4510_NMI_VEC; | |
| 320 | cpustate->icount -= 7; | |
| 321 | PUSH(PCH); | |
| 322 | PUSH(PCL); | |
| 323 | PUSH(P & ~F_B); | |
| 324 | P = (P & ~F_D) | F_I; /* knock out D and set I flag */ | |
| 325 | PCL = RDMEM(EAD); | |
| 326 | PCH = RDMEM(EAD+1); | |
| 327 | LOG(("M4510 '%s' takes NMI ($%04x)\n", cpustate->device->tag(), PCD)); | |
| 328 | } | |
| 329 | } | |
| 330 | else | |
| 331 | { | |
| 332 | cpustate->irq_state = state; | |
| 333 | if( state != CLEAR_LINE ) | |
| 334 | { | |
| 335 | LOG(("M4510 '%s' set_irq_line(ASSERT)\n", cpustate->device->tag())); | |
| 336 | cpustate->pending_irq = 1; | |
| 337 | } | |
| 338 | } | |
| 90 | return direct->read_raw_byte(base->map(adr)); | |
| 339 | 91 | } |
| 340 | 92 | |
| 341 | UINT8 m4510_ | |
| 93 | UINT8 m4510_device::mi_4510_normal::read_decrypted(UINT16 adr) | |
| 342 | 94 | { |
| 343 | m4510_Regs *cpustate = get_safe_token(device); | |
| 344 | return (cpustate->port & cpustate->ddr) | (cpustate->ddr ^ 0xff); | |
| 95 | return direct->read_decrypted_byte(base->map(adr)); | |
| 345 | 96 | } |
| 346 | static READ8_HANDLER( m4510_read_0000 ) | |
| 347 | { | |
| 348 | UINT8 result = 0x00; | |
| 349 | m4510_Regs *cpustate = get_safe_token(&space.device()); | |
| 350 | 97 | |
| 351 | switch(offset) | |
| 352 | { | |
| 353 | case 0x0000: /* DDR */ | |
| 354 | result = cpustate->ddr; | |
| 355 | break; | |
| 356 | case 0x0001: /* Data Port */ | |
| 357 | result = cpustate->in_port_func(0); | |
| 358 | result = (cpustate->ddr & cpustate->port) | (~cpustate->ddr & result); | |
| 359 | break; | |
| 360 | } | |
| 361 | return result; | |
| 362 | } | |
| 363 | ||
| 364 | static WRITE8_HANDLER( m4510_write_0000 ) | |
| 98 | void m4510_device::mi_4510_normal::write(UINT16 adr, UINT8 val) | |
| 365 | 99 | { |
| 366 | m4510_Regs *cpustate = get_safe_token(&space.device()); | |
| 367 | ||
| 368 | switch(offset) | |
| 369 | { | |
| 370 | case 0x0000: /* DDR */ | |
| 371 | cpustate->ddr = data; | |
| 372 | break; | |
| 373 | case 0x0001: /* Data Port */ | |
| 374 | cpustate->port = data; | |
| 375 | break; | |
| 376 | } | |
| 377 | ||
| 378 | cpustate->out_port_func(0, m4510_get_port(downcast<legacy_cpu_device *>(&space.device()))); | |
| 100 | program->write_byte(base->map(adr), val); | |
| 379 | 101 | } |
| 380 | 102 | |
| 381 | static ADDRESS_MAP_START(m4510_mem, AS_PROGRAM, 8, legacy_cpu_device) | |
| 382 | AM_RANGE(0x0000, 0x0001) AM_READWRITE_LEGACY(m4510_read_0000, m4510_write_0000) | |
| 383 | ADDRESS_MAP_END | |
| 384 | ||
| 385 | static CPU_TRANSLATE( m4510 ) | |
| 103 | m4510_device::mi_4510_nd::mi_4510_nd(m4510_device *_base) : mi_4510_normal(_base) | |
| 386 | 104 | { |
| 387 | m4510_Regs *cpustate = get_safe_token(device); | |
| 388 | ||
| 389 | if (space == AS_PROGRAM) | |
| 390 | *address = M4510_MEM(*address); | |
| 391 | return TRUE; | |
| 392 | 105 | } |
| 393 | 106 | |
| 394 | /************************************************************************** | |
| 395 | * Generic set_info | |
| 396 | **************************************************************************/ | |
| 397 | ||
| 398 | static CPU_SET_INFO( m4510 ) | |
| 107 | UINT8 m4510_device::mi_4510_nd::read_direct(UINT16 adr) | |
| 399 | 108 | { |
| 400 | m4510_Regs *cpustate = get_safe_token(device); | |
| 401 | ||
| 402 | switch (state) | |
| 403 | { | |
| 404 | /* --- the following bits of info are set as 64-bit signed integers --- */ | |
| 405 | case CPUINFO_INT_INPUT_STATE + M4510_IRQ_LINE: m4510_set_irq_line(cpustate, M4510_IRQ_LINE, info->i); break; | |
| 406 | case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI: m4510_set_irq_line(cpustate, INPUT_LINE_NMI, info->i); break; | |
| 407 | ||
| 408 | case CPUINFO_INT_PC: PCW = info->i; break; | |
| 409 | case CPUINFO_INT_REGISTER + M4510_PC: cpustate->pc.w.l = info->i; break; | |
| 410 | case CPUINFO_INT_SP: SPL = info->i; break; | |
| 411 | case CPUINFO_INT_REGISTER + M4510_S: cpustate->sp.b.l = info->i; break; | |
| 412 | case CPUINFO_INT_REGISTER + M4510_P: cpustate->p = info->i; break; | |
| 413 | case CPUINFO_INT_REGISTER + M4510_A: cpustate->a = info->i; break; | |
| 414 | case CPUINFO_INT_REGISTER + M4510_X: cpustate->x = info->i; break; | |
| 415 | case CPUINFO_INT_REGISTER + M4510_Y: cpustate->y = info->i; break; | |
| 416 | case CPUINFO_INT_REGISTER + M4510_Z: cpustate->z = info->i; break; | |
| 417 | case CPUINFO_INT_REGISTER + M4510_B: cpustate->zp.b.h = info->i; break; | |
| 418 | case CPUINFO_INT_REGISTER + M4510_MEM_LOW: cpustate->low = info->i; break; | |
| 419 | case CPUINFO_INT_REGISTER + M4510_MEM_HIGH: cpustate->high = info->i; break; | |
| 420 | case CPUINFO_INT_REGISTER + M4510_EA: cpustate->ea.w.l = info->i; break; | |
| 421 | case CPUINFO_INT_REGISTER + M4510_ZP: cpustate->zp.w.l = info->i; break; | |
| 422 | case CPUINFO_INT_REGISTER + M4510_MEM0: cpustate->mem[0] = info->i; break; | |
| 423 | case CPUINFO_INT_REGISTER + M4510_MEM1: cpustate->mem[1] = info->i; break; | |
| 424 | case CPUINFO_INT_REGISTER + M4510_MEM2: cpustate->mem[2] = info->i; break; | |
| 425 | case CPUINFO_INT_REGISTER + M4510_MEM3: cpustate->mem[3] = info->i; break; | |
| 426 | case CPUINFO_INT_REGISTER + M4510_MEM4: cpustate->mem[4] = info->i; break; | |
| 427 | case CPUINFO_INT_REGISTER + M4510_MEM5: cpustate->mem[5] = info->i; break; | |
| 428 | case CPUINFO_INT_REGISTER + M4510_MEM6: cpustate->mem[6] = info->i; break; | |
| 429 | case CPUINFO_INT_REGISTER + M4510_MEM7: cpustate->mem[7] = info->i; break; | |
| 430 | } | |
| 109 | return read(adr); | |
| 431 | 110 | } |
| 432 | 111 | |
| 433 | ||
| 434 | ||
| 435 | /************************************************************************** | |
| 436 | * Generic get_info | |
| 437 | **************************************************************************/ | |
| 438 | ||
| 439 | CPU_GET_INFO( m4510 ) | |
| 112 | UINT8 m4510_device::mi_4510_nd::read_decrypted(UINT16 adr) | |
| 440 | 113 | { |
| 441 | m4510_Regs *cpustate = (device != NULL && device->token() != NULL) ? get_safe_token(device) : NULL; | |
| 442 | ||
| 443 | switch (state) | |
| 444 | { | |
| 445 | /* --- the following bits of info are returned as 64-bit signed integers --- */ | |
| 446 | case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(m4510_Regs); break; | |
| 447 | case CPUINFO_INT_INPUT_LINES: info->i = 2; break; | |
| 448 | case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0; break; | |
| 449 | case CPUINFO_INT_ENDIANNESS: info->i = ENDIANNESS_LITTLE; break; | |
| 450 | case CPUINFO_INT_CLOCK_MULTIPLIER: info->i = 1; break; | |
| 451 | case CPUINFO_INT_CLOCK_DIVIDER: info->i = 1; break; | |
| 452 | case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 1; break; | |
| 453 | case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 3; break; | |
| 454 | case CPUINFO_INT_MIN_CYCLES: info->i = 1; break; | |
| 455 | case CPUINFO_INT_MAX_CYCLES: info->i = 10; break; | |
| 456 | ||
| 457 | case CPUINFO_INT_DATABUS_WIDTH + AS_PROGRAM: info->i = 8; break; | |
| 458 | case CPUINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 20; break; | |
| 459 | case CPUINFO_INT_ADDRBUS_SHIFT + AS_PROGRAM: info->i = 0; break; | |
| 460 | case CPUINFO_INT_LOGADDR_WIDTH_PROGRAM: info->i = 16; break; | |
| 461 | case CPUINFO_INT_PAGE_SHIFT_PROGRAM: info->i = 13; break; | |
| 462 | case CPUINFO_INT_DATABUS_WIDTH + AS_DATA: info->i = 0; break; | |
| 463 | case CPUINFO_INT_ADDRBUS_WIDTH + AS_DATA: info->i = 0; break; | |
| 464 | case CPUINFO_INT_ADDRBUS_SHIFT + AS_DATA: info->i = 0; break; | |
| 465 | case CPUINFO_INT_DATABUS_WIDTH + AS_IO: info->i = 0; break; | |
| 466 | case CPUINFO_INT_ADDRBUS_WIDTH + AS_IO: info->i = 0; break; | |
| 467 | case CPUINFO_INT_ADDRBUS_SHIFT + AS_IO: info->i = 0; break; | |
| 468 | ||
| 469 | case CPUINFO_INT_INPUT_STATE + M4510_IRQ_LINE: info->i = cpustate->irq_state; break; | |
| 470 | case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI: info->i = cpustate->nmi_state; break; | |
| 471 | ||
| 472 | case CPUINFO_INT_PREVIOUSPC: info->i = cpustate->ppc.w.l; break; | |
| 473 | ||
| 474 | case CPUINFO_INT_PC: info->i = PCD; break; | |
| 475 | case CPUINFO_INT_REGISTER + M4510_PC: info->i = cpustate->pc.w.l; break; | |
| 476 | case CPUINFO_INT_SP: info->i = SPL; break; | |
| 477 | case CPUINFO_INT_REGISTER + M4510_S: info->i = cpustate->sp.b.l; break; | |
| 478 | case CPUINFO_INT_REGISTER + M4510_P: info->i = cpustate->p; break; | |
| 479 | case CPUINFO_INT_REGISTER + M4510_A: info->i = cpustate->a; break; | |
| 480 | case CPUINFO_INT_REGISTER + M4510_X: info->i = cpustate->x; break; | |
| 481 | case CPUINFO_INT_REGISTER + M4510_Y: info->i = cpustate->y; break; | |
| 482 | case CPUINFO_INT_REGISTER + M4510_Z: info->i = cpustate->z; break; | |
| 483 | case CPUINFO_INT_REGISTER + M4510_B: info->i = cpustate->zp.b.h; break; | |
| 484 | case CPUINFO_INT_REGISTER + M4510_MEM_LOW: info->i = cpustate->low; break; | |
| 485 | case CPUINFO_INT_REGISTER + M4510_MEM_HIGH: info->i = cpustate->high; break; | |
| 486 | case CPUINFO_INT_REGISTER + M4510_EA: info->i = cpustate->ea.w.l; break; | |
| 487 | case CPUINFO_INT_REGISTER + M4510_ZP: info->i = cpustate->zp.w.l; break; | |
| 488 | case CPUINFO_INT_REGISTER + M4510_MEM0: info->i = cpustate->mem[0]; break; | |
| 489 | case CPUINFO_INT_REGISTER + M4510_MEM1: info->i = cpustate->mem[1]; break; | |
| 490 | case CPUINFO_INT_REGISTER + M4510_MEM2: info->i = cpustate->mem[2]; break; | |
| 491 | case CPUINFO_INT_REGISTER + M4510_MEM3: info->i = cpustate->mem[3]; break; | |
| 492 | case CPUINFO_INT_REGISTER + M4510_MEM4: info->i = cpustate->mem[4]; break; | |
| 493 | case CPUINFO_INT_REGISTER + M4510_MEM5: info->i = cpustate->mem[5]; break; | |
| 494 | case CPUINFO_INT_REGISTER + M4510_MEM6: info->i = cpustate->mem[6]; break; | |
| 495 | case CPUINFO_INT_REGISTER + M4510_MEM7: info->i = cpustate->mem[7]; break; | |
| 496 | ||
| 497 | /* --- the following bits of info are returned as pointers to data or functions --- */ | |
| 498 | case CPUINFO_FCT_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(m4510); break; | |
| 499 | case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(m4510); break; | |
| 500 | case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(m4510); break; | |
| 501 | case CPUINFO_FCT_EXIT: info->exit = CPU_EXIT_NAME(m4510); break; | |
| 502 | case CPUINFO_FCT_EXECUTE: info->execute = CPU_EXECUTE_NAME(m4510); break; | |
| 503 | case CPUINFO_FCT_BURN: info->burn = NULL; break; | |
| 504 | case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(m4510); break; | |
| 505 | case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &cpustate->icount; break; | |
| 506 | case CPUINFO_PTR_INTERNAL_MEMORY_MAP + AS_PROGRAM: info->internal_map8 = ADDRESS_MAP_NAME(m4510_mem); break; | |
| 507 | case CPUINFO_FCT_TRANSLATE: info->translate = CPU_TRANSLATE_NAME(m4510); break; | |
| 508 | ||
| 509 | /* --- the following bits of info are returned as NULL-terminated strings --- */ | |
| 510 | case CPUINFO_STR_NAME: strcpy(info->s, "M4510"); break; | |
| 511 | case CPUINFO_STR_FAMILY: strcpy(info->s, "CBM Semiconductor Group CSG 65CE02"); break; | |
| 512 | case CPUINFO_STR_VERSION: strcpy(info->s, "1.0beta"); break; | |
| 513 | case CPUINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break; | |
| 514 | case CPUINFO_STR_CREDITS: strcpy(info->s, "Copyright Juergen Buchmueller\nCopyright Peter Trauner\nall rights reserved."); break; | |
| 515 | ||
| 516 | case CPUINFO_STR_FLAGS: | |
| 517 | sprintf(info->s, "%c%c%c%c%c%c%c%c", | |
| 518 | cpustate->p & 0x80 ? 'N':'.', | |
| 519 | cpustate->p & 0x40 ? 'V':'.', | |
| 520 | cpustate->p & 0x20 ? 'R':'.', | |
| 521 | cpustate->p & 0x10 ? 'B':'.', | |
| 522 | cpustate->p & 0x08 ? 'D':'.', | |
| 523 | cpustate->p & 0x04 ? 'I':'.', | |
| 524 | cpustate->p & 0x02 ? 'Z':'.', | |
| 525 | cpustate->p & 0x01 ? 'C':'.'); | |
| 526 | break; | |
| 527 | ||
| 528 | case CPUINFO_STR_REGISTER + M4510_PC: sprintf(info->s, "PC:%04X", cpustate->pc.w.l); break; | |
| 529 | case CPUINFO_STR_REGISTER + M4510_S: sprintf(info->s, "S:%02X", cpustate->sp.b.l); break; | |
| 530 | case CPUINFO_STR_REGISTER + M4510_P: sprintf(info->s, "P:%02X", cpustate->p); break; | |
| 531 | case CPUINFO_STR_REGISTER + M4510_A: sprintf(info->s, "A:%02X", cpustate->a); break; | |
| 532 | case CPUINFO_STR_REGISTER + M4510_X: sprintf(info->s, "X:%02X", cpustate->x); break; | |
| 533 | case CPUINFO_STR_REGISTER + M4510_Y: sprintf(info->s, "Y:%02X", cpustate->y); break; | |
| 534 | case CPUINFO_STR_REGISTER + M4510_Z: sprintf(info->s, "Z:%02X", cpustate->z); break; | |
| 535 | case CPUINFO_STR_REGISTER + M4510_B: sprintf(info->s, "B:%02X", cpustate->zp.b.h); break; | |
| 536 | case CPUINFO_STR_REGISTER + M4510_MEM_LOW: sprintf(info->s, "M0:%01X", cpustate->low); break; | |
| 537 | case CPUINFO_STR_REGISTER + M4510_MEM_HIGH: sprintf(info->s, "M1:%01X", cpustate->high); break; | |
| 538 | case CPUINFO_STR_REGISTER + M4510_EA: sprintf(info->s, "EA:%04X", cpustate->ea.w.l); break; | |
| 539 | case CPUINFO_STR_REGISTER + M4510_ZP: sprintf(info->s, "ZP:%03X", cpustate->zp.w.l); break; | |
| 540 | } | |
| 114 | return read(adr); | |
| 541 | 115 | } |
| 542 | 116 | |
| 543 | #undef M4510 | |
| 544 | DEFINE_LEGACY_CPU_DEVICE(M4510, m4510); | |
| 117 | #include "cpu/m6502/m4510.inc" |
| r18874 | r18875 | |
|---|---|---|
| 1 | # n2a03 - D flag is disabled but present in the P register | |
| 2 | brk_imp ora_idx kil_non slo_idx nop_zpg ora_zpg asl_zpg slo_zpg php_imp ora_imm asl_acc anc_imm nop_aba ora_aba asl_aba slo_aba | |
| 3 | bpl_rel ora_idy kil_non slo_idy nop_zpx ora_zpx asl_zpx slo_zpx clc_imp ora_aby nop_imp slo_aby nop_abx ora_abx asl_abx slo_abx | |
| 4 | jsr_adr and_idx kil_non rla_idx bit_zpg and_zpg rol_zpg rla_zpg plp_imp and_imm rol_acc anc_imm bit_aba and_aba rol_aba rla_aba | |
| 5 | bmi_rel and_idy kil_non rla_idy nop_zpx and_zpx rol_zpx rla_zpx sec_imp and_aby nop_imp rla_aby nop_abx and_abx rol_abx rla_abx | |
| 6 | rti_imp eor_idx kil_non sre_idx nop_zpg eor_zpg lsr_zpg sre_zpg pha_imp eor_imm lsr_acc asr_imm jmp_adr eor_aba lsr_aba sre_aba | |
| 7 | bvc_rel eor_idy kil_non sre_idy nop_zpx eor_zpx lsr_zpx sre_zpx cli_imp eor_aby nop_imp sre_aby nop_abx eor_abx lsr_abx sre_abx | |
| 8 | rts_imp adc_nd_idx kil_non rra_nd_idx nop_zpg adc_nd_zpg ror_zpg rra_nd_zpg pla_imp adc_nd_imm ror_acc arr_nd_imm jmp_ind adc_nd_aba ror_aba rra_nd_aba | |
| 9 | bvs_rel adc_nd_idy kil_non rra_nd_idy nop_zpx adc_nd_zpx ror_zpx rra_nd_zpx sei_imp adc_nd_aby nop_imp rra_nd_aby nop_abx adc_nd_abx ror_abx rra_nd_abx | |
| 10 | nop_imp sta_idx nop_imm sax_idx sty_zpg sta_zpg stx_zpg sax_zpg dey_imp nop_imm txa_imp ane_imm sty_aba sta_aba stx_aba sax_aba | |
| 11 | bcc_rel sta_idy kil_non sha_idy sty_zpx sta_zpx stx_zpy sax_zpy tya_imp sta_aby txs_imp shs_aby shy_abx sta_abx shx_aby sha_aby | |
| 12 | ldy_imm lda_idx ldx_imm lax_idx ldy_zpg lda_zpg ldx_zpg lax_zpg tay_imp lda_imm tax_imp lxa_imm ldy_aba lda_aba ldx_aba lax_aba | |
| 13 | bcs_rel lda_idy kil_non lax_idy ldy_zpx lda_zpx ldx_zpy lax_zpy clv_imp lda_aby tsx_imp las_aby ldy_abx lda_abx ldx_aby lax_aby | |
| 14 | cpy_imm cmp_idx nop_imm dcp_idx cpy_zpg cmp_zpg dec_zpg dcp_zpg iny_imp cmp_imm dex_imp sbx_imm cpy_aba cmp_aba dec_aba dcp_aba | |
| 15 | bne_rel cmp_idy kil_non dcp_idy nop_zpx cmp_zpx dec_zpx dcp_zpx cld_imp cmp_aby nop_imp dcp_aby nop_abx cmp_abx dec_abx dcp_abx | |
| 16 | cpx_imm sbc_nd_idx nop_imm isb_nd_idx cpx_zpg sbc_nd_zpg inc_zpg isb_nd_zpg inx_imp sbc_nd_imm nop_imp sbc_nd_imm cpx_aba sbc_nd_aba inc_aba isb_nd_aba | |
| 17 | beq_rel sbc_nd_idy kil_non isb_nd_idy nop_zpx sbc_nd_zpx inc_zpx isb_nd_zpx sed_imp sbc_nd_aby nop_imp isb_nd_aby nop_abx sbc_nd_abx inc_abx isb_nd_abx | |
| 18 | reset |
| r18874 | r18875 | |
|---|---|---|
| 1 | #include <stdio.h> | |
| 2 | #include <stdlib.h> | |
| 3 | #include <string.h> | |
| 4 | #include <assert.h> | |
| 5 | #include <stdarg.h> | |
| 6 | #include <ctype.h> | |
| 7 | #include "osdcomm.h" | |
| 8 | ||
| 9 | #include <string> | |
| 10 | #include <vector> | |
| 11 | ||
| 12 | using namespace std; | |
| 13 | ||
| 14 | enum { STATES = 0x101 }; | |
| 15 | ||
| 16 | const char *snames[STATES-0x100] = { | |
| 17 | "STATE_RESET" | |
| 18 | }; | |
| 19 | ||
| 20 | struct opcode { | |
| 21 | string name; | |
| 22 | vector<string> instructions; | |
| 23 | }; | |
| 24 | ||
| 25 | vector<opcode> opcodes; | |
| 26 | ||
| 27 | struct table_t { | |
| 28 | string opcodes[STATES]; | |
| 29 | }; | |
| 30 | ||
| 31 | table_t table; | |
| 32 | ||
| 33 | string device_name; | |
| 34 | ||
| 35 | static void load_opcodes(const char *fname) | |
| 36 | { | |
| 37 | char buf[4096]; | |
| 38 | FILE *f; | |
| 39 | ||
| 40 | sprintf(buf, "Error opening %s for reading\n", fname); | |
| 41 | f = fopen(fname, "r"); | |
| 42 | if(!f) { | |
| 43 | perror(buf); | |
| 44 | exit(1); | |
| 45 | } | |
| 46 | ||
| 47 | while(fgets(buf, sizeof(buf), f)) { | |
| 48 | char *p = buf; | |
| 49 | if(p[0] == '#' || p[0] == '\r' || p[0] == '\n' || p[0] == 0) | |
| 50 | continue; | |
| 51 | ||
| 52 | for(char *q = p; *q; q++) | |
| 53 | if(*q == '\r' || *q == '\n') { | |
| 54 | *q = 0; | |
| 55 | break; | |
| 56 | } | |
| 57 | ||
| 58 | if(p[0] != ' ' && p[0] != '\t') { | |
| 59 | opcodes.resize(opcodes.size()+1); | |
| 60 | opcodes.back().name = p; | |
| 61 | } else | |
| 62 | opcodes.back().instructions.push_back(p); | |
| 63 | } | |
| 64 | fclose(f); | |
| 65 | } | |
| 66 | ||
| 67 | static void load_disp(const char *fname) | |
| 68 | { | |
| 69 | char buf[4096]; | |
| 70 | FILE *f; | |
| 71 | ||
| 72 | sprintf(buf, "Error opening %s for reading\n", fname); | |
| 73 | f = fopen(fname, "r"); | |
| 74 | if(!f) { | |
| 75 | perror(buf); | |
| 76 | exit(1); | |
| 77 | } | |
| 78 | ||
| 79 | int state = 0; | |
| 80 | ||
| 81 | while(fgets(buf, sizeof(buf), f)) { | |
| 82 | char *p = buf; | |
| 83 | if(p[0] == '#' || p[0] == '\r' || p[0] == '\n' || p[0] == 0) | |
| 84 | continue; | |
| 85 | ||
| 86 | while(state < STATES) { | |
| 87 | while(*p && (*p == '\n' || *p == '\r' || *p == ' ' || *p == '\t')) | |
| 88 | p++; | |
| 89 | if(!*p) | |
| 90 | break; | |
| 91 | ||
| 92 | char *q = p; | |
| 93 | while(*p != '\n' && *p != '\r' && *p != ' ' && *p != '\t') | |
| 94 | p++; | |
| 95 | table.opcodes[state++] = string(q, p); | |
| 96 | } | |
| 97 | } | |
| 98 | fclose(f); | |
| 99 | } | |
| 100 | ||
| 101 | enum { NONE, EAT_ALL, MEMORY }; | |
| 102 | ||
| 103 | static int identify_line_type(string inst) | |
| 104 | { | |
| 105 | if(inst.find("eat-all-cycles") != string::npos) | |
| 106 | return EAT_ALL; | |
| 107 | if(inst.find("read") != string::npos || | |
| 108 | inst.find("write") != string::npos || | |
| 109 | inst.find("prefetch(") != string::npos || | |
| 110 | inst.find("prefetch_noirq(") != string::npos) | |
| 111 | return MEMORY; | |
| 112 | return NONE; | |
| 113 | } | |
| 114 | ||
| 115 | static void save_opcodes(FILE *f) | |
| 116 | { | |
| 117 | for(unsigned int i=0; i != opcodes.size(); i++) { | |
| 118 | int substate; | |
| 119 | opcode &o = opcodes[i]; | |
| 120 | ||
| 121 | fprintf(f, "void %s::%s_full()\n", device_name.c_str(), o.name.c_str()); | |
| 122 | fprintf(f, "{\n"); | |
| 123 | substate = 1; | |
| 124 | for(unsigned int j=0; j != o.instructions.size(); j++) { | |
| 125 | string inst = o.instructions[j]; | |
| 126 | int type = identify_line_type(inst); | |
| 127 | if(type == EAT_ALL) { | |
| 128 | fprintf(f, "\ticount=0; inst_substate = %d; return;", substate); | |
| 129 | substate++; | |
| 130 | } else { | |
| 131 | if(type == MEMORY) | |
| 132 | fprintf(f, "\tif(icount == 0) { inst_substate = %d; return; }\n", substate); | |
| 133 | fprintf(f, "%s\n", inst.c_str()); | |
| 134 | if(type == MEMORY) { | |
| 135 | fprintf(f, "\ticount--;\n"); | |
| 136 | substate++; | |
| 137 | } | |
| 138 | } | |
| 139 | } | |
| 140 | fprintf(f, "}\n"); | |
| 141 | ||
| 142 | fprintf(f, "void %s::%s_partial()\n", device_name.c_str(), o.name.c_str()); | |
| 143 | fprintf(f, "{\n"); | |
| 144 | fprintf(f, "switch(inst_substate) {\n"); | |
| 145 | fprintf(f, "case 0:\n"); | |
| 146 | substate = 1; | |
| 147 | for(unsigned int j=0; j != o.instructions.size(); j++) { | |
| 148 | string inst = o.instructions[j]; | |
| 149 | int type = identify_line_type(inst); | |
| 150 | if(type == EAT_ALL) { | |
| 151 | fprintf(f, "\ticount=0; inst_substate = %d; return;", substate); | |
| 152 | fprintf(f, "case %d:;\n", substate); | |
| 153 | substate++; | |
| 154 | } else { | |
| 155 | if(type == MEMORY) { | |
| 156 | fprintf(f, "\tif(icount == 0) { inst_substate = %d; return; }\n", substate); | |
| 157 | fprintf(f, "case %d:\n", substate); | |
| 158 | } | |
| 159 | fprintf(f, "%s\n", inst.c_str()); | |
| 160 | if(type == MEMORY) { | |
| 161 | fprintf(f, "\ticount--;\n"); | |
| 162 | substate++; | |
| 163 | } | |
| 164 | } | |
| 165 | } | |
| 166 | fprintf(f, "}\n"); | |
| 167 | fprintf(f, "\tinst_substate = 0;\n"); | |
| 168 | fprintf(f, "}\n"); | |
| 169 | fprintf(f, "\n"); | |
| 170 | } | |
| 171 | fprintf(f, "\n"); | |
| 172 | } | |
| 173 | ||
| 174 | static void save_tables(FILE *f) | |
| 175 | { | |
| 176 | fprintf(f, "void %s::do_exec_full()\n", device_name.c_str()); | |
| 177 | fprintf(f, "{\n"); | |
| 178 | fprintf(f, "\tswitch(inst_state) {\n"); | |
| 179 | for(int j=0; j<STATES; j++) { | |
| 180 | if(table.opcodes[j] != ".") { | |
| 181 | if(j < 0x100) | |
| 182 | fprintf(f, "\tcase 0x%02x: %s_full(); break;\n", j, table.opcodes[j].c_str()); | |
| 183 | else | |
| 184 | fprintf(f, "\tcase %s: %s_full(); break;\n", snames[j-0x100], table.opcodes[j].c_str()); | |
| 185 | } | |
| 186 | } | |
| 187 | fprintf(f, "\t}\n"); | |
| 188 | fprintf(f, "}\n"); | |
| 189 | fprintf(f, "void %s::do_exec_partial()\n", device_name.c_str()); | |
| 190 | fprintf(f, "{\n"); | |
| 191 | fprintf(f, "\tswitch(inst_state) {\n"); | |
| 192 | for(int j=0; j<STATES; j++) { | |
| 193 | if(table.opcodes[j] != ".") { | |
| 194 | if(j < 0x100) | |
| 195 | fprintf(f, "\tcase 0x%02x: %s_partial(); break;\n", j, table.opcodes[j].c_str()); | |
| 196 | else | |
| 197 | fprintf(f, "\tcase %s: %s_partial(); break;\n", snames[j-0x100], table.opcodes[j].c_str()); | |
| 198 | } | |
| 199 | } | |
| 200 | fprintf(f, "\t}\n"); | |
| 201 | fprintf(f, "}\n"); | |
| 202 | fprintf(f, "const %s::disasm_entry %s::disasm_entries[0x100] = {\n", device_name.c_str(), device_name.c_str()); | |
| 203 | for(int j=0; j<0x100; j++) | |
| 204 | if(table.opcodes[j] != ".") { | |
| 205 | string opcode = table.opcodes[j]; | |
| 206 | string opc, fullopc, mode; | |
| 207 | string::iterator k, ke; | |
| 208 | for(k = opcode.begin(); k != opcode.end() && *k != '_'; k++); | |
| 209 | for(ke = opcode.end(); ke != opcode.begin() && ke[-1] != '_'; ke--); | |
| 210 | assert(k != opcode.end()); | |
| 211 | opc = string(opcode.begin(), k); | |
| 212 | fullopc = string(opcode.begin(), ke-1); | |
| 213 | mode = string(ke, opcode.end()); | |
| 214 | ||
| 215 | bool step_over = opc == "jsr" || opc == "bsr"; | |
| 216 | bool step_out = opc == "rts" || opc == "rti" || opc == "rtn"; | |
| 217 | bool per_bit = opc == "bbr" || opc == "bbs" || opc == "rmb" || opc == "smb"; | |
| 218 | fprintf(f, "\t{ \"%s\", DASM_%s, %s, %s },\n", | |
| 219 | opc.c_str(), mode.c_str(), step_over ? "DASMFLAG_STEP_OVER" : step_out ? "DASMFLAG_STEP_OUT" : "0", | |
| 220 | per_bit ? "true" : "false"); | |
| 221 | } else | |
| 222 | fprintf(f, "\t{ \"???\", DASM_imp, 0, false },\n"); | |
| 223 | fprintf(f, "};\n"); | |
| 224 | } | |
| 225 | ||
| 226 | static void save(const char *fname) | |
| 227 | { | |
| 228 | char buf[4096]; | |
| 229 | FILE *f; | |
| 230 | ||
| 231 | sprintf(buf, "Error opening %s for writing\n", fname); | |
| 232 | f = fopen(fname, "w"); | |
| 233 | if(!f) { | |
| 234 | perror(buf); | |
| 235 | exit(1); | |
| 236 | } | |
| 237 | ||
| 238 | save_opcodes(f); | |
| 239 | save_tables(f); | |
| 240 | ||
| 241 | fclose(f); | |
| 242 | } | |
| 243 | ||
| 244 | int main(int argc, char *argv[]) | |
| 245 | { | |
| 246 | if(argc != 5) { | |
| 247 | fprintf(stderr, "Usage:\n%s device_name {opc.lst|-} disp.lst device.inc\n", argv[0]); | |
| 248 | exit(1); | |
| 249 | } | |
| 250 | ||
| 251 | device_name = argv[1]; | |
| 252 | if(strcmp(argv[2], "-")) | |
| 253 | load_opcodes(argv[2]); | |
| 254 | load_disp(argv[3]); | |
| 255 | save(argv[4]); | |
| 256 | ||
| 257 | ||
| 258 | return 0; | |
| 259 | } |
| r18874 | r18875 | |
|---|---|---|
| 1 | # NMOS 6502 opcodes | |
| 2 | # Verified with visual6502 | |
| 3 | # documented opcodes | |
| 4 | ||
| 5 | adc_aba | |
| 6 | TMP = read_pc(); | |
| 7 | TMP = set_h(TMP, read_pc()); | |
| 8 | TMP = read(TMP); | |
| 9 | do_adc(TMP); | |
| 10 | prefetch(); | |
| 11 | ||
| 12 | adc_abx | |
| 13 | TMP = read_pc(); | |
| 14 | TMP = set_h(TMP, read_pc()); | |
| 15 | if(page_changing(TMP, X)) { | |
| 16 | read(set_l(TMP, TMP+X)); | |
| 17 | } | |
| 18 | TMP += X; | |
| 19 | TMP = read(TMP); | |
| 20 | do_adc(TMP); | |
| 21 | prefetch(); | |
| 22 | ||
| 23 | adc_aby | |
| 24 | TMP = read_pc(); | |
| 25 | TMP = set_h(TMP, read_pc()); | |
| 26 | if(page_changing(TMP, Y)) { | |
| 27 | read(set_l(TMP, TMP+Y)); | |
| 28 | } | |
| 29 | TMP += Y; | |
| 30 | TMP = read(TMP); | |
| 31 | do_adc(TMP); | |
| 32 | prefetch(); | |
| 33 | ||
| 34 | adc_idx | |
| 35 | TMP2 = read_pc(); | |
| 36 | read(TMP2); | |
| 37 | TMP2 += X; | |
| 38 | TMP = read(TMP2 & 0xff); | |
| 39 | TMP = set_h(TMP, read((TMP2+1) & 0xff)); | |
| 40 | do_adc(read(TMP)); | |
| 41 | prefetch(); | |
| 42 | ||
| 43 | adc_idy | |
| 44 | TMP2 = read_pc(); | |
| 45 | TMP = read(TMP2); | |
| 46 | TMP = set_h(TMP, read(TMP2+1)); | |
| 47 | if(page_changing(TMP, Y)) { | |
| 48 | read(set_l(TMP, TMP+Y)); | |
| 49 | } | |
| 50 | do_adc(read(TMP+Y)); | |
| 51 | prefetch(); | |
| 52 | ||
| 53 | adc_imm | |
| 54 | TMP = read_pc(); | |
| 55 | do_adc(TMP); | |
| 56 | prefetch(); | |
| 57 | ||
| 58 | adc_zpg | |
| 59 | TMP = read_pc(); | |
| 60 | TMP = read(TMP); | |
| 61 | do_adc(TMP); | |
| 62 | prefetch(); | |
| 63 | ||
| 64 | adc_zpx | |
| 65 | TMP = read_pc(); | |
| 66 | read(TMP); | |
| 67 | TMP = read(UINT8(TMP+X)); | |
| 68 | do_adc(TMP); | |
| 69 | prefetch(); | |
| 70 | ||
| 71 | and_aba | |
| 72 | TMP = read_pc(); | |
| 73 | TMP = set_h(TMP, read_pc()); | |
| 74 | A &= read(TMP); | |
| 75 | set_nz(A); | |
| 76 | prefetch(); | |
| 77 | ||
| 78 | and_abx | |
| 79 | TMP = read_pc(); | |
| 80 | TMP = set_h(TMP, read_pc()); | |
| 81 | if(page_changing(TMP, X)) { | |
| 82 | read(set_l(TMP, TMP+X)); | |
| 83 | } | |
| 84 | TMP += X; | |
| 85 | A &= read(TMP); | |
| 86 | set_nz(A); | |
| 87 | prefetch(); | |
| 88 | ||
| 89 | and_aby | |
| 90 | TMP = read_pc(); | |
| 91 | TMP = set_h(TMP, read_pc()); | |
| 92 | if(page_changing(TMP, Y)) { | |
| 93 | read(set_l(TMP, TMP+Y)); | |
| 94 | } | |
| 95 | TMP += Y; | |
| 96 | A &= read(TMP); | |
| 97 | set_nz(A); | |
| 98 | prefetch(); | |
| 99 | ||
| 100 | and_imm | |
| 101 | A &= read_pc(); | |
| 102 | set_nz(A); | |
| 103 | prefetch(); | |
| 104 | ||
| 105 | and_idx | |
| 106 | TMP2 = read_pc(); | |
| 107 | read(TMP2); | |
| 108 | TMP2 += X; | |
| 109 | TMP = read(TMP2 & 0xff); | |
| 110 | TMP = set_h(TMP, read((TMP2+1) & 0xff)); | |
| 111 | A &= read(TMP); | |
| 112 | set_nz(A); | |
| 113 | prefetch(); | |
| 114 | ||
| 115 | and_idy | |
| 116 | TMP2 = read_pc(); | |
| 117 | TMP = read(TMP2); | |
| 118 | TMP = set_h(TMP, read(TMP2+1)); | |
| 119 | if(page_changing(TMP, Y)) { | |
| 120 | read(set_l(TMP, TMP+Y)); | |
| 121 | } | |
| 122 | A &= read(TMP+Y); | |
| 123 | set_nz(A); | |
| 124 | prefetch(); | |
| 125 | ||
| 126 | and_zpg | |
| 127 | TMP = read_pc(); | |
| 128 | A &= read(TMP); | |
| 129 | set_nz(A); | |
| 130 | prefetch(); | |
| 131 | ||
| 132 | and_zpx | |
| 133 | TMP = read_pc(); | |
| 134 | read(TMP); | |
| 135 | A &= read(UINT8(TMP+X)); | |
| 136 | set_nz(A); | |
| 137 | prefetch(); | |
| 138 | ||
| 139 | asl_aba | |
| 140 | TMP = read_pc(); | |
| 141 | TMP = set_h(TMP, read_pc()); | |
| 142 | TMP2 = read(TMP); | |
| 143 | write(TMP, TMP2); | |
| 144 | TMP2 = do_asl(TMP2); | |
| 145 | write(TMP, TMP2); | |
| 146 | prefetch(); | |
| 147 | ||
| 148 | asl_abx | |
| 149 | TMP = read_pc(); | |
| 150 | TMP = set_h(TMP, read_pc()); | |
| 151 | read(set_l(TMP, TMP+X)); | |
| 152 | TMP += X; | |
| 153 | TMP2 = read(TMP); | |
| 154 | write(TMP, TMP2); | |
| 155 | TMP2 = do_asl(TMP2); | |
| 156 | write(TMP, TMP2); | |
| 157 | prefetch(); | |
| 158 | ||
| 159 | asl_acc | |
| 160 | read_pc_noinc(); | |
| 161 | A = do_asl(A); | |
| 162 | prefetch(); | |
| 163 | ||
| 164 | asl_zpg | |
| 165 | TMP = read_pc(); | |
| 166 | TMP2 = read(TMP); | |
| 167 | write(TMP, TMP2); | |
| 168 | TMP2 = do_asl(TMP2); | |
| 169 | write(TMP, TMP2); | |
| 170 | prefetch(); | |
| 171 | ||
| 172 | asl_zpx | |
| 173 | TMP = read_pc(); | |
| 174 | read(TMP); | |
| 175 | TMP = UINT8(TMP+X); | |
| 176 | TMP2 = read(TMP); | |
| 177 | write(TMP, TMP2); | |
| 178 | TMP2 = do_asl(TMP2); | |
| 179 | write(TMP, TMP2); | |
| 180 | prefetch(); | |
| 181 | ||
| 182 | bcc_rel | |
| 183 | TMP = read_pc(); | |
| 184 | if(!(P & F_C)) { | |
| 185 | read_pc_noinc(); | |
| 186 | if(page_changing(PC, INT8(TMP))) { | |
| 187 | read_direct(set_l(PC, PC+INT8(TMP))); | |
| 188 | } | |
| 189 | PC += INT8(TMP); | |
| 190 | } | |
| 191 | prefetch(); | |
| 192 | ||
| 193 | bcs_rel | |
| 194 | TMP = read_pc(); | |
| 195 | if(P & F_C) { | |
| 196 | read_pc_noinc(); | |
| 197 | if(page_changing(PC, INT8(TMP))) { | |
| 198 | read_direct(set_l(PC, PC+INT8(TMP))); | |
| 199 | } | |
| 200 | PC += INT8(TMP); | |
| 201 | } | |
| 202 | prefetch(); | |
| 203 | ||
| 204 | beq_rel | |
| 205 | TMP = read_pc(); | |
| 206 | if(P & F_Z) { | |
| 207 | read_pc_noinc(); | |
| 208 | if(page_changing(PC, INT8(TMP))) { | |
| 209 | read_direct(set_l(PC, PC+INT8(TMP))); | |
| 210 | } | |
| 211 | PC += INT8(TMP); | |
| 212 | } | |
| 213 | prefetch(); | |
| 214 | ||
| 215 | bit_aba | |
| 216 | TMP = read_pc(); | |
| 217 | TMP = set_h(TMP, read_pc()); | |
| 218 | do_bit(read(TMP)); | |
| 219 | prefetch(); | |
| 220 | ||
| 221 | bit_zpg | |
| 222 | TMP = read_pc(); | |
| 223 | do_bit(read(TMP)); | |
| 224 | prefetch(); | |
| 225 | ||
| 226 | bmi_rel | |
| 227 | TMP = read_pc(); | |
| 228 | if(P & F_N) { | |
| 229 | read_pc_noinc(); | |
| 230 | if(page_changing(PC, INT8(TMP))) { | |
| 231 | read_direct(set_l(PC, PC+INT8(TMP))); | |
| 232 | } | |
| 233 | PC += INT8(TMP); | |
| 234 | } | |
| 235 | prefetch(); | |
| 236 | ||
| 237 | bne_rel | |
| 238 | TMP = read_pc(); | |
| 239 | if(!(P & F_Z)) { | |
| 240 | read_pc_noinc(); | |
| 241 | if(page_changing(PC, INT8(TMP))) { | |
| 242 | read_direct(set_l(PC, PC+INT8(TMP))); | |
| 243 | } | |
| 244 | PC += INT8(TMP); | |
| 245 | } | |
| 246 | prefetch(); | |
| 247 | ||
| 248 | bpl_rel | |
| 249 | TMP = read_pc(); | |
| 250 | if(!(P & F_N)) { | |
| 251 | read_pc_noinc(); | |
| 252 | if(page_changing(PC, INT8(TMP))) { | |
| 253 | read_direct(set_l(PC, PC+INT8(TMP))); | |
| 254 | } | |
| 255 | PC += INT8(TMP); | |
| 256 | } | |
| 257 | prefetch(); | |
| 258 | ||
| 259 | brk_imp | |
| 260 | // The 6502 bug when a nmi occurs in a brk is reproduced (case !irq_taken && nmi_state) | |
| 261 | if(irq_taken) { | |
| 262 | read_pc_noinc(); | |
| 263 | } else { | |
| 264 | read_pc(); | |
| 265 | } | |
| 266 | write(SP, PC >> 8); | |
| 267 | dec_SP(); | |
| 268 | write(SP, PC); | |
| 269 | dec_SP(); | |
| 270 | write(SP, irq_taken ? P & ~F_B : P); | |
| 271 | dec_SP(); | |
| 272 | if(nmi_state) { | |
| 273 | PC = read_direct(0xfffa); | |
| 274 | PC = set_h(PC, read_direct(0xfffb)); | |
| 275 | nmi_state = false; | |
| 276 | } else { | |
| 277 | PC = read_direct(0xfffe); | |
| 278 | PC = set_h(PC, read_direct(0xffff)); | |
| 279 | } | |
| 280 | irq_taken = false; | |
| 281 | P |= F_I; // Do *not* move after the prefetch | |
| 282 | prefetch(); | |
| 283 | inst_state = -1; | |
| 284 | ||
| 285 | bvc_rel | |
| 286 | TMP = read_pc(); | |
| 287 | if(!(P & F_V)) { | |
| 288 | read_pc_noinc(); | |
| 289 | if(page_changing(PC, INT8(TMP))) { | |
| 290 | read_direct(set_l(PC, PC+INT8(TMP))); | |
| 291 | } | |
| 292 | PC += INT8(TMP); | |
| 293 | } | |
| 294 | prefetch(); | |
| 295 | ||
| 296 | bvs_rel | |
| 297 | TMP = read_pc(); | |
| 298 | if(P & F_V) { | |
| 299 | read_pc_noinc(); | |
| 300 | if(page_changing(PC, INT8(TMP))) { | |
| 301 | read_direct(set_l(PC, PC+INT8(TMP))); | |
| 302 | } | |
| 303 | PC += INT8(TMP); | |
| 304 | } | |
| 305 | prefetch(); | |
| 306 | ||
| 307 | clc_imp | |
| 308 | read_pc_noinc(); | |
| 309 | P &= ~F_C; | |
| 310 | prefetch(); | |
| 311 | ||
| 312 | cld_imp | |
| 313 | read_pc_noinc(); | |
| 314 | P &= ~F_D; | |
| 315 | prefetch(); | |
| 316 | ||
| 317 | cli_imp | |
| 318 | read_pc_noinc(); | |
| 319 | prefetch(); | |
| 320 | P &= ~F_I; // Do *not* move it before the prefetch | |
| 321 | ||
| 322 | clv_imp | |
| 323 | read_pc_noinc(); | |
| 324 | P &= ~F_V; | |
| 325 | prefetch(); | |
| 326 | ||
| 327 | cmp_aba | |
| 328 | TMP = read_pc(); | |
| 329 | TMP = set_h(TMP, read_pc()); | |
| 330 | TMP = read(TMP); | |
| 331 | do_cmp(A, TMP); | |
| 332 | prefetch(); | |
| 333 | ||
| 334 | cmp_abx | |
| 335 | TMP = read_pc(); | |
| 336 | TMP = set_h(TMP, read_pc()); | |
| 337 | if(page_changing(TMP, X)) { | |
| 338 | read(set_l(TMP, TMP+X)); | |
| 339 | } | |
| 340 | TMP += X; | |
| 341 | TMP = read(TMP); | |
| 342 | do_cmp(A, TMP); | |
| 343 | prefetch(); | |
| 344 | ||
| 345 | cmp_aby | |
| 346 | TMP = read_pc(); | |
| 347 | TMP = set_h(TMP, read_pc()); | |
| 348 | if(page_changing(TMP, Y)) { | |
| 349 | read(set_l(TMP, TMP+Y)); | |
| 350 | } | |
| 351 | TMP += Y; | |
| 352 | TMP = read(TMP); | |
| 353 | do_cmp(A, TMP); | |
| 354 | prefetch(); | |
| 355 | ||
| 356 | cmp_idx | |
| 357 | TMP2 = read_pc(); | |
| 358 | read(TMP2); | |
| 359 | TMP2 += X; | |
| 360 | TMP = read(TMP2 & 0xff); | |
| 361 | TMP = set_h(TMP, read((TMP2+1) & 0xff)); | |
| 362 | do_cmp(A, read(TMP)); | |
| 363 | prefetch(); | |
| 364 | ||
| 365 | cmp_idy | |
| 366 | TMP2 = read_pc(); | |
| 367 | TMP = read(TMP2); | |
| 368 | TMP = set_h(TMP, read(TMP2+1)); | |
| 369 | if(page_changing(TMP, Y)) { | |
| 370 | read(set_l(TMP, TMP+Y)); | |
| 371 | } | |
| 372 | do_cmp(A, read(TMP+Y)); | |
| 373 | prefetch(); | |
| 374 | ||
| 375 | cmp_imm | |
| 376 | TMP = read_pc(); | |
| 377 | do_cmp(A, TMP); | |
| 378 | prefetch(); | |
| 379 | ||
| 380 | cmp_zpg | |
| 381 | TMP = read_pc(); | |
| 382 | TMP = read(TMP); | |
| 383 | do_cmp(A, TMP); | |
| 384 | prefetch(); | |
| 385 | ||
| 386 | cmp_zpx | |
| 387 | TMP = read_pc(); | |
| 388 | read(TMP); | |
| 389 | TMP = read(UINT8(TMP+X)); | |
| 390 | do_cmp(A, TMP); | |
| 391 | prefetch(); | |
| 392 | ||
| 393 | cpx_aba | |
| 394 | TMP = read_pc(); | |
| 395 | TMP = set_h(TMP, read_pc()); | |
| 396 | TMP = read(TMP); | |
| 397 | do_cmp(X, TMP); | |
| 398 | prefetch(); | |
| 399 | ||
| 400 | cpx_imm | |
| 401 | TMP = read_pc(); | |
| 402 | do_cmp(X, TMP); | |
| 403 | prefetch(); | |
| 404 | ||
| 405 | cpx_zpg | |
| 406 | TMP = read_pc(); | |
| 407 | TMP = read(TMP); | |
| 408 | do_cmp(X, TMP); | |
| 409 | prefetch(); | |
| 410 | ||
| 411 | cpy_aba | |
| 412 | TMP = read_pc(); | |
| 413 | TMP = set_h(TMP, read_pc()); | |
| 414 | TMP = read(TMP); | |
| 415 | do_cmp(Y, TMP); | |
| 416 | prefetch(); | |
| 417 | ||
| 418 | cpy_imm | |
| 419 | TMP = read_pc(); | |
| 420 | do_cmp(Y, TMP); | |
| 421 | prefetch(); | |
| 422 | ||
| 423 | cpy_zpg | |
| 424 | TMP = read_pc(); | |
| 425 | TMP = read(TMP); | |
| 426 | do_cmp(Y, TMP); | |
| 427 | prefetch(); | |
| 428 | ||
| 429 | dec_aba | |
| 430 | TMP = read_pc(); | |
| 431 | TMP = set_h(TMP, read_pc()); | |
| 432 | TMP2 = read(TMP); | |
| 433 | write(TMP, TMP2); | |
| 434 | TMP2--; | |
| 435 | set_nz(TMP2); | |
| 436 | write(TMP, TMP2); | |
| 437 | prefetch(); | |
| 438 | ||
| 439 | dec_abx | |
| 440 | TMP = read_pc(); | |
| 441 | TMP = set_h(TMP, read_pc()); | |
| 442 | read(set_l(TMP, TMP+X)); | |
| 443 | TMP += X; | |
| 444 | TMP2 = read(TMP); | |
| 445 | write(TMP, TMP2); | |
| 446 | TMP2--; | |
| 447 | set_nz(TMP2); | |
| 448 | write(TMP, TMP2); | |
| 449 | prefetch(); | |
| 450 | ||
| 451 | dec_zpg | |
| 452 | TMP = read_pc(); | |
| 453 | TMP2 = read(TMP); | |
| 454 | write(TMP, TMP2); | |
| 455 | TMP2--; | |
| 456 | set_nz(TMP2); | |
| 457 | write(TMP, TMP2); | |
| 458 | prefetch(); | |
| 459 | ||
| 460 | dec_zpx | |
| 461 | TMP = read_pc(); | |
| 462 | read(TMP); | |
| 463 | TMP = UINT8(TMP+X); | |
| 464 | TMP2 = read(TMP); | |
| 465 | write(TMP, TMP2); | |
| 466 | TMP2--; | |
| 467 | set_nz(TMP2); | |
| 468 | write(TMP, TMP2); | |
| 469 | prefetch(); | |
| 470 | ||
| 471 | dex_imp | |
| 472 | read_pc_noinc(); | |
| 473 | X--; | |
| 474 | set_nz(X); | |
| 475 | prefetch(); | |
| 476 | ||
| 477 | dey_imp | |
| 478 | read_pc_noinc(); | |
| 479 | Y--; | |
| 480 | set_nz(Y); | |
| 481 | prefetch(); | |
| 482 | ||
| 483 | eor_aba | |
| 484 | TMP = read_pc(); | |
| 485 | TMP = set_h(TMP, read_pc()); | |
| 486 | A ^= read(TMP); | |
| 487 | set_nz(A); | |
| 488 | prefetch(); | |
| 489 | ||
| 490 | eor_abx | |
| 491 | TMP = read_pc(); | |
| 492 | TMP = set_h(TMP, read_pc()); | |
| 493 | if(page_changing(TMP, X)) { | |
| 494 | read(set_l(TMP, TMP+X)); | |
| 495 | } | |
| 496 | TMP += X; | |
| 497 | A ^= read(TMP); | |
| 498 | set_nz(A); | |
| 499 | prefetch(); | |
| 500 | ||
| 501 | eor_aby | |
| 502 | TMP = read_pc(); | |
| 503 | TMP = set_h(TMP, read_pc()); | |
| 504 | if(page_changing(TMP, Y)) { | |
| 505 | read(set_l(TMP, TMP+Y)); | |
| 506 | } | |
| 507 | TMP += Y; | |
| 508 | A ^= read(TMP); | |
| 509 | set_nz(A); | |
| 510 | prefetch(); | |
| 511 | ||
| 512 | eor_idx | |
| 513 | TMP2 = read_pc(); | |
| 514 | read(TMP2); | |
| 515 | TMP2 += X; | |
| 516 | TMP = read(TMP2 & 0xff); | |
| 517 | TMP = set_h(TMP, read((TMP2+1) & 0xff)); | |
| 518 | A ^= read(TMP); | |
| 519 | set_nz(A); | |
| 520 | prefetch(); | |
| 521 | ||
| 522 | eor_idy | |
| 523 | TMP2 = read_pc(); | |
| 524 | TMP = read(TMP2); | |
| 525 | TMP = set_h(TMP, read(TMP2+1)); | |
| 526 | if(page_changing(TMP, Y)) { | |
| 527 | read(set_l(TMP, TMP+Y)); | |
| 528 | } | |
| 529 | A ^= read(TMP+Y); | |
| 530 | set_nz(A); | |
| 531 | prefetch(); | |
| 532 | ||
| 533 | eor_imm | |
| 534 | A ^= read_pc(); | |
| 535 | set_nz(A); | |
| 536 | prefetch(); | |
| 537 | ||
| 538 | eor_zpg | |
| 539 | TMP = read_pc(); | |
| 540 | A ^= read(TMP); | |
| 541 | set_nz(A); | |
| 542 | prefetch(); | |
| 543 | ||
| 544 | eor_zpx | |
| 545 | TMP = read_pc(); | |
| 546 | read(TMP); | |
| 547 | A ^= read(UINT8(TMP+X)); | |
| 548 | set_nz(A); | |
| 549 | prefetch(); | |
| 550 | ||
| 551 | inc_aba | |
| 552 | TMP = read_pc(); | |
| 553 | TMP = set_h(TMP, read_pc()); | |
| 554 | TMP2 = read(TMP); | |
| 555 | write(TMP, TMP2); | |
| 556 | TMP2++; | |
| 557 | set_nz(TMP2); | |
| 558 | write(TMP, TMP2); | |
| 559 | prefetch(); | |
| 560 | ||
| 561 | inc_abx | |
| 562 | TMP = read_pc(); | |
| 563 | TMP = set_h(TMP, read_pc()); | |
| 564 | read(set_l(TMP, TMP+X)); | |
| 565 | TMP += X; | |
| 566 | TMP2 = read(TMP); | |
| 567 | write(TMP, TMP2); | |
| 568 | TMP2++; | |
| 569 | set_nz(TMP2); | |
| 570 | write(TMP, TMP2); | |
| 571 | prefetch(); | |
| 572 | ||
| 573 | inc_zpg | |
| 574 | TMP = read_pc(); | |
| 575 | TMP2 = read(TMP); | |
| 576 | write(TMP, TMP2); | |
| 577 | TMP2++; | |
| 578 | set_nz(TMP2); | |
| 579 | write(TMP, TMP2); | |
| 580 | prefetch(); | |
| 581 | ||
| 582 | inc_zpx | |
| 583 | TMP = read_pc(); | |
| 584 | read(TMP); | |
| 585 | TMP = UINT8(TMP+X); | |
| 586 | TMP2 = read(TMP); | |
| 587 | write(TMP, TMP2); | |
| 588 | TMP2++; | |
| 589 | set_nz(TMP2); | |
| 590 | write(TMP, TMP2); | |
| 591 | prefetch(); | |
| 592 | ||
| 593 | inx_imp | |
| 594 | read_pc_noinc(); | |
| 595 | X++; | |
| 596 | set_nz(X); | |
| 597 | prefetch(); | |
| 598 | ||
| 599 | iny_imp | |
| 600 | read_pc_noinc(); | |
| 601 | Y++; | |
| 602 | set_nz(Y); | |
| 603 | prefetch(); | |
| 604 | ||
| 605 | jmp_adr | |
| 606 | TMP = read_pc(); | |
| 607 | TMP = set_h(TMP, read_pc()); | |
| 608 | PC = TMP; | |
| 609 | prefetch(); | |
| 610 | ||
| 611 | jmp_ind | |
| 612 | TMP = read_pc(); | |
| 613 | TMP = set_h(TMP, read_pc()); | |
| 614 | PC = read(TMP); | |
| 615 | PC = set_h(PC, read(set_l(TMP, TMP+1))); | |
| 616 | prefetch(); | |
| 617 | ||
| 618 | jsr_adr | |
| 619 | TMP = read_pc(); | |
| 620 | read(SP); | |
| 621 | write(SP, PC>>8); | |
| 622 | dec_SP(); | |
| 623 | write(SP, PC); | |
| 624 | dec_SP(); | |
| 625 | TMP = set_h(TMP, read_pc()); | |
| 626 | PC = TMP; | |
| 627 | prefetch(); | |
| 628 | ||
| 629 | lda_aba | |
| 630 | TMP = read_pc(); | |
| 631 | TMP = set_h(TMP, read_pc()); | |
| 632 | A = read(TMP); | |
| 633 | set_nz(A); | |
| 634 | prefetch(); | |
| 635 | ||
| 636 | lda_abx | |
| 637 | TMP = read_pc(); | |
| 638 | TMP = set_h(TMP, read_pc()); | |
| 639 | if(page_changing(TMP, X)) { | |
| 640 | read(set_l(TMP, TMP+X)); | |
| 641 | } | |
| 642 | A = read(TMP + X); | |
| 643 | set_nz(A); | |
| 644 | prefetch(); | |
| 645 | ||
| 646 | lda_aby | |
| 647 | TMP = read_pc(); | |
| 648 | TMP = set_h(TMP, read_pc()); | |
| 649 | if(page_changing(TMP, Y)) { | |
| 650 | read(set_l(TMP, TMP+Y)); | |
| 651 | } | |
| 652 | A = read(TMP + Y); | |
| 653 | set_nz(A); | |
| 654 | prefetch(); | |
| 655 | ||
| 656 | lda_idx | |
| 657 | TMP2 = read_pc(); | |
| 658 | read(TMP2); | |
| 659 | TMP2 += X; | |
| 660 | TMP = read(TMP2 & 0xff); | |
| 661 | TMP = set_h(TMP, read((TMP2+1) & 0xff)); | |
| 662 | A = read(TMP); | |
| 663 | set_nz(A); | |
| 664 | prefetch(); | |
| 665 | ||
| 666 | lda_idy | |
| 667 | TMP2 = read_pc(); | |
| 668 | TMP = read(TMP2); | |
| 669 | TMP = set_h(TMP, read(TMP2+1)); | |
| 670 | if(page_changing(TMP, Y)) { | |
| 671 | read(set_l(TMP, TMP+Y)); | |
| 672 | } | |
| 673 | A = read(TMP+Y); | |
| 674 | set_nz(A); | |
| 675 | prefetch(); | |
| 676 | ||
| 677 | lda_imm | |
| 678 | A = read_pc(); | |
| 679 | set_nz(A); | |
| 680 | prefetch(); | |
| 681 | ||
| 682 | lda_zpg | |
| 683 | TMP = read_pc(); | |
| 684 | A = read(TMP); | |
| 685 | set_nz(A); | |
| 686 | prefetch(); | |
| 687 | ||
| 688 | lda_zpx | |
| 689 | TMP = read_pc(); | |
| 690 | read(TMP); | |
| 691 | A = read(UINT8(TMP+X)); | |
| 692 | set_nz(A); | |
| 693 | prefetch(); | |
| 694 | ||
| 695 | ldx_aba | |
| 696 | TMP = read_pc(); | |
| 697 | TMP = set_h(TMP, read_pc()); | |
| 698 | X = read(TMP); | |
| 699 | set_nz(X); | |
| 700 | prefetch(); | |
| 701 | ||
| 702 | ldx_aby | |
| 703 | TMP = read_pc(); | |
| 704 | TMP = set_h(TMP, read_pc()); | |
| 705 | if(page_changing(TMP, Y)) { | |
| 706 | read(set_l(TMP, TMP+Y)); | |
| 707 | } | |
| 708 | X = read(TMP + Y); | |
| 709 | set_nz(X); | |
| 710 | prefetch(); | |
| 711 | ||
| 712 | ldx_imm | |
| 713 | X = read_pc(); | |
| 714 | set_nz(X); | |
| 715 | prefetch(); | |
| 716 | ||
| 717 | ldx_zpg | |
| 718 | TMP = read_pc(); | |
| 719 | X = read(TMP); | |
| 720 | set_nz(X); | |
| 721 | prefetch(); | |
| 722 | ||
| 723 | ldx_zpy | |
| 724 | TMP = read_pc(); | |
| 725 | read(TMP); | |
| 726 | X = read(UINT8(TMP+Y)); | |
| 727 | set_nz(X); | |
| 728 | prefetch(); | |
| 729 | ||
| 730 | ldy_aba | |
| 731 | TMP = read_pc(); | |
| 732 | TMP = set_h(TMP, read_pc()); | |
| 733 | Y = read(TMP); | |
| 734 | set_nz(Y); | |
| 735 | prefetch(); | |
| 736 | ||
| 737 | ldy_abx | |
| 738 | TMP = read_pc(); | |
| 739 | TMP = set_h(TMP, read_pc()); | |
| 740 | if(page_changing(TMP, X)) { | |
| 741 | read(set_l(TMP, TMP+X)); | |
| 742 | } | |
| 743 | TMP += X; | |
| 744 | Y = read(TMP); | |
| 745 | set_nz(Y); | |
| 746 | prefetch(); | |
| 747 | ||
| 748 | ldy_imm | |
| 749 | Y = read_pc(); | |
| 750 | set_nz(Y); | |
| 751 | prefetch(); | |
| 752 | ||
| 753 | ldy_zpg | |
| 754 | TMP = read_pc(); | |
| 755 | Y = read(TMP); | |
| 756 | set_nz(Y); | |
| 757 | prefetch(); | |
| 758 | ||
| 759 | ldy_zpx | |
| 760 | TMP = read_pc(); | |
| 761 | read(TMP); | |
| 762 | Y = read(UINT8(TMP+X)); | |
| 763 | set_nz(Y); | |
| 764 | prefetch(); | |
| 765 | ||
| 766 | lsr_aba | |
| 767 | TMP = read_pc(); | |
| 768 | TMP = set_h(TMP, read_pc()); | |
| 769 | TMP2 = read(TMP); | |
| 770 | write(TMP, TMP2); | |
| 771 | TMP2 = do_lsr(TMP2); | |
| 772 | write(TMP, TMP2); | |
| 773 | prefetch(); | |
| 774 | ||
| 775 | lsr_abx | |
| 776 | TMP = read_pc(); | |
| 777 | TMP = set_h(TMP, read_pc()); | |
| 778 | read(set_l(TMP, TMP+X)); | |
| 779 | TMP += X; | |
| 780 | TMP2 = read(TMP); | |
| 781 | write(TMP, TMP2); | |
| 782 | TMP2 = do_lsr(TMP2); | |
| 783 | write(TMP, TMP2); | |
| 784 | prefetch(); | |
| 785 | ||
| 786 | lsr_acc | |
| 787 | read_pc_noinc(); | |
| 788 | A = do_lsr(A); | |
| 789 | prefetch(); | |
| 790 | ||
| 791 | lsr_zpg | |
| 792 | TMP = read_pc(); | |
| 793 | TMP2 = read(TMP); | |
| 794 | write(TMP, TMP2); | |
| 795 | TMP2 = do_lsr(TMP2); | |
| 796 | write(TMP, TMP2); | |
| 797 | prefetch(); | |
| 798 | ||
| 799 | lsr_zpx | |
| 800 | TMP = read_pc(); | |
| 801 | read(TMP); | |
| 802 | TMP = UINT8(TMP+X); | |
| 803 | TMP2 = read(TMP); | |
| 804 | write(TMP, TMP2); | |
| 805 | TMP2 = do_lsr(TMP2); | |
| 806 | write(TMP, TMP2); | |
| 807 | prefetch(); | |
| 808 | ||
| 809 | nop_imp | |
| 810 | read_pc_noinc(); | |
| 811 | prefetch(); | |
| 812 | ||
| 813 | ora_aba | |
| 814 | TMP = read_pc(); | |
| 815 | TMP = set_h(TMP, read_pc()); | |
| 816 | A |= read(TMP); | |
| 817 | set_nz(A); | |
| 818 | prefetch(); | |
| 819 | ||
| 820 | ora_abx | |
| 821 | TMP = read_pc(); | |
| 822 | TMP = set_h(TMP, read_pc()); | |
| 823 | if(page_changing(TMP, X)) { | |
| 824 | read(set_l(TMP, TMP+X)); | |
| 825 | } | |
| 826 | TMP += X; | |
| 827 | A |= read(TMP); | |
| 828 | set_nz(A); | |
| 829 | prefetch(); | |
| 830 | ||
| 831 | ora_aby | |
| 832 | TMP = read_pc(); | |
| 833 | TMP = set_h(TMP, read_pc()); | |
| 834 | if(page_changing(TMP, Y)) { | |
| 835 | read(set_l(TMP, TMP+Y)); | |
| 836 | } | |
| 837 | TMP += Y; | |
| 838 | A |= read(TMP); | |
| 839 | set_nz(A); | |
| 840 | prefetch(); | |
| 841 | ||
| 842 | ora_imm | |
| 843 | A |= read_pc(); | |
| 844 | set_nz(A); | |
| 845 | prefetch(); | |
| 846 | ||
| 847 | ora_idx | |
| 848 | TMP2 = read_pc(); | |
| 849 | read(TMP2); | |
| 850 | TMP2 += X; | |
| 851 | TMP = read(TMP2 & 0xff); | |
| 852 | TMP = set_h(TMP, read((TMP2+1) & 0xff)); | |
| 853 | A |= read(TMP); | |
| 854 | set_nz(A); | |
| 855 | prefetch(); | |
| 856 | ||
| 857 | ora_idy | |
| 858 | TMP2 = read_pc(); | |
| 859 | TMP = read(TMP2); | |
| 860 | TMP = set_h(TMP, read(TMP2+1)); | |
| 861 | if(page_changing(TMP, Y)) { | |
| 862 | read(set_l(TMP, TMP+Y)); | |
| 863 | } | |
| 864 | A |= read(TMP+Y); | |
| 865 | set_nz(A); | |
| 866 | prefetch(); | |
| 867 | ||
| 868 | ora_zpg | |
| 869 | TMP = read_pc(); | |
| 870 | A |= read(TMP); | |
| 871 | set_nz(A); | |
| 872 | prefetch(); | |
| 873 | ||
| 874 | ora_zpx | |
| 875 | TMP = read_pc(); | |
| 876 | read(TMP); | |
| 877 | A |= read(UINT8(TMP+X)); | |
| 878 | set_nz(A); | |
| 879 | prefetch(); | |
| 880 | ||
| 881 | pha_imp | |
| 882 | read_pc_noinc(); | |
| 883 | write(SP, A); | |
| 884 | dec_SP(); | |
| 885 | prefetch(); | |
| 886 | ||
| 887 | php_imp | |
| 888 | read_pc_noinc(); | |
| 889 | write(SP, P); | |
| 890 | dec_SP(); | |
| 891 | prefetch(); | |
| 892 | ||
| 893 | pla_imp | |
| 894 | read_pc_noinc(); | |
| 895 | read(SP); | |
| 896 | inc_SP(); | |
| 897 | A = read(SP); | |
| 898 | set_nz(A); | |
| 899 | prefetch(); | |
| 900 | ||
| 901 | plp_imp | |
| 902 | read_pc_noinc(); | |
| 903 | read(SP); | |
| 904 | inc_SP(); | |
| 905 | TMP = read(SP) | (F_B|F_E); | |
| 906 | prefetch(); | |
| 907 | P = TMP; // Do *not* move it before the prefetch | |
| 908 | ||
| 909 | rol_aba | |
| 910 | TMP = read_pc(); | |
| 911 | TMP = set_h(TMP, read_pc()); | |
| 912 | TMP2 = read(TMP); | |
| 913 | write(TMP, TMP2); | |
| 914 | TMP2 = do_rol(TMP2); | |
| 915 | write(TMP, TMP2); | |
| 916 | prefetch(); | |
| 917 | ||
| 918 | rol_abx | |
| 919 | TMP = read_pc(); | |
| 920 | TMP = set_h(TMP, read_pc()); | |
| 921 | read(set_l(TMP, TMP+X)); | |
| 922 | TMP += X; | |
| 923 | TMP2 = read(TMP); | |
| 924 | write(TMP, TMP2); | |
| 925 | TMP2 = do_rol(TMP2); | |
| 926 | write(TMP, TMP2); | |
| 927 | prefetch(); | |
| 928 | ||
| 929 | rol_acc | |
| 930 | read_pc_noinc(); | |
| 931 | A = do_rol(A); | |
| 932 | prefetch(); | |
| 933 | ||
| 934 | rol_zpg | |
| 935 | TMP = read_pc(); | |
| 936 | TMP2 = read(TMP); | |
| 937 | write(TMP, TMP2); | |
| 938 | TMP2 = do_rol(TMP2); | |
| 939 | write(TMP, TMP2); | |
| 940 | prefetch(); | |
| 941 | ||
| 942 | rol_zpx | |
| 943 | TMP = read_pc(); | |
| 944 | read(TMP); | |
| 945 | TMP = UINT8(TMP+X); | |
| 946 | TMP2 = read(TMP); | |
| 947 | write(TMP, TMP2); | |
| 948 | TMP2 = do_rol(TMP2); | |
| 949 | write(TMP, TMP2); | |
| 950 | prefetch(); | |
| 951 | ||
| 952 | ror_aba | |
| 953 | TMP = read_pc(); | |
| 954 | TMP = set_h(TMP, read_pc()); | |
| 955 | TMP2 = read(TMP); | |
| 956 | write(TMP, TMP2); | |
| 957 | TMP2 = do_ror(TMP2); | |
| 958 | write(TMP, TMP2); | |
| 959 | prefetch(); | |
| 960 | ||
| 961 | ror_abx | |
| 962 | TMP = read_pc(); | |
| 963 | TMP = set_h(TMP, read_pc()); | |
| 964 | read(set_l(TMP, TMP+X)); | |
| 965 | TMP += X; | |
| 966 | TMP2 = read(TMP); | |
| 967 | write(TMP, TMP2); | |
| 968 | TMP2 = do_ror(TMP2); | |
| 969 | write(TMP, TMP2); | |
| 970 | prefetch(); | |
| 971 | ||
| 972 | ror_acc | |
| 973 | read_pc_noinc(); | |
| 974 | A = do_ror(A); | |
| 975 | prefetch(); | |
| 976 | ||
| 977 | ror_zpg | |
| 978 | TMP = read_pc(); | |
| 979 | TMP2 = read(TMP); | |
| 980 | write(TMP, TMP2); | |
| 981 | TMP2 = do_ror(TMP2); | |
| 982 | write(TMP, TMP2); | |
| 983 | prefetch(); | |
| 984 | ||
| 985 | ror_zpx | |
| 986 | TMP = read_pc(); | |
| 987 | read(TMP); | |
| 988 | TMP = UINT8(TMP+X); | |
| 989 | TMP2 = read(TMP); | |
| 990 | write(TMP, TMP2); | |
| 991 | TMP2 = do_ror(TMP2); | |
| 992 | write(TMP, TMP2); | |
| 993 | prefetch(); | |
| 994 | ||
| 995 | rti_imp | |
| 996 | read_pc_noinc(); | |
| 997 | read(SP); | |
| 998 | inc_SP(); | |
| 999 | P = read(SP) | (F_B|F_E); | |
| 1000 | inc_SP(); | |
| 1001 | PC = read(SP); | |
| 1002 | inc_SP(); | |
| 1003 | PC = set_h(PC, read(SP)); | |
| 1004 | prefetch(); | |
| 1005 | ||
| 1006 | rts_imp | |
| 1007 | read_pc_noinc(); | |
| 1008 | read(SP); | |
| 1009 | inc_SP(); | |
| 1010 | PC = read(SP); | |
| 1011 | inc_SP(); | |
| 1012 | PC = set_h(PC, read(SP)); | |
| 1013 | read_pc(); | |
| 1014 | prefetch(); | |
| 1015 | ||
| 1016 | sbc_aba | |
| 1017 | TMP = read_pc(); | |
| 1018 | TMP = set_h(TMP, read_pc()); | |
| 1019 | TMP = read(TMP); | |
| 1020 | do_sbc(TMP); | |
| 1021 | prefetch(); | |
| 1022 | ||
| 1023 | sbc_abx | |
| 1024 | TMP = read_pc(); | |
| 1025 | TMP = set_h(TMP, read_pc()); | |
| 1026 | if(page_changing(TMP, X)) { | |
| 1027 | read(set_l(TMP, TMP+X)); | |
| 1028 | } | |
| 1029 | TMP += X; | |
| 1030 | TMP = read(TMP); | |
| 1031 | do_sbc(TMP); | |
| 1032 | prefetch(); | |
| 1033 | ||
| 1034 | sbc_aby | |
| 1035 | TMP = read_pc(); | |
| 1036 | TMP = set_h(TMP, read_pc()); | |
| 1037 | if(page_changing(TMP, Y)) { | |
| 1038 | read(set_l(TMP, TMP+Y)); | |
| 1039 | } | |
| 1040 | TMP += Y; | |
| 1041 | TMP = read(TMP); | |
| 1042 | do_sbc(TMP); | |
| 1043 | prefetch(); | |
| 1044 | ||
| 1045 | sbc_idx | |
| 1046 | TMP2 = read_pc(); | |
| 1047 | read(TMP2); | |
| 1048 | TMP2 += X; | |
| 1049 | TMP = read(TMP2 & 0xff); | |
| 1050 | TMP = set_h(TMP, read((TMP2+1) & 0xff)); | |
| 1051 | do_sbc(read(TMP)); | |
| 1052 | prefetch(); | |
| 1053 | ||
| 1054 | sbc_idy | |
| 1055 | TMP2 = read_pc(); | |
| 1056 | TMP = read(TMP2); | |
| 1057 | TMP = set_h(TMP, read(TMP2+1)); | |
| 1058 | if(page_changing(TMP, Y)) { | |
| 1059 | read(set_l(TMP, TMP+Y)); | |
| 1060 | } | |
| 1061 | do_sbc(read(TMP+Y)); | |
| 1062 | prefetch(); | |
| 1063 | ||
| 1064 | sbc_imm | |
| 1065 | TMP = read_pc(); | |
| 1066 | do_sbc(TMP); | |
| 1067 | prefetch(); | |
| 1068 | ||
| 1069 | sbc_zpg | |
| 1070 | TMP = read_pc(); | |
| 1071 | TMP = read(TMP); | |
| 1072 | do_sbc(TMP); | |
| 1073 | prefetch(); | |
| 1074 | ||
| 1075 | sbc_zpx | |
| 1076 | TMP = read_pc(); | |
| 1077 | read(TMP); | |
| 1078 | TMP = read(UINT8(TMP+X)); | |
| 1079 | do_sbc(TMP); | |
| 1080 | prefetch(); | |
| 1081 | ||
| 1082 | sec_imp | |
| 1083 | read_pc_noinc(); | |
| 1084 | P |= F_C; | |
| 1085 | prefetch(); | |
| 1086 | ||
| 1087 | sed_imp | |
| 1088 | read_pc_noinc(); | |
| 1089 | P |= F_D; | |
| 1090 | prefetch(); | |
| 1091 | ||
| 1092 | sei_imp | |
| 1093 | read_pc_noinc(); | |
| 1094 | prefetch(); | |
| 1095 | P |= F_I; // Do *not* move it before the prefetch | |
| 1096 | ||
| 1097 | sta_aba | |
| 1098 | TMP = read_pc(); | |
| 1099 | TMP = set_h(TMP, read_pc()); | |
| 1100 | write(TMP, A); | |
| 1101 | prefetch(); | |
| 1102 | ||
| 1103 | sta_abx | |
| 1104 | TMP = read_pc(); | |
| 1105 | TMP = set_h(TMP, read_pc()); | |
| 1106 | read(set_l(TMP, TMP+X)); | |
| 1107 | write(TMP+X, A); | |
| 1108 | prefetch(); | |
| 1109 | ||
| 1110 | sta_aby | |
| 1111 | TMP = read_pc(); | |
| 1112 | TMP = set_h(TMP, read_pc()); | |
| 1113 | read(set_l(TMP, TMP+Y)); | |
| 1114 | write(TMP+Y, A); | |
| 1115 | prefetch(); | |
| 1116 | ||
| 1117 | sta_idx | |
| 1118 | TMP2 = read_pc(); | |
| 1119 | read(TMP2); | |
| 1120 | TMP2 += X; | |
| 1121 | TMP = read(TMP2 & 0xff); | |
| 1122 | TMP = set_h(TMP, read((TMP2+1) & 0xff)); | |
| 1123 | write(TMP, A); | |
| 1124 | prefetch(); | |
| 1125 | ||
| 1126 | sta_idy | |
| 1127 | TMP2 = read_pc(); | |
| 1128 | TMP = read(TMP2); | |
| 1129 | TMP = set_h(TMP, read(TMP2+1)); | |
| 1130 | read(set_l(TMP, TMP+Y)); | |
| 1131 | write(TMP+Y, A); | |
| 1132 | prefetch(); | |
| 1133 | ||
| 1134 | sta_zpg | |
| 1135 | TMP = read_pc(); | |
| 1136 | write(TMP, A); | |
| 1137 | prefetch(); | |
| 1138 | ||
| 1139 | sta_zpx | |
| 1140 | TMP = read_pc(); | |
| 1141 | read(TMP); | |
| 1142 | write(UINT8(TMP+X), A); | |
| 1143 | prefetch(); | |
| 1144 | ||
| 1145 | stx_aba | |
| 1146 | TMP = read_pc(); | |
| 1147 | TMP = set_h(TMP, read_pc()); | |
| 1148 | write(TMP, X); | |
| 1149 | prefetch(); | |
| 1150 | ||
| 1151 | stx_zpg | |
| 1152 | TMP = read_pc(); | |
| 1153 | write(TMP, X); | |
| 1154 | prefetch(); | |
| 1155 | ||
| 1156 | stx_zpy | |
| 1157 | TMP = read_pc(); | |
| 1158 | read(TMP); | |
| 1159 | write(UINT8(TMP+Y), X); | |
| 1160 | prefetch(); | |
| 1161 | ||
| 1162 | sty_aba | |
| 1163 | TMP = read_pc(); | |
| 1164 | TMP = set_h(TMP, read_pc()); | |
| 1165 | write(TMP, Y); | |
| 1166 | prefetch(); | |
| 1167 | ||
| 1168 | sty_zpg | |
| 1169 | TMP = read_pc(); | |
| 1170 | write(TMP, Y); | |
| 1171 | prefetch(); | |
| 1172 | ||
| 1173 | sty_zpx | |
| 1174 | TMP = read_pc(); | |
| 1175 | read(TMP); | |
| 1176 | write(UINT8(TMP+X), Y); | |
| 1177 | prefetch(); | |
| 1178 | ||
| 1179 | tax_imp | |
| 1180 | read_pc_noinc(); | |
| 1181 | X = A; | |
| 1182 | set_nz(X); | |
| 1183 | prefetch(); | |
| 1184 | ||
| 1185 | tay_imp | |
| 1186 | read_pc_noinc(); | |
| 1187 | Y = A; | |
| 1188 | set_nz(Y); | |
| 1189 | prefetch(); | |
| 1190 | ||
| 1191 | tsx_imp | |
| 1192 | read_pc_noinc(); | |
| 1193 | X = SP; | |
| 1194 | set_nz(X); | |
| 1195 | prefetch(); | |
| 1196 | ||
| 1197 | txa_imp | |
| 1198 | read_pc_noinc(); | |
| 1199 | A = X; | |
| 1200 | set_nz(A); | |
| 1201 | prefetch(); | |
| 1202 | ||
| 1203 | txs_imp | |
| 1204 | read_pc_noinc(); | |
| 1205 | SP = set_l(SP, X); | |
| 1206 | prefetch(); | |
| 1207 | ||
| 1208 | tya_imp | |
| 1209 | read_pc_noinc(); | |
| 1210 | A = Y; | |
| 1211 | set_nz(A); | |
| 1212 | prefetch(); | |
| 1213 | ||
| 1214 | # exceptions | |
| 1215 | reset | |
| 1216 | PC = read_direct(0xfffc); | |
| 1217 | PC = set_h(PC, read_direct(0xfffd)); | |
| 1218 | prefetch(); | |
| 1219 | inst_state = -1; | |
| 1220 | ||
| 1221 | ||
| 1222 | # undocumented reliable instructions | |
| 1223 | dcp_aba | |
| 1224 | TMP = read_pc(); | |
| 1225 | TMP = set_h(TMP, read_pc()); | |
| 1226 | TMP2 = read(TMP); | |
| 1227 | write(TMP, TMP2); | |
| 1228 | TMP2--; | |
| 1229 | write(TMP, TMP2); | |
| 1230 | do_cmp(A, TMP2); | |
| 1231 | prefetch(); | |
| 1232 | ||
| 1233 | dcp_abx | |
| 1234 | TMP = read_pc(); | |
| 1235 | TMP = set_h(TMP, read_pc()); | |
| 1236 | read(set_l(TMP, TMP+X)); | |
| 1237 | TMP += X; | |
| 1238 | TMP2 = read(TMP); | |
| 1239 | write(TMP, TMP2); | |
| 1240 | TMP2--; | |
| 1241 | write(TMP, TMP2); | |
| 1242 | do_cmp(A, TMP2); | |
| 1243 | prefetch(); | |
| 1244 | ||
| 1245 | dcp_aby | |
| 1246 | TMP = read_pc(); | |
| 1247 | TMP = set_h(TMP, read_pc()); | |
| 1248 | read(set_l(TMP, TMP+Y)); | |
| 1249 | TMP += Y; | |
| 1250 | TMP2 = read(TMP); | |
| 1251 | write(TMP, TMP2); | |
| 1252 | TMP2--; | |
| 1253 | write(TMP, TMP2); | |
| 1254 | do_cmp(A, TMP2); | |
| 1255 | prefetch(); | |
| 1256 | ||
| 1257 | dcp_idx | |
| 1258 | TMP2 = read_pc(); | |
| 1259 | read(TMP2); | |
| 1260 | TMP2 += X; | |
| 1261 | TMP = read(TMP2 & 0xff); | |
| 1262 | TMP = set_h(TMP, read((TMP2+1) & 0xff)); | |
| 1263 | TMP2 = read(TMP); | |
| 1264 | write(TMP, TMP2); | |
| 1265 | TMP2--; | |
| 1266 | write(TMP, TMP2); | |
| 1267 | do_cmp(A, TMP2); | |
| 1268 | prefetch(); | |
| 1269 | ||
| 1270 | dcp_idy | |
| 1271 | TMP2 = read_pc(); | |
| 1272 | TMP = read(TMP2); | |
| 1273 | TMP = set_h(TMP, read(TMP2+1)); | |
| 1274 | read(set_l(TMP, TMP+Y)); | |
| 1275 | TMP += Y; | |
| 1276 | TMP2 = read(TMP); | |
| 1277 | write(TMP, TMP2); | |
| 1278 | TMP2--; | |
| 1279 | write(TMP, TMP2); | |
| 1280 | do_cmp(A, TMP2); | |
| 1281 | prefetch(); | |
| 1282 | ||
| 1283 | dcp_zpg | |
| 1284 | TMP = read_pc(); | |
| 1285 | TMP2 = read(TMP); | |
| 1286 | write(TMP, TMP2); | |
| 1287 | TMP2--; | |
| 1288 | write(TMP, TMP2); | |
| 1289 | do_cmp(A, TMP2); | |
| 1290 | prefetch(); | |
| 1291 | ||
| 1292 | dcp_zpx | |
| 1293 | TMP = read_pc(); | |
| 1294 | read(TMP); | |
| 1295 | TMP = UINT8(TMP+X); | |
| 1296 | TMP2 = read(TMP); | |
| 1297 | write(TMP, TMP2); | |
| 1298 | TMP2--; | |
| 1299 | write(TMP, TMP2); | |
| 1300 | do_cmp(A, TMP2); | |
| 1301 | prefetch(); | |
| 1302 | ||
| 1303 | isb_aba | |
| 1304 | TMP = read_pc(); | |
| 1305 | TMP = set_h(TMP, read_pc()); | |
| 1306 | TMP2 = read(TMP); | |
| 1307 | write(TMP, TMP2); | |
| 1308 | TMP2++; | |
| 1309 | write(TMP, TMP2); | |
| 1310 | do_sbc(TMP2); | |
| 1311 | prefetch(); | |
| 1312 | ||
| 1313 | isb_abx | |
| 1314 | TMP = read_pc(); | |
| 1315 | TMP = set_h(TMP, read_pc()); | |
| 1316 | read(set_l(TMP, TMP+X)); | |
| 1317 | TMP += X; | |
| 1318 | TMP2 = read(TMP); | |
| 1319 | write(TMP, TMP2); | |
| 1320 | TMP2++; | |
| 1321 | write(TMP, TMP2); | |
| 1322 | do_sbc(TMP2); | |
| 1323 | prefetch(); | |
| 1324 | ||
| 1325 | isb_aby | |
| 1326 | TMP = read_pc(); | |
| 1327 | TMP = set_h(TMP, read_pc()); | |
| 1328 | read(set_l(TMP, TMP+Y)); | |
| 1329 | TMP += Y; | |
| 1330 | TMP2 = read(TMP); | |
| 1331 | write(TMP, TMP2); | |
| 1332 | TMP2++; | |
| 1333 | write(TMP, TMP2); | |
| 1334 | do_sbc(TMP2); | |
| 1335 | prefetch(); | |
| 1336 | ||
| 1337 | isb_idx | |
| 1338 | TMP2 = read_pc(); | |
| 1339 | read(TMP2); | |
| 1340 | TMP2 += X; | |
| 1341 | TMP = read(TMP2 & 0xff); | |
| 1342 | TMP = set_h(TMP, read((TMP2+1) & 0xff)); | |
| 1343 | TMP2 = read(TMP); | |
| 1344 | write(TMP, TMP2); | |
| 1345 | TMP2++; | |
| 1346 | write(TMP, TMP2); | |
| 1347 | do_sbc(TMP2); | |
| 1348 | prefetch(); | |
| 1349 | ||
| 1350 | isb_idy | |
| 1351 | TMP2 = read_pc(); | |
| 1352 | TMP = read(TMP2); | |
| 1353 | TMP = set_h(TMP, read(TMP2+1)); | |
| 1354 | read(set_l(TMP, TMP+Y)); | |
| 1355 | TMP += Y; | |
| 1356 | TMP2 = read(TMP); | |
| 1357 | write(TMP, TMP2); | |
| 1358 | TMP2++; | |
| 1359 | write(TMP, TMP2); | |
| 1360 | do_sbc(TMP2); | |
| 1361 | prefetch(); | |
| 1362 | ||
| 1363 | isb_zpg | |
| 1364 | TMP = read_pc(); | |
| 1365 | TMP2 = read(TMP); | |
| 1366 | write(TMP, TMP2); | |
| 1367 | TMP2++; | |
| 1368 | write(TMP, TMP2); | |
| 1369 | do_sbc(TMP2); | |
| 1370 | prefetch(); | |
| 1371 | ||
| 1372 | isb_zpx | |
| 1373 | TMP = read_pc(); | |
| 1374 | read(TMP); | |
| 1375 | TMP = UINT8(TMP+X); | |
| 1376 | TMP2 = read(TMP); | |
| 1377 | write(TMP, TMP2); | |
| 1378 | TMP2++; | |
| 1379 | write(TMP, TMP2); | |
| 1380 | do_sbc(TMP2); | |
| 1381 | prefetch(); | |
| 1382 | ||
| 1383 | lax_aba | |
| 1384 | TMP = read_pc(); | |
| 1385 | TMP = set_h(TMP, read_pc()); | |
| 1386 | A = X = read(TMP); | |
| 1387 | set_nz(A); | |
| 1388 | prefetch(); | |
| 1389 | ||
| 1390 | lax_aby | |
| 1391 | TMP = read_pc(); | |
| 1392 | TMP = set_h(TMP, read_pc()); | |
| 1393 | read(set_l(TMP, TMP+Y)); | |
| 1394 | TMP += Y; | |
| 1395 | A = X = read(TMP); | |
| 1396 | set_nz(A); | |
| 1397 | prefetch(); | |
| 1398 | ||
| 1399 | lax_idx | |
| 1400 | TMP2 = read_pc(); | |
| 1401 | read(TMP2); | |
| 1402 | TMP2 += X; | |
| 1403 | TMP = read(TMP2 & 0xff); | |
| 1404 | TMP = set_h(TMP, read((TMP2+1) & 0xff)); | |
| 1405 | A = X = read(TMP); | |
| 1406 | set_nz(A); | |
| 1407 | prefetch(); | |
| 1408 | ||
| 1409 | lax_idy | |
| 1410 | TMP2 = read_pc(); | |
| 1411 | TMP = read(TMP2); | |
| 1412 | TMP = set_h(TMP, read(TMP2+1)); | |
| 1413 | if(page_changing(TMP, Y)) { | |
| 1414 | read(set_l(TMP, TMP+Y)); | |
| 1415 | } | |
| 1416 | A = X = read(TMP+Y); | |
| 1417 | set_nz(A); | |
| 1418 | prefetch(); | |
| 1419 | ||
| 1420 | lax_zpg | |
| 1421 | TMP = read_pc(); | |
| 1422 | A = X = read(TMP); | |
| 1423 | set_nz(A); | |
| 1424 | prefetch(); | |
| 1425 | ||
| 1426 | lax_zpy | |
| 1427 | TMP = read_pc(); | |
| 1428 | read(TMP); | |
| 1429 | TMP = UINT8(TMP+Y); | |
| 1430 | A = X = read(TMP); | |
| 1431 | set_nz(A); | |
| 1432 | prefetch(); | |
| 1433 | ||
| 1434 | rla_aba | |
| 1435 | TMP = read_pc(); | |
| 1436 | TMP = set_h(TMP, read_pc()); | |
| 1437 | TMP2 = read(TMP); | |
| 1438 | write(TMP, TMP2); | |
| 1439 | TMP2 = do_rol(TMP2); | |
| 1440 | write(TMP, TMP2); | |
| 1441 | A &= TMP2; | |
| 1442 | set_nz(A); | |
| 1443 | prefetch(); | |
| 1444 | ||
| 1445 | rla_abx | |
| 1446 | TMP = read_pc(); | |
| 1447 | TMP = set_h(TMP, read_pc()); | |
| 1448 | read(set_l(TMP, TMP+X)); | |
| 1449 | TMP += X; | |
| 1450 | TMP2 = read(TMP); | |
| 1451 | write(TMP, TMP2); | |
| 1452 | TMP2 = do_rol(TMP2); | |
| 1453 | write(TMP, TMP2); | |
| 1454 | A &= TMP2; | |
| 1455 | set_nz(A); | |
| 1456 | prefetch(); | |
| 1457 | ||
| 1458 | rla_aby | |
| 1459 | TMP = read_pc(); | |
| 1460 | TMP = set_h(TMP, read_pc()); | |
| 1461 | read(set_l(TMP, TMP+Y)); | |
| 1462 | TMP += Y; | |
| 1463 | TMP2 = read(TMP); | |
| 1464 | write(TMP, TMP2); | |
| 1465 | TMP2 = do_rol(TMP2); | |
| 1466 | write(TMP, TMP2); | |
| 1467 | A &= TMP2; | |
| 1468 | set_nz(A); | |
| 1469 | prefetch(); | |
| 1470 | ||
| 1471 | rla_idx | |
| 1472 | TMP2 = read_pc(); | |
| 1473 | read(TMP2); | |
| 1474 | TMP2 += X; | |
| 1475 | TMP = read(TMP2 & 0xff); | |
| 1476 | TMP = set_h(TMP, read((TMP2+1) & 0xff)); | |
| 1477 | TMP2 = read(TMP); | |
| 1478 | write(TMP, TMP2); | |
| 1479 | TMP2 = do_rol(TMP2); | |
| 1480 | write(TMP, TMP2); | |
| 1481 | A &= TMP2; | |
| 1482 | set_nz(A); | |
| 1483 | prefetch(); | |
| 1484 | ||
| 1485 | rla_idy | |
| 1486 | TMP2 = read_pc(); | |
| 1487 | TMP = read(TMP2); | |
| 1488 | TMP = set_h(TMP, read(TMP2+1)); | |
| 1489 | read(set_l(TMP, TMP+Y)); | |
| 1490 | TMP += Y; | |
| 1491 | TMP2 = read(TMP); | |
| 1492 | write(TMP, TMP2); | |
| 1493 | TMP2 = do_rol(TMP2); | |
| 1494 | write(TMP, TMP2); | |
| 1495 | A &= TMP2; | |
| 1496 | set_nz(A); | |
| 1497 | prefetch(); | |
| 1498 | ||
| 1499 | rla_zpg | |
| 1500 | TMP = read_pc(); | |
| 1501 | TMP2 = read(TMP); | |
| 1502 | write(TMP, TMP2); | |
| 1503 | TMP2 = do_rol(TMP2); | |
| 1504 | write(TMP, TMP2); | |
| 1505 | A &= TMP2; | |
| 1506 | set_nz(A); | |
| 1507 | prefetch(); | |
| 1508 | ||
| 1509 | rla_zpx | |
| 1510 | TMP = read_pc(); | |
| 1511 | read(TMP); | |
| 1512 | TMP = UINT8(TMP+X); | |
| 1513 | TMP2 = read(TMP); | |
| 1514 | write(TMP, TMP2); | |
| 1515 | TMP2 = do_rol(TMP2); | |
| 1516 | write(TMP, TMP2); | |
| 1517 | A &= TMP2; | |
| 1518 | set_nz(A); | |
| 1519 | prefetch(); | |
| 1520 | ||
| 1521 | rra_aba | |
| 1522 | TMP = read_pc(); | |
| 1523 | TMP = set_h(TMP, read_pc()); | |
| 1524 | TMP2 = read(TMP); | |
| 1525 | write(TMP, TMP2); | |
| 1526 | TMP2 = do_ror(TMP2); | |
| 1527 | write(TMP, TMP2); | |
| 1528 | do_adc(TMP2); | |
| 1529 | prefetch(); | |
| 1530 | ||
| 1531 | rra_abx | |
| 1532 | TMP = read_pc(); | |
| 1533 | TMP = set_h(TMP, read_pc()); | |
| 1534 | read(set_l(TMP, TMP+X)); | |
| 1535 | TMP += X; | |
| 1536 | TMP2 = read(TMP); | |
| 1537 | write(TMP, TMP2); | |
| 1538 | TMP2 = do_ror(TMP2); | |
| 1539 | write(TMP, TMP2); | |
| 1540 | do_adc(TMP2); | |
| 1541 | prefetch(); | |
| 1542 | ||
| 1543 | rra_aby | |
| 1544 | TMP = read_pc(); | |
| 1545 | TMP = set_h(TMP, read_pc()); | |
| 1546 | read(set_l(TMP, TMP+Y)); | |
| 1547 | TMP += Y; | |
| 1548 | TMP2 = read(TMP); | |
| 1549 | write(TMP, TMP2); | |
| 1550 | TMP2 = do_ror(TMP2); | |
| 1551 | write(TMP, TMP2); | |
| 1552 | do_adc(TMP2); | |
| 1553 | prefetch(); | |
| 1554 | ||
| 1555 | rra_idx | |
| 1556 | TMP2 = read_pc(); | |
| 1557 | read(TMP2); | |
| 1558 | TMP2 += X; | |
| 1559 | TMP = read(TMP2 & 0xff); | |
| 1560 | TMP = set_h(TMP, read((TMP2+1) & 0xff)); | |
| 1561 | TMP2 = read(TMP); | |
| 1562 | write(TMP, TMP2); | |
| 1563 | TMP2 = do_ror(TMP2); | |
| 1564 | write(TMP, TMP2); | |
| 1565 | do_adc(TMP2); | |
| 1566 | prefetch(); | |
| 1567 | ||
| 1568 | rra_idy | |
| 1569 | TMP2 = read_pc(); | |
| 1570 | TMP = read(TMP2); | |
| 1571 | TMP = set_h(TMP, read(TMP2+1)); | |
| 1572 | read(set_l(TMP, TMP+Y)); | |
| 1573 | TMP += Y; | |
| 1574 | TMP2 = read(TMP); | |
| 1575 | write(TMP, TMP2); | |
| 1576 | TMP2 = do_ror(TMP2); | |
| 1577 | write(TMP, TMP2); | |
| 1578 | do_adc(TMP2); | |
| 1579 | prefetch(); | |
| 1580 | ||
| 1581 | rra_zpg | |
| 1582 | TMP = read_pc(); | |
| 1583 | TMP2 = read(TMP); | |
| 1584 | write(TMP, TMP2); | |
| 1585 | TMP2 = do_ror(TMP2); | |
| 1586 | write(TMP, TMP2); | |
| 1587 | do_adc(TMP2); | |
| 1588 | prefetch(); | |
| 1589 | ||
| 1590 | rra_zpx | |
| 1591 | TMP = read_pc(); | |
| 1592 | read(TMP); | |
| 1593 | TMP = UINT8(TMP+X); | |
| 1594 | TMP2 = read(TMP); | |
| 1595 | write(TMP, TMP2); | |
| 1596 | TMP2 = do_ror(TMP2); | |
| 1597 | write(TMP, TMP2); | |
| 1598 | do_adc(TMP2); | |
| 1599 | prefetch(); | |
| 1600 | ||
| 1601 | sax_aba | |
| 1602 | TMP = read_pc(); | |
| 1603 | TMP = set_h(TMP, read_pc()); | |
| 1604 | TMP2 = A & X; | |
| 1605 | write(TMP, TMP2); | |
| 1606 | prefetch(); | |
| 1607 | ||
| 1608 | sax_idx | |
| 1609 | TMP2 = read_pc(); | |
| 1610 | read(TMP2); | |
| 1611 | TMP2 += X; | |
| 1612 | TMP = read(TMP2 & 0xff); | |
| 1613 | TMP = set_h(TMP, read((TMP2+1) & 0xff)); | |
| 1614 | TMP2 = A & X; | |
| 1615 | write(TMP, TMP2); | |
| 1616 | prefetch(); | |
| 1617 | ||
| 1618 | sax_zpg | |
| 1619 | TMP = read_pc(); | |
| 1620 | TMP2 = A & X; | |
| 1621 | write(TMP, TMP2); | |
| 1622 | prefetch(); | |
| 1623 | ||
| 1624 | sax_zpy | |
| 1625 | TMP = read_pc(); | |
| 1626 | read(TMP); | |
| 1627 | TMP = UINT8(TMP+Y); | |
| 1628 | TMP2 = A & X; | |
| 1629 | write(TMP, TMP2); | |
| 1630 | prefetch(); | |
| 1631 | ||
| 1632 | sbx_imm | |
| 1633 | TMP2 = read_pc(); | |
| 1634 | X &= A; | |
| 1635 | if(X < TMP2) | |
| 1636 | P &= ~F_C; | |
| 1637 | else | |
| 1638 | P |= F_C; | |
| 1639 | X -= TMP2; | |
| 1640 | set_nz(X); | |
| 1641 | prefetch(); | |
| 1642 | ||
| 1643 | sha_aby | |
| 1644 | TMP = read_pc(); | |
| 1645 | TMP = set_h(TMP, read_pc()); | |
| 1646 | read(set_l(TMP, TMP+Y)); | |
| 1647 | TMP2 = A & X & ((TMP >> 8)+1); | |
| 1648 | if(page_changing(TMP, Y)) | |
| 1649 | TMP = set_h(TMP+Y, TMP2); | |
| 1650 | else | |
| 1651 | TMP += Y; | |
| 1652 | write(TMP, TMP2); | |
| 1653 | prefetch(); | |
| 1654 | ||
| 1655 | sha_idy | |
| 1656 | TMP2 = read_pc(); | |
| 1657 | TMP = read(TMP2); | |
| 1658 | TMP = set_h(TMP, read(TMP2+1)); | |
| 1659 | read(set_l(TMP, TMP+Y)); | |
| 1660 | TMP2 = A & X & ((TMP >> 8)+1); | |
| 1661 | if(page_changing(TMP, Y)) | |
| 1662 | TMP = set_h(TMP+Y, TMP2); | |
| 1663 | else | |
| 1664 | TMP += Y; | |
| 1665 | write(TMP, TMP2); | |
| 1666 | prefetch(); | |
| 1667 | ||
| 1668 | shs_aby | |
| 1669 | TMP = read_pc(); | |
| 1670 | TMP = set_h(TMP, read_pc()); | |
| 1671 | read(set_l(TMP, TMP+Y)); | |
| 1672 | SP = set_l(SP, A & X); | |
| 1673 | TMP2 = A & X & ((TMP >> 8)+1); | |
| 1674 | if(page_changing(TMP, Y)) | |
| 1675 | TMP = set_h(TMP+Y, TMP2); | |
| 1676 | else | |
| 1677 | TMP += Y; | |
| 1678 | write(TMP, TMP2); | |
| 1679 | prefetch(); | |
| 1680 | ||
| 1681 | shx_aby | |
| 1682 | TMP = read_pc(); | |
| 1683 | TMP = set_h(TMP, read_pc()); | |
| 1684 | read(set_l(TMP, TMP+Y)); | |
| 1685 | TMP2 = X & ((TMP >> 8)+1); | |
| 1686 | if(page_changing(TMP, Y)) | |
| 1687 | TMP = set_h(TMP+Y, TMP2); | |
| 1688 | else | |
| 1689 | TMP += Y; | |
| 1690 | write(TMP, TMP2); | |
| 1691 | prefetch(); | |
| 1692 | ||
| 1693 | shy_abx | |
| 1694 | TMP = read_pc(); | |
| 1695 | TMP = set_h(TMP, read_pc()); | |
| 1696 | read(set_l(TMP, TMP+X)); | |
| 1697 | TMP2 = Y & ((TMP >> 8)+1); | |
| 1698 | if(page_changing(TMP, X)) | |
| 1699 | TMP = set_h(TMP+X, TMP2); | |
| 1700 | else | |
| 1701 | TMP += X; | |
| 1702 | write(TMP, TMP2); | |
| 1703 | prefetch(); | |
| 1704 | ||
| 1705 | slo_aba | |
| 1706 | TMP = read_pc(); | |
| 1707 | TMP = set_h(TMP, read_pc()); | |
| 1708 | TMP2 = read(TMP); | |
| 1709 | write(TMP, TMP2); | |
| 1710 | TMP2 = do_asl(TMP2); | |
| 1711 | write(TMP, TMP2); | |
| 1712 | A |= TMP2; | |
| 1713 | set_nz(A); | |
| 1714 | prefetch(); | |
| 1715 | ||
| 1716 | slo_abx | |
| 1717 | TMP = read_pc(); | |
| 1718 | TMP = set_h(TMP, read_pc()); | |
| 1719 | read(set_l(TMP, TMP+X)); | |
| 1720 | TMP += X; | |
| 1721 | TMP2 = read(TMP); | |
| 1722 | write(TMP, TMP2); | |
| 1723 | TMP2 = do_asl(TMP2); | |
| 1724 | write(TMP, TMP2); | |
| 1725 | A |= TMP2; | |
| 1726 | set_nz(A); | |
| 1727 | prefetch(); | |
| 1728 | ||
| 1729 | slo_aby | |
| 1730 | TMP = read_pc(); | |
| 1731 | TMP = set_h(TMP, read_pc()); | |
| 1732 | read(set_l(TMP, TMP+Y)); | |
| 1733 | TMP += Y; | |
| 1734 | TMP2 = read(TMP); | |
| 1735 | write(TMP, TMP2); | |
| 1736 | TMP2 = do_asl(TMP2); | |
| 1737 | write(TMP, TMP2); | |
| 1738 | A |= TMP2; | |
| 1739 | set_nz(A); | |
| 1740 | prefetch(); | |
| 1741 | ||
| 1742 | slo_idx | |
| 1743 | TMP2 = read_pc(); | |
| 1744 | read(TMP2); | |
| 1745 | TMP2 += X; | |
| 1746 | TMP = read(TMP2 & 0xff); | |
| 1747 | TMP = set_h(TMP, read((TMP2+1) & 0xff)); | |
| 1748 | TMP2 = read(TMP); | |
| 1749 | write(TMP, TMP2); | |
| 1750 | TMP2 = do_asl(TMP2); | |
| 1751 | write(TMP, TMP2); | |
| 1752 | A |= TMP2; | |
| 1753 | set_nz(A); | |
| 1754 | prefetch(); | |
| 1755 | ||
| 1756 | slo_idy | |
| 1757 | TMP2 = read_pc(); | |
| 1758 | TMP = read(TMP2); | |
| 1759 | TMP = set_h(TMP, read(TMP2+1)); | |
| 1760 | read(set_l(TMP, TMP+Y)); | |
| 1761 | TMP += Y; | |
| 1762 | TMP2 = read(TMP); | |
| 1763 | write(TMP, TMP2); | |
| 1764 | TMP2 = do_asl(TMP2); | |
| 1765 | write(TMP, TMP2); | |
| 1766 | A |= TMP2; | |
| 1767 | set_nz(A); | |
| 1768 | prefetch(); | |
| 1769 | ||
| 1770 | slo_zpg | |
| 1771 | TMP = read_pc(); | |
| 1772 | TMP2 = read(TMP); | |
| 1773 | write(TMP, TMP2); | |
| 1774 | TMP2 = do_asl(TMP2); | |
| 1775 | write(TMP, TMP2); | |
| 1776 | A |= TMP2; | |
| 1777 | set_nz(A); | |
| 1778 | prefetch(); | |
| 1779 | ||
| 1780 | slo_zpx | |
| 1781 | TMP = read_pc(); | |
| 1782 | read(TMP); | |
| 1783 | TMP = UINT8(TMP+X); | |
| 1784 | TMP2 = read(TMP); | |
| 1785 | write(TMP, TMP2); | |
| 1786 | TMP2 = do_asl(TMP2); | |
| 1787 | write(TMP, TMP2); | |
| 1788 | A |= TMP2; | |
| 1789 | set_nz(A); | |
| 1790 | prefetch(); | |
| 1791 | ||
| 1792 | sre_aba | |
| 1793 | TMP = read_pc(); | |
| 1794 | TMP = set_h(TMP, read_pc()); | |
| 1795 | TMP2 = read(TMP); | |
| 1796 | write(TMP, TMP2); | |
| 1797 | TMP2 = do_lsr(TMP2); | |
| 1798 | write(TMP, TMP2); | |
| 1799 | A ^= TMP2; | |
| 1800 | set_nz(A); | |
| 1801 | prefetch(); | |
| 1802 | ||
| 1803 | sre_abx | |
| 1804 | TMP = read_pc(); | |
| 1805 | TMP = set_h(TMP, read_pc()); | |
| 1806 | read(set_l(TMP, TMP+X)); | |
| 1807 | TMP += X; | |
| 1808 | TMP2 = read(TMP); | |
| 1809 | write(TMP, TMP2); | |
| 1810 | TMP2 = do_lsr(TMP2); | |
| 1811 | write(TMP, TMP2); | |
| 1812 | A ^= TMP2; | |
| 1813 | set_nz(A); | |
| 1814 | prefetch(); | |
| 1815 | ||
| 1816 | sre_aby | |
| 1817 | TMP = read_pc(); | |
| 1818 | TMP = set_h(TMP, read_pc()); | |
| 1819 | read(set_l(TMP, TMP+Y)); | |
| 1820 | TMP += Y; | |
| 1821 | TMP2 = read(TMP); | |
| 1822 | write(TMP, TMP2); | |
| 1823 | TMP2 = do_lsr(TMP2); | |
| 1824 | write(TMP, TMP2); | |
| 1825 | A ^= TMP2; | |
| 1826 | set_nz(A); | |
| 1827 | prefetch(); | |
| 1828 | ||
| 1829 | sre_idx | |
| 1830 | TMP2 = read_pc(); | |
| 1831 | read(TMP2); | |
| 1832 | TMP2 += X; | |
| 1833 | TMP = read(TMP2 & 0xff); | |
| 1834 | TMP = set_h(TMP, read((TMP2+1) & 0xff)); | |
| 1835 | TMP2 = read(TMP); | |
| 1836 | write(TMP, TMP2); | |
| 1837 | TMP2 = do_lsr(TMP2); | |
| 1838 | write(TMP, TMP2); | |
| 1839 | A ^= TMP2; | |
| 1840 | set_nz(A); | |
| 1841 | prefetch(); | |
| 1842 | ||
| 1843 | sre_idy | |
| 1844 | TMP2 = read_pc(); | |
| 1845 | TMP = read(TMP2); | |
| 1846 | TMP = set_h(TMP, read(TMP2+1)); | |
| 1847 | read(set_l(TMP, TMP+Y)); | |
| 1848 | TMP += Y; | |
| 1849 | TMP2 = read(TMP); | |
| 1850 | write(TMP, TMP2); | |
| 1851 | TMP2 = do_lsr(TMP2); | |
| 1852 | write(TMP, TMP2); | |
| 1853 | A ^= TMP2; | |
| 1854 | set_nz(A); | |
| 1855 | prefetch(); | |
| 1856 | ||
| 1857 | sre_zpg | |
| 1858 | TMP = read_pc(); | |
| 1859 | TMP2 = read(TMP); | |
| 1860 | write(TMP, TMP2); | |
| 1861 | TMP2 = do_lsr(TMP2); | |
| 1862 | write(TMP, TMP2); | |
| 1863 | A ^= TMP2; | |
| 1864 | set_nz(A); | |
| 1865 | prefetch(); | |
| 1866 | ||
| 1867 | sre_zpx | |
| 1868 | TMP = read_pc(); | |
| 1869 | read(TMP); | |
| 1870 | TMP = UINT8(TMP+X); | |
| 1871 | TMP2 = read(TMP); | |
| 1872 | write(TMP, TMP2); | |
| 1873 | TMP2 = do_lsr(TMP2); | |
| 1874 | write(TMP, TMP2); | |
| 1875 | A ^= TMP2; | |
| 1876 | set_nz(A); | |
| 1877 | prefetch(); | |
| 1878 | ||
| 1879 | # undocumented unreliable instructions | |
| 1880 | anc_imm | |
| 1881 | read_pc(); | |
| 1882 | set_nz(A); | |
| 1883 | if(A & 0x80) | |
| 1884 | P |= F_C; | |
| 1885 | else | |
| 1886 | P &= ~F_C; | |
| 1887 | prefetch(); | |
| 1888 | ||
| 1889 | ane_imm | |
| 1890 | TMP2 = read_pc(); | |
| 1891 | A &= TMP2 & X; | |
| 1892 | set_nz(A); | |
| 1893 | prefetch(); | |
| 1894 | ||
| 1895 | asr_imm | |
| 1896 | read_pc(); | |
| 1897 | A = do_lsr(A); | |
| 1898 | prefetch(); | |
| 1899 | ||
| 1900 | arr_imm | |
| 1901 | read_pc(); | |
| 1902 | do_arr(); | |
| 1903 | prefetch(); | |
| 1904 | ||
| 1905 | las_aby | |
| 1906 | TMP = read_pc(); | |
| 1907 | TMP = set_h(TMP, read_pc()); | |
| 1908 | if(page_changing(TMP, Y)) { | |
| 1909 | read(set_l(TMP, TMP+Y)); | |
| 1910 | } | |
| 1911 | TMP2 = read(TMP+Y); | |
| 1912 | A = TMP2 | 0x51; | |
| 1913 | X = 0xff; | |
| 1914 | set_nz(TMP2); | |
| 1915 | prefetch(); | |
| 1916 | ||
| 1917 | lxa_imm | |
| 1918 | TMP2 = read_pc(); | |
| 1919 | A = X = A & TMP2; | |
| 1920 | set_nz(A); | |
| 1921 | prefetch(); | |
| 1922 | ||
| 1923 | # nop variants | |
| 1924 | nop_aba | |
| 1925 | TMP = read_pc(); | |
| 1926 | TMP = set_h(TMP, read_pc()); | |
| 1927 | read(TMP); | |
| 1928 | prefetch(); | |
| 1929 | ||
| 1930 | nop_abx | |
| 1931 | TMP = read_pc(); | |
| 1932 | TMP = set_h(TMP, read_pc()); | |
| 1933 | if(page_changing(TMP, X)) { | |
| 1934 | read(set_l(TMP, TMP+X)); | |
| 1935 | } | |
| 1936 | read(TMP + X); | |
| 1937 | prefetch(); | |
| 1938 | ||
| 1939 | nop_imm | |
| 1940 | read_pc(); | |
| 1941 | prefetch(); | |
| 1942 | ||
| 1943 | nop_zpg | |
| 1944 | TMP = read_pc(); | |
| 1945 | read(TMP); | |
| 1946 | prefetch(); | |
| 1947 | ||
| 1948 | nop_zpx | |
| 1949 | TMP = read_pc(); | |
| 1950 | read(TMP); | |
| 1951 | read(UINT8(TMP+X)); | |
| 1952 | prefetch(); | |
| 1953 | ||
| 1954 | # system killers | |
| 1955 | kil_non | |
| 1956 | read_pc(); | |
| 1957 | read(0xffff); | |
| 1958 | read(0xfffe); | |
| 1959 | read(0xfffe); | |
| 1960 | for(;;) { | |
| 1961 | read(0xffff); | |
| 1962 | } |
| r18874 | r18875 | |
|---|---|---|
| 1 | /*************************************************************************** | |
| 2 | ||
| 3 | m6510.c | |
| 4 | ||
| 5 | 6502 with 6 i/o pins, also known as 8500 | |
| 6 | ||
| 7 | **************************************************************************** | |
| 8 | ||
| 9 | Copyright Olivier Galibert | |
| 10 | All rights reserved. | |
| 11 | ||
| 12 | Redistribution and use in source and binary forms, with or without | |
| 13 | modification, are permitted provided that the following conditions are | |
| 14 | met: | |
| 15 | ||
| 16 | * Redistributions of source code must retain the above copyright | |
| 17 | notice, this list of conditions and the following disclaimer. | |
| 18 | * Redistributions in binary form must reproduce the above copyright | |
| 19 | notice, this list of conditions and the following disclaimer in | |
| 20 | the documentation and/or other materials provided with the | |
| 21 | distribution. | |
| 22 | * Neither the name 'MAME' nor the names of its contributors may be | |
| 23 | used to endorse or promote products derived from this software | |
| 24 | without specific prior written permission. | |
| 25 | ||
| 26 | THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR | |
| 27 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 28 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 29 | DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, | |
| 30 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 31 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
| 32 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 33 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
| 34 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
| 35 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| 36 | POSSIBILITY OF SUCH DAMAGE. | |
| 37 | ||
| 38 | ***************************************************************************/ | |
| 39 | ||
| 40 | #include "emu.h" | |
| 41 | #include "m6510.h" | |
| 42 | ||
| 43 | const device_type M6510 = &device_creator<m6510_device>; | |
| 44 | ||
| 45 | m6510_device::m6510_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : | |
| 46 | m6502_device(mconfig, M6510, "M6510", tag, owner, clock), | |
| 47 | read_port(*this), | |
| 48 | write_port(*this) | |
| 49 | { | |
| 50 | pullup = 0x00; | |
| 51 | floating = 0x00; | |
| 52 | } | |
| 53 | ||
| 54 | m6510_device::m6510_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) : | |
| 55 | m6502_device(mconfig, type, name, tag, owner, clock), | |
| 56 | read_port(*this), | |
| 57 | write_port(*this) | |
| 58 | { | |
| 59 | pullup = 0x00; | |
| 60 | floating = 0x00; | |
| 61 | } | |
| 62 | ||
| 63 | void m6510_device::set_pulls(UINT8 _pullup, UINT8 _floating) | |
| 64 | { | |
| 65 | pullup = _pullup; | |
| 66 | floating = _floating; | |
| 67 | } | |
| 68 | ||
| 69 | offs_t m6510_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) | |
| 70 | { | |
| 71 | return disassemble_generic(buffer, pc, oprom, opram, options, disasm_entries); | |
| 72 | } | |
| 73 | ||
| 74 | void m6510_device::device_start() | |
| 75 | { | |
| 76 | read_port.resolve_safe(0); | |
| 77 | write_port.resolve_safe(); | |
| 78 | ||
| 79 | if(direct_disabled) | |
| 80 | mintf = new mi_6510_nd(this); | |
| 81 | else | |
| 82 | mintf = new mi_6510_normal(this); | |
| 83 | ||
| 84 | init(); | |
| 85 | ||
| 86 | save_item(NAME(pullup)); | |
| 87 | save_item(NAME(floating)); | |
| 88 | save_item(NAME(dir)); | |
| 89 | save_item(NAME(port)); | |
| 90 | save_item(NAME(drive)); | |
| 91 | } | |
| 92 | ||
| 93 | void m6510_device::device_reset() | |
| 94 | { | |
| 95 | dir = 0x00; | |
| 96 | port = 0x00; | |
| 97 | drive = 0x00; | |
| 98 | update_port(); | |
| 99 | } | |
| 100 | ||
| 101 | void m6510_device::update_port() | |
| 102 | { | |
| 103 | drive = (port & dir) | (drive & ~dir); | |
| 104 | write_port((port & dir) | (pullup & ~dir)); | |
| 105 | } | |
| 106 | ||
| 107 | UINT8 m6510_device::get_port() | |
| 108 | { | |
| 109 | return (port & dir) | (pullup & ~dir); | |
| 110 | } | |
| 111 | ||
| 112 | UINT8 m6510_device::dir_r() | |
| 113 | { | |
| 114 | return dir; | |
| 115 | } | |
| 116 | ||
| 117 | UINT8 m6510_device::port_r() | |
| 118 | { | |
| 119 | return ((read_port() | (floating & drive)) & ~dir) | (port & dir); | |
| 120 | } | |
| 121 | ||
| 122 | void m6510_device::dir_w(UINT8 data) | |
| 123 | { | |
| 124 | dir = data; | |
| 125 | update_port(); | |
| 126 | } | |
| 127 | ||
| 128 | void m6510_device::port_w(UINT8 data) | |
| 129 | { | |
| 130 | port = data; | |
| 131 | update_port(); | |
| 132 | } | |
| 133 | ||
| 134 | ||
| 135 | m6510_device::mi_6510_normal::mi_6510_normal(m6510_device *_base) | |
| 136 | { | |
| 137 | base = _base; | |
| 138 | } | |
| 139 | ||
| 140 | UINT8 m6510_device::mi_6510_normal::read(UINT16 adr) | |
| 141 | { | |
| 142 | UINT8 res = program->read_byte(adr); | |
| 143 | if(adr == 0x0000) | |
| 144 | res = base->dir_r(); | |
| 145 | else if(adr == 0x0001) | |
| 146 | res = base->port_r(); | |
| 147 | return res; | |
| 148 | } | |
| 149 | ||
| 150 | UINT8 m6510_device::mi_6510_normal::read_direct(UINT16 adr) | |
| 151 | { | |
| 152 | UINT8 res = direct->read_raw_byte(adr); | |
| 153 | if(adr == 0x0000) | |
| 154 | res = base->dir_r(); | |
| 155 | else if(adr == 0x0001) | |
| 156 | res = base->port_r(); | |
| 157 | return res; | |
| 158 | } | |
| 159 | ||
| 160 | UINT8 m6510_device::mi_6510_normal::read_decrypted(UINT16 adr) | |
| 161 | { | |
| 162 | UINT8 res = direct->read_decrypted_byte(adr); | |
| 163 | if(adr == 0x0000) | |
| 164 | res = base->dir_r(); | |
| 165 | else if(adr == 0x0001) | |
| 166 | res = base->port_r(); | |
| 167 | return res; | |
| 168 | } | |
| 169 | ||
| 170 | void m6510_device::mi_6510_normal::write(UINT16 adr, UINT8 val) | |
| 171 | { | |
| 172 | program->write_byte(adr, val); | |
| 173 | if(adr == 0x0000) | |
| 174 | base->dir_w(val); | |
| 175 | else if(adr == 0x0001) | |
| 176 | base->port_w(val); | |
| 177 | } | |
| 178 | ||
| 179 | m6510_device::mi_6510_nd::mi_6510_nd(m6510_device *_base) : mi_6510_normal(_base) | |
| 180 | { | |
| 181 | } | |
| 182 | ||
| 183 | UINT8 m6510_device::mi_6510_nd::read_direct(UINT16 adr) | |
| 184 | { | |
| 185 | return read(adr); | |
| 186 | } | |
| 187 | ||
| 188 | UINT8 m6510_device::mi_6510_nd::read_decrypted(UINT16 adr) | |
| 189 | { | |
| 190 | return read(adr); | |
| 191 | } | |
| 192 | ||
| 193 | #include "cpu/m6502/m6510.inc" |
| r18874 | r18875 | |
|---|---|---|
| 1 | /*************************************************************************** | |
| 2 | ||
| 3 | m7501.c | |
| 4 | ||
| 5 | 6510 derivative, essentially identical. Also known as the 8501. | |
| 6 | ||
| 7 | **************************************************************************** | |
| 8 | ||
| 9 | Copyright Olivier Galibert | |
| 10 | All rights reserved. | |
| 11 | ||
| 12 | Redistribution and use in source and binary forms, with or without | |
| 13 | modification, are permitted provided that the following conditions are | |
| 14 | met: | |
| 15 | ||
| 16 | * Redistributions of source code must retain the above copyright | |
| 17 | notice, this list of conditions and the following disclaimer. | |
| 18 | * Redistributions in binary form must reproduce the above copyright | |
| 19 | notice, this list of conditions and the following disclaimer in | |
| 20 | the documentation and/or other materials provided with the | |
| 21 | distribution. | |
| 22 | * Neither the name 'MAME' nor the names of its contributors may be | |
| 23 | used to endorse or promote products derived from this software | |
| 24 | without specific prior written permission. | |
| 25 | ||
| 26 | THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR | |
| 27 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 28 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 29 | DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, | |
| 30 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 31 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
| 32 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 33 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
| 34 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
| 35 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| 36 | POSSIBILITY OF SUCH DAMAGE. | |
| 37 | ||
| 38 | ***************************************************************************/ | |
| 39 | ||
| 40 | #include "emu.h" | |
| 41 | #include "m7501.h" | |
| 42 | ||
| 43 | const device_type M7501 = &device_creator<m7501_device>; | |
| 44 | ||
| 45 | m7501_device::m7501_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : | |
| 46 | m6510_device(mconfig, M7501, "M7501", tag, owner, clock) | |
| 47 | { | |
| 48 | } |
| r18874 | r18875 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * m4510.c | |
| 4 | * Portable 4510 emulator V1.0beta | |
| 5 | * | |
| 6 | * Copyright Peter Trauner, all rights reserved. | |
| 7 | * | |
| 8 | * - This source code is released as freeware for non-commercial purposes. | |
| 9 | * - You are free to use and redistribute this code in modified or | |
| 10 | * unmodified form, provided you list me in the credits. | |
| 11 | * - If you modify this source code, you must add a notice to each modified | |
| 12 | * source file that it has been changed. If you're a nice person, you | |
| 13 | * will clearly mark each change too. :) | |
| 14 | * - If you wish to use this for commercial purposes, please contact me at | |
| 15 | * pullmoll@t-online.de | |
| 16 | * - The author of this copywritten work reserves the right to change the | |
| 17 | * terms of its usage and license at any time, including retroactively | |
| 18 | * - This entire notice must remain in the source code. | |
| 19 | * | |
| 20 | *****************************************************************************/ | |
| 1 | /*************************************************************************** | |
| 21 | 2 | |
| 22 | ||
| 3 | m4510.h | |
| 23 | 4 | |
| 5 | 65ce02 with a mmu and a port | |
| 6 | ||
| 7 | **************************************************************************** | |
| 8 | ||
| 9 | Copyright Olivier Galibert | |
| 10 | All rights reserved. | |
| 11 | ||
| 12 | Redistribution and use in source and binary forms, with or without | |
| 13 | modification, are permitted provided that the following conditions are | |
| 14 | met: | |
| 15 | ||
| 16 | * Redistributions of source code must retain the above copyright | |
| 17 | notice, this list of conditions and the following disclaimer. | |
| 18 | * Redistributions in binary form must reproduce the above copyright | |
| 19 | notice, this list of conditions and the following disclaimer in | |
| 20 | the documentation and/or other materials provided with the | |
| 21 | distribution. | |
| 22 | * Neither the name 'MAME' nor the names of its contributors may be | |
| 23 | used to endorse or promote products derived from this software | |
| 24 | without specific prior written permission. | |
| 25 | ||
| 26 | THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR | |
| 27 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 28 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 29 | DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, | |
| 30 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 31 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
| 32 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 33 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
| 34 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
| 35 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| 36 | POSSIBILITY OF SUCH DAMAGE. | |
| 37 | ||
| 38 | ***************************************************************************/ | |
| 39 | ||
| 24 | 40 | #ifndef __M4510_H__ |
| 25 | 41 | #define __M4510_H__ |
| 26 | 42 | |
| 27 | #include "m6502.h" | |
| 43 | #include "m65ce02.h" | |
| 28 | 44 | |
| 45 | class m4510_device : public m65ce02_device { | |
| 46 | public: | |
| 47 | m4510_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 29 | 48 | |
| 30 | enum | |
| 31 | { | |
| 32 | M4510_PC=1, M4510_S, M4510_P, M4510_A, M4510_X, M4510_Y, | |
| 33 | M4510_Z, M4510_B, M4510_EA, M4510_ZP, | |
| 34 | M4510_NMI_STATE, M4510_IRQ_STATE, | |
| 35 | M4510_MEM_LOW,M4510_MEM_HIGH, | |
| 36 | M4510_MEM0, M4510_MEM1, M4510_MEM2, M4510_MEM3, | |
| 37 | M4510_MEM4, M4510_MEM5, M4510_MEM6, M4510_MEM7 | |
| 38 | }; | |
| 49 | static const disasm_entry disasm_entries[0x100]; | |
| 39 | 50 | |
| 40 | #define M4510_IRQ_LINE M6502_IRQ_LINE | |
| 51 | virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options); | |
| 52 | virtual void do_exec_full(); | |
| 53 | virtual void do_exec_partial(); | |
| 41 | 54 | |
| 42 | ||
| 55 | bool get_nomap() const { return nomap; } | |
| 43 | 56 | |
| 57 | protected: | |
| 58 | UINT32 map_offset[2]; | |
| 59 | UINT8 map_enable; | |
| 60 | bool nomap; | |
| 44 | 61 | |
| 45 | extern CPU_DISASSEMBLE( m4510 ); | |
| 62 | class mi_4510_normal : public memory_interface { | |
| 63 | public: | |
| 64 | m4510_device *base; | |
| 46 | 65 | |
| 47 | UINT8 m4510_get_port(legacy_cpu_device *device); | |
| 66 | mi_4510_normal(m4510_device *base); | |
| 67 | virtual UINT8 read(UINT16 adr); | |
| 68 | virtual UINT8 read_direct(UINT16 adr); | |
| 69 | virtual UINT8 read_decrypted(UINT16 adr); | |
| 70 | virtual void write(UINT16 adr, UINT8 val); | |
| 71 | }; | |
| 48 | 72 | |
| 49 | #endif /* __M4510_H__ */ | |
| 73 | class mi_4510_nd : public mi_4510_normal { | |
| 74 | public: | |
| 75 | mi_4510_nd(m4510_device *base); | |
| 76 | virtual UINT8 read_direct(UINT16 adr); | |
| 77 | virtual UINT8 read_decrypted(UINT16 adr); | |
| 78 | }; | |
| 79 | ||
| 80 | virtual void device_start(); | |
| 81 | virtual void device_reset(); | |
| 82 | ||
| 83 | inline UINT32 map(UINT16 adr) { | |
| 84 | if(map_enable & (1 << (adr >> 13))) { | |
| 85 | nomap = false; | |
| 86 | return adr + map_offset[adr >> 15]; | |
| 87 | } | |
| 88 | nomap = true; | |
| 89 | return adr; | |
| 90 | } | |
| 91 | ||
| 92 | #define O(o) void o ## _full(); void o ## _partial() | |
| 93 | ||
| 94 | // 4510 opcodes | |
| 95 | O(eom_imp); | |
| 96 | O(map_imp); | |
| 97 | ||
| 98 | #undef O | |
| 99 | }; | |
| 100 | ||
| 101 | enum { | |
| 102 | M4510_IRQ_LINE = m6502_device::IRQ_LINE, | |
| 103 | M4510_NMI_LINE = m6502_device::NMI_LINE, | |
| 104 | }; | |
| 105 | ||
| 106 | extern const device_type M4510; | |
| 107 | ||
| 108 | #endif |
| r18874 | r18875 | |
|---|---|---|
| 1 | # m65c02 opcodes | |
| 2 | ||
| 3 | adc_c_aba | |
| 4 | TMP = read_pc(); | |
| 5 | TMP = set_h(TMP, read_pc()); | |
| 6 | TMP = read(TMP); | |
| 7 | do_adc(TMP); | |
| 8 | if(P & F_D) { | |
| 9 | read_pc_noinc(); | |
| 10 | set_nz(A); | |
| 11 | } | |
| 12 | prefetch(); | |
| 13 | ||
| 14 | adc_c_abx | |
| 15 | TMP = read_pc(); | |
| 16 | TMP = set_h(TMP, read_pc()); | |
| 17 | if(page_changing(TMP, X)) { | |
| 18 | read(set_l(TMP, TMP+X)); | |
| 19 | } | |
| 20 | TMP += X; | |
| 21 | TMP = read(TMP); | |
| 22 | do_adc(TMP); | |
| 23 | if(P & F_D) { | |
| 24 | read_pc_noinc(); | |
| 25 | set_nz(A); | |
| 26 | } | |
| 27 | prefetch(); | |
| 28 | ||
| 29 | adc_c_aby | |
| 30 | TMP = read_pc(); | |
| 31 | TMP = set_h(TMP, read_pc()); | |
| 32 | if(page_changing(TMP, Y)) { | |
| 33 | read(set_l(TMP, TMP+Y)); | |
| 34 | } | |
| 35 | TMP += Y; | |
| 36 | TMP = read(TMP); | |
| 37 | do_adc(TMP); | |
| 38 | if(P & F_D) { | |
| 39 | read_pc_noinc(); | |
| 40 | set_nz(A); | |
| 41 | } | |
| 42 | prefetch(); | |
| 43 | ||
| 44 | adc_c_idx | |
| 45 | TMP2 = read_pc(); | |
| 46 | read(TMP2); | |
| 47 | TMP2 += X; | |
| 48 | TMP = read(TMP2 & 0xff); | |
| 49 | TMP = set_h(TMP, read((TMP2+1) & 0xff)); | |
| 50 | do_adc(read(TMP)); | |
| 51 | if(P & F_D) { | |
| 52 | read_pc_noinc(); | |
| 53 | set_nz(A); | |
| 54 | } | |
| 55 | prefetch(); | |
| 56 | ||
| 57 | adc_c_idy | |
| 58 | TMP2 = read_pc(); | |
| 59 | TMP = read(TMP2); | |
| 60 | TMP = set_h(TMP, read(TMP2+1)); | |
| 61 | if(page_changing(TMP, Y)) { | |
| 62 | read(set_l(TMP, TMP+Y)); | |
| 63 | } | |
| 64 | do_adc(read(TMP+Y)); | |
| 65 | if(P & F_D) { | |
| 66 | read_pc_noinc(); | |
| 67 | set_nz(A); | |
| 68 | } | |
| 69 | prefetch(); | |
| 70 | ||
| 71 | adc_c_imm | |
| 72 | TMP = read_pc(); | |
| 73 | do_adc(TMP); | |
| 74 | if(P & F_D) { | |
| 75 | read_pc_noinc(); | |
| 76 | set_nz(A); | |
| 77 | } | |
| 78 | prefetch(); | |
| 79 | ||
| 80 | adc_c_zpg | |
| 81 | TMP = read_pc(); | |
| 82 | TMP = read(TMP); | |
| 83 | do_adc(TMP); | |
| 84 | if(P & F_D) { | |
| 85 | read_pc_noinc(); | |
| 86 | set_nz(A); | |
| 87 | } | |
| 88 | prefetch(); | |
| 89 | ||
| 90 | adc_c_zpi | |
| 91 | TMP2 = read_pc(); | |
| 92 | TMP = read(TMP2 & 0xff); | |
| 93 | TMP = set_h(TMP, read((TMP2+1) & 0xff)); | |
| 94 | do_adc(read(TMP)); | |
| 95 | if(P & F_D) { | |
| 96 | read_pc_noinc(); | |
| 97 | set_nz(A); | |
| 98 | } | |
| 99 | prefetch(); | |
| 100 | ||
| 101 | adc_c_zpx | |
| 102 | TMP = read_pc(); | |
| 103 | read(TMP); | |
| 104 | TMP = read(UINT8(TMP+X)); | |
| 105 | do_adc(TMP); | |
| 106 | if(P & F_D) { | |
| 107 | read_pc_noinc(); | |
| 108 | set_nz(A); | |
| 109 | } | |
| 110 | prefetch(); | |
| 111 | ||
| 112 | and_zpi | |
| 113 | TMP2 = read_pc(); | |
| 114 | TMP = read(TMP2 & 0xff); | |
| 115 | TMP = set_h(TMP, read((TMP2+1) & 0xff)); | |
| 116 | A &= read(TMP); | |
| 117 | set_nz(A); | |
| 118 | prefetch(); | |
| 119 | ||
| 120 | asl_c_abx | |
| 121 | TMP = read_pc(); | |
| 122 | TMP = set_h(TMP, read_pc()); | |
| 123 | if(page_changing(TMP, X)) { | |
| 124 | read(set_l(TMP, TMP+X)); | |
| 125 | } | |
| 126 | TMP += X; | |
| 127 | TMP2 = read(TMP); | |
| 128 | write(TMP, TMP2); | |
| 129 | TMP2 = do_asl(TMP2); | |
| 130 | write(TMP, TMP2); | |
| 131 | prefetch(); | |
| 132 | ||
| 133 | bbr_zpb | |
| 134 | // Access pattern uncertain | |
| 135 | TMP = read_pc(); | |
| 136 | TMP2 = read(TMP); | |
| 137 | TMP = read_pc(); | |
| 138 | read_pc_noinc(); | |
| 139 | if(!(TMP2 & (1 << (inst_state & 7)))) { | |
| 140 | PC += INT8(TMP); | |
| 141 | } | |
| 142 | prefetch(); | |
| 143 | ||
| 144 | bbs_zpb | |
| 145 | // Access pattern uncertain | |
| 146 | TMP = read_pc(); | |
| 147 | TMP2 = read(TMP); | |
| 148 | TMP = read_pc(); | |
| 149 | read_pc_noinc(); | |
| 150 | if(TMP2 & (1 << (inst_state & 7))) { | |
| 151 | PC += INT8(TMP); | |
| 152 | } | |
| 153 | prefetch(); | |
| 154 | ||
| 155 | bit_abx | |
| 156 | TMP = read_pc(); | |
| 157 | TMP = set_h(TMP, read_pc()); | |
| 158 | if(page_changing(TMP, X)) { | |
| 159 | read(set_l(TMP, TMP+X)); | |
| 160 | } | |
| 161 | TMP += X; | |
| 162 | do_bit(read(TMP)); | |
| 163 | prefetch(); | |
| 164 | ||
| 165 | bit_imm | |
| 166 | TMP = read_pc(); | |
| 167 | if(A & TMP) | |
| 168 | P &= ~F_Z; | |
| 169 | else | |
| 170 | P |= F_Z; | |
| 171 | prefetch(); | |
| 172 | ||
| 173 | bit_zpx | |
| 174 | TMP = read_pc(); | |
| 175 | read(TMP); | |
| 176 | TMP = read(UINT8(TMP+X)); | |
| 177 | do_bit(TMP); | |
| 178 | prefetch(); | |
| 179 | ||
| 180 | bra_rel | |
| 181 | TMP = read_pc(); | |
| 182 | read_pc_noinc(); | |
| 183 | if(page_changing(PC, INT8(TMP))) { | |
| 184 | read_direct(set_l(PC, PC+INT8(TMP))); | |
| 185 | } | |
| 186 | PC += INT8(TMP); | |
| 187 | prefetch(); | |
| 188 | ||
| 189 | brk_c_imp | |
| 190 | if(irq_taken || nmi_state) { | |
| 191 | read_pc_noinc(); | |
| 192 | } else { | |
| 193 | read_pc(); | |
| 194 | } | |
| 195 | write(SP, PC >> 8); | |
| 196 | dec_SP(); | |
| 197 | write(SP, PC); | |
| 198 | dec_SP(); | |
| 199 | write(SP, irq_taken || nmi_state ? P & ~F_B : P); | |
| 200 | dec_SP(); | |
| 201 | if(irq_taken && nmi_state) { | |
| 202 | PC = read_direct(0xfffa); | |
| 203 | PC = set_h(PC, read_direct(0xfffb)); | |
| 204 | nmi_state = false; | |
| 205 | } else { | |
| 206 | PC = read_direct(0xfffe); | |
| 207 | PC = set_h(PC, read_direct(0xffff)); | |
| 208 | } | |
| 209 | irq_taken = false; | |
| 210 | P = (P | F_I) & ~F_D; // Do *not* move after the prefetch | |
| 211 | prefetch(); | |
| 212 | inst_state = -1; | |
| 213 | ||
| 214 | cmp_zpi | |
| 215 | TMP2 = read_pc(); | |
| 216 | TMP = read(TMP2 & 0xff); | |
| 217 | TMP = set_h(TMP, read((TMP2+1) & 0xff)); | |
| 218 | do_cmp(A, read(TMP)); | |
| 219 | prefetch(); | |
| 220 | ||
| 221 | dec_acc | |
| 222 | read_pc_noinc(); | |
| 223 | A--; | |
| 224 | set_nz(A); | |
| 225 | prefetch(); | |
| 226 | ||
| 227 | eor_zpi | |
| 228 | TMP2 = read_pc(); | |
| 229 | TMP = read(TMP2 & 0xff); | |
| 230 | TMP = set_h(TMP, read((TMP2+1) & 0xff)); | |
| 231 | A ^= read(TMP); | |
| 232 | set_nz(A); | |
| 233 | prefetch(); | |
| 234 | ||
| 235 | inc_acc | |
| 236 | read_pc_noinc(); | |
| 237 | A++; | |
| 238 | set_nz(A); | |
| 239 | prefetch(); | |
| 240 | ||
| 241 | jmp_iax | |
| 242 | TMP = read_pc(); | |
| 243 | TMP = set_h(TMP, read_pc()); | |
| 244 | read(set_l(TMP, TMP+X)); | |
| 245 | TMP += X; | |
| 246 | PC = read(TMP); | |
| 247 | PC = set_h(PC, read(TMP+1)); | |
| 248 | prefetch(); | |
| 249 | ||
| 250 | jmp_c_ind | |
| 251 | TMP = read_pc(); | |
| 252 | TMP = set_h(TMP, read_pc()); | |
| 253 | PC = read(TMP); | |
| 254 | read(set_l(TMP, TMP+1)); | |
| 255 | PC = set_h(PC, read(TMP+1)); | |
| 256 | prefetch(); | |
| 257 | ||
| 258 | lda_zpi | |
| 259 | TMP2 = read_pc(); | |
| 260 | TMP = read(TMP2 & 0xff); | |
| 261 | TMP = set_h(TMP, read((TMP2+1) & 0xff)); | |
| 262 | A = read(TMP); | |
| 263 | set_nz(A); | |
| 264 | prefetch(); | |
| 265 | ||
| 266 | ||
| 267 | lsr_c_abx | |
| 268 | TMP = read_pc(); | |
| 269 | TMP = set_h(TMP, read_pc()); | |
| 270 | if(page_changing(TMP, X)) { | |
| 271 | read(set_l(TMP, TMP+X)); | |
| 272 | } | |
| 273 | TMP += X; | |
| 274 | TMP2 = read(TMP); | |
| 275 | write(TMP, TMP2); | |
| 276 | TMP2 = do_lsr(TMP2); | |
| 277 | write(TMP, TMP2); | |
| 278 | prefetch(); | |
| 279 | ||
| 280 | nop_c_imp | |
| 281 | prefetch(); | |
| 282 | ||
| 283 | nop_c_aba | |
| 284 | read_pc(); | |
| 285 | read_pc(); | |
| 286 | read_pc_noinc(); | |
| 287 | read_pc_noinc(); | |
| 288 | read_pc_noinc(); | |
| 289 | read_pc_noinc(); | |
| 290 | read_pc_noinc(); | |
| 291 | prefetch(); | |
| 292 | ||
| 293 | nop_c_abx | |
| 294 | TMP = read_pc(); | |
| 295 | TMP = set_h(TMP, read_pc()); | |
| 296 | read(set_l(TMP, TMP+X)); | |
| 297 | prefetch(); | |
| 298 | ||
| 299 | ora_zpi | |
| 300 | TMP2 = read_pc(); | |
| 301 | TMP = read(TMP2 & 0xff); | |
| 302 | TMP = set_h(TMP, read((TMP2+1) & 0xff)); | |
| 303 | A |= read(TMP); | |
| 304 | set_nz(A); | |
| 305 | prefetch(); | |
| 306 | ||
| 307 | phx_imp | |
| 308 | read_pc_noinc(); | |
| 309 | write(SP, X); | |
| 310 | dec_SP(); | |
| 311 | prefetch(); | |
| 312 | ||
| 313 | phy_imp | |
| 314 | read_pc_noinc(); | |
| 315 | write(SP, Y); | |
| 316 | dec_SP(); | |
| 317 | prefetch(); | |
| 318 | ||
| 319 | plx_imp | |
| 320 | read_pc_noinc(); | |
| 321 | read(SP); | |
| 322 | inc_SP(); | |
| 323 | X = read(SP); | |
| 324 | set_nz(X); | |
| 325 | prefetch(); | |
| 326 | ||
| 327 | ply_imp | |
| 328 | read_pc_noinc(); | |
| 329 | read(SP); | |
| 330 | inc_SP(); | |
| 331 | Y = read(SP); | |
| 332 | set_nz(Y); | |
| 333 | prefetch(); | |
| 334 | ||
| 335 | rmb_bzp | |
| 336 | // Access pattern unknown but probable (built upon inc_zpg) | |
| 337 | TMP = read_pc(); | |
| 338 | TMP2 = read(TMP); | |
| 339 | write(TMP, TMP2); | |
| 340 | TMP2 &= ~(1 << (inst_state & 7)); | |
| 341 | write(TMP, TMP2); | |
| 342 | prefetch(); | |
| 343 | ||
| 344 | rol_c_abx | |
| 345 | TMP = read_pc(); | |
| 346 | TMP = set_h(TMP, read_pc()); | |
| 347 | if(page_changing(TMP, X)) { | |
| 348 | read(set_l(TMP, TMP+X)); | |
| 349 | } | |
| 350 | TMP += X; | |
| 351 | TMP2 = read(TMP); | |
| 352 | write(TMP, TMP2); | |
| 353 | TMP2 = do_rol(TMP2); | |
| 354 | write(TMP, TMP2); | |
| 355 | prefetch(); | |
| 356 | ||
| 357 | ||
| 358 | ror_c_abx | |
| 359 | TMP = read_pc(); | |
| 360 | TMP = set_h(TMP, read_pc()); | |
| 361 | if(page_changing(TMP, X)) { | |
| 362 | read(set_l(TMP, TMP+X)); | |
| 363 | } | |
| 364 | TMP += X; | |
| 365 | TMP2 = read(TMP); | |
| 366 | write(TMP, TMP2); | |
| 367 | TMP2 = do_ror(TMP2); | |
| 368 | write(TMP, TMP2); | |
| 369 | prefetch(); | |
| 370 | ||
| 371 | sbc_c_aba | |
| 372 | TMP = read_pc(); | |
| 373 | TMP = set_h(TMP, read_pc()); | |
| 374 | TMP = read(TMP); | |
| 375 | do_sbc(TMP); | |
| 376 | if(P & F_D) { | |
| 377 | read_pc_noinc(); | |
| 378 | set_nz(A); | |
| 379 | } | |
| 380 | prefetch(); | |
| 381 | ||
| 382 | sbc_c_abx | |
| 383 | TMP = read_pc(); | |
| 384 | TMP = set_h(TMP, read_pc()); | |
| 385 | if(page_changing(TMP, X)) { | |
| 386 | read(set_l(TMP, TMP+X)); | |
| 387 | } | |
| 388 | TMP += X; | |
| 389 | TMP = read(TMP); | |
| 390 | do_sbc(TMP); | |
| 391 | if(P & F_D) { | |
| 392 | read_pc_noinc(); | |
| 393 | set_nz(A); | |
| 394 | } | |
| 395 | prefetch(); | |
| 396 | ||
| 397 | sbc_c_aby | |
| 398 | TMP = read_pc(); | |
| 399 | TMP = set_h(TMP, read_pc()); | |
| 400 | if(page_changing(TMP, Y)) { | |
| 401 | read(set_l(TMP, TMP+Y)); | |
| 402 | } | |
| 403 | TMP += Y; | |
| 404 | TMP = read(TMP); | |
| 405 | do_sbc(TMP); | |
| 406 | if(P & F_D) { | |
| 407 | read_pc_noinc(); | |
| 408 | set_nz(A); | |
| 409 | } | |
| 410 | prefetch(); | |
| 411 | ||
| 412 | sbc_c_idx | |
| 413 | TMP2 = read_pc(); | |
| 414 | read(TMP2); | |
| 415 | TMP2 += X; | |
| 416 | TMP = read(TMP2 & 0xff); | |
| 417 | TMP = set_h(TMP, read((TMP2+1) & 0xff)); | |
| 418 | do_sbc(read(TMP)); | |
| 419 | if(P & F_D) { | |
| 420 | read_pc_noinc(); | |
| 421 | set_nz(A); | |
| 422 | } | |
| 423 | prefetch(); | |
| 424 | ||
| 425 | sbc_c_idy | |
| 426 | TMP2 = read_pc(); | |
| 427 | TMP = read(TMP2); | |
| 428 | TMP = set_h(TMP, read(TMP2+1)); | |
| 429 | if(page_changing(TMP, Y)) { | |
| 430 | read(set_l(TMP, TMP+Y)); | |
| 431 | } | |
| 432 | do_sbc(read(TMP+Y)); | |
| 433 | if(P & F_D) { | |
| 434 | read_pc_noinc(); | |
| 435 | set_nz(A); | |
| 436 | } | |
| 437 | prefetch(); | |
| 438 | ||
| 439 | sbc_c_imm | |
| 440 | TMP = read_pc(); | |
| 441 | do_sbc(TMP); | |
| 442 | if(P & F_D) { | |
| 443 | read_pc_noinc(); | |
| 444 | set_nz(A); | |
| 445 | } | |
| 446 | prefetch(); | |
| 447 | ||
| 448 | sbc_c_zpg | |
| 449 | TMP = read_pc(); | |
| 450 | TMP = read(TMP); | |
| 451 | do_sbc(TMP); | |
| 452 | if(P & F_D) { | |
| 453 | read_pc_noinc(); | |
| 454 | set_nz(A); | |
| 455 | } | |
| 456 | prefetch(); | |
| 457 | ||
| 458 | sbc_c_zpi | |
| 459 | TMP2 = read_pc(); | |
| 460 | TMP = read(TMP2 & 0xff); | |
| 461 | TMP = set_h(TMP, read((TMP2+1) & 0xff)); | |
| 462 | do_sbc(read(TMP)); | |
| 463 | if(P & F_D) { | |
| 464 | read_pc_noinc(); | |
| 465 | set_nz(A); | |
| 466 | } | |
| 467 | prefetch(); | |
| 468 | ||
| 469 | sbc_c_zpx | |
| 470 | TMP = read_pc(); | |
| 471 | read(TMP); | |
| 472 | TMP = read(UINT8(TMP+X)); | |
| 473 | do_sbc(TMP); | |
| 474 | if(P & F_D) { | |
| 475 | read_pc_noinc(); | |
| 476 | set_nz(A); | |
| 477 | } | |
| 478 | prefetch(); | |
| 479 | ||
| 480 | smb_bzp | |
| 481 | // Access pattern unknown but probable (built upon inc_zpg) | |
| 482 | TMP = read_pc(); | |
| 483 | TMP2 = read(TMP); | |
| 484 | write(TMP, TMP2); | |
| 485 | TMP2 |= 1 << (inst_state & 7); | |
| 486 | write(TMP, TMP2); | |
| 487 | prefetch(); | |
| 488 | ||
| 489 | sta_zpi | |
| 490 | TMP2 = read_pc(); | |
| 491 | TMP = read(TMP2 & 0xff); | |
| 492 | TMP = set_h(TMP, read((TMP2+1) & 0xff)); | |
| 493 | write(TMP, A); | |
| 494 | prefetch(); | |
| 495 | ||
| 496 | stp_imp | |
| 497 | for(;;) { | |
| 498 | eat-all-cycles; | |
| 499 | } | |
| 500 | ||
| 501 | stz_aba | |
| 502 | TMP = read_pc(); | |
| 503 | TMP = set_h(TMP, read_pc()); | |
| 504 | write(TMP, 0x00); | |
| 505 | prefetch(); | |
| 506 | ||
| 507 | stz_abx | |
| 508 | TMP = read_pc(); | |
| 509 | TMP = set_h(TMP, read_pc()); | |
| 510 | read(set_l(TMP, TMP+X)); | |
| 511 | write(TMP+X, 0x00); | |
| 512 | prefetch(); | |
| 513 | ||
| 514 | stz_zpg | |
| 515 | TMP = read_pc(); | |
| 516 | write(TMP, 0x00); | |
| 517 | prefetch(); | |
| 518 | ||
| 519 | stz_zpx | |
| 520 | TMP = read_pc(); | |
| 521 | read(TMP); | |
| 522 | write(UINT8(TMP+X), 0x00); | |
| 523 | prefetch(); | |
| 524 | ||
| 525 | trb_aba | |
| 526 | TMP = read_pc(); | |
| 527 | TMP = set_h(TMP, read_pc()); | |
| 528 | TMP2 = read(TMP); | |
| 529 | write(TMP, TMP2); | |
| 530 | if(A & TMP2) | |
| 531 | P &= ~F_Z; | |
| 532 | else | |
| 533 | P |= F_Z; | |
| 534 | TMP2 &= ~A; | |
| 535 | write(TMP, TMP2); | |
| 536 | prefetch(); | |
| 537 | ||
| 538 | trb_zpg | |
| 539 | TMP = read_pc(); | |
| 540 | TMP2 = read(TMP); | |
| 541 | write(TMP, TMP2); | |
| 542 | if(A & TMP2) | |
| 543 | P &= ~F_Z; | |
| 544 | else | |
| 545 | P |= F_Z; | |
| 546 | TMP2 &= ~A; | |
| 547 | write(TMP, TMP2); | |
| 548 | prefetch(); | |
| 549 | ||
| 550 | tsb_aba | |
| 551 | TMP = read_pc(); | |
| 552 | TMP = set_h(TMP, read_pc()); | |
| 553 | TMP2 = read(TMP); | |
| 554 | write(TMP, TMP2); | |
| 555 | if(A & TMP2) | |
| 556 | P &= ~F_Z; | |
| 557 | else | |
| 558 | P |= F_Z; | |
| 559 | TMP2 |= A; | |
| 560 | write(TMP, TMP2); | |
| 561 | prefetch(); | |
| 562 | ||
| 563 | tsb_zpg | |
| 564 | TMP = read_pc(); | |
| 565 | TMP2 = read(TMP); | |
| 566 | write(TMP, TMP2); | |
| 567 | if(A & TMP2) | |
| 568 | P &= ~F_Z; | |
| 569 | else | |
| 570 | P |= F_Z; | |
| 571 | TMP2 |= A; | |
| 572 | write(TMP, TMP2); | |
| 573 | prefetch(); | |
| 574 | ||
| 575 | wai_imp | |
| 576 | read_pc_noinc(); | |
| 577 | read_pc_noinc(); | |
| 578 | while(!nmi_state && !irq_state) { | |
| 579 | eat-all-cycles; | |
| 580 | } | |
| 581 | prefetch(); |
| r18874 | r18875 | |
|---|---|---|
| 1 | /*************************************************************************** | |
| 2 | ||
| 3 | m65c02.c | |
| 4 | ||
| 5 | Mostek 6502, CMOS variant with some additional instructions (but | |
| 6 | not the bitwise ones) | |
| 7 | ||
| 8 | **************************************************************************** | |
| 9 | ||
| 10 | Copyright Olivier Galibert | |
| 11 | All rights reserved. | |
| 12 | ||
| 13 | Redistribution and use in source and binary forms, with or without | |
| 14 | modification, are permitted provided that the following conditions are | |
| 15 | met: | |
| 16 | ||
| 17 | * Redistributions of source code must retain the above copyright | |
| 18 | notice, this list of conditions and the following disclaimer. | |
| 19 | * Redistributions in binary form must reproduce the above copyright | |
| 20 | notice, this list of conditions and the following disclaimer in | |
| 21 | the documentation and/or other materials provided with the | |
| 22 | distribution. | |
| 23 | * Neither the name 'MAME' nor the names of its contributors may be | |
| 24 | used to endorse or promote products derived from this software | |
| 25 | without specific prior written permission. | |
| 26 | ||
| 27 | THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR | |
| 28 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 29 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 30 | DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, | |
| 31 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 32 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
| 33 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 34 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
| 35 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
| 36 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| 37 | POSSIBILITY OF SUCH DAMAGE. | |
| 38 | ||
| 39 | ***************************************************************************/ | |
| 40 | ||
| 41 | #include "emu.h" | |
| 42 | #include "m65c02.h" | |
| 43 | ||
| 44 | const device_type M65C02 = &device_creator<m65c02_device>; | |
| 45 | ||
| 46 | m65c02_device::m65c02_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : | |
| 47 | m6502_device(mconfig, M65C02, "M65C02", tag, owner, clock) | |
| 48 | { | |
| 49 | } | |
| 50 | ||
| 51 | m65c02_device::m65c02_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) : | |
| 52 | m6502_device(mconfig, type, name, tag, owner, clock) | |
| 53 | { | |
| 54 | } | |
| 55 | ||
| 56 | offs_t m65c02_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) | |
| 57 | { | |
| 58 | return disassemble_generic(buffer, pc, oprom, opram, options, disasm_entries); | |
| 59 | } | |
| 60 | ||
| 61 | #include "cpu/m6502/m65c02.inc" |
| r18874 | r18875 | |
|---|---|---|
| 1 | /*************************************************************************** | |
| 2 | ||
| 3 | m6510.h | |
| 4 | ||
| 5 | 6502 with 6 i/o pins, also known as 8500 | |
| 6 | ||
| 7 | **************************************************************************** | |
| 8 | ||
| 9 | Copyright Olivier Galibert | |
| 10 | All rights reserved. | |
| 11 | ||
| 12 | Redistribution and use in source and binary forms, with or without | |
| 13 | modification, are permitted provided that the following conditions are | |
| 14 | met: | |
| 15 | ||
| 16 | * Redistributions of source code must retain the above copyright | |
| 17 | notice, this list of conditions and the following disclaimer. | |
| 18 | * Redistributions in binary form must reproduce the above copyright | |
| 19 | notice, this list of conditions and the following disclaimer in | |
| 20 | the documentation and/or other materials provided with the | |
| 21 | distribution. | |
| 22 | * Neither the name 'MAME' nor the names of its contributors may be | |
| 23 | used to endorse or promote products derived from this software | |
| 24 | without specific prior written permission. | |
| 25 | ||
| 26 | THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR | |
| 27 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 28 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 29 | DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, | |
| 30 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 31 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
| 32 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 33 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
| 34 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
| 35 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| 36 | POSSIBILITY OF SUCH DAMAGE. | |
| 37 | ||
| 38 | ***************************************************************************/ | |
| 39 | ||
| 40 | #ifndef __M6510FAM_H__ | |
| 41 | #define __M6510FAM_H__ | |
| 42 | ||
| 43 | #include "m6502.h" | |
| 44 | ||
| 45 | #define MCFG_M6510_PORT_CALLBACKS(_read, _write) \ | |
| 46 | downcast<m6510_device *>(device)->set_callbacks(DEVCB2_##_read, DEVCB2_##_write); | |
| 47 | ||
| 48 | #define MCFG_M6510_PORT_PULLS(_up, _down) \ | |
| 49 | downcast<m6510_device *>(device)->set_pulls(_up, _down); | |
| 50 | ||
| 51 | class m6510_device : public m6502_device { | |
| 52 | public: | |
| 53 | m6510_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 54 | m6510_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock); | |
| 55 | ||
| 56 | UINT8 get_port(); | |
| 57 | void set_port(UINT8 val); | |
| 58 | void set_pulls(UINT8 pullup, UINT8 pulldown); | |
| 59 | ||
| 60 | template<class _read, class _write> void set_callbacks(_read rd, _write wr) { | |
| 61 | read_port.set_callback(rd); | |
| 62 | write_port.set_callback(wr); | |
| 63 | } | |
| 64 | ||
| 65 | static const disasm_entry disasm_entries[0x100]; | |
| 66 | ||
| 67 | virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options); | |
| 68 | virtual void do_exec_full(); | |
| 69 | virtual void do_exec_partial(); | |
| 70 | ||
| 71 | protected: | |
| 72 | class mi_6510_normal : public memory_interface { | |
| 73 | public: | |
| 74 | m6510_device *base; | |
| 75 | ||
| 76 | mi_6510_normal(m6510_device *base); | |
| 77 | virtual UINT8 read(UINT16 adr); | |
| 78 | virtual UINT8 read_direct(UINT16 adr); | |
| 79 | virtual UINT8 read_decrypted(UINT16 adr); | |
| 80 | virtual void write(UINT16 adr, UINT8 val); | |
| 81 | }; | |
| 82 | ||
| 83 | class mi_6510_nd : public mi_6510_normal { | |
| 84 | public: | |
| 85 | mi_6510_nd(m6510_device *base); | |
| 86 | virtual UINT8 read_direct(UINT16 adr); | |
| 87 | virtual UINT8 read_decrypted(UINT16 adr); | |
| 88 | }; | |
| 89 | ||
| 90 | devcb2_read8 read_port; | |
| 91 | devcb2_write8 write_port; | |
| 92 | ||
| 93 | UINT8 pullup, floating, dir, port, drive; | |
| 94 | ||
| 95 | virtual void device_start(); | |
| 96 | virtual void device_reset(); | |
| 97 | ||
| 98 | UINT8 dir_r(); | |
| 99 | void dir_w(UINT8 data); | |
| 100 | UINT8 port_r(); | |
| 101 | void port_w(UINT8 data); | |
| 102 | ||
| 103 | void update_port(); | |
| 104 | ||
| 105 | #define O(o) void o ## _full(); void o ## _partial() | |
| 106 | ||
| 107 | // 6510 undocumented instructions in a C64 context | |
| 108 | // implementation follows what the test suites expect (usually an extra and) | |
| 109 | O(anc_10_imm); | |
| 110 | O(ane_10_imm); | |
| 111 | O(arr_10_imm); | |
| 112 | O(asr_10_imm); | |
| 113 | O(las_10_aby); | |
| 114 | O(lxa_10_imm); | |
| 115 | ||
| 116 | #undef O | |
| 117 | }; | |
| 118 | ||
| 119 | enum { | |
| 120 | M6510_IRQ_LINE = m6502_device::IRQ_LINE, | |
| 121 | M6510_NMI_LINE = m6502_device::NMI_LINE, | |
| 122 | }; | |
| 123 | ||
| 124 | extern const device_type M6510; | |
| 125 | ||
| 126 | #endif |
| r18874 | r18875 | |
|---|---|---|
| 1003 | 1003 | |
| 1004 | 1004 | ifneq ($(filter M6502,$(CPUS)),) |
| 1005 | 1005 | OBJDIRS += $(CPUOBJ)/m6502 |
| 1006 | CPUOBJS += $(CPUOBJ)/m6502/m6502.o | |
| 1007 | CPUOBJS += $(CPUOBJ)/m6502/m6509.o | |
| 1008 | CPUOBJS += $(CPUOBJ)/m6502/m65ce02.o | |
| 1009 | CPUOBJS += $(CPUOBJ)/m6502/m4510.o | |
| 1010 | DASMOBJS += $(CPUOBJ)/m6502/6502dasm.o | |
| 1006 | CPUOBJS += $(CPUOBJ)/m6502/deco16.o \ | |
| 1007 | $(CPUOBJ)/m6502/m4510.o \ | |
| 1008 | $(CPUOBJ)/m6502/m6502.o \ | |
| 1009 | $(CPUOBJ)/m6502/m65c02.o \ | |
| 1010 | $(CPUOBJ)/m6502/m65ce02.o \ | |
| 1011 | $(CPUOBJ)/m6502/m65sc02.o \ | |
| 1012 | $(CPUOBJ)/m6502/m6504.o \ | |
| 1013 | $(CPUOBJ)/m6502/m6509.o \ | |
| 1014 | $(CPUOBJ)/m6502/m6510.o \ | |
| 1015 | $(CPUOBJ)/m6502/m6510t.o \ | |
| 1016 | $(CPUOBJ)/m6502/m7501.o \ | |
| 1017 | $(CPUOBJ)/m6502/m8502.o \ | |
| 1018 | $(CPUOBJ)/m6502/n2a03.o \ | |
| 1019 | $(CPUOBJ)/m6502/r65c02.o | |
| 1020 | DASMOBJS += | |
| 1021 | M6502MAKE += $(BUILDOUT)/m6502make$(BUILD_EXE) | |
| 1011 | 1022 | endif |
| 1012 | 1023 | |
| 1024 | $(CPUOBJ)/m6502/deco16.o: $(CPUSRC)/m6502/deco16.c \ | |
| 1025 | $(CPUOBJ)/m6502/deco16.inc \ | |
| 1026 | $(CPUSRC)/m6502/deco16.h \ | |
| 1027 | $(CPUSRC)/m6502/m6502.h | |
| 1028 | ||
| 1013 | 1029 | $(CPUOBJ)/m6502/m4510.o: $(CPUSRC)/m6502/m4510.c \ |
| 1014 | $(CPUSRC)/m6502/t65ce02.c | |
| 1030 | $(CPUOBJ)/m6502/m4510.inc \ | |
| 1031 | $(CPUSRC)/m6502/m4510.h \ | |
| 1032 | $(CPUSRC)/m6502/m65ce02.h \ | |
| 1033 | $(CPUSRC)/m6502/m65c02.h \ | |
| 1034 | $(CPUSRC)/m6502/m6502.h | |
| 1015 | 1035 | |
| 1016 | 1036 | $(CPUOBJ)/m6502/m6502.o: $(CPUSRC)/m6502/m6502.c \ |
| 1017 | $(CPUSRC)/m6502/m6502.h \ | |
| 1018 | $(CPUSRC)/m6502/ops02.h \ | |
| 1019 | $(CPUSRC)/m6502/t6502.c \ | |
| 1020 | $(CPUSRC)/m6502/t65c02.c \ | |
| 1021 | $(CPUSRC)/m6502/t65sc02.c \ | |
| 1022 | $(CPUSRC)/m6502/t6510.c \ | |
| 1023 | $(CPUSRC)/m6502/tn2a03.c \ | |
| 1024 | $(CPUSRC)/m6502/tdeco16.c | |
| 1037 | $(CPUOBJ)/m6502/m6502.inc \ | |
| 1038 | $(CPUSRC)/m6502/m6502.h | |
| 1025 | 1039 | |
| 1040 | $(CPUOBJ)/m6502/m65c02.o: $(CPUSRC)/m6502/m65c02.c \ | |
| 1041 | $(CPUOBJ)/m6502/m65c02.inc \ | |
| 1042 | $(CPUSRC)/m6502/m65c02.h \ | |
| 1043 | $(CPUSRC)/m6502/m6502.h | |
| 1044 | ||
| 1026 | 1045 | $(CPUOBJ)/m6502/m65ce02.o: $(CPUSRC)/m6502/m65ce02.c \ |
| 1046 | $(CPUOBJ)/m6502/m65ce02.inc \ | |
| 1027 | 1047 | $(CPUSRC)/m6502/m65ce02.h \ |
| 1028 | $(CPUSRC)/m6502/opsce02.h \ | |
| 1029 | $(CPUSRC)/m6502/t65ce02.c | |
| 1048 | $(CPUSRC)/m6502/m65c02.h \ | |
| 1049 | $(CPUSRC)/m6502/m6502.h | |
| 1030 | 1050 | |
| 1051 | $(CPUOBJ)/m6502/m65sc02.o: $(CPUSRC)/m6502/m65sc02.c \ | |
| 1052 | $(CPUSRC)/m6502/m65sc02.h \ | |
| 1053 | $(CPUSRC)/m6502/r65c02.h \ | |
| 1054 | $(CPUSRC)/m6502/m65c02.h \ | |
| 1055 | $(CPUSRC)/m6502/m6502.h | |
| 1056 | ||
| 1057 | $(CPUOBJ)/m6502/m6504.o: $(CPUSRC)/m6502/m6504.c \ | |
| 1058 | $(CPUSRC)/m6502/m6504.h \ | |
| 1059 | $(CPUSRC)/m6502/m6502.h | |
| 1060 | ||
| 1031 | 1061 | $(CPUOBJ)/m6502/m6509.o: $(CPUSRC)/m6502/m6509.c \ |
| 1032 | $(CPUSRC)/m6502/m6509.h \ | |
| 1033 | $(CPUSRC)/m6502/ops09.h \ | |
| 1034 | $(CPUSRC)/m6502/t6509.c | |
| 1062 | $(CPUOBJ)/m6502/m6509.inc \ | |
| 1063 | $(CPUSRC)/m6502/m6509.h | |
| 1035 | 1064 | |
| 1065 | $(CPUOBJ)/m6502/m6510.o: $(CPUSRC)/m6502/m6510.c \ | |
| 1066 | $(CPUOBJ)/m6502/m6510.inc \ | |
| 1067 | $(CPUSRC)/m6502/m6510.h \ | |
| 1068 | $(CPUSRC)/m6502/m6502.h | |
| 1036 | 1069 | |
| 1070 | $(CPUOBJ)/m6502/m6510t.o: $(CPUSRC)/m6502/m6510t.c \ | |
| 1071 | $(CPUSRC)/m6502/m6510t.h \ | |
| 1072 | $(CPUSRC)/m6502/m6510.h \ | |
| 1073 | $(CPUSRC)/m6502/m6502.h | |
| 1037 | 1074 | |
| 1075 | $(CPUOBJ)/m6502/m7501.o: $(CPUSRC)/m6502/m7501.c \ | |
| 1076 | $(CPUSRC)/m6502/m7501.h \ | |
| 1077 | $(CPUSRC)/m6502/m6510.h \ | |
| 1078 | $(CPUSRC)/m6502/m6502.h | |
| 1079 | ||
| 1080 | $(CPUOBJ)/m6502/m8502.o: $(CPUSRC)/m6502/m8502.c \ | |
| 1081 | $(CPUSRC)/m6502/m8502.h \ | |
| 1082 | $(CPUSRC)/m6502/m6510.h \ | |
| 1083 | $(CPUSRC)/m6502/m6502.h | |
| 1084 | ||
| 1085 | $(CPUOBJ)/m6502/n2a03.o: $(CPUSRC)/m6502/n2a03.c \ | |
| 1086 | $(CPUOBJ)/m6502/n2a03.inc \ | |
| 1087 | $(CPUSRC)/m6502/n2a03.h \ | |
| 1088 | $(CPUSRC)/m6502/m6502.h | |
| 1089 | ||
| 1090 | $(CPUOBJ)/m6502/r65c02.o: $(CPUSRC)/m6502/r65c02.c \ | |
| 1091 | $(CPUOBJ)/m6502/r65c02.inc \ | |
| 1092 | $(CPUSRC)/m6502/r65c02.h \ | |
| 1093 | $(CPUSRC)/m6502/m65c02.h \ | |
| 1094 | $(CPUSRC)/m6502/m6502.h | |
| 1095 | ||
| 1096 | # rule to generate the C files | |
| 1097 | $(CPUOBJ)/m6502/deco16.inc: $(M6502MAKE) $(CPUSRC)/m6502/odeco16.lst $(CPUSRC)/m6502/ddeco16.lst | |
| 1098 | @echo Generating DECO16 source file... | |
| 1099 | $(M6502MAKE) deco16_device $(CPUSRC)/m6502/odeco16.lst $(CPUSRC)/m6502/ddeco16.lst $@ | |
| 1100 | ||
| 1101 | $(CPUOBJ)/m6502/m4510.inc: $(M6502MAKE) $(CPUSRC)/m6502/om4510.lst $(CPUSRC)/m6502/dm4510.lst | |
| 1102 | @echo Generating M4510 source file... | |
| 1103 | $(M6502MAKE) m4510_device $(CPUSRC)/m6502/om4510.lst $(CPUSRC)/m6502/dm4510.lst $@ | |
| 1104 | ||
| 1105 | $(CPUOBJ)/m6502/m6502.inc: $(M6502MAKE) $(CPUSRC)/m6502/om6502.lst $(CPUSRC)/m6502/dm6502.lst | |
| 1106 | @echo Generating M6502 source file... | |
| 1107 | $(M6502MAKE) m6502_device $(CPUSRC)/m6502/om6502.lst $(CPUSRC)/m6502/dm6502.lst $@ | |
| 1108 | ||
| 1109 | $(CPUOBJ)/m6502/m65c02.inc: $(M6502MAKE) $(CPUSRC)/m6502/om65c02.lst $(CPUSRC)/m6502/dm65c02.lst | |
| 1110 | @echo Generating M65C02 source file... | |
| 1111 | $(M6502MAKE) m65c02_device $(CPUSRC)/m6502/om65c02.lst $(CPUSRC)/m6502/dm65c02.lst $@ | |
| 1112 | ||
| 1113 | $(CPUOBJ)/m6502/m65ce02.inc: $(M6502MAKE) $(CPUSRC)/m6502/om65ce02.lst $(CPUSRC)/m6502/dm65ce02.lst | |
| 1114 | @echo Generating M65CE02 source file... | |
| 1115 | $(M6502MAKE) m65ce02_device $(CPUSRC)/m6502/om65ce02.lst $(CPUSRC)/m6502/dm65ce02.lst $@ | |
| 1116 | ||
| 1117 | $(CPUOBJ)/m6502/m6509.inc: $(M6502MAKE) $(CPUSRC)/m6502/om6509.lst $(CPUSRC)/m6502/dm6509.lst | |
| 1118 | @echo Generating M6509 source file... | |
| 1119 | $(M6502MAKE) m6509_device $(CPUSRC)/m6502/om6509.lst $(CPUSRC)/m6502/dm6509.lst $@ | |
| 1120 | ||
| 1121 | $(CPUOBJ)/m6502/m6510.inc: $(M6502MAKE) $(CPUSRC)/m6502/om6510.lst $(CPUSRC)/m6502/dm6510.lst | |
| 1122 | @echo Generating M6510 source file... | |
| 1123 | $(M6502MAKE) m6510_device $(CPUSRC)/m6502/om6510.lst $(CPUSRC)/m6502/dm6510.lst $@ | |
| 1124 | ||
| 1125 | $(CPUOBJ)/m6502/n2a03.inc: $(M6502MAKE) $(CPUSRC)/m6502/on2a03.lst $(CPUSRC)/m6502/dn2a03.lst | |
| 1126 | @echo Generating N2A03 source file... | |
| 1127 | $(M6502MAKE) n2a03_device $(CPUSRC)/m6502/on2a03.lst $(CPUSRC)/m6502/dn2a03.lst $@ | |
| 1128 | ||
| 1129 | $(CPUOBJ)/m6502/r65c02.inc: $(M6502MAKE) $(CPUSRC)/m6502/dr65c02.lst | |
| 1130 | @echo Generating R65C02 source file... | |
| 1131 | $(M6502MAKE) r65c02_device - $(CPUSRC)/m6502/dr65c02.lst $@ | |
| 1132 | ||
| 1133 | ||
| 1134 | # rule to build the generator | |
| 1135 | ifneq ($(CROSS_BUILD),1) | |
| 1136 | ||
| 1137 | BUILD += $(M6502MAKE) | |
| 1138 | ||
| 1139 | $(M6502MAKE): $(CPUOBJ)/m6502/m6502make.o | |
| 1140 | @echo Linking $@... | |
| 1141 | $(LD) $(LDFLAGS) $(OSDBGLDFLAGS) $^ -o $@ | |
| 1142 | ||
| 1143 | endif | |
| 1144 | ||
| 1145 | ||
| 1038 | 1146 | #------------------------------------------------- |
| 1039 | 1147 | # Motorola 680x |
| 1040 | 1148 | #------------------------------------------------- |
| r18874 | r18875 | |
| 1203 | 1311 | $(CPUOBJ)/dsp56k/dsp56dsm.o: $(CPUSRC)/dsp56k/opcode.c \ |
| 1204 | 1312 | $(CPUSRC)/dsp56k/opcode.h \ |
| 1205 | 1313 | $(CPUSRC)/dsp56k/inst.c \ |
| 1206 | ||
| 1314 | $(CPUSRC)/dsp56k/inst.h \ | |
| 1207 | 1315 | $(CPUSRC)/dsp56k/pmove.c \ |
| 1208 | 1316 | $(CPUSRC)/dsp56k/pmove.h \ |
| 1209 | 1317 | $(CPUSRC)/dsp56k/tables.c \ |
| r18874 | r18875 | |
|---|---|---|
| 46 | 46 | |
| 47 | 47 | #include "emu.h" |
| 48 | 48 | #include "nes_apu.h" |
| 49 | #include "cpu/m6502/ | |
| 49 | #include "cpu/m6502/n2a03.h" | |
| 50 | 50 | |
| 51 | 51 | #include "nes_defs.h" |
| 52 | 52 | |
| r18874 | r18875 | |
| 371 | 371 | if (chan->regs[0] & 0x80) /* IRQ Generator */ |
| 372 | 372 | { |
| 373 | 373 | chan->irq_occurred = TRUE; |
| 374 | n2a03_i | |
| 374 | downcast<n2a03_device &>(info->APU.dpcm.memory->device()).set_input_line(N2A03_IRQ_LINE, ASSERT_LINE); | |
| 375 | 375 | } |
| 376 | 376 | break; |
| 377 | 377 | } |
| r18874 | r18875 | |
| 520 | 520 | /* DMC */ |
| 521 | 521 | case APU_WRE0: |
| 522 | 522 | info->APU.dpcm.regs[0] = value; |
| 523 | if (0 == (value & 0x80)) | |
| 523 | if (0 == (value & 0x80)) { | |
| 524 | downcast<n2a03_device &>(info->APU.dpcm.memory->device()).set_input_line(N2A03_IRQ_LINE, CLEAR_LINE); | |
| 524 | 525 | info->APU.dpcm.irq_occurred = FALSE; |
| 526 | } | |
| 525 | 527 | break; |
| 526 | 528 | |
| 527 | 529 | case APU_WRE1: /* 7-bit DAC */ |
| r18874 | r18875 | |
|---|---|---|
| 1 | The new 6502 family implementation | |
| 2 | ---------------------------------- | |
| 3 | ||
| 4 | 1. Introduction | |
| 5 | ||
| 6 | The new 6502 family implementation has been created to reach | |
| 7 | sub-instruction accuracy in observable behaviour. It is designed with | |
| 8 | 3 goals in mind: | |
| 9 | ||
| 10 | - every bus cycle must happen at the exact time it would happen in a | |
| 11 | real cpu, and every access the real cpu does is done | |
| 12 | ||
| 13 | - instructions can be interrupted at any time in the middle then | |
| 14 | restarted at that point transparently | |
| 15 | ||
| 16 | - instructions can be interrupted even from within a memory handler | |
| 17 | for bus contention/wait states emulation purposes | |
| 18 | ||
| 19 | Point 1 has been ensured through bisimulation with the gate-level | |
| 20 | simulation perfect6502. Point 2 has been ensured structurally through | |
| 21 | a code generator which will be explained in section 8. Point 3 is not | |
| 22 | done yet due to lack of support on the memory subsystem side, but | |
| 23 | section 9 shows how it will be handled. | |
| 24 | ||
| 25 | ||
| 26 | 2. The 6502 family | |
| 27 | ||
| 28 | The MOS 6502 family has been large and productive. A large number of | |
| 29 | variants exist, varying on bus sizes, i/o, and even opcodes. Some | |
| 30 | offshots (g65c816, hu6280) even exist that live elsewhere in the mame | |
| 31 | tree. The final class hierarchy is this: | |
| 32 | ||
| 33 | 6502 | |
| 34 | | | |
| 35 | +------+--------+--+--+-------+-------+ | |
| 36 | | | | | | | | |
| 37 | 6510 deco16 6504 6509 n2a03 65c02 | |
| 38 | | | | |
| 39 | +-----+-----+ r65c02 | |
| 40 | | | | | | |
| 41 | 6510t 7501 8502 +---+---+ | |
| 42 | | | | |
| 43 | 65ce02 65sc02 | |
| 44 | | | |
| 45 | 4510 | |
| 46 | ||
| 47 | The 6510 adds an up to 8 bits i/o port, with the 6510t, 7501 and 8502 | |
| 48 | being software-identical variants with different pin count (hence i/o | |
| 49 | count), die process (nmos, hnmos, etc) and clock support. | |
| 50 | ||
| 51 | The deco16 is a Deco variant with a small number of not really understood | |
| 52 | additional instructions and some i/o. | |
| 53 | ||
| 54 | The 6504 is a pin and address-bus reduced version. | |
| 55 | ||
| 56 | The 6509 adds internal support for paging. | |
| 57 | ||
| 58 | The n2a03 is the nes variant with the D flag disabled and sound | |
| 59 | functionality integrated. | |
| 60 | ||
| 61 | The 65c02 is the very first cmos variant with some additional | |
| 62 | instructions, some fixes, and most of the undocumented instructions | |
| 63 | turned into nops. The R (rockwell, but eventually produced by wdc too | |
| 64 | among others) variant adds a number of bitwise instructions and also | |
| 65 | stp and wai. The sc variant, used by the Lynx portable console, looks | |
| 66 | identical to the R variant. The 's' probably indicates a | |
| 67 | static-ram-cell process allowing full dc-to-max clock control. | |
| 68 | ||
| 69 | The 65ce02 is the final evolution of the ISA in this hierarchy, with | |
| 70 | additional instructions, registers, and removals of a lot of dummy | |
| 71 | accesses that slowed the original 6502 down by at least 25%. The 4510 | |
| 72 | is a 65ce02 with integrated mmu and gpio support. | |
| 73 | ||
| 74 | ||
| 75 | 3. Usage of the classes | |
| 76 | ||
| 77 | All the cpus are standard modern cpu devices, with all the normal | |
| 78 | interaction with the device infrastructure. To include one of these | |
| 79 | cpu in your driver you need to include "cpu/m6502/<cpu>.h" and then do | |
| 80 | a MCFG_CPU_ADD("tag", <CPU>, clock). | |
| 81 | ||
| 82 | 6510 variants port i/o callbacks are setup through: | |
| 83 | MCFG_<CPU>_PORT_CALLBACKS(READ8(type, read_method), WRITE8(type, write_method)) | |
| 84 | ||
| 85 | And the pullup and floating lines mask is given through: | |
| 86 | MCFG_<CPU>_PORT_PULLS(pullups, floating) | |
| 87 | ||
| 88 | In order to see all bus accesses on the memory handlers it is possible | |
| 89 | to disable accesses through the direct map (at a cpu cost, of course) | |
| 90 | with: | |
| 91 | MCFG_M6502_DISABLE_DIRECT() | |
| 92 | ||
| 93 | In that case, transparent decryption support is also disabled, | |
| 94 | everything goes through normal memory-map read/write calls. The state | |
| 95 | of the sync line is given by the cpu method get_sync(), making | |
| 96 | implementing the decryption in the handler possible. | |
| 97 | ||
| 98 | In a final addition, the cpu method get_cycle() gives the current time | |
| 99 | in cycles since the start of the machine from the point of view of the | |
| 100 | cpu. Or, in other words, what is usually called the cycle number for | |
| 101 | the cpu when somebody talks about bus contention or wait states. The | |
| 102 | call is designed to be fast (no system-wide sync, usually no call to | |
| 103 | machine.time()) and is precise. Cycle number for every access is | |
| 104 | exact at the sub-instruction level. | |
| 105 | ||
| 106 | The 4510 special nomap line is accessible through get_nomap(). | |
| 107 | ||
| 108 | Other than these specifics, these are perfectly normal cpu classes. | |
| 109 | ||
| 110 | ||
| 111 | 4. General structure of the emulations | |
| 112 | ||
| 113 | Each variant is emulated through up to 4 files: | |
| 114 | - <cpu>.h = header for the cpu class | |
| 115 | - <cpu>.c = implementation of most of the cpu class | |
| 116 | - d<cpu>.lst = dispatch table for the cpu | |
| 117 | - o<cpu>.lst = opcode implementation code for the cpu | |
| 118 | ||
| 119 | The last two are optional. They're used to generate a <cpu>.inc file | |
| 120 | in the object directory which is included by the .c file. | |
| 121 | ||
| 122 | At a minimum, the class must include a constructor and an enum picking | |
| 123 | up the correct input line ids. See m65sc02 for a minimalist example. | |
| 124 | The header can also include specific configuration macros (see m8502) | |
| 125 | and also the class can include specific memory accessors (more on | |
| 126 | these later, simple example in m6504). | |
| 127 | ||
| 128 | If the cpu has its own dispatch table, the class must also include the | |
| 129 | declaration (but not definition) of disasm_entries, do_exec_full and | |
| 130 | do_exec_partial, the declaration and definition of disasm_disassemble | |
| 131 | (identical for all classes but refers to the class-specific | |
| 132 | disasm_entries array) and include the .inc file (which provides the | |
| 133 | missing definitions). Support for the generation must also be added | |
| 134 | to cpu.mak. | |
| 135 | ||
| 136 | If the cpu has in addition its own opcodes, their declaration must be | |
| 137 | done through a macro, see f.i. m65c02. The .inc file will provide the | |
| 138 | definitions. | |
| 139 | ||
| 140 | ||
| 141 | 5. Dispatch tables | |
| 142 | ||
| 143 | Each d<cpu>.lst is the dispatch table for the cpu. Lines starting | |
| 144 | with '#' are comments. The file must include 257 entries, the first | |
| 145 | 256 being opcodes and the 257th what the cpu should do on reset. In | |
| 146 | the 6502 irq and nmi actually magically call the "brk" opcode, hence | |
| 147 | the lack of specific description for them. | |
| 148 | ||
| 149 | Entries 0 to 255, i.e. the opcodes, must have one of these two | |
| 150 | structures: | |
| 151 | - opcode_addressing-mode | |
| 152 | - opcode_middle_addressing-mode | |
| 153 | ||
| 154 | Opcode is traditionally a three-character value. Addressing mode must | |
| 155 | be a 3-letter value corresponding to one of the DASM_* macros in | |
| 156 | m6502.h. Opcode and addressing mode are used to generate the | |
| 157 | disassembly table. The full entry text is used in the opcode | |
| 158 | description file and the dispatching methods, allowing for per-cpu | |
| 159 | variants for identical-looking opcodes. | |
| 160 | ||
| 161 | An entry of "." was usable for unimplemented/unknown opcodes, | |
| 162 | generating "???" in the disassembly, but is not a good idea at this | |
| 163 | point since it will infloop in execute() if encountered. | |
| 164 | ||
| 165 | ||
| 166 | 6. Opcode descriptions | |
| 167 | ||
| 168 | Each o<cpu>.lst file includes the cpu-specific opcodes descriptions. | |
| 169 | An opcode description is a series of lines starting by an opcode entry | |
| 170 | by itself and followed by a series of indented lines with code | |
| 171 | executing the opcode. | |
| 172 | ||
| 173 | For instance the asl <absolute adress> opcode looks like this: | |
| 174 | ||
| 175 | asl_aba | |
| 176 | TMP = read_pc(); | |
| 177 | TMP = set_h(TMP, read_pc()); | |
| 178 | TMP2 = read(TMP); | |
| 179 | write(TMP, TMP2); | |
| 180 | TMP2 = do_asl(TMP2); | |
| 181 | write(TMP, TMP2); | |
| 182 | prefetch(); | |
| 183 | ||
| 184 | First the low part of the address is read, then the high part (read_pc | |
| 185 | is auto-incrementing). Then, now that the address is available the | |
| 186 | value to shift is read, then re-written (yes, the 6502 does that), | |
| 187 | shifted then the final result is written (do_asl takes care of the | |
| 188 | flags). The instruction finishes with a prefetch of the next | |
| 189 | instruction, as all non-cpu-crashing instructions do. | |
| 190 | ||
| 191 | Available bus-accessing functions are: | |
| 192 | - read(adr) - standard read | |
| 193 | - read_direct(adr) - read from program space | |
| 194 | - read_pc() - read at the PC address and increment it | |
| 195 | - read_pc_noinc() - read at the PC address | |
| 196 | - read_9() - 6509 indexed-y banked read | |
| 197 | - write(adr, val) - standard write | |
| 198 | - prefetch() - instruction prefetch | |
| 199 | - prefetch_noirq() - instruction prefetch without irq check | |
| 200 | ||
| 201 | Cycle counting is done by the code generator which detects (through | |
| 202 | string matching) the accesses and generates the appropriate code. In | |
| 203 | addition to the bus-accessing functions a special line can be used to | |
| 204 | wait for the next event (irq or whatever). "eat-all-cycles;" on a | |
| 205 | line will do that wait then continue. It is used by wai_imp and | |
| 206 | stp_imp for the m65c02. | |
| 207 | ||
| 208 | Due to the constraints of the code generation, some rules have to be | |
| 209 | followed: | |
| 210 | ||
| 211 | - in general, stay with one instruction/expression per line | |
| 212 | ||
| 213 | - there must be no side effects in the parameters of a bus-accessing | |
| 214 | function | |
| 215 | ||
| 216 | - local variables lifetime must not go past a bus access. In general, | |
| 217 | it's better to leave them to helper methods (like do_asl) which do not | |
| 218 | do bus accesses. Note that "TMP" and "TMP2" are not local variables, | |
| 219 | they're variables of the class. | |
| 220 | ||
| 221 | - single-line then or else constructs must have braces around them if | |
| 222 | they're calling a bus-accessing function | |
| 223 | ||
| 224 | The per-opcode generated code are methods of the cpu class. As such | |
| 225 | they have complete access to other methods of the class, variables of | |
| 226 | the class, everything. | |
| 227 | ||
| 228 | ||
| 229 | 7. Memory interface | |
| 230 | ||
| 231 | For better opcode reuse with the mmu/banking variants, a memory access | |
| 232 | subclass has been created. It's called memory_interface, declared in | |
| 233 | m6502_device, and provides the following accessors: | |
| 234 | ||
| 235 | - UINT8 read(UINT16 adr) - normal read | |
| 236 | - UINT8 read_direct(UINT16 adr) - direct read | |
| 237 | - UINT8 read_decrypted(UINT16 adr) - decrypted data read | |
| 238 | - void write(UINT16 adr, UINT8 val) - normal write | |
| 239 | ||
| 240 | - UINT8 read_9(UINT16 adr) - special y-indexed 6509 read, defaults to read() | |
| 241 | - void write_9(UINT16 adr, UINT8 val); - special y-indexed 6509 write, defaults to write() | |
| 242 | ||
| 243 | Two implementations are given by default, one usual, | |
| 244 | mi_default_normal, one disabling direct access, mi_default_nd. A cpu | |
| 245 | that wants its own interface (see 6504 or 6509 for instance) must | |
| 246 | override device_start, intialize mintf there then call init(). | |
| 247 | ||
| 248 | ||
| 249 | 8. The generated code | |
| 250 | ||
| 251 | A code generator is used to support interrupting and restarting an | |
| 252 | instruction in the middle. This is done through a two-level state | |
| 253 | machine with updates only at the boundaries. More precisely, | |
| 254 | inst_state tells you which main state you're in. It's equal to the | |
| 255 | opcode byte when 0-255, and 256 means reset. It's always valid and | |
| 256 | used by instructions like rmb. inst_substate indicates at which step | |
| 257 | we are in an instruction, but it set only when an instruction has been | |
| 258 | interrupted. Let's go back to the asl <abs> code: | |
| 259 | ||
| 260 | asl_aba | |
| 261 | TMP = read_pc(); | |
| 262 | TMP = set_h(TMP, read_pc()); | |
| 263 | TMP2 = read(TMP); | |
| 264 | write(TMP, TMP2); | |
| 265 | TMP2 = do_asl(TMP2); | |
| 266 | write(TMP, TMP2); | |
| 267 | prefetch(); | |
| 268 | ||
| 269 | ||
| 270 | The complete generated code is: | |
| 271 | void m6502_device::asl_aba_partial() | |
| 272 | { | |
| 273 | switch(inst_substate) { | |
| 274 | case 0: | |
| 275 | if(icount == 0) { inst_substate = 1; return; } | |
| 276 | case 1: | |
| 277 | TMP = read_pc(); | |
| 278 | icount--; | |
| 279 | if(icount == 0) { inst_substate = 2; return; } | |
| 280 | case 2: | |
| 281 | TMP = set_h(TMP, read_pc()); | |
| 282 | icount--; | |
| 283 | if(icount == 0) { inst_substate = 3; return; } | |
| 284 | case 3: | |
| 285 | TMP2 = read(TMP); | |
| 286 | icount--; | |
| 287 | if(icount == 0) { inst_substate = 4; return; } | |
| 288 | case 4: | |
| 289 | write(TMP, TMP2); | |
| 290 | icount--; | |
| 291 | TMP2 = do_asl(TMP2); | |
| 292 | if(icount == 0) { inst_substate = 5; return; } | |
| 293 | case 5: | |
| 294 | write(TMP, TMP2); | |
| 295 | icount--; | |
| 296 | if(icount == 0) { inst_substate = 6; return; } | |
| 297 | case 6: | |
| 298 | prefetch(); | |
| 299 | icount--; | |
| 300 | } | |
| 301 | inst_substate = 0; | |
| 302 | } | |
| 303 | ||
| 304 | ||
| 305 | One can see that the initial switch() restarts the instruction at the | |
| 306 | appropriate substate, that icount is updated after each access, and | |
| 307 | upon reaching 0 the instruction is interrupted and the substate | |
| 308 | updated. Since most instructions are started from the beginning a | |
| 309 | specific variant is generated for when inst_substate is known to be 0: | |
| 310 | ||
| 311 | void m6502_device::asl_aba_full() | |
| 312 | { | |
| 313 | if(icount == 0) { inst_substate = 1; return; } | |
| 314 | TMP = read_pc(); | |
| 315 | icount--; | |
| 316 | if(icount == 0) { inst_substate = 2; return; } | |
| 317 | TMP = set_h(TMP, read_pc()); | |
| 318 | icount--; | |
| 319 | if(icount == 0) { inst_substate = 3; return; } | |
| 320 | TMP2 = read(TMP); | |
| 321 | icount--; | |
| 322 | if(icount == 0) { inst_substate = 4; return; } | |
| 323 | write(TMP, TMP2); | |
| 324 | icount--; | |
| 325 | TMP2 = do_asl(TMP2); | |
| 326 | if(icount == 0) { inst_substate = 5; return; } | |
| 327 | write(TMP, TMP2); | |
| 328 | icount--; | |
| 329 | if(icount == 0) { inst_substate = 6; return; } | |
| 330 | prefetch(); | |
| 331 | icount--; | |
| 332 | } | |
| 333 | ||
| 334 | That variant removes the switch, avoiding a costly computed branch and | |
| 335 | also an inst_substate write. There is in addition a fair chance that | |
| 336 | the decrement-test with zero pair is compiled into something | |
| 337 | efficient. | |
| 338 | ||
| 339 | All these opcode functions are called through two virtual methods, | |
| 340 | do_exec_full and do_exec_partial, which are generated into a 257-entry | |
| 341 | switch statement. Pointers-to-methods being expensive to call, a | |
| 342 | virtual function implementing a switch has a fair chance of being | |
| 343 | better. | |
| 344 | ||
| 345 | The execute main call ends up very simple: | |
| 346 | void m6502_device::execute_run() | |
| 347 | { | |
| 348 | if(inst_substate) | |
| 349 | do_exec_partial(); | |
| 350 | ||
| 351 | while(icount > 0) { | |
| 352 | if(inst_state < 0x100) { | |
| 353 | PPC = NPC; | |
| 354 | inst_state = IR; | |
| 355 | if(machine().debug_flags & DEBUG_FLAG_ENABLED) | |
| 356 | debugger_instruction_hook(this, NPC); | |
| 357 | } | |
| 358 | do_exec_full(); | |
| 359 | } | |
| 360 | } | |
| 361 | ||
| 362 | If an instruction was partially executed finish it (icount will then | |
| 363 | be zero if it still doesn't finish). Then try to run complete | |
| 364 | instructions. The NPC/IR dance is due to the fact that the 6502 does | |
| 365 | instruction prefetching, so the instruction PC and opcode come from | |
| 366 | the prefetch results. | |
| 367 | ||
| 368 | ||
| 369 | 9. Future bus contention/delay slot support | |
| 370 | ||
| 371 | Supporting bus contention and delay slots in the context of the code | |
| 372 | generator only requires being able to abort a bus access when not | |
| 373 | enough cycles are available into icount, and restart it when cycles | |
| 374 | have become available again. The implementation plan is to: | |
| 375 | ||
| 376 | - Have a delay() method on the cpu that removes cycles from icount. | |
| 377 | If icount becomes zero or less, having it throw a suspend() exception. | |
| 378 | ||
| 379 | - Change the code generator to generate this: | |
| 380 | void m6502_device::asl_aba_partial() | |
| 381 | { | |
| 382 | switch(inst_substate) { | |
| 383 | case 0: | |
| 384 | if(icount == 0) { inst_substate = 1; return; } | |
| 385 | case 1: | |
| 386 | try { | |
| 387 | TMP = read_pc(); | |
| 388 | } catch(suspend) { inst_substate = 1; return; } | |
| 389 | icount--; | |
| 390 | if(icount == 0) { inst_substate = 2; return; } | |
| 391 | case 2: | |
| 392 | try { | |
| 393 | TMP = set_h(TMP, read_pc()); | |
| 394 | } catch(suspend) { inst_substate = 2; return; } | |
| 395 | icount--; | |
| 396 | if(icount == 0) { inst_substate = 3; return; } | |
| 397 | case 3: | |
| 398 | try { | |
| 399 | TMP2 = read(TMP); | |
| 400 | } catch(suspend) { inst_substate = 3; return; } | |
| 401 | icount--; | |
| 402 | if(icount == 0) { inst_substate = 4; return; } | |
| 403 | case 4: | |
| 404 | try { | |
| 405 | write(TMP, TMP2); | |
| 406 | } catch(suspend) { inst_substate = 4; return; } | |
| 407 | icount--; | |
| 408 | TMP2 = do_asl(TMP2); | |
| 409 | if(icount == 0) { inst_substate = 5; return; } | |
| 410 | case 5: | |
| 411 | try { | |
| 412 | write(TMP, TMP2); | |
| 413 | } catch(suspend) { inst_substate = 5; return; } | |
| 414 | icount--; | |
| 415 | if(icount == 0) { inst_substate = 6; return; } | |
| 416 | case 6: | |
| 417 | try { | |
| 418 | prefetch(); | |
| 419 | } catch(suspend) { inst_substate = 6; return; } | |
| 420 | icount--; | |
| 421 | } | |
| 422 | inst_substate = 0; | |
| 423 | } | |
| 424 | ||
| 425 | A modern try/catch costs nothing if an exception is not thrown. Using | |
| 426 | this the control will go back to the main loop, which will then look | |
| 427 | like this: | |
| 428 | ||
| 429 | void m6502_device::execute_run() | |
| 430 | { | |
| 431 | if(waiting_cycles) { | |
| 432 | icount -= waiting_cycles; | |
| 433 | waiting_cycles = 0; | |
| 434 | } | |
| 435 | ||
| 436 | if(icount > 0 && inst_substate) | |
| 437 | do_exec_partial(); | |
| 438 | ||
| 439 | while(icount > 0) { | |
| 440 | if(inst_state < 0x100) { | |
| 441 | PPC = NPC; | |
| 442 | inst_state = IR; | |
| 443 | if(machine().debug_flags & DEBUG_FLAG_ENABLED) | |
| 444 | debugger_instruction_hook(this, NPC); | |
| 445 | } | |
| 446 | do_exec_full(); | |
| 447 | } | |
| 448 | ||
| 449 | waiting_cycles = -icount; | |
| 450 | icount = 0; | |
| 451 | } | |
| 452 | ||
| 453 | A negative icount means that the cpu won't be able to do anything for | |
| 454 | some time in the future, because it's either waiting for the bus to be | |
| 455 | free or for a peripheral to answer. These cycles will be counted | |
| 456 | until elapsed and then normal processing will go on. It's important | |
| 457 | to note that the exception path only happens when the contention/wait | |
| 458 | state goes further than the scheduling slice of the cpu. That should | |
| 459 | not usually be the case, so the cost should be minimal. | |
| 460 | ||
| 461 | 10. Current TODO | |
| 462 | ||
| 463 | - Implement the bus contention/wait states stuff, but that requires | |
| 464 | support on the memory map side first. | |
| 465 | ||
| 466 | - Integrate the i/o subsystems in the 4510 | |
| 467 | ||
| 468 | - Possibly integrate the sound subsytem in the n2a03 | |
| 469 | ||
| 470 | - Add decent hookups for the apple 3 madness |
| Previous | 199869 Revisions | Next |