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]6502dasm.c ddeco16.lst deco16.c deco16.h dm4510.lst dm6502.lst dm6509.lst dm6510.lst dm65c02.lst dm65ce02.lst dn2a03.lst dr65c02.lst ill02.h m4510.c m4510.h m6502.c m6502.h m6502make.c m6504.c m6504.h m6509.c m6509.h m6510.c m6510.h m6510t.c m6510t.h m65c02.c m65c02.h m65ce02.c m65ce02.h m65sc02.c m65sc02.h m7501.c m7501.h m8502.c m8502.h minc4510.h mincce02.h n2a03.c n2a03.h odeco16.lst om4510.lst om6502.lst om6509.lst om6510.lst om65c02.lst om65ce02.lst on2a03.lst ops02.h ops09.h ops4510.h opsc02.h opsce02.h opsn2a03.h r65c02.c r65c02.h t6502.c t6509.c t6510.c t65c02.c t65ce02.c t65sc02.c tdeco16.c tn2a03.c
[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

trunk/src/mess/machine/isa_finalchs.c
r18874r18875
99
1010#include "emu.h"
1111#include "isa_finalchs.h"
12#include "cpu/m6502/m6502.h"
12#include "cpu/m6502/m65c02.h"
1313
1414static UINT8 FCH_latch_data = 0;
1515
trunk/src/mess/machine/lynx.c
r18874r18875
44
55#include "emu.h"
66#include "includes/lynx.h"
7#include "cpu/m6502/m6502.h"
7#include "cpu/m6502/m65sc02.h"
88#include "imagedev/cartslot.h"
99
1010
trunk/src/mess/machine/c1541.h
r18874r18875
100100
101101   inline void set_iec_data();
102102
103   required_device<cpu_device> m_maincpu;
103   required_device<m6502_device> m_maincpu;
104104   required_device<via6522_device> m_via0;
105105   required_device<via6522_device> m_via1;
106106   required_device<c64h156_device> m_ga;
trunk/src/mess/machine/fd2000.h
r18874r18875
1515#define ADDRESS_MAP_MODERN
1616
1717#include "emu.h"
18#include "cpu/m6502/m6502.h"
18#include "cpu/m6502/m65c02.h"
1919#include "imagedev/flopdrv.h"
2020#include "formats/mfi_dsk.h"
2121#include "machine/6522via.h"
r18874r18875
6262   void cbm_iec_data(int state);
6363   void cbm_iec_reset(int state);
6464
65   required_device<cpu_device> m_maincpu;
65   required_device<m65c02_device> m_maincpu;
6666};
6767
6868
trunk/src/mess/machine/c1551.c
r18874r18875
131131   m_ga->ds_w((data >> 5) & 0x03);
132132}
133133
134static 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
145134//-------------------------------------------------
146135//  tpi6525_interface tpi0_intf
147136//-------------------------------------------------
r18874r18875
408397static MACHINE_CONFIG_FRAGMENT( c1551 )
409398   MCFG_CPU_ADD(M6510T_TAG, M6510T, XTAL_16MHz/8)
410399   MCFG_CPU_PROGRAM_MAP(c1551_mem)
411   MCFG_CPU_CONFIG(cpu_intf)
400   MCFG_M6510T_PORT_CALLBACKS(READ8(c1551_device, port_r), WRITE8(c1551_device, port_w))
412401   MCFG_QUANTUM_PERFECT_CPU(M6510T_TAG)
413402
414403   MCFG_PLS100_ADD(PLA_TAG)
trunk/src/mess/machine/c1551.h
r18874r18875
1414
1515
1616#include "emu.h"
17#include "cpu/m6502/m6502.h"
17#include "cpu/m6502/m6510t.h"
1818#include "imagedev/flopdrv.h"
1919#include "formats/d64_dsk.h"
2020#include "formats/g64_dsk.h"
r18874r18875
8484private:
8585   bool tpi1_selected(offs_t offset);
8686
87   required_device<cpu_device> m_maincpu;
87   required_device<m6510t_device> m_maincpu;
8888   required_device<device_t> m_tpi0;
8989   required_device<device_t> m_tpi1;
9090   required_device<c64h156_device> m_ga;
trunk/src/mess/machine/c64.c
r18874r18875
1515
1616#include "emu.h"
1717
18#include "cpu/m6502/m6502.h"
18#include "cpu/m6502/m6510.h"
1919#include "cpu/z80/z80.h"
2020#include "sound/sid6581.h"
2121#include "machine/6526cia.h"
r18874r18875
159159   legacy_c64_state *state = machine.driver_data<legacy_c64_state>();
160160   int loram, hiram, charen;
161161   int ultimax_mode = 0;
162   int data = m6510_get_port(machine.device<legacy_cpu_device>("maincpu")) & 0x07;
162   int data = machine.device<m6510_device>("maincpu")->get_port() & 0x07;
163163
164164   /* Are we in Ultimax mode? */
165165   if (!state->m_game && state->m_exrom)
trunk/src/mess/machine/c65.c
r18874r18875
102102   c65_state *state = machine.driver_data<c65_state>();
103103   if (level != state->m_old_level)
104104   {
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);
107107      state->m_old_level = level;
108108   }
109109}
r18874r18875
837837   c65_state *state = machine.driver_data<c65_state>();
838838   int data, loram, hiram, charen;
839839
840   data = m4510_get_port(machine.device<legacy_cpu_device>("maincpu"));
840   data = 0x00; // machine.device<m4510_device>("maincpu")->get_port();
841841   if (data == state->m_old_data)
842842      return;
843843
trunk/src/mess/machine/serialbox.h
r18874r18875
1414
1515
1616#include "emu.h"
17#include "cpu/m6502/m6502.h"
17#include "cpu/m6502/m65c02.h"
1818#include "machine/cbmiec.h"
1919
2020
r18874r18875
5757   void cbm_iec_reset(int state);
5858
5959private:
60   required_device<cpu_device> m_maincpu;
60   required_device<m65c02_device> m_maincpu;
6161};
6262
6363
trunk/src/mess/machine/c2040.h
r18874r18875
1515
1616#include "emu.h"
1717#include "cpu/m6502/m6502.h"
18#include "cpu/m6502/m6504.h"
1819#include "imagedev/flopdrv.h"
1920#include "formats/d64_dsk.h"
2021#include "formats/g64_dsk.h"
r18874r18875
9798   inline void mpi_step_motor(int unit, int stp);
9899   inline void initialize(int drives);
99100
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;
102103   required_device<riot6532_device> m_riot0;
103104   required_device<riot6532_device> m_riot1;
104105   required_device<device_t> m_miot;
trunk/src/mess/machine/e01.h
r18874r18875
1313#define __E01__
1414
1515#include "emu.h"
16#include "cpu/m6502/m6502.h"
16#include "cpu/m6502/m65c02.h"
1717#include "imagedev/flopdrv.h"
1818#include "machine/6522via.h"
1919#include "machine/ctronics.h"
r18874r18875
7979   // device_econet_interface overrides
8080   virtual void econet_clk(int state);
8181
82   required_device<cpu_device> m_maincpu;
82   required_device<m65c02_device> m_maincpu;
8383   required_device<device_t> m_fdc;
8484   required_device<device_t> m_adlc;
8585   required_device<mc146818_device> m_rtc;
trunk/src/mess/includes/c64.h
r18874r18875
44#define __C64__
55
66#include "emu.h"
7#include "cpu/m6502/m6510.h"
78#include "formats/cbm_snqk.h"
89#include "includes/cbm.h"
910#include "machine/c64exp.h"
r18874r18875
6364        m_iec_srq(1)
6465   { }
6566
66   required_device<cpu_device> m_maincpu;
67   required_device<m6510_device> m_maincpu;
6768   required_device<pls100_device> m_pla;
6869   required_device<mos6566_device> m_vic;
6970   required_device<sid6581_device> m_sid;
trunk/src/mess/includes/vic10.h
r18874r18875
55
66
77#include "emu.h"
8#include "cpu/m6502/m6510.h"
89#include "includes/cbm.h"
910#include "machine/cbmipt.h"
1011#include "machine/mos6526.h"
r18874r18875
4445        m_exp_irq(CLEAR_LINE)
4546   { }
4647
47   required_device<cpu_device> m_maincpu;
48   required_device<m6510_device> m_maincpu;
4849   required_device<mos6566_device> m_vic;
4950   required_device<sid6581_device> m_sid;
5051   required_device<mos6526_device> m_cia;
trunk/src/mess/includes/vic20.h
r18874r18875
77#include "emu.h"
88#include "includes/cbm.h"
99#include "formats/cbm_snqk.h"
10#include "cpu/m6502/m6502.h"
10#include "cpu/m6502/m6510.h"
1111#include "imagedev/cartslot.h"
1212#include "machine/6522via.h"
1313#include "machine/cbmiec.h"
r18874r18875
4848        m_color_ram(*this, "color_ram")
4949   { }
5050
51   required_device<cpu_device> m_maincpu;
51   required_device<m6510_device> m_maincpu;
5252   required_device<via6522_device> m_via0;
5353   required_device<via6522_device> m_via1;
5454   required_device<mos6560_device> m_vic;
trunk/src/mess/includes/plus4.h
r18874r18875
44#define __PLUS4__
55
66#include "emu.h"
7#include "cpu/m6502/m7501.h"
78#include "formats/cbm_snqk.h"
89#include "includes/cbm.h"
910#include "audio/t6721.h"
r18874r18875
5253        m_exp_irq(CLEAR_LINE)
5354   { }
5455
55   required_device<legacy_cpu_device> m_maincpu;
56   required_device<m7501_device> m_maincpu;
5657   required_device<pls100_device> m_pla;
5758   required_device<mos7360_device> m_ted;
5859   optional_device<acia6551_device> m_acia;
trunk/src/mess/includes/c128.h
r18874r18875
66#include "emu.h"
77#include "formats/cbm_snqk.h"
88#include "includes/cbm.h"
9#include "cpu/m6502/m8502.h"
10#include "machine/6526cia.h"
911#include "machine/c64exp.h"
1012#include "machine/c64user.h"
1113#include "machine/cbmiec.h"
r18874r18875
8890   { }
8991
9092   required_device<legacy_cpu_device> m_maincpu;
91   required_device<legacy_cpu_device> m_subcpu;
93   required_device<m8502_device> m_subcpu;
9294   required_device<mos8722_device> m_mmu;
9395   required_device<mos8721_device> m_pla;
9496   required_device<mos8563_device> m_vdc;
trunk/src/mess/drivers/c128.c
r18874r18875
11311131   m_cassette->motor_w(BIT(data, 5));
11321132}
11331133
1134static 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};
11431134
1144
11451135//-------------------------------------------------
11461136//  CBM_IEC_INTERFACE( cbm_iec_intf )
11471137//-------------------------------------------------
r18874r18875
13861376   MCFG_QUANTUM_PERFECT_CPU(Z80A_TAG)
13871377
13881378   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)
13891381   MCFG_CPU_PROGRAM_MAP(m8502_mem)
1390   MCFG_CPU_CONFIG(cpu_intf)
13911382   MCFG_CPU_VBLANK_INT_DRIVER(SCREEN_VIC_TAG, c128_state, frame_interrupt)
13921383   MCFG_QUANTUM_PERFECT_CPU(M8502_TAG)
13931384
r18874r18875
14911482   MCFG_QUANTUM_PERFECT_CPU(Z80A_TAG)
14921483
14931484   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)
14941487   MCFG_CPU_PROGRAM_MAP(m8502_mem)
1495   MCFG_CPU_CONFIG(cpu_intf)
14961488   MCFG_CPU_VBLANK_INT_DRIVER(SCREEN_VIC_TAG, c128_state, frame_interrupt)
14971489   MCFG_QUANTUM_PERFECT_CPU(M8502_TAG)
14981490
trunk/src/mess/drivers/c64.c
r18874r18875
713713   m_cassette->motor_w(BIT(data, 5));
714714}
715715
716static 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
727716//-------------------------------------------------
728717//  M6510_INTERFACE( sx64_cpu_intf )
729718//-------------------------------------------------
r18874r18875
767756   m_charen = BIT(data, 2);
768757}
769758
770static 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
781759//-------------------------------------------------
782760//  M6510_INTERFACE( c64gs_cpu_intf )
783761//-------------------------------------------------
r18874r18875
821799   m_charen = BIT(data, 2);
822800}
823801
824static 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
835802//-------------------------------------------------
836803//  PET_DATASSETTE_PORT_INTERFACE( datassette_intf )
837804//-------------------------------------------------
r18874r18875
10421009   // basic hardware
10431010   MCFG_CPU_ADD(M6510_TAG, M6510, VIC6567_CLOCK)
10441011   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)
10461014   MCFG_CPU_VBLANK_INT_DRIVER(SCREEN_TAG, c64_state, frame_interrupt)
10471015   MCFG_QUANTUM_PERFECT_CPU(M6510_TAG)
10481016
r18874r18875
11011069
11021070   // basic hardware
11031071   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)
11051074
11061075   // devices
11071076   MCFG_DEVICE_REMOVE("iec8")
r18874r18875
11411110   // basic hardware
11421111   MCFG_CPU_ADD(M6510_TAG, M6510, VIC6569_CLOCK)
11431112   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)
11451115   MCFG_CPU_VBLANK_INT_DRIVER(SCREEN_TAG, c64_state, frame_interrupt)
11461116   MCFG_QUANTUM_PERFECT_CPU(M6510_TAG)
11471117
r18874r18875
11911161
11921162   // basic hardware
11931163   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)
11951166
11961167   // devices
11971168   MCFG_DEVICE_REMOVE("iec8")
r18874r18875
12181189   // basic hardware
12191190   MCFG_CPU_ADD(M6510_TAG, M6510, VIC6569_CLOCK)
12201191   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
12221195   MCFG_CPU_VBLANK_INT_DRIVER(SCREEN_TAG, c64_state, frame_interrupt)
12231196   MCFG_QUANTUM_PERFECT_CPU(M6510_TAG)
12241197
trunk/src/mess/drivers/apple2.c
r18874r18875
183183
184184#include "emu.h"
185185#include "cpu/m6502/m6502.h"
186#include "cpu/m6502/m65c02.h"
186187#include "cpu/z80/z80.h"
187188#include "imagedev/flopdrv.h"
188189#include "imagedev/cassette.h"
trunk/src/mess/drivers/bbc.c
r18874r18875
1212
1313#include "emu.h"
1414#include "cpu/m6502/m6502.h"
15#include "cpu/m6502/m65sc02.h"
1516#include "machine/6522via.h"
1617#include "machine/econet.h"
1718#include "machine/e01.h"
trunk/src/mess/drivers/apple3.c
r18874r18875
3434/* the Apple /// does some weird tricks whereby it monitors the SYNC pin
3535 * on the CPU to check for indexed instructions and directs them to
3636 * different memory locations */
37#if 0
3738static const m6502_interface apple3_m6502_interface =
3839{
3940   DEVCB_DRIVER_MEMBER(apple3_state, apple3_indexed_read),   /* read_indexed_func */
r18874r18875
4344    0x00,
4445    0x00
4546};
47#endif
4648
4749static const floppy_interface apple3_floppy_interface =
4850{
r18874r18875
7072   /* basic machine hardware */
7173   MCFG_CPU_ADD("maincpu", M6502, 2000000)        /* 2 MHz */
7274   MCFG_CPU_PROGRAM_MAP(apple3_map)
73   MCFG_CPU_CONFIG( apple3_m6502_interface )
75//   MCFG_CPU_CONFIG( apple3_m6502_interface )
7476   MCFG_CPU_PERIODIC_INT_DRIVER(apple3_state, apple3_interrupt,  192)
7577   MCFG_QUANTUM_TIME(attotime::from_hz(60))
7678
trunk/src/mess/drivers/mmodular.c
r18874r18875
8787
8888#include "emu.h"
8989#include "cpu/m68000/m68000.h"
90#include "cpu/m6502/m6502.h"
90#include "cpu/m6502/m65c02.h"
9191#include "cpu/arm/arm.h"
9292#include "sound/beep.h"
9393//#include "machine/6551acia.h"
r18874r18875
813813
814814TIMER_DEVICE_CALLBACK_MEMBER(polgar_state::cause_M6502_irq)
815815{
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);
819819}
820820
821821
trunk/src/mess/drivers/mephisto.c
r18874r18875
6161
6262
6363#include "emu.h"
64#include "cpu/m6502/m6502.h"
64#include "cpu/m6502/m65c02.h"
6565#include "sound/beep.h"
6666//#include "mephisto.lh"
6767
r18874r18875
7777   m_beep(*this, BEEPER_TAG)
7878   { }
7979
80   required_device<cpu_device> m_maincpu;
80   required_device<m65c02_device> m_maincpu;
8181   required_device<device_t> m_beep;
8282   DECLARE_WRITE8_MEMBER(write_lcd);
8383   DECLARE_WRITE8_MEMBER(mephisto_NMI);
r18874r18875
351351
352352TIMER_DEVICE_CALLBACK_MEMBER(mephisto_state::update_irq)//only mm2
353353{
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);
356357
357358   beep_set_state(m_beep, m_led_status&64?1:0);
358359}
trunk/src/mess/drivers/vic10.c
r18874r18875
409409   m_cassette->motor_w(BIT(data, 5));
410410}
411411
412static 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
423412//-------------------------------------------------
424413//  PET_DATASSETTE_PORT_INTERFACE( datassette_intf )
425414//-------------------------------------------------
r18874r18875
505494   // basic hardware
506495   MCFG_CPU_ADD(M6510_TAG, M6510, VIC6566_CLOCK)
507496   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)
509499   MCFG_CPU_VBLANK_INT_DRIVER(SCREEN_TAG, vic10_state,  vic10_frame_interrupt)
510500   MCFG_QUANTUM_PERFECT_CPU(M6510_TAG)
511501
trunk/src/mess/drivers/lisa.c
r18874r18875
1010
1111#include "emu.h"
1212#include "cpu/m68000/m68000.h"
13#include "cpu/m6502/m6502.h"
13#include "cpu/m6502/m6504.h"
1414#include "cpu/cop400/cop400.h"
1515#include "includes/lisa.h"
1616#include "devices/sonydriv.h"
trunk/src/mess/drivers/lynx.c
r18874r18875
77******************************************************************************/
88
99#include "emu.h"
10#include "cpu/m6502/m6502.h"
10#include "cpu/m6502/m65sc02.h"
1111#include "includes/lynx.h"
1212
1313#include "imagedev/snapquik.h"
trunk/src/mess/drivers/plus4.c
r18874r18875
542542   m_cassette->write(!BIT(data, 1));
543543}
544544
545static 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
555static 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
565545//-------------------------------------------------
566546//  ted7360_interface ted_intf
567547//-------------------------------------------------
r18874r18875
911891   // basic machine hardware
912892   MCFG_CPU_ADD(MOS7501_TAG, M7501, XTAL_14_31818MHz/16)
913893   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)
915896   MCFG_CPU_VBLANK_INT_DRIVER(SCREEN_TAG, plus4_state,  c16_frame_interrupt)
916897   MCFG_CPU_PERIODIC_INT_DRIVER(plus4_state, c16_raster_interrupt,  TED7360_HRETRACERATE)
917898   MCFG_QUANTUM_TIME(attotime::from_hz(60))
r18874r18875
950931   // basic machine hardware
951932   MCFG_CPU_ADD(MOS7501_TAG, M7501, XTAL_17_73447MHz/20)
952933   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)
954936   MCFG_CPU_VBLANK_INT_DRIVER(SCREEN_TAG, plus4_state,  c16_frame_interrupt)
955937   MCFG_CPU_PERIODIC_INT_DRIVER(plus4_state, c16_raster_interrupt,  TED7360_HRETRACERATE)
956938   MCFG_QUANTUM_TIME(attotime::from_hz(60))
r18874r18875
987969
988970static MACHINE_CONFIG_DERIVED( c16n, ntsc )
989971   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)
991974
992975   MCFG_DEVICE_REMOVE(MOS6551_TAG)
993976   MCFG_DEVICE_REMOVE(MOS6529_USER_TAG)
r18874r18875
1008991
1009992static MACHINE_CONFIG_DERIVED( c16p, pal )
1010993   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)
1012996
1013997   MCFG_DEVICE_REMOVE(MOS6551_TAG)
1014998   MCFG_DEVICE_REMOVE(MOS6529_USER_TAG)
trunk/src/mess/drivers/nes.c
r18874r18875
1414#include "video/ppu2c0x.h"
1515#include "includes/nes.h"
1616//#include "includes/nes_mmc.h"
17#include "cpu/m6502/m6502.h"
17#include "cpu/m6502/n2a03.h"
1818#include "imagedev/cartslot.h"
1919#include "sound/nes_apu.h"
2020#include "imagedev/flopdrv.h"
trunk/src/mess/drivers/clcd.c
r18874r18875
1010
1111
1212#include "emu.h"
13#include "cpu/m6502/m6502.h"
13#include "cpu/m6502/m65c02.h"
1414#include "machine/6522via.h"
1515#include "machine/6551acia.h"
1616#include "rendlay.h"
r18874r18875
253253   DEVCB_NULL,//DEVCB_DRIVER_LINE_MEMBER(clcd_state, via0_ca2_w), // CASS MOTOR
254254   DEVCB_NULL,
255255
256   DEVCB_CPU_INPUT_LINE("maincpu", M6502_IRQ_LINE)
256   DEVCB_CPU_INPUT_LINE("maincpu", M65C02_IRQ_LINE)
257257};
258258
259259static const via6522_interface via1_intf =
trunk/src/mess/drivers/svision.c
r18874r18875
66
77#include <assert.h>
88#include "emu.h"
9#include "cpu/m6502/m6502.h"
9#include "cpu/m6502/m65c02.h"
1010
1111#include "includes/svision.h"
1212#include "imagedev/cartslot.h"
r18874r18875
6161   int irq = state->m_svision.timer_shot && (state->BANK & 2);
6262   irq = irq || (*state->m_dma_finished && (state->BANK & 4));
6363
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);
6565}
6666
6767TIMER_CALLBACK_MEMBER(svision_state::svision_timer)
trunk/src/mess/drivers/sbc6510.c
r18874r18875
4949****************************************************************************/
5050
5151#include "emu.h"
52#include "cpu/m6502/m6502.h"
52#include "cpu/m6502/m6510.h"
5353#include "machine/6526cia.h"
5454#include "sound/ay8910.h"
5555#include "machine/terminal.h"
r18874r18875
198198{
199199}
200200
201static M6510_INTERFACE( sbc6510_m6510_interface )
202{
203   DEVCB_NULL,
204   DEVCB_NULL,
205   DEVCB_NULL,
206   DEVCB_NULL,
207   0x00,
208   0x00
209};
210
211201READ8_MEMBER( sbc6510_state::psg_a_r )
212202{
213203   return 0xff;
r18874r18875
250240
251241const legacy_mos6526_interface cia_intf =
252242{
253   DEVCB_CPU_INPUT_LINE("maincpu", M6502_IRQ_LINE), // irq
243   DEVCB_CPU_INPUT_LINE("maincpu", M6510_IRQ_LINE), // irq
254244   DEVCB_NULL,   // pc (timer related) not connected
255245   DEVCB_NULL,   // cnt (serial related) not connected
256246   DEVCB_NULL,   // sp (serial related) not connected
r18874r18875
263253static MACHINE_CONFIG_START( sbc6510, sbc6510_state )
264254   /* basic machine hardware */
265255   MCFG_CPU_ADD("maincpu",M6510, XTAL_1MHz)
266   MCFG_CPU_CONFIG( sbc6510_m6510_interface )
267256   MCFG_CPU_PROGRAM_MAP(sbc6510_mem)
268257
269258
trunk/src/mame/audio/dkong.c
r18874r18875
11#include "emu.h"
22#include "cpu/mcs48/mcs48.h"
3#include "cpu/m6502/m6502.h"
3#include "cpu/m6502/n2a03.h"
44#include "sound/nes_apu.h"
55#include "sound/discrete.h"
66#include "machine/latch8.h"
trunk/src/mame/video/liberate.c
r18874r18875
1010*******************************************************************************/
1111
1212#include "emu.h"
13#include "cpu/m6502/deco16.h"
1314#include "cpu/m6502/m6502.h"
1415#include "includes/liberate.h"
1516
trunk/src/mame/drivers/alvg.c
r18874r18875
11
22#include "emu.h"
3#include "cpu/m6502/m65ce02.h"
3#include "cpu/m6502/m65c02.h"
44
55class alvg_state : public driver_device
66{
trunk/src/mame/drivers/tceptor.c
r18874r18875
77 */
88
99#include "emu.h"
10#include "cpu/m6502/m6502.h"
10#include "cpu/m6502/m65c02.h"
1111#include "cpu/m6809/m6809.h"
1212#include "cpu/m6800/m6800.h"
1313#include "cpu/m68000/m68000.h"
trunk/src/mame/drivers/punchout.c
r18874r18875
111111
112112#include "emu.h"
113113#include "cpu/z80/z80.h"
114#include "cpu/m6502/m6502.h"
114#include "cpu/m6502/n2a03.h"
115115#include "sound/vlm5030.h"
116116#include "sound/nes_apu.h"
117117#include "machine/nvram.h"
trunk/src/mame/drivers/cham24.c
r18874r18875
5555*/
5656
5757#include "emu.h"
58#include "cpu/m6502/m6502.h"
58#include "cpu/m6502/n2a03.h"
5959#include "sound/dac.h"
6060#include "sound/nes_apu.h"
6161#include "video/ppu2c0x.h"
trunk/src/mame/drivers/liberate.c
r18874r18875
1515*******************************************************************************/
1616
1717#include "emu.h"
18#include "cpu/m6502/deco16.h"
1819#include "cpu/m6502/m6502.h"
1920#include "sound/ay8910.h"
2021#include "includes/liberate.h"
trunk/src/mame/drivers/4roses.c
r18874r18875
173173#define MASTER_CLOCK   XTAL_16MHz
174174
175175#include "emu.h"
176#include "cpu/m6502/m6502.h"
176#include "cpu/m6502/m65c02.h"
177177#include "video/mc6845.h"
178178#include "sound/ay8910.h"
179179#include "machine/nvram.h"
trunk/src/mame/drivers/famibox.c
r18874r18875
5959
6060#include "emu.h"
6161#include "video/ppu2c0x.h"
62#include "cpu/m6502/m6502.h"
62#include "cpu/m6502/n2a03.h"
6363#include "imagedev/cartslot.h"
6464#include "sound/nes_apu.h"
6565#include "sound/dac.h"
trunk/src/mame/drivers/allied.c
r18874r18875
77***************************************************************************/
88
99#include "emu.h"
10#include "cpu/m6502/m6502.h"
10#include "cpu/m6502/m6504.h"
1111
1212class allied_state : public driver_device
1313{
trunk/src/mame/drivers/snookr10.c
r18874r18875
362362#define MASTER_CLOCK   XTAL_16MHz
363363
364364#include "emu.h"
365#include "cpu/m6502/m6502.h"
365#include "cpu/m6502/m65sc02.h"
366366#include "sound/okim6295.h"
367367#include "snookr10.lh"
368368#include "includes/snookr10.h"
trunk/src/mame/drivers/multigam.c
r18874r18875
6666*/
6767
6868#include "emu.h"
69#include "cpu/m6502/m6502.h"
69#include "cpu/m6502/n2a03.h"
7070#include "sound/dac.h"
7171#include "sound/nes_apu.h"
7272#include "video/ppu2c0x.h"
trunk/src/mame/drivers/bwing.c
r18874r18875
2323
2424#include "emu.h"
2525#include "cpu/m6809/m6809.h"
26#include "cpu/m6502/m6502.h"
26#include "cpu/m6502/deco16.h"
2727#include "sound/ay8910.h"
2828#include "sound/dac.h"
2929#include "includes/bwing.h"
trunk/src/mame/drivers/cmmb.c
r18874r18875
4545***************************************************************************/
4646
4747#include "emu.h"
48#include "cpu/m6502/m6502.h"
48#include "cpu/m6502/m65sc02.h"
4949
5050
5151class cmmb_state : public driver_device
trunk/src/mame/drivers/rgum.c
r18874r18875
1313
1414#include "emu.h"
1515#include "cpu/z80/z80.h"
16#include "cpu/m6502/m6502.h"
16#include "cpu/m6502/m65c02.h"
1717#include "video/mc6845.h"
1818#include "machine/i8255.h"
1919#include "sound/ay8910.h"
trunk/src/mame/drivers/gts3.c
r18874r18875
44
55
66#include "emu.h"
7#include "cpu/m6502/m65ce02.h"
7#include "cpu/m6502/m65c02.h"
88
99class gts3_state : public driver_device
1010{
trunk/src/mame/drivers/seta.c
r18874r18875
13571357#include "emu.h"
13581358#include "cpu/z80/z80.h"
13591359#include "cpu/m68000/m68000.h"
1360#include "cpu/m6502/m6502.h"
1360#include "cpu/m6502/m65c02.h"
13611361#include "includes/seta.h"
13621362#include "machine/6821pia.h"
13631363#include "machine/6850acia.h"
trunk/src/mame/drivers/calomega.c
r18874r18875
645645
646646#include "emu.h"
647647#include "cpu/m6502/m6502.h"
648#include "cpu/m6502/m65c02.h"
648649#include "video/mc6845.h"
649650#include "machine/6821pia.h"
650651#include "machine/6850acia.h"
trunk/src/mame/drivers/thedeep.c
r18874r18875
2626
2727#include "emu.h"
2828#include "cpu/z80/z80.h"
29#include "cpu/m6502/m6502.h"
29#include "cpu/m6502/m65c02.h"
3030#include "cpu/mcs51/mcs51.h"
3131#include "includes/thedeep.h"
3232#include "sound/2203intf.h"
trunk/src/mame/drivers/vsnes.c
r18874r18875
138138***************************************************************************/
139139
140140#include "emu.h"
141#include "cpu/m6502/m6502.h"
141#include "cpu/m6502/n2a03.h"
142142#include "rendlay.h"
143143#include "video/ppu2c0x.h"
144144#include "machine/rp5h01.h"
trunk/src/mame/drivers/funworld.c
r18874r18875
810810#define MASTER_CLOCK   XTAL_16MHz
811811
812812#include "emu.h"
813#include "cpu/m6502/m6502.h"
813#include "cpu/m6502/m65c02.h"
814#include "cpu/m6502/m65sc02.h"
814815#include "video/mc6845.h"
815816#include "machine/6821pia.h"
816817#include "sound/ay8910.h"
trunk/src/mame/drivers/exprraid.c
r18874r18875
204204***************************************************************************/
205205
206206#include "emu.h"
207#include "cpu/m6502/deco16.h"
207208#include "cpu/m6502/m6502.h"
208209#include "cpu/m6809/m6809.h"
209210#include "sound/2203intf.h"
trunk/src/mame/drivers/playch10.c
r18874r18875
290290***************************************************************************/
291291
292292#include "emu.h"
293#include "cpu/m6502/m6502.h"
293#include "cpu/m6502/n2a03.h"
294294#include "video/ppu2c0x.h"
295295#include "cpu/z80/z80.h"
296296#include "machine/rp5h01.h"
trunk/src/tools/unidasm.c
r18874r18875
125125CPU_DISASSEMBLE( lh5801 );
126126CPU_DISASSEMBLE( lr35902 );
127127CPU_DISASSEMBLE( m37710_generic );
128CPU_DISASSEMBLE( m6502 );
129CPU_DISASSEMBLE( m65sc02 );
130CPU_DISASSEMBLE( m65c02 );
131CPU_DISASSEMBLE( m65ce02 );
132CPU_DISASSEMBLE( m6510 );
133CPU_DISASSEMBLE( deco16 );
134CPU_DISASSEMBLE( m4510 );
135128CPU_DISASSEMBLE( m6800 );
136129CPU_DISASSEMBLE( m6801 );
137130CPU_DISASSEMBLE( m6802 );
r18874r18875
254247   { "lh5801",     _8bit,  0, CPU_DISASSEMBLE_NAME(lh5801) },
255248   { "lr35902",    _8bit,  0, CPU_DISASSEMBLE_NAME(lr35902) },
256249   { "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) },
264250   { "m6800",      _8bit,  0, CPU_DISASSEMBLE_NAME(m6800) },
265251   { "m6801",      _8bit,  0, CPU_DISASSEMBLE_NAME(m6801) },
266252   { "m6802",      _8bit,  0, CPU_DISASSEMBLE_NAME(m6802) },
trunk/src/emu/cpu/m6502/opsn2a03.h
r18874r18875
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)
trunk/src/emu/cpu/m6502/t6510.c
r18874r18875
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
37OP(00) {                  BRK;                 } /* 7 BRK */
38OP(20) {                  JSR;                 } /* 6 JSR */
39OP(40) {                  RTI;                 } /* 6 RTI */
40OP(60) {                  RTS;                 } /* 6 RTS */
41OP(80) { RDOPARG(); NOP;                 } /* 2 NOP IMM */
42OP(a0) { int tmp; RD_IMM; LDY;                 } /* 2 LDY IMM */
43OP(c0) { int tmp; RD_IMM; CPY;                 } /* 2 CPY IMM */
44OP(e0) { int tmp; RD_IMM; CPX;                 } /* 2 CPX IMM */
45
46OP(10) { BPL;                                  } /* 2-4 BPL REL */
47OP(30) { BMI;                                  } /* 2-4 BMI REL */
48OP(50) { BVC;                                  } /* 2-4 BVC REL */
49OP(70) { BVS;                                  } /* 2-4 BVS REL */
50OP(90) { BCC;                                  } /* 2-4 BCC REL */
51OP(b0) { BCS;                                  } /* 2-4 BCS REL */
52OP(d0) { BNE;                                  } /* 2-4 BNE REL */
53OP(f0) { BEQ;                                  } /* 2-4 BEQ REL */
54
55OP(01) { int tmp; RD_IDX; ORA;                 } /* 6 ORA IDX */
56OP(21) { int tmp; RD_IDX; AND;                 } /* 6 AND IDX */
57OP(41) { int tmp; RD_IDX; EOR;                 } /* 6 EOR IDX */
58OP(61) { int tmp; RD_IDX; ADC;                 } /* 6 ADC IDX */
59OP(81) { int tmp; STA; WR_IDX;                 } /* 6 STA IDX */
60OP(a1) { int tmp; RD_IDX; LDA;                 } /* 6 LDA IDX */
61OP(c1) { int tmp; RD_IDX; CMP;                 } /* 6 CMP IDX */
62OP(e1) { int tmp; RD_IDX; SBC;                 } /* 6 SBC IDX */
63
64OP(11) { int tmp; RD_IDY_P; ORA;               } /* 5 ORA IDY page penalty */
65OP(31) { int tmp; RD_IDY_P; AND;               } /* 5 AND IDY page penalty */
66OP(51) { int tmp; RD_IDY_P; EOR;               } /* 5 EOR IDY page penalty */
67OP(71) { int tmp; RD_IDY_P; ADC;               } /* 5 ADC IDY page penalty */
68OP(91) { int tmp; STA; WR_IDY_NP;              } /* 6 STA IDY */
69OP(b1) { int tmp; RD_IDY_P; LDA;               } /* 5 LDA IDY page penalty */
70OP(d1) { int tmp; RD_IDY_P; CMP;               } /* 5 CMP IDY page penalty */
71OP(f1) { int tmp; RD_IDY_P; SBC;               } /* 5 SBC IDY page penalty */
72
73OP(02) {                  KIL;                 } /* 1 KIL */
74OP(22) {                  KIL;                 } /* 1 KIL */
75OP(42) {                  KIL;                 } /* 1 KIL */
76OP(62) {                  KIL;                 } /* 1 KIL */
77OP(82) { RDOPARG(); NOP;                 } /* 2 NOP IMM */
78OP(a2) { int tmp; RD_IMM; LDX;                 } /* 2 LDX IMM */
79OP(c2) { RDOPARG(); NOP;                 } /* 2 NOP IMM */
80OP(e2) { RDOPARG(); NOP;                 } /* 2 NOP IMM */
81
82OP(12) { KIL;                                  } /* 1 KIL */
83OP(32) { KIL;                                  } /* 1 KIL */
84OP(52) { KIL;                                  } /* 1 KIL */
85OP(72) { KIL;                                  } /* 1 KIL */
86OP(92) { KIL;                                  } /* 1 KIL */
87OP(b2) { KIL;                                  } /* 1 KIL */
88OP(d2) { KIL;                                  } /* 1 KIL */
89OP(f2) { KIL;                                  } /* 1 KIL */
90
91OP(03) { int tmp; RD_IDX; WB_EA; SLO; WB_EA;   } /* 7 SLO IDX */
92OP(23) { int tmp; RD_IDX; WB_EA; RLA; WB_EA;   } /* 7 RLA IDX */
93OP(43) { int tmp; RD_IDX; WB_EA; SRE; WB_EA;   } /* 7 SRE IDX */
94OP(63) { int tmp; RD_IDX; WB_EA; RRA; WB_EA;   } /* 7 RRA IDX */
95OP(83) { int tmp;                SAX; WR_IDX;  } /* 6 SAX IDX */
96OP(a3) { int tmp; RD_IDX; LAX;                 } /* 6 LAX IDX */
97OP(c3) { int tmp; RD_IDX; WB_EA; DCP; WB_EA;   } /* 7 DCP IDX */
98OP(e3) { int tmp; RD_IDX; WB_EA; ISB; WB_EA;   } /* 7 ISB IDX */
99
100OP(13) { int tmp; RD_IDY_NP; WB_EA; SLO; WB_EA; } /* 7 SLO IDY */
101OP(33) { int tmp; RD_IDY_NP; WB_EA; RLA; WB_EA; } /* 7 RLA IDY */
102OP(53) { int tmp; RD_IDY_NP; WB_EA; SRE; WB_EA; } /* 7 SRE IDY */
103OP(73) { int tmp; RD_IDY_NP; WB_EA; RRA; WB_EA; } /* 7 RRA IDY */
104OP(93) { int tmp; EA_IDY_NP; SAH; WB_EA;        } /* 5 SAH IDY */
105OP(b3) { int tmp; RD_IDY_P; LAX;                } /* 5 LAX IDY page penalty */
106OP(d3) { int tmp; RD_IDY_NP; WB_EA; DCP; WB_EA; } /* 7 DCP IDY */
107OP(f3) { int tmp; RD_IDY_NP; WB_EA; ISB; WB_EA; } /* 7 ISB IDY */
108
109OP(04) { RD_ZPG_DISCARD; NOP;                  } /* 3 NOP ZPG */
110OP(24) { int tmp; RD_ZPG; BIT;                  } /* 3 BIT ZPG */
111OP(44) { RD_ZPG_DISCARD; NOP;                  } /* 3 NOP ZPG */
112OP(64) { RD_ZPG_DISCARD; NOP;                  } /* 3 NOP ZPG */
113OP(84) { int tmp; STY; WR_ZPG;                  } /* 3 STY ZPG */
114OP(a4) { int tmp; RD_ZPG; LDY;                  } /* 3 LDY ZPG */
115OP(c4) { int tmp; RD_ZPG; CPY;                  } /* 3 CPY ZPG */
116OP(e4) { int tmp; RD_ZPG; CPX;                  } /* 3 CPX ZPG */
117
118OP(14) { RD_ZPX_DISCARD; NOP;                  } /* 4 NOP ZPX */
119OP(34) { RD_ZPX_DISCARD; NOP;                  } /* 4 NOP ZPX */
120OP(54) { RD_ZPX_DISCARD; NOP;                  } /* 4 NOP ZPX */
121OP(74) { RD_ZPX_DISCARD; NOP;                  } /* 4 NOP ZPX */
122OP(94) { int tmp; STY; WR_ZPX;                  } /* 4 STY ZPX */
123OP(b4) { int tmp; RD_ZPX; LDY;                  } /* 4 LDY ZPX */
124OP(d4) { RD_ZPX_DISCARD; NOP;                  } /* 4 NOP ZPX */
125OP(f4) { RD_ZPX_DISCARD; NOP;                  } /* 4 NOP ZPX */
126
127OP(05) { int tmp; RD_ZPG; ORA;                  } /* 3 ORA ZPG */
128OP(25) { int tmp; RD_ZPG; AND;                  } /* 3 AND ZPG */
129OP(45) { int tmp; RD_ZPG; EOR;                  } /* 3 EOR ZPG */
130OP(65) { int tmp; RD_ZPG; ADC;                  } /* 3 ADC ZPG */
131OP(85) { int tmp; STA; WR_ZPG;                  } /* 3 STA ZPG */
132OP(a5) { int tmp; RD_ZPG; LDA;                  } /* 3 LDA ZPG */
133OP(c5) { int tmp; RD_ZPG; CMP;                  } /* 3 CMP ZPG */
134OP(e5) { int tmp; RD_ZPG; SBC;                  } /* 3 SBC ZPG */
135
136OP(15) { int tmp; RD_ZPX; ORA;                  } /* 4 ORA ZPX */
137OP(35) { int tmp; RD_ZPX; AND;                  } /* 4 AND ZPX */
138OP(55) { int tmp; RD_ZPX; EOR;                  } /* 4 EOR ZPX */
139OP(75) { int tmp; RD_ZPX; ADC;                  } /* 4 ADC ZPX */
140OP(95) { int tmp; STA; WR_ZPX;                  } /* 4 STA ZPX */
141OP(b5) { int tmp; RD_ZPX; LDA;                  } /* 4 LDA ZPX */
142OP(d5) { int tmp; RD_ZPX; CMP;                  } /* 4 CMP ZPX */
143OP(f5) { int tmp; RD_ZPX; SBC;                  } /* 4 SBC ZPX */
144
145OP(06) { int tmp; RD_ZPG; WB_EA; ASL; WB_EA;    } /* 5 ASL ZPG */
146OP(26) { int tmp; RD_ZPG; WB_EA; ROL; WB_EA;    } /* 5 ROL ZPG */
147OP(46) { int tmp; RD_ZPG; WB_EA; LSR; WB_EA;    } /* 5 LSR ZPG */
148OP(66) { int tmp; RD_ZPG; WB_EA; ROR; WB_EA;    } /* 5 ROR ZPG */
149OP(86) { int tmp; STX; WR_ZPG;                  } /* 3 STX ZPG */
150OP(a6) { int tmp; RD_ZPG; LDX;                  } /* 3 LDX ZPG */
151OP(c6) { int tmp; RD_ZPG; WB_EA; DEC; WB_EA;    } /* 5 DEC ZPG */
152OP(e6) { int tmp; RD_ZPG; WB_EA; INC; WB_EA;    } /* 5 INC ZPG */
153
154OP(16) { int tmp; RD_ZPX; WB_EA; ASL; WB_EA;    } /* 6 ASL ZPX */
155OP(36) { int tmp; RD_ZPX; WB_EA; ROL; WB_EA;    } /* 6 ROL ZPX */
156OP(56) { int tmp; RD_ZPX; WB_EA; LSR; WB_EA;    } /* 6 LSR ZPX */
157OP(76) { int tmp; RD_ZPX; WB_EA; ROR; WB_EA;    } /* 6 ROR ZPX */
158OP(96) { int tmp; STX; WR_ZPY;                  } /* 4 STX ZPY */
159OP(b6) { int tmp; RD_ZPY; LDX;                  } /* 4 LDX ZPY */
160OP(d6) { int tmp; RD_ZPX; WB_EA; DEC; WB_EA;    } /* 6 DEC ZPX */
161OP(f6) { int tmp; RD_ZPX; WB_EA; INC; WB_EA;    } /* 6 INC ZPX */
162
163OP(07) { int tmp; RD_ZPG; WB_EA; SLO; WB_EA;    } /* 5 SLO ZPG */
164OP(27) { int tmp; RD_ZPG; WB_EA; RLA; WB_EA;    } /* 5 RLA ZPG */
165OP(47) { int tmp; RD_ZPG; WB_EA; SRE; WB_EA;    } /* 5 SRE ZPG */
166OP(67) { int tmp; RD_ZPG; WB_EA; RRA; WB_EA;    } /* 5 RRA ZPG */
167OP(87) { int tmp; SAX; WR_ZPG;                  } /* 3 SAX ZPG */
168OP(a7) { int tmp; RD_ZPG; LAX;                  } /* 3 LAX ZPG */
169OP(c7) { int tmp; RD_ZPG; WB_EA; DCP; WB_EA;    } /* 5 DCP ZPG */
170OP(e7) { int tmp; RD_ZPG; WB_EA; ISB; WB_EA;    } /* 5 ISB ZPG */
171
172OP(17) { int tmp; RD_ZPX; WB_EA; SLO; WB_EA;    } /* 6 SLO ZPX */
173OP(37) { int tmp; RD_ZPX; WB_EA; RLA; WB_EA;    } /* 6 RLA ZPX */
174OP(57) { int tmp; RD_ZPX; WB_EA; SRE; WB_EA;    } /* 6 SRE ZPX */
175OP(77) { int tmp; RD_ZPX; WB_EA; RRA; WB_EA;    } /* 6 RRA ZPX */
176OP(97) { int tmp; SAX; WR_ZPY;                  } /* 4 SAX ZPY */
177OP(b7) { int tmp; RD_ZPY; LAX;                  } /* 4 LAX ZPY */
178OP(d7) { int tmp; RD_ZPX; WB_EA; DCP; WB_EA;    } /* 6 DCP ZPX */
179OP(f7) { int tmp; RD_ZPX; WB_EA; ISB; WB_EA;    } /* 6 ISB ZPX */
180
181OP(08) { RD_DUM; PHP;                           } /* 3 PHP */
182OP(28) { RD_DUM; PLP;                           } /* 4 PLP */
183OP(48) { RD_DUM; PHA;                           } /* 3 PHA */
184OP(68) { RD_DUM; PLA;                           } /* 4 PLA */
185OP(88) { RD_DUM; DEY;                           } /* 2 DEY */
186OP(a8) { RD_DUM; TAY;                           } /* 2 TAY */
187OP(c8) { RD_DUM; INY;                           } /* 2 INY */
188OP(e8) { RD_DUM; INX;                           } /* 2 INX */
189
190OP(18) { RD_DUM; CLC;                           } /* 2 CLC */
191OP(38) { RD_DUM; SEC;                           } /* 2 SEC */
192OP(58) { RD_DUM; CLI;                           } /* 2 CLI */
193OP(78) { RD_DUM; SEI;                           } /* 2 SEI */
194OP(98) { RD_DUM; TYA;                           } /* 2 TYA */
195OP(b8) { RD_DUM; CLV;                           } /* 2 CLV */
196OP(d8) { RD_DUM; CLD;                           } /* 2 CLD */
197OP(f8) { RD_DUM; SED;                           } /* 2 SED */
198
199OP(09) { int tmp; RD_IMM; ORA;                  } /* 2 ORA IMM */
200OP(29) { int tmp; RD_IMM; AND;                  } /* 2 AND IMM */
201OP(49) { int tmp; RD_IMM; EOR;                  } /* 2 EOR IMM */
202OP(69) { int tmp; RD_IMM; ADC;                  } /* 2 ADC IMM */
203OP(89) { RD_IMM_DISCARD; NOP;                  } /* 2 NOP IMM */
204OP(a9) { int tmp; RD_IMM; LDA;                  } /* 2 LDA IMM */
205OP(c9) { int tmp; RD_IMM; CMP;                  } /* 2 CMP IMM */
206OP(e9) { int tmp; RD_IMM; SBC;                  } /* 2 SBC IMM */
207
208OP(19) { int tmp; RD_ABY_P; ORA;                } /* 4 ORA ABY page penalty */
209OP(39) { int tmp; RD_ABY_P; AND;                } /* 4 AND ABY page penalty */
210OP(59) { int tmp; RD_ABY_P; EOR;                } /* 4 EOR ABY page penalty */
211OP(79) { int tmp; RD_ABY_P; ADC;                } /* 4 ADC ABY page penalty */
212OP(99) { int tmp; STA; WR_ABY_NP;               } /* 5 STA ABY */
213OP(b9) { int tmp; RD_ABY_P; LDA;                } /* 4 LDA ABY page penalty */
214OP(d9) { int tmp; RD_ABY_P; CMP;                } /* 4 CMP ABY page penalty */
215OP(f9) { int tmp; RD_ABY_P; SBC;                } /* 4 SBC ABY page penalty */
216
217OP(0a) { int tmp; RD_DUM; RD_ACC; ASL; WB_ACC;  } /* 2 ASL A */
218OP(2a) { int tmp; RD_DUM; RD_ACC; ROL; WB_ACC;  } /* 2 ROL A */
219OP(4a) { int tmp; RD_DUM; RD_ACC; LSR; WB_ACC;  } /* 2 LSR A */
220OP(6a) { int tmp; RD_DUM; RD_ACC; ROR; WB_ACC;  } /* 2 ROR A */
221OP(8a) { RD_DUM; TXA;                           } /* 2 TXA */
222OP(aa) { RD_DUM; TAX;                           } /* 2 TAX */
223OP(ca) { RD_DUM; DEX;                           } /* 2 DEX */
224OP(ea) { RD_DUM; NOP;                           } /* 2 NOP */
225
226OP(1a) { RD_DUM; NOP;                           } /* 2 NOP */
227OP(3a) { RD_DUM; NOP;                           } /* 2 NOP */
228OP(5a) { RD_DUM; NOP;                           } /* 2 NOP */
229OP(7a) { RD_DUM; NOP;                           } /* 2 NOP */
230OP(9a) { RD_DUM; TXS;                           } /* 2 TXS */
231OP(ba) { RD_DUM; TSX;                           } /* 2 TSX */
232OP(da) { RD_DUM; NOP;                           } /* 2 NOP */
233OP(fa) { RD_DUM; NOP;                           } /* 2 NOP */
234
235OP(0b) { int tmp; RD_IMM; ANC;                  } /* 2 ANC IMM */
236OP(2b) { int tmp; RD_IMM; ANC;                  } /* 2 ANC IMM */
237OP(4b) { int tmp; RD_IMM; ASR; WB_ACC;          } /* 2 ASR IMM */
238OP(6b) { int tmp; RD_IMM; ARR; WB_ACC;          } /* 2 ARR IMM */
239OP(8b) { int tmp; RD_IMM; AXA;                  } /* 2 AXA IMM */
240OP(ab) { int tmp; RD_IMM; OAL_6510;             } /* 2 OAL IMM */
241OP(cb) { int tmp; RD_IMM; ASX;                  } /* 2 ASX IMM */
242OP(eb) { int tmp; RD_IMM; SBC;                  } /* 2 SBC IMM */
243
244OP(1b) { int tmp; RD_ABY_NP; WB_EA; SLO; WB_EA; } /* 7 SLO ABY */
245OP(3b) { int tmp; RD_ABY_NP; WB_EA; RLA; WB_EA; } /* 7 RLA ABY */
246OP(5b) { int tmp; RD_ABY_NP; WB_EA; SRE; WB_EA; } /* 7 SRE ABY */
247OP(7b) { int tmp; RD_ABY_NP; WB_EA; RRA; WB_EA; } /* 7 RRA ABY */
248OP(9b) { int tmp; EA_ABY_NP; SSH; WB_EA;        } /* 5 SSH ABY */
249OP(bb) { int tmp; RD_ABY_P; AST;                } /* 4 AST ABY page penalty */
250OP(db) { int tmp; RD_ABY_NP; WB_EA; DCP; WB_EA; } /* 7 DCP ABY */
251OP(fb) { int tmp; RD_ABY_NP; WB_EA; ISB; WB_EA; } /* 7 ISB ABY */
252
253OP(0c) { RD_ABS_DISCARD; NOP;                  } /* 4 NOP ABS */
254OP(2c) { int tmp; RD_ABS; BIT;                  } /* 4 BIT ABS */
255OP(4c) { EA_ABS; JMP;                           } /* 3 JMP ABS */
256OP(6c) { int tmp; EA_IND; JMP;                  } /* 5 JMP IND */
257OP(8c) { int tmp; STY; WR_ABS;                  } /* 4 STY ABS */
258OP(ac) { int tmp; RD_ABS; LDY;                  } /* 4 LDY ABS */
259OP(cc) { int tmp; RD_ABS; CPY;                  } /* 4 CPY ABS */
260OP(ec) { int tmp; RD_ABS; CPX;                  } /* 4 CPX ABS */
261
262OP(1c) { RD_ABX_P_DISCARD; NOP;                } /* 4 NOP ABX page penalty */
263OP(3c) { RD_ABX_P_DISCARD; NOP;                } /* 4 NOP ABX page penalty */
264OP(5c) { RD_ABX_P_DISCARD; NOP;                } /* 4 NOP ABX page penalty */
265OP(7c) { RD_ABX_P_DISCARD; NOP;                } /* 4 NOP ABX page penalty */
266OP(9c) { int tmp; EA_ABX_NP; SYH; WB_EA;        } /* 5 SYH ABX */
267OP(bc) { int tmp; RD_ABX_P; LDY;                } /* 4 LDY ABX page penalty */
268OP(dc) { RD_ABX_P_DISCARD; NOP;                } /* 4 NOP ABX page penalty */
269OP(fc) { RD_ABX_P_DISCARD; NOP;                } /* 4 NOP ABX page penalty */
270
271OP(0d) { int tmp; RD_ABS; ORA;                  } /* 4 ORA ABS */
272OP(2d) { int tmp; RD_ABS; AND;                  } /* 4 AND ABS */
273OP(4d) { int tmp; RD_ABS; EOR;                  } /* 4 EOR ABS */
274OP(6d) { int tmp; RD_ABS; ADC;                  } /* 4 ADC ABS */
275OP(8d) { int tmp; STA; WR_ABS;                  } /* 4 STA ABS */
276OP(ad) { int tmp; RD_ABS; LDA;                  } /* 4 LDA ABS */
277OP(cd) { int tmp; RD_ABS; CMP;                  } /* 4 CMP ABS */
278OP(ed) { int tmp; RD_ABS; SBC;                  } /* 4 SBC ABS */
279
280OP(1d) { int tmp; RD_ABX_P; ORA;                } /* 4 ORA ABX page penalty */
281OP(3d) { int tmp; RD_ABX_P; AND;                } /* 4 AND ABX page penalty */
282OP(5d) { int tmp; RD_ABX_P; EOR;                } /* 4 EOR ABX page penalty */
283OP(7d) { int tmp; RD_ABX_P; ADC;                } /* 4 ADC ABX page penalty */
284OP(9d) { int tmp; STA; WR_ABX_NP;               } /* 5 STA ABX */
285OP(bd) { int tmp; RD_ABX_P; LDA;                } /* 4 LDA ABX page penalty */
286OP(dd) { int tmp; RD_ABX_P; CMP;                } /* 4 CMP ABX page penalty */
287OP(fd) { int tmp; RD_ABX_P; SBC;                } /* 4 SBC ABX page penalty */
288
289OP(0e) { int tmp; RD_ABS; WB_EA; ASL; WB_EA;    } /* 6 ASL ABS */
290OP(2e) { int tmp; RD_ABS; WB_EA; ROL; WB_EA;    } /* 6 ROL ABS */
291OP(4e) { int tmp; RD_ABS; WB_EA; LSR; WB_EA;    } /* 6 LSR ABS */
292OP(6e) { int tmp; RD_ABS; WB_EA; ROR; WB_EA;    } /* 6 ROR ABS */
293OP(8e) { int tmp; STX; WR_ABS;                  } /* 4 STX ABS */
294OP(ae) { int tmp; RD_ABS; LDX;                  } /* 4 LDX ABS */
295OP(ce) { int tmp; RD_ABS; WB_EA; DEC; WB_EA;    } /* 6 DEC ABS */
296OP(ee) { int tmp; RD_ABS; WB_EA; INC; WB_EA;    } /* 6 INC ABS */
297
298OP(1e) { int tmp; RD_ABX_NP; WB_EA; ASL; WB_EA; } /* 7 ASL ABX */
299OP(3e) { int tmp; RD_ABX_NP; WB_EA; ROL; WB_EA; } /* 7 ROL ABX */
300OP(5e) { int tmp; RD_ABX_NP; WB_EA; LSR; WB_EA; } /* 7 LSR ABX */
301OP(7e) { int tmp; RD_ABX_NP; WB_EA; ROR; WB_EA; } /* 7 ROR ABX */
302OP(9e) { int tmp; EA_ABY_NP; SXH; WB_EA;   } /* 5 SXH ABY */
303OP(be) { int tmp; RD_ABY_P; LDX;      } /* 4 LDX ABY page penalty */
304OP(de) { int tmp; RD_ABX_NP; WB_EA; DEC; WB_EA; } /* 7 DEC ABX */
305OP(fe) { int tmp; RD_ABX_NP; WB_EA; INC; WB_EA; } /* 7 INC ABX */
306
307OP(0f) { int tmp; RD_ABS; WB_EA; SLO; WB_EA;    } /* 6 SLO ABS */
308OP(2f) { int tmp; RD_ABS; WB_EA; RLA; WB_EA;    } /* 6 RLA ABS */
309OP(4f) { int tmp; RD_ABS; WB_EA; SRE; WB_EA;    } /* 6 SRE ABS */
310OP(6f) { int tmp; RD_ABS; WB_EA; RRA; WB_EA;    } /* 6 RRA ABS */
311OP(8f) { int tmp; SAX; WR_ABS;                  } /* 4 SAX ABS */
312OP(af) { int tmp; RD_ABS; LAX;                  } /* 4 LAX ABS */
313OP(cf) { int tmp; RD_ABS; WB_EA; DCP; WB_EA;    } /* 6 DCP ABS */
314OP(ef) { int tmp; RD_ABS; WB_EA; ISB; WB_EA;    } /* 6 ISB ABS */
315
316OP(1f) { int tmp; RD_ABX_NP; WB_EA; SLO; WB_EA; } /* 7 SLO ABX */
317OP(3f) { int tmp; RD_ABX_NP; WB_EA; RLA; WB_EA; } /* 7 RLA ABX */
318OP(5f) { int tmp; RD_ABX_NP; WB_EA; SRE; WB_EA; } /* 7 SRE ABX */
319OP(7f) { int tmp; RD_ABX_NP; WB_EA; RRA; WB_EA; } /* 7 RRA ABX */
320OP(9f) { int tmp; EA_ABY_NP; SAH; WB_EA;        } /* 5 SAH ABY */
321OP(bf) { int tmp; RD_ABY_P; LAX;                } /* 4 LAX ABY page penalty */
322OP(df) { int tmp; RD_ABX_NP; WB_EA; DCP; WB_EA; } /* 7 DCP ABX */
323OP(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
327static 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
trunk/src/emu/cpu/m6502/opsce02.h
r18874r18875
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)
trunk/src/emu/cpu/m6502/ill02.h
r18874r18875
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__ */
trunk/src/emu/cpu/m6502/mincce02.h
r18874r18875
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
trunk/src/emu/cpu/m6502/ops02.h
r18874r18875
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)
trunk/src/emu/cpu/m6502/opsc02.h
r18874r18875
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;
trunk/src/emu/cpu/m6502/ops4510.h
r18874r18875
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))
trunk/src/emu/cpu/m6502/t6502.c
r18874r18875
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
36OP(00) {                  BRK;                 } /* 7 BRK */
37OP(20) {                  JSR;                 } /* 6 JSR */
38OP(40) {                  RTI;                 } /* 6 RTI */
39OP(60) {                  RTS;                 } /* 6 RTS */
40OP(80) { RDOPARG(); NOP;                 } /* 2 NOP IMM */
41OP(a0) { int tmp; RD_IMM; LDY;                 } /* 2 LDY IMM */
42OP(c0) { int tmp; RD_IMM; CPY;                 } /* 2 CPY IMM */
43OP(e0) { int tmp; RD_IMM; CPX;                 } /* 2 CPX IMM */
44
45OP(10) { BPL;                                  } /* 2-4 BPL REL */
46OP(30) { BMI;                                  } /* 2-4 BMI REL */
47OP(50) { BVC;                                  } /* 2-4 BVC REL */
48OP(70) { BVS;                                  } /* 2-4 BVS REL */
49OP(90) { BCC;                                  } /* 2-4 BCC REL */
50OP(b0) { BCS;                                  } /* 2-4 BCS REL */
51OP(d0) { BNE;                                  } /* 2-4 BNE REL */
52OP(f0) { BEQ;                                  } /* 2-4 BEQ REL */
53
54OP(01) { int tmp; RD_IDX; ORA;                 } /* 6 ORA IDX */
55OP(21) { int tmp; RD_IDX; AND;                 } /* 6 AND IDX */
56OP(41) { int tmp; RD_IDX; EOR;                 } /* 6 EOR IDX */
57OP(61) { int tmp; RD_IDX; ADC;                 } /* 6 ADC IDX */
58OP(81) { int tmp; STA; WR_IDX;                 } /* 6 STA IDX */
59OP(a1) { int tmp; RD_IDX; LDA;                 } /* 6 LDA IDX */
60OP(c1) { int tmp; RD_IDX; CMP;                 } /* 6 CMP IDX */
61OP(e1) { int tmp; RD_IDX; SBC;                 } /* 6 SBC IDX */
62
63OP(11) { int tmp; RD_IDY_P; ORA;               } /* 5 ORA IDY page penalty */
64OP(31) { int tmp; RD_IDY_P; AND;               } /* 5 AND IDY page penalty */
65OP(51) { int tmp; RD_IDY_P; EOR;               } /* 5 EOR IDY page penalty */
66OP(71) { int tmp; RD_IDY_P; ADC;               } /* 5 ADC IDY page penalty */
67OP(91) { int tmp; STA; WR_IDY_NP;              } /* 6 STA IDY */
68OP(b1) { int tmp; RD_IDY_P; LDA;               } /* 5 LDA IDY page penalty */
69OP(d1) { int tmp; RD_IDY_P; CMP;               } /* 5 CMP IDY page penalty */
70OP(f1) { int tmp; RD_IDY_P; SBC;               } /* 5 SBC IDY page penalty */
71
72OP(02) {                  KIL;                 } /* 1 KIL */
73OP(22) {                  KIL;                 } /* 1 KIL */
74OP(42) {                  KIL;                 } /* 1 KIL */
75OP(62) {                  KIL;                 } /* 1 KIL */
76OP(82) { RDOPARG(); NOP;                 } /* 2 NOP IMM */
77OP(a2) { int tmp; RD_IMM; LDX;                 } /* 2 LDX IMM */
78OP(c2) { RDOPARG(); NOP;                 } /* 2 NOP IMM */
79OP(e2) { RDOPARG(); NOP;                 } /* 2 NOP IMM */
80
81OP(12) { KIL;                                  } /* 1 KIL */
82OP(32) { KIL;                                  } /* 1 KIL */
83OP(52) { KIL;                                  } /* 1 KIL */
84OP(72) { KIL;                                  } /* 1 KIL */
85OP(92) { KIL;                                  } /* 1 KIL */
86OP(b2) { KIL;                                  } /* 1 KIL */
87OP(d2) { KIL;                                  } /* 1 KIL */
88OP(f2) { KIL;                                  } /* 1 KIL */
89
90OP(03) { int tmp; RD_IDX; WB_EA; SLO; WB_EA;   } /* 7 SLO IDX */
91OP(23) { int tmp; RD_IDX; WB_EA; RLA; WB_EA;   } /* 7 RLA IDX */
92OP(43) { int tmp; RD_IDX; WB_EA; SRE; WB_EA;   } /* 7 SRE IDX */
93OP(63) { int tmp; RD_IDX; WB_EA; RRA; WB_EA;   } /* 7 RRA IDX */
94OP(83) { int tmp;                SAX; WR_IDX;  } /* 6 SAX IDX */
95OP(a3) { int tmp; RD_IDX; LAX;                 } /* 6 LAX IDX */
96OP(c3) { int tmp; RD_IDX; WB_EA; DCP; WB_EA;   } /* 7 DCP IDX */
97OP(e3) { int tmp; RD_IDX; WB_EA; ISB; WB_EA;   } /* 7 ISB IDX */
98
99OP(13) { int tmp; RD_IDY_NP; WB_EA; SLO; WB_EA; } /* 7 SLO IDY */
100OP(33) { int tmp; RD_IDY_NP; WB_EA; RLA; WB_EA; } /* 7 RLA IDY */
101OP(53) { int tmp; RD_IDY_NP; WB_EA; SRE; WB_EA; } /* 7 SRE IDY */
102OP(73) { int tmp; RD_IDY_NP; WB_EA; RRA; WB_EA; } /* 7 RRA IDY */
103OP(93) { int tmp; EA_IDY_NP; SAH; WB_EA;        } /* 5 SAH IDY */
104OP(b3) { int tmp; RD_IDY_P; LAX;                } /* 5 LAX IDY page penalty */
105OP(d3) { int tmp; RD_IDY_NP; WB_EA; DCP; WB_EA; } /* 7 DCP IDY */
106OP(f3) { int tmp; RD_IDY_NP; WB_EA; ISB; WB_EA; } /* 7 ISB IDY */
107
108OP(04) { RD_ZPG_DISCARD; NOP;                  } /* 3 NOP ZPG */
109OP(24) { int tmp; RD_ZPG; BIT;                  } /* 3 BIT ZPG */
110OP(44) { RD_ZPG_DISCARD; NOP;                  } /* 3 NOP ZPG */
111OP(64) { RD_ZPG_DISCARD; NOP;                  } /* 3 NOP ZPG */
112OP(84) { int tmp; STY; WR_ZPG;                  } /* 3 STY ZPG */
113OP(a4) { int tmp; RD_ZPG; LDY;                  } /* 3 LDY ZPG */
114OP(c4) { int tmp; RD_ZPG; CPY;                  } /* 3 CPY ZPG */
115OP(e4) { int tmp; RD_ZPG; CPX;                  } /* 3 CPX ZPG */
116
117OP(14) { RD_ZPX_DISCARD; NOP;                  } /* 4 NOP ZPX */
118OP(34) { RD_ZPX_DISCARD; NOP;                  } /* 4 NOP ZPX */
119OP(54) { RD_ZPX_DISCARD; NOP;                  } /* 4 NOP ZPX */
120OP(74) { RD_ZPX_DISCARD; NOP;                  } /* 4 NOP ZPX */
121OP(94) { int tmp; STY; WR_ZPX;                  } /* 4 STY ZPX */
122OP(b4) { int tmp; RD_ZPX; LDY;                  } /* 4 LDY ZPX */
123OP(d4) { RD_ZPX_DISCARD; NOP;                  } /* 4 NOP ZPX */
124OP(f4) { RD_ZPX_DISCARD; NOP;                  } /* 4 NOP ZPX */
125
126OP(05) { int tmp; RD_ZPG; ORA;                  } /* 3 ORA ZPG */
127OP(25) { int tmp; RD_ZPG; AND;                  } /* 3 AND ZPG */
128OP(45) { int tmp; RD_ZPG; EOR;                  } /* 3 EOR ZPG */
129OP(65) { int tmp; RD_ZPG; ADC;                  } /* 3 ADC ZPG */
130OP(85) { int tmp; STA; WR_ZPG;                  } /* 3 STA ZPG */
131OP(a5) { int tmp; RD_ZPG; LDA;                  } /* 3 LDA ZPG */
132OP(c5) { int tmp; RD_ZPG; CMP;                  } /* 3 CMP ZPG */
133OP(e5) { int tmp; RD_ZPG; SBC;                  } /* 3 SBC ZPG */
134
135OP(15) { int tmp; RD_ZPX; ORA;                  } /* 4 ORA ZPX */
136OP(35) { int tmp; RD_ZPX; AND;                  } /* 4 AND ZPX */
137OP(55) { int tmp; RD_ZPX; EOR;                  } /* 4 EOR ZPX */
138OP(75) { int tmp; RD_ZPX; ADC;                  } /* 4 ADC ZPX */
139OP(95) { int tmp; STA; WR_ZPX;                  } /* 4 STA ZPX */
140OP(b5) { int tmp; RD_ZPX; LDA;                  } /* 4 LDA ZPX */
141OP(d5) { int tmp; RD_ZPX; CMP;                  } /* 4 CMP ZPX */
142OP(f5) { int tmp; RD_ZPX; SBC;                  } /* 4 SBC ZPX */
143
144OP(06) { int tmp; RD_ZPG; WB_EA; ASL; WB_EA;    } /* 5 ASL ZPG */
145OP(26) { int tmp; RD_ZPG; WB_EA; ROL; WB_EA;    } /* 5 ROL ZPG */
146OP(46) { int tmp; RD_ZPG; WB_EA; LSR; WB_EA;    } /* 5 LSR ZPG */
147OP(66) { int tmp; RD_ZPG; WB_EA; ROR; WB_EA;    } /* 5 ROR ZPG */
148OP(86) { int tmp; STX; WR_ZPG;                  } /* 3 STX ZPG */
149OP(a6) { int tmp; RD_ZPG; LDX;                  } /* 3 LDX ZPG */
150OP(c6) { int tmp; RD_ZPG; WB_EA; DEC; WB_EA;    } /* 5 DEC ZPG */
151OP(e6) { int tmp; RD_ZPG; WB_EA; INC; WB_EA;    } /* 5 INC ZPG */
152
153OP(16) { int tmp; RD_ZPX; WB_EA; ASL; WB_EA;    } /* 6 ASL ZPX */
154OP(36) { int tmp; RD_ZPX; WB_EA; ROL; WB_EA;    } /* 6 ROL ZPX */
155OP(56) { int tmp; RD_ZPX; WB_EA; LSR; WB_EA;    } /* 6 LSR ZPX */
156OP(76) { int tmp; RD_ZPX; WB_EA; ROR; WB_EA;    } /* 6 ROR ZPX */
157OP(96) { int tmp; STX; WR_ZPY;                  } /* 4 STX ZPY */
158OP(b6) { int tmp; RD_ZPY; LDX;                  } /* 4 LDX ZPY */
159OP(d6) { int tmp; RD_ZPX; WB_EA; DEC; WB_EA;    } /* 6 DEC ZPX */
160OP(f6) { int tmp; RD_ZPX; WB_EA; INC; WB_EA;    } /* 6 INC ZPX */
161
162OP(07) { int tmp; RD_ZPG; WB_EA; SLO; WB_EA;    } /* 5 SLO ZPG */
163OP(27) { int tmp; RD_ZPG; WB_EA; RLA; WB_EA;    } /* 5 RLA ZPG */
164OP(47) { int tmp; RD_ZPG; WB_EA; SRE; WB_EA;    } /* 5 SRE ZPG */
165OP(67) { int tmp; RD_ZPG; WB_EA; RRA; WB_EA;    } /* 5 RRA ZPG */
166OP(87) { int tmp; SAX; WR_ZPG;                  } /* 3 SAX ZPG */
167OP(a7) { int tmp; RD_ZPG; LAX;                  } /* 3 LAX ZPG */
168OP(c7) { int tmp; RD_ZPG; WB_EA; DCP; WB_EA;    } /* 5 DCP ZPG */
169OP(e7) { int tmp; RD_ZPG; WB_EA; ISB; WB_EA;    } /* 5 ISB ZPG */
170
171OP(17) { int tmp; RD_ZPX; WB_EA; SLO; WB_EA;    } /* 6 SLO ZPX */
172OP(37) { int tmp; RD_ZPX; WB_EA; RLA; WB_EA;    } /* 6 RLA ZPX */
173OP(57) { int tmp; RD_ZPX; WB_EA; SRE; WB_EA;    } /* 6 SRE ZPX */
174OP(77) { int tmp; RD_ZPX; WB_EA; RRA; WB_EA;    } /* 6 RRA ZPX */
175OP(97) { int tmp; SAX; WR_ZPY;                  } /* 4 SAX ZPY */
176OP(b7) { int tmp; RD_ZPY; LAX;                  } /* 4 LAX ZPY */
177OP(d7) { int tmp; RD_ZPX; WB_EA; DCP; WB_EA;    } /* 6 DCP ZPX */
178OP(f7) { int tmp; RD_ZPX; WB_EA; ISB; WB_EA;    } /* 6 ISB ZPX */
179
180OP(08) { RD_DUM; PHP;                           } /* 3 PHP */
181OP(28) { RD_DUM; PLP;                           } /* 4 PLP */
182OP(48) { RD_DUM; PHA;                           } /* 3 PHA */
183OP(68) { RD_DUM; PLA;                           } /* 4 PLA */
184OP(88) { RD_DUM; DEY;                           } /* 2 DEY */
185OP(a8) { RD_DUM; TAY;                           } /* 2 TAY */
186OP(c8) { RD_DUM; INY;                           } /* 2 INY */
187OP(e8) { RD_DUM; INX;                           } /* 2 INX */
188
189OP(18) { RD_DUM; CLC;                           } /* 2 CLC */
190OP(38) { RD_DUM; SEC;                           } /* 2 SEC */
191OP(58) { RD_DUM; CLI;                           } /* 2 CLI */
192OP(78) { RD_DUM; SEI;                           } /* 2 SEI */
193OP(98) { RD_DUM; TYA;                           } /* 2 TYA */
194OP(b8) { RD_DUM; CLV;                           } /* 2 CLV */
195OP(d8) { RD_DUM; CLD;                           } /* 2 CLD */
196OP(f8) { RD_DUM; SED;                           } /* 2 SED */
197
198OP(09) { int tmp; RD_IMM; ORA;                  } /* 2 ORA IMM */
199OP(29) { int tmp; RD_IMM; AND;                  } /* 2 AND IMM */
200OP(49) { int tmp; RD_IMM; EOR;                  } /* 2 EOR IMM */
201OP(69) { int tmp; RD_IMM; ADC;                  } /* 2 ADC IMM */
202OP(89) { RD_IMM_DISCARD; NOP;                  } /* 2 NOP IMM */
203OP(a9) { int tmp; RD_IMM; LDA;                  } /* 2 LDA IMM */
204OP(c9) { int tmp; RD_IMM; CMP;                  } /* 2 CMP IMM */
205OP(e9) { int tmp; RD_IMM; SBC;                  } /* 2 SBC IMM */
206
207OP(19) { int tmp; RD_ABY_P; ORA;                } /* 4 ORA ABY page penalty */
208OP(39) { int tmp; RD_ABY_P; AND;                } /* 4 AND ABY page penalty */
209OP(59) { int tmp; RD_ABY_P; EOR;                } /* 4 EOR ABY page penalty */
210OP(79) { int tmp; RD_ABY_P; ADC;                } /* 4 ADC ABY page penalty */
211OP(99) { int tmp; STA; WR_ABY_NP;               } /* 5 STA ABY */
212OP(b9) { int tmp; RD_ABY_P; LDA;                } /* 4 LDA ABY page penalty */
213OP(d9) { int tmp; RD_ABY_P; CMP;                } /* 4 CMP ABY page penalty */
214OP(f9) { int tmp; RD_ABY_P; SBC;                } /* 4 SBC ABY page penalty */
215
216OP(0a) { int tmp; RD_DUM; RD_ACC; ASL; WB_ACC;  } /* 2 ASL A */
217OP(2a) { int tmp; RD_DUM; RD_ACC; ROL; WB_ACC;  } /* 2 ROL A */
218OP(4a) { int tmp; RD_DUM; RD_ACC; LSR; WB_ACC;  } /* 2 LSR A */
219OP(6a) { int tmp; RD_DUM; RD_ACC; ROR; WB_ACC;  } /* 2 ROR A */
220OP(8a) { RD_DUM; TXA;                           } /* 2 TXA */
221OP(aa) { RD_DUM; TAX;                           } /* 2 TAX */
222OP(ca) { RD_DUM; DEX;                           } /* 2 DEX */
223OP(ea) { RD_DUM; NOP;                           } /* 2 NOP */
224
225OP(1a) { RD_DUM; NOP;                           } /* 2 NOP */
226OP(3a) { RD_DUM; NOP;                           } /* 2 NOP */
227OP(5a) { RD_DUM; NOP;                           } /* 2 NOP */
228OP(7a) { RD_DUM; NOP;                           } /* 2 NOP */
229OP(9a) { RD_DUM; TXS;                           } /* 2 TXS */
230OP(ba) { RD_DUM; TSX;                           } /* 2 TSX */
231OP(da) { RD_DUM; NOP;                           } /* 2 NOP */
232OP(fa) { RD_DUM; NOP;                           } /* 2 NOP */
233
234OP(0b) { int tmp; RD_IMM; ANC;                  } /* 2 ANC IMM */
235OP(2b) { int tmp; RD_IMM; ANC;                  } /* 2 ANC IMM */
236OP(4b) { int tmp; RD_IMM; ASR; WB_ACC;          } /* 2 ASR IMM */
237OP(6b) { int tmp; RD_IMM; ARR; WB_ACC;          } /* 2 ARR IMM */
238OP(8b) { int tmp; RD_IMM; AXA;                  } /* 2 AXA IMM */
239OP(ab) { int tmp; RD_IMM; OAL;                  } /* 2 OAL IMM */
240OP(cb) { int tmp; RD_IMM; ASX;                  } /* 2 ASX IMM */
241OP(eb) { int tmp; RD_IMM; SBC;                  } /* 2 SBC IMM */
242
243OP(1b) { int tmp; RD_ABY_NP; WB_EA; SLO; WB_EA; } /* 7 SLO ABY */
244OP(3b) { int tmp; RD_ABY_NP; WB_EA; RLA; WB_EA; } /* 7 RLA ABY */
245OP(5b) { int tmp; RD_ABY_NP; WB_EA; SRE; WB_EA; } /* 7 SRE ABY */
246OP(7b) { int tmp; RD_ABY_NP; WB_EA; RRA; WB_EA; } /* 7 RRA ABY */
247OP(9b) { int tmp; EA_ABY_NP; SSH; WB_EA;        } /* 5 SSH ABY */
248OP(bb) { int tmp; RD_ABY_P; AST;                } /* 4 AST ABY page penalty */
249OP(db) { int tmp; RD_ABY_NP; WB_EA; DCP; WB_EA; } /* 7 DCP ABY */
250OP(fb) { int tmp; RD_ABY_NP; WB_EA; ISB; WB_EA; } /* 7 ISB ABY */
251
252OP(0c) { RD_ABS_DISCARD; NOP;                  } /* 4 NOP ABS */
253OP(2c) { int tmp; RD_ABS; BIT;                  } /* 4 BIT ABS */
254OP(4c) { EA_ABS; JMP;                           } /* 3 JMP ABS */
255OP(6c) { int tmp; EA_IND; JMP;                  } /* 5 JMP IND */
256OP(8c) { int tmp; STY; WR_ABS;                  } /* 4 STY ABS */
257OP(ac) { int tmp; RD_ABS; LDY;                  } /* 4 LDY ABS */
258OP(cc) { int tmp; RD_ABS; CPY;                  } /* 4 CPY ABS */
259OP(ec) { int tmp; RD_ABS; CPX;                  } /* 4 CPX ABS */
260
261OP(1c) { RD_ABX_P_DISCARD; NOP;                } /* 4 NOP ABX page penalty */
262OP(3c) { RD_ABX_P_DISCARD; NOP;                } /* 4 NOP ABX page penalty */
263OP(5c) { RD_ABX_P_DISCARD; NOP;                } /* 4 NOP ABX page penalty */
264OP(7c) { RD_ABX_P_DISCARD; NOP;                } /* 4 NOP ABX page penalty */
265OP(9c) { int tmp; EA_ABX_NP; SYH; WB_EA;        } /* 5 SYH ABX */
266OP(bc) { int tmp; RD_ABX_P; LDY;                } /* 4 LDY ABX page penalty */
267OP(dc) { RD_ABX_P_DISCARD; NOP;                } /* 4 NOP ABX page penalty */
268OP(fc) { RD_ABX_P_DISCARD; NOP;                } /* 4 NOP ABX page penalty */
269
270OP(0d) { int tmp; RD_ABS; ORA;                  } /* 4 ORA ABS */
271OP(2d) { int tmp; RD_ABS; AND;                  } /* 4 AND ABS */
272OP(4d) { int tmp; RD_ABS; EOR;                  } /* 4 EOR ABS */
273OP(6d) { int tmp; RD_ABS; ADC;                  } /* 4 ADC ABS */
274OP(8d) { int tmp; STA; WR_ABS;                  } /* 4 STA ABS */
275OP(ad) { int tmp; RD_ABS; LDA;                  } /* 4 LDA ABS */
276OP(cd) { int tmp; RD_ABS; CMP;                  } /* 4 CMP ABS */
277OP(ed) { int tmp; RD_ABS; SBC;                  } /* 4 SBC ABS */
278
279OP(1d) { int tmp; RD_ABX_P; ORA;                } /* 4 ORA ABX page penalty */
280OP(3d) { int tmp; RD_ABX_P; AND;                } /* 4 AND ABX page penalty */
281OP(5d) { int tmp; RD_ABX_P; EOR;                } /* 4 EOR ABX page penalty */
282OP(7d) { int tmp; RD_ABX_P; ADC;                } /* 4 ADC ABX page penalty */
283OP(9d) { int tmp; STA; WR_ABX_NP;               } /* 5 STA ABX */
284OP(bd) { int tmp; RD_ABX_P; LDA;                } /* 4 LDA ABX page penalty */
285OP(dd) { int tmp; RD_ABX_P; CMP;                } /* 4 CMP ABX page penalty */
286OP(fd) { int tmp; RD_ABX_P; SBC;                } /* 4 SBC ABX page penalty */
287
288OP(0e) { int tmp; RD_ABS; WB_EA; ASL; WB_EA;    } /* 6 ASL ABS */
289OP(2e) { int tmp; RD_ABS; WB_EA; ROL; WB_EA;    } /* 6 ROL ABS */
290OP(4e) { int tmp; RD_ABS; WB_EA; LSR; WB_EA;    } /* 6 LSR ABS */
291OP(6e) { int tmp; RD_ABS; WB_EA; ROR; WB_EA;    } /* 6 ROR ABS */
292OP(8e) { int tmp; STX; WR_ABS;                  } /* 4 STX ABS */
293OP(ae) { int tmp; RD_ABS; LDX;                  } /* 4 LDX ABS */
294OP(ce) { int tmp; RD_ABS; WB_EA; DEC; WB_EA;    } /* 6 DEC ABS */
295OP(ee) { int tmp; RD_ABS; WB_EA; INC; WB_EA;    } /* 6 INC ABS */
296
297OP(1e) { int tmp; RD_ABX_NP; WB_EA; ASL; WB_EA; } /* 7 ASL ABX */
298OP(3e) { int tmp; RD_ABX_NP; WB_EA; ROL; WB_EA; } /* 7 ROL ABX */
299OP(5e) { int tmp; RD_ABX_NP; WB_EA; LSR; WB_EA; } /* 7 LSR ABX */
300OP(7e) { int tmp; RD_ABX_NP; WB_EA; ROR; WB_EA; } /* 7 ROR ABX */
301OP(9e) { int tmp; EA_ABY_NP; SXH; WB_EA;   } /* 5 SXH ABY */
302OP(be) { int tmp; RD_ABY_P; LDX;      } /* 4 LDX ABY page penalty */
303OP(de) { int tmp; RD_ABX_NP; WB_EA; DEC; WB_EA; } /* 7 DEC ABX */
304OP(fe) { int tmp; RD_ABX_NP; WB_EA; INC; WB_EA; } /* 7 INC ABX */
305
306OP(0f) { int tmp; RD_ABS; WB_EA; SLO; WB_EA;    } /* 6 SLO ABS */
307OP(2f) { int tmp; RD_ABS; WB_EA; RLA; WB_EA;    } /* 6 RLA ABS */
308OP(4f) { int tmp; RD_ABS; WB_EA; SRE; WB_EA;    } /* 6 SRE ABS */
309OP(6f) { int tmp; RD_ABS; WB_EA; RRA; WB_EA;    } /* 6 RRA ABS */
310OP(8f) { int tmp; SAX; WR_ABS;                  } /* 4 SAX ABS */
311OP(af) { int tmp; RD_ABS; LAX;                  } /* 4 LAX ABS */
312OP(cf) { int tmp; RD_ABS; WB_EA; DCP; WB_EA;    } /* 6 DCP ABS */
313OP(ef) { int tmp; RD_ABS; WB_EA; ISB; WB_EA;    } /* 6 ISB ABS */
314
315OP(1f) { int tmp; RD_ABX_NP; WB_EA; SLO; WB_EA; } /* 7 SLO ABX */
316OP(3f) { int tmp; RD_ABX_NP; WB_EA; RLA; WB_EA; } /* 7 RLA ABX */
317OP(5f) { int tmp; RD_ABX_NP; WB_EA; SRE; WB_EA; } /* 7 SRE ABX */
318OP(7f) { int tmp; RD_ABX_NP; WB_EA; RRA; WB_EA; } /* 7 RRA ABX */
319OP(9f) { int tmp; EA_ABY_NP; SAH; WB_EA;        } /* 5 SAH ABY */
320OP(bf) { int tmp; RD_ABY_P; LAX;                } /* 4 LAX ABY page penalty */
321OP(df) { int tmp; RD_ABX_NP; WB_EA; DCP; WB_EA; } /* 7 DCP ABX */
322OP(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
326static 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
trunk/src/emu/cpu/m6502/minc4510.h
r18874r18875
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
trunk/src/emu/cpu/m6502/t65c02.c
r18874r18875
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   ********************/
41OP(00) { BRK_C02;                                   } /* 7 BRK */
42OP(20) { JSR;                                       } /* 6 JSR */
43OP(40) { RTI;                                       } /* 6 RTI */
44OP(60) { RTS;                                       } /* 6 RTS */
45OP(80) { int tmp; BRA_C02( 1 );                     } /* 3-4 BRA REL */
46OP(a0) { int tmp; RD_IMM; LDY;                      } /* 2 LDY IMM */
47OP(c0) { int tmp; RD_IMM; CPY;                      } /* 2 CPY IMM */
48OP(e0) { int tmp; RD_IMM; CPX;                      } /* 2 CPX IMM */
49
50OP(10) { int tmp; BRA_C02( ! ( P & F_N ) );         } /* 2-4 BPL REL */
51OP(30) { int tmp; BRA_C02(   ( P & F_N ) );         } /* 2-4 BMI REL */
52OP(50) { int tmp; BRA_C02( ! ( P & F_V ) );         } /* 2-4 BVC REL */
53OP(70) { int tmp; BRA_C02(   ( P & F_V ) );         } /* 2-4 BVS REL */
54OP(90) { int tmp; BRA_C02( ! ( P & F_C ) );         } /* 2-4 BCC REL */
55OP(b0) { int tmp; BRA_C02(   ( P & F_C ) );         } /* 2-4 BCS REL */
56OP(d0) { int tmp; BRA_C02( ! ( P & F_Z ) );         } /* 2-4 BNE REL */
57OP(f0) { int tmp; BRA_C02(   ( P & F_Z ) );         } /* 2-4 BEQ REL */
58
59OP(01) { int tmp; RD_IDX; ORA;                      } /* 6 ORA IDX */
60OP(21) { int tmp; RD_IDX; AND;                      } /* 6 AND IDX */
61OP(41) { int tmp; RD_IDX; EOR;                      } /* 6 EOR IDX */
62OP(61) { int tmp; RD_IDX; ADC_C02;                  } /* 6/7 ADC IDX */
63OP(81) { int tmp; STA; WR_IDX;                      } /* 6 STA IDX */
64OP(a1) { int tmp; RD_IDX; LDA;                      } /* 6 LDA IDX */
65OP(c1) { int tmp; RD_IDX; CMP;                      } /* 6 CMP IDX */
66OP(e1) { int tmp; RD_IDX; SBC_C02;                  } /* 6/7 SBC IDX */
67
68OP(11) { int tmp; RD_IDY_C02_P; ORA;                } /* 5 ORA IDY page penalty */
69OP(31) { int tmp; RD_IDY_C02_P; AND;                } /* 5 AND IDY page penalty */
70OP(51) { int tmp; RD_IDY_C02_P; EOR;                } /* 5 EOR IDY page penalty */
71OP(71) { int tmp; RD_IDY_C02_P; ADC_C02;            } /* 5/6 ADC IDY page penalty */
72OP(91) { int tmp; STA; WR_IDY_C02_NP;               } /* 6 STA IDY */
73OP(b1) { int tmp; RD_IDY_C02_P; LDA;                } /* 5 LDA IDY page penalty */
74OP(d1) { int tmp; RD_IDY_C02_P; CMP;                } /* 5 CMP IDY page penalty */
75OP(f1) { int tmp; RD_IDY_C02_P; SBC_C02;            } /* 5/6 SBC IDY page penalty */
76
77OP(02) { RD_IMM_DISCARD; NOP;                      } /* 2 NOP not sure for rockwell */
78OP(22) { RD_IMM_DISCARD; NOP;                      } /* 2 NOP not sure for rockwell */
79OP(42) { RD_IMM_DISCARD; NOP;                      } /* 2 NOP not sure for rockwell */
80OP(62) { RD_IMM_DISCARD; NOP;                      } /* 2 NOP not sure for rockwell */
81OP(82) { RD_IMM_DISCARD; NOP;                      } /* 2 NOP not sure for rockwell */
82OP(a2) { int tmp; RD_IMM; LDX;                      } /* 2 LDX IMM */
83OP(c2) { RD_IMM_DISCARD; NOP;                      } /* 2 NOP not sure for rockwell */
84OP(e2) { RD_IMM_DISCARD; NOP;                      } /* 2 NOP not sure for rockwell */
85
86OP(12) { int tmp; RD_ZPI; ORA;                      } /* 5 ORA ZPI */
87OP(32) { int tmp; RD_ZPI; AND;                      } /* 5 AND ZPI */
88OP(52) { int tmp; RD_ZPI; EOR;                      } /* 5 EOR ZPI */
89OP(72) { int tmp; RD_ZPI; ADC_C02;                  } /* 5/6 ADC ZPI */
90OP(92) { int tmp; STA; WR_ZPI;                      } /* 5 STA ZPI */
91OP(b2) { int tmp; RD_ZPI; LDA;                      } /* 5 LDA ZPI */
92OP(d2) { int tmp; RD_ZPI; CMP;                      } /* 5 CMP ZPI */
93OP(f2) { int tmp; RD_ZPI; SBC_C02;                  } /* 5/6 SBC ZPI */
94
95OP(03) { NOP;                                       } /* 1 NOP not sure for rockwell */
96OP(23) { NOP;                                       } /* 1 NOP not sure for rockwell */
97OP(43) { NOP;                                       } /* 1 NOP not sure for rockwell */
98OP(63) { NOP;                                       } /* 1 NOP not sure for rockwell */
99OP(83) { NOP;                                       } /* 1 NOP not sure for rockwell */
100OP(a3) { NOP;                                       } /* 1 NOP not sure for rockwell */
101OP(c3) { NOP;                                       } /* 1 NOP not sure for rockwell */
102OP(e3) { NOP;                                       } /* 1 NOP not sure for rockwell */
103
104OP(13) { NOP;                                       } /* 1 NOP not sure for rockwell */
105OP(33) { NOP;                                       } /* 1 NOP not sure for rockwell */
106OP(53) { NOP;                                       } /* 1 NOP not sure for rockwell */
107OP(73) { NOP;                                       } /* 1 NOP not sure for rockwell */
108OP(93) { NOP;                                       } /* 1 NOP not sure for rockwell */
109OP(b3) { NOP;                                       } /* 1 NOP not sure for rockwell */
110OP(d3) { NOP;                                       } /* 1 NOP not sure for rockwell */
111OP(f3) { NOP;                                       } /* 1 NOP not sure for rockwell */
112
113OP(04) { int tmp; RD_ZPG; RD_EA; TSB; WB_EA;        } /* 5 TSB ZPG */
114OP(24) { int tmp; RD_ZPG; BIT;                      } /* 3 BIT ZPG */
115OP(44) { RD_ZPG_DISCARD; NOP;                      } /* 3 NOP not sure for rockwell */
116OP(64) { int tmp; STZ; WR_ZPG;                      } /* 3 STZ ZPG */
117OP(84) { int tmp; STY; WR_ZPG;                      } /* 3 STY ZPG */
118OP(a4) { int tmp; RD_ZPG; LDY;                      } /* 3 LDY ZPG */
119OP(c4) { int tmp; RD_ZPG; CPY;                      } /* 3 CPY ZPG */
120OP(e4) { int tmp; RD_ZPG; CPX;                      } /* 3 CPX ZPG */
121
122OP(14) { int tmp; RD_ZPG; RD_EA; TRB; WB_EA;        } /* 5 TRB ZPG */
123OP(34) { int tmp; RD_ZPX; BIT;                      } /* 4 BIT ZPX */
124OP(54) { RD_ZPX_DISCARD; NOP;                      } /* 4 NOP not sure for rockwell */
125OP(74) { int tmp; STZ; WR_ZPX;                      } /* 4 STZ ZPX */
126OP(94) { int tmp; STY; WR_ZPX;                      } /* 4 STY ZPX */
127OP(b4) { int tmp; RD_ZPX; LDY;                      } /* 4 LDY ZPX */
128OP(d4) { RD_ZPX_DISCARD; NOP;                      } /* 4 NOP not sure for rockwell */
129OP(f4) { RD_ZPX_DISCARD; NOP;                      } /* 4 NOP not sure for rockwell */
130
131OP(05) { int tmp; RD_ZPG; ORA;                      } /* 3 ORA ZPG */
132OP(25) { int tmp; RD_ZPG; AND;                      } /* 3 AND ZPG */
133OP(45) { int tmp; RD_ZPG; EOR;                      } /* 3 EOR ZPG */
134OP(65) { int tmp; RD_ZPG; ADC_C02;                  } /* 3/4 ADC ZPG */
135OP(85) { int tmp; STA; WR_ZPG;                      } /* 3 STA ZPG */
136OP(a5) { int tmp; RD_ZPG; LDA;                      } /* 3 LDA ZPG */
137OP(c5) { int tmp; RD_ZPG; CMP;                      } /* 3 CMP ZPG */
138OP(e5) { int tmp; RD_ZPG; SBC_C02;                  } /* 3/4 SBC ZPG */
139
140OP(15) { int tmp; RD_ZPX; ORA;                      } /* 4 ORA ZPX */
141OP(35) { int tmp; RD_ZPX; AND;                      } /* 4 AND ZPX */
142OP(55) { int tmp; RD_ZPX; EOR;                      } /* 4 EOR ZPX */
143OP(75) { int tmp; RD_ZPX; ADC_C02;                  } /* 4/5 ADC ZPX */
144OP(95) { int tmp; STA; WR_ZPX;                      } /* 4 STA ZPX */
145OP(b5) { int tmp; RD_ZPX; LDA;                      } /* 4 LDA ZPX */
146OP(d5) { int tmp; RD_ZPX; CMP;                      } /* 4 CMP ZPX */
147OP(f5) { int tmp; RD_ZPX; SBC_C02;                  } /* 4/5 SBC ZPX */
148
149OP(06) { int tmp; RD_ZPG, RD_EA; ASL; WB_EA;        } /* 5 ASL ZPG */
150OP(26) { int tmp; RD_ZPG; RD_EA; ROL; WB_EA;        } /* 5 ROL ZPG */
151OP(46) { int tmp; RD_ZPG; RD_EA; LSR; WB_EA;        } /* 5 LSR ZPG */
152OP(66) { int tmp; RD_ZPG; RD_EA; ROR; WB_EA;        } /* 5 ROR ZPG */
153OP(86) { int tmp; STX; WR_ZPG;                      } /* 3 STX ZPG */
154OP(a6) { int tmp; RD_ZPG; LDX;                      } /* 3 LDX ZPG */
155OP(c6) { int tmp; RD_ZPG; RD_EA; DEC; WB_EA;        } /* 5 DEC ZPG */
156OP(e6) { int tmp; RD_ZPG; RD_EA; INC; WB_EA;        } /* 5 INC ZPG */
157
158OP(16) { int tmp; RD_ZPX; RD_EA; ASL; WB_EA;        } /* 6 ASL ZPX */
159OP(36) { int tmp; RD_ZPX; RD_EA; ROL; WB_EA;        } /* 6 ROL ZPX */
160OP(56) { int tmp; RD_ZPX; RD_EA; LSR; WB_EA;        } /* 6 LSR ZPX */
161OP(76) { int tmp; RD_ZPX; RD_EA; ROR; WB_EA;        } /* 6 ROR ZPX */
162OP(96) { int tmp; STX; WR_ZPY;                      } /* 4 STX ZPY */
163OP(b6) { int tmp; RD_ZPY; LDX;                      } /* 4 LDX ZPY */
164OP(d6) { int tmp; RD_ZPX; RD_EA; DEC; WB_EA;        } /* 6 DEC ZPX */
165OP(f6) { int tmp; RD_ZPX; RD_EA; INC; WB_EA;        } /* 6 INC ZPX */
166
167OP(07) { int tmp; RD_ZPG; RD_EA; RMB(0);WB_EA;      } /* 5 RMB0 ZPG */
168OP(27) { int tmp; RD_ZPG; RD_EA; RMB(2);WB_EA;      } /* 5 RMB2 ZPG */
169OP(47) { int tmp; RD_ZPG; RD_EA; RMB(4);WB_EA;      } /* 5 RMB4 ZPG */
170OP(67) { int tmp; RD_ZPG; RD_EA; RMB(6);WB_EA;      } /* 5 RMB6 ZPG */
171OP(87) { int tmp; RD_ZPG; RD_EA; SMB(0);WB_EA;      } /* 5 SMB0 ZPG */
172OP(a7) { int tmp; RD_ZPG; RD_EA; SMB(2);WB_EA;      } /* 5 SMB2 ZPG */
173OP(c7) { int tmp; RD_ZPG; RD_EA; SMB(4);WB_EA;      } /* 5 SMB4 ZPG */
174OP(e7) { int tmp; RD_ZPG; RD_EA; SMB(6);WB_EA;      } /* 5 SMB6 ZPG */
175
176OP(17) { int tmp; RD_ZPG; RD_EA; RMB(1);WB_EA;      } /* 5 RMB1 ZPG */
177OP(37) { int tmp; RD_ZPG; RD_EA; RMB(3);WB_EA;      } /* 5 RMB3 ZPG */
178OP(57) { int tmp; RD_ZPG; RD_EA; RMB(5);WB_EA;      } /* 5 RMB5 ZPG */
179OP(77) { int tmp; RD_ZPG; RD_EA; RMB(7);WB_EA;      } /* 5 RMB7 ZPG */
180OP(97) { int tmp; RD_ZPG; RD_EA; SMB(1);WB_EA;      } /* 5 SMB1 ZPG */
181OP(b7) { int tmp; RD_ZPG; RD_EA; SMB(3);WB_EA;      } /* 5 SMB3 ZPG */
182OP(d7) { int tmp; RD_ZPG; RD_EA; SMB(5);WB_EA;      } /* 5 SMB5 ZPG */
183OP(f7) { int tmp; RD_ZPG; RD_EA; SMB(7);WB_EA;      } /* 5 SMB7 ZPG */
184
185OP(08) { RD_DUM; PHP;                               } /* 3 PHP */
186OP(28) { RD_DUM; PLP;                               } /* 4 PLP */
187OP(48) { RD_DUM; PHA;                               } /* 3 PHA */
188OP(68) { RD_DUM; PLA;                               } /* 4 PLA */
189OP(88) { RD_DUM; DEY;                               } /* 2 DEY */
190OP(a8) { RD_DUM; TAY;                               } /* 2 TAY */
191OP(c8) { RD_DUM; INY;                               } /* 2 INY */
192OP(e8) { RD_DUM; INX;                               } /* 2 INX */
193
194OP(18) { RD_DUM; CLC;                               } /* 2 CLC */
195OP(38) { RD_DUM; SEC;                               } /* 2 SEC */
196OP(58) { RD_DUM; CLI;                               } /* 2 CLI */
197OP(78) { RD_DUM; SEI;                               } /* 2 SEI */
198OP(98) { RD_DUM; TYA;                               } /* 2 TYA */
199OP(b8) { RD_DUM; CLV;                               } /* 2 CLV */
200OP(d8) { RD_DUM; CLD;                               } /* 2 CLD */
201OP(f8) { RD_DUM; SED;                               } /* 2 SED */
202
203OP(09) { int tmp; RD_IMM; ORA;                      } /* 2 ORA IMM */
204OP(29) { int tmp; RD_IMM; AND;                      } /* 2 AND IMM */
205OP(49) { int tmp; RD_IMM; EOR;                      } /* 2 EOR IMM */
206OP(69) { int tmp; RD_IMM; ADC_C02;                  } /* 2/3 ADC IMM */
207OP(89) { int tmp; RD_IMM; BIT_IMM_C02;              } /* 2 BIT IMM */
208OP(a9) { int tmp; RD_IMM; LDA;                      } /* 2 LDA IMM */
209OP(c9) { int tmp; RD_IMM; CMP;                      } /* 2 CMP IMM */
210OP(e9) { int tmp; RD_IMM; SBC_C02;                  } /* 2/3 SBC IMM */
211
212OP(19) { int tmp; RD_ABY_C02_P; ORA;                } /* 4 ORA ABY page penalty */
213OP(39) { int tmp; RD_ABY_C02_P; AND;                } /* 4 AND ABY page penalty */
214OP(59) { int tmp; RD_ABY_C02_P; EOR;                } /* 4 EOR ABY page penalty */
215OP(79) { int tmp; RD_ABY_C02_P; ADC_C02;            } /* 4/5 ADC ABY page penalty */
216OP(99) { int tmp; STA; WR_ABY_C02_NP;               } /* 5 STA ABY */
217OP(b9) { int tmp; RD_ABY_C02_P; LDA;                } /* 4 LDA ABY page penalty */
218OP(d9) { int tmp; RD_ABY_C02_P; CMP;                } /* 4 CMP ABY page penalty */
219OP(f9) { int tmp; RD_ABY_C02_P; SBC_C02;            } /* 4/5 SBC ABY page penalty */
220
221OP(0a) { int tmp; RD_DUM; RD_ACC; ASL; WB_ACC;      } /* 2 ASL A */
222OP(2a) { int tmp; RD_DUM; RD_ACC; ROL; WB_ACC;      } /* 2 ROL A */
223OP(4a) { int tmp; RD_DUM; RD_ACC; LSR; WB_ACC;      } /* 2 LSR A */
224OP(6a) { int tmp; RD_DUM; RD_ACC; ROR; WB_ACC;      } /* 2 ROR A */
225OP(8a) { RD_DUM; TXA;                               } /* 2 TXA */
226OP(aa) { RD_DUM; TAX;                               } /* 2 TAX */
227OP(ca) { RD_DUM; DEX;                               } /* 2 DEX */
228OP(ea) { RD_DUM; NOP;                               } /* 2 NOP */
229
230OP(1a) { RD_DUM;INA;                                } /* 2 INA */
231OP(3a) { RD_DUM;DEA;                                } /* 2 DEA */
232OP(5a) { RD_DUM;PHY;                                } /* 3 PHY */
233OP(7a) { RD_DUM;PLY;                                } /* 4 PLY */
234OP(9a) { RD_DUM; TXS;                               } /* 2 TXS */
235OP(ba) { RD_DUM; TSX;                               } /* 2 TSX */
236OP(da) { RD_DUM;PHX;                                } /* 3 PHX */
237OP(fa) { RD_DUM;PLX;                                } /* 4 PLX */
238
239OP(0b) { NOP;                                       } /* 1 NOP not sure for rockwell */
240OP(2b) { NOP;                                       } /* 1 NOP not sure for rockwell */
241OP(4b) { NOP;                                       } /* 1 NOP not sure for rockwell */
242OP(6b) { NOP;                                       } /* 1 NOP not sure for rockwell */
243OP(8b) { NOP;                                       } /* 1 NOP not sure for rockwell */
244OP(ab) { NOP;                                       } /* 1 NOP not sure for rockwell */
245OP(cb) { NOP;                                       } /* 1 NOP not sure for rockwell */
246OP(eb) { NOP;                                       } /* 1 NOP not sure for rockwell */
247
248OP(1b) { NOP;                                       } /* 1 NOP not sure for rockwell */
249OP(3b) { NOP;                                       } /* 1 NOP not sure for rockwell */
250OP(5b) { NOP;                                       } /* 1 NOP not sure for rockwell */
251OP(7b) { NOP;                                       } /* 1 NOP not sure for rockwell */
252OP(9b) { NOP;                                       } /* 1 NOP not sure for rockwell */
253OP(bb) { NOP;                                       } /* 1 NOP not sure for rockwell */
254OP(db) { NOP;                                       } /* 1 NOP not sure for rockwell */
255OP(fb) { NOP;                                       } /* 1 NOP not sure for rockwell */
256
257OP(0c) { int tmp; RD_ABS; RD_EA; TSB; WB_EA;        } /* 6 TSB ABS */
258OP(2c) { int tmp; RD_ABS; BIT;                      } /* 4 BIT ABS */
259OP(4c) { EA_ABS; JMP;                               } /* 3 JMP ABS */
260OP(6c) { int tmp; EA_IND_C02; JMP;                  } /* 6 JMP IND */
261OP(8c) { int tmp; STY; WR_ABS;                      } /* 4 STY ABS */
262OP(ac) { int tmp; RD_ABS; LDY;                      } /* 4 LDY ABS */
263OP(cc) { int tmp; RD_ABS; CPY;                      } /* 4 CPY ABS */
264OP(ec) { int tmp; RD_ABS; CPX;                      } /* 4 CPX ABS */
265
266OP(1c) { int tmp; RD_ABS; RD_EA; TRB; WB_EA;        } /* 6 TRB ABS */
267OP(3c) { int tmp; RD_ABX_C02_P; BIT;                } /* 4 BIT ABX page penalty */
268OP(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 */
269OP(7c) { int tmp; EA_IAX; JMP;                      } /* 6 JMP IAX page penalty */
270OP(9c) { int tmp; STZ; WR_ABS;                      } /* 4 STZ ABS */
271OP(bc) { int tmp; RD_ABX_C02_P; LDY;                } /* 4 LDY ABX page penalty */
272OP(dc) { RD_ABX_C02_NP_DISCARD; NOP;               } /* 4 NOP ABX not sure for rockwell. Page penalty not sure  */
273OP(fc) { RD_ABX_C02_NP_DISCARD; NOP;               } /* 4 NOP ABX not sure for rockwell. Page penalty not sure  */
274
275OP(0d) { int tmp; RD_ABS; ORA;                      } /* 4 ORA ABS */
276OP(2d) { int tmp; RD_ABS; AND;                      } /* 4 AND ABS */
277OP(4d) { int tmp; RD_ABS; EOR;                      } /* 4 EOR ABS */
278OP(6d) { int tmp; RD_ABS; ADC_C02;                  } /* 4/5 ADC ABS */
279OP(8d) { int tmp; STA; WR_ABS;                      } /* 4 STA ABS */
280OP(ad) { int tmp; RD_ABS; LDA;                      } /* 4 LDA ABS */
281OP(cd) { int tmp; RD_ABS; CMP;                      } /* 4 CMP ABS */
282OP(ed) { int tmp; RD_ABS; SBC_C02;                  } /* 4/5 SBC ABS */
283
284OP(1d) { int tmp; RD_ABX_C02_P; ORA;                } /* 4 ORA ABX page penalty */
285OP(3d) { int tmp; RD_ABX_C02_P; AND;                } /* 4 AND ABX page penalty */
286OP(5d) { int tmp; RD_ABX_C02_P; EOR;                } /* 4 EOR ABX page penalty */
287OP(7d) { int tmp; RD_ABX_C02_P; ADC_C02;            } /* 4/5 ADC ABX page penalty */
288OP(9d) { int tmp; STA; WR_ABX_C02_NP;               } /* 5 STA ABX */
289OP(bd) { int tmp; RD_ABX_C02_P; LDA;                } /* 4 LDA ABX page penalty */
290OP(dd) { int tmp; RD_ABX_C02_P; CMP;                } /* 4 CMP ABX page penalty */
291OP(fd) { int tmp; RD_ABX_C02_P; SBC_C02;            } /* 4/5 SBC ABX page penalty */
292
293OP(0e) { int tmp; RD_ABS; RD_EA; ASL; WB_EA;        } /* 6 ASL ABS */
294OP(2e) { int tmp; RD_ABS; RD_EA; ROL; WB_EA;        } /* 6 ROL ABS */
295OP(4e) { int tmp; RD_ABS; RD_EA; LSR; WB_EA;        } /* 6 LSR ABS */
296OP(6e) { int tmp; RD_ABS; RD_EA; ROR; WB_EA;        } /* 6 ROR ABS */
297OP(8e) { int tmp; STX; WR_ABS;                      } /* 4 STX ABS */
298OP(ae) { int tmp; RD_ABS; LDX;                      } /* 4 LDX ABS */
299OP(ce) { int tmp; RD_ABS; RD_EA; DEC; WB_EA;        } /* 6 DEC ABS */
300OP(ee) { int tmp; RD_ABS; RD_EA; INC; WB_EA;        } /* 6 INC ABS */
301
302OP(1e) { int tmp; RD_ABX_C02_NP; RD_EA; ASL; WB_EA; } /* 7 ASL ABX */
303OP(3e) { int tmp; RD_ABX_C02_NP; RD_EA; ROL; WB_EA; } /* 7 ROL ABX */
304OP(5e) { int tmp; RD_ABX_C02_NP; RD_EA; LSR; WB_EA; } /* 7 LSR ABX */
305OP(7e) { int tmp; RD_ABX_C02_NP; RD_EA; ROR; WB_EA; } /* 7 ROR ABX */
306OP(9e) { int tmp; STZ; WR_ABX_C02_NP;               } /* 5 STZ ABX */
307OP(be) { int tmp; RD_ABY_C02_P; LDX;                } /* 4 LDX ABY page penalty */
308OP(de) { int tmp; RD_ABX_C02_NP; RD_EA; DEC; WB_EA; } /* 7 DEC ABX */
309OP(fe) { int tmp; RD_ABX_C02_NP; RD_EA; INC; WB_EA; } /* 7 INC ABX */
310
311OP(0f) { int tmp; RD_ZPG; BBR(0);                   } /* 5-7 BBR0 ZPG */
312OP(2f) { int tmp; RD_ZPG; BBR(2);                   } /* 5-7 BBR2 ZPG */
313OP(4f) { int tmp; RD_ZPG; BBR(4);                   } /* 5-7 BBR4 ZPG */
314OP(6f) { int tmp; RD_ZPG; BBR(6);                   } /* 5-7 BBR6 ZPG */
315OP(8f) { int tmp; RD_ZPG; BBS(0);                   } /* 5-7 BBS0 ZPG */
316OP(af) { int tmp; RD_ZPG; BBS(2);                   } /* 5-7 BBS2 ZPG */
317OP(cf) { int tmp; RD_ZPG; BBS(4);                   } /* 5-7 BBS4 ZPG */
318OP(ef) { int tmp; RD_ZPG; BBS(6);                   } /* 5-7 BBS6 ZPG */
319
320OP(1f) { int tmp; RD_ZPG; BBR(1);                   } /* 5-7 BBR1 ZPG */
321OP(3f) { int tmp; RD_ZPG; BBR(3);                   } /* 5-7 BBR3 ZPG */
322OP(5f) { int tmp; RD_ZPG; BBR(5);                   } /* 5-7 BBR5 ZPG */
323OP(7f) { int tmp; RD_ZPG; BBR(7);                   } /* 5-7 BBR7 ZPG */
324OP(9f) { int tmp; RD_ZPG; BBS(1);                   } /* 5-7 BBS1 ZPG */
325OP(bf) { int tmp; RD_ZPG; BBS(3);                   } /* 5-7 BBS3 ZPG */
326OP(df) { int tmp; RD_ZPG; BBS(5);                   } /* 5-7 BBS5 ZPG */
327OP(ff) { int tmp; RD_ZPG; BBS(7);                   } /* 5-7 BBS7 ZPG */
328
329static 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
365OP(cb_wdc) { RD_DUM; RD_DUM;                            } /* 3 WAI, TODO: Implement HALT mode */
366OP(db_wdc) { RD_DUM; RD_DUM;                            } /* 3 STP, TODO: Implement STP mode */
367OP(1e_wdc) { int tmp; RD_ABX_P; RD_EA; ASL; WB_EA;      } /* 6 ASL ABX page penalty */
368OP(3e_wdc) { int tmp; RD_ABX_P; RD_EA; ROL; WB_EA;      } /* 6 ROL ABX page penalty */
369OP(5e_wdc) { int tmp; RD_ABX_P; RD_EA; LSR; WB_EA;      } /* 6 LSR ABX page penalty */
370OP(7e_wdc) { int tmp; RD_ABX_P; RD_EA; ROR; WB_EA;      } /* 6 ROR ABX page penalty */
371OP(de_wdc) { int tmp; RD_ABX_P; RD_EA; DEC; WB_EA;      } /* 6 DEC ABX page penalty */
372OP(fe_wdc) { int tmp; RD_ABX_P; RD_EA; INC; WB_EA;      } /* 6 INC ABX page penalty */
373
374static 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
trunk/src/emu/cpu/m6502/t65ce02.c
r18874r18875
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   ********************/
36OP(00) { BRK; } /* 7 BRK */
37OP(20) { JSR; } /* 5 JSR */
38OP(40) { int tmp; RTI; } /* 5 RTI */
39OP(60) { RTS; } /* 4 RTS */
40OP(80) { int tmp; BRA(1); } /* 2 BRA */
41OP(a0) { int tmp; RD_IMM; LDY; } /* 2 LDY IMM */
42OP(c0) { int tmp; RD_IMM; CPY; } /* 2 CPY IMM */
43OP(e0) { int tmp; RD_IMM; CPX; } /* 2 CPX IMM */
44
45OP(10) { int tmp; BRA( ! ( P & F_N ) ); } /* 2 BPL REL */
46OP(30) { int tmp; BRA(   ( P & F_N ) ); } /* 2 BMI REL */
47OP(50) { int tmp; BRA( ! ( P & F_V ) ); } /* 2 BVC REL */
48OP(70) { int tmp; BRA(   ( P & F_V ) ); } /* 2 BVS REL */
49OP(90) { int tmp; BRA( ! ( P & F_C ) ); } /* 2 BCC REL */
50OP(b0) { int tmp; BRA(   ( P & F_C ) ); } /* 2 BCS REL */
51OP(d0) { int tmp; BRA( ! ( P & F_Z ) ); } /* 2 BNE REL */
52OP(f0) { int tmp; BRA(   ( P & F_Z ) ); } /* 2 BEQ REL */
53
54OP(01) { int tmp; RD_IDX; ORA; } /* 5 ORA IDX */
55OP(21) { int tmp; RD_IDX; AND; } /* 5 AND IDX */
56OP(41) { int tmp; RD_IDX; EOR; } /* 5 EOR IDX */
57OP(61) { int tmp; RD_IDX; ADC; } /* 5 ADC IDX */
58OP(81) { int tmp; STA; WR_IDX; } /* 5 STA IDX */
59OP(a1) { int tmp; RD_IDX; LDA; } /* 5 LDA IDX */
60OP(c1) { int tmp; RD_IDX; CMP; } /* 5 CMP IDX */
61OP(e1) { int tmp; RD_IDX; SBC; } /* 5 SBC IDX */
62
63OP(11) { int tmp; RD_IDY; ORA; } /* 5 ORA IDY */
64OP(31) { int tmp; RD_IDY; AND; } /* 5 AND IDY */
65OP(51) { int tmp; RD_IDY; EOR; } /* 5 EOR IDY */
66OP(71) { int tmp; RD_IDY; ADC; } /* 5 ADC IDY */
67OP(91) { int tmp; STA; WR_IDY; } /* 5 STA IDY */
68OP(b1) { int tmp; RD_IDY; LDA; } /* 5 LDA IDY */
69OP(d1) { int tmp; RD_IDY; CMP; } /* 5 CMP IDY */
70OP(f1) { int tmp; RD_IDY; SBC; } /* 5 SBC IDY */
71
72OP(02) { RD_DUM; CLE; } /* 2 CLE */
73OP(22) { JSR_IND; } /* 7 JSR IND */
74OP(42) { RD_DUM; NEG; } /* 2 NEG */
75OP(62) { int tmp; RD_IMM; RTN; } /* 7 RTN IMM */
76OP(82) { RD_INSY_DISCARD; } /* 6 STA INSY */
77OP(a2) { int tmp; RD_IMM; LDX; } /* 2 LDX IMM */
78OP(c2) { int tmp; RD_IMM; CPZ; } /* 2 CPZ IMM */
79OP(e2) { int tmp; RD_INSY; LDA; } /* 6 LDA INSY */
80
81OP(12) { int tmp; RD_IDZ; ORA; } /* 5 ORA IDZ */
82OP(32) { int tmp; RD_IDZ; AND; } /* 5 AND IDZ */
83OP(52) { int tmp; RD_IDZ; EOR; } /* 5 EOR IDZ */
84OP(72) { int tmp; RD_IDZ; ADC; } /* 5 ADC IDZ */
85OP(92) { RD_IDZ_DISCARD; } /* 5 STA IDZ */
86OP(b2) { int tmp; RD_IDZ; LDA; } /* 5 LDA IDZ */
87OP(d2) { int tmp; RD_IDZ; CMP; } /* 5 CMP IDZ */
88OP(f2) { int tmp; RD_IDZ; SBC; } /* 5 SBC IDZ */
89
90OP(03) { RD_DUM; SEE; } /* 2 SEE */
91OP(23) { JSR_INDX; } /* 7 JSR INDX */
92OP(43) { int tmp; RD_DUM; RD_ACC; ASR_65CE02; WR_ACC; } /* 2 ASR A */
93OP(63) { BSR; } /* 5 BSR */
94OP(83) { BRA_WORD(1); } /* 3 BRA REL WORD */
95OP(a3) { int tmp; RD_IMM; LDZ; } /* 2 LDZ IMM */
96OP(c3) { PAIR tmp; RD_ZPG_WORD; DEW; WB_EA_WORD;  } /* 6 DEW ABS */
97OP(e3) { PAIR tmp; RD_ZPG_WORD; INW; WB_EA_WORD;  } /* 6 INW ABS */
98
99OP(13) { BRA_WORD( ! ( P & F_N ) ); } /* 3 BPL REL WORD */
100OP(33) { BRA_WORD(   ( P & F_N ) ); } /* 3 BMI REL WORD */
101OP(53) { BRA_WORD( ! ( P & F_V ) ); } /* 3 BVC REL WORD */
102OP(73) { BRA_WORD(   ( P & F_V ) ); } /* 3 BVS REL WORD */
103OP(93) { BRA_WORD( ! ( P & F_C ) ); } /* 3 BCC REL WORD */
104OP(b3) { BRA_WORD(   ( P & F_C ) ); } /* 3 BCS REL WORD */
105OP(d3) { BRA_WORD( ! ( P & F_Z ) ); } /* 3 BNE REL WORD */
106OP(f3) { BRA_WORD(   ( P & F_Z ) ); } /* 3 BEQ REL WORD */
107
108OP(04) { int tmp; RD_ZPG; TSB; WB_EA; } /* 4 TSB ZPG */
109OP(24) { int tmp; RD_ZPG; RD_DUM; BIT; } /* 4 BIT ZPG */
110OP(44) { int tmp; RD_ZPG; ASR_65CE02; WB_EA;  } /* 4 ASR ZPG */
111OP(64) { int tmp; STZ_65CE02; WR_ZPG; } /* 3 STZ ZPG */
112OP(84) { int tmp; STY; WR_ZPG; } /* 3 STY ZPG */
113OP(a4) { int tmp; RD_ZPG; LDY; } /* 3 LDY ZPG */
114OP(c4) { int tmp; RD_ZPG; CPY; } /* 3 CPY ZPG */
115OP(e4) { int tmp; RD_ZPG; CPX; } /* 3 CPX ZPG */
116
117OP(14) { int tmp; RD_ZPG; TRB; WB_EA; } /* 4 TRB ZPG */
118OP(34) { int tmp; RD_ZPX; RD_DUM; BIT; } /* 4 BIT ZPX */
119OP(54) { int tmp; RD_ZPX; ASR_65CE02; WB_EA;  } /* 4 ASR ZPX */
120OP(74) { int tmp; STZ_65CE02; WR_ZPX; } /* 3 STZ ZPX */
121OP(94) { int tmp; STY; WR_ZPX; } /* 3 STY ZPX */
122OP(b4) { int tmp; RD_ZPX; LDY; } /* 3 LDY ZPX */
123OP(d4) { int tmp; RD_ZPG; CPZ; } /* 3 CPZ ZPG */
124OP(f4) { PAIR tmp; RD_IMM_WORD; PUSH_WORD(tmp); } /* 5 PHW imm16 */
125
126OP(05) { int tmp; RD_ZPG; ORA; } /* 3 ORA ZPG */
127OP(25) { int tmp; RD_ZPG; AND; } /* 3 AND ZPG */
128OP(45) { int tmp; RD_ZPG; EOR; } /* 3 EOR ZPG */
129OP(65) { int tmp; RD_ZPG; ADC; } /* 3 ADC ZPG */
130OP(85) { int tmp; STA; WR_ZPG; } /* 3 STA ZPG */
131OP(a5) { int tmp; RD_ZPG; LDA; } /* 3 LDA ZPG */
132OP(c5) { int tmp; RD_ZPG; CMP; } /* 3 CMP ZPG */
133OP(e5) { int tmp; RD_ZPG; SBC; } /* 3 SBC ZPG */
134
135OP(15) { int tmp; RD_ZPX; ORA; } /* 3 ORA ZPX */
136OP(35) { int tmp; RD_ZPX; AND; } /* 3 AND ZPX */
137OP(55) { int tmp; RD_ZPX; EOR; } /* 3 EOR ZPX */
138OP(75) { int tmp; RD_ZPX; ADC; } /* 3 ADC ZPX */
139OP(95) { int tmp; STA; WR_ZPX; } /* 3 STA ZPX */
140OP(b5) { int tmp; RD_ZPX; LDA; } /* 3 LDA ZPX */
141OP(d5) { int tmp; RD_ZPX; CMP; } /* 3 CMP ZPX */
142OP(f5) { int tmp; RD_ZPX; SBC; } /* 3 SBC ZPX */
143
144OP(06) { int tmp; RD_ZPG; ASL; WB_EA; } /* 4 ASL ZPG */
145OP(26) { int tmp; RD_ZPG; ROL; WB_EA; } /* 4 ROL ZPG */
146OP(46) { int tmp; RD_ZPG; LSR; WB_EA; } /* 4 LSR ZPG */
147OP(66) { int tmp; RD_ZPG; ROR; WB_EA; } /* 4 ROR ZPG */
148OP(86) { int tmp; STX; WR_ZPG; } /* 3 STX ZPG */
149OP(a6) { int tmp; RD_ZPG; LDX; } /* 3 LDX ZPG */
150OP(c6) { int tmp; RD_ZPG; DEC; WB_EA; } /* 4 DEC ZPG */
151OP(e6) { int tmp; RD_ZPG; INC; WB_EA; } /* 4 INC ZPG */
152
153OP(16) { int tmp; RD_ZPX; ASL; WB_EA; } /* 4 ASL ZPX */
154OP(36) { int tmp; RD_ZPX; ROL; WB_EA; } /* 4 ROL ZPX */
155OP(56) { int tmp; RD_ZPX; LSR; WB_EA; } /* 4 LSR ZPX */
156OP(76) { int tmp; RD_ZPX; ROR; WB_EA; } /* 4 ROR ZPX */
157OP(96) { int tmp; STX; WR_ZPY; } /* 3 STX ZPY */
158OP(b6) { int tmp; RD_ZPY; LDX; } /* 3 LDX ZPY */
159OP(d6) { int tmp; RD_ZPX; DEC; WB_EA; } /* 4 DEC ZPX */
160OP(f6) { int tmp; RD_ZPX; INC; WB_EA; } /* 4 INC ZPX */
161
162OP(07) { int tmp; RD_ZPG; RMB(0); WB_EA; } /* 4 RMB0 ZPG */
163OP(27) { int tmp; RD_ZPG; RMB(2); WB_EA; } /* 4 RMB2 ZPG */
164OP(47) { int tmp; RD_ZPG; RMB(4); WB_EA; } /* 4 RMB4 ZPG */
165OP(67) { int tmp; RD_ZPG; RMB(6); WB_EA; } /* 4 RMB6 ZPG */
166OP(87) { int tmp; RD_ZPG; SMB(0); WB_EA; } /* 4 SMB0 ZPG */
167OP(a7) { int tmp; RD_ZPG; SMB(2); WB_EA; } /* 4 SMB2 ZPG */
168OP(c7) { int tmp; RD_ZPG; SMB(4); WB_EA; } /* 4 SMB4 ZPG */
169OP(e7) { int tmp; RD_ZPG; SMB(6); WB_EA; } /* 4 SMB6 ZPG */
170
171OP(17) { int tmp; RD_ZPG; RMB(1); WB_EA; } /* 4 RMB1 ZPG */
172OP(37) { int tmp; RD_ZPG; RMB(3); WB_EA; } /* 4 RMB3 ZPG */
173OP(57) { int tmp; RD_ZPG; RMB(5); WB_EA; } /* 4 RMB5 ZPG */
174OP(77) { int tmp; RD_ZPG; RMB(7); WB_EA; } /* 4 RMB7 ZPG */
175OP(97) { int tmp; RD_ZPG; SMB(1); WB_EA; } /* 4 SMB1 ZPG */
176OP(b7) { int tmp; RD_ZPG; SMB(3); WB_EA; } /* 4 SMB3 ZPG */
177OP(d7) { int tmp; RD_ZPG; SMB(5); WB_EA; } /* 4 SMB5 ZPG */
178OP(f7) { int tmp; RD_ZPG; SMB(7); WB_EA; } /* 4 SMB7 ZPG */
179
180OP(08) { RD_DUM; PHP; } /* 3 PHP */
181OP(28) { RD_DUM; PLP; } /* 3 PLP */
182OP(48) { RD_DUM; PHA; } /* 3 PHA */
183OP(68) { RD_DUM; PLA; } /* 3 PLA */
184OP(88) { DEY; } /* 1 DEY */
185OP(a8) { TAY; } /* 1 TAY */
186OP(c8) { INY; } /* 1 INY */
187OP(e8) { INX; } /* 1 INX */
188
189OP(18) { CLC; } /* 1 CLC */
190OP(38) { SEC; } /* 1 SEC */
191OP(58) { CLI; } /* 1 CLI */
192OP(78) { RD_DUM; SEI; } /* 2 SEI */
193OP(98) { TYA; } /* 1 TYA */
194OP(b8) { CLV; } /* 1 CLV */
195OP(d8) { CLD; } /* 1 CLD */
196OP(f8) { SED; } /* 1 SED */
197
198OP(09) { int tmp; RD_IMM; ORA; } /* 2 ORA IMM */
199OP(29) { int tmp; RD_IMM; AND; } /* 2 AND IMM */
200OP(49) { int tmp; RD_IMM; EOR; } /* 2 EOR IMM */
201OP(69) { int tmp; RD_IMM; ADC; } /* 2 ADC IMM */
202OP(89) { int tmp; RD_IMM; BIT; } /* 2 BIT IMM */
203OP(a9) { int tmp; RD_IMM; LDA; } /* 2 LDA IMM */
204OP(c9) { int tmp; RD_IMM; CMP; } /* 2 CMP IMM */
205OP(e9) { int tmp; RD_IMM; SBC; } /* 2 SBC IMM */
206
207OP(19) { int tmp; RD_ABY; ORA; } /* 4 ORA ABY */
208OP(39) { int tmp; RD_ABY; AND; } /* 4 AND ABY */
209OP(59) { int tmp; RD_ABY; EOR; } /* 4 EOR ABY */
210OP(79) { int tmp; RD_ABY; ADC; } /* 4 ADC ABY */
211OP(99) { int tmp; STA; WR_ABY; } /* 4 STA ABY */
212OP(b9) { int tmp; RD_ABY; LDA; } /* 4 LDA ABY */
213OP(d9) { int tmp; RD_ABY; CMP; } /* 4 CMP ABY */
214OP(f9) { int tmp; RD_ABY; SBC; } /* 4 SBC ABY */
215
216OP(0a) { int tmp; RD_ACC; ASL; WR_ACC; } /* 1 ASL A */
217OP(2a) { int tmp; RD_ACC; ROL; WR_ACC; } /* 1 ROL A */
218OP(4a) { int tmp; RD_ACC; LSR; WR_ACC; } /* 1 LSR A */
219OP(6a) { int tmp; RD_ACC; ROR; WR_ACC; } /* 1 ROR A */
220OP(8a) { TXA; } /* 1 TXA */
221OP(aa) { TAX; } /* 1 TAX */
222OP(ca) { DEX; } /* 1 DEX */
223OP(ea) { NOP; } /* 1 NOP */
224
225OP(1a) { INA; } /* 1 INA */
226OP(3a) { DEA; } /* 1 DEA */
227OP(5a) { RD_DUM; PHY; } /* 3 PHY */
228OP(7a) { RD_DUM; PLY; } /* 3 PLY */
229OP(9a) { TXS; } /* 1 TXS */
230OP(ba) { TSX; } /* 1 TSX */
231OP(da) { RD_DUM; PHX; } /* 3 PHX */
232OP(fa) { RD_DUM; PLX; } /* 3 PLX */
233
234OP(0b) { TSY; } /* 1 TSY */
235OP(2b) { TYS; } /* 1 TYS */
236OP(4b) { TAZ; } /* 1 TAZ */
237OP(6b) { TZA; } /* 1 TZA */
238OP(8b) { int tmp; STY; WR_ABX; } /* 4 STY ABX */
239OP(ab) { int tmp; RD_ABS; LDZ; } /* 4 LDZ ABS */
240OP(cb) { PAIR tmp; tmp.d = 0; RD_ABS_WORD; ASW; WB_EA_WORD;  } /* 7 ASW ABS */
241OP(eb) { PAIR tmp; RD_ABS_WORD; ROW; WB_EA_WORD;  } /* 6/7? roW ABS */
242
243OP(1b) { INZ; } /* 1 INZ */
244OP(3b) { DEZ; } /* 1 DEZ */
245OP(5b) { TAB; } /* 1 TAB */
246OP(7b) { TBA; } /* 1 TBA */
247OP(9b) { int tmp; STX; WR_ABY; } /* 4 STX ABY */
248OP(bb) { int tmp; RD_ABX; LDZ; } /* 4 LDZ ABX */
249OP(db) { RD_DUM; PHZ; } /* 3 PHZ */
250OP(fb) { RD_DUM; PLZ; } /* 3 PLZ */
251
252OP(0c) { int tmp; RD_ABS; TSB; WB_EA; } /* 5 TSB ABS */
253OP(2c) { int tmp; RD_ABS; RD_DUM; BIT; } /* 5 BIT ABS */
254OP(4c) { EA_ABS; JMP; } /* 3 JMP ABS */
255OP(6c) { int tmp; EA_IND; JMP; } /* 5 JMP IND */
256OP(8c) { int tmp; STY; WR_ABS; } /* 4 STY ABS */
257OP(ac) { int tmp; RD_ABS; LDY; } /* 4 LDY ABS */
258OP(cc) { int tmp; RD_ABS; CPY; } /* 4 CPY ABS */
259OP(ec) { int tmp; RD_ABS; CPX; } /* 4 CPX ABS */
260
261OP(1c) { int tmp; RD_ABS; TRB; WB_EA;  } /* 5 TRB ABS */
262OP(3c) { int tmp; RD_ABX; RD_DUM; BIT;        } /* 5 BIT ABX */
263#ifdef M4510
264OP(5c) {         MAP;        } /* 4? MAP */
265#else
266OP(5c) { int t1,t2,t3; AUG; } /* 4 AUGMENT/no operation */
267#endif
268OP(7c) { int tmp; EA_IAX; JMP; } /* 5 JMP IAX */
269OP(9c) { int tmp; STZ_65CE02; WR_ABS; } /* 4 STZ ABS */
270OP(bc) { int tmp; RD_ABX; LDY; } /* 4 LDY ABX */
271OP(dc) { int tmp; RD_ABS; CPZ; } /* 4 CPZ ABS */
272OP(fc) { PAIR tmp; RD_ABS_WORD; PUSH_WORD(tmp); } /* 7 PHW ab */
273
274OP(0d) { int tmp; RD_ABS; ORA; } /* 4 ORA ABS */
275OP(2d) { int tmp; RD_ABS; AND; } /* 4 AND ABS */
276OP(4d) { int tmp; RD_ABS; EOR; } /* 4 EOR ABS */
277OP(6d) { int tmp; RD_ABS; ADC; } /* 4 ADC ABS */
278OP(8d) { int tmp; STA; WR_ABS; } /* 4 STA ABS */
279OP(ad) { int tmp; RD_ABS; LDA; } /* 4 LDA ABS */
280OP(cd) { int tmp; RD_ABS; CMP; } /* 4 CMP ABS */
281OP(ed) { int tmp; RD_ABS; SBC; } /* 4 SBC ABS */
282
283OP(1d) { int tmp; RD_ABX; ORA; } /* 4 ORA ABX */
284OP(3d) { int tmp; RD_ABX; AND; } /* 4 AND ABX */
285OP(5d) { int tmp; RD_ABX; EOR; } /* 4 EOR ABX */
286OP(7d) { int tmp; RD_ABX; ADC; } /* 4 ADC ABX */
287OP(9d) { int tmp; STA; WR_ABX; } /* 4 STA ABX */
288OP(bd) { int tmp; RD_ABX; LDA; } /* 4 LDA ABX */
289OP(dd) { int tmp; RD_ABX; CMP; } /* 4 CMP ABX */
290OP(fd) { int tmp; RD_ABX; SBC; } /* 4 SBC ABX */
291
292OP(0e) { int tmp; RD_ABS; ASL; WB_EA; } /* 5 ASL ABS */
293OP(2e) { int tmp; RD_ABS; ROL; WB_EA; } /* 5 ROL ABS */
294OP(4e) { int tmp; RD_ABS; LSR; WB_EA; } /* 5 LSR ABS */
295OP(6e) { int tmp; RD_ABS; ROR; WB_EA; } /* 5 ROR ABS */
296OP(8e) { int tmp; STX; WR_ABS; } /* 4 STX ABS */
297OP(ae) { int tmp; RD_ABS; LDX; } /* 4 LDX ABS */
298OP(ce) { int tmp; RD_ABS; DEC; WB_EA; } /* 5 DEC ABS */
299OP(ee) { int tmp; RD_ABS; INC; WB_EA; } /* 5 INC ABS */
300
301OP(1e) { int tmp; RD_ABX; ASL; WB_EA; } /* 5 ASL ABX */
302OP(3e) { int tmp; RD_ABX; ROL; WB_EA; } /* 5 ROL ABX */
303OP(5e) { int tmp; RD_ABX; LSR; WB_EA; } /* 5 LSR ABX */
304OP(7e) { int tmp; RD_ABX; ROR; WB_EA; } /* 5 ROR ABX */
305OP(9e) { int tmp; STZ_65CE02; WR_ABX; } /* 4 STZ ABX */
306OP(be) { int tmp; RD_ABY; LDX; } /* 4 LDX ABY */
307OP(de) { int tmp; RD_ABX; DEC; WB_EA; } /* 5 DEC ABX */
308OP(fe) { int tmp; RD_ABX; INC; WB_EA; } /* 5 INC ABX */
309
310OP(0f) { int tmp; RD_ZPG; BBR(0); } /* 4 BBR0 ZPG */
311OP(2f) { int tmp; RD_ZPG; BBR(2); } /* 4 BBR2 ZPG */
312OP(4f) { int tmp; RD_ZPG; BBR(4); } /* 4 BBR4 ZPG */
313OP(6f) { int tmp; RD_ZPG; BBR(6); } /* 4 BBR6 ZPG */
314OP(8f) { int tmp; RD_ZPG; BBS(0); } /* 4 BBS0 ZPG */
315OP(af) { int tmp; RD_ZPG; BBS(2); } /* 4 BBS2 ZPG */
316OP(cf) { int tmp; RD_ZPG; BBS(4); } /* 4 BBS4 ZPG */
317OP(ef) { int tmp; RD_ZPG; BBS(6); } /* 4 BBS6 ZPG */
318
319OP(1f) { int tmp; RD_ZPG; BBR(1); } /* 4 BBR1 ZPG */
320OP(3f) { int tmp; RD_ZPG; BBR(3); } /* 4 BBR3 ZPG */
321OP(5f) { int tmp; RD_ZPG; BBR(5); } /* 4 BBR5 ZPG */
322OP(7f) { int tmp; RD_ZPG; BBR(7); } /* 4 BBR7 ZPG */
323OP(9f) { int tmp; RD_ZPG; BBS(1); } /* 4 BBS1 ZPG */
324OP(bf) { int tmp; RD_ZPG; BBS(3); } /* 4 BBS3 ZPG */
325OP(df) { int tmp; RD_ZPG; BBS(5); } /* 4 BBS5 ZPG */
326OP(ff) { int tmp; RD_ZPG; BBS(7); } /* 4 BBS7 ZPG */
327
328#ifdef M4510
329static 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
364static 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
trunk/src/emu/cpu/m6502/6502dasm.c
r18874r18875
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
37enum 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
63enum 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
97static 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
131struct op6502_info
132{
133   UINT8 opc;
134   UINT8 arg;
135};
136
137static 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
204static 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 */
272static 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
339static 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
407static 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
474static 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 *****************************************************************************/
545static 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
734CPU_DISASSEMBLE( m6502 )
735{
736   return internal_m6502_dasm(op6502, buffer, pc, oprom, opram);
737}
738
739CPU_DISASSEMBLE( m65sc02 )
740{
741   return internal_m6502_dasm(op65sc02, buffer, pc, oprom, opram);
742}
743
744CPU_DISASSEMBLE( m65c02 )
745{
746   return internal_m6502_dasm(op65c02, buffer, pc, oprom, opram);
747}
748
749CPU_DISASSEMBLE( m65ce02 )
750{
751   return internal_m6502_dasm(op65ce02, buffer, pc, oprom, opram);
752}
753
754CPU_DISASSEMBLE( m6510 )
755{
756   return internal_m6502_dasm(op6502, buffer, pc, oprom, opram);
757}
758
759CPU_DISASSEMBLE( deco16 )
760{
761   return internal_m6502_dasm(opdeco16, buffer, pc, oprom, opram);
762}
763
764CPU_DISASSEMBLE( m4510 )
765{
766   return internal_m6502_dasm(op4510, buffer, pc, oprom, opram);
767}
trunk/src/emu/cpu/m6502/tdeco16.c
r18874r18875
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   ********************/
29OP(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 */
33OP(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
65OP(02) { RD_DUM; ILL; }                         /* 2 ILL */
66OP(22) { RD_DUM; ILL; }                         /* 2 ILL */
67OP(42) { RD_DUM; ILL; }                         /* 2 ILL */
68OP(62) { RD_DUM; ILL; }                         /* 2 ILL */
69OP(82) { RD_DUM; ILL; }                         /* 2 ILL */
70#define deco16_a2 m6502_a2                        /* 2 LDX IMM */
71OP(c2) { RD_DUM; ILL; }                         /* 2 ILL */
72OP(e2) { RD_DUM; ILL; }                         /* 2 ILL */
73
74OP(12) { RD_DUM; ILL; }                           /* 2 ILL / 3 ora zpi ?? */
75OP(32) { RD_DUM; ILL; }                           /* 2 ILL / 3 and zpi ?? */
76OP(52) { RD_DUM; ILL; }                           /* 2 ILL / 3 eor zpi ?? */
77OP(72) { RD_DUM; ILL; }                           /* 2 ILL / 3 adc zpi ?? */
78OP(92) { RD_DUM; ILL; }                           /* 2 ILL / 3 sta zpi ?? */
79OP(b2) { RD_DUM; ILL; }                           /* 2 ILL / 3 lda zpi ?? */
80OP(d2) { RD_DUM; ILL; }                           /* 2 ILL / 3 cmp zpi ?? */
81OP(f2) { RD_DUM; ILL; }                           /* 2 ILL / 3 sbc zpi ?? */
82
83OP(03) { RD_DUM; ILL; }                         /* 2 ILL */
84OP(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}
93OP(43) { RD_DUM; ILL; }                         /* 2 ILL */
94OP(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}
103OP(83) { RD_DUM; ILL; }                         /* 2 ILL */
104OP(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}
113OP(c3) { RD_DUM; ILL; }                         /* 2 ILL */
114OP(e3) { RD_DUM; ILL; }                         /* 2 ILL */
115
116OP(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            } /*  */
124OP(33) { RD_DUM; ILL; }                         /* 2 ILL */
125OP(53) { RD_DUM; ILL; }                         /* 2 ILL */
126OP(73) { RD_DUM; ILL; }                         /* 2 ILL */
127OP(93) { RD_DUM; ILL; }                         /* 2 ILL */
128OP(b3) { RD_DUM; ILL; }                         /* 2 ILL */
129OP(d3) { RD_DUM; ILL; }                         /* 2 ILL */
130OP(f3) { RD_DUM; ILL; }                         /* 2 ILL */
131
132OP(04) { RD_DUM; ILL; }                           /* 2 ILL / 3 tsb zpg ?? */
133#define deco16_24 m6502_24                        /* 3 BIT ZPG */
134OP(44) { RD_DUM; ILL; }                         /* 2 ILL */
135OP(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
141OP(14) { RD_DUM; ILL; }                           /* 2 ILL / 3 trb zpg ?? */
142OP(34) { RD_DUM; ILL; }                           /* 2 ILL / 4 bit zpx ?? */
143OP(54) { RD_DUM; ILL; }                         /* 2 ILL */
144OP(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 */
147OP(d4) { RD_DUM; ILL; }                         /* 2 ILL */
148OP(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
186OP(07) { RD_DUM; ILL; }                           /* 2 ILL / 5 RMB0 ZPG ?? */
187OP(27) { RD_DUM; ILL; }                           /* 2 ILL / 5 RMB2 ZPG ?? */
188OP(47) { RD_DUM; ILL; }                           /* 2 ILL / 5 RMB4 ZPG ?? */
189OP(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} /*  */
198OP(87) { int tmp; cpustate->icount -= 1; RD_IMM;
199   logerror("%04x: OP87 %02x\n",PCW,tmp);
200
201} /*  */
202OP(a7) { RD_DUM; ILL; }                           /* 2 ILL / 5 SMB2 ZPG ?? */
203OP(c7) { RD_DUM; ILL; }                           /* 2 ILL / 5 SMB4 ZPG ?? */
204OP(e7) { RD_DUM; ILL; }                           /* 2 ILL / 5 SMB6 ZPG ?? */
205
206OP(17) { RD_DUM; ILL; }                           /* 2 ILL / 5 RMB1 ZPG ?? */
207OP(37) { RD_DUM; ILL; }                           /* 2 ILL / 5 RMB3 ZPG ?? */
208OP(57) { RD_DUM; ILL; }                           /* 2 ILL / 5 RMB5 ZPG ?? */
209OP(77) { RD_DUM; ILL; }                           /* 2 ILL / 5 RMB7 ZPG ?? */
210OP(97) { RD_DUM; ILL; }                           /* 2 ILL / 5 SMB1 ZPG ?? */
211OP(b7) { RD_DUM; ILL; }                           /* 2 ILL / 5 SMB3 ZPG ?? */
212OP(d7) { RD_DUM; ILL; }                           /* 2 ILL / 5 SMB5 ZPG ?? */
213OP(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
269OP(0b) { int tmp; cpustate->icount -= 1; RD_IMM;
270   logerror("%04x: OP0B %02x\n",PCW,tmp);
271
272            }
273OP(2b) { RD_DUM; ILL; }                         /* 2 ILL */
274OP(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            }
285OP(6b) { RD_DUM; ILL; }                         /* 2 ILL */
286OP(8b) { RD_DUM; ILL; }                         /* 2 ILL */
287OP(ab) { RD_DUM; ILL; }                         /* 2 ILL */
288OP(cb) { RD_DUM; ILL; }                         /* 2 ILL */
289OP(eb) { RD_DUM; ILL; }                         /* 2 ILL */
290
291OP(1b) { RD_DUM; ILL; }                         /* 2 ILL */
292OP(3b) { RD_DUM; ILL; }                         /* 2 ILL */
293OP(5b) { RD_DUM; ILL; }                         /* 2 ILL */
294OP(7b) { RD_DUM; ILL; }                         /* 2 ILL */
295OP(9b) { RD_DUM; ILL; }                         /* 2 ILL */
296OP(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}
305OP(db) { RD_DUM; ILL; }                         /* 2 ILL */
306OP(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 */
319OP(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 */
323OP(dc) { RD_DUM; ILL; }                         /* 2 ILL */
324OP(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
362OP(0f) { RD_DUM; ILL; }                           /* 2 ILL / 5 BBR0 ZPG ?? */
363OP(2f) { RD_DUM; ILL; }                           /* 2 ILL / 5 BBR2 ZPG ?? */
364OP(4f) { RD_DUM; ILL; }                           /* 2 ILL / 5 BBR4 ZPG ?? */
365OP(6f) { RD_DUM; ILL; }                           /* 2 ILL / 5 BBR6 ZPG ?? */
366OP(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} /*  */
374OP(af) { RD_DUM; ILL; }                           /* 2 ILL / 5 BBS2 ZPG ?? */
375OP(cf) { RD_DUM; ILL; }                           /* 2 ILL / 5 BBS4 ZPG ?? */
376OP(ef) { RD_DUM; ILL; }                           /* 2 ILL / 5 BBS6 ZPG ?? */
377
378OP(1f) { RD_DUM; ILL; }                           /* 2 ILL / 5 BBR1 ZPG ?? */
379OP(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}
388OP(5f) { RD_DUM; ILL; }                           /* 2 ILL / 5 BBR5 ZPG ?? */
389OP(7f) { RD_DUM; ILL; }                           /* 2 ILL / 5 BBR7 ZPG ?? */
390OP(9f) { RD_DUM; ILL; }                           /* 2 ILL / 5 BBS1 ZPG ?? */
391OP(bf) { RD_DUM; ILL; }                           /* 2 ILL / 5 BBS3 ZPG ?? */
392OP(df) { RD_DUM; ILL; }                           /* 2 ILL / 5 BBS5 ZPG ?? */
393OP(ff) { RD_DUM; ILL; }                           /* 2 ILL / 5 BBS7 ZPG ?? */
394
395static 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};
trunk/src/emu/cpu/m6502/t65sc02.c
r18874r18875
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   ********************/
44OP(63) { BSR;                                             } /* 5? BSR */
45
46static 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
trunk/src/emu/cpu/m6502/tn2a03.c
r18874r18875
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   **********/
44OP(61) { int tmp; RD_IDX; ADC_NES;     } /* 6 ADC IDX */
45OP(e1) { int tmp; RD_IDX; SBC_NES;     } /* 6 SBC IDX */
46OP(71) { int tmp; RD_IDY_P; ADC_NES;     } /* 5 ADC IDY page penalty */
47OP(f1) { int tmp; RD_IDY_P; SBC_NES;     } /* 5 SBC IDY page penalty */
48OP(63) { int tmp; RD_IDX; WB_EA; RRA_NES; WB_EA;   } /* 7 RRA IDX */
49OP(73) { int tmp; RD_IDY_NP; WB_EA; RRA_NES; WB_EA; } /* 7 RRA IDY */
50OP(e3) { int tmp; RD_IDX; WB_EA; ISB_NES; WB_EA;   } /* 7 ISB IDX */
51OP(f3) { int tmp; RD_IDY_NP; WB_EA; ISB_NES; WB_EA; } /* 7 ISB IDY */
52OP(65) { int tmp; RD_ZPG; ADC_NES;     } /* 3 ADC ZPG */
53OP(e5) { int tmp; RD_ZPG; SBC_NES;     } /* 3 SBC ZPG */
54OP(75) { int tmp; RD_ZPX; ADC_NES;     } /* 4 ADC ZPX */
55OP(f5) { int tmp; RD_ZPX; SBC_NES;     } /* 4 SBC ZPX */
56OP(67) { int tmp; RD_ZPG; WB_EA; RRA_NES; WB_EA;    } /* 5 RRA ZPG */
57OP(77) { int tmp; RD_ZPX; WB_EA; RRA_NES; WB_EA;    } /* 6 RRA ZPX */
58OP(e7) { int tmp; RD_ZPG; WB_EA; ISB_NES; WB_EA;    } /* 5 ISB ZPG */
59OP(f7) { int tmp; RD_ZPX; WB_EA; ISB_NES; WB_EA;    } /* 6 ISB ZPX */
60OP(69) { int tmp; RD_IMM; ADC_NES;     } /* 2 ADC IMM */
61OP(e9) { int tmp; RD_IMM; SBC_NES;     } /* 2 SBC IMM */
62OP(79) { int tmp; RD_ABY_P; ADC_NES;     } /* 4 ADC ABY page penalty */
63OP(f9) { int tmp; RD_ABY_P; SBC_NES;     } /* 4 SBC ABY page penalty */
64OP(6b) { int tmp; RD_IMM; ARR_NES; WB_ACC; } /* 2 ARR IMM */
65OP(7b) { int tmp; RD_ABY_NP; WB_EA; RRA_NES; WB_EA; } /* 7 RRA ABY */
66OP(ab) { int tmp; RD_IMM; OAL_NES;                  } /* 2 OAL IMM */
67OP(eb) { int tmp; RD_IMM; SBC_NES;        } /* 2 SBC IMM */
68OP(fb) { int tmp; RD_ABY_NP; WB_EA; ISB_NES; WB_EA; } /* 7 ISB ABY */
69OP(9c) { int tmp; EA_ABX_NP; SYH_NES; WB_EA;     } /* 5 SYH ABX */
70OP(6d) { int tmp; RD_ABS; ADC_NES;     } /* 4 ADC ABS */
71OP(ed) { int tmp; RD_ABS; SBC_NES;     } /* 4 SBC ABS */
72OP(7d) { int tmp; RD_ABX_P; ADC_NES;     } /* 4 ADC ABX page penalty */
73OP(fd) { int tmp; RD_ABX_P; SBC_NES;     } /* 4 SBC ABX page penalty */
74OP(9e) { int tmp; EA_ABY_NP; SXH_NES; WB_EA;    } /* 5 SXH ABY */
75OP(6f) { int tmp; RD_ABS; WB_EA; RRA_NES; WB_EA;    } /* 6 RRA ABS */
76OP(7f) { int tmp; RD_ABX_NP; WB_EA; RRA_NES; WB_EA; } /* 7 RRA ABX */
77OP(ef) { int tmp; RD_ABS; WB_EA; ISB_NES; WB_EA;    } /* 6 ISB ABS */
78OP(ff) { int tmp; RD_ABX_NP; WB_EA; ISB_NES; WB_EA; } /* 7 ISB ABX */
79
80
81static 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};
trunk/src/emu/cpu/m6502/ops09.h
r18874r18875
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))
trunk/src/emu/cpu/m6502/t6509.c
r18874r18875
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
29OP(00) {                  BRK;                 } /* 7 BRK */
30OP(20) {                  JSR;                 } /* 6 JSR */
31OP(40) {                  RTI;                 } /* 6 RTI */
32OP(60) {                  RTS;                 } /* 6 RTS */
33OP(80) { RD_IMM_DISCARD; NOP;                 } /* 2 NOP IMM */
34OP(a0) { int tmp; RD_IMM; LDY;                 } /* 2 LDY IMM */
35OP(c0) { int tmp; RD_IMM; CPY;                 } /* 2 CPY IMM */
36OP(e0) { int tmp; RD_IMM; CPX;                 } /* 2 CPX IMM */
37
38OP(10) { int tmp; BPL;                         } /* 2-4 BPL REL */
39OP(30) { int tmp; BMI;                         } /* 2-4 BMI REL */
40OP(50) { int tmp; BVC;                         } /* 2-4 BVC REL */
41OP(70) { int tmp; BVS;                         } /* 2-4 BVS REL */
42OP(90) { int tmp; BCC;                         } /* 2-4 BCC REL */
43OP(b0) { int tmp; BCS;                         } /* 2-4 BCS REL */
44OP(d0) { int tmp; BNE;                         } /* 2-4 BNE REL */
45OP(f0) { int tmp; BEQ;                         } /* 2-4 BEQ REL */
46
47OP(01) { int tmp; RD_IDX; ORA;                 } /* 6 ORA IDX */
48OP(21) { int tmp; RD_IDX; AND;                 } /* 6 AND IDX */
49OP(41) { int tmp; RD_IDX; EOR;                 } /* 6 EOR IDX */
50OP(61) { int tmp; RD_IDX; ADC;                 } /* 6 ADC IDX */
51OP(81) { int tmp; STA; WR_IDX;                 } /* 6 STA IDX */
52OP(a1) { int tmp; RD_IDX; LDA;                 } /* 6 LDA IDX */
53OP(c1) { int tmp; RD_IDX; CMP;                 } /* 6 CMP IDX */
54OP(e1) { int tmp; RD_IDX; SBC;                 } /* 6 SBC IDX */
55
56OP(11) { int tmp; RD_IDY_P; ORA;               } /* 5 ORA IDY page penalty */
57OP(31) { int tmp; RD_IDY_P; AND;               } /* 5 AND IDY page penalty */
58OP(51) { int tmp; RD_IDY_P; EOR;               } /* 5 EOR IDY page penalty */
59OP(71) { int tmp; RD_IDY_P; ADC;               } /* 5 ADC IDY page penalty */
60OP(91) { int tmp; STA; WR_IDY_6509;              } /* 6 STA IDY */
61OP(b1) { int tmp; RD_IDY_6509; LDA;               } /* 5 LDA IDY page penalty */
62OP(d1) { int tmp; RD_IDY_P; CMP;               } /* 5 CMP IDY page penalty */
63OP(f1) { int tmp; RD_IDY_P; SBC;               } /* 5 SBC IDY page penalty */
64
65OP(02) {                  KIL;                 } /* 1 KIL */
66OP(22) {                  KIL;                 } /* 1 KIL */
67OP(42) {                  KIL;                 } /* 1 KIL */
68OP(62) {                  KIL;                 } /* 1 KIL */
69OP(82) { RD_IMM_DISCARD; NOP;                 } /* 2 NOP IMM */
70OP(a2) { int tmp; RD_IMM; LDX;                 } /* 2 LDX IMM */
71OP(c2) { RD_IMM_DISCARD; NOP;                 } /* 2 NOP IMM */
72OP(e2) { RD_IMM_DISCARD; NOP;                 } /* 2 NOP IMM */
73
74OP(12) { KIL;                                  } /* 1 KIL */
75OP(32) { KIL;                                  } /* 1 KIL */
76OP(52) { KIL;                                  } /* 1 KIL */
77OP(72) { KIL;                                  } /* 1 KIL */
78OP(92) { KIL;                                  } /* 1 KIL */
79OP(b2) { KIL;                                  } /* 1 KIL */
80OP(d2) { KIL;                                  } /* 1 KIL */
81OP(f2) { KIL;                                  } /* 1 KIL */
82
83OP(03) { int tmp; RD_IDX; WB_EA; SLO; WB_EA;   } /* 7 SLO IDX */
84OP(23) { int tmp; RD_IDX; WB_EA; RLA; WB_EA;   } /* 7 RLA IDX */
85OP(43) { int tmp; RD_IDX; WB_EA; SRE; WB_EA;   } /* 7 SRE IDX */
86OP(63) { int tmp; RD_IDX; WB_EA; RRA; WB_EA;   } /* 7 RRA IDX */
87OP(83) { int tmp;                SAX; WR_IDX;  } /* 6 SAX IDX */
88OP(a3) { int tmp; RD_IDX; LAX;                 } /* 6 LAX IDX */
89OP(c3) { int tmp; RD_IDX; WB_EA; DCP; WB_EA;   } /* 7 DCP IDX */
90OP(e3) { int tmp; RD_IDX; WB_EA; ISB; WB_EA;   } /* 7 ISB IDX */
91
92OP(13) { int tmp; RD_IDY_NP; WB_EA; SLO; WB_EA; } /* 7 SLO IDY */
93OP(33) { int tmp; RD_IDY_NP; WB_EA; RLA; WB_EA; } /* 7 RLA IDY */
94OP(53) { int tmp; RD_IDY_NP; WB_EA; SRE; WB_EA; } /* 7 SRE IDY */
95OP(73) { int tmp; RD_IDY_NP; WB_EA; RRA; WB_EA; } /* 7 RRA IDY */
96OP(93) { int tmp; EA_IDY_NP; SAH; WB_EA;        } /* 5 SAH IDY */
97OP(b3) { int tmp; RD_IDY_P; LAX;                } /* 5 LAX IDY page penalty */
98OP(d3) { int tmp; RD_IDY_NP; WB_EA; DCP; WB_EA; } /* 7 DCP IDY */
99OP(f3) { int tmp; RD_IDY_NP; WB_EA; ISB; WB_EA; } /* 7 ISB IDY */
100
101OP(04) { RD_ZPG_DISCARD; NOP;                  } /* 3 NOP ZPG */
102OP(24) { int tmp; RD_ZPG; BIT;                  } /* 3 BIT ZPG */
103OP(44) { RD_ZPG_DISCARD; NOP;                  } /* 3 NOP ZPG */
104OP(64) { RD_ZPG_DISCARD; NOP;                  } /* 3 NOP ZPG */
105OP(84) { int tmp; STY; WR_ZPG;                  } /* 3 STY ZPG */
106OP(a4) { int tmp; RD_ZPG; LDY;                  } /* 3 LDY ZPG */
107OP(c4) { int tmp; RD_ZPG; CPY;                  } /* 3 CPY ZPG */
108OP(e4) { int tmp; RD_ZPG; CPX;                  } /* 3 CPX ZPG */
109
110OP(14) { RD_ZPX_DISCARD; NOP;                  } /* 4 NOP ZPX */
111OP(34) { RD_ZPX_DISCARD; NOP;                  } /* 4 NOP ZPX */
112OP(54) { RD_ZPX_DISCARD; NOP;                  } /* 4 NOP ZPX */
113OP(74) { RD_ZPX_DISCARD; NOP;                  } /* 4 NOP ZPX */
114OP(94) { int tmp; STY; WR_ZPX;                  } /* 4 STY ZPX */
115OP(b4) { int tmp; RD_ZPX; LDY;                  } /* 4 LDY ZPX */
116OP(d4) { RD_ZPX_DISCARD; NOP;                  } /* 4 NOP ZPX */
117OP(f4) { RD_ZPX_DISCARD; NOP;                  } /* 4 NOP ZPX */
118
119OP(05) { int tmp; RD_ZPG; ORA;                  } /* 3 ORA ZPG */
120OP(25) { int tmp; RD_ZPG; AND;                  } /* 3 AND ZPG */
121OP(45) { int tmp; RD_ZPG; EOR;                  } /* 3 EOR ZPG */
122OP(65) { int tmp; RD_ZPG; ADC;                  } /* 3 ADC ZPG */
123OP(85) { int tmp; STA; WR_ZPG;                  } /* 3 STA ZPG */
124OP(a5) { int tmp; RD_ZPG; LDA;                  } /* 3 LDA ZPG */
125OP(c5) { int tmp; RD_ZPG; CMP;                  } /* 3 CMP ZPG */
126OP(e5) { int tmp; RD_ZPG; SBC;                  } /* 3 SBC ZPG */
127
128OP(15) { int tmp; RD_ZPX; ORA;                  } /* 4 ORA ZPX */
129OP(35) { int tmp; RD_ZPX; AND;                  } /* 4 AND ZPX */
130OP(55) { int tmp; RD_ZPX; EOR;                  } /* 4 EOR ZPX */
131OP(75) { int tmp; RD_ZPX; ADC;                  } /* 4 ADC ZPX */
132OP(95) { int tmp; STA; WR_ZPX;                  } /* 4 STA ZPX */
133OP(b5) { int tmp; RD_ZPX; LDA;                  } /* 4 LDA ZPX */
134OP(d5) { int tmp; RD_ZPX; CMP;                  } /* 4 CMP ZPX */
135OP(f5) { int tmp; RD_ZPX; SBC;                  } /* 4 SBC ZPX */
136
137OP(06) { int tmp; RD_ZPG; WB_EA; ASL; WB_EA;    } /* 5 ASL ZPG */
138OP(26) { int tmp; RD_ZPG; WB_EA; ROL; WB_EA;    } /* 5 ROL ZPG */
139OP(46) { int tmp; RD_ZPG; WB_EA; LSR; WB_EA;    } /* 5 LSR ZPG */
140OP(66) { int tmp; RD_ZPG; WB_EA; ROR; WB_EA;    } /* 5 ROR ZPG */
141OP(86) { int tmp; STX; WR_ZPG;                  } /* 3 STX ZPG */
142OP(a6) { int tmp; RD_ZPG; LDX;                  } /* 3 LDX ZPG */
143OP(c6) { int tmp; RD_ZPG; WB_EA; DEC; WB_EA;    } /* 5 DEC ZPG */
144OP(e6) { int tmp; RD_ZPG; WB_EA; INC; WB_EA;    } /* 5 INC ZPG */
145
146OP(16) { int tmp; RD_ZPX; WB_EA; ASL; WB_EA;    } /* 6 ASL ZPX */
147OP(36) { int tmp; RD_ZPX; WB_EA; ROL; WB_EA;    } /* 6 ROL ZPX */
148OP(56) { int tmp; RD_ZPX; WB_EA; LSR; WB_EA;    } /* 6 LSR ZPX */
149OP(76) { int tmp; RD_ZPX; WB_EA; ROR; WB_EA;    } /* 6 ROR ZPX */
150OP(96) { int tmp; STX; WR_ZPY;                  } /* 4 STX ZPY */
151OP(b6) { int tmp; RD_ZPY; LDX;                  } /* 4 LDX ZPY */
152OP(d6) { int tmp; RD_ZPX; WB_EA; DEC; WB_EA;    } /* 6 DEC ZPX */
153OP(f6) { int tmp; RD_ZPX; WB_EA; INC; WB_EA;    } /* 6 INC ZPX */
154
155OP(07) { int tmp; RD_ZPG; WB_EA; SLO; WB_EA;    } /* 5 SLO ZPG */
156OP(27) { int tmp; RD_ZPG; WB_EA; RLA; WB_EA;    } /* 5 RLA ZPG */
157OP(47) { int tmp; RD_ZPG; WB_EA; SRE; WB_EA;    } /* 5 SRE ZPG */
158OP(67) { int tmp; RD_ZPG; WB_EA; RRA; WB_EA;    } /* 5 RRA ZPG */
159OP(87) { int tmp; SAX; WR_ZPG;                  } /* 3 SAX ZPG */
160OP(a7) { int tmp; RD_ZPG; LAX;                  } /* 3 LAX ZPG */
161OP(c7) { int tmp; RD_ZPG; WB_EA; DCP; WB_EA;    } /* 5 DCP ZPG */
162OP(e7) { int tmp; RD_ZPG; WB_EA; ISB; WB_EA;    } /* 5 ISB ZPG */
163
164OP(17) { int tmp; RD_ZPX; WB_EA; SLO; WB_EA;    } /* 6 SLO ZPX */
165OP(37) { int tmp; RD_ZPX; WB_EA; RLA; WB_EA;    } /* 6 RLA ZPX */
166OP(57) { int tmp; RD_ZPX; WB_EA; SRE; WB_EA;    } /* 6 SRE ZPX */
167OP(77) { int tmp; RD_ZPX; WB_EA; RRA; WB_EA;    } /* 6 RRA ZPX */
168OP(97) { int tmp; SAX; WR_ZPY;                  } /* 4 SAX ZPY */
169OP(b7) { int tmp; RD_ZPY; LAX;                  } /* 4 LAX ZPY */
170OP(d7) { int tmp; RD_ZPX; WB_EA; DCP; WB_EA;    } /* 6 DCP ZPX */
171OP(f7) { int tmp; RD_ZPX; WB_EA; ISB; WB_EA;    } /* 6 ISB ZPX */
172
173OP(08) { RD_DUM; PHP;                           } /* 3 PHP */
174OP(28) { RD_DUM; PLP;                           } /* 4 PLP */
175OP(48) { RD_DUM; PHA;                           } /* 3 PHA */
176OP(68) { RD_DUM; PLA;                           } /* 4 PLA */
177OP(88) { RD_DUM; DEY;                           } /* 2 DEY */
178OP(a8) { RD_DUM; TAY;                           } /* 2 TAY */
179OP(c8) { RD_DUM; INY;                           } /* 2 INY */
180OP(e8) { RD_DUM; INX;                           } /* 2 INX */
181
182OP(18) { RD_DUM; CLC;                           } /* 2 CLC */
183OP(38) { RD_DUM; SEC;                           } /* 2 SEC */
184OP(58) { RD_DUM; CLI;                           } /* 2 CLI */
185OP(78) { RD_DUM; SEI;                           } /* 2 SEI */
186OP(98) { RD_DUM; TYA;                           } /* 2 TYA */
187OP(b8) { RD_DUM; CLV;                           } /* 2 CLV */
188OP(d8) { RD_DUM; CLD;                           } /* 2 CLD */
189OP(f8) { RD_DUM; SED;                           } /* 2 SED */
190
191OP(09) { int tmp; RD_IMM; ORA;                  } /* 2 ORA IMM */
192OP(29) { int tmp; RD_IMM; AND;                  } /* 2 AND IMM */
193OP(49) { int tmp; RD_IMM; EOR;                  } /* 2 EOR IMM */
194OP(69) { int tmp; RD_IMM; ADC;                  } /* 2 ADC IMM */
195OP(89) { RD_IMM_DISCARD; NOP;                  } /* 2 NOP IMM */
196OP(a9) { int tmp; RD_IMM; LDA;                  } /* 2 LDA IMM */
197OP(c9) { int tmp; RD_IMM; CMP;                  } /* 2 CMP IMM */
198OP(e9) { int tmp; RD_IMM; SBC;                  } /* 2 SBC IMM */
199
200OP(19) { int tmp; RD_ABY_P; ORA;                } /* 4 ORA ABY page penalty */
201OP(39) { int tmp; RD_ABY_P; AND;                } /* 4 AND ABY page penalty */
202OP(59) { int tmp; RD_ABY_P; EOR;                } /* 4 EOR ABY page penalty */
203OP(79) { int tmp; RD_ABY_P; ADC;                } /* 4 ADC ABY page penalty */
204OP(99) { int tmp; STA; WR_ABY_NP;               } /* 5 STA ABY */
205OP(b9) { int tmp; RD_ABY_P; LDA;                } /* 4 LDA ABY page penalty */
206OP(d9) { int tmp; RD_ABY_P; CMP;                } /* 4 CMP ABY page penalty */
207OP(f9) { int tmp; RD_ABY_P; SBC;                } /* 4 SBC ABY page penalty */
208
209OP(0a) { int tmp; RD_DUM; RD_ACC; ASL; WB_ACC;  } /* 2 ASL A */
210OP(2a) { int tmp; RD_DUM; RD_ACC; ROL; WB_ACC;  } /* 2 ROL A */
211OP(4a) { int tmp; RD_DUM; RD_ACC; LSR; WB_ACC;  } /* 2 LSR A */
212OP(6a) { int tmp; RD_DUM; RD_ACC; ROR; WB_ACC;  } /* 2 ROR A */
213OP(8a) { RD_DUM; TXA;                           } /* 2 TXA */
214OP(aa) { RD_DUM; TAX;                           } /* 2 TAX */
215OP(ca) { RD_DUM; DEX;                           } /* 2 DEX */
216OP(ea) { RD_DUM; NOP;                           } /* 2 NOP */
217
218OP(1a) { RD_DUM; NOP;                           } /* 2 NOP */
219OP(3a) { RD_DUM; NOP;                           } /* 2 NOP */
220OP(5a) { RD_DUM; NOP;                           } /* 2 NOP */
221OP(7a) { RD_DUM; NOP;                           } /* 2 NOP */
222OP(9a) { RD_DUM; TXS;                           } /* 2 TXS */
223OP(ba) { RD_DUM; TSX;                           } /* 2 TSX */
224OP(da) { RD_DUM; NOP;                           } /* 2 NOP */
225OP(fa) { RD_DUM; NOP;                           } /* 2 NOP */
226
227OP(0b) { int tmp; RD_IMM; ANC;                  } /* 2 ANC IMM */
228OP(2b) { int tmp; RD_IMM; ANC;                  } /* 2 ANC IMM */
229OP(4b) { int tmp; RD_IMM; ASR; WB_ACC;          } /* 2 ASR IMM */
230OP(6b) { int tmp; RD_IMM; ARR; WB_ACC;          } /* 2 ARR IMM */
231OP(8b) { int tmp; RD_IMM; AXA;                  } /* 2 AXA IMM */
232OP(ab) { int tmp; RD_IMM; OAL;                  } /* 2 OAL IMM */
233OP(cb) { int tmp; RD_IMM; ASX;                  } /* 2 ASX IMM */
234OP(eb) { int tmp; RD_IMM; SBC;                  } /* 2 SBC IMM */
235
236OP(1b) { int tmp; RD_ABY_NP; WB_EA; SLO; WB_EA; } /* 7 SLO ABY */
237OP(3b) { int tmp; RD_ABY_NP; WB_EA; RLA; WB_EA; } /* 7 RLA ABY */
238OP(5b) { int tmp; RD_ABY_NP; WB_EA; SRE; WB_EA; } /* 7 SRE ABY */
239OP(7b) { int tmp; RD_ABY_NP; WB_EA; RRA; WB_EA; } /* 7 RRA ABY */
240OP(9b) { int tmp; EA_ABY_NP; SSH; WB_EA;        } /* 5 SSH ABY */
241OP(bb) { int tmp; RD_ABY_P; AST;                } /* 4 AST ABY page penalty */
242OP(db) { int tmp; RD_ABY_NP; WB_EA; DCP; WB_EA; } /* 7 DCP ABY */
243OP(fb) { int tmp; RD_ABY_NP; WB_EA; ISB; WB_EA; } /* 7 ISB ABY */
244
245OP(0c) { RD_ABS_DISCARD; NOP;                  } /* 4 NOP ABS */
246OP(2c) { int tmp; RD_ABS; BIT;                  } /* 4 BIT ABS */
247OP(4c) { EA_ABS; JMP;                           } /* 3 JMP ABS */
248OP(6c) { int tmp; EA_IND; JMP;                  } /* 5 JMP IND */
249OP(8c) { int tmp; STY; WR_ABS;                  } /* 4 STY ABS */
250OP(ac) { int tmp; RD_ABS; LDY;                  } /* 4 LDY ABS */
251OP(cc) { int tmp; RD_ABS; CPY;                  } /* 4 CPY ABS */
252OP(ec) { int tmp; RD_ABS; CPX;                  } /* 4 CPX ABS */
253
254OP(1c) { RD_ABX_P_DISCARD; NOP;                } /* 4 NOP ABX page penalty */
255OP(3c) { RD_ABX_P_DISCARD; NOP;                } /* 4 NOP ABX page penalty */
256OP(5c) { RD_ABX_P_DISCARD; NOP;                } /* 4 NOP ABX page penalty */
257OP(7c) { RD_ABX_P_DISCARD; NOP;                } /* 4 NOP ABX page penalty */
258OP(9c) { int tmp; EA_ABX_NP; SYH; WB_EA;        } /* 5 SYH ABX */
259OP(bc) { int tmp; RD_ABX_P; LDY;                } /* 4 LDY ABX page penalty */
260OP(dc) { RD_ABX_P_DISCARD; NOP;                } /* 4 NOP ABX page penalty */
261OP(fc) { RD_ABX_P_DISCARD; NOP;                } /* 4 NOP ABX page penalty */
262
263OP(0d) { int tmp; RD_ABS; ORA;                  } /* 4 ORA ABS */
264OP(2d) { int tmp; RD_ABS; AND;                  } /* 4 AND ABS */
265OP(4d) { int tmp; RD_ABS; EOR;                  } /* 4 EOR ABS */
266OP(6d) { int tmp; RD_ABS; ADC;                  } /* 4 ADC ABS */
267OP(8d) { int tmp; STA; WR_ABS;                  } /* 4 STA ABS */
268OP(ad) { int tmp; RD_ABS; LDA;                  } /* 4 LDA ABS */
269OP(cd) { int tmp; RD_ABS; CMP;                  } /* 4 CMP ABS */
270OP(ed) { int tmp; RD_ABS; SBC;                  } /* 4 SBC ABS */
271
272OP(1d) { int tmp; RD_ABX_P; ORA;                } /* 4 ORA ABX page penalty */
273OP(3d) { int tmp; RD_ABX_P; AND;                } /* 4 AND ABX page penalty */
274OP(5d) { int tmp; RD_ABX_P; EOR;                } /* 4 EOR ABX page penalty */
275OP(7d) { int tmp; RD_ABX_P; ADC;                } /* 4 ADC ABX page penalty */
276OP(9d) { int tmp; STA; WR_ABX_NP;               } /* 5 STA ABX */
277OP(bd) { int tmp; RD_ABX_P; LDA;                } /* 4 LDA ABX page penalty */
278OP(dd) { int tmp; RD_ABX_P; CMP;                } /* 4 CMP ABX page penalty */
279OP(fd) { int tmp; RD_ABX_P; SBC;                } /* 4 SBC ABX page penalty */
280
281OP(0e) { int tmp; RD_ABS; WB_EA; ASL; WB_EA;    } /* 6 ASL ABS */
282OP(2e) { int tmp; RD_ABS; WB_EA; ROL; WB_EA;    } /* 6 ROL ABS */
283OP(4e) { int tmp; RD_ABS; WB_EA; LSR; WB_EA;    } /* 6 LSR ABS */
284OP(6e) { int tmp; RD_ABS; WB_EA; ROR; WB_EA;    } /* 6 ROR ABS */
285OP(8e) { int tmp; STX; WR_ABS;                  } /* 4 STX ABS */
286OP(ae) { int tmp; RD_ABS; LDX;                  } /* 4 LDX ABS */
287OP(ce) { int tmp; RD_ABS; WB_EA; DEC; WB_EA;    } /* 6 DEC ABS */
288OP(ee) { int tmp; RD_ABS; WB_EA; INC; WB_EA;    } /* 6 INC ABS */
289
290OP(1e) { int tmp; RD_ABX_NP; WB_EA; ASL; WB_EA; } /* 7 ASL ABX */
291OP(3e) { int tmp; RD_ABX_NP; WB_EA; ROL; WB_EA; } /* 7 ROL ABX */
292OP(5e) { int tmp; RD_ABX_NP; WB_EA; LSR; WB_EA; } /* 7 LSR ABX */
293OP(7e) { int tmp; RD_ABX_NP; WB_EA; ROR; WB_EA; } /* 7 ROR ABX */
294OP(9e) { int tmp; EA_ABY_NP; SXH; WB_EA;        } /* 5 SXH ABY */
295OP(be) { int tmp; RD_ABY_P; LDX;                } /* 4 LDX ABY page penalty */
296OP(de) { int tmp; RD_ABX_NP; WB_EA; DEC; WB_EA; } /* 7 DEC ABX */
297OP(fe) { int tmp; RD_ABX_NP; WB_EA; INC; WB_EA; } /* 7 INC ABX */
298
299OP(0f) { int tmp; RD_ABS; WB_EA; SLO; WB_EA;    } /* 6 SLO ABS */
300OP(2f) { int tmp; RD_ABS; WB_EA; RLA; WB_EA;    } /* 6 RLA ABS */
301OP(4f) { int tmp; RD_ABS; WB_EA; SRE; WB_EA;    } /* 6 SRE ABS */
302OP(6f) { int tmp; RD_ABS; WB_EA; RRA; WB_EA;    } /* 6 RRA ABS */
303OP(8f) { int tmp; SAX; WR_ABS;                  } /* 4 SAX ABS */
304OP(af) { int tmp; RD_ABS; LAX;                  } /* 4 LAX ABS */
305OP(cf) { int tmp; RD_ABS; WB_EA; DCP; WB_EA;    } /* 6 DCP ABS */
306OP(ef) { int tmp; RD_ABS; WB_EA; ISB; WB_EA;    } /* 6 ISB ABS */
307
308OP(1f) { int tmp; RD_ABX_NP; WB_EA; SLO; WB_EA; } /* 7 SLO ABX */
309OP(3f) { int tmp; RD_ABX_NP; WB_EA; RLA; WB_EA; } /* 7 RLA ABX */
310OP(5f) { int tmp; RD_ABX_NP; WB_EA; SRE; WB_EA; } /* 7 SRE ABX */
311OP(7f) { int tmp; RD_ABX_NP; WB_EA; RRA; WB_EA; } /* 7 RRA ABX */
312OP(9f) { int tmp; EA_ABY_NP; SAH; WB_EA;        } /* 5 SAH ABY */
313OP(bf) { int tmp; RD_ABY_P; LAX;                } /* 4 LAX ABY page penalty */
314OP(df) { int tmp; RD_ABX_NP; WB_EA; DCP; WB_EA; } /* 7 DCP ABX */
315OP(ff) { int tmp; RD_ABX_NP; WB_EA; ISB; WB_EA; } /* 7 ISB ABX */
316
317static 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
trunk/src/emu/cpu/m6502/m7501.h
r18874r18875
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
51class m7501_device : public m6510_device {
52public:
53   m7501_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
54};
55
56enum {
57   M7501_IRQ_LINE = m6502_device::IRQ_LINE,
58   M7501_NMI_LINE = m6502_device::NMI_LINE,
59};
60
61extern const device_type M7501;
62
63#endif
trunk/src/emu/cpu/m6502/om6509.lst
r18874r18875
1# 6509 opcodes
2
3lda_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
14sta_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();
trunk/src/emu/cpu/m6502/m65ce02.c
r18874r18875
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/***************************************************************************
292
30/*
3    m65ce02.c
314
32* neg is now simple 2er komplement negation with set of N and Z
5    6502 with Z register and some more stuff
336
34* phw push low order byte, push high order byte!
7****************************************************************************
358
36* tys txs not interruptable, not implemented
9    Copyright Olivier Galibert
10    All rights reserved.
3711
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:
3915
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.
4325
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.
4637
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***************************************************************************/
5339
54#define VERBOSE 0
40#include "emu.h"
41#include "m65ce02.h"
5542
56#define LOG(x)   do { if (VERBOSE) logerror x; } while (0)
43const device_type M65CE02 = &device_creator<m65ce02_device>;
5744
58struct   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
84INLINE m65ce02_Regs *get_safe_token(device_t *device)
45m65ce02_device::m65ce02_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
46   m65c02_device(mconfig, M65CE02, "M65CE02", tag, owner, clock)
8547{
86   assert(device != NULL);
87   assert(device->type() == M65CE02);
88   return (m65ce02_Regs *)downcast<legacy_cpu_device *>(device)->token();
8948}
9049
91/***************************************************************
92 * include the opcode macros, functions and tables
93 ***************************************************************/
94
95#include "t65ce02.c"
96
97static CPU_INIT( m65ce02 )
50m65ce02_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)
9852{
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   }
12053}
12154
122static CPU_RESET( m65ce02 )
55offs_t m65ce02_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
12356{
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);
14258}
14359
144static CPU_EXIT( m65ce02 )
60void m65ce02_device::init()
14561{
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;
14771}
14872
149INLINE void m65ce02_take_irq(m65ce02_Regs *cpustate)
73void m65ce02_device::device_start()
15074{
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();
16681}
16782
168static CPU_EXECUTE( m65ce02 )
83void m65ce02_device::device_reset()
16984{
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;
20688}
20789
208static void m65ce02_set_irq_line(m65ce02_Regs *cpustate, int irqline, int state)
90void m65ce02_device::state_import(const device_state_entry &entry)
20991{
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;
227100   }
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   }
237101}
238102
239/**************************************************************************
240 * Generic set_info
241 **************************************************************************/
242
243static CPU_SET_INFO( m65ce02 )
103void m65ce02_device::state_export(const device_state_entry &entry)
244104{
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   }
266105}
267106
268/**************************************************************************
269 * Generic get_info
270 **************************************************************************/
271
272CPU_GET_INFO( m65ce02 )
107void m65ce02_device::state_string_export(const device_state_entry &entry, astring &string)
273108{
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;
361124   }
362125}
363126
364DEFINE_LEGACY_CPU_DEVICE(M65CE02, m65ce02);
127#include "cpu/m6502/m65ce02.inc"
trunk/src/emu/cpu/m6502/m65c02.h
r18874r18875
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
46class m65c02_device : public m6502_device {
47public:
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
57protected:
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
97enum {
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
103extern const device_type M65C02;
104
105#endif
trunk/src/emu/cpu/m6502/n2a03.c
r18874r18875
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
43const device_type N2A03 = &device_creator<n2a03_device>;
44
45n2a03_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
50offs_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
55void 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
65UINT8 n2a03_device::mi_2a03_normal::read(UINT16 adr)
66{
67   return program->read_byte(adr);
68}
69
70UINT8 n2a03_device::mi_2a03_normal::read_direct(UINT16 adr)
71{
72   return direct->read_raw_byte(adr);
73}
74
75UINT8 n2a03_device::mi_2a03_normal::read_decrypted(UINT16 adr)
76{
77   return direct->read_decrypted_byte(adr);
78}
79
80void n2a03_device::mi_2a03_normal::write(UINT16 adr, UINT8 val)
81{
82   program->write_byte(adr, val);
83}
84
85UINT8 n2a03_device::mi_2a03_nd::read(UINT16 adr)
86{
87   return program->read_byte(adr);
88}
89
90UINT8 n2a03_device::mi_2a03_nd::read_direct(UINT16 adr)
91{
92   return program->read_byte(adr);
93}
94
95UINT8 n2a03_device::mi_2a03_nd::read_decrypted(UINT16 adr)
96{
97   return program->read_byte(adr);
98}
99
100void 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"
trunk/src/emu/cpu/m6502/m65ce02.h
r18874r18875
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/***************************************************************************
212
22#pragma once
3    m65ce02.h
234
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
2440#ifndef __M65CE02_H__
2541#define __M65CE02_H__
2642
27#include "m6502.h"
43#include "m65c02.h"
2844
29enum
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
45class m65ce02_device : public m65c02_device {
46public:
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
56protected:
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
34167};
35168
36#define M65CE02_IRQ_LINE            M6502_IRQ_LINE
169enum {
170   M65CE02_IRQ_LINE = m6502_device::IRQ_LINE,
171   M65CE02_NMI_LINE = m6502_device::NMI_LINE,
172};
37173
38DECLARE_LEGACY_CPU_DEVICE(M65CE02, m65ce02);
39174
40extern CPU_DISASSEMBLE( m65ce02 );
175enum {
176   M65CE02_Z = M6502_IR+1,
177   M65CE02_B
178};
41179
42#endif /* __M65CE02_H__ */
180extern const device_type M65CE02;
181
182#endif
trunk/src/emu/cpu/m6502/n2a03.h
r18874r18875
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
45class n2a03_device : public m6502_device {
46public:
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
55protected:
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
88enum {
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
94extern const device_type N2A03;
95
96#endif
trunk/src/emu/cpu/m6502/m6510t.c
r18874r18875
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
43const device_type M6510T = &device_creator<m6510t_device>;
44
45m6510t_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}
trunk/src/emu/cpu/m6502/dm6502.lst
r18874r18875
1# m6502_family_device - 6502, 6504
2brk_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
3bpl_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
4jsr_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
5bmi_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
6rti_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
7bvc_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
8rts_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
9bvs_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
10nop_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
11bcc_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
12ldy_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
13bcs_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
14cpy_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
15bne_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
16cpx_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
17beq_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
18reset
trunk/src/emu/cpu/m6502/m65sc02.c
r18874r18875
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
43const device_type M65SC02 = &device_creator<m65sc02_device>;
44
45m65sc02_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}
trunk/src/emu/cpu/m6502/m6510t.h
r18874r18875
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
51class m6510t_device : public m6510_device {
52public:
53   m6510t_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
54};
55
56enum {
57   M6510T_IRQ_LINE = m6502_device::IRQ_LINE,
58   M6510T_SET_OVERFLOW = m6502_device::V_LINE,
59};
60
61extern const device_type M6510T;
62
63#endif
trunk/src/emu/cpu/m6502/m65sc02.h
r18874r18875
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
45class m65sc02_device : public r65c02_device {
46public:
47   m65sc02_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
48};
49
50enum {
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
56extern const device_type M65SC02;
57
58#endif
trunk/src/emu/cpu/m6502/dm6509.lst
r18874r18875
1# m6509 - special banking on two specific instructions, and banking in general
2brk_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
3bpl_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
4jsr_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
5bmi_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
6rti_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
7bvc_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
8rts_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
9bvs_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
10nop_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
11bcc_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
12ldy_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
13bcs_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
14cpy_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
15bne_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
16cpx_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
17beq_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
18reset
trunk/src/emu/cpu/m6502/dr65c02.lst
r18874r18875
1# r65c02 - rockwell variant, with the bitwise instructions and stp/wai
2brk_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
3bpl_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
4jsr_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
5bmi_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
6rti_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
7bvc_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
8rts_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
9bvs_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
10bra_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
11bcc_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
12ldy_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
13bcs_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
14cpy_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
15bne_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
16cpx_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
17beq_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
18reset
trunk/src/emu/cpu/m6502/ddeco16.lst
r18874r18875
1# deco16 - deco variant
2brk_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
3bpl_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
4jsr_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
5bmi_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
6rti_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
7bvc_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
8rts_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
9bvs_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
10ill_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
11bcc_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
12ldy_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
13bcs_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
14cpy_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
15bne_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
16cpx_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
17beq_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
18reset
trunk/src/emu/cpu/m6502/om4510.lst
r18874r18875
1# 4510 opcodes
2
3eom_imp
4   inhibit_interrupts = false; // before or after prefetch?
5   prefetch();
6
7map_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();
trunk/src/emu/cpu/m6502/om6510.lst
r18874r18875
1# 6510 undocumented instructions in a C64 context
2anc_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
12ane_10_imm
13   TMP2 = read_pc();
14   A = (A | 0xee) & TMP2 & X;
15   set_nz(A);
16   prefetch();
17
18asr_10_imm
19   TMP2 = read_pc();
20   A = do_lsr(A & TMP2);
21   set_nz(A);
22   prefetch();
23
24arr_10_imm
25   TMP2 = read_pc();
26   A &= TMP2;
27   do_arr();
28   prefetch();
29
30las_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
42lxa_10_imm
43   TMP2 = read_pc();
44   A = X = (A | 0xee) & TMP2;
45   set_nz(A);
46   prefetch();
trunk/src/emu/cpu/m6502/m6502.c
r18874r18875
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/***************************************************************************
262
27#include "emu.h"
28#include "debugger.h"
29#include "m6502.h"
30#include "ops02.h"
31#include "ill02.h"
3    m6502.c
324
5    Mostek 6502, original NMOS variant
336
34#define M6502_NMI_VEC   0xfffa
35#define M6502_RST_VEC   0xfffc
36#define M6502_IRQ_VEC   0xfffe
7****************************************************************************
378
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.
4111
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:
4315
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.
4525
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.
4637
38***************************************************************************/
4739
48/****************************************************************************
49 * The 6502 registers.
50 ****************************************************************************/
51struct 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"
6943
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;
44const device_type M6502 = &device_creator<m6502_device>;
7745
78   devcb_resolved_read8 rdmem_id;               /* readmem callback for indexed instructions */
79   devcb_resolved_write8 wrmem_id;               /* writemem callback for indexed instructions */
46m6502_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}
8052
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
91INLINE m6502_Regs *get_safe_token(device_t *device)
53m6502_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)
9256{
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;
10558}
10659
107/***************************************************************
108 * include the opcode macros, functions and tables
109 ***************************************************************/
110#include "t6502.c"
60void m6502_device::device_start()
61{
62   if(direct_disabled)
63      mintf = new mi_default_nd;
64   else
65      mintf = new mi_default_normal;
11166
112#include "t6510.c"
67   init();
68}
11369
114#include "opsn2a03.h"
70void m6502_device::init()
71{
72   mintf->program = &space(AS_PROGRAM);
73   mintf->direct = &mintf->program->direct();
11574
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);
11786
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));
119104
120#include "t65c02.c"
105   m_icountptr = &icount;
121106
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}
123126
124#include "tdeco16.c"
127void 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}
125139
126/*****************************************************************************
127 *
128 *      6502 CPU interface functions
129 *
130 *****************************************************************************/
131140
132static void m6502_common_init(legacy_cpu_device *device, device_irq_acknowledge_callback irqcallback, UINT8 subtype, void (*const *insn)(m6502_Regs *cpustate), const char *type)
141UINT32 m6502_device::execute_min_cycles() const
133142{
134   m6502_Regs *cpustate = get_safe_token(device);
135   const m6502_interface *intf = (const m6502_interface *)device->static_config();
143   return 1;
144}
136145
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   }
146UINT32 m6502_device::execute_max_cycles() const
147{
148   return 10;
188149}
189150
190static CPU_INIT( m6502 )
151UINT32 m6502_device::execute_input_lines() const
191152{
192   m6502_common_init(device, irqcallback, SUBTYPE_6502, insn6502, "m6502");
153   return 3;
193154}
194155
195static CPU_RESET( m6502 )
156void m6502_device::do_adc_d(UINT8 val)
196157{
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}
202176
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;
177void 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;
209191}
210192
211static CPU_EXIT( m6502 )
193void m6502_device::do_adc(UINT8 val)
212194{
213   /* nothing to do yet */
195   if(P & F_D)
196      do_adc_d(val);
197   else
198      do_adc_nd(val);
214199}
215200
216INLINE void m6502_take_irq(m6502_Regs *cpustate)
201void m6502_device::do_arr_nd()
217202{
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;
233216}
234217
235static CPU_EXECUTE( m6502 )
218void m6502_device::do_arr_d()
236219{
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;
238232
239   do
240   {
241      UINT8 op;
242      PPC = PCD;
233   if((A & 0x0f) >= 0x05)
234      a = ((a + 6) & 0x0f) | (a & 0xf0);
243235
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;
282241}
283242
284static void m6502_set_irq_line(m6502_Regs *cpustate, int irqline, int state)
243void m6502_device::do_arr()
285244{
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();
304247   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();
325249}
326250
327
328
329/****************************************************************************
330 * 2A03 section
331 ****************************************************************************/
332
333static CPU_INIT( n2a03 )
251void m6502_device::do_cmp(UINT8 val1, UINT8 val2)
334252{
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;
336261}
337262
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. */
342void n2a03_irq(device_t *device)
263void m6502_device::do_sbc_d(UINT8 val)
343264{
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);
347283}
348284
349
350/****************************************************************************
351 * 6510 section
352 ****************************************************************************/
353
354static CPU_INIT( m6510 )
285void m6502_device::do_sbc_nd(UINT8 val)
355286{
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;
357298}
358299
359static CPU_RESET( m6510 )
300void m6502_device::do_sbc(UINT8 val)
360301{
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);
367306}
368307
369UINT8 m6510_get_port(legacy_cpu_device *device)
308void m6502_device::do_bit(UINT8 val)
370309{
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;
373318}
374319
375static READ8_HANDLER( m6510_read_0000 )
320UINT8 m6502_device::do_asl(UINT8 v)
376321{
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;
399331}
400332
401static WRITE8_HANDLER( m6510_write_0000 )
333UINT8 m6502_device::do_lsr(UINT8 v)
402334{
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;
426342}
427343
428static 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)
430ADDRESS_MAP_END
431
432
433
434/****************************************************************************
435 * 65C02 section
436 ****************************************************************************/
437
438static CPU_INIT( m65c02 )
344UINT8 m6502_device::do_ror(UINT8 v)
439345{
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;
441358}
442359
443static CPU_RESET( m65c02 )
360UINT8 m6502_device::do_rol(UINT8 v)
444361{
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;
449374}
450375
451INLINE void m65c02_take_irq(m6502_Regs *cpustate)
376UINT8 m6502_device::do_asr(UINT8 v)
452377{
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;
466387   }
467   cpustate->pending_irq = 0;
388   return v;
468389}
469390
470static CPU_EXECUTE( m65c02 )
391UINT64 m6502_device::get_cycle()
471392{
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;
509394}
510395
511static void m65c02_set_irq_line(m6502_Regs *cpustate, int irqline, int state)
396void m6502_device::execute_run()
512397{
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);
529408      }
409      do_exec_full();
530410   }
531   else
532      m6502_set_irq_line(cpustate, irqline,state);
411   end_cycles = 0;
533412}
534413
535/****************************************************************************
536 * 65SC02 section
537 ****************************************************************************/
538static CPU_INIT( m65sc02 )
414void m6502_device::execute_set_input(int inputnum, int state)
539415{
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   }
541425}
542426
543/****************************************************************************
544 * DECO16 section
545 ****************************************************************************/
546427
547static CPU_INIT( deco16 )
428const address_space_config *m6502_device::memory_space_config(address_spacenum spacenum) const
548429{
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;
552431}
553432
554433
555static CPU_RESET( deco16 )
434void m6502_device::state_import(const device_state_entry &entry)
556435{
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}
558443
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 */
444void m6502_device::state_export(const device_state_entry &entry)
445{
570446}
571447
572INLINE void deco16_take_irq(m6502_Regs *cpustate)
448void m6502_device::state_string_export(const device_state_entry &entry, astring &string)
573449{
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;
587461   }
588   cpustate->pending_irq = 0;
589462}
590463
591static void deco16_set_irq_line(m6502_Regs *cpustate, int irqline, int state)
464
465UINT32 m6502_device::disasm_min_opcode_bytes() const
592466{
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;
630468}
631469
632static CPU_EXECUTE( deco16 )
470UINT32 m6502_device::disasm_max_opcode_bytes() const
633471{
634   m6502_Regs *cpustate = get_safe_token(device);
472   return 4;
473}
635474
636   do
637   {
638      UINT8 op;
639      PPC = PCD;
475offs_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);
640482
641      debugger_instruction_hook(device, PCD);
483   switch(table[oprom[0]].mode) {
484   case DASM_non:
485      flags |= 1;
486      break;
642487
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;
645492
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;
649497
498   case DASM_aby:
499      sprintf(buffer, " $%02x%02x, y", opram[2], opram[1]);
500      flags |= 3;
501      break;
650502
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;
669507
670   } while (cpustate->icount > 0);
671}
508   case DASM_adr:
509      sprintf(buffer, " $%02x%02x", opram[2], opram[1]);
510      flags |= 3;
511      break;
672512
513   case DASM_bzp:
514      sprintf(buffer, "%d $%02x", oprom[0] & 7, opram[1]);
515      flags |= 2;
516      break;
673517
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;
677522
678static 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;
681527
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;
688532
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;
701537
538   case DASM_imm:
539      sprintf(buffer, " #$%02x", opram[1]);
540      flags |= 2;
541      break;
702542
543   case DASM_imp:
544      flags |= 1;
545      break;
703546
704/**************************************************************************
705 * Generic get_info
706 **************************************************************************/
547   case DASM_ind:
548      sprintf(buffer, " ($%02x%02x)", opram[2], opram[1]);
549      flags |= 3;
550      break;
707551
708CPU_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;
711556
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;
725561
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;
735566
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;
739571
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;
741576
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;
753581
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;
763586
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;
770591
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;
782596
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();
791605   }
606   return flags;
792607}
793608
794/**************************************************************************
795 * CPU-specific set_info
796 **************************************************************************/
797
798CPU_GET_INFO( m6504 )
609void m6502_device::prefetch()
799610{
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;
805615
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++;
808621}
809622
810/**************************************************************************
811 * CPU-specific set_info
812 **************************************************************************/
813
814CPU_GET_INFO( n2a03 )
623void m6502_device::prefetch_noirq()
815624{
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++;
826630}
827631
828
829/**************************************************************************
830 * CPU-specific set_info
831 **************************************************************************/
832
833static CPU_SET_INFO( m6510 )
632void m6502_device::set_nz(UINT8 v)
834633{
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;
839639}
840640
841CPU_GET_INFO( m6510 )
641offs_t m6502_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
842642{
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);
857644}
858645
859646
860/**************************************************************************
861 * CPU-specific set_info
862 **************************************************************************/
863
864CPU_GET_INFO( m6510t )
647UINT8 m6502_device::memory_interface::read_9(UINT16 adr)
865648{
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);
873650}
874651
875
876/**************************************************************************
877 * CPU-specific set_info
878 **************************************************************************/
879
880CPU_GET_INFO( m7501 )
652void m6502_device::memory_interface::write_9(UINT16 adr, UINT8 val)
881653{
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);
889655}
890656
891657
892/**************************************************************************
893 * CPU-specific set_info
894 **************************************************************************/
895
896CPU_GET_INFO( m8502 )
658UINT8 m6502_device::mi_default_normal::read(UINT16 adr)
897659{
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);
905661}
906662
907
908/**************************************************************************
909 * CPU-specific set_info
910 **************************************************************************/
911
912static CPU_SET_INFO( m65c02 )
663UINT8 m6502_device::mi_default_normal::read_direct(UINT16 adr)
913664{
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);
923666}
924667
925CPU_GET_INFO( m65c02 )
668UINT8 m6502_device::mi_default_normal::read_decrypted(UINT16 adr)
926669{
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);
941671}
942672
943
944/**************************************************************************
945 * CPU-specific set_info
946 **************************************************************************/
947
948CPU_GET_INFO( m65sc02 )
673void m6502_device::mi_default_normal::write(UINT16 adr, UINT8 val)
949674{
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);
965676}
966677
967
968/**************************************************************************
969 * CPU-specific set_info
970 **************************************************************************/
971
972static CPU_SET_INFO( deco16 )
678UINT8 m6502_device::mi_default_nd::read_direct(UINT16 adr)
973679{
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);
985681}
986682
987CPU_GET_INFO( deco16 )
683UINT8 m6502_device::mi_default_nd::read_decrypted(UINT16 adr)
988684{
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);
1011686}
1012687
1013DEFINE_LEGACY_CPU_DEVICE(M6502, m6502);
1014DEFINE_LEGACY_CPU_DEVICE(M6504, m6504);
1015DEFINE_LEGACY_CPU_DEVICE(M6510, m6510);
1016DEFINE_LEGACY_CPU_DEVICE(M6510T, m6510t);
1017DEFINE_LEGACY_CPU_DEVICE(M7501, m7501);
1018DEFINE_LEGACY_CPU_DEVICE(M8502, m8502);
1019DEFINE_LEGACY_CPU_DEVICE(N2A03, n2a03);
1020DEFINE_LEGACY_CPU_DEVICE(M65C02, m65c02);
1021DEFINE_LEGACY_CPU_DEVICE(M65SC02, m65sc02);
1022DEFINE_LEGACY_CPU_DEVICE(DECO16, deco16);
688#include "cpu/m6502/m6502.inc"
trunk/src/emu/cpu/m6502/m8502.c
r18874r18875
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
43const device_type M8502 = &device_creator<m8502_device>;
44
45m8502_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}
trunk/src/emu/cpu/m6502/m6504.c
r18874r18875
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
43const device_type M6504 = &device_creator<m6504_device>;
44
45m6504_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
51void 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
61UINT8 m6504_device::mi_6504_normal::read(UINT16 adr)
62{
63   return program->read_byte(adr & 0x1fff);
64}
65
66UINT8 m6504_device::mi_6504_normal::read_direct(UINT16 adr)
67{
68   return direct->read_raw_byte(adr & 0x1fff);
69}
70
71UINT8 m6504_device::mi_6504_normal::read_decrypted(UINT16 adr)
72{
73   return direct->read_decrypted_byte(adr & 0x1fff);
74}
75
76void m6504_device::mi_6504_normal::write(UINT16 adr, UINT8 val)
77{
78   program->write_byte(adr & 0x1fff, val);
79}
80
81UINT8 m6504_device::mi_6504_nd::read_direct(UINT16 adr)
82{
83   return read(adr);
84}
85
86UINT8 m6504_device::mi_6504_nd::read_decrypted(UINT16 adr)
87{
88   return read(adr);
89}
trunk/src/emu/cpu/m6502/m6502.h
r18874r18875
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/***************************************************************************
242
25#pragma once
3    m6502.h
264
27#ifndef __M6502_H__
28#define __M6502_H__
5    Mostek 6502, original NMOS variant
296
7****************************************************************************
308
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.
3311
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:
4015
41enum
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.
4725
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.
5337
38***************************************************************************/
5439
55/* Optional interface to set callbacks */
56#define M6510_INTERFACE(name) \
57   const m6502_interface (name) =
40#ifndef __M6502FAM_H__
41#define __M6502FAM_H__
5842
59struct 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();
6845
69DECLARE_LEGACY_CPU_DEVICE(M6502, m6502);
70DECLARE_LEGACY_CPU_DEVICE(M6504, m6504);
71extern CPU_DISASSEMBLE( m6502 );
46class m6502_device : public cpu_device {
47public:
48   enum {
49      IRQ_LINE, NMI_LINE, V_LINE
50   };
7251
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);
8654
87#define M6510_IRQ_LINE               M6502_IRQ_LINE
55   UINT64 get_cycle();
56   bool get_sync() const { return sync; }
8857
89DECLARE_LEGACY_CPU_DEVICE(M6510, m6510);
58protected:
59   class memory_interface {
60   public:
61      address_space *program;
62      direct_read_data *direct;
9063
91extern 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   };
9271
93UINT8 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   };
9479
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   };
10585
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   };
10792
108DECLARE_LEGACY_CPU_DEVICE(M6510T, m6510t);
93   enum {
94      STATE_RESET = 0x100,
95   };
10996
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   };
110123
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   };
121134
122#define M7501_IRQ_LINE               M6502_IRQ_LINE
135   virtual void init();
123136
124DECLARE_LEGACY_CPU_DEVICE(M7501, m7501);
137   // device-level overrides
138   virtual void device_start();
139   virtual void device_reset();
125140
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);
136147
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;
138150
139DECLARE_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);
140155
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);
141160
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;
155162
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 */
157174
158DECLARE_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;
159181
160#define N2A03_DEFAULTCLOCK (21477272.724 / 12)
182   static const disasm_entry disasm_entries[0x100];
161183
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. */
166extern 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);
167195
196   virtual void do_exec_full();
197   virtual void do_exec_partial();
168198
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); }
182203
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); }
184206
185DECLARE_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();
186213
187extern 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);
188224
225#define O(o) void o ## _full(); void o ## _partial()
189226
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);
203285
204#define M65SC02_IRQ_LINE            M6502_IRQ_LINE
286   //   exceptions
287   O(reset);
205288
206DECLARE_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);
207303
208extern 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);
209314
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);
223317
224#define DECO16_IRQ_LINE               M6502_IRQ_LINE
318   //   system killers
319   O(kil_non);
225320
226DECLARE_LEGACY_CPU_DEVICE(DECO16, deco16);
321#undef O
322};
227323
228extern CPU_DISASSEMBLE( deco16 );
324enum {
325   M6502_PC = 1,
326   M6502_A,
327   M6502_X,
328   M6502_Y,
329   M6502_P,
330   M6502_S,
331   M6502_IR
332};
229333
230#endif /* __M6502_H__ */
334enum {
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
340extern const device_type M6502;
341
342#endif
trunk/src/emu/cpu/m6502/m6504.h
r18874r18875
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
45class m6504_device : public m6502_device {
46public:
47   m6504_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
48
49protected:
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
68enum {
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
74extern const device_type M6504;
75
76#endif
trunk/src/emu/cpu/m6502/om65ce02.lst
r18874r18875
1# 65ce02 opcodes, a lot only remove dummy read/write cycles, some are new, some use the B register
2
3adc_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
12adc_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
22adc_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
32adc_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
43adc_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
53adc_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
63adc_ce_imm
64   TMP = read_pc();
65   do_adc(TMP);
66   if(P & F_D)
67      set_nz(A);
68   prefetch();
69
70adc_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
78adc_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
86and_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
94and_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
102and_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
112and_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
121and_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
130and_ce_zpg
131   TMP = read_pc();
132   A &= read(B|TMP);
133   set_nz(A);
134   prefetch();
135
136and_ce_zpx
137   TMP = read_pc();
138   A &= read(B|UINT8(TMP+X));
139   set_nz(A);
140   prefetch();
141
142asl_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
150asl_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
159asl_ce_acc
160   A = do_asl(A);
161   prefetch();
162
163asl_ce_zpg
164   TMP = B|read_pc();
165   TMP2 = read(TMP);
166   TMP2 = do_asl(TMP2);
167   write(TMP, TMP2);
168   prefetch();
169
170asl_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
178asr_acc
179   A = do_asr(A);
180   prefetch();
181
182asr_zpg
183   TMP = B|read_pc();
184   TMP2 = read(TMP);
185   TMP2 = do_asr(TMP2);
186   write(TMP, TMP2);
187   prefetch();
188
189asr_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
197asw_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
214aug_iw3
215   read_pc();
216   read_pc();
217   read_pc();
218   prefetch();
219
220bbr_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
229bbs_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
238bcc_ce_rel
239   TMP = read_pc();
240   if(!(P & F_C))
241      PC += INT8(TMP);
242   prefetch();
243
244bcc_rw2
245   TMP = read_pc();
246   TMP = set_h(TMP, read_pc());
247   if(!(P & F_C))
248      PC += TMP;
249   prefetch();
250
251bcs_ce_rel
252   TMP = read_pc();
253   if(P & F_C)
254      PC += INT8(TMP);
255   prefetch();
256
257bcs_rw2
258   TMP = read_pc();
259   TMP = set_h(TMP, read_pc());
260   if(P & F_C)
261      PC += TMP;
262   prefetch();
263
264beq_ce_rel
265   TMP = read_pc();
266   if(P & F_Z)
267      PC += INT8(TMP);
268   prefetch();
269
270beq_rw2
271   TMP = read_pc();
272   TMP = set_h(TMP, read_pc());
273   if(P & F_Z)
274      PC += TMP;
275   prefetch();
276
277bit_ce_abx
278   TMP = read_pc();
279   TMP = set_h(TMP, read_pc());
280   TMP += X;
281   do_bit(read(TMP));
282   prefetch();
283
284bit_ce_imm
285   TMP = read_pc();
286   do_bit(TMP);
287   prefetch();
288
289bit_ce_zpg
290   TMP = B|read_pc();
291   do_bit(read(TMP));
292   prefetch();
293
294bit_ce_zpx
295   TMP = read_pc();
296   TMP = read(B|UINT8(TMP+X));
297   do_bit(TMP);
298   prefetch();
299
300bmi_ce_rel
301   TMP = read_pc();
302   if(P & F_N)
303      PC += INT8(TMP);
304   prefetch();
305
306bmi_rw2
307   TMP = read_pc();
308   TMP = set_h(TMP, read_pc());
309   if(P & F_N)
310      PC += TMP;
311   prefetch();
312
313bne_ce_rel
314   TMP = read_pc();
315   if(!(P & F_Z))
316      PC += INT8(TMP);
317   prefetch();
318
319bne_rw2
320   TMP = read_pc();
321   TMP = set_h(TMP, read_pc());
322   if(!(P & F_Z))
323      PC += TMP;
324   prefetch();
325
326bpl_ce_rel
327   TMP = read_pc();
328   if(!(P & F_N))
329      PC += INT8(TMP);
330   prefetch();
331
332bpl_rw2
333   TMP = read_pc();
334   TMP = set_h(TMP, read_pc());
335   if(!(P & F_N))
336      PC += TMP;
337   prefetch();
338
339bra_ce_rel
340   TMP = read_pc();
341   PC += INT8(TMP);
342   prefetch();
343
344bra_rw2
345   TMP = read_pc();
346   TMP = set_h(TMP, read_pc());
347   PC += TMP;
348   prefetch();
349
350brk_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
375bsr_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
385bvc_ce_rel
386   TMP = read_pc();
387   if(!(P & F_V))
388      PC += INT8(TMP);
389   prefetch();
390
391bvc_rw2
392   TMP = read_pc();
393   TMP = set_h(TMP, read_pc());
394   if(!(P & F_V))
395      PC += TMP;
396   prefetch();
397
398bvs_ce_rel
399   TMP = read_pc();
400   if(P & F_V)
401      PC += INT8(TMP);
402   prefetch();
403
404bvs_rw2
405   TMP = read_pc();
406   TMP = set_h(TMP, read_pc());
407   if(P & F_V)
408      PC += TMP;
409   prefetch();
410
411clc_ce_imp
412   P &= ~F_C;
413   prefetch();
414
415cld_ce_imp
416   P &= ~F_D;
417   prefetch();
418
419cle_imp
420   read_pc_noinc();
421   P &= ~F_E;
422   prefetch();
423
424cli_ce_imp
425   prefetch();
426   P &= ~F_I; // Do *not* move it before the prefetch
427
428clv_ce_imp
429   P &= ~F_V;
430   prefetch();
431
432cmp_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
440cmp_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
448cmp_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
457cmp_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
465cmp_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
473cmp_ce_zpg
474   TMP = read_pc();
475   TMP = read(B|TMP);
476   do_cmp(A, TMP);
477   prefetch();
478
479cmp_ce_zpx
480   TMP = read_pc();
481   read(TMP);
482   TMP = read(B|UINT8(TMP+X));
483   do_cmp(A, TMP);
484   prefetch();
485
486cpx_ce_zpg
487   TMP = read_pc();
488   TMP = read(B|TMP);
489   do_cmp(X, TMP);
490   prefetch();
491
492cpy_ce_zpg
493   TMP = read_pc();
494   TMP = read(B|TMP);
495   do_cmp(Y, TMP);
496   prefetch();
497
498cpz_aba
499   TMP = read_pc();
500   TMP = set_h(TMP, read_pc());
501   TMP = read(TMP);
502   do_cmp(Z, TMP);
503   prefetch();
504
505cpz_imm
506   TMP = read_pc();
507   do_cmp(Z, TMP);
508   prefetch();
509
510cpz_zpg
511   TMP = read_pc();
512   TMP = read(B|TMP);
513   do_cmp(Z, TMP);
514   prefetch();
515
516dec_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
525dec_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
535dec_ce_acc
536   A--;
537   set_nz(A);
538   prefetch();
539
540dec_ce_zpg
541   TMP = B|read_pc();
542   TMP2 = read(TMP);
543   TMP2--;
544   set_nz(TMP2);
545   write(TMP, TMP2);
546   prefetch();
547
548dec_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
557dew_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
574dex_ce_imp
575   X--;
576   set_nz(X);
577   prefetch();
578
579dey_ce_imp
580   Y--;
581   set_nz(Y);
582   prefetch();
583
584dez_imp
585   Z--;
586   set_nz(Z);
587   prefetch();
588
589eor_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
597eor_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
605eor_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
615eor_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
624eor_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
633eor_ce_zpg
634   TMP = read_pc();
635   A ^= read(B|TMP);
636   set_nz(A);
637   prefetch();
638
639eor_ce_zpx
640   TMP = read_pc();
641   A ^= read(B|UINT8(TMP+X));
642   set_nz(A);
643   prefetch();
644
645inc_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
654inc_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
664inc_ce_acc
665   A++;
666   set_nz(A);
667   prefetch();
668
669inc_ce_zpg
670   TMP = B|read_pc();
671   TMP2 = read(TMP);
672   TMP2++;
673   set_nz(TMP2);
674   write(TMP, TMP2);
675   prefetch();
676
677inc_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
686inw_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
703inx_ce_imp
704   X++;
705   set_nz(X);
706   prefetch();
707
708iny_ce_imp
709   Y++;
710   set_nz(Y);
711   prefetch();
712
713inz_imp
714   Z++;
715   set_nz(Z);
716   prefetch();
717
718jmp_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
726jmp_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
733jsr_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
743jsr_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
755jsr_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
766lda_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
773lda_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
780lda_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
790lda_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
799lda_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
808lda_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
822lda_ce_zpg
823   TMP = read_pc();
824   A = read(B|TMP);
825   set_nz(A);
826   prefetch();
827
828lda_ce_zpx
829   TMP = read_pc();
830   A = read(B|UINT8(TMP+X));
831   set_nz(A);
832   prefetch();
833
834ldx_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
841ldx_ce_zpg
842   TMP = read_pc();
843   X = read(B|TMP);
844   set_nz(X);
845   prefetch();
846
847ldx_ce_zpy
848   TMP = read_pc();
849   X = read(B|UINT8(TMP+Y));
850   set_nz(X);
851   prefetch();
852
853ldy_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
861ldy_ce_zpg
862   TMP = read_pc();
863   Y = read(B|TMP);
864   set_nz(Y);
865   prefetch();
866
867ldy_ce_zpx
868   TMP = read_pc();
869   Y = read(B|UINT8(TMP+X));
870   set_nz(Y);
871   prefetch();
872
873ldz_aba
874   TMP = read_pc();
875   TMP = set_h(TMP, read_pc());
876   Z = read(TMP);
877   set_nz(Z);
878   prefetch();
879
880ldz_abx
881   TMP = read_pc();
882   TMP = set_h(TMP, read_pc());
883   Z = read(TMP + X);
884   set_nz(Z);
885   prefetch();
886
887ldz_imm
888   Z = read_pc();
889   set_nz(Z);
890   prefetch();
891
892lsr_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
900lsr_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
910lsr_ce_acc
911   A = do_lsr(A);
912   prefetch();
913
914lsr_ce_zpg
915   TMP = B|read_pc();
916   TMP2 = read(TMP);
917   TMP2 = do_lsr(TMP2);
918   write(TMP, TMP2);
919   prefetch();
920
921lsr_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
929neg_acc
930   read_pc_noinc();
931   A = -A;
932   set_nz(A);
933   prefetch();
934
935ora_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
943ora_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
951ora_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
961ora_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
970ora_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
979ora_ce_zpg
980   TMP = read_pc();
981   A |= read(B|TMP);
982   set_nz(A);
983   prefetch();
984
985ora_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
992pha_ce_imp
993   read_pc_noinc();
994   write(SP, A);
995   dec_SP_ce();
996   prefetch();
997
998php_ce_imp
999   read_pc_noinc();
1000   write(SP, P);
1001   dec_SP_ce();
1002   prefetch();
1003
1004phw_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
1015phw_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
1024phx_ce_imp
1025   read_pc_noinc();
1026   write(SP, X);
1027   dec_SP_ce();
1028   prefetch();
1029
1030phy_ce_imp
1031   read_pc_noinc();
1032   write(SP, Y);
1033   dec_SP_ce();
1034   prefetch();
1035
1036phz_imp
1037   read_pc_noinc();
1038   write(SP, Z);
1039   dec_SP_ce();
1040   prefetch();
1041
1042pla_ce_imp
1043   read_pc_noinc();
1044   inc_SP_ce();
1045   A = read(SP);
1046   set_nz(A);
1047   prefetch();
1048
1049plp_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
1056plx_ce_imp
1057   read_pc_noinc();
1058   inc_SP_ce();
1059   X = read(SP);
1060   set_nz(X);
1061   prefetch();
1062
1063ply_ce_imp
1064   read_pc_noinc();
1065   inc_SP_ce();
1066   Y = read(SP);
1067   set_nz(Y);
1068   prefetch();
1069
1070plz_imp
1071   read_pc_noinc();
1072   inc_SP_ce();
1073   Z = read(SP);
1074   set_nz(Z);
1075   prefetch();
1076
1077rmb_ce_bzp
1078   TMP = read_pc();
1079   TMP2 = read(TMP);
1080   TMP2 &= ~(1 << (inst_state & 7));
1081   write(TMP, TMP2);
1082   prefetch();
1083
1084rol_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
1092rol_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
1101rol_ce_acc
1102   A = do_rol(A);
1103   prefetch();
1104
1105rol_ce_zpg
1106   TMP = B|read_pc();
1107   TMP2 = read(TMP);
1108   TMP2 = do_rol(TMP2);
1109   write(TMP, TMP2);
1110   prefetch();
1111
1112rol_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
1120ror_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
1128ror_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
1137ror_ce_acc
1138   A = do_ror(A);
1139   prefetch();
1140
1141ror_ce_zpg
1142   TMP = B|read_pc();
1143   TMP2 = read(TMP);
1144   TMP2 = do_ror(TMP2);
1145   write(TMP, TMP2);
1146   prefetch();
1147
1148ror_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
1156row_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
1176rti_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
1186rtn_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
1201rts_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
1209sbc_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
1218sbc_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
1228sbc_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
1238sbc_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
1249sbc_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
1259sbc_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
1269sbc_ce_imm
1270   TMP = read_pc();
1271   do_sbc(TMP);
1272   if(P & F_D)
1273      set_nz(A);
1274   prefetch();
1275
1276sbc_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
1284sbc_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
1293sec_ce_imp
1294   P |= F_C;
1295   prefetch();
1296
1297sed_ce_imp
1298   P |= F_D;
1299   prefetch();
1300
1301see_imp
1302   read_pc_noinc();
1303   P |= F_E;
1304   prefetch();
1305
1306sei_ce_imp
1307   prefetch();
1308   P |= F_I; // Do *not* move it before the prefetch
1309
1310smb_ce_bzp
1311   TMP = read_pc();
1312   TMP2 = read(TMP);
1313   TMP2 |= 1 << (inst_state & 7);
1314   write(TMP, TMP2);
1315   prefetch();
1316
1317sta_ce_abx
1318   TMP = read_pc();
1319   TMP = set_h(TMP, read_pc());
1320   write(TMP+X, A);
1321   prefetch();
1322
1323sta_ce_aby
1324   TMP = read_pc();
1325   TMP = set_h(TMP, read_pc());
1326   write(TMP+Y, A);
1327   prefetch();
1328
1329sta_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
1338sta_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
1346sta_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
1354sta_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
1367sta_ce_zpg
1368   TMP = read_pc();
1369   write(B|TMP, A);
1370   prefetch();
1371
1372sta_ce_zpx
1373   TMP = read_pc();
1374   write(B|UINT8(TMP+X), A);
1375   prefetch();
1376
1377stx_aby
1378   TMP = read_pc();
1379   TMP = set_h(TMP, read_pc());
1380   write(TMP+Y, X);
1381   prefetch();
1382
1383stx_ce_zpg
1384   TMP = read_pc();
1385   write(B|TMP, X);
1386   prefetch();
1387
1388stx_ce_zpy
1389   TMP = read_pc();
1390   write(B|UINT8(TMP+Y), X);
1391   prefetch();
1392
1393sty_abx
1394   TMP = read_pc();
1395   TMP = set_h(TMP, read_pc());
1396   write(TMP+X, Y);
1397   prefetch();
1398
1399sty_ce_zpg
1400   TMP = read_pc();
1401   write(B|TMP, Y);
1402   prefetch();
1403
1404sty_ce_zpx
1405   TMP = read_pc();
1406   write(B|UINT8(TMP+X), Y);
1407   prefetch();
1408
1409stz_ce_aba
1410   TMP = read_pc();
1411   TMP = set_h(TMP, read_pc());
1412   write(TMP, A);
1413   prefetch();
1414
1415stz_ce_abx
1416   TMP = read_pc();
1417   TMP = set_h(TMP, read_pc());
1418   write(TMP+X, A);
1419   prefetch();
1420
1421stz_ce_zpg
1422   TMP = read_pc();
1423   write(B|TMP, Z);
1424   prefetch();
1425
1426stz_ce_zpx
1427   TMP = read_pc();
1428   write(B|UINT8(TMP+X), Z);
1429   prefetch();
1430
1431tab_imp
1432   B = A << 8;
1433   prefetch();
1434
1435tax_ce_imp
1436   X = A;
1437   set_nz(X);
1438   prefetch();
1439
1440tay_ce_imp
1441   Y = A;
1442   set_nz(Y);
1443   prefetch();
1444
1445taz_imp
1446   Z = A;
1447   set_nz(Z);
1448   prefetch();
1449
1450tba_imp
1451   A = B >> 8;
1452   set_nz(A);
1453   prefetch();
1454
1455trb_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
1467trb_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
1478tsb_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
1490tsb_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
1501tsx_ce_imp
1502   X = SP;
1503   set_nz(X);
1504   prefetch();
1505
1506tsy_imp
1507   Y = SP >> 8;
1508   set_nz(Y);
1509   prefetch();
1510
1511txa_ce_imp
1512   A = X;
1513   set_nz(A);
1514   prefetch();
1515
1516txs_ce_imp
1517   SP = set_l(SP, X);
1518   prefetch_noirq();
1519
1520tys_imp
1521   SP = set_h(SP, Y);
1522   prefetch();
1523
1524tya_ce_imp
1525   A = Y;
1526   set_nz(A);
1527   prefetch();
1528
1529tza_imp
1530   A = Z;
1531   set_nz(A);
1532   prefetch();
trunk/src/emu/cpu/m6502/m6509.c
r18874r18875
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/***************************************************************************
242
25The basic difference is the amount of RAM these machines have been supplied with. The B128 and the CBM *10
26models had 128k RAM, the others 256k. This implies some banking scheme, as the 6502 can only address 64k. And
27indeed those machines use a 6509, that can address 1 MByte of RAM. It has 2 registers at addresses 0 and 1. The
28indirect bank register at address 1 determines the bank (0-15) where the opcodes LDA (zp),Y and STA (zp),Y
29take the data from. The exec bank register at address 0 determines the bank where all other read and write
30addresses take place.
3    m6509.c
314
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
346
35 lda  (zp),y
36 sta  (zp),y
7****************************************************************************
378
38*/
9    Copyright Olivier Galibert
10    All rights reserved.
3911
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:
4315
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.
4725
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.
5437
55#define VERBOSE 0
38***************************************************************************/
5639
57#define LOG(x)   do { if (VERBOSE) logerror x; } while (0)
40#include "emu.h"
41#include "m6509.h"
5842
59struct 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;
43const device_type M6509 = &device_creator<m6509_device>;
8344
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
91INLINE m6509_Regs *get_safe_token(device_t *device)
45m6509_device::m6509_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
46   m6502_device(mconfig, M6509, "M6509", tag, owner, clock)
9247{
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;
9651}
9752
98/***************************************************************
99 * include the opcode macros, functions and tables
100 ***************************************************************/
101
102#include "t6509.c"
103
104static READ8_HANDLER( m6509_read_00000 )
53void m6509_device::device_start()
10554{
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);
10759
108   return cpustate->pc_bank.b.h2;
109}
60   init();
11061
111static 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);
11664}
11765
118static WRITE8_HANDLER( m6509_write_00000 )
66void m6509_device::device_reset()
11967{
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;
12470}
12571
126static WRITE8_HANDLER( m6509_write_00001 )
72offs_t m6509_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
12773{
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);
13175}
13276
133static 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)
136ADDRESS_MAP_END
13777
138static CPU_INIT( m6509 )
78m6509_device::mi_6509_normal::mi_6509_normal(m6509_device *_base)
13979{
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;
17381}
17482
175static CPU_RESET( m6509 )
83UINT8 m6509_device::mi_6509_normal::read(UINT16 adr)
17684{
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;
19591}
19692
197static CPU_EXIT( m6509 )
93UINT8 m6509_device::mi_6509_normal::read_direct(UINT16 adr)
19894{
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;
200101}
201102
202INLINE void m6509_take_irq(   m6509_Regs *cpustate)
103UINT8 m6509_device::mi_6509_normal::read_decrypted(UINT16 adr)
203104{
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;
221111}
222112
223static CPU_EXECUTE( m6509 )
113UINT8 m6509_device::mi_6509_normal::read_9(UINT16 adr)
224114{
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;
270121}
271122
272static void m6509_set_irq_line(m6509_Regs *cpustate, int irqline, int state)
123void m6509_device::mi_6509_normal::write(UINT16 adr, UINT8 val)
273124{
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);
313130}
314131
315/**************************************************************************
316 * Generic set_info
317 **************************************************************************/
318
319static CPU_SET_INFO( m6509 )
132void m6509_device::mi_6509_normal::write_9(UINT16 adr, UINT8 val)
320133{
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}
322140
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   }
141m6509_device::mi_6509_nd::mi_6509_nd(m6509_device *_base) : mi_6509_normal(_base)
142{
343143}
344144
345
346
347/**************************************************************************
348 * Generic get_info
349 **************************************************************************/
350
351CPU_GET_INFO( m6509 )
145UINT8 m6509_device::mi_6509_nd::read_direct(UINT16 adr)
352146{
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}
354154
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   }
155UINT8 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;
439163}
440164
441DEFINE_LEGACY_CPU_DEVICE(M6509, m6509);
165#include "cpu/m6502/m6509.inc"
trunk/src/emu/cpu/m6502/odeco16.lst
r18874r18875
1# deco 16 opcodes
2ill_non
3   logerror("%s: Unimplemented instruction %02x\n", tag(), inst_state);
4   prefetch();
5
6u0B_zpg
7   TMP2 = read_pc();
8   if(DECO16_VERBOSE)
9      logerror("%s: OP0B %02x (%04x)\n", tag(), NPC, TMP2);
10   prefetch();
11
12u13_zpg
13   TMP2 = read_pc();
14   if(DECO16_VERBOSE)
15      logerror("%s: OP13 %02x (%04x)\n", tag(), NPC, TMP2);
16   prefetch();
17
18u23_zpg
19   TMP2 = read_pc();
20   if(DECO16_VERBOSE)
21      logerror("%s: OP23 %02x (%04x)\n", tag(), NPC, TMP2);
22   prefetch();
23
24u3F_zpg
25   TMP2 = read_pc();
26   if(DECO16_VERBOSE)
27      logerror("%s: OPBB %02x (%04x)\n", tag(), NPC, TMP2);
28   prefetch();
29
30u4B_zpg
31   TMP2 = read_pc();
32   A = io->read_byte(1);
33   prefetch();
34
35u87_zpg
36   TMP2 = read_pc();
37   if(DECO16_VERBOSE)
38      logerror("%s: OP87 %02x (%04x)\n", tag(), NPC, TMP2);
39   prefetch();
40
41u8F_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
48uA3_zpg
49   TMP2 = read_pc();
50   if(DECO16_VERBOSE)
51      logerror("%s: OPA3 %02x (%04x)\n", tag(), NPC, TMP2);
52   prefetch();
53
54uBB_zpg
55   TMP2 = read_pc();
56   if(DECO16_VERBOSE)
57      logerror("%s: OPBB %02x (%04x)\n", tag(), NPC, TMP2);
58   prefetch();
59
60vbl_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();
trunk/src/emu/cpu/m6502/m8502.h
r18874r18875
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
51class m8502_device : public m6510_device {
52public:
53   m8502_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
54};
55
56enum {
57   M8502_IRQ_LINE = m6502_device::IRQ_LINE,
58   M8502_NMI_LINE = m6502_device::NMI_LINE,
59};
60
61extern const device_type M8502;
62
63#endif
trunk/src/emu/cpu/m6502/r65c02.c
r18874r18875
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
43const device_type R65C02 = &device_creator<r65c02_device>;
44
45r65c02_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
50r65c02_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
55offs_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"
trunk/src/emu/cpu/m6502/deco16.c
r18874r18875
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
45const device_type DECO16 = &device_creator<deco16_device>;
46
47deco16_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
53offs_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
59void 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
71const 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"
trunk/src/emu/cpu/m6502/on2a03.lst
r18874r18875
1# n2a03 opcodes - same as 6502 but with d disabled
2adc_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
9adc_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
20adc_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
31adc_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
40adc_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
50adc_nd_imm
51   TMP = read_pc();
52   do_adc_nd(TMP);
53   prefetch();
54
55adc_nd_zpg
56   TMP = read_pc();
57   TMP = read(TMP);
58   do_adc_nd(TMP);
59   prefetch();
60
61adc_nd_zpx
62   TMP = read_pc();
63   read(TMP);
64   TMP = read(UINT8(TMP+X));
65   do_adc_nd(TMP);
66   prefetch();
67
68arr_nd_imm
69   read_pc();
70   do_arr_nd();
71   prefetch();
72
73rra_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
83rra_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
95rra_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
107rra_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
120rra_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
133rra_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
142rra_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
153sbc_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
160sbc_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
171sbc_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
182sbc_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
191sbc_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
201sbc_nd_imm
202   TMP = read_pc();
203   do_sbc_nd(TMP);
204   prefetch();
205
206sbc_nd_zpg
207   TMP = read_pc();
208   TMP = read(TMP);
209   do_sbc_nd(TMP);
210   prefetch();
211
212sbc_nd_zpx
213   TMP = read_pc();
214   read(TMP);
215   TMP = read(UINT8(TMP+X));
216   do_sbc_nd(TMP);
217   prefetch();
218
219isb_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
229isb_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
241isb_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
253isb_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
266isb_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
279isb_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
288isb_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();
trunk/src/emu/cpu/m6502/m6509.h
r18874r18875
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/***************************************************************************
212
22#pragma once
3    m6509.h
234
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
2440#ifndef __M6509_H__
25#define _M6509_H
41#define __M6509_H__
2642
2743#include "m6502.h"
2844
29enum
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
45class m6509_device : public m6502_device {
46public:
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
55protected:
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
3496};
3597
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
98enum {
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};
41103
42DECLARE_LEGACY_CPU_DEVICE(M6509, m6509);
104enum {
105   M6509_BI = M6502_IR+1,
106   M6509_BY
107};
43108
44#endif /* __M6509_H__ */
109extern const device_type M6509;
110
111#endif
trunk/src/emu/cpu/m6502/deco16.h
r18874r18875
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
45class deco16_device : public m6502_device {
46public:
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
55protected:
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
80enum {
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
86extern const device_type DECO16;
87
88#endif
trunk/src/emu/cpu/m6502/r65c02.h
r18874r18875
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
45class r65c02_device : public m65c02_device {
46public:
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
57enum {
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
63extern const device_type R65C02;
64
65#endif
trunk/src/emu/cpu/m6502/dm4510.lst
r18874r18875
1# m4510 - 65ce02 with a mmu
2brk_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
3bpl_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
4jsr_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
5bmi_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
6rti_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
7bvc_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
8rts_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
9bvs_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
10bra_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
11bcc_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
12ldy_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
13bcs_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
14cpy_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
15bne_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
16cpx_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
17beq_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
18reset
trunk/src/emu/cpu/m6502/dm6510.lst
r18874r18875
1# m6510_family - identical to 6502, except for some undocumented instructions that have to be handled specifically
2brk_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
3bpl_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
4jsr_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
5bmi_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
6rti_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
7bvc_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
8rts_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
9bvs_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
10nop_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
11bcc_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
12ldy_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
13bcs_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
14cpy_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
15bne_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
16cpx_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
17beq_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
18reset
trunk/src/emu/cpu/m6502/dm65c02.lst
r18874r18875
1# m65c02
2brk_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
3bpl_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
4jsr_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
5bmi_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
6rti_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
7bvc_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
8rts_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
9bvs_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
10bra_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
11bcc_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
12ldy_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
13bcs_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
14cpy_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
15bne_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
16cpx_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
17beq_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
18reset
trunk/src/emu/cpu/m6502/dm65ce02.lst
r18874r18875
1# m65ce02 - Adds the B and Z registers to the r65c02, a bunch of instructions, and changes most of the timings
2brk_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
3bpl_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
4jsr_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
5bmi_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
6rti_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
7bvc_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
8rts_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
9bvs_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
10bra_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
11bcc_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
12ldy_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
13bcs_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
14cpy_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
15bne_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
16cpx_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
17beq_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
18reset
trunk/src/emu/cpu/m6502/m4510.c
r18874r18875
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/***************************************************************************
242
25/*
26   c65 memory management
27   (reset)
28   c64 ff
29   c65 20 (interface)
3    m4510.c
304
31a   (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
356
36b   (c65 dosmode?)
37   c65 65 (interface, full colorram)
38   a:00 x:11 y:80 z:31
39   c64 ff
7****************************************************************************
408
41c   (?)
42   c64 07
43   a:00 x:00 y:00 z:00
9    Copyright Olivier Galibert
10    All rights reserved.
4411
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:
4615
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.
4825
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.
4937
50   monitor
51   c64 ff
52   a:a0 x:82 y:00 z:83
38***************************************************************************/
5339
54   c64 mode
55   c65 0
56   c65 2f:0 !
57   c64 ff
58   a:00 x:00 y:00 z:00
59
60internal 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
63g      0 00 e0 00 f0
64g  10000 00 e1 00 f1
65g  20000 00 e2 00 f2
66g  30000 00 e3 00 f3
67g  40000 00 e4 00 f4
68g  50000 00 e5 00 f5
69g  60000 00 e6 00 f6
70.
71.
72g  f0000 00 ef 00 ff
73the same for 100000 .. 700000
74g 800000 00 e3 00 b3
75
76thesis:
77a: ?0?0 0000
78   ? ?       only in monitor mode set
79x:      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
89y: ?000 0000
90   ?         only in dos mode set
91z:      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
10340#include "emu.h"
104#include "debugger.h"
105#include "m6502.h"
10641#include "m4510.h"
10742
108#include "minc4510.h"
109#include "opsce02.h"
110#include "ops4510.h"
43const device_type M4510 = &device_creator<m4510_device>;
11144
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
123struct 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
160INLINE m4510_Regs *get_safe_token(device_t *device)
45m4510_device::m4510_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
46   m65ce02_device(mconfig, M4510, "M4510", tag, owner, clock)
16147{
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;
16551}
16652
167/***************************************************************
168 * include the opcode macros, functions and tables
169 ***************************************************************/
170
171INLINE int m4510_cpu_readop(m4510_Regs *cpustate)
53offs_t m4510_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
17254{
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);
17556}
17657
177INLINE int m4510_cpu_readop_arg(m4510_Regs *cpustate)
58void m4510_device::device_start()
17859{
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
186static 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);
20462   else
205   {
206      devcb_read8 nullrcb = DEVCB_NULL;
207      devcb_write8 nullwcb = DEVCB_NULL;
63      mintf = new mi_4510_normal(this);
20864
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();
21566
216static 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));
24469}
24570
246static CPU_EXIT( m4510 )
71void m4510_device::device_reset()
24772{
248   /* nothing to do yet */
73   map_offset[0] = map_offset[1] = 0;
74   map_enable = 0;
75   nomap = true;
24976}
25077
251INLINE void m4510_take_irq(m4510_Regs *cpustate)
78m4510_device::mi_4510_normal::mi_4510_normal(m4510_device *_base)
25279{
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;
26881}
26982
270static CPU_EXECUTE( m4510 )
83UINT8 m4510_device::mi_4510_normal::read(UINT16 adr)
27184{
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));
30886}
30987
310static void m4510_set_irq_line(m4510_Regs *cpustate, int irqline, int state)
88UINT8 m4510_device::mi_4510_normal::read_direct(UINT16 adr)
31189{
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));
33991}
34092
341UINT8 m4510_get_port(legacy_cpu_device *device)
93UINT8 m4510_device::mi_4510_normal::read_decrypted(UINT16 adr)
34294{
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));
34596}
346static READ8_HANDLER( m4510_read_0000 )
347{
348   UINT8 result = 0x00;
349   m4510_Regs *cpustate = get_safe_token(&space.device());
35097
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
364static WRITE8_HANDLER( m4510_write_0000 )
98void m4510_device::mi_4510_normal::write(UINT16 adr, UINT8 val)
36599{
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);
379101}
380102
381static 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)
383ADDRESS_MAP_END
384
385static CPU_TRANSLATE( m4510 )
103m4510_device::mi_4510_nd::mi_4510_nd(m4510_device *_base) : mi_4510_normal(_base)
386104{
387   m4510_Regs *cpustate = get_safe_token(device);
388
389   if (space == AS_PROGRAM)
390      *address = M4510_MEM(*address);
391   return TRUE;
392105}
393106
394/**************************************************************************
395 * Generic set_info
396 **************************************************************************/
397
398static CPU_SET_INFO( m4510 )
107UINT8 m4510_device::mi_4510_nd::read_direct(UINT16 adr)
399108{
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);
431110}
432111
433
434
435/**************************************************************************
436 * Generic get_info
437 **************************************************************************/
438
439CPU_GET_INFO( m4510 )
112UINT8 m4510_device::mi_4510_nd::read_decrypted(UINT16 adr)
440113{
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);
541115}
542116
543#undef M4510
544DEFINE_LEGACY_CPU_DEVICE(M4510, m4510);
117#include "cpu/m6502/m4510.inc"
trunk/src/emu/cpu/m6502/dn2a03.lst
r18874r18875
1# n2a03 - D flag is disabled but present in the P register
2brk_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
3bpl_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
4jsr_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
5bmi_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
6rti_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
7bvc_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
8rts_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
9bvs_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
10nop_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
11bcc_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
12ldy_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
13bcs_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
14cpy_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
15bne_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
16cpx_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
17beq_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
18reset
trunk/src/emu/cpu/m6502/m6502make.c
r18874r18875
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
12using namespace std;
13
14enum { STATES = 0x101 };
15
16const char *snames[STATES-0x100] = {
17   "STATE_RESET"
18};
19
20struct opcode {
21   string name;
22   vector<string> instructions;
23};
24
25vector<opcode> opcodes;
26
27struct table_t {
28   string opcodes[STATES];
29};
30
31table_t table;
32
33string device_name;
34
35static 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
67static 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
101enum { NONE, EAT_ALL, MEMORY };
102
103static 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
115static 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
174static 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
226static 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
244int 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}
trunk/src/emu/cpu/m6502/om6502.lst
r18874r18875
1# NMOS 6502 opcodes
2# Verified with visual6502
3#   documented opcodes
4
5adc_aba
6   TMP = read_pc();
7   TMP = set_h(TMP, read_pc());
8   TMP = read(TMP);
9   do_adc(TMP);
10   prefetch();
11
12adc_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
23adc_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
34adc_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
43adc_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
53adc_imm
54   TMP = read_pc();
55   do_adc(TMP);
56   prefetch();
57
58adc_zpg
59   TMP = read_pc();
60   TMP = read(TMP);
61   do_adc(TMP);
62   prefetch();
63
64adc_zpx
65   TMP = read_pc();
66   read(TMP);
67   TMP = read(UINT8(TMP+X));
68   do_adc(TMP);
69   prefetch();
70
71and_aba
72   TMP = read_pc();
73   TMP = set_h(TMP, read_pc());
74   A &= read(TMP);
75   set_nz(A);
76   prefetch();
77
78and_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
89and_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
100and_imm
101   A &= read_pc();
102   set_nz(A);
103   prefetch();
104
105and_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
115and_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
126and_zpg
127   TMP = read_pc();
128   A &= read(TMP);
129   set_nz(A);
130   prefetch();
131
132and_zpx
133   TMP = read_pc();
134   read(TMP);
135   A &= read(UINT8(TMP+X));
136   set_nz(A);
137   prefetch();
138
139asl_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
148asl_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
159asl_acc
160   read_pc_noinc();
161   A = do_asl(A);
162   prefetch();
163
164asl_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
172asl_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
182bcc_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
193bcs_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
204beq_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
215bit_aba
216   TMP = read_pc();
217   TMP = set_h(TMP, read_pc());
218   do_bit(read(TMP));
219   prefetch();
220
221bit_zpg
222   TMP = read_pc();
223   do_bit(read(TMP));
224   prefetch();
225
226bmi_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
237bne_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
248bpl_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
259brk_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
285bvc_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
296bvs_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
307clc_imp
308   read_pc_noinc();
309   P &= ~F_C;
310   prefetch();
311
312cld_imp
313   read_pc_noinc();
314   P &= ~F_D;
315   prefetch();
316
317cli_imp
318   read_pc_noinc();
319   prefetch();
320   P &= ~F_I; // Do *not* move it before the prefetch
321
322clv_imp
323   read_pc_noinc();
324   P &= ~F_V;
325   prefetch();
326
327cmp_aba
328   TMP = read_pc();
329   TMP = set_h(TMP, read_pc());
330   TMP = read(TMP);
331   do_cmp(A, TMP);
332   prefetch();
333
334cmp_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
345cmp_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
356cmp_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
365cmp_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
375cmp_imm
376   TMP = read_pc();
377   do_cmp(A, TMP);
378   prefetch();
379
380cmp_zpg
381   TMP = read_pc();
382   TMP = read(TMP);
383   do_cmp(A, TMP);
384   prefetch();
385
386cmp_zpx
387   TMP = read_pc();
388   read(TMP);
389   TMP = read(UINT8(TMP+X));
390   do_cmp(A, TMP);
391   prefetch();
392
393cpx_aba
394   TMP = read_pc();
395   TMP = set_h(TMP, read_pc());
396   TMP = read(TMP);
397   do_cmp(X, TMP);
398   prefetch();
399
400cpx_imm
401   TMP = read_pc();
402   do_cmp(X, TMP);
403   prefetch();
404
405cpx_zpg
406   TMP = read_pc();
407   TMP = read(TMP);
408   do_cmp(X, TMP);
409   prefetch();
410
411cpy_aba
412   TMP = read_pc();
413   TMP = set_h(TMP, read_pc());
414   TMP = read(TMP);
415   do_cmp(Y, TMP);
416   prefetch();
417
418cpy_imm
419   TMP = read_pc();
420   do_cmp(Y, TMP);
421   prefetch();
422
423cpy_zpg
424   TMP = read_pc();
425   TMP = read(TMP);
426   do_cmp(Y, TMP);
427   prefetch();
428
429dec_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
439dec_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
451dec_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
460dec_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
471dex_imp
472   read_pc_noinc();
473   X--;
474   set_nz(X);
475   prefetch();
476
477dey_imp
478   read_pc_noinc();
479   Y--;
480   set_nz(Y);
481   prefetch();
482
483eor_aba
484   TMP = read_pc();
485   TMP = set_h(TMP, read_pc());
486   A ^= read(TMP);
487   set_nz(A);
488   prefetch();
489
490eor_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
501eor_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
512eor_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
522eor_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
533eor_imm
534   A ^= read_pc();
535   set_nz(A);
536   prefetch();
537
538eor_zpg
539   TMP = read_pc();
540   A ^= read(TMP);
541   set_nz(A);
542   prefetch();
543
544eor_zpx
545   TMP = read_pc();
546   read(TMP);
547   A ^= read(UINT8(TMP+X));
548   set_nz(A);
549   prefetch();
550
551inc_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
561inc_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
573inc_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
582inc_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
593inx_imp
594   read_pc_noinc();
595   X++;
596   set_nz(X);
597   prefetch();
598
599iny_imp
600   read_pc_noinc();
601   Y++;
602   set_nz(Y);
603   prefetch();
604
605jmp_adr
606   TMP = read_pc();
607   TMP = set_h(TMP, read_pc());
608   PC = TMP;
609   prefetch();
610
611jmp_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
618jsr_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
629lda_aba
630   TMP = read_pc();
631   TMP = set_h(TMP, read_pc());
632   A = read(TMP);
633   set_nz(A);
634   prefetch();
635
636lda_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
646lda_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
656lda_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
666lda_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
677lda_imm
678   A = read_pc();
679   set_nz(A);
680   prefetch();
681
682lda_zpg
683   TMP = read_pc();
684   A = read(TMP);
685   set_nz(A);
686   prefetch();
687
688lda_zpx
689   TMP = read_pc();
690   read(TMP);
691   A = read(UINT8(TMP+X));
692   set_nz(A);
693   prefetch();
694
695ldx_aba
696   TMP = read_pc();
697   TMP = set_h(TMP, read_pc());
698   X = read(TMP);
699   set_nz(X);
700   prefetch();
701
702ldx_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
712ldx_imm
713   X = read_pc();
714   set_nz(X);
715   prefetch();
716
717ldx_zpg
718   TMP = read_pc();
719   X = read(TMP);
720   set_nz(X);
721   prefetch();
722
723ldx_zpy
724   TMP = read_pc();
725   read(TMP);
726   X = read(UINT8(TMP+Y));
727   set_nz(X);
728   prefetch();
729
730ldy_aba
731   TMP = read_pc();
732   TMP = set_h(TMP, read_pc());
733   Y = read(TMP);
734   set_nz(Y);
735   prefetch();
736
737ldy_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
748ldy_imm
749   Y = read_pc();
750   set_nz(Y);
751   prefetch();
752
753ldy_zpg
754   TMP = read_pc();
755   Y = read(TMP);
756   set_nz(Y);
757   prefetch();
758
759ldy_zpx
760   TMP = read_pc();
761   read(TMP);
762   Y = read(UINT8(TMP+X));
763   set_nz(Y);
764   prefetch();
765
766lsr_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
775lsr_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
786lsr_acc
787   read_pc_noinc();
788   A = do_lsr(A);
789   prefetch();
790
791lsr_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
799lsr_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
809nop_imp
810   read_pc_noinc();
811   prefetch();
812
813ora_aba
814   TMP = read_pc();
815   TMP = set_h(TMP, read_pc());
816   A |= read(TMP);
817   set_nz(A);
818   prefetch();
819
820ora_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
831ora_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
842ora_imm
843   A |= read_pc();
844   set_nz(A);
845   prefetch();
846
847ora_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
857ora_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
868ora_zpg
869   TMP = read_pc();
870   A |= read(TMP);
871   set_nz(A);
872   prefetch();
873
874ora_zpx
875   TMP = read_pc();
876   read(TMP);
877   A |= read(UINT8(TMP+X));
878   set_nz(A);
879   prefetch();
880
881pha_imp
882   read_pc_noinc();
883   write(SP, A);
884   dec_SP();
885   prefetch();
886
887php_imp
888   read_pc_noinc();
889   write(SP, P);
890   dec_SP();
891   prefetch();
892
893pla_imp
894   read_pc_noinc();
895   read(SP);
896   inc_SP();
897   A = read(SP);
898   set_nz(A);
899   prefetch();
900
901plp_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
909rol_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
918rol_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
929rol_acc
930   read_pc_noinc();
931   A = do_rol(A);
932   prefetch();
933
934rol_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
942rol_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
952ror_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
961ror_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
972ror_acc
973   read_pc_noinc();
974   A = do_ror(A);
975   prefetch();
976
977ror_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
985ror_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
995rti_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
1006rts_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
1016sbc_aba
1017   TMP = read_pc();
1018   TMP = set_h(TMP, read_pc());
1019   TMP = read(TMP);
1020   do_sbc(TMP);
1021   prefetch();
1022
1023sbc_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
1034sbc_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
1045sbc_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
1054sbc_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
1064sbc_imm
1065   TMP = read_pc();
1066   do_sbc(TMP);
1067   prefetch();
1068
1069sbc_zpg
1070   TMP = read_pc();
1071   TMP = read(TMP);
1072   do_sbc(TMP);
1073   prefetch();
1074
1075sbc_zpx
1076   TMP = read_pc();
1077   read(TMP);
1078   TMP = read(UINT8(TMP+X));
1079   do_sbc(TMP);
1080   prefetch();
1081
1082sec_imp
1083   read_pc_noinc();
1084   P |= F_C;
1085   prefetch();
1086
1087sed_imp
1088   read_pc_noinc();
1089   P |= F_D;
1090   prefetch();
1091
1092sei_imp
1093   read_pc_noinc();
1094   prefetch();
1095   P |= F_I; // Do *not* move it before the prefetch
1096
1097sta_aba
1098   TMP = read_pc();
1099   TMP = set_h(TMP, read_pc());
1100   write(TMP, A);
1101   prefetch();
1102
1103sta_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
1110sta_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
1117sta_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
1126sta_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
1134sta_zpg
1135   TMP = read_pc();
1136   write(TMP, A);
1137   prefetch();
1138
1139sta_zpx
1140   TMP = read_pc();
1141   read(TMP);
1142   write(UINT8(TMP+X), A);
1143   prefetch();
1144
1145stx_aba
1146   TMP = read_pc();
1147   TMP = set_h(TMP, read_pc());
1148   write(TMP, X);
1149   prefetch();
1150
1151stx_zpg
1152   TMP = read_pc();
1153   write(TMP, X);
1154   prefetch();
1155
1156stx_zpy
1157   TMP = read_pc();
1158   read(TMP);
1159   write(UINT8(TMP+Y), X);
1160   prefetch();
1161
1162sty_aba
1163   TMP = read_pc();
1164   TMP = set_h(TMP, read_pc());
1165   write(TMP, Y);
1166   prefetch();
1167
1168sty_zpg
1169   TMP = read_pc();
1170   write(TMP, Y);
1171   prefetch();
1172
1173sty_zpx
1174   TMP = read_pc();
1175   read(TMP);
1176   write(UINT8(TMP+X), Y);
1177   prefetch();
1178
1179tax_imp
1180   read_pc_noinc();
1181   X = A;
1182   set_nz(X);
1183   prefetch();
1184
1185tay_imp
1186   read_pc_noinc();
1187   Y = A;
1188   set_nz(Y);
1189   prefetch();
1190
1191tsx_imp
1192   read_pc_noinc();
1193   X = SP;
1194   set_nz(X);
1195   prefetch();
1196
1197txa_imp
1198   read_pc_noinc();
1199   A = X;
1200   set_nz(A);
1201   prefetch();
1202
1203txs_imp
1204   read_pc_noinc();
1205   SP = set_l(SP, X);
1206   prefetch();
1207
1208tya_imp
1209   read_pc_noinc();
1210   A = Y;
1211   set_nz(A);
1212   prefetch();
1213
1214#   exceptions
1215reset
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
1223dcp_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
1233dcp_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
1245dcp_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
1257dcp_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
1270dcp_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
1283dcp_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
1292dcp_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
1303isb_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
1313isb_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
1325isb_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
1337isb_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
1350isb_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
1363isb_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
1372isb_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
1383lax_aba
1384   TMP = read_pc();
1385   TMP = set_h(TMP, read_pc());
1386   A = X = read(TMP);
1387   set_nz(A);
1388   prefetch();
1389
1390lax_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
1399lax_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
1409lax_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
1420lax_zpg
1421   TMP = read_pc();
1422   A = X = read(TMP);
1423   set_nz(A);
1424   prefetch();
1425
1426lax_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
1434rla_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
1445rla_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
1458rla_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
1471rla_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
1485rla_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
1499rla_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
1509rla_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
1521rra_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
1531rra_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
1543rra_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
1555rra_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
1568rra_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
1581rra_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
1590rra_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
1601sax_aba
1602   TMP = read_pc();
1603   TMP = set_h(TMP, read_pc());
1604   TMP2 = A & X;
1605   write(TMP, TMP2);
1606   prefetch();
1607
1608sax_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
1618sax_zpg
1619   TMP = read_pc();
1620   TMP2 = A & X;
1621   write(TMP, TMP2);
1622   prefetch();
1623
1624sax_zpy
1625   TMP = read_pc();
1626   read(TMP);
1627   TMP = UINT8(TMP+Y);
1628   TMP2 = A & X;
1629   write(TMP, TMP2);
1630   prefetch();
1631
1632sbx_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
1643sha_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
1655sha_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
1668shs_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
1681shx_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
1693shy_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
1705slo_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
1716slo_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
1729slo_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
1742slo_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
1756slo_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
1770slo_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
1780slo_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
1792sre_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
1803sre_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
1816sre_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
1829sre_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
1843sre_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
1857sre_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
1867sre_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
1880anc_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
1889ane_imm
1890   TMP2 = read_pc();
1891   A &= TMP2 & X;
1892   set_nz(A);
1893   prefetch();
1894
1895asr_imm
1896   read_pc();
1897   A = do_lsr(A);
1898   prefetch();
1899
1900arr_imm
1901   read_pc();
1902   do_arr();
1903   prefetch();
1904
1905las_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
1917lxa_imm
1918   TMP2 = read_pc();
1919   A = X = A & TMP2;
1920   set_nz(A);
1921   prefetch();
1922
1923# nop variants
1924nop_aba
1925   TMP = read_pc();
1926   TMP = set_h(TMP, read_pc());
1927   read(TMP);
1928   prefetch();
1929
1930nop_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
1939nop_imm
1940   read_pc();
1941   prefetch();
1942
1943nop_zpg
1944   TMP = read_pc();
1945   read(TMP);
1946   prefetch();
1947
1948nop_zpx
1949   TMP = read_pc();
1950   read(TMP);
1951   read(UINT8(TMP+X));
1952   prefetch();
1953
1954# system killers
1955kil_non
1956   read_pc();
1957   read(0xffff);
1958   read(0xfffe);
1959   read(0xfffe);
1960   for(;;) {
1961      read(0xffff);
1962   }   
trunk/src/emu/cpu/m6502/m6510.c
r18874r18875
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
43const device_type M6510 = &device_creator<m6510_device>;
44
45m6510_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
54m6510_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
63void m6510_device::set_pulls(UINT8 _pullup, UINT8 _floating)
64{
65   pullup = _pullup;
66   floating = _floating;
67}
68
69offs_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
74void 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
93void m6510_device::device_reset()
94{
95   dir = 0x00;
96   port = 0x00;
97   drive = 0x00;
98   update_port();
99}
100
101void m6510_device::update_port()
102{
103   drive = (port & dir) | (drive & ~dir);
104   write_port((port & dir) | (pullup & ~dir));
105}
106
107UINT8 m6510_device::get_port()
108{
109   return (port & dir) | (pullup & ~dir);
110}
111
112UINT8 m6510_device::dir_r()
113{
114   return dir;
115}
116
117UINT8 m6510_device::port_r()
118{
119   return ((read_port() | (floating & drive)) & ~dir) | (port & dir);
120}
121
122void m6510_device::dir_w(UINT8 data)
123{
124   dir = data;
125   update_port();
126}
127
128void m6510_device::port_w(UINT8 data)
129{
130   port = data;
131   update_port();
132}
133
134
135m6510_device::mi_6510_normal::mi_6510_normal(m6510_device *_base)
136{
137   base = _base;
138}
139
140UINT8 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
150UINT8 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
160UINT8 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
170void 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
179m6510_device::mi_6510_nd::mi_6510_nd(m6510_device *_base) : mi_6510_normal(_base)
180{
181}
182
183UINT8 m6510_device::mi_6510_nd::read_direct(UINT16 adr)
184{
185   return read(adr);
186}
187
188UINT8 m6510_device::mi_6510_nd::read_decrypted(UINT16 adr)
189{
190   return read(adr);
191}
192
193#include "cpu/m6502/m6510.inc"
trunk/src/emu/cpu/m6502/m7501.c
r18874r18875
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
43const device_type M7501 = &device_creator<m7501_device>;
44
45m7501_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}
trunk/src/emu/cpu/m6502/m4510.h
r18874r18875
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/***************************************************************************
212
22#pragma once
3    m4510.h
234
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
2440#ifndef __M4510_H__
2541#define __M4510_H__
2642
27#include "m6502.h"
43#include "m65ce02.h"
2844
45class m4510_device : public m65ce02_device {
46public:
47   m4510_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
2948
30enum
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];
3950
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();
4154
42DECLARE_LEGACY_CPU_DEVICE(M4510, m4510);
55   bool get_nomap() const { return nomap; }
4356
57protected:
58   UINT32 map_offset[2];
59   UINT8 map_enable;
60   bool nomap;
4461
45extern CPU_DISASSEMBLE( m4510 );
62   class mi_4510_normal : public memory_interface {
63   public:
64      m4510_device *base;
4665
47UINT8 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   };
4872
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
101enum {
102   M4510_IRQ_LINE = m6502_device::IRQ_LINE,
103   M4510_NMI_LINE = m6502_device::NMI_LINE,
104};
105
106extern const device_type M4510;
107
108#endif
trunk/src/emu/cpu/m6502/om65c02.lst
r18874r18875
1# m65c02 opcodes
2
3adc_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
14adc_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
29adc_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
44adc_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
57adc_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
71adc_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
80adc_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
90adc_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
101adc_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
112and_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
120asl_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
133bbr_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
144bbs_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
155bit_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
165bit_imm
166   TMP = read_pc();
167   if(A & TMP)
168      P &= ~F_Z;
169   else
170      P |= F_Z;
171   prefetch();
172
173bit_zpx
174   TMP = read_pc();
175   read(TMP);
176   TMP = read(UINT8(TMP+X));
177   do_bit(TMP);
178   prefetch();
179
180bra_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
189brk_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
214cmp_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
221dec_acc
222   read_pc_noinc();
223   A--;
224   set_nz(A);
225   prefetch();
226
227eor_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
235inc_acc
236   read_pc_noinc();
237   A++;
238   set_nz(A);
239   prefetch();
240
241jmp_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
250jmp_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
258lda_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
267lsr_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
280nop_c_imp
281   prefetch();
282
283nop_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
293nop_c_abx
294   TMP = read_pc();
295   TMP = set_h(TMP, read_pc());
296   read(set_l(TMP, TMP+X));
297   prefetch();
298
299ora_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
307phx_imp
308   read_pc_noinc();
309   write(SP, X);
310   dec_SP();
311   prefetch();
312
313phy_imp
314   read_pc_noinc();
315   write(SP, Y);
316   dec_SP();
317   prefetch();
318
319plx_imp
320   read_pc_noinc();
321   read(SP);
322   inc_SP();
323   X = read(SP);
324   set_nz(X);
325   prefetch();
326
327ply_imp
328   read_pc_noinc();
329   read(SP);
330   inc_SP();
331   Y = read(SP);
332   set_nz(Y);
333   prefetch();
334
335rmb_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
344rol_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
358ror_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
371sbc_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
382sbc_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
397sbc_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
412sbc_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
425sbc_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
439sbc_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
448sbc_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
458sbc_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
469sbc_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
480smb_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
489sta_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
496stp_imp
497   for(;;) {
498      eat-all-cycles;
499   }
500
501stz_aba
502   TMP = read_pc();
503   TMP = set_h(TMP, read_pc());
504   write(TMP, 0x00);
505   prefetch();
506
507stz_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
514stz_zpg
515   TMP = read_pc();
516   write(TMP, 0x00);
517   prefetch();
518
519stz_zpx
520   TMP = read_pc();
521   read(TMP);
522   write(UINT8(TMP+X), 0x00);
523   prefetch();
524
525trb_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
538trb_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
550tsb_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
563tsb_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
575wai_imp
576   read_pc_noinc();
577   read_pc_noinc();
578   while(!nmi_state && !irq_state) {
579      eat-all-cycles;
580   }
581   prefetch();
trunk/src/emu/cpu/m6502/m65c02.c
r18874r18875
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
44const device_type M65C02 = &device_creator<m65c02_device>;
45
46m65c02_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
51m65c02_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
56offs_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"
trunk/src/emu/cpu/m6502/m6510.h
r18874r18875
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
51class m6510_device : public m6502_device {
52public:
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
71protected:
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
119enum {
120   M6510_IRQ_LINE = m6502_device::IRQ_LINE,
121   M6510_NMI_LINE = m6502_device::NMI_LINE,
122};
123
124extern const device_type M6510;
125
126#endif
trunk/src/emu/cpu/cpu.mak
r18874r18875
10031003
10041004ifneq ($(filter M6502,$(CPUS)),)
10051005OBJDIRS += $(CPUOBJ)/m6502
1006CPUOBJS += $(CPUOBJ)/m6502/m6502.o
1007CPUOBJS += $(CPUOBJ)/m6502/m6509.o
1008CPUOBJS += $(CPUOBJ)/m6502/m65ce02.o
1009CPUOBJS += $(CPUOBJ)/m6502/m4510.o
1010DASMOBJS += $(CPUOBJ)/m6502/6502dasm.o
1006CPUOBJS += $(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
1020DASMOBJS +=
1021M6502MAKE += $(BUILDOUT)/m6502make$(BUILD_EXE)
10111022endif
10121023
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
10131029$(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
10151035
10161036$(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
10251039
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
10261045$(CPUOBJ)/m6502/m65ce02.o:   $(CPUSRC)/m6502/m65ce02.c \
1046                     $(CPUOBJ)/m6502/m65ce02.inc \
10271047                     $(CPUSRC)/m6502/m65ce02.h \
1028                     $(CPUSRC)/m6502/opsce02.h \
1029                     $(CPUSRC)/m6502/t65ce02.c
1048                     $(CPUSRC)/m6502/m65c02.h \
1049                     $(CPUSRC)/m6502/m6502.h
10301050
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
10311061$(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
10351064
1065$(CPUOBJ)/m6502/m6510.o:   $(CPUSRC)/m6502/m6510.c \
1066                     $(CPUOBJ)/m6502/m6510.inc \
1067                     $(CPUSRC)/m6502/m6510.h \
1068                     $(CPUSRC)/m6502/m6502.h
10361069
1070$(CPUOBJ)/m6502/m6510t.o:   $(CPUSRC)/m6502/m6510t.c \
1071                     $(CPUSRC)/m6502/m6510t.h \
1072                     $(CPUSRC)/m6502/m6510.h \
1073                     $(CPUSRC)/m6502/m6502.h
10371074
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
1135ifneq ($(CROSS_BUILD),1)
1136
1137BUILD += $(M6502MAKE)
1138
1139$(M6502MAKE): $(CPUOBJ)/m6502/m6502make.o
1140   @echo Linking $@...
1141   $(LD) $(LDFLAGS) $(OSDBGLDFLAGS) $^ -o $@
1142
1143endif
1144
1145
10381146#-------------------------------------------------
10391147# Motorola 680x
10401148#-------------------------------------------------
r18874r18875
12031311$(CPUOBJ)/dsp56k/dsp56dsm.o:   $(CPUSRC)/dsp56k/opcode.c \
12041312                        $(CPUSRC)/dsp56k/opcode.h \
12051313                        $(CPUSRC)/dsp56k/inst.c \
1206                         $(CPUSRC)/dsp56k/inst.h \
1314                        $(CPUSRC)/dsp56k/inst.h \
12071315                        $(CPUSRC)/dsp56k/pmove.c \
12081316                        $(CPUSRC)/dsp56k/pmove.h \
12091317                        $(CPUSRC)/dsp56k/tables.c \
trunk/src/emu/sound/nes_apu.c
r18874r18875
4646
4747#include "emu.h"
4848#include "nes_apu.h"
49#include "cpu/m6502/m6502.h"
49#include "cpu/m6502/n2a03.h"
5050
5151#include "nes_defs.h"
5252
r18874r18875
371371               if (chan->regs[0] & 0x80) /* IRQ Generator */
372372               {
373373                  chan->irq_occurred = TRUE;
374                  n2a03_irq(&info->APU.dpcm.memory->device());
374                  downcast<n2a03_device &>(info->APU.dpcm.memory->device()).set_input_line(N2A03_IRQ_LINE, ASSERT_LINE);
375375               }
376376               break;
377377            }
r18874r18875
520520   /* DMC */
521521   case APU_WRE0:
522522      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);
524525         info->APU.dpcm.irq_occurred = FALSE;
526      }
525527      break;
526528
527529   case APU_WRE1: /* 7-bit DAC */
trunk/docs/m6502.txt
r18874r18875
1The new 6502 family implementation
2----------------------------------
3
4  1. Introduction
5
6The new 6502 family implementation has been created to reach
7sub-instruction accuracy in observable behaviour.  It is designed with
83 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
19Point 1 has been ensured through bisimulation with the gate-level
20simulation perfect6502.  Point 2 has been ensured structurally through
21a code generator which will be explained in section 8.  Point 3 is not
22done yet due to lack of support on the memory subsystem side, but
23section 9 shows how it will be handled.
24
25
26  2. The 6502 family
27
28The MOS 6502 family has been large and productive.  A large number of
29variants exist, varying on bus sizes, i/o, and even opcodes.  Some
30offshots (g65c816, hu6280) even exist that live elsewhere in the mame
31tree.  The final class hierarchy is this:
32
33                          6502
34                           |
35        +------+--------+--+--+-------+-------+
36        |      |        |     |       |       |
37      6510   deco16   6504   6509   n2a03   65c02
38        |                                     |
39  +-----+-----+                            r65c02
40  |     |     |                               |
416510t  7501  8502                         +---+---+     
42                                          |       |
43                                       65ce02   65sc02
44                                          |
45                                        4510
46
47The 6510 adds an up to 8 bits i/o port, with the 6510t, 7501 and 8502
48being software-identical variants with different pin count (hence i/o
49count), die process (nmos, hnmos, etc) and clock support.
50
51The deco16 is a Deco variant with a small number of not really understood
52additional instructions and some i/o.
53
54The 6504 is a pin and address-bus reduced version.
55
56The 6509 adds internal support for paging.
57
58The n2a03 is the nes variant with the D flag disabled and sound
59functionality integrated.
60
61The 65c02 is the very first cmos variant with some additional
62instructions, some fixes, and most of the undocumented instructions
63turned into nops.  The R (rockwell, but eventually produced by wdc too
64among others) variant adds a number of bitwise instructions and also
65stp and wai.  The sc variant, used by the Lynx portable console, looks
66identical to the R variant.  The 's' probably indicates a
67static-ram-cell process allowing full dc-to-max clock control.
68
69The 65ce02 is the final evolution of the ISA in this hierarchy, with
70additional instructions, registers, and removals of a lot of dummy
71accesses that slowed the original 6502 down by at least 25%.  The 4510
72is a 65ce02 with integrated mmu and gpio support.
73
74
75  3. Usage of the classes
76
77All the cpus are standard modern cpu devices, with all the normal
78interaction with the device infrastructure.  To include one of these
79cpu in your driver you need to include "cpu/m6502/<cpu>.h" and then do
80a MCFG_CPU_ADD("tag", <CPU>, clock).
81
826510 variants port i/o callbacks are setup through:
83  MCFG_<CPU>_PORT_CALLBACKS(READ8(type, read_method), WRITE8(type, write_method))
84
85And the pullup and floating lines mask is given through:
86  MCFG_<CPU>_PORT_PULLS(pullups, floating)
87
88In order to see all bus accesses on the memory handlers it is possible
89to disable accesses through the direct map (at a cpu cost, of course)
90with:
91  MCFG_M6502_DISABLE_DIRECT()
92
93In that case, transparent decryption support is also disabled,
94everything goes through normal memory-map read/write calls.  The state
95of the sync line is given by the cpu method get_sync(), making
96implementing the decryption in the handler possible.
97
98In a final addition, the cpu method get_cycle() gives the current time
99in cycles since the start of the machine from the point of view of the
100cpu.  Or, in other words, what is usually called the cycle number for
101the cpu when somebody talks about bus contention or wait states.  The
102call is designed to be fast (no system-wide sync, usually no call to
103machine.time()) and is precise.  Cycle number for every access is
104exact at the sub-instruction level.
105
106The 4510 special nomap line is accessible through get_nomap().
107
108Other than these specifics, these are perfectly normal cpu classes.
109
110
111  4. General structure of the emulations
112
113Each 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
119The last two are optional.  They're used to generate a <cpu>.inc file
120in the object directory which is included by the .c file.
121
122At a minimum, the class must include a constructor and an enum picking
123up the correct input line ids.  See m65sc02 for a minimalist example.
124The header can also include specific configuration macros (see m8502)
125and also the class can include specific memory accessors (more on
126these later, simple example in m6504).
127
128If the cpu has its own dispatch table, the class must also include the
129declaration (but not definition) of disasm_entries, do_exec_full and
130do_exec_partial, the declaration and definition of disasm_disassemble
131(identical for all classes but refers to the class-specific
132disasm_entries array) and include the .inc file (which provides the
133missing definitions).  Support for the generation must also be added
134to cpu.mak.
135
136If the cpu has in addition its own opcodes, their declaration must be
137done through a macro, see f.i. m65c02.  The .inc file will provide the
138definitions.
139
140
141  5. Dispatch tables
142
143Each d<cpu>.lst is the dispatch table for the cpu.  Lines starting
144with '#' are comments.  The file must include 257 entries, the first
145256 being opcodes and the 257th what the cpu should do on reset.  In
146the 6502 irq and nmi actually magically call the "brk" opcode, hence
147the lack of specific description for them.
148
149Entries 0 to 255, i.e. the opcodes, must have one of these two
150structures:
151- opcode_addressing-mode
152- opcode_middle_addressing-mode
153
154Opcode is traditionally a three-character value.  Addressing mode must
155be a 3-letter value corresponding to one of the DASM_* macros in
156m6502.h.  Opcode and addressing mode are used to generate the
157disassembly table.  The full entry text is used in the opcode
158description file and the dispatching methods, allowing for per-cpu
159variants for identical-looking opcodes.
160
161An entry of "." was usable for unimplemented/unknown opcodes,
162generating "???" in the disassembly, but is not a good idea at this
163point since it will infloop in execute() if encountered.
164
165
166  6. Opcode descriptions
167
168Each o<cpu>.lst file includes the cpu-specific opcodes descriptions.
169An opcode description is a series of lines starting by an opcode entry
170by itself and followed by a series of indented lines with code
171executing the opcode.
172
173For instance the asl <absolute adress> opcode looks like this:
174
175asl_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
184First the low part of the address is read, then the high part (read_pc
185is auto-incrementing).  Then, now that the address is available the
186value to shift is read, then re-written (yes, the 6502 does that),
187shifted then the final result is written (do_asl takes care of the
188flags).  The instruction finishes with a prefetch of the next
189instruction, as all non-cpu-crashing instructions do.
190
191Available 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
201Cycle counting is done by the code generator which detects (through
202string matching) the accesses and generates the appropriate code.  In
203addition to the bus-accessing functions a special line can be used to
204wait for the next event (irq or whatever).  "eat-all-cycles;" on a
205line will do that wait then continue.  It is used by wai_imp and
206stp_imp for the m65c02.
207
208Due to the constraints of the code generation, some rules have to be
209followed:
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
224The per-opcode generated code are methods of the cpu class.  As such
225they have complete access to other methods of the class, variables of
226the class, everything.
227
228
229  7. Memory interface
230
231For better opcode reuse with the mmu/banking variants, a memory access
232subclass has been created.  It's called memory_interface, declared in
233m6502_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
243Two implementations are given by default, one usual,
244mi_default_normal, one disabling direct access, mi_default_nd.  A cpu
245that wants its own interface (see 6504 or 6509 for instance) must
246override device_start, intialize mintf there then call init().
247
248
249  8. The generated code
250
251A code generator is used to support interrupting and restarting an
252instruction in the middle.  This is done through a two-level state
253machine with updates only at the boundaries.  More precisely,
254inst_state tells you which main state you're in.  It's equal to the
255opcode byte when 0-255, and 256 means reset.  It's always valid and
256used by instructions like rmb.  inst_substate indicates at which step
257we are in an instruction, but it set only when an instruction has been
258interrupted.  Let's go back to the asl <abs> code:
259
260asl_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
270The complete generated code is:
271void m6502_device::asl_aba_partial()
272{
273switch(inst_substate) {
274case 0:
275    if(icount == 0) { inst_substate = 1; return; }
276case 1:
277    TMP = read_pc();
278    icount--;
279    if(icount == 0) { inst_substate = 2; return; }
280case 2:
281    TMP = set_h(TMP, read_pc());
282    icount--;
283    if(icount == 0) { inst_substate = 3; return; }
284case 3:
285    TMP2 = read(TMP);
286    icount--;
287    if(icount == 0) { inst_substate = 4; return; }
288case 4:
289    write(TMP, TMP2);
290    icount--;
291    TMP2 = do_asl(TMP2);
292    if(icount == 0) { inst_substate = 5; return; }
293case 5:
294    write(TMP, TMP2);
295    icount--;
296    if(icount == 0) { inst_substate = 6; return; }
297case 6:
298    prefetch();
299    icount--;
300}
301    inst_substate = 0;
302}
303
304
305One can see that the initial switch() restarts the instruction at the
306appropriate substate, that icount is updated after each access, and
307upon reaching 0 the instruction is interrupted and the substate
308updated.  Since most instructions are started from the beginning a
309specific variant is generated for when inst_substate is known to be 0:
310
311void 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
334That variant removes the switch, avoiding a costly computed branch and
335also an inst_substate write.  There is in addition a fair chance that
336the decrement-test with zero pair is compiled into something
337efficient.
338
339All these opcode functions are called through two virtual methods,
340do_exec_full and do_exec_partial, which are generated into a 257-entry
341switch statement.  Pointers-to-methods being expensive to call, a
342virtual function implementing a switch has a fair chance of being
343better.
344
345The execute main call ends up very simple:
346void 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
362If an instruction was partially executed finish it (icount will then
363be zero if it still doesn't finish).  Then try to run complete
364instructions.  The NPC/IR dance is due to the fact that the 6502 does
365instruction prefetching, so the instruction PC and opcode come from
366the prefetch results.
367
368
369  9. Future bus contention/delay slot support
370
371Supporting bus contention and delay slots in the context of the code
372generator only requires being able to abort a bus access when not
373enough cycles are available into icount, and restart it when cycles
374have 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:
380void m6502_device::asl_aba_partial()
381{
382switch(inst_substate) {
383case 0:
384    if(icount == 0) { inst_substate = 1; return; }
385case 1:
386    try {
387    TMP = read_pc();
388    } catch(suspend) { inst_substate = 1; return; }
389    icount--;
390    if(icount == 0) { inst_substate = 2; return; }
391case 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; }
397case 3:
398    try {
399    TMP2 = read(TMP);
400    } catch(suspend) { inst_substate = 3; return; }
401    icount--;
402    if(icount == 0) { inst_substate = 4; return; }
403case 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; }
410case 5:
411    try {
412    write(TMP, TMP2);
413    } catch(suspend) { inst_substate = 5; return; }
414    icount--;
415    if(icount == 0) { inst_substate = 6; return; }
416case 6:
417    try {
418    prefetch();
419    } catch(suspend) { inst_substate = 6; return; }
420    icount--;
421}
422    inst_substate = 0;
423}
424
425A modern try/catch costs nothing if an exception is not thrown.  Using
426this the control will go back to the main loop, which will then look
427like this:
428
429void 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
453A negative icount means that the cpu won't be able to do anything for
454some time in the future, because it's either waiting for the bus to be
455free or for a peripheral to answer.  These cycles will be counted
456until elapsed and then normal processing will go on.  It's important
457to note that the exception path only happens when the contention/wait
458state goes further than the scheduling slice of the cpu.  That should
459not 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


© 1997-2024 The MAME Team