1 // license:BSD-3-Clause
2 // copyright-holders:R. Belmont, Karl Stenerud
3 /* ======================================================================== */
4 /* =============================== COPYRIGHT ============================== */
5 /* ======================================================================== */
6 /*
7 
8   Sony/Nintendo SPC700 CPU Emulator
9 
10   The SPC700 is 6502-based at heart but contains a lot of the extended
11   opcodes of the Mitsubishi 770 and 7700 series 65xxx-based MCUs,  plus
12   a few special twists borrowed from the 68000.
13 
14   It was designed by Sony's Ken Kutaragi, later the "father of the PlayStation".
15 
16   Original emulation by Anthony Kruize and Lee Hammerton.
17   Substantially revised by R. Belmont.
18 
19   Thanks to Anonymous, TRAC, Brad Martin, anomie, Blargg, and everyone
20   else on ZSNES Technical for probing the darker corners of the SNES
21   with test programs so we have a chance at getting things accurate.
22 
23   MESS Bugzilla bugs:
24   - 804 ADC sets carry too late (FIXED)
25   - 805 ADDW/SUBW set V wrongly (FIXED)
26   - 806 BRK should modify PSW (FIXED)
27   - 807 DAA/DAS problem (FIXED)
28 
29 
30 */
31 /* ======================================================================== */
32 /* ================================= NOTES ================================ */
33 /* ======================================================================== */
34 /*
35 
36 snes mapped ports: f0-ff
37 Address  Function Register  R/W  When Reset          Remarks
38 
39 00F0H     (test)            ---  ------             Installed in sound-CPU
40 00F1H     Control            W   Control = "00-000"
41 00F2H    Register Add.      R/W  Indeterminate      Installed in DSP
42 00F3H    Register Data      R/W  Indeterminate      Installed in DSP
43 00F4H    Port-0             R/W  Port0r = "00"      Installed in sound-CPU
44                                  Port0w = "00"
45 00F5H    Port-1             R/W  Port1r = "00"      Installed in sound-CPU
46                                  Port1w = "00"
47 00F6H    Port-2             R/W  Port2r = "00"      Installed in sound-CPU
48                                  Port2w = "00"
49 00F7H    Port-3             R/W  Port3r = "00"      Installed in sound-CPU
50                                  Port3w = "00"
51 00F8H    ------             ---  ----------         -------------------
52 00F9H    ------             ---  ----------         -------------------
53 00FAH    Timer-0             W   Indeterminate      Installed in sound-CPU
54 00FBH    Timer-1             W   Indeterminate      Installed in sound-CPU
55 00FCH    Timer-2             W   Indeterminate      Installed in sound-CPU
56 00FDH    Counter-0           W   Indeterminate      Installed in sound-CPU
57 00FEH    Counter-1           W   Indeterminate      Installed in sound-CPU
58 00FFH    Counter-2           W   Indeterminate      Installed in sound-CPU
59 
60 */
61 /* ======================================================================== */
62 /* ================================ INCLUDES ============================== */
63 /* ======================================================================== */
64 
65 #include "emu.h"
66 #include "spc700.h"
67 
68 #include "debugger.h"
69 
70 #include <climits>
71 
72 
73 /* ======================================================================== */
74 /* ==================== ARCHITECTURE-DEPENDANT DEFINES ==================== */
75 /* ======================================================================== */
76 
77 #undef int8
78 
79 /* Allow for architectures that don't have 8-bit sizes */
80 #if UCHAR_MAX == 0xff
81 #define int8 char
82 #define MAKE_INT_8(A) (int8)((A)&0xff)
83 #else
84 #define int8   int
MAKE_INT_8(int A)85 static inline int MAKE_INT_8(int A) {return (A & 0x80) ? A | ~0xff : A & 0xff;}
86 #endif /* UCHAR_MAX == 0xff */
87 
88 #define MAKE_UINT_8(A) ((A)&0xff)
89 #define MAKE_UINT_16(A) ((A)&0xffff)
90 
91 /* ======================================================================== */
92 /* ============================ GENERAL DEFINES =========================== */
93 /* ======================================================================== */
94 
95 /* Bits */
96 #define BIT_0       0x01
97 #define BIT_1       0x02
98 #define BIT_2       0x04
99 #define BIT_3       0x08
100 #define BIT_4       0x10
101 #define BIT_5       0x20
102 #define BIT_6       0x40
103 #define BIT_7       0x80
104 #define BIT_8       0x100
105 
106 /* Flag positions in Processor Status Register */
107 #define FLAGPOS_N       BIT_7       /* Negative             */
108 #define FLAGPOS_V       BIT_6       /* Overflow             */
109 #define FLAGPOS_P       BIT_5       /* Direct Page Selector */
110 #define FLAGPOS_B       BIT_4       /* Break                */
111 #define FLAGPOS_H       BIT_3       /* Half-carry           */
112 #define FLAGPOS_I       BIT_2       /* Interrupt            */
113 #define FLAGPOS_Z       BIT_1       /* Zero                 */
114 #define FLAGPOS_C       BIT_0       /* Carry                */
115 
116 #define NFLAG_SET       FLAGPOS_N
117 #define VFLAG_SET       BIT_7
118 #define PFLAG_SET       BIT_8
119 #define BFLAG_SET       FLAGPOS_B
120 #define HFLAG_SET       BIT_3
121 #define IFLAG_SET       FLAGPOS_I
122 #define ZFLAG_SET       0
123 #define CFLAG_SET       BIT_8
124 #define NZFLAG_CLEAR    1
125 #define VFLAG_CLEAR     0
126 #define PFLAG_CLEAR     0
127 #define BFLAG_CLEAR     0
128 #define HFLAG_CLEAR     0
129 #define IFLAG_CLEAR     0
130 #define CFLAG_CLEAR     0
131 
132 #define NMI_SET     1
133 #define NMI_CLEAR   0
134 #define IRQ_SET     IFLAG_CLEAR
135 #define IRQ_CLEAR   IFLAG_SET
136 
137 #define STACK_PAGE  0x100               /* Stack Page Offset */
138 
139 #define VECTOR_RST  0xfffe              /* Reset */
140 #define VECTOR_BRK  0xffde              /* Break Instruction */
141 #define VECTOR_IRQ  0xfffc              /* IRQ ??? what is real vector? */
142 #define VECTOR_NMI  0xfffa              /* NMI ??? what is real vector? */
143 
144 #define REG_A       m_a     /* Accumulator */
145 #define REG_X       m_x     /* Index X Register */
146 #define REG_Y       m_y     /* Index Y Register */
147 #define REG_S       m_s     /* Stack Pointer */
148 #define REG_PC      m_pc        /* Program Counter */
149 #define REG_PPC     m_ppc       /* Previous Program Counter */
150 #define REG_P       m_p     /* Processor Status Register */
151 #define FLAG_NZ     m_flag_n = m_flag_z /* Negative Flag and inverted Zero flag */
152 #define FLAG_N      m_flag_n    /* Negative flag */
153 #define FLAG_Z      m_flag_z    /* Inverted Zero flag */
154 #define FLAG_V      m_flag_v    /* Overflow Flag */
155 #define FLAG_P      m_flag_p    /* Direct Page Flag */
156 #define FLAG_B      m_flag_b    /* BRK Instruction Flag */
157 #define FLAG_H      m_flag_h    /* Decimal Mode Flag */
158 #define FLAG_I      m_flag_i    /* Interrupt Mask Flag */
159 #define FLAG_C      m_flag_c    /* Carry Flag */
160 #define LINE_IRQ    m_line_irq  /* Status of the IRQ line */
161 #define LINE_NMI    m_line_nmi  /* Status of the NMI line */
162 #define REG_IR      m_ir        /* Instruction Register */
163 #define CLOCKS      m_ICount        /* Clock cycles remaining */
164 #define CPU_STOPPED m_stopped   /* Stopped status */
165 
166 #define SRC     m_source    /* Source Operand */
167 #define DST     m_destination   /* Destination Operand */
168 #define TMP1        m_temp1 /* temporary result 1 */
169 #define TMP2        m_temp2 /* temporary result 2 */
170 #define TMP3        m_temp3 /* temporary result 3 */
171 
172 #define STOP_LEVEL_STOP     1
173 #define STOP_LEVEL_SLEEP    2
174 
175 
176 /* ======================================================================== */
177 /* ============================ GENERAL MACROS ============================ */
178 /* ======================================================================== */
179 
180 /* Condition code tests */
181 #define COND_CC()   (!(FLAG_C&0x100))   /* Carry Clear */
182 #define COND_CS()   (FLAG_C&0x100)      /* Carry Set */
183 #define COND_EQ()   (!FLAG_Z)           /* Equal */
184 #define COND_NE()   (FLAG_Z)            /* Not Equal */
185 #define COND_MI()   (FLAG_N&0x80)       /* Minus */
186 #define COND_PL()   (!(FLAG_N&0x80))    /* Plus */
187 #define COND_VC()   (!(FLAG_V&0x80))    /* Overflow Clear */
188 #define COND_VS()   (FLAG_V&0x80)       /* Overflow Set */
189 
190 /* Set Overflow flag in math operations */
191 #define VFLAG_ADD_8(S, D, R)   ((S^R) & (D^R))
192 #define VFLAG_ADD_16(S, D, R) (((S^R) & (D^R))>>8)
193 #define VFLAG_SUB_8(S, D, R)   ((S^D) & (R^D))
194 #define VFLAG_SUB_16(S, D, R) (((S^D) & (R^D))>>8)
195 
196 #define CFLAG_1()     ((FLAG_C>>8)&1)
197 #define CFLAG_AS_NOT_1() (!(FLAG_C&CFLAG_SET))
198 
199 #define NZFLAG_16(A) (((A)&0x7f) | (((A)>>1)&0x40) | (((A)>>8)&0xff))
200 #define CFLAG_16(A)  ((A)>>8)
201 
202 
203 /* ======================================================================== */
204 /* ================================= MAME ================================= */
205 /* ======================================================================== */
206 
207 #define spc700_read_8(addr) m_program->read_byte(addr)
208 #define spc700_write_8(addr,data) m_program->write_byte(addr,data)
209 
210 #define spc700_read_8_direct(A)     spc700_read_8(A)
211 #define spc700_write_8_direct(A, V) spc700_write_8(A, V)
212 //#define spc700_read_instruction(A)    memory_decrypted_read_byte(m_program,A)
213 //#define spc700_read_8_immediate(A)    memory_raw_read_byte(m_program,A)
214 #define spc700_read_instruction(A)    m_program->read_byte(A)
215 #define spc700_read_8_immediate(A)    m_program->read_byte(A)
216 #define spc700_jumping(A)
217 #define spc700_branching(A)
218 
219 
220 
221 DEFINE_DEVICE_TYPE(SPC700, spc700_device, "spc700", "Sony SPC700")
222 
223 
spc700_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)224 spc700_device::spc700_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
225 	: spc700_device(mconfig, SPC700, tag, owner, clock)
226 {
227 }
228 
spc700_device(const machine_config & mconfig,device_type type,const char * tag,device_t * owner,uint32_t clock,address_map_constructor internal_map)229 spc700_device::spc700_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor internal_map)
230 	: cpu_device(mconfig, type, tag, owner, clock)
231 	, m_program_config("program", ENDIANNESS_LITTLE, 8, 16, 0, internal_map)
232 	, m_a(0)
233 	, m_x(0)
234 	, m_y(0)
235 	, m_s(0)
236 	, m_pc(0)
237 	, m_ppc(0)
238 	, m_debugger_temp(0)
239 {
240 }
241 
memory_space_config() const242 device_memory_interface::space_config_vector spc700_device::memory_space_config() const
243 {
244 	return space_config_vector {
245 		std::make_pair(AS_PROGRAM, &m_program_config)
246 	};
247 }
248 
249 
250 /* ======================================================================== */
251 /* ============================ UTILITY MACROS ============================ */
252 /* ======================================================================== */
253 
254 /* Use up clock cycles */
255 #define CLK_DIVIDER 2
256 #define CLK(A) CLOCKS -= ((A)*(CLK_DIVIDER))
257 #define CLK_ALL() CLOCKS = 0
258 
259 
read_8_normal(uint32_t address)260 uint32_t spc700_device::read_8_normal(uint32_t address)
261 {
262 	address = MAKE_UINT_16(address);
263 	return spc700_read_8(address);
264 }
265 
read_8_immediate(uint32_t address)266 uint32_t spc700_device::read_8_immediate(uint32_t address)
267 {
268 	address = MAKE_UINT_16(address);
269 	return spc700_read_8_immediate(address);
270 }
271 
read_8_instruction(uint32_t address)272 uint32_t spc700_device::read_8_instruction(uint32_t address)
273 {
274 	address = MAKE_UINT_16(address);
275 	return spc700_read_instruction(address);
276 }
277 
read_8_direct(uint32_t address)278 uint32_t spc700_device::read_8_direct(uint32_t address)
279 {
280 	address = MAKE_UINT_8(address) | FLAG_P;
281 	return spc700_read_8_direct(address);
282 }
283 
write_8_normal(uint32_t address,uint32_t value)284 void spc700_device::write_8_normal(uint32_t address, uint32_t value)
285 {
286 	address = MAKE_UINT_16(address);
287 	value = MAKE_UINT_8(value);
288 	spc700_write_8(address, value);
289 }
290 
write_8_direct(uint32_t address,uint32_t value)291 void spc700_device::write_8_direct(uint32_t address, uint32_t value)
292 {
293 	address = MAKE_UINT_8(address) | FLAG_P;
294 	value = MAKE_UINT_8(value);
295 	spc700_write_8_direct(address, value);
296 }
297 
298 
read_16_normal(uint32_t address)299 uint32_t spc700_device::read_16_normal(uint32_t address)
300 {
301 	return read_8_normal(address) | (read_8_normal(address+1)<<8);
302 }
303 
read_16_immediate(uint32_t address)304 uint32_t spc700_device::read_16_immediate(uint32_t address)
305 {
306 	return read_8_immediate(address) | (read_8_immediate(address+1)<<8);
307 }
308 
read_16_direct(uint32_t address)309 uint32_t spc700_device::read_16_direct(uint32_t address)
310 {
311 	return read_8_direct(address) | (read_8_direct(address+1)<<8);
312 }
313 
write_16_direct(uint32_t address,uint32_t value)314 void spc700_device::write_16_direct(uint32_t address, uint32_t value)
315 {
316 	write_8_direct(address, value);
317 	write_8_direct(address+1, value>>8);
318 }
319 
320 /* Low level memory access macros */
321 #define read_8_NORM(A)      read_8_normal(A)
322 #define read_8_IMM(A)       read_8_immediate(A)
323 #define read_8_ABS(A)       read_8_normal(A)
324 #define read_8_ABX(A)       read_8_normal(A)
325 #define read_8_ABY(A)       read_8_normal(A)
326 #define read_8_AXI(A)       read_8_normal(A)
327 #define read_8_DP(A)        read_8_direct(A)
328 #define read_8_DPX(A)       read_8_direct(A)
329 #define read_8_DPY(A)       read_8_direct(A)
330 #define read_8_DPI(A)       read_8_normal(A)
331 #define read_8_DXI(A)       read_8_normal(A)
332 #define read_8_DIY(A)       read_8_normal(A)
333 #define read_8_STK(A)       read_8_normal(A)
334 #define read_8_XI(A)        read_8_direct(A)
335 #define read_8_XII(A)       read_8_direct(A)
336 #define read_8_YI(A)        read_8_direct(A)
337 
338 
339 #define read_16_NORM(A)     read_16_normal(A)
340 #define read_16_IMM(A)      read_16_immediate(A)
341 #define read_16_ABS(A)      read_16_absolute(A)
342 #define read_16_ABX(A)      read_16_normal(A)
343 #define read_16_DP(A)       read_16_direct(A)
344 #define read_16_DPX(A)      read_16_direct(A)
345 #define read_16_DPY(A)      read_16_direct(A)
346 #define read_16_DPI(A)      read_16_normal(A)
347 #define read_16_VEC(A)      read_16_normal(A)
348 #define read_16_XI(A)       read_16_direct(A)
349 #define read_16_XII(A)      read_16_direct(A)
350 #define read_16_YI(A)       read_16_direct(A)
351 
352 #define write_8_NORM(A, V)  write_8_normal(A, V)
353 #define write_8_IMM(A, V)   write_8_normal(A, V)
354 #define write_8_ABS(A, V)   write_8_normal(A, V)
355 #define write_8_ABX(A, V)   write_8_normal(A, V)
356 #define write_8_ABY(A, V)   write_8_normal(A, V)
357 #define write_8_AXI(A, V)   write_8_normal(A, V)
358 #define write_8_DP(A, V)    write_8_direct(A, V)
359 #define write_8_DPX(A, V)   write_8_direct(A, V)
360 #define write_8_DPY(A, V)   write_8_direct(A, V)
361 #define write_8_DPI(A, V)   write_8_normal(A, V)
362 #define write_8_DXI(A, V)   write_8_normal(A, V)
363 #define write_8_DIY(A, V)   write_8_normal(A, V)
364 #define write_8_STK(A, V)   write_8_normal(A, V)
365 #define write_8_XI(A, V)    write_8_direct(A, V)
366 #define write_8_XII(A, V)   write_8_direct(A, V)
367 #define write_8_YI(A, V)    write_8_direct(A, V)
368 
369 #define write_16_NORM(A, V) write_16_normal(A, V)
370 #define write_16_ABS(A, V)  write_16_normal(A, V)
371 #define write_16_ABX(A, V)  write_16_normal(A, V)
372 #define write_16_ABY(A, V)  write_16_normal(A, V)
373 #define write_16_AXI(A, V)  write_16_normal(A, V)
374 #define write_16_DP(A, V)   write_16_direct(A, V)
375 #define write_16_DPX(A, V)  write_16_direct(A, V)
376 #define write_16_DPY(A, V)  write_16_direct(A, V)
377 #define write_16_DPI(A, V)  write_16_normal(A, V)
378 #define write_16_DXI(A, V)  write_16_normal(A, V)
379 #define write_16_DIY(A, V)  write_16_normal(A, V)
380 #define write_16_STK(A, V)  write_16_normal(A, V)
381 #define write_16_XI(A, V)   write_16_direct(A, V)
382 #define write_16_XII(A, V)  write_16_direct(A, V)
383 #define write_16_YI(A, V)   write_16_direct(A, V)
384 
385 
386 #define OPER_8_IMM()    read_8_IMM(EA_IMM())
387 #define OPER_8_ABS()    read_8_ABS(EA_ABS())
388 #define OPER_8_ABX()    read_8_ABX(EA_ABX())
389 #define OPER_8_ABY()    read_8_ABY(EA_ABY())
390 #define OPER_8_AXI()    read_8_IND(EA_IND())
391 #define OPER_8_DP() read_8_DP(EA_DP())
392 #define OPER_8_DPX()    read_8_DPX(EA_DPX())
393 #define OPER_8_DPY()    read_8_DPY(EA_DPY())
394 #define OPER_8_DPI()    read_8_DPI(EA_DPI())
395 #define OPER_8_DXI()    read_8_DXI(EA_DXI())
396 #define OPER_8_DIY()    read_8_DIY(EA_DIY())
397 #define OPER_8_XI() read_8_XI(EA_XI())
398 #define OPER_8_XII()    read_8_XI(EA_XII())
399 #define OPER_8_YI() read_8_YI(EA_YI())
400 
401 #define OPER_16_IMM()   read_16_IMM(EA_IMM16())
402 #define OPER_16_ABS()   read_16_ABS(EA_ABS())
403 #define OPER_16_ABX()   read_16_ABX(EA_ABX())
404 #define OPER_16_ABY()   read_16_ABY(EA_ABY())
405 #define OPER_16_AXI()   read_16_IND(EA_IND())
406 #define OPER_16_DP()    read_16_DP(EA_DP())
407 #define OPER_16_DPX()   read_16_DPX(EA_DPX())
408 #define OPER_16_DPY()   read_16_DPY(EA_DPY())
409 #define OPER_16_DPI()   read_16_DPI(EA_DXI())
410 #define OPER_16_DXI()   read_16_DXI(EA_DXI())
411 #define OPER_16_DIY()   read_16_DIY(EA_DIY())
412 #define OPER_16_XI()    read_16_XI(EA_XI())
413 #define OPER_16_XII()   read_16_XI(EA_XII())
414 #define OPER_16_YI()    read_16_YI(EA_YI())
415 
416 /* Effective Address Calculations */
EA_IMM()417 uint32_t spc700_device::EA_IMM()   {return REG_PC++;}
EA_IMM16()418 uint32_t spc700_device::EA_IMM16() {REG_PC += 2; return REG_PC-2;}
EA_ABS()419 uint32_t spc700_device::EA_ABS()   {return OPER_16_IMM();}
EA_ABX()420 uint32_t spc700_device::EA_ABX()   {return EA_ABS() + REG_X;}
EA_ABY()421 uint32_t spc700_device::EA_ABY()   {return EA_ABS() + REG_Y;}
EA_AXI()422 uint32_t spc700_device::EA_AXI()   {return OPER_16_ABX();}
EA_DP()423 uint32_t spc700_device::EA_DP()    {return OPER_8_IMM();}
EA_DPX()424 uint32_t spc700_device::EA_DPX()   {return (EA_DP() + REG_X)&0xff;}
EA_DPY()425 uint32_t spc700_device::EA_DPY()   {return (EA_DP() + REG_Y)&0xff;}
EA_DXI()426 uint32_t spc700_device::EA_DXI()   {return OPER_16_DPX();}
EA_DIY()427 uint32_t spc700_device::EA_DIY()   {uint32_t addr = OPER_16_DP(); return addr + REG_Y;}
EA_XI()428 uint32_t spc700_device::EA_XI()    {return REG_X;}
EA_XII()429 uint32_t spc700_device::EA_XII()   {uint32_t val = REG_X;REG_X = MAKE_UINT_8(REG_X+1);return val;}
EA_YI()430 uint32_t spc700_device::EA_YI()    {return REG_Y;}
431 
432 
433 
434 /* Change the Program Counter */
JUMP(uint32_t address)435 void spc700_device::JUMP(uint32_t address)
436 {
437 	REG_PC = address;
438 	spc700_jumping(REG_PC);
439 }
440 
BRANCH(uint32_t offset)441 void spc700_device::BRANCH(uint32_t offset)
442 {
443 	REG_PC = MAKE_UINT_16(REG_PC + MAKE_INT_8(offset));
444 	spc700_branching(REG_PC);
445 }
446 
447 
448 #define GET_REG_YA() (REG_A | (REG_Y<<8))
449 
SET_REG_YA(uint32_t value)450 void spc700_device::SET_REG_YA(uint32_t value)
451 {
452 	REG_A = MAKE_UINT_8(value);
453 	REG_Y = MAKE_UINT_8(value>>8);
454 }
455 
456 /* Get the Processor Status Register */
457 #define GET_REG_P()             \
458 	((FLAG_N & 0x80)        |   \
459 	((FLAG_V & 0x80) >> 1)  |   \
460 	(FLAG_P>>3)             |   \
461 	FLAG_B                  |   \
462 	(FLAG_H& HFLAG_SET)     |   \
463 	FLAG_I                  |   \
464 	((!FLAG_Z) << 1)        |   \
465 	CFLAG_1())
466 
467 /* Set the Process Status Register */
SET_REG_P(uint32_t value)468 void spc700_device::SET_REG_P(uint32_t value)
469 {
470 	FLAG_N = (value & 0x80);
471 	FLAG_Z = !(value & 2);
472 	FLAG_V = value<<1;
473 	FLAG_P = (value & FLAGPOS_P) << 3;
474 	FLAG_B = value & FLAGPOS_B;
475 	FLAG_H = value & HFLAG_SET;
476 	FLAG_C = value << 8;
477 	SET_FLAG_I(value);
478 }
479 
480 /* Push/Pull data to/from the stack */
PUSH_8(uint32_t value)481 void spc700_device::PUSH_8(uint32_t value)
482 {
483 	write_8_STK(REG_S+STACK_PAGE, value);
484 	REG_S = MAKE_UINT_8(REG_S - 1);
485 }
486 
PULL_8()487 uint32_t spc700_device::PULL_8()
488 {
489 	REG_S = MAKE_UINT_8(REG_S + 1);
490 	return read_8_STK(REG_S+STACK_PAGE);
491 }
492 
PUSH_16(uint32_t value)493 void spc700_device::PUSH_16(uint32_t value)
494 {
495 	PUSH_8(value>>8);
496 	PUSH_8(value);
497 }
498 
PULL_16()499 uint32_t spc700_device::PULL_16()
500 {
501 	uint32_t value = PULL_8();
502 	return value | (PULL_8()<<8);
503 }
504 
CHECK_IRQ()505 void spc700_device::CHECK_IRQ()
506 {
507 	if(FLAG_I & LINE_IRQ)
508 		SERVICE_IRQ();
509 }
510 
SERVICE_IRQ()511 void spc700_device::SERVICE_IRQ()
512 {
513 	fatalerror("spc700: SERVICE_IRQ() not implemented yet!\n");
514 }
515 
516 
SET_FLAG_I(uint32_t value)517 void spc700_device::SET_FLAG_I(uint32_t value)
518 {
519 	FLAG_I = value & IFLAG_SET;
520 #if !SPC700_OPTIMIZE_SNES
521 	CHECK_IRQ();
522 #endif
523 }
524 
525 /* ======================================================================== */
526 /* =========================== OPERATION MACROS =========================== */
527 /* ======================================================================== */
528 
529 #define SUBOP_ADC(A, B)                     \
530 	m_spc_int16 = (A) + (B) + CFLAG_1();         \
531 	TMP1 = ((A) & 0x0f) + (CFLAG_1());           \
532 	FLAG_C  = (m_spc_int16 > 0xff) ? CFLAG_SET : 0;     \
533 	FLAG_V =  (~((A) ^ (B))) & (((A) ^ m_spc_int16) & 0x80); \
534 	FLAG_H = (((m_spc_int16 & 0x0f) - TMP1) & 0x10) >> 1;   \
535 	FLAG_NZ = (uint8_t)m_spc_int16
536 
537 
538 /* Add With Carry */
539 #define OP_ADC(BCLK, MODE)                  \
540 			CLK(BCLK);              \
541 			SRC     = OPER_8_##MODE();      \
542 			SUBOP_ADC(SRC, REG_A);          \
543 			REG_A = (uint8_t)m_spc_int16;
544 
545 
546 /* Add With Carry to memory */
547 #define OP_ADCM(BCLK, SMODE, DMODE)             \
548 			CLK(BCLK);              \
549 			SRC     = OPER_8_##SMODE();     \
550 			DST     = EA_##DMODE();         \
551 			SUBOP_ADC(SRC, read_8_##DMODE(DST));    \
552 			write_8_##DMODE(DST, (uint8_t)m_spc_int16)
553 
554 /* Add word */
555 #define OP_ADDW(BCLK)                       \
556 			CLK(BCLK);              \
557 			SRC = OPER_16_DP();         \
558 			DST = GET_REG_YA();         \
559 			TMP1 = ((SRC) & 0xff) + ((DST) & 0xff); \
560 			TMP2 = (TMP1 > 0xff) ? 1 : 0;       \
561 			TMP3 = ((SRC) >> 8) + ((DST) >> 8) + TMP2;  \
562 			m_spc_int16 = ((TMP1 & 0xff) + (TMP3 << 8)) & 0xffff;   \
563 			FLAG_C = (TMP3 > 0xff) ? CFLAG_SET : 0; \
564 			FLAG_H = ((unsigned) ((((DST) >> 8) & 0x0F) + \
565 				(((SRC) >> 8) & 0x0F) + TMP2)) > 0x0F ? HFLAG_SET : 0; \
566 			FLAG_V = (~((DST) ^ (SRC)) & ((SRC) ^ (uint16_t) m_spc_int16) & 0x8000) ? VFLAG_SET : 0; \
567 			FLAG_Z = (m_spc_int16 != 0);        \
568 			FLAG_N = (m_spc_int16>>8);      \
569 			SET_REG_YA(m_spc_int16);
570 
571 /* Logical AND with accumulator */
572 #define OP_AND(BCLK, MODE)                                                  \
573 			CLK(BCLK);                                                      \
574 			FLAG_NZ = REG_A &= OPER_8_##MODE()
575 
576 /* Logical AND operand */
577 #define OP_ANDM(BCLK, SMODE, DMODE)                                         \
578 			CLK(BCLK);                                                      \
579 			FLAG_NZ = OPER_8_##SMODE();                                     \
580 			DST     = EA_##DMODE();                                         \
581 			FLAG_NZ &= read_8_##DMODE(DST);                                 \
582 			write_8_##DMODE(DST, FLAG_NZ)
583 
584 /* Logical AND bit to C */
585 #define OP_AND1(BCLK)                                                       \
586 			CLK(BCLK);                                                      \
587 			DST = EA_IMM16();                                               \
588 			if(FLAG_C & CFLAG_SET)                                          \
589 			{                                                               \
590 				DST = read_16_IMM(DST);                                     \
591 				SRC = 1 << (DST >> 13);                                     \
592 				DST &= 0x1fff;                                              \
593 				if(!(read_8_NORM(DST) & SRC))                               \
594 					FLAG_C = CFLAG_CLEAR;                                   \
595 			}
596 
597 /* AND negated bit to C */
598 #define OP_ANDN1(BCLK)                                                      \
599 			CLK(BCLK);                                                      \
600 			DST = EA_IMM16();                                               \
601 			if(FLAG_C & CFLAG_SET)                                          \
602 			{                                                               \
603 				DST = read_16_IMM(DST);                                     \
604 				SRC = 1 << (DST >> 13);                                     \
605 				DST &= 0x1fff;                                              \
606 				if(read_8_NORM(DST) & SRC)                                  \
607 					FLAG_C = CFLAG_CLEAR;                                   \
608 			}
609 
610 /* Arithmetic Shift Left accumulator */
611 #define OP_ASL(BCLK)                                                        \
612 			CLK(BCLK);                                                      \
613 			FLAG_C  = REG_A << 1;                                           \
614 			FLAG_NZ = REG_A = MAKE_UINT_8(FLAG_C)
615 
616 /* Arithmetic Shift Left operand */
617 #define OP_ASLM(BCLK, MODE)                                                 \
618 			CLK(BCLK);                                                      \
619 			DST     = EA_##MODE();                                          \
620 			FLAG_C  = read_8_##MODE(DST) << 1;                              \
621 			FLAG_NZ = MAKE_UINT_8(FLAG_C);                                  \
622 			write_8_##MODE(DST, FLAG_NZ)
623 
624 /* Branch if Bit Reset */
625 #define OP_BBC(BCLK, BIT)                                                   \
626 			CLK(BCLK);                                                      \
627 			SRC     = OPER_8_DP();                                          \
628 			DST     = OPER_8_IMM();                                         \
629 			if(!(SRC & BIT))                                                \
630 			{                                                               \
631 				CLK(2);                                                     \
632 				BRANCH(DST);                                              \
633 			}
634 
635 /* Branch if Bit Set */
636 #define OP_BBS(BCLK, BIT)                                                   \
637 			CLK(BCLK);                                                      \
638 			SRC     = OPER_8_DP();                                          \
639 			DST     = OPER_8_IMM();                                         \
640 			if(SRC & BIT)                                                   \
641 			{                                                               \
642 				CLK(2);                                                     \
643 				BRANCH(DST);                                              \
644 			}
645 
646 /* Branch on Condition Code */
647 #define OP_BCC(BCLK, COND)                                                  \
648 			CLK(BCLK);                                                      \
649 			DST     = OPER_8_IMM();                                         \
650 			if(COND)                                                        \
651 			{                                                               \
652 				CLK(2);                                                     \
653 				BRANCH(DST);                                              \
654 			}
655 
656 /* Branch Unconditional */
657 /* speed up busy loops */
658 #define OP_BRA(BCLK)                                                        \
659 			CLK(BCLK);                                                      \
660 			BRANCH(OPER_8_IMM());                                         \
661 			if(REG_PC == REG_PPC)                                           \
662 				CLK_ALL()
663 
664 /* Cause a Break interrupt */
665 #define OP_BRK(BCLK)                                                        \
666 			CLK(BCLK);                                                      \
667 			PUSH_16(REG_PC);                                              \
668 			PUSH_8(GET_REG_P());                                      \
669 			FLAG_B |= FLAGPOS_B;                                                \
670 			FLAG_I = IFLAG_CLEAR;                                               \
671 			JUMP(read_16_VEC(VECTOR_BRK))
672 
673 /* Call subroutine */
674 #define OP_CALL(BCLK)                                                       \
675 			CLK(BCLK);                                                      \
676 			DST     = EA_ABS();                                             \
677 			PUSH_16(REG_PC);                                              \
678 			JUMP(DST)
679 
680 /* Compare accumulator and branch if not equal */
681 #define OP_CBNE(BCLK, MODE)                                                 \
682 			CLK(BCLK);                                                      \
683 			SRC     = OPER_8_##MODE();                                      \
684 			DST     = EA_IMM();                                             \
685 			if(SRC != REG_A)                                                \
686 			{                                                               \
687 				CLK(2);                                                     \
688 				BRANCH(read_8_IMM(DST));                                  \
689 			}
690 
691 /* Clear Carry flag */
692 #define OP_CLRC(BCLK)                                                       \
693 			CLK(BCLK);                                                      \
694 			FLAG_C  = CFLAG_CLEAR
695 
696 /* Clear Memory Bit */
697 #define OP_CLR(BCLK, BIT)                                                   \
698 			CLK(BCLK);                                                      \
699 			DST     = EA_DP();                                              \
700 			SRC     = read_8_DP(DST) & ~BIT;                                \
701 			write_8_DP(DST, SRC)
702 
703 /* Clear Overflow flag (also clears half-carry) */
704 #define OP_CLRV(BCLK)                                                       \
705 			CLK(BCLK);      \
706 			FLAG_V = VFLAG_CLEAR;   \
707 			FLAG_H = 0;
708 
709 /* Clear the Page flag */
710 #define OP_CLRP(BCLK)                                                       \
711 			CLK(BCLK);                                                      \
712 			FLAG_P  = PFLAG_CLEAR
713 
714 /* Compare operand to register */
715 #define OP_CMPR(BCLK, REG, MODE)                                            \
716 			CLK(BCLK);              \
717 			SRC     = OPER_8_##MODE();      \
718 			m_spc_int16 = (short)REG - (short)SRC;  \
719 			FLAG_C  = (m_spc_int16 >= 0) ? CFLAG_SET : 0;   \
720 			FLAG_NZ = MAKE_UINT_8(m_spc_int16);
721 
722 /* Compare memory */
723 #define OP_CMPM(BCLK, SMODE, DMODE)                                         \
724 			CLK(BCLK);              \
725 			SRC     = OPER_8_##SMODE();     \
726 			m_spc_int16 = (short)OPER_8_##DMODE() - (short)SRC; \
727 			FLAG_C  = (m_spc_int16 >= 0) ? CFLAG_SET : 0;    \
728 			FLAG_NZ = MAKE_UINT_8(m_spc_int16);
729 
730 /* Compare word */
731 #define OP_CMPW(BCLK, MODE)                                                 \
732 			CLK(BCLK);                                                      \
733 			SRC     = OPER_16_##MODE();                                     \
734 			m_spc_int32 = (int)GET_REG_YA() - (int)SRC;                             \
735 			FLAG_C  = (m_spc_int32 >= 0) ? CFLAG_SET : 0;                                   \
736 			FLAG_NZ = NZFLAG_16(m_spc_int32);
737 
738 /* Decimal adjust for addition */
739 #define OP_DAA(BCLK)                    \
740 			CLK(BCLK);              \
741 			SRC = REG_A;            \
742 			if (((SRC & 0x0f) > 9) || (FLAG_H & HFLAG_SET)) \
743 			{               \
744 				REG_A += 6;     \
745 				if (REG_A < 6)      \
746 				{           \
747 					FLAG_C = CFLAG_SET; \
748 				}           \
749 			}               \
750 			if ((SRC > 0x99) || (FLAG_C & CFLAG_SET))   \
751 			{               \
752 				REG_A += 0x60;      \
753 				FLAG_C = CFLAG_SET; \
754 			}               \
755 			FLAG_NZ = REG_A = MAKE_UINT_8(REG_A);
756 
757 /* Decimal adjust for subtraction */
758 #define OP_DAS(BCLK)                                                        \
759 			CLK(BCLK);          \
760 			SRC = REG_A;            \
761 			if (!(FLAG_H & HFLAG_SET) || ((SRC & 0xf) > 9)) \
762 			{               \
763 				REG_A -= 6;     \
764 			}               \
765 			if (!(FLAG_C & CFLAG_SET) || (SRC > 0x99))  \
766 			{               \
767 				REG_A -= 0x60;      \
768 				FLAG_C = 0;     \
769 			}               \
770 			FLAG_NZ = REG_A = MAKE_UINT_8(REG_A)
771 
772 /* Decrement register and branch if not zero */
773 /* speed up busy loops */
774 #define OP_DBNZR(BCLK)                                                      \
775 			CLK(BCLK);                                                      \
776 			REG_Y  = MAKE_UINT_8(REG_Y - 1);                                \
777 			DST    = EA_IMM();                                              \
778 			if(REG_Y != 0)                                                  \
779 			{                                                               \
780 				CLK(2);                                                     \
781 				BRANCH(read_8_IMM(DST));                                  \
782 			}
783 
784 /* Decrement operand and branch if not zero */
785 /* Speed up busy loops but do reads/writes for compatibility */
786 #define OP_DBNZM(BCLK)                                                      \
787 			CLK(BCLK);                                                      \
788 			DST     = EA_DP();                                              \
789 			SRC     = MAKE_UINT_8(read_8_DP(DST) - 1);                      \
790 			write_8_DP(DST, SRC);                                           \
791 			DST = EA_IMM();                                                 \
792 			if(SRC != 0)                                                    \
793 			{                                                               \
794 				CLK(2);                                                     \
795 				BRANCH(read_8_IMM(DST));                                  \
796 			}
797 
798 /* Decrement register */
799 #define OP_DECR(BCLK, REG)                                                  \
800 			CLK(BCLK);                                                      \
801 			FLAG_NZ = REG = MAKE_UINT_8(REG - 1)
802 
803 /* Decrement operand */
804 #define OP_DECM(BCLK, MODE)                                                 \
805 			CLK(BCLK);                                                      \
806 			DST     = EA_##MODE();                                          \
807 			FLAG_NZ = MAKE_UINT_8(read_8_##MODE(DST) - 1);                  \
808 			write_8_##MODE(DST, FLAG_NZ)
809 
810 /* Decrement word */
811 #define OP_DECW(BCLK)                                                       \
812 			CLK(BCLK);                                                      \
813 			DST     = EA_DP();                                              \
814 			FLAG_NZ = MAKE_UINT_16(read_16_DP(DST) - 1);                    \
815 			write_16_DP(DST, FLAG_Z);                                       \
816 			FLAG_NZ = NZFLAG_16(FLAG_Z)
817 
818 /* Disable interrupts */
819 #define OP_DI(BCLK)                                                         \
820 			CLK(BCLK);                                                      \
821 			FLAG_I  = IFLAG_CLEAR
822 
823 /* Divide - should be almost exactly how the hardware works */
824 #define OP_DIV(BCLK)                                                        \
825 			CLK(BCLK);      \
826 			TMP1 = SRC = GET_REG_YA();  \
827 			TMP2 = (REG_X << 9);    \
828 			FLAG_H = 0; \
829 			if ((REG_Y & 0xf) >= (REG_X & 0xf)) FLAG_H = HFLAG_SET; \
830 			for (TMP3 = 0; TMP3 < 9; TMP3++)    \
831 			{           \
832 				TMP1 <<= 1; \
833 				if (TMP1 & 0x20000) TMP1 = (TMP1 & 0x1ffff) | 1;    \
834 				if (TMP1 >= TMP2) TMP1 ^= 1;    \
835 				if (TMP1 & 1) TMP1 = ((TMP1 - TMP2) & 0x1ffff); \
836 			}           \
837 			FLAG_V = (TMP1 & 0x100) ? VFLAG_SET : 0;    \
838 			SET_REG_YA((((TMP1 >> 9) & 0xff) << 8) + (TMP1 & 0xff));  \
839 			FLAG_NZ = MAKE_UINT_8(GET_REG_YA());
840 
841 /* Enable interrupts */
842 #define OP_EI(BCLK)                                                         \
843 			CLK(BCLK);                                                      \
844 			FLAG_I  = IFLAG_SET
845 
846 /* Exclusive Or operand to accumulator */
847 #define OP_EOR(BCLK, MODE)                                                  \
848 			CLK(BCLK);                                                      \
849 			FLAG_NZ = REG_A ^= OPER_8_##MODE()
850 
851 /* Logical EOR operand */
852 #define OP_EORM(BCLK, SMODE, DMODE)                                         \
853 			CLK(BCLK);                                                      \
854 			FLAG_NZ = OPER_8_##SMODE();                                     \
855 			DST     = EA_##DMODE();                                         \
856 			FLAG_NZ ^= read_8_##DMODE(DST);                                 \
857 			write_8_##DMODE(DST, FLAG_NZ)
858 
859 /* Exclusive OR bit to C */
860 #define OP_EOR1(BCLK)                                                       \
861 			CLK(BCLK);                                                      \
862 			DST     = OPER_16_IMM();                                        \
863 			SRC     = 1 << (DST >> 13);                                     \
864 			DST     &= 0x1fff;                                              \
865 			if(read_8_NORM(DST) & SRC)                                      \
866 				FLAG_C = ~FLAG_C
867 
868 /* Increment register */
869 #define OP_INCR(BCLK, REG)                                                  \
870 			CLK(BCLK);                                                      \
871 			FLAG_NZ = REG = MAKE_UINT_8(REG + 1)
872 
873 /* Increment operand */
874 #define OP_INCM(BCLK, MODE)                                                 \
875 			CLK(BCLK);                                                      \
876 			DST     = EA_##MODE();                                          \
877 			FLAG_NZ = MAKE_UINT_8(read_8_##MODE(DST) + 1);                  \
878 			write_8_##MODE(DST, FLAG_NZ)
879 
880 /* Increment word */
881 #define OP_INCW(BCLK)                                                       \
882 			CLK(BCLK);                                                      \
883 			DST     = EA_DP();                                              \
884 			FLAG_NZ = MAKE_UINT_16(read_16_DP(DST) + 1);                    \
885 			write_16_DP(DST, FLAG_Z);                                       \
886 			FLAG_NZ = NZFLAG_16(FLAG_Z)
887 
888 /* Jump */
889 /* If we're in a busy loop, eat all clock cycles */
890 #define OP_JMP(BCLK, MODE)                                                  \
891 			CLK(BCLK);                                                      \
892 			JUMP(EA_##MODE());                                                \
893 			if(REG_PC == REG_PPC)                                           \
894 				CLK_ALL()
895 
896 /* Jump to Subroutine */
897 #define OP_JSR(BCLK, MODE)                                                  \
898 			CLK(BCLK);                                                      \
899 			PUSH_16(REG_PC);                                              \
900 			JUMP(EA_##MODE())
901 
902 /* Logical Shift Right accumulator */
903 #define OP_LSR(BCLK)                                                        \
904 			CLK(BCLK);                                                      \
905 			FLAG_C = REG_A << 8;                                            \
906 			FLAG_NZ = REG_A >>= 1
907 
908 /* Logical Shift Right operand */
909 #define OP_LSRM(BCLK, MODE)                                                 \
910 			CLK(BCLK);                                                      \
911 			DST     = EA_##MODE();                                          \
912 			FLAG_NZ = read_8_##MODE(DST);                                   \
913 			FLAG_C  = FLAG_N << 8;                                          \
914 			FLAG_NZ >>= 1;                                                  \
915 			write_8_##MODE(DST, FLAG_NZ)
916 
917 /* Move from register to register */
918 #define OP_MOVRR(BCLK, SREG, DREG)                                          \
919 			CLK(BCLK);                                                      \
920 			FLAG_NZ = DREG = SREG
921 
922 /* Move from register to memory */
923 #define OP_MOVRM(BCLK, SREG, DMODE)                                         \
924 			CLK(BCLK);                                                      \
925 			write_8_##DMODE(EA_##DMODE(), SREG)
926 
927 /* Move from memory to register */
928 #define OP_MOVMR(BCLK, SMODE, DREG)                                         \
929 			CLK(BCLK);                                                      \
930 			FLAG_NZ = DREG = OPER_8_##SMODE()
931 
932 /* Move from memory to memory */
933 #define OP_MOVMM(BCLK, SMODE, DMODE)                                        \
934 			CLK(BCLK);                                                      \
935 			SRC     = OPER_8_##SMODE();                                     \
936 			DST     = EA_##DMODE();                                         \
937 			write_8_##DMODE(DST, SRC)
938 
939 /* Move word register to memory */
940 #define OP_MOVWRM(BCLK)                                                     \
941 			CLK(BCLK);                                                      \
942 			write_16_DP(EA_DP(), GET_REG_YA())
943 
944 /* Move word memory to register */
945 #define OP_MOVWMR(BCLK)                                                     \
946 			CLK(BCLK);                                                      \
947 			FLAG_NZ = OPER_16_DP();                                         \
948 			SET_REG_YA(FLAG_Z);                                           \
949 			FLAG_NZ = NZFLAG_16(FLAG_Z)
950 
951 /* Move from Stack pointer to X */
952 #define OP_MOVSX(BCLK)                                                      \
953 			CLK(BCLK);                                                      \
954 			FLAG_NZ = REG_X = REG_S
955 
956 /* Move from X to Stack pointer */
957 #define OP_MOVXS(BCLK)                                                      \
958 			CLK(BCLK);                                                      \
959 			REG_S  = REG_X
960 
961 /* Move bit from memory to C */
962 #define OP_MOV1C(BCLK)                                                      \
963 			CLK(BCLK);                                                      \
964 			DST     = OPER_16_IMM();                                        \
965 			SRC     = 1 << (DST >> 13);                                     \
966 			DST     &= 0x1fff;                                              \
967 			FLAG_C  = ((read_8_NORM(DST) & SRC) != 0) << 8
968 
969 /* Move bit from C to memory */
970 #define OP_MOV1M(BCLK)                                                      \
971 			CLK(BCLK);                                                      \
972 			DST     = OPER_16_IMM();                                        \
973 			SRC     = 1 << (DST >> 13);                                     \
974 			DST     &= 0x1fff;                                              \
975 			if(FLAG_C & CFLAG_SET)                                          \
976 				write_8_NORM(DST, read_8_NORM(DST) | SRC);                  \
977 			else                                                            \
978 				write_8_NORM(DST, read_8_NORM(DST) & ~SRC)
979 
980 
981 /* Multiply A and Y and store result in YA */
982 #define OP_MUL(BCLK)                                                        \
983 			CLK(BCLK);          \
984 			SRC = REG_Y * REG_A;        \
985 			REG_A = MAKE_UINT_8(SRC);   \
986 			FLAG_NZ = REG_Y = SRC >> 8;
987 
988 /* No Operation */
989 #define OP_NOP(BCLK)                                                        \
990 			CLK(BCLK)
991 
992 /* Invert the C flag */
993 #define OP_NOTC(BCLK)                                                       \
994 			CLK(BCLK);                                                      \
995 			FLAG_C  = ~FLAG_C
996 
997 /* NOT bit */
998 #define OP_NOT1(BCLK)                                                       \
999 			CLK(BCLK);                                                      \
1000 			DST     = OPER_16_IMM();                                        \
1001 			SRC     = 1 << (DST >> 13);                                     \
1002 			DST     &= 0x1fff;                                              \
1003 			write_8_NORM(DST, read_8_NORM(DST) ^ SRC)
1004 
1005 /* Logical OR operand to accumulator */
1006 #define OP_OR(BCLK, MODE)                                                   \
1007 			CLK(BCLK);                                                      \
1008 			FLAG_NZ = REG_A |= OPER_8_##MODE()
1009 
1010 /* Logical OR operand */
1011 #define OP_ORM(BCLK, SMODE, DMODE)                                          \
1012 			CLK(BCLK);                                                      \
1013 			FLAG_NZ = OPER_8_##SMODE();                                     \
1014 			DST     = EA_##DMODE();                                         \
1015 			FLAG_NZ |= read_8_##DMODE(DST);                                 \
1016 			write_8_##DMODE(DST, FLAG_NZ)
1017 
1018 /* Logical OR bit to C */
1019 #define OP_OR1(BCLK)                                                        \
1020 			CLK(BCLK);                                                      \
1021 			DST = EA_IMM16();                                               \
1022 			if(!(FLAG_C & CFLAG_SET))                                       \
1023 			{                                                               \
1024 				DST = read_16_IMM(DST);                                     \
1025 				SRC = 1 << (DST >> 13);                                     \
1026 				DST &= 0x1fff;                                              \
1027 				if(read_8_NORM(DST) & SRC)                                  \
1028 					FLAG_C = CFLAG_SET;                                     \
1029 			}
1030 
1031 /* OR negated bit to C */
1032 #define OP_ORN1(BCLK)                                                       \
1033 			CLK(BCLK);                                                      \
1034 			DST = EA_IMM16();                                               \
1035 			if(!(FLAG_C & CFLAG_SET))                                       \
1036 			{                                                               \
1037 				DST = read_16_IMM(DST);                                     \
1038 				SRC = 1 << (DST >> 13);                                     \
1039 				DST &= 0x1fff;                                              \
1040 				if(!(read_8_NORM(DST) & SRC))                               \
1041 					FLAG_C = CFLAG_SET;                                     \
1042 			}
1043 
1044 /* UPage Call */
1045 #define OP_PCALL(BCLK)                                                      \
1046 			CLK(BCLK);                                                      \
1047 			DST     = EA_DP();                                              \
1048 			PUSH_16(REG_PC);                                              \
1049 			JUMP(0xff00 | DST)
1050 
1051 /* Push a register to the stack */
1052 #define OP_PUSH(BCLK, REG)                                                  \
1053 			CLK(BCLK);                                                      \
1054 			PUSH_8(REG)
1055 
1056 /* Push the Processor Status Register to the stack */
1057 #define OP_PHP(BCLK)                                                        \
1058 			CLK(BCLK);                                                      \
1059 			PUSH_8(GET_REG_P())
1060 
1061 /* Pull a register from the stack */
1062 #define OP_PULL(BCLK, REG)                                                  \
1063 			CLK(BCLK);                                                      \
1064 			REG     = PULL_8()
1065 
1066 /* Pull the Processor Status Register from the stack */
1067 #define OP_PLP(BCLK)                                                        \
1068 			CLK(BCLK);                                                      \
1069 			SET_REG_P(PULL_8())
1070 
1071 /* Return from Subroutine */
1072 #define OP_RET(BCLK)                                                        \
1073 			CLK(BCLK);                                                      \
1074 			JUMP(PULL_16())
1075 
1076 /* Return from Interrupt */
1077 #define OP_RETI(BCLK)                                                       \
1078 			CLK(BCLK);                                                      \
1079 			SET_REG_P(PULL_8());                                          \
1080 			JUMP(PULL_16())
1081 
1082 /* Rotate Left the accumulator */
1083 #define OP_ROL(BCLK)                                                        \
1084 			CLK(BCLK);                                                      \
1085 			FLAG_C  = (REG_A<<1) | CFLAG_1();                            \
1086 			FLAG_NZ = REG_A = MAKE_UINT_8(FLAG_C)
1087 
1088 /* Rotate Left an operand */
1089 #define OP_ROLM(BCLK, MODE)                                                 \
1090 			CLK(BCLK);                                                      \
1091 			DST     = EA_##MODE();                                          \
1092 			FLAG_C  = (read_8_##MODE(DST)<<1) | CFLAG_1();               \
1093 			FLAG_NZ = MAKE_UINT_8(FLAG_C);                                  \
1094 			write_8_##MODE(DST, FLAG_NZ)
1095 
1096 /* Rotate Right the accumulator */
1097 #define OP_ROR(BCLK)                                                        \
1098 			CLK(BCLK);                                                      \
1099 			REG_A   |= FLAG_C & 0x100;                                      \
1100 			FLAG_C  = REG_A << 8;                                           \
1101 			FLAG_NZ = REG_A >>= 1
1102 
1103 /* Rotate Right an operand */
1104 #define OP_RORM(BCLK, MODE)                                                 \
1105 			CLK(BCLK);                                                      \
1106 			DST     = EA_##MODE();                                          \
1107 			FLAG_NZ = read_8_##MODE(DST) | (FLAG_C & 0x100);                \
1108 			FLAG_C  = FLAG_N << 8;                                          \
1109 			FLAG_NZ >>= 1;                                                  \
1110 			write_8_##MODE(DST, FLAG_NZ)
1111 
1112 /* Subtract with Carry */
1113 #define OP_SBC(BCLK, MODE)                  \
1114 			CLK(BCLK);              \
1115 			SRC     = OPER_8_##MODE();      \
1116 			TMP2 = REG_A - SRC - (CFLAG_1() ^ 1); \
1117 			SUBOP_ADC(REG_A, ~SRC);         \
1118 			FLAG_C = (TMP2 <= 0xff) ? CFLAG_SET : 0; \
1119 			REG_A = (uint8_t)m_spc_int16;
1120 
1121 /* Subtract With Carry to memory */
1122 #define OP_SBCM(BCLK, SMODE, DMODE)             \
1123 			CLK(BCLK);              \
1124 			SRC     = OPER_8_##SMODE();     \
1125 			DST     = EA_##DMODE();         \
1126 			TMP3 = read_8_##DMODE(DST);     \
1127 			TMP2 = TMP3 - SRC - (CFLAG_1() ^ 1); \
1128 			SUBOP_ADC(~SRC, TMP3);          \
1129 			FLAG_C = (TMP2 <= 0xff) ? CFLAG_SET : 0; \
1130 			write_8_##DMODE(DST, (uint8_t)m_spc_int16)
1131 
1132 /* Set Carry flag */
1133 #define OP_SETC(BCLK)                                                       \
1134 			CLK(BCLK);                                                      \
1135 			FLAG_C  = CFLAG_SET
1136 
1137 /* Set Page flag */
1138 #define OP_SETP(BCLK)                                                       \
1139 			CLK(BCLK);                                                      \
1140 			FLAG_P  = PFLAG_SET
1141 
1142 /* Set Memory Bit */
1143 #define OP_SET(BCLK, BIT)                                                   \
1144 			CLK(BCLK);                                                      \
1145 			DST    = EA_DP();                                               \
1146 			SRC    = read_8_DP(DST) | BIT;                                  \
1147 			write_8_DP(DST, SRC)
1148 
1149 /* Put the CPU to sleep */
1150 #define OP_SLEEP(BCLK)                                                      \
1151 			CLK(BCLK);                                                      \
1152 			CPU_STOPPED |= STOP_LEVEL_SLEEP;                                \
1153 			CLK_ALL()
1154 
1155 /* Stop the CPU */
1156 #define OP_STOP(BCLK)                                                       \
1157 			CLK(BCLK);                                                      \
1158 			CPU_STOPPED |= STOP_LEVEL_STOP;                                 \
1159 			CLK_ALL()
1160 
1161 /* Subtract word */
1162 #define OP_SUBW(BCLK)                       \
1163 			CLK(BCLK);              \
1164 			SRC = OPER_16_DP();         \
1165 			DST = GET_REG_YA();         \
1166 			TMP1 = ((DST) & 0xff) - ((SRC) & 0xff); \
1167 			TMP2 = (TMP1 > 0xff) ? 1 : 0;       \
1168 			TMP3 = ((DST) >> 8) - ((SRC) >> 8) - TMP2;  \
1169 			m_spc_int16 = ((TMP1 & 0xff) + (TMP3 << 8)) & 0xffff;   \
1170 			FLAG_C = (TMP3 <= 0xff) ? CFLAG_SET : 0;    \
1171 			FLAG_H = ((unsigned) ((((DST) >> 8) & 0x0F) - \
1172 				(((SRC) >> 8) & 0x0F) - TMP2)) > 0x0F ?  0: HFLAG_SET; \
1173 			FLAG_V = (((DST) ^ (SRC)) & ((DST) ^ (uint16_t) m_spc_int16) & 0x8000) ? VFLAG_SET : 0; \
1174 			FLAG_Z = (m_spc_int16 != 0);        \
1175 			FLAG_N = (m_spc_int16>>8);      \
1176 			SET_REG_YA(m_spc_int16);
1177 
1178 /* Table Call */
1179 #define OP_TCALL(BCLK, NUM)                                                 \
1180 			CLK(BCLK);                                                      \
1181 			PUSH_16(REG_PC);                                              \
1182 			JUMP(read_16_NORM(0xffc0 + ((15-NUM)<<1)))
1183 
1184 /* Test and Clear Bits */
1185 #define OP_TCLR1(BCLK, MODE)                                                \
1186 			CLK(BCLK);                                                      \
1187 			DST     = EA_##MODE();                                          \
1188 			FLAG_NZ = read_8_##MODE(DST);                                   \
1189 			m_spc_int16 = (short)REG_A - (short)(read_8_##MODE(DST)); \
1190 			write_8_##MODE(DST, FLAG_NZ & ~REG_A); \
1191 			FLAG_NZ = MAKE_UINT_8(m_spc_int16);
1192 
1193 /* Test and Set Bits */
1194 #define OP_TSET1(BCLK, MODE)                                                \
1195 			CLK(BCLK);                                                      \
1196 			DST     = EA_##MODE();                                          \
1197 			FLAG_NZ = read_8_##MODE(DST);                                   \
1198 		m_spc_int16 = (short)REG_A - (short)(read_8_##MODE(DST)); \
1199 		write_8_##MODE(DST, FLAG_NZ | REG_A); \
1200 		FLAG_NZ = MAKE_UINT_8(m_spc_int16);
1201 
1202 /* Exchange high and low nybbles of accumulator */
1203 #define OP_XCN(BCLK)                                                        \
1204 			CLK(BCLK);                                                      \
1205 			FLAG_NZ = REG_A = MAKE_UINT_8((REG_A<<4) | (REG_A>>4))
1206 
1207 #define OP_ILLEGAL(BCLK)                                                    \
1208 			CLK(BCLK)
1209 
1210 
1211 /* ======================================================================== */
1212 /* ================================= API ================================== */
1213 /* ======================================================================== */
1214 
device_start()1215 void spc700_device::device_start()
1216 {
1217 	m_program = &space(AS_PROGRAM);
1218 
1219 	save_item(NAME(m_a));
1220 	save_item(NAME(m_x));
1221 	save_item(NAME(m_y));
1222 	save_item(NAME(m_s));
1223 	save_item(NAME(m_pc));
1224 	save_item(NAME(m_ppc));
1225 	save_item(NAME(m_flag_n));
1226 	save_item(NAME(m_flag_z));
1227 	save_item(NAME(m_flag_v));
1228 	save_item(NAME(m_flag_p));
1229 	save_item(NAME(m_flag_b));
1230 	save_item(NAME(m_flag_h));
1231 	save_item(NAME(m_flag_i));
1232 	save_item(NAME(m_flag_c));
1233 	save_item(NAME(m_line_irq));
1234 	save_item(NAME(m_line_nmi));
1235 	save_item(NAME(m_line_rst));
1236 	save_item(NAME(m_ir));
1237 	save_item(NAME(m_stopped));
1238 	save_item(NAME(m_ICount));
1239 	save_item(NAME(m_source));
1240 	save_item(NAME(m_destination));
1241 	save_item(NAME(m_temp1));
1242 	save_item(NAME(m_temp2));
1243 	save_item(NAME(m_temp3));
1244 	save_item(NAME(m_spc_int16));
1245 	save_item(NAME(m_spc_int32));
1246 
1247 	// Register state for debugger
1248 	state_add( SPC700_PC, "PC", m_pc            ).formatstr("%04X");
1249 	state_add( SPC700_S,  "S",  m_s             ).formatstr("%02X");
1250 	state_add( SPC700_P,  "P",  m_debugger_temp ).callimport().callexport().formatstr("%02X");
1251 	state_add( SPC700_A,  "A",  m_a             ).formatstr("%02X");
1252 	state_add( SPC700_X,  "X",  m_x             ).formatstr("%02X");
1253 	state_add( SPC700_Y,  "Y",  m_y             ).formatstr("%02X");
1254 
1255 	state_add(STATE_GENPC, "GENPC", m_pc).formatstr("%04X").noshow();
1256 	state_add(STATE_GENPCBASE, "CURPC", m_ppc).formatstr("%04X").noshow();
1257 	state_add(STATE_GENSP, "GENSP", m_debugger_temp).mask(0x1ff).callexport().formatstr("%04X").noshow();
1258 	state_add(STATE_GENFLAGS, "GENFLAGS",  m_debugger_temp).formatstr("%8s").noshow();
1259 
1260 	set_icountptr(m_ICount);
1261 }
1262 
1263 
state_string_export(const device_state_entry & entry,std::string & str) const1264 void spc700_device::state_string_export(const device_state_entry &entry, std::string &str) const
1265 {
1266 	switch (entry.index())
1267 	{
1268 		case STATE_GENFLAGS:
1269 			str = string_format("%c%c%c%c%c%c%c%c",
1270 				(FLAG_N & 0x80)      ? 'N':'.',
1271 				(FLAG_V & 0x80)      ? 'V':'.',
1272 				(FLAG_P)             ? 'P':'.',
1273 				(FLAG_B)             ? 'B':'.',
1274 				(FLAG_H & HFLAG_SET) ? 'H':'.',
1275 				(FLAG_I)             ? 'I':'.',
1276 				(!FLAG_Z)            ? 'Z':'.',
1277 				(FLAG_C & 0x100)     ? 'C':'.'
1278 			);
1279 			break;
1280 	}
1281 }
1282 
1283 
state_import(const device_state_entry & entry)1284 void spc700_device::state_import(const device_state_entry &entry)
1285 {
1286 	switch (entry.index())
1287 	{
1288 		case SPC700_P:
1289 			SET_REG_P(m_debugger_temp);
1290 			break;
1291 	}
1292 }
1293 
1294 
state_export(const device_state_entry & entry)1295 void spc700_device::state_export(const device_state_entry &entry)
1296 {
1297 	switch (entry.index())
1298 	{
1299 		case SPC700_P:
1300 			m_debugger_temp = ((FLAG_N & 0x80)          |
1301 					((FLAG_V & 0x80) >> 1)    |
1302 					FLAG_P>>3             |
1303 					FLAG_B                    |
1304 					(FLAG_H & HFLAG_SET)  |
1305 					FLAG_I                    |
1306 					((!FLAG_Z) << 1)      |
1307 					((FLAG_C >> 8)&1));
1308 			break;
1309 
1310 		case STATE_GENSP:
1311 			m_debugger_temp = m_s + STACK_PAGE;
1312 			break;
1313 	}
1314 }
1315 
1316 
device_reset()1317 void spc700_device::device_reset()
1318 {
1319 	CPU_STOPPED = 0;
1320 	LINE_IRQ = 0;
1321 	LINE_NMI = 0;
1322 	REG_S   = 0;
1323 	FLAG_NZ = NZFLAG_CLEAR;
1324 	FLAG_V  = VFLAG_CLEAR;
1325 	FLAG_P  = PFLAG_CLEAR;
1326 	FLAG_B  = BFLAG_CLEAR;
1327 	FLAG_H  = HFLAG_CLEAR;
1328 	FLAG_I  = IFLAG_CLEAR;
1329 	FLAG_C  = CFLAG_CLEAR;
1330 	JUMP(read_16_VEC(VECTOR_RST));
1331 }
1332 
1333 
execute_set_input(int inptnum,int state)1334 void spc700_device::execute_set_input( int inptnum, int state )
1335 {
1336 	if ( inptnum == INPUT_LINE_NMI )
1337 	{
1338 		/* Assert or clear the NMI line of the CPU */
1339 #if !SPC700_OPTIMIZE_SNES
1340 		if(state == CLEAR_LINE)
1341 			LINE_NMI = 0;
1342 		else if(!LINE_NMI)
1343 		{
1344 			LINE_NMI = 1;
1345 			CLK(7);
1346 			PUSH_16(REG_PC);
1347 			PUSH_8(GET_REG_P());
1348 			JUMP(read_16_VEC(VECTOR_NMI));
1349 		}
1350 #endif /* SPC700_OPTIMIZE_SNES */
1351 	}
1352 	else
1353 	{
1354 		/* Assert or clear the IRQ line of the CPU */
1355 #if !SPC700_OPTIMIZE_SNES
1356 		LINE_IRQ = (state != CLEAR_LINE) ? IRQ_SET : IRQ_CLEAR;
1357 		CHECK_IRQ();
1358 #endif /* SPC700_OPTIMIZE_SNES */
1359 	}
1360 }
1361 
1362 #include "spc700ds.h"
1363 
create_disassembler()1364 std::unique_ptr<util::disasm_interface> spc700_device::create_disassembler()
1365 {
1366 	return std::make_unique<spc700_disassembler>();
1367 }
1368 
1369 //int dump_flag = 0;
1370 
1371 /* Execute instructions for <clocks> cycles */
execute_run()1372 void spc700_device::execute_run()
1373 {
1374 	if (CPU_STOPPED)
1375 	{
1376 		CLOCKS = 0;
1377 		return;
1378 	}
1379 	while(CLOCKS > 0)
1380 	{
1381 		REG_PPC = REG_PC;
1382 		debugger_instruction_hook(REG_PC);
1383 		REG_PC++;
1384 
1385 		switch(REG_IR = read_8_immediate(REG_PPC))
1386 		{
1387 			case 0x00: OP_NOP   ( 2               ); break; /* NOP           */
1388 			case 0x01: OP_TCALL ( 8, 0            ); break; /* TCALL 0       */
1389 			case 0x02: OP_SET   ( 4, BIT_0        ); break; /* SET 0         */
1390 			case 0x03: OP_BBS   ( 5, BIT_0        ); break; /* BBS 0         */
1391 
1392 			case 0x04: OP_OR    ( 3, DP           ); break; /* ORA dp        */
1393 			case 0x05: OP_OR    ( 4, ABS          ); break; /* ORA abs       */
1394 			case 0x06: OP_OR    ( 3, XI           ); break; /* ORA xi        */
1395 			case 0x07: OP_OR    ( 6, DXI          ); break; /* ORA dxi       */
1396 
1397 			case 0x08: OP_OR    ( 2, IMM          ); break; /* ORA imm       */
1398 			case 0x09: OP_ORM   ( 6, DP , DP      ); break; /* ORM dp dp     */
1399 			case 0x0a: OP_OR1   ( 5               ); break; /* OR1 bit       */
1400 			case 0x0b: OP_ASLM  ( 4, DP           ); break; /* ASL dp        */
1401 
1402 			case 0x0c: OP_ASLM  ( 5, ABS          ); break; /* ASL abs       */
1403 			case 0x0d: OP_PHP   ( 4               ); break; /* PHP           */
1404 			case 0x0e: OP_TSET1 ( 6, ABS          ); break; /* TSET1 abs     */
1405 			case 0x0f: OP_BRK   ( 8               ); break; /* BRK           */
1406 
1407 			case 0x10: OP_BCC   ( 2, COND_PL()    ); break; /* BPL           */
1408 			case 0x11: OP_TCALL ( 8, 1            ); break; /* TCALL 1       */
1409 			case 0x12: OP_CLR   ( 4, BIT_0        ); break; /* CLR 0         */
1410 			case 0x13: OP_BBC   ( 5, BIT_0        ); break; /* BBC 0         */
1411 
1412 			case 0x14: OP_OR    ( 4, DPX          ); break; /* ORA dpx       */
1413 			case 0x15: OP_OR    ( 5, ABX          ); break; /* ORA abx       */
1414 			case 0x16: OP_OR    ( 5, ABY          ); break; /* ORA aby       */
1415 			case 0x17: OP_OR    ( 6, DIY          ); break; /* ORA diy       */
1416 
1417 			case 0x18: OP_ORM   ( 5, IMM, DP      ); break; /* ORM dp, imm   */
1418 			case 0x19: OP_ORM   ( 5, YI, XI       ); break; /* ORM xi, yi    */
1419 			case 0x1a: OP_DECW  ( 6               ); break; /* DECW di       */
1420 			case 0x1b: OP_ASLM  ( 5, DPX          ); break; /* ASL dpx       */
1421 
1422 			case 0x1c: OP_ASL   ( 2               ); break; /* ASL a         */
1423 			case 0x1d: OP_DECR  ( 2, REG_X        ); break; /* DEC x         */
1424 			case 0x1e: OP_CMPR  ( 4, REG_X, ABS   ); break; /* CMP x, abs    */
1425 			case 0x1f: OP_JMP   ( 6, AXI          ); break; /* JMP axi       */
1426 
1427 			case 0x20: OP_CLRP  ( 2               ); break; /* CLRP          */
1428 			case 0x21: OP_TCALL ( 8, 2            ); break; /* TCALL 2       */
1429 			case 0x22: OP_SET   ( 4, BIT_1        ); break; /* SET 1         */
1430 			case 0x23: OP_BBS   ( 5, BIT_1        ); break; /* BBS 1         */
1431 
1432 			case 0x24: OP_AND   ( 3, DP           ); break; /* AND dp        */
1433 			case 0x25: OP_AND   ( 4, ABS          ); break; /* AND abs       */
1434 			case 0x26: OP_AND   ( 3, XI           ); break; /* AND xi        */
1435 			case 0x27: OP_AND   ( 6, DXI          ); break; /* AND dxi       */
1436 
1437 			case 0x28: OP_AND   ( 2, IMM          ); break; /* AND imm       */
1438 			case 0x29: OP_ANDM  ( 6, DP , DP      ); break; /* AND dp, dp    */
1439 			case 0x2a: OP_ORN1  ( 5               ); break; /* OR1 !bit      */
1440 			case 0x2b: OP_ROLM  ( 4, DP           ); break; /* ROL dp        */
1441 
1442 			case 0x2c: OP_ROLM  ( 5, ABS          ); break; /* ROL abs       */
1443 			case 0x2d: OP_PUSH  ( 4, REG_A        ); break; /* PUSH a        */
1444 			case 0x2e: OP_CBNE  ( 5, DP           ); break; /* CBNE dp       */
1445 			case 0x2f: OP_BRA   ( 4               ); break; /* BRA           */
1446 
1447 			case 0x30: OP_BCC   ( 2, COND_MI()    ); break; /* BMI           */
1448 			case 0x31: OP_TCALL ( 8, 3            ); break; /* TCALL 3       */
1449 			case 0x32: OP_CLR   ( 4, BIT_1        ); break; /* CLR 1         */
1450 			case 0x33: OP_BBC   ( 5, BIT_1        ); break; /* BBC 1         */
1451 
1452 			case 0x34: OP_AND   ( 4, DPX          ); break; /* AND dpx       */
1453 			case 0x35: OP_AND   ( 5, ABX          ); break; /* AND abx       */
1454 			case 0x36: OP_AND   ( 5, ABY          ); break; /* AND aby       */
1455 			case 0x37: OP_AND   ( 6, DIY          ); break; /* AND diy       */
1456 
1457 			case 0x38: OP_ANDM  ( 5, IMM, DP      ); break; /* AND dp, imm   */
1458 			case 0x39: OP_ANDM  ( 5, YI , XI      ); break; /* AND xi, yi    */
1459 			case 0x3a: OP_INCW  ( 6               ); break; /* INCW di       */
1460 			case 0x3b: OP_ROLM  ( 5, DPX          ); break; /* ROL dpx       */
1461 
1462 			case 0x3c: OP_ROL   ( 2               ); break; /* ROL acc       */
1463 			case 0x3d: OP_INCR  ( 2, REG_X        ); break; /* INC x         */
1464 			case 0x3e: OP_CMPR  ( 3, REG_X, DP    ); break; /* CMP x, dp     */
1465 			case 0x3f: OP_CALL  ( 8               ); break; /* CALL abs      */
1466 
1467 			case 0x40: OP_SETP  ( 2               ); break; /* RTI           */
1468 			case 0x41: OP_TCALL ( 8, 4            ); break; /* TCALL 4       */
1469 			case 0x42: OP_SET   ( 4, BIT_2        ); break; /* SET 2         */
1470 			case 0x43: OP_BBS   ( 5, BIT_2        ); break; /* BBS 2         */
1471 
1472 			case 0x44: OP_EOR   ( 3, DP           ); break; /* EOR dp        */
1473 			case 0x45: OP_EOR   ( 4, ABS          ); break; /* EOR abs       */
1474 			case 0x46: OP_EOR   ( 3, XI           ); break; /* EOR xi        */
1475 			case 0x47: OP_EOR   ( 6, DXI          ); break; /* EOR dxi       */
1476 
1477 			case 0x48: OP_EOR   ( 2, IMM          ); break; /* EOR imm       */
1478 			case 0x49: OP_EORM  ( 6, DP, DP       ); break; /* EOR dp, dp    */
1479 			case 0x4a: OP_AND1  ( 4               ); break; /* AND1 bit      */
1480 			case 0x4b: OP_LSRM  ( 4, DP           ); break; /* LSR dp        */
1481 
1482 			case 0x4c: OP_LSRM  ( 5, ABS          ); break; /* LSR abs       */
1483 			case 0x4d: OP_PUSH  ( 4, REG_X        ); break; /* PUSH x        */
1484 			case 0x4e: OP_TCLR1 ( 6, ABS          ); break; /* TCLR1 abs     */
1485 			case 0x4f: OP_PCALL ( 6               ); break; /* PCALL         */
1486 
1487 			case 0x50: OP_BCC   ( 2, COND_VC()    ); break; /* BVC           */
1488 			case 0x51: OP_TCALL ( 8, 5            ); break; /* TCALL 5       */
1489 			case 0x52: OP_CLR   ( 4, BIT_2        ); break; /* CLR 2         */
1490 			case 0x53: OP_BBC   ( 5, BIT_2        ); break; /* BBC 2         */
1491 
1492 			case 0x54: OP_EOR   ( 4, DPX          ); break; /* EOR dpx       */
1493 			case 0x55: OP_EOR   ( 5, ABX          ); break; /* EOR abx       */
1494 			case 0x56: OP_EOR   ( 5, ABY          ); break; /* EOR aby       */
1495 			case 0x57: OP_EOR   ( 6, DIY          ); break; /* EOR diy       */
1496 
1497 			case 0x58: OP_EORM  ( 5, IMM, DP      ); break; /* EOR dp, imm   */
1498 			case 0x59: OP_EORM  ( 5, YI , XI      ); break; /* EOR xi, yi    */
1499 			case 0x5a: OP_CMPW  ( 4, DP           ); break; /* CMPW dp       */
1500 			case 0x5b: OP_LSRM  ( 5, DPX          ); break; /* LSR dpx       */
1501 
1502 			case 0x5c: OP_LSR   ( 2               ); break; /* LSR           */
1503 			case 0x5d: OP_MOVRR ( 2, REG_A, REG_X ); break; /* MOV X, A      */
1504 			case 0x5e: OP_CMPR  ( 4, REG_Y, ABS   ); break; /* CMP Y, abs    */
1505 			case 0x5f: OP_JMP   ( 3, ABS          ); break; /* JMP abs       */
1506 
1507 			case 0x60: OP_CLRC  ( 2               ); break; /* CLRC          */
1508 			case 0x61: OP_TCALL ( 8, 6            ); break; /* TCALL 6       */
1509 			case 0x62: OP_SET   ( 4, BIT_3        ); break; /* SET 3         */
1510 			case 0x63: OP_BBS   ( 5, BIT_3        ); break; /* BBS 3         */
1511 
1512 			case 0x64: OP_CMPR  ( 3, REG_A, DP    ); break; /* CMP A, dp     */
1513 			case 0x65: OP_CMPR  ( 4, REG_A, ABS   ); break; /* CMP A, abs    */
1514 			case 0x66: OP_CMPR  ( 3, REG_A, XI    ); break; /* CMP A, xi     */
1515 			case 0x67: OP_CMPR  ( 6, REG_A, DXI   ); break; /* CMP A, dxi    */
1516 
1517 			case 0x68: OP_CMPR  ( 2, REG_A, IMM   ); break; /* CMP A, imm    */
1518 			case 0x69: OP_CMPM  ( 6, DP, DP       ); break; /* CMP dp, dp    */
1519 			case 0x6a: OP_ANDN1 ( 4               ); break; /* AND1 !bit     */
1520 			case 0x6b: OP_RORM  ( 4, DP           ); break; /* ROR dp        */
1521 
1522 			case 0x6c: OP_RORM  ( 5, ABS          ); break; /* ROR abs       */
1523 			case 0x6d: OP_PUSH  ( 4, REG_Y        ); break; /* PUSH Y        */
1524 			case 0x6e: OP_DBNZM ( 5               ); break; /* DBNZ dp       */
1525 			case 0x6f: OP_RET   ( 5               ); break; /* RET           */
1526 
1527 			case 0x70: OP_BCC   ( 2, COND_VS()    ); break; /* BVS           */
1528 			case 0x71: OP_TCALL ( 8, 7            ); break; /* TCALL 7       */
1529 			case 0x72: OP_CLR   ( 4, BIT_3        ); break; /* CLR 3         */
1530 			case 0x73: OP_BBC   ( 5, BIT_3        ); break; /* BBC 3         */
1531 			case 0x74: OP_CMPR  ( 4, REG_A, DPX   ); break; /* CMP A, dpx    */
1532 			case 0x75: OP_CMPR  ( 5, REG_A, ABX   ); break; /* CMP A, abx    */
1533 			case 0x76: OP_CMPR  ( 5, REG_A, ABY   ); break; /* CMP A, aby    */
1534 			case 0x77: OP_CMPR  ( 6, REG_A, DIY   ); break; /* CMP A, diy    */
1535 
1536 			case 0x78: OP_CMPM  ( 5, IMM, DP      ); break; /* CMP dp, imm   */
1537 			case 0x79: OP_CMPM  ( 5, YI, XI       ); break; /* CMP xi, yi    */
1538 			case 0x7a: OP_ADDW  ( 5               ); break; /* ADDW di       */
1539 			case 0x7b: OP_RORM  ( 5, DPX          ); break; /* ROR dpx       */
1540 
1541 			case 0x7c: OP_ROR   ( 2               ); break; /* ROR A         */
1542 			case 0x7d: OP_MOVRR ( 2, REG_X, REG_A ); break; /* MOV A, X      */
1543 			case 0x7e: OP_CMPR  ( 3, REG_Y, DP    ); break; /* CMP Y, dp     */
1544 			case 0x7f: OP_RETI  ( 6               ); break; /* RETI          */
1545 
1546 			case 0x80: OP_SETC  ( 2               ); break; /* SETC          */
1547 			case 0x81: OP_TCALL ( 8, 8            ); break; /* TCALL 8       */
1548 			case 0x82: OP_SET   ( 4, BIT_4        ); break; /* SET 4         */
1549 			case 0x83: OP_BBS   ( 5, BIT_4        ); break; /* BBS 4         */
1550 
1551 			case 0x84: OP_ADC   ( 3, DP           ); break; /* ADC dp        */
1552 			case 0x85: OP_ADC   ( 4, ABS          ); break; /* ADC abs       */
1553 			case 0x86: OP_ADC   ( 3, XI           ); break; /* ADC xi        */
1554 			case 0x87: OP_ADC   ( 6, DXI          ); break; /* ADC dxi       */
1555 
1556 			case 0x88: OP_ADC   ( 2, IMM          ); break; /* ADC imm       */
1557 			case 0x89: OP_ADCM  ( 6, DP, DP       ); break; /* ADC dp, dp    */
1558 			case 0x8a: OP_EOR1  ( 5               ); break; /* EOR1 bit      */
1559 			case 0x8b: OP_DECM  ( 4, DP           ); break; /* DEC dp        */
1560 
1561 			case 0x8c: OP_DECM  ( 5, ABS          ); break; /* DEC abs       */
1562 			case 0x8d: OP_MOVMR ( 2, IMM, REG_Y   ); break; /* MOV Y, imm    */
1563 			case 0x8e: OP_PLP   ( 4               ); break; /* POP PSW       */
1564 			case 0x8f: OP_MOVMM ( 5, IMM, DP      ); break; /* MOV dp, imm   */
1565 
1566 			case 0x90: OP_BCC   ( 2, COND_CC()    ); break; /* BCC           */
1567 			case 0x91: OP_TCALL ( 8, 9            ); break; /* TCALL 9       */
1568 			case 0x92: OP_CLR   ( 4, BIT_4        ); break; /* CLR 4         */
1569 			case 0x93: OP_BBC   ( 5, BIT_4        ); break; /* BBC 4         */
1570 
1571 			case 0x94: OP_ADC   ( 4, DPX          ); break; /* ADC dpx       */
1572 			case 0x95: OP_ADC   ( 5, ABX          ); break; /* ADC abx       */
1573 			case 0x96: OP_ADC   ( 5, ABY          ); break; /* ADC aby       */
1574 			case 0x97: OP_ADC   ( 6, DIY          ); break; /* ADC diy       */
1575 
1576 			case 0x98: OP_ADCM  ( 5, IMM, DP      ); break; /* ADC dp, imm   */
1577 			case 0x99: OP_ADCM  ( 5, YI, XI       ); break; /* ADC xi, yi    */
1578 			case 0x9a: OP_SUBW  ( 5               ); break; /* SUBW dp       */
1579 			case 0x9b: OP_DECM  ( 5, DPX          ); break; /* DEC dpx       */
1580 
1581 			case 0x9c: OP_DECR  ( 2, REG_A        ); break; /* DEC A         */
1582 			case 0x9d: OP_MOVSX ( 2               ); break; /* MOV X, SP     */
1583 			case 0x9e: OP_DIV   (12               ); break; /* DIV YA, X     */
1584 			case 0x9f: OP_XCN   ( 5               ); break; /* XCN A         */
1585 
1586 			case 0xa0: OP_EI    ( 3               ); break; /* EI            */
1587 			case 0xa1: OP_TCALL ( 8, 10           ); break; /* TCALL 10      */
1588 			case 0xa2: OP_SET   ( 4, BIT_5        ); break; /* SET 5         */
1589 			case 0xa3: OP_BBS   ( 5, BIT_5        ); break; /* BBS 5         */
1590 
1591 			case 0xa4: OP_SBC   ( 3, DP           ); break; /* SBC dp        */
1592 			case 0xa5: OP_SBC   ( 4, ABS          ); break; /* SBC abs       */
1593 			case 0xa6: OP_SBC   ( 3, XI           ); break; /* SBC xi        */
1594 			case 0xa7: OP_SBC   ( 6, DXI          ); break; /* SBC dxi       */
1595 
1596 			case 0xa8: OP_SBC   ( 2, IMM          ); break; /* SBC imm       */
1597 			case 0xa9: OP_SBCM  ( 6, DP, DP       ); break; /* SBC dp, dp    */
1598 			case 0xaa: OP_MOV1C ( 4               ); break; /* MOV1 bit->C   */
1599 			case 0xab: OP_INCM  ( 4, DP           ); break; /* INC dp        */
1600 
1601 			case 0xac: OP_INCM  ( 5, ABS          ); break; /* INC abs       */
1602 			case 0xad: OP_CMPR  ( 2, REG_Y, IMM   ); break; /* CMP Y, imm    */
1603 			case 0xae: OP_PULL  ( 4, REG_A        ); break; /* POP A         */
1604 			case 0xaf: OP_MOVRM ( 4, REG_A, XII   ); break; /* MOV xii, A    */
1605 
1606 			case 0xb0: OP_BCC   ( 2, COND_CS()    ); break; /* BCS           */
1607 			case 0xb1: OP_TCALL ( 8, 11           ); break; /* TCALL 11      */
1608 			case 0xb2: OP_CLR   ( 4, BIT_5        ); break; /* CLR 5         */
1609 			case 0xb3: OP_BBC   ( 5, BIT_5        ); break; /* BBC 5         */
1610 
1611 			case 0xb4: OP_SBC   ( 4, DPX          ); break; /* SBC dpx       */
1612 			case 0xb5: OP_SBC   ( 5, ABX          ); break; /* SBC abx       */
1613 			case 0xb6: OP_SBC   ( 5, ABY          ); break; /* SBC aby       */
1614 			case 0xb7: OP_SBC   ( 6, DIY          ); break; /* SBC diy       */
1615 
1616 			case 0xb8: OP_SBCM  ( 5, IMM, DP      ); break; /* SBC dp, imm   */
1617 			case 0xb9: OP_SBCM  ( 5, YI, XI       ); break; /* SBC xi, yi    */
1618 			case 0xba: OP_MOVWMR( 5               ); break; /* MOVW YA, dp   */
1619 			case 0xbb: OP_INCM  ( 5, DPX          ); break; /* INC dpx       */
1620 
1621 			case 0xbc: OP_INCR  ( 2, REG_A        ); break; /* INC A         */
1622 			case 0xbd: OP_MOVXS ( 2               ); break; /* MOV SP, X     */
1623 			case 0xbe: OP_DAS   ( 3               ); break; /* DAS A         */
1624 			case 0xbf: OP_MOVMR ( 4, XII, REG_A   ); break; /* MOV A, xii    */
1625 
1626 			case 0xc0: OP_DI    ( 3               ); break; /* DI            */
1627 			case 0xc1: OP_TCALL ( 8, 12           ); break; /* TCALL 12      */
1628 			case 0xc2: OP_SET   ( 4, BIT_6        ); break; /* SET 6         */
1629 			case 0xc3: OP_BBS   ( 5, BIT_6        ); break; /* BBS 6         */
1630 			case 0xc4: OP_MOVRM ( 4, REG_A, DP    ); break; /* MOV dp, A     */
1631 			case 0xc5: OP_MOVRM ( 5, REG_A, ABS   ); break; /* MOV abs, A    */
1632 			case 0xc6: OP_MOVRM ( 4, REG_A, XI    ); break; /* MOV xi, A     */
1633 			case 0xc7: OP_MOVRM ( 7, REG_A, DXI   ); break; /* MOV dxi, A    */
1634 
1635 			case 0xc8: OP_CMPR  ( 2, REG_X, IMM   ); break; /* CMP X, imm    */
1636 			case 0xc9: OP_MOVRM ( 5, REG_X, ABS   ); break; /* MOV abs, X    */
1637 			case 0xca: OP_MOV1M ( 6               ); break; /* MOV1 C->bit   */
1638 			case 0xcb: OP_MOVRM ( 4, REG_Y, DP    ); break; /* MOV dp, Y     */
1639 
1640 			case 0xcc: OP_MOVRM ( 5, REG_Y, ABS   ); break; /* MOV abs, Y    */
1641 			case 0xcd: OP_MOVMR ( 2, IMM, REG_X   ); break; /* MOV X, imm    */
1642 			case 0xce: OP_PULL  ( 4, REG_X        ); break; /* POP X         */
1643 			case 0xcf: OP_MUL   ( 9               ); break; /* MUL YA        */
1644 
1645 			case 0xd0: OP_BCC   ( 2, COND_NE()    ); break; /* BNE           */
1646 			case 0xd1: OP_TCALL ( 8, 13           ); break; /* TCALL 13      */
1647 			case 0xd2: OP_CLR   ( 4, BIT_6        ); break; /* CLR 6         */
1648 			case 0xd3: OP_BBC   ( 5, BIT_6        ); break; /* BBC 6         */
1649 
1650 			case 0xd4: OP_MOVRM ( 5, REG_A, DPX   ); break; /* MOV dpx, A    */
1651 			case 0xd5: OP_MOVRM ( 6, REG_A, ABX   ); break; /* MOV abx, A    */
1652 			case 0xd6: OP_MOVRM ( 6, REG_A, ABY   ); break; /* MOV aby, A    */
1653 			case 0xd7: OP_MOVRM ( 7, REG_A, DIY   ); break; /* MOV diy, A    */
1654 
1655 			case 0xd8: OP_MOVRM ( 4, REG_X, DP    ); break; /* MOV dp, X     */
1656 			case 0xd9: OP_MOVRM ( 5, REG_X, DPY   ); break; /* MOV dpy, X    */
1657 			case 0xda: OP_MOVWRM( 5               ); break; /* MOVW dp, YA   */
1658 			case 0xdb: OP_MOVRM ( 5, REG_Y, DPX   ); break; /* MOV dpx, Y    */
1659 
1660 			case 0xdc: OP_DECR  ( 2, REG_Y        ); break; /* DEC Y         */
1661 			case 0xdd: OP_MOVRR ( 2, REG_Y, REG_A ); break; /* MOV A, Y      */
1662 			case 0xde: OP_CBNE  ( 6, DPX          ); break; /* CBNE dpx      */
1663 			case 0xdf: OP_DAA   ( 3               ); break; /* DAA           */
1664 
1665 			case 0xe0: OP_CLRV  ( 2               ); break; /* CLRV          */
1666 			case 0xe1: OP_TCALL ( 8, 14           ); break; /* TCALL 14      */
1667 			case 0xe2: OP_SET   ( 4, BIT_7        ); break; /* SET 7         */
1668 			case 0xe3: OP_BBS   ( 5, BIT_7        ); break; /* BBS 7         */
1669 
1670 			case 0xe4: OP_MOVMR ( 3, DP, REG_A    ); break; /* MOV A, dp     */
1671 			case 0xe5: OP_MOVMR ( 4, ABS, REG_A   ); break; /* MOV A, abs    */
1672 			case 0xe6: OP_MOVMR ( 3, XI, REG_A    ); break; /* MOV A, xi     */
1673 			case 0xe7: OP_MOVMR ( 6, DXI, REG_A   ); break; /* MOV A, dxi    */
1674 
1675 			case 0xe8: OP_MOVMR ( 2, IMM, REG_A   ); break; /* CMP A, imm    */
1676 			case 0xe9: OP_MOVMR ( 4, ABS, REG_X   ); break; /* MOV X, abs    */
1677 			case 0xea: OP_NOT1  ( 5               ); break; /* NOT1          */
1678 			case 0xeb: OP_MOVMR ( 3, DP, REG_Y    ); break; /* MOV Y, dp     */
1679 
1680 			case 0xec: OP_MOVMR ( 4, ABS, REG_Y   ); break; /* MOV Y, abs    */
1681 			case 0xed: OP_NOTC  ( 3               ); break; /* NOTC          */
1682 			case 0xee: OP_PULL  ( 4, REG_Y        ); break; /* POP Y         */
1683 			case 0xef: OP_SLEEP ( 1               ); break; /* SLEEP         */
1684 
1685 			case 0xf0: OP_BCC   ( 2, COND_EQ()    ); break; /* BEQ           */
1686 			case 0xf1: OP_TCALL ( 8, 15           ); break; /* TCALL1 5      */
1687 			case 0xf2: OP_CLR   ( 4, BIT_7        ); break; /* CLR 7         */
1688 			case 0xf3: OP_BBC   ( 5, BIT_7        ); break; /* BBC 7         */
1689 
1690 			case 0xf4: OP_MOVMR ( 4, DPX, REG_A   ); break; /* MOV A, dpx    */
1691 			case 0xf5: OP_MOVMR ( 5, ABX, REG_A   ); break; /* MOV A, abx    */
1692 			case 0xf6: OP_MOVMR ( 5, ABY, REG_A   ); break; /* MOV A, aby    */
1693 			case 0xf7: OP_MOVMR ( 6, DIY, REG_A   ); break; /* MOV A, diy    */
1694 
1695 			case 0xf8: OP_MOVMR ( 3, DP, REG_X    ); break; /* MOV X, dp     */
1696 			case 0xf9: OP_MOVMR ( 4, DPY, REG_X   ); break; /* MOV X, dpy    */
1697 			case 0xfa: OP_MOVMM ( 5, DP, DP       ); break; /* MOV dp, dp    */
1698 			case 0xfb: OP_MOVMR ( 4, DPX, REG_Y   ); break; /* MOV Y, DPX    */
1699 			case 0xfc: OP_INCR  ( 2, REG_Y        ); break; /* INC Y         */
1700 			case 0xfd: OP_MOVRR ( 2, REG_A, REG_Y ); break; /* MOV Y, A      */
1701 			case 0xfe: OP_DBNZR ( 4               ); break; /* DBNZ Y        */
1702 			case 0xff: OP_STOP  ( 1               ); break; /* STOP          */
1703 		}
1704 	}
1705 }
1706 
1707 /* ======================================================================== */
1708 /* ============================== END OF FILE ============================= */
1709 /* ======================================================================== */
1710