Previous 199869 Revisions Next

r26762 Thursday 26th December, 2013 at 15:05:35 UTC by Wilbert Pol
spc700.c: Modernized cpu core.  [Wilbert Pol]
[src/emu/cpu/spc700]spc700.c spc700.h

trunk/src/emu/cpu/spc700/spc700.h
r26761r26762
44#define __SPC700_H__
55
66
7DECLARE_LEGACY_CPU_DEVICE(SPC700, spc700);
7class spc700_device :  public cpu_device
8{
9public:
10   // construction/destruction
11   spc700_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
812
13protected:
14   // device-level overrides
15   virtual void device_start();
16   virtual void device_reset();
17
18   // device_execute_interface overrides
19   virtual UINT32 execute_min_cycles() const { return 2; }
20   virtual UINT32 execute_max_cycles() const { return 8; }
21   virtual UINT32 execute_input_lines() const { return 1; }
22   virtual void execute_run();
23   virtual void execute_set_input(int inputnum, int state);
24
25   // device_memory_interface overrides
26   virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const { return (spacenum == AS_PROGRAM) ? &m_program_config : NULL; }
27
28   // device_state_interface overrides
29   virtual void state_import(const device_state_entry &entry);
30   virtual void state_export(const device_state_entry &entry);
31   void state_string_export(const device_state_entry &entry, astring &string);
32
33   // device_disasm_interface overrides
34   virtual UINT32 disasm_min_opcode_bytes() const { return 1; }
35   virtual UINT32 disasm_max_opcode_bytes() const { return 3; }
36   virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
37
38private:
39   address_space_config m_program_config;
40
41   UINT32 m_a;     /* Accumulator */
42   UINT32 m_x;     /* Index Register X */
43   UINT32 m_y;     /* Index Register Y */
44   UINT32 m_s;     /* Stack Pointer */
45   UINT32 m_pc;    /* Program Counter */
46   UINT32 m_ppc;   /* Previous Program Counter */
47   UINT32 m_flag_n;    /* Negative Flag */
48   UINT32 m_flag_z;    /* Zero flag */
49   UINT32 m_flag_v;    /* Overflow Flag */
50   UINT32 m_flag_p;    /* Direct Page Flag */
51   UINT32 m_flag_b;    /* BRK Instruction Flag */
52   UINT32 m_flag_h;    /* Half-carry Flag */
53   UINT32 m_flag_i;    /* Interrupt Mask Flag */
54   UINT32 m_flag_c;    /* Carry Flag */
55   UINT32 m_line_irq;  /* Status of the IRQ line */
56   UINT32 m_line_nmi;  /* Status of the NMI line */
57   UINT32 m_line_rst;  /* Status of the RESET line */
58   UINT32 m_ir;        /* Instruction Register */
59   address_space *m_program;
60   UINT32 m_stopped;   /* stopped status */
61   int m_ICount;
62   UINT32 m_source;
63   UINT32 m_destination;
64   UINT32 m_temp1;
65   UINT32 m_temp2;
66   UINT32 m_temp3;
67   short m_spc_int16;
68   int m_spc_int32;
69
70   UINT32 m_debugger_temp;
71
72   inline UINT32 read_8_normal(UINT32 address);
73   inline UINT32 read_8_immediate(UINT32 address);
74   inline UINT32 read_8_instruction(UINT32 address);
75   inline UINT32 read_8_direct(UINT32 address);
76   inline void write_8_normal(UINT32 address, UINT32 value);
77   inline void write_8_direct(UINT32 address, UINT32 value);
78   inline UINT32 read_16_normal(UINT32 address);
79   inline UINT32 read_16_immediate(UINT32 address);
80   inline UINT32 read_16_direct(UINT32 address);
81   inline void write_16_direct(UINT32 address, UINT32 value);
82   inline UINT32 EA_IMM();
83   inline UINT32 EA_IMM16();
84   inline UINT32 EA_ABS();
85   inline UINT32 EA_ABX();
86   inline UINT32 EA_ABY();
87   inline UINT32 EA_AXI();
88   inline UINT32 EA_DP();
89   inline UINT32 EA_DPX();
90   inline UINT32 EA_DPY();
91   inline UINT32 EA_DXI();
92   inline UINT32 EA_DIY();
93   inline UINT32 EA_XI();
94   inline UINT32 EA_XII();
95   inline UINT32 EA_YI();
96   inline void JUMP(UINT32 address);
97   inline void BRANCH(UINT32 offset);
98   inline void SET_REG_YA(UINT32 value);
99   inline void SET_REG_P(UINT32 value);
100   inline void PUSH_8(UINT32 value);
101   inline UINT32 PULL_8();
102   inline void PUSH_16(UINT32 value);
103   inline UINT32 PULL_16();
104   inline void CHECK_IRQ();
105   inline void SET_FLAG_I(UINT32 value);
106   void SERVICE_IRQ();
107};
108
109
110extern const device_type SPC700;
111
112
9113/* ======================================================================== */
10114/* ============================= Configuration ============================ */
11115/* ======================================================================== */
12116
13#undef uint
14#define uint unsigned int
15
16117/* Turn on optimizations for SNES since it doesn't hook up the interrupt lines */
17118#define SPC700_OPTIMIZE_SNES 1
18119
trunk/src/emu/cpu/spc700/spc700.c
r26761r26762
6565#include "debugger.h"
6666#include "spc700.h"
6767
68/* CPU Structure */
69struct spc700i_cpu
70{
71   uint a;     /* Accumulator */
72   uint x;     /* Index Register X */
73   uint y;     /* Index Register Y */
74   uint s;     /* Stack Pointer */
75   uint pc;    /* Program Counter */
76   uint ppc;   /* Previous Program Counter */
77   uint flag_n;    /* Negative Flag */
78   uint flag_z;    /* Zero flag */
79   uint flag_v;    /* Overflow Flag */
80   uint flag_p;    /* Direct Page Flag */
81   uint flag_b;    /* BRK Instruction Flag */
82   uint flag_h;    /* Half-carry Flag */
83   uint flag_i;    /* Interrupt Mask Flag */
84   uint flag_c;    /* Carry Flag */
85   uint line_irq;  /* Status of the IRQ line */
86   uint line_nmi;  /* Status of the NMI line */
87   uint line_rst;  /* Status of the RESET line */
88   uint ir;        /* Instruction Register */
89   device_irq_acknowledge_callback int_ack;
90   legacy_cpu_device *device;
91   address_space *program;
92   uint stopped;   /* stopped status */
93   int ICount;
94   uint source;
95   uint destination;
96   uint temp1, temp2, temp3;
97   short spc_int16;
98   int spc_int32;
99};
10068
101INLINE spc700i_cpu *get_safe_token(device_t *device)
102{
103   assert(device != NULL);
104   assert(device->type() == SPC700);
105   return (spc700i_cpu *)downcast<legacy_cpu_device *>(device)->token();
106}
107
10869/* ======================================================================== */
10970/* ==================== ARCHITECTURE-DEPENDANT DEFINES ==================== */
11071/* ======================================================================== */
11172
112/* This should be set to the default size of your processor (min 16 bit) */
113#undef uint
114#define uint unsigned int
115
116#undef uint8
117#define uint8 unsigned char
118
11973#undef int8
12074
12175/* Allow for architectures that don't have 8-bit sizes */
r26761r26762
183137#define VECTOR_IRQ  0xfffc              /* IRQ ??? what is real vector? */
184138#define VECTOR_NMI  0xfffa              /* NMI ??? what is real vector? */
185139
186#define REG_A       cpustate->a     /* Accumulator */
187#define REG_X       cpustate->x     /* Index X Register */
188#define REG_Y       cpustate->y     /* Index Y Register */
189#define REG_S       cpustate->s     /* Stack Pointer */
190#define REG_PC      cpustate->pc        /* Program Counter */
191#define REG_PPC     cpustate->ppc       /* Previous Program Counter */
192#define REG_P       cpustate->p     /* Processor Status Register */
193#define FLAG_NZ     cpustate->flag_n = cpustate->flag_z /* Negative Flag and inverted Zero flag */
194#define FLAG_N      cpustate->flag_n    /* Negative flag */
195#define FLAG_Z      cpustate->flag_z    /* Inverted Zero flag */
196#define FLAG_V      cpustate->flag_v    /* Overflow Flag */
197#define FLAG_P      cpustate->flag_p    /* Direct Page Flag */
198#define FLAG_B      cpustate->flag_b    /* BRK Instruction Flag */
199#define FLAG_H      cpustate->flag_h    /* Decimal Mode Flag */
200#define FLAG_I      cpustate->flag_i    /* Interrupt Mask Flag */
201#define FLAG_C      cpustate->flag_c    /* Carry Flag */
202#define LINE_IRQ    cpustate->line_irq  /* Status of the IRQ line */
203#define LINE_NMI    cpustate->line_nmi  /* Status of the NMI line */
204#define REG_IR      cpustate->ir        /* Instruction Register */
205#define INT_ACK     cpustate->int_ack   /* Interrupt Acknowledge function pointer */
206#define CLOCKS      cpustate->ICount        /* Clock cycles remaining */
207#define CPU_STOPPED cpustate->stopped   /* Stopped status */
140#define REG_A       m_a     /* Accumulator */
141#define REG_X       m_x     /* Index X Register */
142#define REG_Y       m_y     /* Index Y Register */
143#define REG_S       m_s     /* Stack Pointer */
144#define REG_PC      m_pc        /* Program Counter */
145#define REG_PPC     m_ppc       /* Previous Program Counter */
146#define REG_P       m_p     /* Processor Status Register */
147#define FLAG_NZ     m_flag_n = m_flag_z /* Negative Flag and inverted Zero flag */
148#define FLAG_N      m_flag_n    /* Negative flag */
149#define FLAG_Z      m_flag_z    /* Inverted Zero flag */
150#define FLAG_V      m_flag_v    /* Overflow Flag */
151#define FLAG_P      m_flag_p    /* Direct Page Flag */
152#define FLAG_B      m_flag_b    /* BRK Instruction Flag */
153#define FLAG_H      m_flag_h    /* Decimal Mode Flag */
154#define FLAG_I      m_flag_i    /* Interrupt Mask Flag */
155#define FLAG_C      m_flag_c    /* Carry Flag */
156#define LINE_IRQ    m_line_irq  /* Status of the IRQ line */
157#define LINE_NMI    m_line_nmi  /* Status of the NMI line */
158#define REG_IR      m_ir        /* Instruction Register */
159#define CLOCKS      m_ICount        /* Clock cycles remaining */
160#define CPU_STOPPED m_stopped   /* Stopped status */
208161
209#define SRC     cpustate->source    /* Source Operand */
210#define DST     cpustate->destination   /* Destination Operand */
211#define TMP1        cpustate->temp1 /* temporary result 1 */
212#define TMP2        cpustate->temp2 /* temporary result 2 */
213#define TMP3        cpustate->temp3 /* temporary result 3 */
162#define SRC     m_source    /* Source Operand */
163#define DST     m_destination   /* Destination Operand */
164#define TMP1        m_temp1 /* temporary result 1 */
165#define TMP2        m_temp2 /* temporary result 2 */
166#define TMP3        m_temp3 /* temporary result 3 */
214167
215168#define STOP_LEVEL_STOP     1
216169#define STOP_LEVEL_SLEEP    2
r26761r26762
247200/* ================================= MAME ================================= */
248201/* ======================================================================== */
249202
250#define spc700_read_8(addr) cpustate->program->read_byte(addr)
251#define spc700_write_8(addr,data) cpustate->program->write_byte(addr,data)
203#define spc700_read_8(addr) m_program->read_byte(addr)
204#define spc700_write_8(addr,data) m_program->write_byte(addr,data)
252205
253206#define spc700_read_8_direct(A)     spc700_read_8(A)
254207#define spc700_write_8_direct(A, V) spc700_write_8(A, V)
255//#define spc700_read_instruction(A)    memory_decrypted_read_byte(cpustate->program,A)
256//#define spc700_read_8_immediate(A)    memory_raw_read_byte(cpustate->program,A)
257#define spc700_read_instruction(A)    cpustate->program->read_byte(A)
258#define spc700_read_8_immediate(A)    cpustate->program->read_byte(A)
208//#define spc700_read_instruction(A)    memory_decrypted_read_byte(m_program,A)
209//#define spc700_read_8_immediate(A)    memory_raw_read_byte(m_program,A)
210#define spc700_read_instruction(A)    m_program->read_byte(A)
211#define spc700_read_8_immediate(A)    m_program->read_byte(A)
259212#define spc700_jumping(A)
260213#define spc700_branching(A)
261214
262215
263216
217const device_type SPC700 = &device_creator<spc700_device>;
218
219
220spc700_device::spc700_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
221   : cpu_device(mconfig, SPC700, "SPC700", tag, owner, clock, "spc700", __FILE__)
222   , m_program_config("program", ENDIANNESS_LITTLE, 8, 16, 0)
223{
224}
225
226
264227/* ======================================================================== */
265228/* ============================ UTILITY MACROS ============================ */
266229/* ======================================================================== */
r26761r26762
269232#define CLK(A) CLOCKS -= (A)
270233#define CLK_ALL() CLOCKS = 0
271234
272#define BREAKOUT break
273235
274INLINE uint read_8_normal(spc700i_cpu *cpustate, uint address)
236UINT32 spc700_device::read_8_normal(UINT32 address)
275237{
276238   address = MAKE_UINT_16(address);
277239   return spc700_read_8(address);
278240}
279241
280INLINE uint read_8_immediate(spc700i_cpu *cpustate, uint address)
242UINT32 spc700_device::read_8_immediate(UINT32 address)
281243{
282244   address = MAKE_UINT_16(address);
283245   return spc700_read_8_immediate(address);
284246}
285247
286#ifdef UNUSED_FUNCTION
287INLINE uint read_8_instruction(spc700i_cpu *cpustate, uint address)
248UINT32 spc700_device::read_8_instruction(UINT32 address)
288249{
289250   address = MAKE_UINT_16(address);
290251   return spc700_read_instruction(address);
291252}
292#endif
293253
294INLINE uint read_8_direct(spc700i_cpu *cpustate, uint address)
254UINT32 spc700_device::read_8_direct(UINT32 address)
295255{
296256   address = MAKE_UINT_8(address) | FLAG_P;
297257   return spc700_read_8_direct(address);
298258}
299259
300INLINE void write_8_normal(spc700i_cpu *cpustate, uint address, uint value)
260void spc700_device::write_8_normal(UINT32 address, UINT32 value)
301261{
302262   address = MAKE_UINT_16(address);
303263   value = MAKE_UINT_8(value);
304264   spc700_write_8(address, value);
305265}
306266
307INLINE void write_8_direct(spc700i_cpu *cpustate, uint address, uint value)
267void spc700_device::write_8_direct(UINT32 address, UINT32 value)
308268{
309269   address = MAKE_UINT_8(address) | FLAG_P;
310270   value = MAKE_UINT_8(value);
r26761r26762
312272}
313273
314274
315INLINE uint read_16_normal(spc700i_cpu *cpustate, uint address)
275UINT32 spc700_device::read_16_normal(UINT32 address)
316276{
317   return read_8_normal(cpustate, address) | (read_8_normal(cpustate, address+1)<<8);
277   return read_8_normal(address) | (read_8_normal(address+1)<<8);
318278}
319279
320INLINE uint read_16_immediate(spc700i_cpu *cpustate, uint address)
280UINT32 spc700_device::read_16_immediate(UINT32 address)
321281{
322   return read_8_immediate(cpustate, address) | (read_8_immediate(cpustate, address+1)<<8);
282   return read_8_immediate(address) | (read_8_immediate(address+1)<<8);
323283}
324284
325INLINE uint read_16_direct(spc700i_cpu *cpustate, uint address)
285UINT32 spc700_device::read_16_direct(UINT32 address)
326286{
327   return read_8_direct(cpustate, address) | (read_8_direct(cpustate, address+1)<<8);
287   return read_8_direct(address) | (read_8_direct(address+1)<<8);
328288}
329289
330INLINE void write_16_direct(spc700i_cpu *cpustate, uint address, uint value)
290void spc700_device::write_16_direct(UINT32 address, UINT32 value)
331291{
332   write_8_direct(cpustate, address, value);
333   write_8_direct(cpustate, address+1, value>>8);
292   write_8_direct(address, value);
293   write_8_direct(address+1, value>>8);
334294}
335295
336296/* Low level memory access macros */
337#define read_8_NORM(A)      read_8_normal(cpustate, A)
338#define read_8_IMM(A)       read_8_immediate(cpustate, A)
339#define read_8_ABS(A)       read_8_normal(cpustate, A)
340#define read_8_ABX(A)       read_8_normal(cpustate, A)
341#define read_8_ABY(A)       read_8_normal(cpustate, A)
342#define read_8_AXI(A)       read_8_normal(cpustate, A)
343#define read_8_DP(A)        read_8_direct(cpustate, A)
344#define read_8_DPX(A)       read_8_direct(cpustate, A)
345#define read_8_DPY(A)       read_8_direct(cpustate, A)
346#define read_8_DPI(A)       read_8_normal(cpustate, A)
347#define read_8_DXI(A)       read_8_normal(cpustate, A)
348#define read_8_DIY(A)       read_8_normal(cpustate, A)
349#define read_8_STK(A)       read_8_normal(cpustate, A)
350#define read_8_XI(A)        read_8_direct(cpustate, A)
351#define read_8_XII(A)       read_8_direct(cpustate, A)
352#define read_8_YI(A)        read_8_direct(cpustate, A)
297#define read_8_NORM(A)      read_8_normal(A)
298#define read_8_IMM(A)       read_8_immediate(A)
299#define read_8_ABS(A)       read_8_normal(A)
300#define read_8_ABX(A)       read_8_normal(A)
301#define read_8_ABY(A)       read_8_normal(A)
302#define read_8_AXI(A)       read_8_normal(A)
303#define read_8_DP(A)        read_8_direct(A)
304#define read_8_DPX(A)       read_8_direct(A)
305#define read_8_DPY(A)       read_8_direct(A)
306#define read_8_DPI(A)       read_8_normal(A)
307#define read_8_DXI(A)       read_8_normal(A)
308#define read_8_DIY(A)       read_8_normal(A)
309#define read_8_STK(A)       read_8_normal(A)
310#define read_8_XI(A)        read_8_direct(A)
311#define read_8_XII(A)       read_8_direct(A)
312#define read_8_YI(A)        read_8_direct(A)
353313
354314
355#define read_16_NORM(A)     read_16_normal(cpustate, A)
356#define read_16_IMM(A)      read_16_immediate(cpustate, A)
357#define read_16_ABS(A)      read_16_absolute(cpustate, A)
358#define read_16_ABX(A)      read_16_normal(cpustate, A)
359#define read_16_DP(A)       read_16_direct(cpustate, A)
360#define read_16_DPX(A)      read_16_direct(cpustate, A)
361#define read_16_DPY(A)      read_16_direct(cpustate, A)
362#define read_16_DPI(A)      read_16_normal(cpustate, A)
363#define read_16_VEC(A)      read_16_normal(cpustate, A)
364#define read_16_XI(A)       read_16_direct(cpustate, A)
365#define read_16_XII(A)      read_16_direct(cpustate, A)
366#define read_16_YI(A)       read_16_direct(cpustate, A)
315#define read_16_NORM(A)     read_16_normal(A)
316#define read_16_IMM(A)      read_16_immediate(A)
317#define read_16_ABS(A)      read_16_absolute(A)
318#define read_16_ABX(A)      read_16_normal(A)
319#define read_16_DP(A)       read_16_direct(A)
320#define read_16_DPX(A)      read_16_direct(A)
321#define read_16_DPY(A)      read_16_direct(A)
322#define read_16_DPI(A)      read_16_normal(A)
323#define read_16_VEC(A)      read_16_normal(A)
324#define read_16_XI(A)       read_16_direct(A)
325#define read_16_XII(A)      read_16_direct(A)
326#define read_16_YI(A)       read_16_direct(A)
367327
368#define write_8_NORM(A, V)  write_8_normal(cpustate, A, V)
369#define write_8_IMM(A, V)   write_8_normal(cpustate, A, V)
370#define write_8_ABS(A, V)   write_8_normal(cpustate, A, V)
371#define write_8_ABX(A, V)   write_8_normal(cpustate, A, V)
372#define write_8_ABY(A, V)   write_8_normal(cpustate, A, V)
373#define write_8_AXI(A, V)   write_8_normal(cpustate, A, V)
374#define write_8_DP(A, V)    write_8_direct(cpustate, A, V)
375#define write_8_DPX(A, V)   write_8_direct(cpustate, A, V)
376#define write_8_DPY(A, V)   write_8_direct(cpustate, A, V)
377#define write_8_DPI(A, V)   write_8_normal(cpustate, A, V)
378#define write_8_DXI(A, V)   write_8_normal(cpustate, A, V)
379#define write_8_DIY(A, V)   write_8_normal(cpustate, A, V)
380#define write_8_STK(A, V)   write_8_normal(cpustate, A, V)
381#define write_8_XI(A, V)    write_8_direct(cpustate, A, V)
382#define write_8_XII(A, V)   write_8_direct(cpustate, A, V)
383#define write_8_YI(A, V)    write_8_direct(cpustate, A, V)
328#define write_8_NORM(A, V)  write_8_normal(A, V)
329#define write_8_IMM(A, V)   write_8_normal(A, V)
330#define write_8_ABS(A, V)   write_8_normal(A, V)
331#define write_8_ABX(A, V)   write_8_normal(A, V)
332#define write_8_ABY(A, V)   write_8_normal(A, V)
333#define write_8_AXI(A, V)   write_8_normal(A, V)
334#define write_8_DP(A, V)    write_8_direct(A, V)
335#define write_8_DPX(A, V)   write_8_direct(A, V)
336#define write_8_DPY(A, V)   write_8_direct(A, V)
337#define write_8_DPI(A, V)   write_8_normal(A, V)
338#define write_8_DXI(A, V)   write_8_normal(A, V)
339#define write_8_DIY(A, V)   write_8_normal(A, V)
340#define write_8_STK(A, V)   write_8_normal(A, V)
341#define write_8_XI(A, V)    write_8_direct(A, V)
342#define write_8_XII(A, V)   write_8_direct(A, V)
343#define write_8_YI(A, V)    write_8_direct(A, V)
384344
385#define write_16_NORM(A, V) write_16_normal(cpustate, A, V)
386#define write_16_ABS(A, V)  write_16_normal(cpustate, A, V)
387#define write_16_ABX(A, V)  write_16_normal(cpustate, A, V)
388#define write_16_ABY(A, V)  write_16_normal(cpustate, A, V)
389#define write_16_AXI(A, V)  write_16_normal(cpustate, A, V)
390#define write_16_DP(A, V)   write_16_direct(cpustate, A, V)
391#define write_16_DPX(A, V)  write_16_direct(cpustate, A, V)
392#define write_16_DPY(A, V)  write_16_direct(cpustate, A, V)
393#define write_16_DPI(A, V)  write_16_normal(cpustate, A, V)
394#define write_16_DXI(A, V)  write_16_normal(cpustate, A, V)
395#define write_16_DIY(A, V)  write_16_normal(cpustate, A, V)
396#define write_16_STK(A, V)  write_16_normal(cpustate, A, V)
397#define write_16_XI(A, V)   write_16_direct(cpustate, A, V)
398#define write_16_XII(A, V)  write_16_direct(cpustate, A, V)
399#define write_16_YI(A, V)   write_16_direct(cpustate, A, V)
345#define write_16_NORM(A, V) write_16_normal(A, V)
346#define write_16_ABS(A, V)  write_16_normal(A, V)
347#define write_16_ABX(A, V)  write_16_normal(A, V)
348#define write_16_ABY(A, V)  write_16_normal(A, V)
349#define write_16_AXI(A, V)  write_16_normal(A, V)
350#define write_16_DP(A, V)   write_16_direct(A, V)
351#define write_16_DPX(A, V)  write_16_direct(A, V)
352#define write_16_DPY(A, V)  write_16_direct(A, V)
353#define write_16_DPI(A, V)  write_16_normal(A, V)
354#define write_16_DXI(A, V)  write_16_normal(A, V)
355#define write_16_DIY(A, V)  write_16_normal(A, V)
356#define write_16_STK(A, V)  write_16_normal(A, V)
357#define write_16_XI(A, V)   write_16_direct(A, V)
358#define write_16_XII(A, V)  write_16_direct(A, V)
359#define write_16_YI(A, V)   write_16_direct(A, V)
400360
401361
402#define OPER_8_IMM(cpustate)    read_8_IMM(EA_IMM(cpustate))
403#define OPER_8_ABS(cpustate)    read_8_ABS(EA_ABS(cpustate))
404#define OPER_8_ABX(cpustate)    read_8_ABX(EA_ABX(cpustate))
405#define OPER_8_ABY(cpustate)    read_8_ABY(EA_ABY(cpustate))
406#define OPER_8_AXI(cpustate)    read_8_IND(EA_IND(cpustate))
407#define OPER_8_DP(cpustate) read_8_DP(EA_DP(cpustate))
408#define OPER_8_DPX(cpustate)    read_8_DPX(EA_DPX(cpustate))
409#define OPER_8_DPY(cpustate)    read_8_DPY(EA_DPY(cpustate))
410#define OPER_8_DPI(cpustate)    read_8_DPI(EA_DPI(cpustate))
411#define OPER_8_DXI(cpustate)    read_8_DXI(EA_DXI(cpustate))
412#define OPER_8_DIY(cpustate)    read_8_DIY(EA_DIY(cpustate))
413#define OPER_8_XI(cpustate) read_8_XI(EA_XI(cpustate))
414#define OPER_8_XII(cpustate)    read_8_XI(EA_XII(cpustate))
415#define OPER_8_YI(cpustate) read_8_YI(EA_YI(cpustate))
362#define OPER_8_IMM()    read_8_IMM(EA_IMM())
363#define OPER_8_ABS()    read_8_ABS(EA_ABS())
364#define OPER_8_ABX()    read_8_ABX(EA_ABX())
365#define OPER_8_ABY()    read_8_ABY(EA_ABY())
366#define OPER_8_AXI()    read_8_IND(EA_IND())
367#define OPER_8_DP() read_8_DP(EA_DP())
368#define OPER_8_DPX()    read_8_DPX(EA_DPX())
369#define OPER_8_DPY()    read_8_DPY(EA_DPY())
370#define OPER_8_DPI()    read_8_DPI(EA_DPI())
371#define OPER_8_DXI()    read_8_DXI(EA_DXI())
372#define OPER_8_DIY()    read_8_DIY(EA_DIY())
373#define OPER_8_XI() read_8_XI(EA_XI())
374#define OPER_8_XII()    read_8_XI(EA_XII())
375#define OPER_8_YI() read_8_YI(EA_YI())
416376
417#define OPER_16_IMM(cpustate)   read_16_IMM(EA_IMM16(cpustate))
418#define OPER_16_ABS(cpustate)   read_16_ABS(EA_ABS(cpustate))
419#define OPER_16_ABX(cpustate)   read_16_ABX(EA_ABX(cpustate))
420#define OPER_16_ABY(cpustate)   read_16_ABY(EA_ABY(cpustate))
421#define OPER_16_AXI(cpustate)   read_16_IND(EA_IND(cpustate))
422#define OPER_16_DP(cpustate)    read_16_DP(EA_DP(cpustate))
423#define OPER_16_DPX(cpustate)   read_16_DPX(EA_DPX(cpustate))
424#define OPER_16_DPY(cpustate)   read_16_DPY(EA_DPY(cpustate))
425#define OPER_16_DPI(cpustate)   read_16_DPI(EA_DXI(cpustate))
426#define OPER_16_DXI(cpustate)   read_16_DXI(EA_DXI(cpustate))
427#define OPER_16_DIY(cpustate)   read_16_DIY(EA_DIY(cpustate))
428#define OPER_16_XI(cpustate)    read_16_XI(EA_XI(cpustate))
429#define OPER_16_XII(cpustate)   read_16_XI(EA_XII(cpustate))
430#define OPER_16_YI(cpustate)    read_16_YI(EA_YI(cpustate))
377#define OPER_16_IMM()   read_16_IMM(EA_IMM16())
378#define OPER_16_ABS()   read_16_ABS(EA_ABS())
379#define OPER_16_ABX()   read_16_ABX(EA_ABX())
380#define OPER_16_ABY()   read_16_ABY(EA_ABY())
381#define OPER_16_AXI()   read_16_IND(EA_IND())
382#define OPER_16_DP()    read_16_DP(EA_DP())
383#define OPER_16_DPX()   read_16_DPX(EA_DPX())
384#define OPER_16_DPY()   read_16_DPY(EA_DPY())
385#define OPER_16_DPI()   read_16_DPI(EA_DXI())
386#define OPER_16_DXI()   read_16_DXI(EA_DXI())
387#define OPER_16_DIY()   read_16_DIY(EA_DIY())
388#define OPER_16_XI()    read_16_XI(EA_XI())
389#define OPER_16_XII()   read_16_XI(EA_XII())
390#define OPER_16_YI()    read_16_YI(EA_YI())
431391
432392/* Effective Address Calculations */
433INLINE uint EA_IMM(spc700i_cpu *cpustate)   {return REG_PC++;}
434INLINE uint EA_IMM16(spc700i_cpu *cpustate) {REG_PC += 2; return REG_PC-2;}
435INLINE uint EA_ABS(spc700i_cpu *cpustate)   {return OPER_16_IMM(cpustate);}
436INLINE uint EA_ABX(spc700i_cpu *cpustate)   {return EA_ABS(cpustate) + REG_X;}
437INLINE uint EA_ABY(spc700i_cpu *cpustate)   {return EA_ABS(cpustate) + REG_Y;}
438INLINE uint EA_AXI(spc700i_cpu *cpustate)   {return OPER_16_ABX(cpustate);}
439INLINE uint EA_DP(spc700i_cpu *cpustate)   {return OPER_8_IMM(cpustate);}
440INLINE uint EA_DPX(spc700i_cpu *cpustate)   {return (EA_DP(cpustate) + REG_X)&0xff;}
441INLINE uint EA_DPY(spc700i_cpu *cpustate)   {return (EA_DP(cpustate) + REG_Y)&0xff;}
442INLINE uint EA_DXI(spc700i_cpu *cpustate)   {return OPER_16_DPX(cpustate);}
443INLINE uint EA_DIY(spc700i_cpu *cpustate)   {uint addr = OPER_16_DP(cpustate); if((addr&0xff00) != ((addr+REG_Y)&0xff00)) CLK(1); return addr + REG_Y;}
444INLINE uint EA_XI(spc700i_cpu *cpustate)    {return REG_X;}
445INLINE uint EA_XII(spc700i_cpu *cpustate)   {uint val = REG_X;REG_X = MAKE_UINT_8(REG_X+1);return val;}
446INLINE uint EA_YI(spc700i_cpu *cpustate)    {return REG_Y;}
393UINT32 spc700_device::EA_IMM()   {return REG_PC++;}
394UINT32 spc700_device::EA_IMM16() {REG_PC += 2; return REG_PC-2;}
395UINT32 spc700_device::EA_ABS()   {return OPER_16_IMM();}
396UINT32 spc700_device::EA_ABX()   {return EA_ABS() + REG_X;}
397UINT32 spc700_device::EA_ABY()   {return EA_ABS() + REG_Y;}
398UINT32 spc700_device::EA_AXI()   {return OPER_16_ABX();}
399UINT32 spc700_device::EA_DP()   {return OPER_8_IMM();}
400UINT32 spc700_device::EA_DPX()   {return (EA_DP() + REG_X)&0xff;}
401UINT32 spc700_device::EA_DPY()   {return (EA_DP() + REG_Y)&0xff;}
402UINT32 spc700_device::EA_DXI()   {return OPER_16_DPX();}
403UINT32 spc700_device::EA_DIY()   {UINT32 addr = OPER_16_DP(); if((addr&0xff00) != ((addr+REG_Y)&0xff00)) CLK(1); return addr + REG_Y;}
404UINT32 spc700_device::EA_XI()    {return REG_X;}
405UINT32 spc700_device::EA_XII()   {UINT32 val = REG_X;REG_X = MAKE_UINT_8(REG_X+1);return val;}
406UINT32 spc700_device::EA_YI()    {return REG_Y;}
447407
448408
449409
450410/* Change the Program Counter */
451INLINE void JUMP(spc700i_cpu *cpustate, uint address)
411void spc700_device::JUMP(UINT32 address)
452412{
453413   REG_PC = address;
454414   spc700_jumping(REG_PC);
455415}
456416
457INLINE void BRANCH(spc700i_cpu *cpustate, uint offset)
417void spc700_device::BRANCH(UINT32 offset)
458418{
459419   REG_PC = MAKE_UINT_16(REG_PC + MAKE_INT_8(offset));
460420   spc700_branching(REG_PC);
r26761r26762
463423
464424#define GET_REG_YA() (REG_A | (REG_Y<<8))
465425
466INLINE void SET_REG_YA(spc700i_cpu *cpustate, uint value)
426void spc700_device::SET_REG_YA(UINT32 value)
467427{
468428   REG_A = MAKE_UINT_8(value);
469429   REG_Y = MAKE_UINT_8(value>>8);
r26761r26762
480440   ((!FLAG_Z) << 1)        |   \
481441   CFLAG_AS_1())
482442
483INLINE void SET_FLAG_I(spc700i_cpu *cpustate, uint value);
484
485443/* Set the Process Status Register */
486INLINE void SET_REG_P(spc700i_cpu *cpustate, uint value)
444void spc700_device::SET_REG_P(UINT32 value)
487445{
488446   FLAG_N = (value & 0x80);
489447   FLAG_Z = !(value & 2);
r26761r26762
492450   FLAG_B = value & FLAGPOS_B;
493451   FLAG_H = value & HFLAG_SET;
494452   FLAG_C = value << 8;
495   SET_FLAG_I(cpustate, value);
453   SET_FLAG_I(value);
496454}
497455
498456/* Push/Pull data to/from the stack */
499INLINE void PUSH_8(spc700i_cpu *cpustate, uint value)
457void spc700_device::PUSH_8(UINT32 value)
500458{
501459   write_8_STK(REG_S+STACK_PAGE, value);
502460   REG_S = MAKE_UINT_8(REG_S - 1);
503461}
504462
505INLINE uint PULL_8(spc700i_cpu *cpustate)
463UINT32 spc700_device::PULL_8()
506464{
507465   REG_S = MAKE_UINT_8(REG_S + 1);
508466   return read_8_STK(REG_S+STACK_PAGE);
509467}
510468
511INLINE void PUSH_16(spc700i_cpu *cpustate, uint value)
469void spc700_device::PUSH_16(UINT32 value)
512470{
513   PUSH_8(cpustate, value>>8);
514   PUSH_8(cpustate, value);
471   PUSH_8(value>>8);
472   PUSH_8(value);
515473}
516474
517INLINE uint PULL_16(spc700i_cpu *cpustate)
475UINT32 spc700_device::PULL_16()
518476{
519   uint value = PULL_8(cpustate);
520   return value | (PULL_8(cpustate)<<8);
477   UINT32 value = PULL_8();
478   return value | (PULL_8()<<8);
521479}
522480
523#if !SPC700_OPTIMIZE_SNES
524INLINE void CHECK_IRQ(spc700i_cpu *cpustate)
481void spc700_device::CHECK_IRQ()
525482{
526483   if(FLAG_I & LINE_IRQ)
527484      SERVICE_IRQ();
528485}
529#endif /* SPC700_OPTIMIZE_SNES */
530486
531INLINE void SET_FLAG_I(spc700i_cpu *cpustate, uint value)
487void spc700_device::SERVICE_IRQ()
532488{
489   fatalerror("spc700: SERVICE_IRQ() not implemented yet!\n");
490}
491
492
493void spc700_device::SET_FLAG_I(UINT32 value)
494{
533495   FLAG_I = value & IFLAG_SET;
534496#if !SPC700_OPTIMIZE_SNES
535   CHECK_IRQ(cpustate);
497   CHECK_IRQ();
536498#endif
537499}
538500
r26761r26762
541503/* ======================================================================== */
542504
543505#define SUBOP_ADC(A, B)                     \
544   cpustate->spc_int16 = (A) + (B) + CFLAG_AS_1();         \
506   m_spc_int16 = (A) + (B) + CFLAG_AS_1();         \
545507   TMP1 = ((A) & 0x0f) + (CFLAG_AS_1());           \
546   FLAG_C  = (cpustate->spc_int16 > 0xff) ? CFLAG_SET : 0;     \
547   FLAG_V =  (~((A) ^ (B))) & (((A) ^ cpustate->spc_int16) & 0x80); \
548   FLAG_H = (((cpustate->spc_int16 & 0x0f) - TMP1) & 0x10) >> 1;   \
549   FLAG_NZ = (UINT8)cpustate->spc_int16
508   FLAG_C  = (m_spc_int16 > 0xff) ? CFLAG_SET : 0;     \
509   FLAG_V =  (~((A) ^ (B))) & (((A) ^ m_spc_int16) & 0x80); \
510   FLAG_H = (((m_spc_int16 & 0x0f) - TMP1) & 0x10) >> 1;   \
511   FLAG_NZ = (UINT8)m_spc_int16
550512
551513
552514/* Add With Carry */
553515#define OP_ADC(BCLK, MODE)                  \
554516         CLK(BCLK);              \
555         SRC     = OPER_8_##MODE(cpustate);      \
517         SRC     = OPER_8_##MODE();      \
556518         SUBOP_ADC(SRC, REG_A);          \
557         REG_A = (UINT8)cpustate->spc_int16;
519         REG_A = (UINT8)m_spc_int16;
558520
559521
560522/* Add With Carry to memory */
561523#define OP_ADCM(BCLK, SMODE, DMODE)             \
562524         CLK(BCLK);              \
563         SRC     = OPER_8_##SMODE(cpustate);     \
564         DST     = EA_##DMODE(cpustate);         \
525         SRC     = OPER_8_##SMODE();     \
526         DST     = EA_##DMODE();         \
565527         SUBOP_ADC(SRC, read_8_##DMODE(DST));    \
566         write_8_##DMODE(DST, (UINT8)cpustate->spc_int16)
528         write_8_##DMODE(DST, (UINT8)m_spc_int16)
567529
568530/* Add word */
569531#define OP_ADDW(BCLK)                       \
570532         CLK(BCLK);              \
571         SRC = OPER_16_DP(cpustate);         \
533         SRC = OPER_16_DP();         \
572534         DST = GET_REG_YA();         \
573535         TMP1 = ((SRC) & 0xff) + ((DST) & 0xff); \
574536         TMP2 = (TMP1 > 0xff) ? 1 : 0;       \
575537         TMP3 = ((SRC) >> 8) + ((DST) >> 8) + TMP2;  \
576         cpustate->spc_int16 = ((TMP1 & 0xff) + (TMP3 << 8)) & 0xffff;   \
538         m_spc_int16 = ((TMP1 & 0xff) + (TMP3 << 8)) & 0xffff;   \
577539         FLAG_C = (TMP3 > 0xff) ? CFLAG_SET : 0; \
578540         FLAG_H = ((unsigned) ((((DST) >> 8) & 0x0F) + \
579541            (((SRC) >> 8) & 0x0F) + TMP2)) > 0x0F ? HFLAG_SET : 0; \
580         FLAG_V = (~((DST) ^ (SRC)) & ((SRC) ^ (UINT16) cpustate->spc_int16) & 0x8000) ? VFLAG_SET : 0; \
581         FLAG_Z = (cpustate->spc_int16 != 0);        \
582         FLAG_N = (cpustate->spc_int16>>8);      \
583         SET_REG_YA(cpustate, cpustate->spc_int16);
542         FLAG_V = (~((DST) ^ (SRC)) & ((SRC) ^ (UINT16) m_spc_int16) & 0x8000) ? VFLAG_SET : 0; \
543         FLAG_Z = (m_spc_int16 != 0);        \
544         FLAG_N = (m_spc_int16>>8);      \
545         SET_REG_YA(m_spc_int16);
584546
585547/* Logical AND with accumulator */
586548#define OP_AND(BCLK, MODE)                                                  \
587549         CLK(BCLK);                                                      \
588         FLAG_NZ = REG_A &= OPER_8_##MODE(cpustate)
550         FLAG_NZ = REG_A &= OPER_8_##MODE()
589551
590552/* Logical AND operand */
591553#define OP_ANDM(BCLK, SMODE, DMODE)                                         \
592554         CLK(BCLK);                                                      \
593         FLAG_NZ = OPER_8_##SMODE(cpustate);                                     \
594         DST     = EA_##DMODE(cpustate);                                         \
555         FLAG_NZ = OPER_8_##SMODE();                                     \
556         DST     = EA_##DMODE();                                         \
595557         FLAG_NZ &= read_8_##DMODE(DST);                                 \
596558         write_8_##DMODE(DST, FLAG_NZ)
597559
598560/* Logical AND bit to C */
599561#define OP_AND1(BCLK)                                                       \
600562         CLK(BCLK);                                                      \
601         DST = EA_IMM16(cpustate);                                               \
563         DST = EA_IMM16();                                               \
602564         if(FLAG_C & CFLAG_SET)                                          \
603565         {                                                               \
604566            DST = read_16_IMM(DST);                                     \
r26761r26762
611573/* AND negated bit to C */
612574#define OP_ANDN1(BCLK)                                                      \
613575         CLK(BCLK);                                                      \
614         DST = EA_IMM16(cpustate);                                               \
576         DST = EA_IMM16();                                               \
615577         if(FLAG_C & CFLAG_SET)                                          \
616578         {                                                               \
617579            DST = read_16_IMM(DST);                                     \
r26761r26762
630592/* Arithmetic Shift Left operand */
631593#define OP_ASLM(BCLK, MODE)                                                 \
632594         CLK(BCLK);                                                      \
633         DST     = EA_##MODE(cpustate);                                          \
595         DST     = EA_##MODE();                                          \
634596         FLAG_C  = read_8_##MODE(DST) << 1;                              \
635597         FLAG_NZ = MAKE_UINT_8(FLAG_C);                                  \
636598         write_8_##MODE(DST, FLAG_NZ)
r26761r26762
638600/* Branch if Bit Reset */
639601#define OP_BBC(BCLK, BIT)                                                   \
640602         CLK(BCLK);                                                      \
641         SRC     = OPER_8_DP(cpustate);                                          \
642         DST     = OPER_8_IMM(cpustate);                                         \
603         SRC     = OPER_8_DP();                                          \
604         DST     = OPER_8_IMM();                                         \
643605         if(!(SRC & BIT))                                                \
644606         {                                                               \
645607            CLK(2);                                                     \
646            BRANCH(cpustate, DST);                                              \
608            BRANCH(DST);                                              \
647609         }
648610
649611/* Branch if Bit Set */
650612#define OP_BBS(BCLK, BIT)                                                   \
651613         CLK(BCLK);                                                      \
652         SRC     = OPER_8_DP(cpustate);                                          \
653         DST     = OPER_8_IMM(cpustate);                                         \
614         SRC     = OPER_8_DP();                                          \
615         DST     = OPER_8_IMM();                                         \
654616         if(SRC & BIT)                                                   \
655617         {                                                               \
656618            CLK(2);                                                     \
657            BRANCH(cpustate, DST);                                              \
619            BRANCH(DST);                                              \
658620         }
659621
660622/* Branch on Condition Code */
661623#define OP_BCC(BCLK, COND)                                                  \
662624         CLK(BCLK);                                                      \
663         DST     = OPER_8_IMM(cpustate);                                         \
625         DST     = OPER_8_IMM();                                         \
664626         if(COND)                                                        \
665627         {                                                               \
666628            CLK(2);                                                     \
667            BRANCH(cpustate, DST);                                              \
629            BRANCH(DST);                                              \
668630         }
669631
670632/* Branch Unconditional */
671633/* speed up busy loops */
672634#define OP_BRA(BCLK)                                                        \
673635         CLK(BCLK);                                                      \
674         BRANCH(cpustate, OPER_8_IMM(cpustate));                                         \
636         BRANCH(OPER_8_IMM());                                         \
675637         if(REG_PC == REG_PPC)                                           \
676638            CLK_ALL()
677639
678640/* Cause a Break interrupt */
679641#define OP_BRK(BCLK)                                                        \
680642         CLK(BCLK);                                                      \
681         PUSH_16(cpustate, REG_PC);                                              \
682         PUSH_8(cpustate, GET_REG_P());                                      \
643         PUSH_16(REG_PC);                                              \
644         PUSH_8(GET_REG_P());                                      \
683645         FLAG_B |= FLAGPOS_B;                                                \
684646         FLAG_I = IFLAG_CLEAR;                                               \
685         JUMP(cpustate, read_16_VEC(VECTOR_BRK))
647         JUMP(read_16_VEC(VECTOR_BRK))
686648
687649/* Call subroutine */
688650#define OP_CALL(BCLK)                                                       \
689651         CLK(BCLK);                                                      \
690         DST     = EA_ABS(cpustate);                                             \
691         PUSH_16(cpustate, REG_PC);                                              \
692         JUMP(cpustate, DST)
652         DST     = EA_ABS();                                             \
653         PUSH_16(REG_PC);                                              \
654         JUMP(DST)
693655
694656/* Compare accumulator and branch if not equal */
695657#define OP_CBNE(BCLK, MODE)                                                 \
696658         CLK(BCLK);                                                      \
697         SRC     = OPER_8_##MODE(cpustate);                                      \
698         DST     = EA_IMM(cpustate);                                             \
659         SRC     = OPER_8_##MODE();                                      \
660         DST     = EA_IMM();                                             \
699661         if(SRC != REG_A)                                                \
700662         {                                                               \
701663            CLK(2);                                                     \
702            BRANCH(cpustate, read_8_IMM(DST));                                  \
664            BRANCH(read_8_IMM(DST));                                  \
703665         }
704666
705667/* Clear Carry flag */
r26761r26762
710672/* Clear Memory Bit */
711673#define OP_CLR(BCLK, BIT)                                                   \
712674         CLK(BCLK);                                                      \
713         DST     = EA_DP(cpustate);                                              \
675         DST     = EA_DP();                                              \
714676         SRC     = read_8_DP(DST) & ~BIT;                                \
715677         write_8_DP(DST, SRC)
716678
r26761r26762
728690/* Compare operand to register */
729691#define OP_CMPR(BCLK, REG, MODE)                                            \
730692         CLK(BCLK);              \
731         SRC     = OPER_8_##MODE(cpustate);      \
732         cpustate->spc_int16 = (short)REG - (short)SRC;  \
733         FLAG_C  = (cpustate->spc_int16 >= 0) ? CFLAG_SET : 0;   \
734         FLAG_NZ = MAKE_UINT_8(cpustate->spc_int16);
693         SRC     = OPER_8_##MODE();      \
694         m_spc_int16 = (short)REG - (short)SRC;  \
695         FLAG_C  = (m_spc_int16 >= 0) ? CFLAG_SET : 0;   \
696         FLAG_NZ = MAKE_UINT_8(m_spc_int16);
735697
736698/* Compare memory */
737699#define OP_CMPM(BCLK, SMODE, DMODE)                                         \
738700         CLK(BCLK);              \
739         SRC     = OPER_8_##SMODE(cpustate);     \
740         cpustate->spc_int16 = (short)OPER_8_##DMODE(cpustate) - (short)SRC; \
741         FLAG_C  = (cpustate->spc_int16 >= 0) ? CFLAG_SET : 0;    \
742         FLAG_NZ = MAKE_UINT_8(cpustate->spc_int16);
701         SRC     = OPER_8_##SMODE();     \
702         m_spc_int16 = (short)OPER_8_##DMODE() - (short)SRC; \
703         FLAG_C  = (m_spc_int16 >= 0) ? CFLAG_SET : 0;    \
704         FLAG_NZ = MAKE_UINT_8(m_spc_int16);
743705
744706/* Compare word */
745707#define OP_CMPW(BCLK, MODE)                                                 \
746708         CLK(BCLK);                                                      \
747         SRC     = OPER_16_##MODE(cpustate);                                     \
748         cpustate->spc_int32 = (int)GET_REG_YA() - (int)SRC;                             \
749         FLAG_C  = (cpustate->spc_int32 >= 0) ? CFLAG_SET : 0;                                   \
750         FLAG_NZ = NZFLAG_16(cpustate->spc_int32);
709         SRC     = OPER_16_##MODE();                                     \
710         m_spc_int32 = (int)GET_REG_YA() - (int)SRC;                             \
711         FLAG_C  = (m_spc_int32 >= 0) ? CFLAG_SET : 0;                                   \
712         FLAG_NZ = NZFLAG_16(m_spc_int32);
751713
752714/* Decimal adjust for addition */
753715#define OP_DAA(BCLK)                    \
r26761r26762
788750#define OP_DBNZR(BCLK)                                                      \
789751         CLK(BCLK);                                                      \
790752         REG_Y  = MAKE_UINT_8(REG_Y - 1);                                \
791         DST    = EA_IMM(cpustate);                                              \
753         DST    = EA_IMM();                                              \
792754         if(REG_Y != 0)                                                  \
793755         {                                                               \
794756            CLK(2);                                                     \
795            BRANCH(cpustate, read_8_IMM(DST));                                  \
757            BRANCH(read_8_IMM(DST));                                  \
796758         }
797759
798760/* Decrement operand and branch if not zero */
799761/* Speed up busy loops but do reads/writes for compatibility */
800762#define OP_DBNZM(BCLK)                                                      \
801763         CLK(BCLK);                                                      \
802         DST     = EA_DP(cpustate);                                              \
764         DST     = EA_DP();                                              \
803765         SRC     = MAKE_UINT_8(read_8_DP(DST) - 1);                      \
804766         write_8_DP(DST, SRC);                                           \
805         DST = EA_IMM(cpustate);                                                 \
767         DST = EA_IMM();                                                 \
806768         if(SRC != 0)                                                    \
807769         {                                                               \
808770            CLK(2);                                                     \
809            BRANCH(cpustate, read_8_IMM(DST));                                  \
771            BRANCH(read_8_IMM(DST));                                  \
810772         }
811773
812774/* Decrement register */
r26761r26762
817779/* Decrement operand */
818780#define OP_DECM(BCLK, MODE)                                                 \
819781         CLK(BCLK);                                                      \
820         DST     = EA_##MODE(cpustate);                                          \
782         DST     = EA_##MODE();                                          \
821783         FLAG_NZ = MAKE_UINT_8(read_8_##MODE(DST) - 1);                  \
822784         write_8_##MODE(DST, FLAG_NZ)
823785
824786/* Decrement word */
825787#define OP_DECW(BCLK)                                                       \
826788         CLK(BCLK);                                                      \
827         DST     = EA_DP(cpustate);                                              \
789         DST     = EA_DP();                                              \
828790         FLAG_NZ = MAKE_UINT_16(read_16_DP(DST) - 1);                    \
829791         write_16_DP(DST, FLAG_Z);                                       \
830792         FLAG_NZ = NZFLAG_16(FLAG_Z)
r26761r26762
849811            if (TMP1 & 1) TMP1 = ((TMP1 - TMP2) & 0x1ffff); \
850812         }           \
851813         FLAG_V = (TMP1 & 0x100) ? VFLAG_SET : 0;    \
852         SET_REG_YA(cpustate, (((TMP1 >> 9) & 0xff) << 8) + (TMP1 & 0xff));  \
814         SET_REG_YA((((TMP1 >> 9) & 0xff) << 8) + (TMP1 & 0xff));  \
853815         FLAG_NZ = MAKE_UINT_8(GET_REG_YA());
854816
855817/* Enable interrupts */
r26761r26762
860822/* Exclusive Or operand to accumulator */
861823#define OP_EOR(BCLK, MODE)                                                  \
862824         CLK(BCLK);                                                      \
863         FLAG_NZ = REG_A ^= OPER_8_##MODE(cpustate)
825         FLAG_NZ = REG_A ^= OPER_8_##MODE()
864826
865827/* Logical EOR operand */
866828#define OP_EORM(BCLK, SMODE, DMODE)                                         \
867829         CLK(BCLK);                                                      \
868         FLAG_NZ = OPER_8_##SMODE(cpustate);                                     \
869         DST     = EA_##DMODE(cpustate);                                         \
830         FLAG_NZ = OPER_8_##SMODE();                                     \
831         DST     = EA_##DMODE();                                         \
870832         FLAG_NZ ^= read_8_##DMODE(DST);                                 \
871833         write_8_##DMODE(DST, FLAG_NZ)
872834
873835/* Exclusive OR bit to C */
874836#define OP_EOR1(BCLK)                                                       \
875837         CLK(BCLK);                                                      \
876         DST     = OPER_16_IMM(cpustate);                                        \
838         DST     = OPER_16_IMM();                                        \
877839         SRC     = 1 << (DST >> 13);                                     \
878840         DST     &= 0x1fff;                                              \
879841         if(read_8_NORM(DST) & SRC)                                      \
r26761r26762
887849/* Increment operand */
888850#define OP_INCM(BCLK, MODE)                                                 \
889851         CLK(BCLK);                                                      \
890         DST     = EA_##MODE(cpustate);                                          \
852         DST     = EA_##MODE();                                          \
891853         FLAG_NZ = MAKE_UINT_8(read_8_##MODE(DST) + 1);                  \
892854         write_8_##MODE(DST, FLAG_NZ)
893855
894856/* Increment word */
895857#define OP_INCW(BCLK)                                                       \
896858         CLK(BCLK);                                                      \
897         DST     = EA_DP(cpustate);                                              \
859         DST     = EA_DP();                                              \
898860         FLAG_NZ = MAKE_UINT_16(read_16_DP(DST) + 1);                    \
899861         write_16_DP(DST, FLAG_Z);                                       \
900862         FLAG_NZ = NZFLAG_16(FLAG_Z)
r26761r26762
903865/* If we're in a busy loop, eat all clock cycles */
904866#define OP_JMP(BCLK, MODE)                                                  \
905867         CLK(BCLK);                                                      \
906         JUMP(cpustate, EA_##MODE(cpustate));                                                \
868         JUMP(EA_##MODE());                                                \
907869         if(REG_PC == REG_PPC)                                           \
908870            CLK_ALL()
909871
910872/* Jump to Subroutine */
911873#define OP_JSR(BCLK, MODE)                                                  \
912874         CLK(BCLK);                                                      \
913         PUSH_16(cpustate, REG_PC);                                              \
914         JUMP(cpustate, EA_##MODE(cpustate))
875         PUSH_16(REG_PC);                                              \
876         JUMP(EA_##MODE())
915877
916878/* Logical Shift Right accumulator */
917879#define OP_LSR(BCLK)                                                        \
r26761r26762
922884/* Logical Shift Right operand */
923885#define OP_LSRM(BCLK, MODE)                                                 \
924886         CLK(BCLK);                                                      \
925         DST     = EA_##MODE(cpustate);                                          \
887         DST     = EA_##MODE();                                          \
926888         FLAG_NZ = read_8_##MODE(DST);                                   \
927889         FLAG_C  = FLAG_NZ << 8;                                         \
928890         FLAG_NZ >>= 1;                                                  \
r26761r26762
936898/* Move from register to memory */
937899#define OP_MOVRM(BCLK, SREG, DMODE)                                         \
938900         CLK(BCLK);                                                      \
939         write_8_##DMODE(EA_##DMODE(cpustate), SREG)
901         write_8_##DMODE(EA_##DMODE(), SREG)
940902
941903/* Move from memory to register */
942904#define OP_MOVMR(BCLK, SMODE, DREG)                                         \
943905         CLK(BCLK);                                                      \
944         FLAG_NZ = DREG = OPER_8_##SMODE(cpustate)
906         FLAG_NZ = DREG = OPER_8_##SMODE()
945907
946908/* Move from memory to memory */
947909#define OP_MOVMM(BCLK, SMODE, DMODE)                                        \
948910         CLK(BCLK);                                                      \
949         SRC     = OPER_8_##SMODE(cpustate);                                     \
950         DST     = EA_##DMODE(cpustate);                                         \
911         SRC     = OPER_8_##SMODE();                                     \
912         DST     = EA_##DMODE();                                         \
951913         write_8_##DMODE(DST, SRC)
952914
953915/* Move word register to memory */
954916#define OP_MOVWRM(BCLK)                                                     \
955917         CLK(BCLK);                                                      \
956         write_16_DP(EA_DP(cpustate), GET_REG_YA())
918         write_16_DP(EA_DP(), GET_REG_YA())
957919
958920/* Move word memory to register */
959921#define OP_MOVWMR(BCLK)                                                     \
960922         CLK(BCLK);                                                      \
961         FLAG_NZ = OPER_16_DP(cpustate);                                         \
962         SET_REG_YA(cpustate, FLAG_Z);                                           \
923         FLAG_NZ = OPER_16_DP();                                         \
924         SET_REG_YA(FLAG_Z);                                           \
963925         FLAG_NZ = NZFLAG_16(FLAG_Z)
964926
965927/* Move from Stack pointer to X */
r26761r26762
975937/* Move bit from memory to C */
976938#define OP_MOV1C(BCLK)                                                      \
977939         CLK(BCLK);                                                      \
978         DST     = OPER_16_IMM(cpustate);                                        \
940         DST     = OPER_16_IMM();                                        \
979941         SRC     = 1 << (DST >> 13);                                     \
980942         DST     &= 0x1fff;                                              \
981943         FLAG_C  = ((read_8_NORM(DST) & SRC) != 0) << 8
r26761r26762
983945/* Move bit from C to memory */
984946#define OP_MOV1M(BCLK)                                                      \
985947         CLK(BCLK);                                                      \
986         DST     = OPER_16_IMM(cpustate);                                        \
948         DST     = OPER_16_IMM();                                        \
987949         SRC     = 1 << (DST >> 13);                                     \
988950         DST     &= 0x1fff;                                              \
989951         if(FLAG_C & CFLAG_SET)                                          \
r26761r26762
1011973/* NOT bit */
1012974#define OP_NOT1(BCLK)                                                       \
1013975         CLK(BCLK);                                                      \
1014         DST     = OPER_16_IMM(cpustate);                                        \
976         DST     = OPER_16_IMM();                                        \
1015977         SRC     = 1 << (DST >> 13);                                     \
1016978         DST     &= 0x1fff;                                              \
1017979         write_8_NORM(DST, read_8_NORM(DST) ^ SRC)
r26761r26762
1019981/* Logical OR operand to accumulator */
1020982#define OP_OR(BCLK, MODE)                                                   \
1021983         CLK(BCLK);                                                      \
1022         FLAG_NZ = REG_A |= OPER_8_##MODE(cpustate)
984         FLAG_NZ = REG_A |= OPER_8_##MODE()
1023985
1024986/* Logical OR operand */
1025987#define OP_ORM(BCLK, SMODE, DMODE)                                          \
1026988         CLK(BCLK);                                                      \
1027         FLAG_NZ = OPER_8_##SMODE(cpustate);                                     \
1028         DST     = EA_##DMODE(cpustate);                                         \
989         FLAG_NZ = OPER_8_##SMODE();                                     \
990         DST     = EA_##DMODE();                                         \
1029991         FLAG_NZ |= read_8_##DMODE(DST);                                 \
1030992         write_8_##DMODE(DST, FLAG_NZ)
1031993
1032994/* Logical OR bit to C */
1033995#define OP_OR1(BCLK)                                                        \
1034996         CLK(BCLK);                                                      \
1035         DST = EA_IMM16(cpustate);                                               \
997         DST = EA_IMM16();                                               \
1036998         if(!(FLAG_C & CFLAG_SET))                                       \
1037999         {                                                               \
10381000            DST = read_16_IMM(DST);                                     \
r26761r26762
10451007/* OR negated bit to C */
10461008#define OP_ORN1(BCLK)                                                       \
10471009         CLK(BCLK);                                                      \
1048         DST = EA_IMM16(cpustate);                                               \
1010         DST = EA_IMM16();                                               \
10491011         if(!(FLAG_C & CFLAG_SET))                                       \
10501012         {                                                               \
10511013            DST = read_16_IMM(DST);                                     \
r26761r26762
10581020/* UPage Call */
10591021#define OP_PCALL(BCLK)                                                      \
10601022         CLK(BCLK);                                                      \
1061         DST     = EA_DP(cpustate);                                              \
1062         PUSH_16(cpustate, REG_PC);                                              \
1063         JUMP(cpustate, 0xff00 | DST)
1023         DST     = EA_DP();                                              \
1024         PUSH_16(REG_PC);                                              \
1025         JUMP(0xff00 | DST)
10641026
10651027/* Push a register to the stack */
10661028#define OP_PUSH(BCLK, REG)                                                  \
10671029         CLK(BCLK);                                                      \
1068         PUSH_8(cpustate, REG)
1030         PUSH_8(REG)
10691031
10701032/* Push the Processor Status Register to the stack */
10711033#define OP_PHP(BCLK)                                                        \
10721034         CLK(BCLK);                                                      \
1073         PUSH_8(cpustate, GET_REG_P())
1035         PUSH_8(GET_REG_P())
10741036
10751037/* Pull a register from the stack */
10761038#define OP_PULL(BCLK, REG)                                                  \
10771039         CLK(BCLK);                                                      \
1078         REG     = PULL_8(cpustate)
1040         REG     = PULL_8()
10791041
10801042/* Pull the Processor Status Register from the stack */
10811043#define OP_PLP(BCLK)                                                        \
10821044         CLK(BCLK);                                                      \
1083         SET_REG_P(cpustate, PULL_8(cpustate))
1045         SET_REG_P(PULL_8())
10841046
10851047/* Return from Subroutine */
10861048#define OP_RET(BCLK)                                                        \
10871049         CLK(BCLK);                                                      \
1088         JUMP(cpustate, PULL_16(cpustate))
1050         JUMP(PULL_16())
10891051
10901052/* Return from Interrupt */
10911053#define OP_RETI(BCLK)                                                       \
10921054         CLK(BCLK);                                                      \
1093         SET_REG_P(cpustate, PULL_8(cpustate));                                          \
1094         JUMP(cpustate, PULL_16(cpustate))
1055         SET_REG_P(PULL_8());                                          \
1056         JUMP(PULL_16())
10951057
10961058/* Rotate Left the accumulator */
10971059#define OP_ROL(BCLK)                                                        \
r26761r26762
11021064/* Rotate Left an operand */
11031065#define OP_ROLM(BCLK, MODE)                                                 \
11041066         CLK(BCLK);                                                      \
1105         DST     = EA_##MODE(cpustate);                                          \
1067         DST     = EA_##MODE();                                          \
11061068         FLAG_C  = (read_8_##MODE(DST)<<1) | CFLAG_AS_1();               \
11071069         FLAG_NZ = MAKE_UINT_8(FLAG_C);                                  \
11081070         write_8_##MODE(DST, FLAG_NZ)
r26761r26762
11171079/* Rotate Right an operand */
11181080#define OP_RORM(BCLK, MODE)                                                 \
11191081         CLK(BCLK);                                                      \
1120         DST     = EA_##MODE(cpustate);                                          \
1082         DST     = EA_##MODE();                                          \
11211083         FLAG_NZ = read_8_##MODE(DST) | (FLAG_C & 0x100);                \
11221084         FLAG_C  = FLAG_NZ << 8;                                         \
11231085         FLAG_NZ >>= 1;                                                  \
r26761r26762
11261088/* Subtract with Carry */
11271089#define OP_SBC(BCLK, MODE)                  \
11281090         CLK(BCLK);              \
1129         SRC     = OPER_8_##MODE(cpustate);      \
1091         SRC     = OPER_8_##MODE();      \
11301092         TMP2 = REG_A - SRC - (CFLAG_AS_1() ^ 1); \
11311093         SUBOP_ADC(REG_A, ~SRC);         \
11321094         FLAG_C = (TMP2 <= 0xff) ? CFLAG_SET : 0; \
1133         REG_A = (UINT8)cpustate->spc_int16;
1095         REG_A = (UINT8)m_spc_int16;
11341096
11351097/* Subtract With Carry to memory */
11361098#define OP_SBCM(BCLK, SMODE, DMODE)             \
11371099         CLK(BCLK);              \
1138         SRC     = OPER_8_##SMODE(cpustate);     \
1139         DST     = EA_##DMODE(cpustate);         \
1100         SRC     = OPER_8_##SMODE();     \
1101         DST     = EA_##DMODE();         \
11401102         TMP3 = read_8_##DMODE(DST);     \
11411103         TMP2 = TMP3 - SRC - (CFLAG_AS_1() ^ 1); \
11421104         SUBOP_ADC(~SRC, TMP3);          \
11431105         FLAG_C = (TMP2 <= 0xff) ? CFLAG_SET : 0; \
1144         write_8_##DMODE(DST, (UINT8)cpustate->spc_int16)
1106         write_8_##DMODE(DST, (UINT8)m_spc_int16)
11451107
11461108/* Set Carry flag */
11471109#define OP_SETC(BCLK)                                                       \
r26761r26762
11561118/* Set Memory Bit */
11571119#define OP_SET(BCLK, BIT)                                                   \
11581120         CLK(BCLK);                                                      \
1159         DST    = EA_DP(cpustate);                                               \
1121         DST    = EA_DP();                                               \
11601122         SRC    = read_8_DP(DST) | BIT;                                  \
11611123         write_8_DP(DST, SRC)
11621124
r26761r26762
11751137/* Subtract word */
11761138#define OP_SUBW(BCLK)                       \
11771139         CLK(BCLK);              \
1178         SRC = OPER_16_DP(cpustate);         \
1140         SRC = OPER_16_DP();         \
11791141         DST = GET_REG_YA();         \
11801142         TMP1 = ((DST) & 0xff) - ((SRC) & 0xff); \
11811143         TMP2 = (TMP1 > 0xff) ? 1 : 0;       \
11821144         TMP3 = ((DST) >> 8) - ((SRC) >> 8) - TMP2;  \
1183         cpustate->spc_int16 = ((TMP1 & 0xff) + (TMP3 << 8)) & 0xffff;   \
1145         m_spc_int16 = ((TMP1 & 0xff) + (TMP3 << 8)) & 0xffff;   \
11841146         FLAG_C = (TMP3 <= 0xff) ? CFLAG_SET : 0;    \
11851147         FLAG_H = ((unsigned) ((((DST) >> 8) & 0x0F) - \
11861148            (((SRC) >> 8) & 0x0F) - TMP2)) > 0x0F ?  0: HFLAG_SET; \
1187         FLAG_V = (((DST) ^ (SRC)) & ((DST) ^ (UINT16) cpustate->spc_int16) & 0x8000) ? VFLAG_SET : 0; \
1188         FLAG_Z = (cpustate->spc_int16 != 0);        \
1189         FLAG_N = (cpustate->spc_int16>>8);      \
1190         SET_REG_YA(cpustate, cpustate->spc_int16);
1149         FLAG_V = (((DST) ^ (SRC)) & ((DST) ^ (UINT16) m_spc_int16) & 0x8000) ? VFLAG_SET : 0; \
1150         FLAG_Z = (m_spc_int16 != 0);        \
1151         FLAG_N = (m_spc_int16>>8);      \
1152         SET_REG_YA(m_spc_int16);
11911153
11921154/* Table Call */
11931155#define OP_TCALL(BCLK, NUM)                                                 \
11941156         CLK(BCLK);                                                      \
1195         PUSH_16(cpustate, REG_PC);                                              \
1196         JUMP(cpustate, read_16_NORM(0xffc0 + ((15-NUM)<<1)))
1157         PUSH_16(REG_PC);                                              \
1158         JUMP(read_16_NORM(0xffc0 + ((15-NUM)<<1)))
11971159
11981160/* Test and Clear Bits */
11991161#define OP_TCLR1(BCLK, MODE)                                                \
12001162         CLK(BCLK);                                                      \
1201         DST     = EA_##MODE(cpustate);                                          \
1163         DST     = EA_##MODE();                                          \
12021164         FLAG_NZ = read_8_##MODE(DST);                                   \
12031165         write_8_##MODE(DST, FLAG_NZ & ~REG_A);                          \
12041166         FLAG_NZ &= REG_A
r26761r26762
12061168/* Test and Set Bits */
12071169#define OP_TSET1(BCLK, MODE)                                                \
12081170         CLK(BCLK);                                                      \
1209         DST     = EA_##MODE(cpustate);                                          \
1171         DST     = EA_##MODE();                                          \
12101172         FLAG_NZ = read_8_##MODE(DST);                                   \
12111173         write_8_##MODE(DST, FLAG_NZ | REG_A);                           \
12121174         FLAG_NZ &= REG_A
r26761r26762
12241186/* ================================= API ================================== */
12251187/* ======================================================================== */
12261188
1227static void state_register( legacy_cpu_device *device )
1189void spc700_device::device_start()
12281190{
1229   spc700i_cpu *cpustate = get_safe_token(device);
1191   m_program = &space(AS_PROGRAM);
12301192
1231   device->save_item(NAME(cpustate->a));
1232   device->save_item(NAME(cpustate->x));
1233   device->save_item(NAME(cpustate->y));
1234   device->save_item(NAME(cpustate->s));
1235   device->save_item(NAME(cpustate->pc));
1236   device->save_item(NAME(cpustate->ppc));
1237   device->save_item(NAME(cpustate->flag_n));
1238   device->save_item(NAME(cpustate->flag_z));
1239   device->save_item(NAME(cpustate->flag_v));
1240   device->save_item(NAME(cpustate->flag_p));
1241   device->save_item(NAME(cpustate->flag_b));
1242   device->save_item(NAME(cpustate->flag_h));
1243   device->save_item(NAME(cpustate->flag_i));
1244   device->save_item(NAME(cpustate->flag_c));
1245   device->save_item(NAME(cpustate->line_irq));
1246   device->save_item(NAME(cpustate->line_nmi));
1247   device->save_item(NAME(cpustate->line_rst));
1248   device->save_item(NAME(cpustate->ir));
1249   device->save_item(NAME(cpustate->stopped));
1250   device->save_item(NAME(cpustate->ICount));
1251   device->save_item(NAME(cpustate->source));
1252   device->save_item(NAME(cpustate->destination));
1253   device->save_item(NAME(cpustate->temp1));
1254   device->save_item(NAME(cpustate->temp2));
1255   device->save_item(NAME(cpustate->temp3));
1256   device->save_item(NAME(cpustate->spc_int16));
1257   device->save_item(NAME(cpustate->spc_int32));
1193   save_item(NAME(m_a));
1194   save_item(NAME(m_x));
1195   save_item(NAME(m_y));
1196   save_item(NAME(m_s));
1197   save_item(NAME(m_pc));
1198   save_item(NAME(m_ppc));
1199   save_item(NAME(m_flag_n));
1200   save_item(NAME(m_flag_z));
1201   save_item(NAME(m_flag_v));
1202   save_item(NAME(m_flag_p));
1203   save_item(NAME(m_flag_b));
1204   save_item(NAME(m_flag_h));
1205   save_item(NAME(m_flag_i));
1206   save_item(NAME(m_flag_c));
1207   save_item(NAME(m_line_irq));
1208   save_item(NAME(m_line_nmi));
1209   save_item(NAME(m_line_rst));
1210   save_item(NAME(m_ir));
1211   save_item(NAME(m_stopped));
1212   save_item(NAME(m_ICount));
1213   save_item(NAME(m_source));
1214   save_item(NAME(m_destination));
1215   save_item(NAME(m_temp1));
1216   save_item(NAME(m_temp2));
1217   save_item(NAME(m_temp3));
1218   save_item(NAME(m_spc_int16));
1219   save_item(NAME(m_spc_int32));
1220
1221   // Register state for debugger
1222   state_add( SPC700_PC, "PC", m_pc            ).formatstr("%04X");
1223   state_add( SPC700_S,  "S",  m_s             ).formatstr("%02X");
1224   state_add( SPC700_P,  "P",  m_debugger_temp ).callimport().callexport().formatstr("%02X");
1225   state_add( SPC700_A,  "A",  m_a             ).formatstr("%02X");
1226   state_add( SPC700_X,  "X",  m_x             ).formatstr("%02X");
1227   state_add( SPC700_Y,  "Y",  m_y             ).formatstr("%02X");
1228
1229   state_add(STATE_GENPC, "curpc", m_pc).formatstr("%04X").noshow();
1230   state_add(STATE_GENSP, "GENSP", m_debugger_temp).mask(0x1ff).callexport().formatstr("%04X").noshow();
1231   state_add(STATE_GENFLAGS, "GENFLAGS",  m_debugger_temp).formatstr("%8s").noshow();
1232   state_add(STATE_GENPCBASE, "GENPCBASE", m_ppc).formatstr("%04X").noshow();
1233
1234   m_icountptr = &m_ICount;
12581235}
12591236
1260static CPU_INIT( spc700 )
1237
1238void spc700_device::state_string_export(const device_state_entry &entry, astring &string)
12611239{
1262   spc700i_cpu *cpustate = get_safe_token(device);
1240   switch (entry.index())
1241   {
1242      case STATE_GENFLAGS:
1243         string.printf("%c%c%c%c%c%c%c%c",
1244            (m_flag_n & 0x80)        ? 'N':'.',
1245            ((m_flag_v & 0x80) >> 1) ? 'V':'.',
1246            (m_flag_p>>3)            ? 'P':'.',
1247            (m_flag_b)               ? 'B':'.',
1248            (m_flag_h & HFLAG_SET)   ? 'H':'.',
1249            ( m_flag_i)              ? 'I':'.',
1250            ((!m_flag_z) << 1)       ? 'Z':'.',
1251            ((m_flag_c >> 8)&1)      ? 'C':'.'
1252         );
1253         break;
1254   }
1255}
12631256
1264   state_register(device);
12651257
1266   INT_ACK = irqcallback;
1267   cpustate->device = device;
1268   cpustate->program = &device->space(AS_PROGRAM);
1258void spc700_device::state_import(const device_state_entry &entry)
1259{
1260   switch (entry.index())
1261   {
1262      case SPC700_P:
1263         SET_REG_P(m_debugger_temp);
1264         break;
1265   }
12691266}
12701267
12711268
1272static CPU_RESET( spc700 )
1269void spc700_device::state_export(const device_state_entry &entry)
12731270{
1274   spc700i_cpu *cpustate = get_safe_token(device);
1271   switch (entry.index())
1272   {
1273      case SPC700_P:
1274         m_debugger_temp = ((m_flag_n & 0x80)          |
1275               ((m_flag_v & 0x80) >> 1)    |
1276               m_flag_p>>3             |
1277               m_flag_b                    |
1278               (m_flag_h & HFLAG_SET)  |
1279               m_flag_i                    |
1280               ((!m_flag_z) << 1)      |
1281               ((m_flag_c >> 8)&1));
1282         break;
12751283
1284      case STATE_GENSP:
1285         m_debugger_temp = m_s + STACK_PAGE;
1286         break;
1287   }
1288}
1289
1290
1291void spc700_device::device_reset()
1292{
12761293   CPU_STOPPED = 0;
1277#if !SPC700_OPTIMIZE_SNES
12781294   LINE_IRQ = 0;
12791295   LINE_NMI = 0;
1280#endif /* SPC700_OPTIMIZE_SNES */
12811296   REG_S   = 0;
12821297   FLAG_NZ = NZFLAG_CLEAR;
12831298   FLAG_V  = VFLAG_CLEAR;
r26761r26762
12861301   FLAG_H  = HFLAG_CLEAR;
12871302   FLAG_I  = IFLAG_CLEAR;
12881303   FLAG_C  = CFLAG_CLEAR;
1289   JUMP(cpustate, read_16_VEC(VECTOR_RST));
1304   JUMP(read_16_VEC(VECTOR_RST));
12901305}
12911306
1292/* Exit and clean up */
1293static CPU_EXIT( spc700 )
1294{
1295   /* nothing to do yet */
1296}
12971307
1298
1299/* Assert or clear the NMI line of the CPU */
1300static void spc700_set_nmi_line(spc700i_cpu *cpustate,int state)
1308void spc700_device::execute_set_input( int inptnum, int state )
13011309{
1302#if !SPC700_OPTIMIZE_SNES
1303   if(state == CLEAR_LINE)
1304      LINE_NMI = 0;
1305   else if(!LINE_NMI)
1310   if ( inptnum == INPUT_LINE_NMI )
13061311   {
1307      LINE_NMI = 1;
1308      CLK(7);
1309      PUSH_16(cpustate, REG_PC);
1310      PUSH_8(cpustate, GET_REG_P());
1311      JUMP(cpustate, read_16_VEC(VECTOR_NMI));
1312   }
1312      /* Assert or clear the NMI line of the CPU */
1313#if !SPC700_OPTIMIZE_SNES
1314      if(state == CLEAR_LINE)
1315         LINE_NMI = 0;
1316      else if(!LINE_NMI)
1317      {
1318         LINE_NMI = 1;
1319         CLK(7);
1320         PUSH_16(REG_PC);
1321         PUSH_8(GET_REG_P());
1322         JUMP(read_16_VEC(VECTOR_NMI));
1323      }
13131324#endif /* SPC700_OPTIMIZE_SNES */
1314}
1315
1316/* Assert or clear the IRQ line of the CPU */
1317static void spc700_set_irq_line(spc700i_cpu *cpustate,int line, int state)
1318{
1325   }
1326   else
1327   {
1328      /* Assert or clear the IRQ line of the CPU */
13191329#if !SPC700_OPTIMIZE_SNES
1320   LINE_IRQ = (state != CLEAR_LINE) ? IRQ_SET : IRQ_CLEAR;
1321   CHECK_IRQ();
1330      LINE_IRQ = (state != CLEAR_LINE) ? IRQ_SET : IRQ_CLEAR;
1331      CHECK_IRQ();
13221332#endif /* SPC700_OPTIMIZE_SNES */
1333   }
13231334}
13241335
13251336#include "spc700ds.h"
13261337
1338offs_t spc700_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
1339{
1340   return CPU_DISASSEMBLE_NAME(spc700)(this, buffer, pc, oprom, opram, options);
1341}
1342
13271343//int dump_flag = 0;
13281344
13291345/* Execute instructions for <clocks> cycles */
1330static CPU_EXECUTE( spc700 )
1346void spc700_device::execute_run()
13311347{
1332   spc700i_cpu *cpustate = get_safe_token(device);
1333
13341348   if (CPU_STOPPED)
13351349   {
13361350      CLOCKS = 0;
r26761r26762
13391353   while(CLOCKS > 0)
13401354   {
13411355      REG_PPC = REG_PC;
1342      debugger_instruction_hook(device, REG_PC);
1356      debugger_instruction_hook(this, REG_PC);
13431357      REG_PC++;
13441358
1345      switch(REG_IR = read_8_immediate(cpustate, REG_PPC))
1359      switch(REG_IR = read_8_immediate(REG_PPC))
13461360      {
13471361         case 0x00: OP_NOP   ( 2               ); break; /* NOP           */
13481362         case 0x01: OP_TCALL ( 8, 0            ); break; /* TCALL 0       */
r26761r26762
16641678   }
16651679}
16661680
1667
1668/**************************************************************************
1669 * Generic set_info
1670 **************************************************************************/
1671
1672static CPU_SET_INFO( spc700 )
1673{
1674   spc700i_cpu *cpustate = get_safe_token(device);
1675
1676   switch (state)
1677   {
1678      /* --- the following bits of info are set as 64-bit signed integers --- */
1679      case CPUINFO_INT_INPUT_STATE + 0:           spc700_set_irq_line(cpustate, 0, info->i);      break;
1680      case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI:      spc700_set_nmi_line(cpustate, info->i);         break;
1681
1682      case CPUINFO_INT_PC:
1683      case CPUINFO_INT_REGISTER + SPC700_PC:          REG_PC = MAKE_UINT_16(info->i);         break;
1684      case CPUINFO_INT_SP:
1685      case CPUINFO_INT_REGISTER + SPC700_S:           REG_S = MAKE_UINT_8(info->i);           break;
1686      case CPUINFO_INT_REGISTER + SPC700_P:           SET_REG_P(cpustate, info->i);                       break;
1687      case CPUINFO_INT_REGISTER + SPC700_A:           REG_A = MAKE_UINT_8(info->i);           break;
1688      case CPUINFO_INT_REGISTER + SPC700_X:           REG_X = MAKE_UINT_8(info->i);           break;
1689      case CPUINFO_INT_REGISTER + SPC700_Y:           REG_Y = MAKE_UINT_8(info->i);           break;
1690   }
1691}
1692
1693
1694
1695/**************************************************************************
1696 * Generic get_info
1697 **************************************************************************/
1698
1699CPU_GET_INFO( spc700 )
1700{
1701   spc700i_cpu *cpustate = (device != NULL && device->token() != NULL) ? get_safe_token(device) : NULL;
1702   uint p = 0;
1703
1704   if (cpustate != NULL)
1705   {
1706      p = ((cpustate->flag_n & 0x80)          |
1707               ((cpustate->flag_v & 0x80) >> 1)    |
1708               cpustate->flag_p>>3             |
1709               cpustate->flag_b                    |
1710               (cpustate->flag_h & HFLAG_SET)  |
1711               cpustate->flag_i                    |
1712               ((!cpustate->flag_z) << 1)      |
1713               ((cpustate->flag_c >> 8)&1));
1714   }
1715
1716   switch (state)
1717   {
1718      /* --- the following bits of info are returned as 64-bit signed integers --- */
1719      case CPUINFO_INT_CONTEXT_SIZE:                  info->i = sizeof(spc700i_cpu);          break;
1720      case CPUINFO_INT_INPUT_LINES:                   info->i = 1;                            break;
1721      case CPUINFO_INT_DEFAULT_IRQ_VECTOR:            info->i = 0;                            break;
1722      case CPUINFO_INT_ENDIANNESS:                    info->i = ENDIANNESS_LITTLE;                    break;
1723      case CPUINFO_INT_CLOCK_MULTIPLIER:              info->i = 1;                            break;
1724      case CPUINFO_INT_CLOCK_DIVIDER:                 info->i = 1;                            break;
1725      case CPUINFO_INT_MIN_INSTRUCTION_BYTES:         info->i = 1;                            break;
1726      case CPUINFO_INT_MAX_INSTRUCTION_BYTES:         info->i = 3;                            break;
1727      case CPUINFO_INT_MIN_CYCLES:                    info->i = 2;                            break;
1728      case CPUINFO_INT_MAX_CYCLES:                    info->i = 8;                            break;
1729
1730      case CPUINFO_INT_DATABUS_WIDTH + AS_PROGRAM:    info->i = 8;                    break;
1731      case CPUINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 16;                  break;
1732      case CPUINFO_INT_ADDRBUS_SHIFT + AS_PROGRAM: info->i = 0;                   break;
1733      case CPUINFO_INT_DATABUS_WIDTH + AS_DATA:   info->i = 0;                    break;
1734      case CPUINFO_INT_ADDRBUS_WIDTH + AS_DATA:   info->i = 0;                    break;
1735      case CPUINFO_INT_ADDRBUS_SHIFT + AS_DATA:   info->i = 0;                    break;
1736      case CPUINFO_INT_DATABUS_WIDTH + AS_IO:     info->i = 0;                break;
1737      case CPUINFO_INT_ADDRBUS_WIDTH + AS_IO:     info->i = 0;                break;
1738      case CPUINFO_INT_ADDRBUS_SHIFT + AS_IO:     info->i = 0;                break;
1739
1740      case CPUINFO_INT_INPUT_STATE + 0:               info->i = (LINE_IRQ == IRQ_SET) ? ASSERT_LINE : CLEAR_LINE; break;
1741
1742      case CPUINFO_INT_PREVIOUSPC:                    info->i = REG_PPC;          break;
1743
1744      case CPUINFO_INT_PC:
1745      case CPUINFO_INT_REGISTER + SPC700_PC:              info->i = REG_PC;           break;
1746      case CPUINFO_INT_SP:
1747      case CPUINFO_INT_REGISTER + SPC700_S:                   info->i = REG_S + STACK_PAGE;       break;
1748      case CPUINFO_INT_REGISTER + SPC700_P:                   info->i = GET_REG_P();          break;
1749      case CPUINFO_INT_REGISTER + SPC700_A:                   info->i = REG_A;            break;
1750      case CPUINFO_INT_REGISTER + SPC700_X:               info->i = REG_X;            break;
1751      case CPUINFO_INT_REGISTER + SPC700_Y:               info->i = REG_Y;            break;
1752
1753      /* --- the following bits of info are returned as pointers to data or functions --- */
1754      case CPUINFO_FCT_SET_INFO:                  info->setinfo = CPU_SET_INFO_NAME(spc700);      break;
1755      case CPUINFO_FCT_INIT:                      info->init = CPU_INIT_NAME(spc700);         break;
1756      case CPUINFO_FCT_RESET:                     info->reset = CPU_RESET_NAME(spc700);           break;
1757      case CPUINFO_FCT_EXIT:                      info->exit = CPU_EXIT_NAME(spc700);         break;
1758      case CPUINFO_FCT_EXECUTE:                   info->execute = CPU_EXECUTE_NAME(spc700);       break;
1759      case CPUINFO_FCT_BURN:                      info->burn = NULL;                  break;
1760      case CPUINFO_FCT_DISASSEMBLE:                   info->disassemble = CPU_DISASSEMBLE_NAME(spc700);   break;
1761      case CPUINFO_PTR_INSTRUCTION_COUNTER:           info->icount = &cpustate->ICount;               break;
1762
1763      /* --- the following bits of info are returned as NULL-terminated strings --- */
1764      case CPUINFO_STR_NAME:                      strcpy(info->s, "SPC700");              break;
1765      case CPUINFO_STR_SHORTNAME:                 strcpy(info->s, "spc700");              break;
1766      case CPUINFO_STR_FAMILY:                    strcpy(info->s, "Sony SPC700");             break;
1767      case CPUINFO_STR_VERSION:                   strcpy(info->s, "1.1");                 break;
1768      case CPUINFO_STR_SOURCE_FILE:                   strcpy(info->s, __FILE__);              break;
1769      case CPUINFO_STR_CREDITS:                   strcpy(info->s, "Copyright Nicola Salmoria and the MAME team, all rights reserved."); break;
1770
1771      case CPUINFO_STR_FLAGS:
1772         sprintf(info->s, "%c%c%c%c%c%c%c%c",
1773            p & 0x80 ? 'N':'.',
1774            p & 0x40 ? 'V':'.',
1775            p & 0x20 ? 'P':'.',
1776            p & 0x10 ? 'B':'.',
1777            p & 0x08 ? 'H':'.',
1778            p & 0x04 ? 'I':'.',
1779            p & 0x02 ? 'Z':'.',
1780            p & 0x01 ? 'C':'.');
1781         break;
1782
1783      case CPUINFO_STR_REGISTER + SPC700_PC:          sprintf(info->s, "PC:%04X", cpustate->pc); break;
1784      case CPUINFO_STR_REGISTER + SPC700_S:           sprintf(info->s, "S:%02X", cpustate->s); break;
1785      case CPUINFO_STR_REGISTER + SPC700_P:           sprintf(info->s, "P:%02X", p); break;
1786      case CPUINFO_STR_REGISTER + SPC700_A:           sprintf(info->s, "A:%02X", cpustate->a); break;
1787      case CPUINFO_STR_REGISTER + SPC700_X:           sprintf(info->s, "X:%02X", cpustate->x); break;
1788      case CPUINFO_STR_REGISTER + SPC700_Y:           sprintf(info->s, "Y:%02X", cpustate->y); break;
1789   }
1790}
1791
1792DEFINE_LEGACY_CPU_DEVICE(SPC700, spc700);
1793
17941681/* ======================================================================== */
17951682/* ============================== END OF FILE ============================= */
17961683/* ======================================================================== */

Previous 199869 Revisions Next


© 1997-2024 The MAME Team