1 /* ======================================================================== */
2 /* ============================= CONFIGURATION ============================ */
3 /* ======================================================================== */
4 
5 #undef FLAG_SET_E
6 #undef FLAG_SET_M
7 #undef FLAG_SET_X
8 #if EXECUTION_MODE == EXECUTION_MODE_E
9 #define FLAG_SET_E 1
10 #define FLAG_SET_M 1
11 #define FLAG_SET_X 1
12 #elif EXECUTION_MODE == EXECUTION_MODE_M0X0
13 #define FLAG_SET_E 0
14 #define FLAG_SET_M 0
15 #define FLAG_SET_X 0
16 #elif EXECUTION_MODE == EXECUTION_MODE_M0X1
17 #define FLAG_SET_E 0
18 #define FLAG_SET_M 0
19 #define FLAG_SET_X 1
20 #elif EXECUTION_MODE == EXECUTION_MODE_M1X0
21 #define FLAG_SET_E 0
22 #define FLAG_SET_M 1
23 #define FLAG_SET_X 0
24 #elif EXECUTION_MODE == EXECUTION_MODE_M1X1
25 #define FLAG_SET_E 0
26 #define FLAG_SET_M 1
27 #define FLAG_SET_X 1
28 #endif
29 
30 #undef VECTOR_IRQ
31 #undef VECTOR_NMI
32 #undef VECTOR_ABORT
33 #undef VECTOR_BRK
34 #undef VECTOR_COP
35 
36 #if FLAG_SET_E
37 #define VECTOR_IRQ			VECTOR_IRQ_E
38 #define VECTOR_NMI			VECTOR_NMI_E
39 #define VECTOR_ABORT		VECTOR_ABORT_E
40 #define VECTOR_BRK			VECTOR_BRK_E
41 #define VECTOR_COP			VECTOR_COP_E
42 #else /* FLAG_SET_E */
43 #define VECTOR_IRQ			VECTOR_IRQ_N
44 #define VECTOR_NMI			VECTOR_NMI_N
45 #define VECTOR_ABORT		VECTOR_ABORT_N
46 #define VECTOR_BRK			VECTOR_BRK_N
47 #define VECTOR_COP			VECTOR_COP_N
48 #endif
49 
50 
51 
52 /* ======================================================================== */
53 /* ================================= MEMORY =============================== */
54 /* ======================================================================== */
55 
56 #define ADDRESS_65816(A) ((A)&0x00ffffff)
57 
g65816i_read_8_normal(uint address)58 static INLINE uint g65816i_read_8_normal(uint address)
59 {
60 	address = ADDRESS_65816(address);
61 	return g65816_read_8(address);
62 }
63 
g65816i_read_8_immediate(uint address)64 static INLINE uint g65816i_read_8_immediate(uint address)
65 {
66 	address = ADDRESS_65816(address);
67 	return g65816_read_8_immediate(address);
68 }
69 
g65816i_read_8_direct(uint address)70 static INLINE uint g65816i_read_8_direct(uint address)
71 {
72 #if FLAG_SET_E
73 	/* force address into zero page */
74 	address = REGISTER_D + MAKE_UINT_8(address - REGISTER_D);
75 #else
76 	address = ADDRESS_65816(address);
77 #endif
78 	return g65816_read_8(address);
79 }
80 
g65816i_write_8_normal(uint address,uint value)81 static INLINE void g65816i_write_8_normal(uint address, uint value)
82 {
83 	address = ADDRESS_65816(address);
84 	g65816_write_8(address, MAKE_UINT_8(value));
85 }
86 
g65816i_write_8_direct(uint address,uint value)87 static INLINE void g65816i_write_8_direct(uint address, uint value)
88 {
89 #if FLAG_SET_E
90 	/* force address into zero page */
91 	address = REGISTER_D + MAKE_UINT_8(address - REGISTER_D);
92 #else
93 	address = ADDRESS_65816(address);
94 #endif
95 	g65816_write_8(address, MAKE_UINT_8(value));
96 }
97 
g65816i_read_16_normal(uint address)98 static INLINE uint g65816i_read_16_normal(uint address)
99 {
100 	return	 g65816i_read_8_normal(address) |
101 			(g65816i_read_8_normal(address+1)<<8);
102 }
103 
g65816i_read_16_immediate(uint address)104 static INLINE uint g65816i_read_16_immediate(uint address)
105 {
106 	return	 g65816i_read_8_immediate(address) |
107 			(g65816i_read_8_immediate(address+1)<<8);
108 }
109 
g65816i_read_16_direct(uint address)110 static INLINE uint g65816i_read_16_direct(uint address)
111 {
112 	return   g65816i_read_8_direct(address) |
113 			(g65816i_read_8_direct(address+1)<<8);
114 }
115 
g65816i_write_16_normal(uint address,uint value)116 static INLINE void g65816i_write_16_normal(uint address, uint value)
117 {
118 	g65816i_write_8_normal(address, value&0xff);
119 	g65816i_write_8_normal(address+1, value>>8);
120 }
121 
g65816i_write_16_direct(uint address,uint value)122 static INLINE void g65816i_write_16_direct(uint address, uint value)
123 {
124 	g65816i_write_8_direct(address, value&0xff);
125 	g65816i_write_8_direct(address+1, value>>8);
126 }
127 
g65816i_read_24_normal(uint address)128 static INLINE uint g65816i_read_24_normal(uint address)
129 {
130 	return	 g65816i_read_8_normal(address)       |
131 			(g65816i_read_8_normal(address+1)<<8) |
132 			(g65816i_read_8_normal(address+2)<<16);
133 }
134 
g65816i_read_24_immediate(uint address)135 static INLINE uint g65816i_read_24_immediate(uint address)
136 {
137 	return	 g65816i_read_8_immediate(address)       |
138 			(g65816i_read_8_immediate(address+1)<<8) |
139 			(g65816i_read_8_immediate(address+2)<<16);
140 }
141 
g65816i_read_24_direct(uint address)142 static INLINE uint g65816i_read_24_direct(uint address)
143 {
144 	return	 g65816i_read_8_direct(address)         |
145 			(g65816i_read_8_direct(address+1)<<8) |
146 			(g65816i_read_8_direct(address+2)<<16);
147 }
148 
149 
150 
151 /* ======================================================================== */
152 /* ================================= STACK ================================ */
153 /* ======================================================================== */
154 
g65816i_push_8(uint value)155 static INLINE void g65816i_push_8(uint value)
156 {
157 	g65816i_write_8_normal(REGISTER_S, value);
158 #if FLAG_SET_E
159 	REGISTER_S = MAKE_UINT_8(REGISTER_S-1) | 0x100;
160 #else
161 	REGISTER_S = MAKE_UINT_16(REGISTER_S-1);
162 #endif
163 }
164 
g65816i_pull_8(void)165 static INLINE uint g65816i_pull_8(void)
166 {
167 #if FLAG_SET_E
168 	REGISTER_S = MAKE_UINT_8(REGISTER_S+1) | 0x100;
169 #else
170 	REGISTER_S = MAKE_UINT_16(REGISTER_S+1);
171 #endif
172 	return g65816i_read_8_normal(REGISTER_S);
173 }
174 
g65816i_push_16(uint value)175 static INLINE void g65816i_push_16(uint value)
176 {
177 	g65816i_push_8(value>>8);
178 	g65816i_push_8(value&0xff);
179 }
180 
g65816i_pull_16(void)181 static INLINE uint g65816i_pull_16(void)
182 {
183 	uint res = g65816i_pull_8();
184 	return res | (g65816i_pull_8() << 8);
185 }
186 
g65816i_push_24(uint value)187 static INLINE void g65816i_push_24(uint value)
188 {
189 	g65816i_push_8(value>>16);
190 	g65816i_push_8((value>>8)&0xff);
191 	g65816i_push_8(value&0xff);
192 }
193 
g65816i_pull_24(void)194 static INLINE uint g65816i_pull_24(void)
195 {
196 	uint res = g65816i_pull_8();
197 	res |= g65816i_pull_8() << 8;
198 	return res | (g65816i_pull_8() << 16);
199 }
200 
201 
202 /* ======================================================================== */
203 /* ============================ PROGRAM COUNTER =========================== */
204 /* ======================================================================== */
205 
g65816i_jump_16(uint address)206 static INLINE void g65816i_jump_16(uint address)
207 {
208 	REGISTER_PC = MAKE_UINT_16(address);
209 	g65816i_jumping(REGISTER_PC);
210 }
211 
g65816i_jump_24(uint address)212 static INLINE void g65816i_jump_24(uint address)
213 {
214 	REGISTER_PB = address&0xff0000;
215 	REGISTER_PC = MAKE_UINT_16(address);
216 	g65816i_jumping(REGISTER_PC);
217 }
218 
g65816i_branch_8(uint offset)219 static INLINE void g65816i_branch_8(uint offset)
220 {
221 #if FLAG_SET_E
222 	uint old_pc = REGISTER_PC;
223 	REGISTER_PC = MAKE_UINT_16(REGISTER_PC + MAKE_INT_8(offset));
224 	if((REGISTER_PC^old_pc)&0xff00)
225 		CLK(1);
226 #else
227 	REGISTER_PC = MAKE_UINT_16(REGISTER_PC + MAKE_INT_8(offset));
228 #endif
229 	g65816i_branching(REGISTER_PC);
230 }
231 
g65816i_branch_16(uint offset)232 static INLINE void g65816i_branch_16(uint offset)
233 {
234 	REGISTER_PC = MAKE_UINT_16(REGISTER_PC + offset);
235 	g65816i_branching(REGISTER_PC);
236 }
237 
238 
239 /* ======================================================================== */
240 /* ============================ STATUS REGISTER =========================== */
241 /* ======================================================================== */
242 
243 #if !FLAG_SET_E
g65816i_set_flag_mx(uint value)244 static INLINE void g65816i_set_flag_mx(uint value)
245 {
246 #if FLAG_SET_M
247 	if(!(value & FLAGPOS_M))
248 	{
249 		REGISTER_A |= REGISTER_B;
250 		REGISTER_B = 0;
251 		FLAG_M = MFLAG_CLEAR;
252 	}
253 #else
254 	if(value & FLAGPOS_M)
255 	{
256 		REGISTER_B = REGISTER_A & 0xff00;
257 		REGISTER_A = MAKE_UINT_8(REGISTER_A);
258 		FLAG_M = MFLAG_SET;
259 	}
260 #endif
261 #if FLAG_SET_X
262 	if(!(value & FLAGPOS_X))
263 	{
264 		FLAG_X = XFLAG_CLEAR;
265 	}
266 #else
267 	if(value & FLAGPOS_X)
268 	{
269 		REGISTER_X = MAKE_UINT_8(REGISTER_X);
270 		REGISTER_Y = MAKE_UINT_8(REGISTER_Y);
271 		FLAG_X = XFLAG_SET;
272 	}
273 #endif
274 	g65816i_set_execution_mode((FLAG_M>>4) | (FLAG_X>>4));
275 }
276 #endif
277 
g65816i_set_flag_e(uint value)278 static INLINE void g65816i_set_flag_e(uint value)
279 {
280 #if FLAG_SET_E
281 	if(!value)
282 	{
283 		FLAG_E = EFLAG_CLEAR;
284 		g65816i_set_execution_mode(EXECUTION_MODE_M1X1);
285 	}
286 #else
287 	if(value)
288 	{
289 #if !FLAG_SET_M
290 		REGISTER_B = REGISTER_A & 0xff00;
291 		REGISTER_A &= 0x00ff;
292 		FLAG_M = MFLAG_SET;
293 #endif
294 #if !FLAG_SET_X
295 		REGISTER_X = MAKE_UINT_8(REGISTER_X);
296 		REGISTER_Y = MAKE_UINT_8(REGISTER_Y);
297 		FLAG_X = XFLAG_SET;
298 #endif
299 		REGISTER_S = MAKE_UINT_8(REGISTER_S) | 0x100;
300 		FLAG_E = EFLAG_SET;
301 		g65816i_set_execution_mode(EXECUTION_MODE_E);
302 	}
303 #endif
304 }
305 
306 //INLINE void g65816i_check_maskable_interrupt(void);
307 
g65816i_set_flag_i(uint value)308 static INLINE void g65816i_set_flag_i(uint value)
309 {
310 	value &= FLAGPOS_I;
311 	if(!FLAG_I || value)
312 	{
313 		FLAG_I = value;
314 		return;
315 	}
316 	FLAG_I = value;
317 //	g65816i_check_maskable_interrupt();
318 }
319 
320 
321 
322 
323 /* Get the Processor Status Register */
g65816i_get_reg_p(void)324 static INLINE uint g65816i_get_reg_p(void)
325 {
326 	return	(FLAG_N&0x80)		|
327 			((FLAG_V>>1)&0x40)	|
328 			FLAG_M				|
329 			FLAG_X				|
330 			FLAG_D				|
331 			FLAG_I				|
332 			((!FLAG_Z)<<1)		|
333 			((FLAG_C>>8)&1);
334 }
335 
g65816i_set_reg_p(uint value)336 static INLINE void g65816i_set_reg_p(uint value)
337 {
338 #if FLAG_SET_E
339 	FLAG_N = value;
340 	FLAG_V = value << 1;
341 	FLAG_D = value & FLAGPOS_D;
342 	FLAG_Z = !(value & FLAGPOS_Z);
343 	FLAG_C = value << 8;
344 	g65816i_set_flag_i(value);
345 #else
346 	FLAG_N = value;
347 	FLAG_V = value << 1;
348 	FLAG_D = value & FLAGPOS_D;
349 	FLAG_Z = !(value & FLAGPOS_Z);
350 	FLAG_C = value << 8;
351 	g65816i_set_flag_mx(value);
352 	g65816i_set_flag_i(value);
353 #endif
354 }
355 
356 
357 /* ======================================================================== */
358 /* =============================== INTERRUPTS ============================= */
359 /* ======================================================================== */
360 
g65816i_interrupt_hardware(uint vector)361 static INLINE void g65816i_interrupt_hardware(uint vector)
362 {
363 #if FLAG_SET_E
364 	CLK(7);
365 	g65816i_push_16(REGISTER_PC);
366 	g65816i_push_8(g65816i_get_reg_p() & ~FLAGPOS_B);
367 	FLAG_D = DFLAG_CLEAR;
368 	g65816i_set_flag_i(IFLAG_SET);
369 	REGISTER_PB = 0;
370 	g65816i_jump_16(g65816i_read_16_normal(vector));
371 	if(INT_ACK) INT_ACK(0);
372 #else
373 	CLK(8);
374 	g65816i_push_8(REGISTER_PB>>16);
375 	g65816i_push_16(REGISTER_PC);
376 	g65816i_push_8(g65816i_get_reg_p());
377 	FLAG_D = DFLAG_CLEAR;
378 	g65816i_set_flag_i(IFLAG_SET);
379 	REGISTER_PB = 0;
380 	g65816i_jump_16(g65816i_read_16_normal(vector));
381 	if(INT_ACK) INT_ACK(0);
382 #endif
383 }
384 
g65816i_interrupt_software(uint vector)385 static INLINE void g65816i_interrupt_software(uint vector)
386 {
387 #if FLAG_SET_E
388 	CLK(7);
389 	g65816i_push_16(REGISTER_PC);
390 	g65816i_push_8(g65816i_get_reg_p());
391 	FLAG_D = DFLAG_CLEAR;
392 	g65816i_set_flag_i(IFLAG_SET);
393 	REGISTER_PB = 0;
394 	g65816i_jump_16(g65816i_read_16_normal(vector));
395 #else
396 	CLK(8);
397 	g65816i_push_8(REGISTER_PB>>16);
398 	g65816i_push_16(REGISTER_PC);
399 	g65816i_push_8(g65816i_get_reg_p());
400 	FLAG_D = DFLAG_CLEAR;
401 	g65816i_set_flag_i(IFLAG_SET);
402 	REGISTER_PB = 0;
403 	g65816i_jump_16(g65816i_read_16_normal(vector));
404 #endif
405 }
406 
g65816i_interrupt_nmi(void)407 static INLINE void g65816i_interrupt_nmi(void)
408 {
409 #if FLAG_SET_E
410 	CLK(7);
411 	g65816i_push_16(REGISTER_PC);
412 	g65816i_push_8(g65816i_get_reg_p() & ~FLAGPOS_B);
413 	FLAG_D = DFLAG_CLEAR;
414 	REGISTER_PB = 0;
415 	g65816i_jump_16(g65816i_read_16_normal(VECTOR_NMI));
416 #else
417 	CLK(8);
418 	g65816i_push_8(REGISTER_PB>>16);
419 	g65816i_push_16(REGISTER_PC);
420 	g65816i_push_8(g65816i_get_reg_p());
421 	FLAG_D = DFLAG_CLEAR;
422 	REGISTER_PB = 0;
423 	g65816i_jump_16(g65816i_read_16_normal(VECTOR_NMI));
424 #endif
425 }
426 
427 
g65816i_check_maskable_interrupt(void)428 static INLINE void g65816i_check_maskable_interrupt(void)
429 {
430 	if(!(CPU_STOPPED & STOP_LEVEL_STOP) && LINE_IRQ && !FLAG_I)
431 	{
432 		g65816i_interrupt_hardware(VECTOR_IRQ);
433 		LINE_IRQ=0;
434 	}
435 }
436 
437 
438 /* ======================================================================== */
439 /* ========================== EFFECTIVE ADDRESSES ========================= */
440 /* ======================================================================== */
441 
442 /* Effective-address based memory access macros */
443 #define read_8_NORM(A)		g65816i_read_8_normal(A)
444 #define read_8_IMM(A)		g65816i_read_8_immediate(A)
445 #define read_8_D(A)			g65816i_read_8_direct(A)
446 #define read_8_A(A)			g65816i_read_8_normal(A)
447 #define read_8_AL(A)		g65816i_read_8_normal(A)
448 #define read_8_DX(A)		g65816i_read_8_direct(A)
449 #define read_8_DY(A)		g65816i_read_8_direct(A)
450 #define read_8_AX(A)		g65816i_read_8_normal(A)
451 #define read_8_ALX(A)		g65816i_read_8_normal(A)
452 #define read_8_AY(A)		g65816i_read_8_normal(A)
453 #define read_8_DI(A)		g65816i_read_8_normal(A)
454 #define read_8_DLI(A)		g65816i_read_8_normal(A)
455 #define read_8_AI(A)		g65816i_read_8_normal(A)
456 #define read_8_ALI(A)		g65816i_read_8_normal(A)
457 #define read_8_DXI(A)		g65816i_read_8_normal(A)
458 #define read_8_DIY(A)		g65816i_read_8_normal(A)
459 #define read_8_DLIY(A)		g65816i_read_8_normal(A)
460 #define read_8_AXI(A)		g65816i_read_8_normal(A)
461 #define read_8_S(A)			g65816i_read_8_normal(A)
462 #define read_8_SIY(A)		g65816i_read_8_normal(A)
463 
464 #define read_16_NORM(A)		g65816i_read_16_normal(A)
465 #define read_16_IMM(A)		g65816i_read_16_immediate(A)
466 #define read_16_D(A)		g65816i_read_16_direct(A)
467 #define read_16_A(A)		g65816i_read_16_normal(A)
468 #define read_16_AL(A)		g65816i_read_16_normal(A)
469 #define read_16_DX(A)		g65816i_read_16_direct(A)
470 #define read_16_DY(A)		g65816i_read_16_direct(A)
471 #define read_16_AX(A)		g65816i_read_16_normal(A)
472 #define read_16_ALX(A)		g65816i_read_16_normal(A)
473 #define read_16_AY(A)		g65816i_read_16_normal(A)
474 #define read_16_DI(A)		g65816i_read_16_normal(A)
475 #define read_16_DLI(A)		g65816i_read_16_normal(A)
476 #define read_16_AI(A)		g65816i_read_16_normal(A)
477 #define read_16_ALI(A)		g65816i_read_16_normal(A)
478 #define read_16_DXI(A)		g65816i_read_16_normal(A)
479 #define read_16_DIY(A)		g65816i_read_16_normal(A)
480 #define read_16_DLIY(A)		g65816i_read_16_normal(A)
481 #define read_16_AXI(A)		g65816i_read_16_normal(A)
482 #define read_16_S(A)		g65816i_read_16_normal(A)
483 #define read_16_SIY(A)		g65816i_read_16_normal(A)
484 
485 #define read_24_NORM(A)		g65816i_read_24_normal(A)
486 #define read_24_IMM(A)		g65816i_read_24_immediate(A)
487 #define read_24_D(A)		g65816i_read_24_direct(A)
488 #define read_24_A(A)		g65816i_read_24_normal(A)
489 #define read_24_AL(A)		g65816i_read_24_normal(A)
490 #define read_24_DX(A)		g65816i_read_24_direct(A)
491 #define read_24_DY(A)		g65816i_read_24_direct(A)
492 #define read_24_AX(A)		g65816i_read_24_normal(A)
493 #define read_24_ALX(A)		g65816i_read_24_normal(A)
494 #define read_24_AY(A)		g65816i_read_24_normal(A)
495 #define read_24_DI(A)		g65816i_read_24_normal(A)
496 #define read_24_DLI(A)		g65816i_read_24_normal(A)
497 #define read_24_AI(A)		g65816i_read_24_normal(A)
498 #define read_24_ALI(A)		g65816i_read_24_normal(A)
499 #define read_24_DXI(A)		g65816i_read_24_normal(A)
500 #define read_24_DIY(A)		g65816i_read_24_normal(A)
501 #define read_24_DLIY(A)		g65816i_read_24_normal(A)
502 #define read_24_AXI(A)		g65816i_read_24_normal(A)
503 #define read_24_S(A)		g65816i_read_24_normal(A)
504 #define read_24_SIY(A)		g65816i_read_24_normal(A)
505 
506 #define write_8_NORM(A, V)	g65816i_write_8_normal(A, V)
507 #define write_8_D(A, V)		g65816i_write_8_direct(A, V)
508 #define write_8_A(A, V)		g65816i_write_8_normal(A, V)
509 #define write_8_AL(A, V)	g65816i_write_8_normal(A, V)
510 #define write_8_DX(A, V)	g65816i_write_8_direct(A, V)
511 #define write_8_DY(A, V)	g65816i_write_8_direct(A, V)
512 #define write_8_AX(A, V)	g65816i_write_8_normal(A, V)
513 #define write_8_ALX(A, V)	g65816i_write_8_normal(A, V)
514 #define write_8_AY(A, V)	g65816i_write_8_normal(A, V)
515 #define write_8_DI(A, V)	g65816i_write_8_normal(A, V)
516 #define write_8_DLI(A, V)	g65816i_write_8_normal(A, V)
517 #define write_8_AI(A, V)	g65816i_write_8_normal(A, V)
518 #define write_8_ALI(A, V)	g65816i_write_8_normal(A, V)
519 #define write_8_DXI(A, V)	g65816i_write_8_normal(A, V)
520 #define write_8_DIY(A, V)	g65816i_write_8_normal(A, V)
521 #define write_8_DLIY(A, V)	g65816i_write_8_normal(A, V)
522 #define write_8_AXI(A, V)	g65816i_write_8_normal(A, V)
523 #define write_8_S(A, V)		g65816i_write_8_normal(A, V)
524 #define write_8_SIY(A, V)	g65816i_write_8_normal(A, V)
525 
526 #define write_16_NORM(A, V)	g65816i_write_16_normal(A, V)
527 #define write_16_D(A, V)	g65816i_write_16_direct(A, V)
528 #define write_16_A(A, V)	g65816i_write_16_normal(A, V)
529 #define write_16_AL(A, V)	g65816i_write_16_normal(A, V)
530 #define write_16_DX(A, V)	g65816i_write_16_direct(A, V)
531 #define write_16_DY(A, V)	g65816i_write_16_direct(A, V)
532 #define write_16_AX(A, V)	g65816i_write_16_normal(A, V)
533 #define write_16_ALX(A, V)	g65816i_write_16_normal(A, V)
534 #define write_16_AY(A, V)	g65816i_write_16_normal(A, V)
535 #define write_16_DI(A, V)	g65816i_write_16_normal(A, V)
536 #define write_16_DLI(A, V)	g65816i_write_16_normal(A, V)
537 #define write_16_AI(A, V)	g65816i_write_16_normal(A, V)
538 #define write_16_ALI(A, V)	g65816i_write_16_normal(A, V)
539 #define write_16_DXI(A, V)	g65816i_write_16_normal(A, V)
540 #define write_16_DIY(A, V)	g65816i_write_16_normal(A, V)
541 #define write_16_DLIY(A, V)	g65816i_write_16_normal(A, V)
542 #define write_16_AXI(A, V)	g65816i_write_16_normal(A, V)
543 #define write_16_S(A, V)	g65816i_write_16_normal(A, V)
544 #define write_16_SIY(A, V)	g65816i_write_16_normal(A, V)
545 
546 
547 #define OPER_8_IMM()		read_8_IMM(EA_IMM8())
548 #define OPER_8_D()			read_8_D(EA_D())
549 #define OPER_8_A()			read_8_A(EA_A())
550 #define OPER_8_AL()			read_8_AL(EA_AL())
551 #define OPER_8_DX()			read_8_DX(EA_DX())
552 #define OPER_8_DY()			read_8_DY(EA_DY())
553 #define OPER_8_AX()			read_8_AX(EA_AX())
554 #define OPER_8_ALX()		read_8_ALX(EA_ALX())
555 #define OPER_8_AY()			read_8_AY(EA_AY())
556 #define OPER_8_DI()			read_8_DI(EA_DI())
557 #define OPER_8_DLI()		read_8_DLI(EA_DLI())
558 #define OPER_8_AI()			read_8_AI(EA_AI())
559 #define OPER_8_ALI()		read_8_ALI(EA_ALI())
560 #define OPER_8_DXI()		read_8_DXI(EA_DXI())
561 #define OPER_8_DIY()		read_8_DIY(EA_DIY())
562 #define OPER_8_DLIY()		read_8_DLIY(EA_DLIY())
563 #define OPER_8_AXI()		read_8_AXI(EA_AXI())
564 #define OPER_8_S()			read_8_S(EA_S())
565 #define OPER_8_SIY()		read_8_SIY(EA_SIY())
566 
567 #define OPER_16_IMM()		read_16_IMM(EA_IMM16())
568 #define OPER_16_D()			read_16_D(EA_D())
569 #define OPER_16_A()			read_16_A(EA_A())
570 #define OPER_16_AL()		read_16_AL(EA_AL())
571 #define OPER_16_DX()		read_16_DX(EA_DX())
572 #define OPER_16_DY()		read_16_DY(EA_DY())
573 #define OPER_16_AX()		read_16_AX(EA_AX())
574 #define OPER_16_ALX()		read_16_ALX(EA_ALX())
575 #define OPER_16_AY()		read_16_AY(EA_AY())
576 #define OPER_16_DI()		read_16_DI(EA_DI())
577 #define OPER_16_DLI()		read_16_DLI(EA_DLI())
578 #define OPER_16_AI()		read_16_AI(EA_AI())
579 #define OPER_16_ALI()		read_16_ALI(EA_ALI())
580 #define OPER_16_DXI()		read_16_DXI(EA_DXI())
581 #define OPER_16_DIY()		read_16_DIY(EA_DIY())
582 #define OPER_16_DLIY()		read_16_DLIY(EA_DLIY())
583 #define OPER_16_AXI()		read_16_AXI(EA_AXI())
584 #define OPER_16_S()			read_16_S(EA_S())
585 #define OPER_16_SIY()		read_16_SIY(EA_SIY())
586 
587 #define OPER_24_IMM()		read_24_IMM(EA_IMM24())
588 #define OPER_24_D()			read_24_D(EA_D())
589 #define OPER_24_A()			read_24_A(EA_A())
590 #define OPER_24_AL()		read_24_AL(EA_AL())
591 #define OPER_24_DX()		read_24_DX(EA_DX())
592 #define OPER_24_DY()		read_24_DY(EA_DY())
593 #define OPER_24_AX()		read_24_AX(EA_AX())
594 #define OPER_24_ALX()		read_24_ALX(EA_ALX())
595 #define OPER_24_AY()		read_24_AY(EA_AY())
596 #define OPER_24_DI()		read_24_DI(EA_DI())
597 #define OPER_24_DLI()		read_24_DLI(EA_DLI())
598 #define OPER_24_AI()		read_24_AI(EA_AI())
599 #define OPER_24_ALI()		read_24_ALI(EA_ALI())
600 #define OPER_24_DXI()		read_24_DXI(EA_DXI())
601 #define OPER_24_DIY()		read_24_DIY(EA_DIY())
602 #define OPER_24_DLIY()		read_24_DLIY(EA_DLIY())
603 #define OPER_24_AXI()		read_24_AXI(EA_AXI())
604 #define OPER_24_S()			read_24_S(EA_S())
605 #define OPER_24_SIY()		read_24_SIY(EA_SIY())
606 
EA_IMM8(void)607 static INLINE uint EA_IMM8(void)  {REGISTER_PC += 1; return REGISTER_PB | MAKE_UINT_16(REGISTER_PC-1);}
EA_IMM16(void)608 static INLINE uint EA_IMM16(void) {REGISTER_PC += 2; return REGISTER_PB | MAKE_UINT_16(REGISTER_PC-2);}
EA_IMM24(void)609 static INLINE uint EA_IMM24(void) {REGISTER_PC += 3; return REGISTER_PB | MAKE_UINT_16(REGISTER_PC-3);}
EA_D(void)610 static INLINE uint EA_D(void)     {if(MAKE_UINT_8(REGISTER_D)) CLK(1); return MAKE_UINT_16(REGISTER_D + OPER_8_IMM());}
EA_A(void)611 static INLINE uint EA_A(void)     {return REGISTER_DB | OPER_16_IMM();}
EA_AL(void)612 static INLINE uint EA_AL(void)    {return OPER_24_IMM();}
EA_DX(void)613 static INLINE uint EA_DX(void)    {return MAKE_UINT_16(REGISTER_D + OPER_8_IMM() + REGISTER_X);}
EA_DY(void)614 static INLINE uint EA_DY(void)    {return MAKE_UINT_16(REGISTER_D + OPER_8_IMM() + REGISTER_Y);}
EA_AX(void)615 static INLINE uint EA_AX(void)    {uint tmp = EA_A(); if((tmp^(tmp+REGISTER_X))&0xff00) CLK(1); return tmp + REGISTER_X;}
EA_ALX(void)616 static INLINE uint EA_ALX(void)   {return EA_AL() + REGISTER_X;}
EA_AY(void)617 static INLINE uint EA_AY(void)    {uint tmp = EA_A(); if((tmp^(tmp+REGISTER_X))&0xff00) CLK(1); return tmp + REGISTER_Y;}
EA_DI(void)618 static INLINE uint EA_DI(void)    {return REGISTER_DB | OPER_16_D();}
EA_DLI(void)619 static INLINE uint EA_DLI(void)   {return OPER_24_D();}
EA_AI(void)620 static INLINE uint EA_AI(void)    {return read_16_A(OPER_16_IMM());}
EA_ALI(void)621 static INLINE uint EA_ALI(void)   {return OPER_24_A();}
EA_DXI(void)622 static INLINE uint EA_DXI(void)   {return REGISTER_DB | OPER_16_DX();}
EA_DIY(void)623 static INLINE uint EA_DIY(void)   {uint tmp = REGISTER_DB | OPER_16_D(); if((tmp^(tmp+REGISTER_X))&0xff00) CLK(1); return tmp + REGISTER_Y;}
EA_DLIY(void)624 static INLINE uint EA_DLIY(void)  {return OPER_24_D() + REGISTER_Y;}
EA_AXI(void)625 static INLINE uint EA_AXI(void)   {return read_16_AXI(MAKE_UINT_16(OPER_16_IMM() + REGISTER_X));}
EA_S(void)626 static INLINE uint EA_S(void)     {return MAKE_UINT_16(REGISTER_S + OPER_8_IMM());}
EA_SIY(void)627 static INLINE uint EA_SIY(void)   {return EA_S() + REGISTER_DB + REGISTER_Y;}
628 
629 
630 
631 /* ======================================================================== */
632 /* =========================== OPERATION MACROS =========================== */
633 /* ======================================================================== */
634 
635 /* M6502   Add With Carry */
636 #undef OP_ADC
637 #if FLAG_SET_M
638 #define OP_ADC(MODE)														\
639 			CLK(CLK_OP + CLK_R8 + CLK_##MODE);								\
640 			SRC    = OPER_8_##MODE();										\
641 			FLAG_C = REGISTER_A + SRC + CFLAG_AS_1();						\
642 			if(FLAG_D)														\
643 			{																\
644 				if((FLAG_C & 0xf) > 9)										\
645 					FLAG_C+=6;												\
646 				if((FLAG_C & 0xf0) > 0x90)									\
647 					FLAG_C+=0x60;											\
648 			}																\
649 			FLAG_V = VFLAG_ADD_8(SRC, REGISTER_A, FLAG_C);					\
650 			FLAG_N = FLAG_Z = REGISTER_A = MAKE_UINT_8(FLAG_C)
651 #else
652 #define OP_ADC(MODE)														\
653 			CLK(CLK_OP + CLK_R16 + CLK_##MODE);								\
654 			SRC    = OPER_16_##MODE();										\
655 			if(!FLAG_D)														\
656 			{																\
657 				FLAG_C = REGISTER_A + SRC + CFLAG_AS_1();						\
658 				FLAG_V = VFLAG_ADD_16(SRC, REGISTER_A, FLAG_C);					\
659 				FLAG_Z = REGISTER_A = MAKE_UINT_16(FLAG_C);						\
660 				FLAG_N = NFLAG_16(REGISTER_A);									\
661 				FLAG_C = CFLAG_16(FLAG_C);									\
662 				BREAKOUT;													\
663 			}																\
664 			FLAG_C = MAKE_UINT_8(REGISTER_A) + MAKE_UINT_8(SRC) + CFLAG_AS_1();	\
665 			if((FLAG_C & 0xf) > 9)											\
666 				FLAG_C+=6;													\
667 			if((FLAG_C & 0xf0) > 0x90)										\
668 				FLAG_C+=0x60;												\
669 			FLAG_Z = MAKE_UINT_8(FLAG_C);									\
670 																			\
671 			FLAG_C = MAKE_UINT_8(REGISTER_A>>8) + MAKE_UINT_8(SRC>>8) + CFLAG_AS_1();	\
672 			if((FLAG_C & 0xf) > 9)											\
673 				FLAG_C+=6;													\
674 			if((FLAG_C & 0xf0) > 0x90)										\
675 				FLAG_C+=0x60;												\
676 			FLAG_Z |= MAKE_UINT_8(FLAG_C) << 8;								\
677 			FLAG_N = NFLAG_16(FLAG_Z);										\
678 			FLAG_V = VFLAG_ADD_16(SRC, REGISTER_A, FLAG_C);					\
679 			REGISTER_A  = FLAG_Z
680 #endif
681 
682 /* M6502   Logical AND with accumulator */
683 #undef OP_AND
684 #if FLAG_SET_M
685 #define OP_AND(MODE)														\
686 			CLK(CLK_OP + CLK_R8 + CLK_##MODE);								\
687 			FLAG_N = FLAG_Z = REGISTER_A &= OPER_8_##MODE()
688 #else
689 #define OP_AND(MODE)														\
690 			CLK(CLK_OP + CLK_R16 + CLK_##MODE);								\
691 			FLAG_Z = REGISTER_A &= OPER_16_##MODE();								\
692 			FLAG_N = NFLAG_16(REGISTER_A)
693 #endif
694 
695 /* M6502   Arithmetic Shift Left accumulator */
696 #undef OP_ASL
697 #if FLAG_SET_M
698 #define OP_ASL()															\
699 			CLK(CLK_OP + CLK_IMPLIED);										\
700 			FLAG_C = REGISTER_A << 1;											\
701 			FLAG_N = FLAG_Z = REGISTER_A = MAKE_UINT_8(FLAG_C)
702 #else
703 #define OP_ASL()															\
704 			CLK(CLK_OP + CLK_IMPLIED);										\
705 			FLAG_C = REGISTER_A << 1;											\
706 			FLAG_Z = REGISTER_A = MAKE_UINT_16(FLAG_C);							\
707 			FLAG_N = NFLAG_16(FLAG_C);										\
708 			FLAG_C = CFLAG_16(FLAG_C)
709 #endif
710 
711 /* M6502   Arithmetic Shift Left operand */
712 #undef OP_ASLM
713 #if FLAG_SET_M
714 #define OP_ASLM(MODE)														\
715 			CLK(CLK_OP + CLK_RMW8 + CLK_W_##MODE);							\
716 			DST    = EA_##MODE();											\
717 			FLAG_C = read_8_##MODE(DST) << 1;								\
718 			FLAG_N = FLAG_Z = MAKE_UINT_8(FLAG_C);							\
719 			write_8_##MODE(DST, FLAG_Z)
720 #else
721 #define OP_ASLM(MODE)														\
722 			CLK(CLK_OP + CLK_RMW16 + CLK_W_##MODE);							\
723 			DST    = EA_##MODE();											\
724 			FLAG_C = read_16_##MODE(DST) << 1;								\
725 			FLAG_Z = MAKE_UINT_16(FLAG_C);									\
726 			FLAG_N = NFLAG_16(FLAG_C);										\
727 			FLAG_C = CFLAG_16(FLAG_C);										\
728 			write_16_##MODE(DST, FLAG_Z)
729 #endif
730 
731 /* M6502   Branch on Condition Code */
732 #undef OP_BCC
733 #define OP_BCC(COND)														\
734 			DST = OPER_8_IMM();												\
735 			if(COND)														\
736 			{																\
737 				CLK(CLK_OP + CLK_RELATIVE_8 + 1);							\
738 				g65816i_branch_8(DST);										\
739 				BREAKOUT;													\
740 			}																\
741 			CLK(CLK_OP + CLK_RELATIVE_8);									\
742 
743 /* M6502   Set flags according to bits */
744 #undef OP_BIT
745 #if FLAG_SET_M
746 #define OP_BIT(MODE)														\
747 			CLK(CLK_OP + CLK_R8 + CLK_##MODE);								\
748 			FLAG_N = OPER_8_##MODE();										\
749 			FLAG_Z = FLAG_N & REGISTER_A;										\
750 			FLAG_V = FLAG_N << 1
751 #else
752 #define OP_BIT(MODE)														\
753 			CLK(CLK_OP + CLK_R16 + CLK_##MODE);								\
754 			FLAG_N = OPER_16_##MODE();										\
755 			FLAG_Z = FLAG_N & REGISTER_A;										\
756 			FLAG_N = NFLAG_16(FLAG_N);										\
757 			FLAG_V = FLAG_N << 1
758 #endif
759 
760 /* G65816  Set flags according to bits (immediate addressing mode) */
761 #undef OP_BITI
762 #if FLAG_SET_M
763 #define OP_BITI()															\
764 			CLK(CLK_OP + CLK_R8 + CLK_IMM);									\
765 			FLAG_Z = REGISTER_A & OPER_8_IMM()
766 #else
767 #define OP_BITI()															\
768 			CLK(CLK_OP + CLK_R16 + CLK_IMM);								\
769 			FLAG_Z = REGISTER_A & OPER_16_IMM()
770 #endif
771 
772 /* M6502   Cause a Break interrupt */
773 #undef OP_BRK
774 #define OP_BRK()															\
775 			REGISTER_PC++;														\
776 			g65816i_interrupt_software(VECTOR_BRK)
777 
778 /* G65816  Branch Always */
779 #undef OP_BRA
780 #define OP_BRA()															\
781 			CLK(CLK_OP + CLK_IMPLIED + CLK_RELATIVE_8);						\
782 			g65816i_branch_8(OPER_8_IMM())
783 
784 /* G65816  Branch Always Long */
785 #undef OP_BRL
786 #define OP_BRL()															\
787 			CLK(CLK_OP + CLK_IMPLIED + CLK_RELATIVE_16);					\
788 			g65816i_branch_16(OPER_16_IMM())
789 
790 /* M6502   Clear Carry flag */
791 #undef OP_CLC
792 #define OP_CLC()															\
793 			CLK(CLK_OP + CLK_IMPLIED);										\
794 			FLAG_C = CFLAG_CLEAR
795 
796 /* M6502   Clear Decimal flag */
797 #undef OP_CLD
798 #define OP_CLD()															\
799 			CLK(CLK_OP + CLK_IMPLIED);										\
800 			FLAG_D = DFLAG_CLEAR
801 
802 /* M6502   Clear Interrupt Mask flag */
803 #undef OP_CLI
804 #define OP_CLI()															\
805 			CLK(CLK_OP + CLK_IMPLIED);										\
806 			g65816i_set_flag_i(IFLAG_CLEAR)
807 
808 /* M6502   Clear oVerflow flag */
809 #undef OP_CLV
810 #define OP_CLV()															\
811 			CLK(CLK_OP + CLK_IMPLIED);										\
812 			FLAG_V = VFLAG_CLEAR
813 
814 /* M6502   Compare operand to accumulator */
815 /* Unusual behavior: C flag is inverted */
816 #undef OP_CMP
817 #if FLAG_SET_M
818 #define OP_CMP(MODE)														\
819 			CLK(CLK_OP + CLK_R8 + CLK_##MODE);								\
820 			FLAG_C = REGISTER_A - OPER_8_##MODE();								\
821 			FLAG_N = FLAG_Z = MAKE_UINT_8(FLAG_C);							\
822 			FLAG_C ^= CFLAG_SET
823 #else
824 #define OP_CMP(MODE)														\
825 			CLK(CLK_OP + CLK_R16 + CLK_##MODE);								\
826 			FLAG_C = REGISTER_A - OPER_16_##MODE();								\
827 			FLAG_Z = MAKE_UINT_16(FLAG_C);									\
828 			FLAG_N = NFLAG_16(FLAG_C);										\
829 			FLAG_C = ~CFLAG_16(FLAG_C)
830 #endif
831 
832 /* M6502   Compare operand to index register */
833 /* Unusual behavior: C flag is inverted */
834 #undef OP_CMPX
835 #if FLAG_SET_X
836 #define OP_CMPX(REG, MODE)													\
837 			CLK(CLK_OP + CLK_R8 + CLK_##MODE);								\
838 			FLAG_C = REG - OPER_8_##MODE();									\
839 			FLAG_N = FLAG_Z = MAKE_UINT_8(FLAG_C);							\
840 			FLAG_C ^= CFLAG_SET
841 #else
842 #define OP_CMPX(REG, MODE)													\
843 			CLK(CLK_OP + CLK_R16 + CLK_##MODE);								\
844 			FLAG_C = REG - OPER_16_##MODE();								\
845 			FLAG_Z = MAKE_UINT_16(FLAG_C);									\
846 			FLAG_N = NFLAG_16(FLAG_C);										\
847 			FLAG_C = ~CFLAG_16(FLAG_C)
848 #endif
849 
850 /* G65816  Coprocessor operation */
851 #undef OP_COP
852 #define OP_COP()															\
853 			REGISTER_PC++;														\
854 			g65816i_interrupt_software(VECTOR_COP)
855 
856 /* M6502   Decrement accumulator */
857 #undef OP_DEC
858 #if FLAG_SET_M
859 #define OP_DEC()															\
860 			CLK(CLK_OP + CLK_IMPLIED);										\
861 			FLAG_N = FLAG_Z = REGISTER_A = MAKE_UINT_8(REGISTER_A - 1)
862 #else
863 #define OP_DEC()															\
864 			CLK(CLK_OP + CLK_IMPLIED);										\
865 			FLAG_Z = REGISTER_A = MAKE_UINT_16(REGISTER_A - 1);						\
866 			FLAG_N = NFLAG_16(REGISTER_A)
867 #endif
868 
869 /* M6502   Decrement operand */
870 #undef OP_DECM
871 #if FLAG_SET_M
872 #define OP_DECM(MODE)														\
873 			CLK(CLK_OP + CLK_RMW8 + CLK_W_##MODE);							\
874 			DST    = EA_##MODE();											\
875 			FLAG_N = FLAG_Z = MAKE_UINT_8(read_8_##MODE(DST) - 1);			\
876 			write_8_##MODE(DST, FLAG_Z)
877 #else
878 #define OP_DECM(MODE)														\
879 			CLK(CLK_OP + CLK_RMW16 + CLK_W_##MODE);							\
880 			DST    = EA_##MODE();											\
881 			FLAG_Z = MAKE_UINT_16(read_16_##MODE(DST) - 1);					\
882 			FLAG_N = NFLAG_16(FLAG_Z);										\
883 			write_16_##MODE(DST, FLAG_Z)
884 #endif
885 
886 /* M6502   Decrement index register */
887 #undef OP_DECX
888 #if FLAG_SET_X
889 #define OP_DECX(REG)														\
890 			CLK(CLK_OP + CLK_IMPLIED);										\
891 			FLAG_N = FLAG_Z = REG = MAKE_UINT_8(REG - 1)
892 #else
893 #define OP_DECX(REG)														\
894 			CLK(CLK_OP + CLK_IMPLIED);										\
895 			FLAG_Z = REG = MAKE_UINT_16(REG - 1);							\
896 			FLAG_N = NFLAG_16(REG)
897 #endif
898 
899 /* M6502   Exclusive Or operand to accumulator */
900 #undef OP_EOR
901 #if FLAG_SET_M
902 #define OP_EOR(MODE)														\
903 			CLK(CLK_OP + CLK_R8 + CLK_##MODE);								\
904 			FLAG_N = FLAG_Z = REGISTER_A ^= OPER_8_##MODE()
905 #else
906 #define OP_EOR(MODE)														\
907 			CLK(CLK_OP + CLK_R16 + CLK_##MODE);								\
908 			FLAG_Z = REGISTER_A ^= OPER_16_##MODE();								\
909 			FLAG_N = NFLAG_16(REGISTER_A)
910 #endif
911 
912 /* M6502   Increment accumulator */
913 #undef OP_INC
914 #if FLAG_SET_M
915 #define OP_INC()															\
916 			CLK(CLK_OP + CLK_IMPLIED);										\
917 			FLAG_N = FLAG_Z = REGISTER_A = MAKE_UINT_8(REGISTER_A + 1)
918 #else
919 #define OP_INC()															\
920 			CLK(CLK_OP + CLK_IMPLIED);										\
921 			FLAG_Z = REGISTER_A = MAKE_UINT_16(REGISTER_A + 1);						\
922 			FLAG_N = NFLAG_16(REGISTER_A)
923 #endif
924 
925 /* M6502   Increment operand */
926 #undef OP_INCM
927 #if FLAG_SET_M
928 #define OP_INCM(MODE)														\
929 			CLK(CLK_OP + CLK_RMW8 + CLK_W_##MODE);							\
930 			DST    = EA_##MODE();											\
931 			FLAG_N = FLAG_Z = MAKE_UINT_8(read_8_##MODE(DST) + 1);			\
932 			write_8_##MODE(DST, FLAG_Z)
933 #else
934 #define OP_INCM(MODE)														\
935 			CLK(CLK_OP + CLK_RMW16 + CLK_W_##MODE);							\
936 			DST    = EA_##MODE();											\
937 			FLAG_Z = MAKE_UINT_16(read_16_##MODE(DST) + 1);					\
938 			FLAG_N = NFLAG_16(FLAG_Z);										\
939 			write_16_##MODE(DST, FLAG_Z)
940 #endif
941 
942 /* M6502   Increment index register */
943 #undef OP_INCX
944 #if FLAG_SET_X
945 #define OP_INCX(REG)														\
946 			CLK(CLK_OP + CLK_IMPLIED);										\
947 			FLAG_N = FLAG_Z = REG = MAKE_UINT_8(REG + 1)
948 #else
949 #define OP_INCX(REG)														\
950 			CLK(CLK_OP + CLK_IMPLIED);										\
951 			FLAG_Z = REG = MAKE_UINT_16(REG + 1);							\
952 			FLAG_N = NFLAG_16(REG)
953 #endif
954 
955 /* G65816  Jump Long */
956 #undef OP_JMLAI
957 #define OP_JMLAI()															\
958 			CLK(CLK_OP + CLK_AI + 1);										\
959 			g65816i_jump_24(read_24_A(OPER_16_IMM()))
960 
961 /* M6502   Jump */
962 #undef OP_JMP
963 #define OP_JMP(MODE)														\
964 			CLK(CLK_OP + CLK_##MODE);										\
965 			g65816i_jump_16(EA_##MODE())
966 
967 /* M6502   Jump absolute indexed indirect */
968 #undef OP_JMPAXI
969 #define OP_JMPAXI()															\
970 			CLK(CLK_OP + CLK_AXI);											\
971 			g65816i_jump_16(read_16_AXI(REGISTER_PB | (MAKE_UINT_16(OPER_16_IMM() + REGISTER_X))))
972 
973 /* G65816  Jump absolute long */
974 #undef OP_JMPAL
975 #define OP_JMPAL()															\
976 			CLK(CLK_OP + CLK_AL);											\
977 			g65816i_jump_24(EA_AL())
978 
979 /* G65816  Jump to Subroutine Long */
980 /* Unusual behavior: stacks PC-1 */
981 #undef OP_JSL
982 #define OP_JSL(MODE)														\
983 			CLK(CLK_OP + CLK_W24 + CLK_##MODE + 1);							\
984 			DST = EA_##MODE();												\
985 			g65816i_push_8(REGISTER_PB>>16);										\
986 			g65816i_push_16(REGISTER_PC-1);										\
987 			g65816i_jump_24(DST)
988 
989 /* M6502   Jump to Subroutine */
990 /* Unusual behavior: stacks PC-1 */
991 #undef OP_JSR
992 #define OP_JSR(MODE)														\
993 			CLK(CLK_OP + CLK_W16 + CLK_##MODE);								\
994 			DST = EA_##MODE();												\
995 			g65816i_push_16(REGISTER_PC-1);										\
996 			g65816i_jump_16(DST)
997 
998 /* M6502   Jump to Subroutine */
999 /* Unusual behavior: stacks PC-1 */
1000 #undef OP_JSRAXI
1001 #define OP_JSRAXI()															\
1002 			CLK(CLK_OP + CLK_W16 + CLK_AXI);								\
1003 			DST = read_16_AXI(REGISTER_PB | (MAKE_UINT_16(OPER_16_IMM() + REGISTER_X))); \
1004 			g65816i_push_16(REGISTER_PC-1);										\
1005 			g65816i_jump_16(DST)
1006 
1007 /* M6502   Load accumulator with operand */
1008 #undef OP_LDA
1009 #if FLAG_SET_M
1010 #define OP_LDA(MODE)														\
1011 			CLK(CLK_OP + CLK_R8 + CLK_##MODE);								\
1012 			FLAG_N = FLAG_Z = REGISTER_A = OPER_8_##MODE()
1013 #else
1014 #define OP_LDA(MODE)														\
1015 			CLK(CLK_OP + CLK_R16 + CLK_##MODE);								\
1016 			FLAG_Z = REGISTER_A = OPER_16_##MODE();								\
1017 			FLAG_N = NFLAG_16(REGISTER_A)
1018 #endif
1019 
1020 /* M6502   Load index register with operand */
1021 #undef OP_LDX
1022 #if FLAG_SET_X
1023 #define OP_LDX(REG, MODE)													\
1024 			CLK(CLK_OP + CLK_R8 + CLK_##MODE);								\
1025 			FLAG_N = FLAG_Z = REG = OPER_8_##MODE()
1026 #else
1027 #define OP_LDX(REG, MODE)													\
1028 			CLK(CLK_OP + CLK_R16 + CLK_##MODE);								\
1029 			FLAG_Z = REG = OPER_16_##MODE();								\
1030 			FLAG_N = NFLAG_16(REG)
1031 #endif
1032 
1033 /* M6502   Logical Shift Right accumulator */
1034 #undef OP_LSR
1035 #if FLAG_SET_M
1036 #define OP_LSR()															\
1037 			CLK(CLK_OP + CLK_IMPLIED);										\
1038 			FLAG_N = 0;														\
1039 			FLAG_C = REGISTER_A << 8;											\
1040 			FLAG_Z = REGISTER_A >>= 1
1041 #else
1042 #define OP_LSR()															\
1043 			CLK(CLK_OP + CLK_IMPLIED);										\
1044 			FLAG_N = 0;														\
1045 			FLAG_C = REGISTER_A << 8;											\
1046 			FLAG_Z = REGISTER_A >>= 1
1047 #endif
1048 
1049 /* M6502   Logical Shift Right operand */
1050 #undef OP_LSRM
1051 #if FLAG_SET_M
1052 #define OP_LSRM(MODE)														\
1053 			CLK(CLK_OP + CLK_RMW8 + CLK_W_##MODE);							\
1054 			DST    = EA_##MODE();											\
1055 			FLAG_N = 0;														\
1056 			FLAG_Z = read_8_##MODE(DST);									\
1057 			FLAG_C = FLAG_Z << 8;											\
1058 			FLAG_Z >>= 1;													\
1059 			write_8_##MODE(DST, FLAG_Z)
1060 #else
1061 #define OP_LSRM(MODE)														\
1062 			CLK(CLK_OP + CLK_RMW16 + CLK_W_##MODE);							\
1063 			DST    = EA_##MODE();											\
1064 			FLAG_N = 0;														\
1065 			FLAG_Z = read_16_##MODE(DST);									\
1066 			FLAG_C = FLAG_Z << 8;											\
1067 			FLAG_Z >>= 1;													\
1068 			write_16_##MODE(DST, FLAG_Z)
1069 #endif
1070 
1071 /* G65816  Move Block Negative */
1072 #undef OP_MVN
1073 #if FLAG_SET_X
1074 #define OP_MVN()															\
1075 			DST = OPER_8_IMM()<<16;											\
1076 			SRC = OPER_8_IMM()<<16;											\
1077 			REGISTER_A |= REGISTER_B;													\
1078 			CLK((REGISTER_A+1)<<3);												\
1079 			for(;(int)REGISTER_A >= 0;REGISTER_A--)									\
1080 			{																\
1081 				write_8_NORM(DST | REGISTER_Y, read_8_NORM(SRC | REGISTER_X));		\
1082 				REGISTER_X = MAKE_UINT_8(REGISTER_X+1);								\
1083 				REGISTER_Y = MAKE_UINT_8(REGISTER_Y+1);								\
1084 			}																\
1085 			if(!FLAG_M)														\
1086 			{																\
1087 				REGISTER_A = 0xffff;												\
1088 				BREAKOUT;													\
1089 			}																\
1090 			REGISTER_A = 0x00ff;													\
1091 			REGISTER_B = 0xff00
1092 #else
1093 #define OP_MVN()															\
1094 			DST = OPER_8_IMM()<<16;											\
1095 			SRC = OPER_8_IMM()<<16;											\
1096 			REGISTER_A |= REGISTER_B;													\
1097 			CLK((REGISTER_A+1)<<3);												\
1098 			for(;(int)REGISTER_A >= 0;REGISTER_A--)									\
1099 			{																\
1100 				write_8_NORM(DST | REGISTER_Y, read_8_NORM(SRC | REGISTER_X));		\
1101 				REGISTER_X = MAKE_UINT_16(REGISTER_X+1);								\
1102 				REGISTER_Y = MAKE_UINT_16(REGISTER_Y+1);								\
1103 			}																\
1104 			if(!FLAG_M)														\
1105 			{																\
1106 				REGISTER_A = 0xffff;												\
1107 				BREAKOUT;													\
1108 			}																\
1109 			REGISTER_A = 0x00ff;													\
1110 			REGISTER_B = 0xff00
1111 #endif
1112 
1113 /* G65816  Move Block Positive */
1114 #undef OP_MVP
1115 #if FLAG_SET_X
1116 #define OP_MVP()															\
1117 			DST = OPER_8_IMM()<<16;											\
1118 			SRC = OPER_8_IMM()<<16;											\
1119 			REGISTER_A |= REGISTER_B;													\
1120 			CLK((REGISTER_A+1)<<3);												\
1121 			for(;(int)REGISTER_A >= 0;REGISTER_A--)									\
1122 			{																\
1123 				write_8_NORM(DST | REGISTER_Y, read_8_NORM(SRC | REGISTER_X));		\
1124 				REGISTER_X = MAKE_UINT_8(REGISTER_X-1);								\
1125 				REGISTER_Y = MAKE_UINT_8(REGISTER_Y-1);								\
1126 			}																\
1127 			if(!FLAG_M)														\
1128 			{																\
1129 				REGISTER_A = 0xffff;												\
1130 				BREAKOUT;													\
1131 			}																\
1132 			REGISTER_A = 0x00ff;													\
1133 			REGISTER_B = 0xff00
1134 #else
1135 #define OP_MVP()															\
1136 			DST = OPER_8_IMM()<<16;											\
1137 			SRC = OPER_8_IMM()<<16;											\
1138 			REGISTER_A |= REGISTER_B;													\
1139 			CLK((REGISTER_A+1)<<3);												\
1140 			for(;(int)REGISTER_A >= 0;REGISTER_A--)									\
1141 			{																\
1142 				write_8_NORM(DST | REGISTER_Y, read_8_NORM(SRC | REGISTER_X));		\
1143 				REGISTER_X = MAKE_UINT_16(REGISTER_X-1);								\
1144 				REGISTER_Y = MAKE_UINT_16(REGISTER_Y-1);								\
1145 			}																\
1146 			if(!FLAG_M)														\
1147 			{																\
1148 				REGISTER_A = 0xffff;												\
1149 				BREAKOUT;													\
1150 			}																\
1151 			REGISTER_A = 0x00ff;													\
1152 			REGISTER_B = 0xff00
1153 #endif
1154 
1155 /* M6502   No Operation */
1156 #undef OP_NOP
1157 #define OP_NOP()															\
1158 			CLK(CLK_OP + CLK_IMPLIED)
1159 
1160 /* M6502   Logical OR operand to accumulator */
1161 #undef OP_ORA
1162 #if FLAG_SET_M
1163 #define OP_ORA(MODE)														\
1164 			CLK(CLK_OP + CLK_R8 + CLK_##MODE);								\
1165 			FLAG_N = FLAG_Z = REGISTER_A |= OPER_8_ ## MODE()
1166 #else
1167 #define OP_ORA(MODE)														\
1168 			CLK(CLK_OP + CLK_R16 + CLK_##MODE);								\
1169 			FLAG_Z = REGISTER_A |= OPER_16_##MODE();								\
1170 			FLAG_N = NFLAG_16(REGISTER_A)
1171 #endif
1172 
1173 /* G65816  Push Effective Address */
1174 #undef OP_PEA
1175 #define OP_PEA()															\
1176 			CLK(CLK_OP + CLK_R16 + CLK_W16);								\
1177 			g65816i_push_16(OPER_16_IMM())
1178 
1179 /* G65816  Push Effective Indirect Address */
1180 #undef OP_PEI
1181 #define OP_PEI()															\
1182 			CLK(CLK_OP + CLK_R16 + CLK_W16 + CLK_D);						\
1183 			g65816i_push_16(EA_DI())
1184 
1185 /* G65816  Push Effective PC-Relative Address */
1186 #undef OP_PER
1187 #define OP_PER()															\
1188 			CLK(CLK_OP + CLK_R16 + CLK_W16 + 1);							\
1189 			SRC = OPER_16_IMM();											\
1190 			g65816i_push_16(REGISTER_PC + SRC)
1191 
1192 /* M6502   Push accumulator to the stack */
1193 #undef OP_PHA
1194 #if FLAG_SET_M
1195 #define OP_PHA()															\
1196 			CLK(CLK_OP + CLK_W8 + 1);										\
1197 			g65816i_push_8(REGISTER_A)
1198 #else
1199 #define OP_PHA()															\
1200 			CLK(CLK_OP + CLK_W16 + 1);										\
1201 			g65816i_push_16(REGISTER_A)
1202 #endif
1203 
1204 /* M6502   Push index register to the stack */
1205 #undef OP_PHX
1206 #if FLAG_SET_X
1207 #define OP_PHX(REG)															\
1208 			CLK(CLK_OP + CLK_W8 + 1);										\
1209 			g65816i_push_8(REG)
1210 #else
1211 #define OP_PHX(REG)															\
1212 			CLK(CLK_OP + CLK_W16 + 1);										\
1213 			g65816i_push_16(REG)
1214 #endif
1215 
1216 /* G65816  Push data bank register */
1217 #undef OP_PHB
1218 #define OP_PHB()															\
1219 			CLK(CLK_OP + CLK_W8 + 1);										\
1220 			g65816i_push_8(REGISTER_DB>>16)
1221 
1222 /* G65816  Push direct register */
1223 #undef OP_PHD
1224 #define OP_PHD()															\
1225 			CLK(CLK_OP + CLK_W16 + 1);										\
1226 			g65816i_push_16(REGISTER_D)
1227 
1228 /* G65816  Push program bank register */
1229 #undef OP_PHK
1230 #define OP_PHK()															\
1231 			CLK(CLK_OP + CLK_W8 + 1);										\
1232 			g65816i_push_8(REGISTER_PB>>16)
1233 
1234 /* M6502   Push the Processor Status Register to the stack */
1235 #undef OP_PHP
1236 #define OP_PHP()															\
1237 			CLK(CLK_OP + CLK_W8 + 1);										\
1238 			g65816i_push_8(g65816i_get_reg_p())
1239 
1240 /* M6502   Pull accumulator from the stack */
1241 #undef OP_PLA
1242 #if FLAG_SET_M
1243 #define OP_PLA()															\
1244 			CLK(CLK_OP + CLK_R8 + 2);										\
1245 			FLAG_N = FLAG_Z = REGISTER_A = g65816i_pull_8()
1246 #else
1247 #define OP_PLA()															\
1248 			CLK(CLK_OP + CLK_R16 + 2);										\
1249 			FLAG_Z = REGISTER_A = g65816i_pull_16();								\
1250 			FLAG_N = NFLAG_16(FLAG_Z)
1251 #endif
1252 
1253 /* M6502   Pull index register from the stack */
1254 #undef OP_PLX
1255 #if FLAG_SET_X
1256 #define OP_PLX(REG)															\
1257 			CLK(CLK_OP + CLK_R8 + 2);										\
1258 			FLAG_N = FLAG_Z = REG = g65816i_pull_8()
1259 #else
1260 #define OP_PLX(REG)															\
1261 			CLK(CLK_OP + CLK_R16 + 2);										\
1262 			FLAG_Z = REG = g65816i_pull_16();								\
1263 			FLAG_N = NFLAG_16(FLAG_Z)
1264 #endif
1265 
1266 /* G65816  Pull data bank register */
1267 #undef OP_PLB
1268 #define OP_PLB()															\
1269 			CLK(CLK_OP + CLK_R8 + 2);										\
1270 			FLAG_N = FLAG_Z = g65816i_pull_8();								\
1271 			REGISTER_DB = FLAG_Z << 16
1272 
1273 /* G65816  Pull direct register */
1274 #undef OP_PLD
1275 #define OP_PLD()															\
1276 			CLK(CLK_OP + CLK_R16 + 2);										\
1277 			FLAG_Z = REGISTER_D = g65816i_pull_16();								\
1278 			FLAG_N = NFLAG_16(FLAG_Z)
1279 
1280 /* M6502   Pull the Processor Status Register from the stack */
1281 #undef OP_PLP
1282 #define OP_PLP()															\
1283 			CLK(CLK_OP + CLK_R8 + 2);										\
1284 			g65816i_set_reg_p(g65816i_pull_8())
1285 
1286 /* G65816  Reset Program status word */
1287 #undef OP_REP
1288 #define OP_REP()															\
1289 			CLK(CLK_OP + CLK_R8 + 1);										\
1290 			g65816i_set_reg_p(g65816i_get_reg_p() & ~OPER_8_IMM())
1291 
1292 /* M6502   Rotate Left the accumulator */
1293 #undef OP_ROL
1294 #if FLAG_SET_M
1295 #define OP_ROL()															\
1296 			CLK(CLK_OP + CLK_IMPLIED);										\
1297 			FLAG_C = (REGISTER_A<<1) | CFLAG_AS_1();								\
1298 			FLAG_N = FLAG_Z = REGISTER_A = MAKE_UINT_8(FLAG_C)
1299 #else
1300 #define OP_ROL()															\
1301 			CLK(CLK_OP + CLK_IMPLIED);										\
1302 			FLAG_C = (REGISTER_A<<1) | CFLAG_AS_1();								\
1303 			FLAG_Z = REGISTER_A = MAKE_UINT_16(FLAG_C);							\
1304 			FLAG_N = NFLAG_16(FLAG_C);										\
1305 			FLAG_C = CFLAG_16(FLAG_C)
1306 #endif
1307 
1308 /* M6502   Rotate Left an operand */
1309 #undef OP_ROLM
1310 #if FLAG_SET_M
1311 #define OP_ROLM(MODE)														\
1312 			CLK(CLK_OP + CLK_RMW8 + CLK_W_##MODE);							\
1313 			DST = EA_##MODE();												\
1314 			FLAG_C = (read_8_##MODE(DST)<<1) | CFLAG_AS_1();				\
1315 			FLAG_N = FLAG_Z = MAKE_UINT_8(FLAG_C);							\
1316 			write_8_##MODE(DST, FLAG_Z)
1317 #else
1318 #define OP_ROLM(MODE)														\
1319 			CLK(CLK_OP + CLK_RMW16 + CLK_W_##MODE);							\
1320 			DST = EA_##MODE();												\
1321 			FLAG_C = (read_16_##MODE(DST)<<1) | CFLAG_AS_1();				\
1322 			FLAG_Z = MAKE_UINT_16(FLAG_C);									\
1323 			FLAG_N = NFLAG_16(FLAG_C);										\
1324 			FLAG_C = CFLAG_16(FLAG_C);										\
1325 			write_16_##MODE(DST, FLAG_Z)
1326 #endif
1327 
1328 /* M6502   Rotate Right the accumulator */
1329 #undef OP_ROR
1330 #if FLAG_SET_M
1331 #define OP_ROR()															\
1332 			CLK(CLK_OP + CLK_IMPLIED);										\
1333 			REGISTER_A |= FLAG_C & 0x100;										\
1334 			FLAG_C = REGISTER_A << 8;											\
1335 			FLAG_N = FLAG_Z = REGISTER_A >>= 1
1336 #else
1337 #define OP_ROR()															\
1338 			CLK(CLK_OP + CLK_IMPLIED);										\
1339 			REGISTER_A |= (FLAG_C<<8) & 0x10000;									\
1340 			FLAG_C = REGISTER_A << 8;											\
1341 			FLAG_Z = REGISTER_A >>= 1;											\
1342 			FLAG_N = NFLAG_16(REGISTER_A)
1343 #endif
1344 
1345 /* M6502   Rotate Right an operand */
1346 #undef OP_RORM
1347 #if FLAG_SET_M
1348 #define OP_RORM(MODE)														\
1349 			CLK(CLK_OP + CLK_RMW8 + CLK_W_##MODE);							\
1350 			DST = EA_##MODE();												\
1351 			FLAG_Z = read_8_##MODE(DST) | (FLAG_C & 0x100);					\
1352 			FLAG_C = FLAG_Z << 8;											\
1353 			FLAG_N = FLAG_Z >>= 1;											\
1354 			write_8_##MODE(DST, FLAG_Z)
1355 #else
1356 #define OP_RORM(MODE)														\
1357 			CLK(CLK_OP + CLK_RMW16 + CLK_W_##MODE);							\
1358 			DST = EA_##MODE();												\
1359 			FLAG_Z = read_16_##MODE(DST) | ((FLAG_C<<8) & 0x10000);			\
1360 			FLAG_C = FLAG_Z << 8;											\
1361 			FLAG_Z >>= 1;													\
1362 			FLAG_N = NFLAG_16(FLAG_Z);										\
1363 			write_16_##MODE(DST, FLAG_Z)
1364 #endif
1365 
1366 /* M6502   Return from Interrupt */
1367 #undef OP_RTI
1368 #if FLAG_SET_E
1369 #define OP_RTI()															\
1370 			CLK(7);															\
1371 			g65816i_set_reg_p(g65816i_pull_8());							\
1372 			g65816i_jump_16(g65816i_pull_16())
1373 #else
1374 #define OP_RTI()															\
1375 			CLK(8);															\
1376 			g65816i_set_reg_p(g65816i_pull_8());							\
1377 			g65816i_jump_16(g65816i_pull_16());								\
1378 			REGISTER_PB = g65816i_pull_8() << 16
1379 #endif
1380 
1381 /* G65816  Return from Subroutine Long */
1382 /* Unusual behavior: Gets PC and increments */
1383 #undef OP_RTL
1384 #define OP_RTL()															\
1385 			CLK(6);															\
1386 			g65816i_jump_24(g65816i_pull_24()+1)
1387 
1388 /* M6502   Return from Subroutine */
1389 /* Unusual behavior: Gets PC and increments */
1390 #undef OP_RTS
1391 #define OP_RTS()															\
1392 			CLK(6);															\
1393 			g65816i_jump_16(g65816i_pull_16()+1)
1394 
1395 /* M6502   Subtract with Carry */
1396 /* Unusual behavior: C flag is inverted */
1397 #undef OP_SBC
1398 #if FLAG_SET_M
1399 #define OP_SBC(MODE)														\
1400 			CLK(CLK_OP + CLK_R8 + CLK_##MODE);								\
1401 			SRC = OPER_8_##MODE();											\
1402 			FLAG_C = ~FLAG_C;												\
1403 			if(!FLAG_D)														\
1404 			{																\
1405 				FLAG_C = REGISTER_A - SRC - CFLAG_AS_1();						\
1406 				FLAG_V = VFLAG_SUB_8(SRC, REGISTER_A, FLAG_C);					\
1407 				FLAG_N = FLAG_Z = REGISTER_A = MAKE_UINT_8(FLAG_C);				\
1408 				FLAG_C = ~FLAG_C;											\
1409 				BREAKOUT;													\
1410 			}																\
1411 			DST = CFLAG_AS_1();												\
1412 			FLAG_C = REGISTER_A - SRC - DST;										\
1413 			FLAG_V = VFLAG_SUB_8(SRC, REGISTER_A, FLAG_C);						\
1414 			if((FLAG_C & 0xf) > 9)											\
1415 				FLAG_C-=6;													\
1416 			if((FLAG_C & 0xf0) > 0x90)										\
1417 				FLAG_C-=0x60;												\
1418 			FLAG_N = FLAG_Z = REGISTER_A = MAKE_UINT_8(FLAG_C);					\
1419 			FLAG_C = ~FLAG_C
1420 #else
1421 #define OP_SBC(MODE)														\
1422 			CLK(CLK_OP + CLK_R16 + CLK_##MODE);								\
1423 			SRC = OPER_16_##MODE();											\
1424 			FLAG_C = ~FLAG_C;												\
1425 			if(!FLAG_D)														\
1426 			{																\
1427 				FLAG_C = REGISTER_A - SRC - CFLAG_AS_1();						\
1428 				FLAG_V = VFLAG_SUB_16(SRC, REGISTER_A, FLAG_C);					\
1429 				FLAG_Z = REGISTER_A = MAKE_UINT_16(FLAG_C);						\
1430 				FLAG_N = NFLAG_16(REGISTER_A);									\
1431 				FLAG_C = ~CFLAG_16(FLAG_C);									\
1432 				BREAKOUT;													\
1433 			}																\
1434 			DST    = CFLAG_AS_1();											\
1435 			FLAG_C = MAKE_UINT_8(REGISTER_A) - MAKE_UINT_8(SRC) - DST;			\
1436 			if((FLAG_C & 0xf) > 9)											\
1437 				FLAG_C-=6;													\
1438 			if((FLAG_C & 0xf0) > 0x90)										\
1439 				FLAG_C-=0x60;												\
1440 			FLAG_Z = MAKE_UINT_8(FLAG_C);									\
1441 			DST    = CFLAG_AS_1();											\
1442 			FLAG_C = MAKE_UINT_8(REGISTER_A>>8) - MAKE_UINT_8(SRC>>8) - DST;		\
1443 			if((FLAG_C & 0xf) > 9)											\
1444 				FLAG_C-=6;													\
1445 			if((FLAG_C & 0xf0) > 0x90)										\
1446 				FLAG_C-=0x60;												\
1447 			FLAG_Z |= MAKE_UINT_8(FLAG_C) << 8;								\
1448 			FLAG_N = NFLAG_16(FLAG_Z);										\
1449 			FLAG_V = VFLAG_SUB_16(SRC, REGISTER_A, FLAG_Z);						\
1450 			REGISTER_A  = FLAG_Z;												\
1451 			FLAG_C = ~FLAG_C
1452 #endif
1453 
1454 /* M6502   Set Carry flag */
1455 #undef OP_SEC
1456 #define OP_SEC()															\
1457 			CLK(CLK_OP + CLK_IMPLIED);										\
1458 			FLAG_C = CFLAG_SET
1459 
1460 /* M6502   Set Decimal flag */
1461 #undef OP_SED
1462 #define OP_SED()															\
1463 			CLK(CLK_OP + CLK_IMPLIED);										\
1464 			FLAG_D = DFLAG_SET
1465 
1466 /* M6502   Set Interrupt Mask flag */
1467 #undef OP_SEI
1468 #define OP_SEI()															\
1469 			CLK(CLK_OP + CLK_IMPLIED);										\
1470 			g65816i_set_flag_i(IFLAG_SET)
1471 
1472 /* G65816  Set Program status word */
1473 #undef OP_SEP
1474 #define OP_SEP()															\
1475 			CLK(CLK_OP + CLK_R8 + 1);										\
1476 			g65816i_set_reg_p(g65816i_get_reg_p() | OPER_8_IMM())
1477 
1478 /* M6502   Store accumulator to memory */
1479 #undef OP_STA
1480 #if FLAG_SET_M
1481 #define OP_STA(MODE)														\
1482 			CLK(CLK_OP + CLK_W8 + CLK_W_##MODE);								\
1483 			write_8_##MODE(EA_##MODE(), REGISTER_A)
1484 #else
1485 #define OP_STA(MODE)														\
1486 			CLK(CLK_OP + CLK_W16 + CLK_W_##MODE);								\
1487 			write_16_##MODE(EA_##MODE(), REGISTER_A)
1488 #endif
1489 
1490 /* M6502   Store index register to memory */
1491 #undef OP_STX
1492 #if FLAG_SET_X
1493 #define OP_STX(REG, MODE)													\
1494 			CLK(CLK_OP + CLK_W8 + CLK_W_##MODE);								\
1495 			write_8_##MODE(EA_##MODE(), REG)
1496 #else
1497 #define OP_STX(REG, MODE)													\
1498 			CLK(CLK_OP + CLK_W16 + CLK_W_##MODE);								\
1499 			write_16_##MODE(EA_##MODE(), REG)
1500 #endif
1501 
1502 /* M6502   Store zero to memory */
1503 #undef OP_STZ
1504 #if FLAG_SET_M
1505 #define OP_STZ(MODE)														\
1506 			CLK(CLK_OP + CLK_W8 + CLK_W_##MODE);								\
1507 			write_8_##MODE(EA_##MODE(), 0)
1508 #else
1509 #define OP_STZ(MODE)														\
1510 			CLK(CLK_OP + CLK_W16 + CLK_W_##MODE);								\
1511 			write_16_##MODE(EA_##MODE(), 0)
1512 #endif
1513 
1514 /* G65816  Stop the clock */
1515 #undef OP_STP
1516 #define OP_STP()															\
1517 			USE_ALL_CLKS();													\
1518 			CPU_STOPPED |= STOP_LEVEL_STOP
1519 
1520 /* M6502   Transfer accumulator to index */
1521 #undef OP_TAX
1522 #if FLAG_SET_M
1523 #if FLAG_SET_X
1524 #define OP_TAX(REG)															\
1525 			CLK(CLK_OP + CLK_IMPLIED);										\
1526 			FLAG_Z = REG = REGISTER_A;											\
1527 			FLAG_N = NFLAG_8(FLAG_Z)
1528 #else /* FLAG_SET_X */
1529 #define OP_TAX(REG)															\
1530 			CLK(CLK_OP + CLK_IMPLIED);										\
1531 			FLAG_Z = REG = REGISTER_B | REGISTER_A;									\
1532 			FLAG_N = NFLAG_16(FLAG_Z)
1533 #endif /* FLAG_SET_X */
1534 #else /* FLAG_SET_M */
1535 #if FLAG_SET_X
1536 #define OP_TAX(REG)															\
1537 			CLK(CLK_OP + CLK_IMPLIED);										\
1538 			FLAG_Z = REG = MAKE_UINT_8(REGISTER_A);								\
1539 			FLAG_N = NFLAG_8(FLAG_Z)
1540 #else /* FLAG_SET_X */
1541 #define OP_TAX(REG)															\
1542 			CLK(CLK_OP + CLK_IMPLIED);										\
1543 			FLAG_Z = REG = REGISTER_A;											\
1544 			FLAG_N = NFLAG_16(FLAG_Z)
1545 #endif /* FLAG_SET_X */
1546 #endif /* FLAG_SET_M */
1547 
1548 
1549 /* M6502   Transfer index to accumulator */
1550 #undef OP_TXA
1551 #if FLAG_SET_M
1552 #define OP_TXA(REG)															\
1553 			CLK(CLK_OP + CLK_IMPLIED);										\
1554 			FLAG_Z = REGISTER_A = MAKE_UINT_8(REG);								\
1555 			FLAG_N = NFLAG_8(FLAG_Z)
1556 #else
1557 #define OP_TXA(REG)															\
1558 			CLK(CLK_OP + CLK_IMPLIED);										\
1559 			FLAG_Z = REGISTER_A = REG;											\
1560 			FLAG_N = NFLAG_16(FLAG_Z)
1561 #endif
1562 
1563 /* G65816  Transfer C to direct register */
1564 #undef OP_TCD
1565 #if FLAG_SET_M
1566 #define OP_TCD()															\
1567 			CLK(CLK_OP + CLK_IMPLIED);										\
1568 			FLAG_Z = REGISTER_D = REGISTER_A | REGISTER_B;									\
1569 			FLAG_N = NFLAG_16(FLAG_Z)
1570 #else
1571 #define OP_TCD()															\
1572 			CLK(CLK_OP + CLK_IMPLIED);										\
1573 			FLAG_Z = REGISTER_D = REGISTER_A;											\
1574 			FLAG_N = NFLAG_16(FLAG_Z)
1575 #endif
1576 
1577 /* G65816  Transfer direct register to C */
1578 #undef OP_TDC
1579 #if FLAG_SET_M
1580 #define OP_TDC()															\
1581 			CLK(CLK_OP + CLK_IMPLIED);										\
1582 			FLAG_Z = REGISTER_D;													\
1583 			FLAG_N = NFLAG_16(FLAG_Z);										\
1584 			REGISTER_A = MAKE_UINT_8(REGISTER_D);										\
1585 			REGISTER_B = REGISTER_D & 0xff00
1586 #else
1587 #define OP_TDC()															\
1588 			CLK(CLK_OP + CLK_IMPLIED);										\
1589 			FLAG_Z = REGISTER_A = REGISTER_D;											\
1590 			FLAG_N = NFLAG_16(FLAG_Z)
1591 #endif
1592 
1593 /* G65816  Transfer C to stack pointer */
1594 #undef OP_TCS
1595 #if FLAG_SET_E
1596 #define OP_TCS()															\
1597 			CLK(CLK_OP + CLK_IMPLIED);										\
1598 			REGISTER_S = MAKE_UINT_8(REGISTER_A) | 0x100
1599 #else
1600 #define OP_TCS()															\
1601 			CLK(CLK_OP + CLK_IMPLIED);										\
1602 			REGISTER_S = REGISTER_A | REGISTER_B
1603 #endif
1604 
1605 /* G65816  Transfer stack pointer to C */
1606 #undef OP_TSC
1607 #if FLAG_SET_M
1608 #define OP_TSC()															\
1609 			CLK(CLK_OP + CLK_IMPLIED);										\
1610 			FLAG_Z = REGISTER_S;													\
1611 			FLAG_N = NFLAG_16(FLAG_Z);										\
1612 			REGISTER_A = MAKE_UINT_8(REGISTER_S);										\
1613 			REGISTER_B = REGISTER_S & 0xff00
1614 #else
1615 #define OP_TSC()															\
1616 			CLK(CLK_OP + CLK_IMPLIED);										\
1617 			FLAG_Z = REGISTER_A = REGISTER_S;											\
1618 			FLAG_N = NFLAG_16(FLAG_Z)
1619 #endif
1620 
1621 /* M6502   Transfer stack pointer to X */
1622 #undef OP_TSX
1623 #if FLAG_SET_X
1624 #define OP_TSX()															\
1625 			CLK(CLK_OP + CLK_IMPLIED);										\
1626 			FLAG_Z = REGISTER_X = MAKE_UINT_8(REGISTER_S);							\
1627 			FLAG_N = NFLAG_8(FLAG_Z)
1628 #else
1629 #define OP_TSX()															\
1630 			CLK(CLK_OP + CLK_IMPLIED);										\
1631 			FLAG_Z = REGISTER_X = REGISTER_S;											\
1632 			FLAG_N = NFLAG_16(FLAG_Z)
1633 #endif
1634 
1635 /* M6502   Transfer X to stack pointer */
1636 #undef OP_TXS
1637 #if FLAG_SET_E
1638 #define OP_TXS()															\
1639 			CLK(CLK_OP + CLK_IMPLIED);										\
1640 			REGISTER_S = MAKE_UINT_8(REGISTER_X) | 0x100
1641 #else
1642 #define OP_TXS()															\
1643 			CLK(CLK_OP + CLK_IMPLIED);										\
1644 			REGISTER_S = REGISTER_X
1645 #endif
1646 
1647 /* G65816  Transfer X to Y */
1648 #undef OP_TXY
1649 #if FLAG_SET_X
1650 #define OP_TXY()															\
1651 			CLK(CLK_OP + CLK_IMPLIED);										\
1652 			FLAG_Z = REGISTER_Y = REGISTER_X;											\
1653 			FLAG_N = NFLAG_8(FLAG_Z)
1654 #else
1655 #define OP_TXY()															\
1656 			CLK(CLK_OP + CLK_IMPLIED);										\
1657 			FLAG_Z = REGISTER_Y = REGISTER_X;											\
1658 			FLAG_N = NFLAG_16(FLAG_Z)
1659 #endif
1660 
1661 /* G65816  Transfer Y to X */
1662 #undef OP_TYX
1663 #if FLAG_SET_X
1664 #define OP_TYX()															\
1665 			CLK(CLK_OP + CLK_IMPLIED);										\
1666 			FLAG_Z = REGISTER_X = REGISTER_Y;											\
1667 			FLAG_N = NFLAG_8(FLAG_Z)
1668 #else
1669 #define OP_TYX()															\
1670 			CLK(CLK_OP + CLK_IMPLIED);										\
1671 			FLAG_Z = REGISTER_X = REGISTER_Y;											\
1672 			FLAG_N = NFLAG_16(FLAG_Z)
1673 #endif
1674 
1675 /* G65816  Test and reset bit */
1676 #undef OP_TRB
1677 #if FLAG_SET_M
1678 #define OP_TRB(MODE)														\
1679 			CLK(CLK_OP + CLK_RMW8 + CLK_W_##MODE);							\
1680 			DST    = EA_##MODE();											\
1681 			FLAG_Z = read_8_##MODE(DST);									\
1682 			write_8_##MODE(DST, FLAG_Z & ~REGISTER_A);							\
1683 			FLAG_Z &= REGISTER_A
1684 #else
1685 #define OP_TRB(MODE)														\
1686 			CLK(CLK_OP + CLK_RMW16 + CLK_W_##MODE);							\
1687 			DST    = EA_##MODE();											\
1688 			FLAG_Z = read_16_##MODE(DST);									\
1689 			write_16_##MODE(DST, FLAG_Z & ~REGISTER_A);							\
1690 			FLAG_Z &= REGISTER_A
1691 #endif
1692 
1693 /* G65816  Test and set bit */
1694 #undef OP_TSB
1695 #if FLAG_SET_M
1696 #define OP_TSB(MODE)														\
1697 			CLK(CLK_OP + CLK_RMW8 + CLK_W_##MODE);							\
1698 			DST    = EA_##MODE();											\
1699 			FLAG_Z = read_8_##MODE(DST);									\
1700 			write_8_##MODE(DST, FLAG_Z | REGISTER_A);							\
1701 			FLAG_Z &= REGISTER_A
1702 #else
1703 #define OP_TSB(MODE)														\
1704 			CLK(CLK_OP + CLK_RMW16 + CLK_W_##MODE);							\
1705 			DST    = EA_##MODE();											\
1706 			FLAG_Z = read_16_##MODE(DST);									\
1707 			write_16_##MODE(DST, FLAG_Z | REGISTER_A);							\
1708 			FLAG_Z &= REGISTER_A
1709 #endif
1710 
1711 /* G65816  Wait for interrupt */
1712 #undef OP_WAI
1713 #define OP_WAI()															\
1714 			USE_ALL_CLKS();													\
1715 			CPU_STOPPED |= STOP_LEVEL_WAI
1716 
1717 /* G65816  William D. Mensch, JR. (65816 designer) - future expansion */
1718 #undef OP_WDM
1719 #define OP_WDM()															\
1720 			CLK(CLK_OP + CLK_IMPLIED);										\
1721 			REGISTER_PC++
1722 
1723 /* G65816  Exchange accum high and low bytes */
1724 #undef OP_XBA
1725 #if FLAG_SET_M
1726 #define OP_XBA()															\
1727 			CLK(CLK_OP + CLK_IMPLIED);										\
1728 			FLAG_Z = REGISTER_B>>8;												\
1729 			REGISTER_B = REGISTER_A<<8;												\
1730 			REGISTER_A = FLAG_Z;													\
1731 			FLAG_N = NFLAG_8(FLAG_Z)
1732 #else
1733 #define OP_XBA()															\
1734 			CLK(CLK_OP + CLK_IMPLIED + 1);									\
1735 			FLAG_Z = REGISTER_A >> 8;											\
1736 			REGISTER_A = MAKE_UINT_16(REGISTER_A<<8) | FLAG_Z;						\
1737 			FLAG_N = NFLAG_8(FLAG_Z)
1738 #endif
1739 
1740 /* G65816  Exchange carry and emulation bits */
1741 #undef OP_XCE
1742 #define OP_XCE()															\
1743 			CLK(CLK_OP + CLK_IMPLIED);										\
1744 			SRC = CFLAG_AS_1();												\
1745 			FLAG_C = FLAG_E<<8;												\
1746 			g65816i_set_flag_e(SRC)
1747 
1748 
1749 
1750 
1751 /* ======================================================================== */
1752 /* ======================== OPCODE & FUNCTION TABLES ====================== */
1753 /* ======================================================================== */
1754 
1755 #undef OP
1756 #undef O
1757 #undef TABLE_OPCODES
1758 #undef TABLE_FUNCTION
1759 
1760 #if FLAG_SET_E
1761 #define OP(CODE, OPERATION) static void g65816i_ ## CODE ## _E(void) {OPERATION;}
1762 #define O(CODE) g65816i_ ## CODE ## _E
1763 #define TABLE_OPCODES void (*g65816i_opcodes_E[256])(void)
1764 #define TABLE_FUNCTION(RTYPE, NAME, ARGS)	RTYPE g65816i_ ## NAME ## _E ARGS
1765 
1766 #else
1767 
1768 #if !FLAG_SET_M && !FLAG_SET_X
1769 #define OP(CODE, OPERATION) static void g65816i_ ## CODE ## _M0X0(void) {OPERATION;}
1770 #define O(CODE) g65816i_ ## CODE ## _M0X0
1771 #define TABLE_OPCODES void (*g65816i_opcodes_M0X0[256])(void)
1772 #define TABLE_FUNCTION(RTYPE, NAME, ARGS)	RTYPE g65816i_ ## NAME ## _M0X0 ARGS
1773 
1774 #elif !FLAG_SET_M && FLAG_SET_X
1775 
1776 #define OP(CODE, OPERATION) static void g65816i_ ## CODE ## _M0X1(void) {OPERATION;}
1777 #define O(CODE) g65816i_ ## CODE ## _M0X1
1778 #define TABLE_OPCODES void (*g65816i_opcodes_M0X1[256])(void)
1779 #define TABLE_FUNCTION(RTYPE, NAME, ARGS)	RTYPE g65816i_ ## NAME ## _M0X1 ARGS
1780 
1781 #elif FLAG_SET_M && !FLAG_SET_X
1782 
1783 #define OP(CODE, OPERATION) static void g65816i_ ## CODE ## _M1X0(void) {OPERATION;}
1784 #define O(CODE) g65816i_ ## CODE ## _M1X0
1785 #define TABLE_OPCODES void (*g65816i_opcodes_M1X0[256])(void)
1786 #define TABLE_FUNCTION(RTYPE, NAME, ARGS)	RTYPE g65816i_ ## NAME ## _M1X0 ARGS
1787 
1788 #elif FLAG_SET_M && FLAG_SET_X
1789 
1790 #define OP(CODE, OPERATION) static void g65816i_ ## CODE ## _M1X1(void) {OPERATION;}
1791 #define O(CODE) g65816i_ ## CODE ## _M1X1
1792 #define TABLE_OPCODES void (*g65816i_opcodes_M1X1[256])(void)
1793 #define TABLE_FUNCTION(RTYPE, NAME, ARGS)	RTYPE g65816i_ ## NAME ## _M1X1 ARGS
1794 
1795 #endif
1796 #endif
1797 #define BREAKOUT return
1798 
1799 
1800 
1801 /* OP  FUNCTION                     Comment     */
1802 OP(00, OP_BRK  (             ) ) /* BRK         */
1803 OP(01, OP_ORA  ( DXI         ) ) /* ORA dxi     */
1804 OP(02, OP_COP  (             ) ) /* COP     (G) */
1805 OP(03, OP_ORA  ( S           ) ) /* ORA s   (G) */
1806 OP(04, OP_TSB  ( D           ) ) /* TSB d   (C) */
1807 OP(05, OP_ORA  ( D           ) ) /* ORA d       */
1808 OP(06, OP_ASLM ( D           ) ) /* ASL d       */
1809 OP(07, OP_ORA  ( DLI         ) ) /* ORA dli (G) */
1810 OP(08, OP_PHP  (             ) ) /* PHP         */
1811 OP(09, OP_ORA  ( IMM         ) ) /* ORA imm     */
1812 OP(0a, OP_ASL  (             ) ) /* ASL acc     */
1813 OP(0b, OP_PHD  (             ) ) /* PHD     (G) */
1814 OP(0c, OP_TSB  ( A           ) ) /* TSB a   (C) */
1815 OP(0d, OP_ORA  ( A           ) ) /* ORA a       */
1816 OP(0e, OP_ASLM ( A           ) ) /* ASL a       */
1817 OP(0f, OP_ORA  ( AL          ) ) /* ORA al  (G) */
1818 OP(10, OP_BCC  ( COND_PL()   ) ) /* BPL         */
1819 OP(11, OP_ORA  ( DIY         ) ) /* ORA diy     */
1820 OP(12, OP_ORA  ( DI          ) ) /* ORA di  (C) */
1821 OP(13, OP_ORA  ( SIY         ) ) /* ORA siy (G) */
1822 OP(14, OP_TRB  ( D           ) ) /* TRB d   (C) */
1823 OP(15, OP_ORA  ( DX          ) ) /* ORA dx      */
1824 OP(16, OP_ASLM ( DX          ) ) /* ASL dx      */
1825 OP(17, OP_ORA  ( DLIY        ) ) /* ORA dliy(C) */
1826 OP(18, OP_CLC  (             ) ) /* CLC         */
1827 OP(19, OP_ORA  ( AY          ) ) /* ORA ay      */
1828 OP(1a, OP_INC  (             ) ) /* INA     (C) */
1829 OP(1b, OP_TCS  (             ) ) /* TCS     (G) */
1830 OP(1c, OP_TRB  ( A           ) ) /* TRB a   (C) */
1831 OP(1d, OP_ORA  ( AX          ) ) /* ORA ax      */
1832 OP(1e, OP_ASLM ( AX          ) ) /* ASL ax      */
1833 OP(1f, OP_ORA  ( ALX         ) ) /* ORA alx (G) */
1834 OP(20, OP_JSR  ( A           ) ) /* JSR a       */
1835 OP(21, OP_AND  ( DXI         ) ) /* AND dxi     */
1836 OP(22, OP_JSL  ( AL          ) ) /* JSL al  (G) */
1837 OP(23, OP_AND  ( S           ) ) /* AND s   (G) */
1838 OP(24, OP_BIT  ( D           ) ) /* BIT d       */
1839 OP(25, OP_AND  ( D           ) ) /* AND d       */
1840 OP(26, OP_ROLM ( D           ) ) /* ROL d       */
1841 OP(27, OP_AND  ( DLI         ) ) /* AND dli (G) */
1842 OP(28, OP_PLP  (             ) ) /* PLP         */
1843 OP(29, OP_AND  ( IMM         ) ) /* AND imm     */
1844 OP(2a, OP_ROL  (             ) ) /* ROL acc     */
1845 OP(2b, OP_PLD  (             ) ) /* PLD     (G) */
1846 OP(2c, OP_BIT  ( A           ) ) /* BIT a       */
1847 OP(2d, OP_AND  ( A           ) ) /* AND a       */
1848 OP(2e, OP_ROLM ( A           ) ) /* ROL a       */
1849 OP(2f, OP_AND  ( AL          ) ) /* AND al  (G) */
1850 OP(30, OP_BCC  ( COND_MI()   ) ) /* BMI         */
1851 OP(31, OP_AND  ( DIY         ) ) /* AND diy     */
1852 OP(32, OP_AND  ( DI          ) ) /* AND di  (C) */
1853 OP(33, OP_AND  ( SIY         ) ) /* AND siy     */
1854 OP(34, OP_BIT  ( DX          ) ) /* BIT dx  (C) */
1855 OP(35, OP_AND  ( DX          ) ) /* AND dx      */
1856 OP(36, OP_ROLM ( DX          ) ) /* ROL dx      */
1857 OP(37, OP_AND  ( DLIY        ) ) /* AND dliy(G) */
1858 OP(38, OP_SEC  (             ) ) /* SEC         */
1859 OP(39, OP_AND  ( AY          ) ) /* AND ay      */
1860 OP(3a, OP_DEC  (             ) ) /* DEA     (C) */
1861 OP(3b, OP_TSC  (             ) ) /* TSC     (G) */
1862 OP(3c, OP_BIT  ( AX          ) ) /* BIT abx (C) */
1863 OP(3d, OP_AND  ( AX          ) ) /* AND ax      */
1864 OP(3e, OP_ROLM ( AX          ) ) /* ROL ax      */
1865 OP(3f, OP_AND  ( ALX         ) ) /* AND alx (G) */
1866 OP(40, OP_RTI  (             ) ) /* RTI         */
1867 OP(41, OP_EOR  ( DXI         ) ) /* EOR dxi     */
1868 OP(42, OP_WDM  (             ) ) /* WDM         */
1869 OP(43, OP_EOR  ( S           ) ) /* EOR s   (G) */
1870 OP(44, OP_MVP  (             ) ) /* MVP     (G) */
1871 OP(45, OP_EOR  ( D           ) ) /* EOR d       */
1872 OP(46, OP_LSRM ( D           ) ) /* LSR d       */
1873 OP(47, OP_EOR  ( DLI         ) ) /* EOR dli (G) */
1874 OP(48, OP_PHA  (             ) ) /* PHA         */
1875 OP(49, OP_EOR  ( IMM         ) ) /* EOR imm     */
1876 OP(4a, OP_LSR  (             ) ) /* LSR acc     */
1877 OP(4b, OP_PHK  (             ) ) /* PHK     (G) */
1878 OP(4c, OP_JMP  ( A           ) ) /* JMP a       */
1879 OP(4d, OP_EOR  ( A           ) ) /* EOR a       */
1880 OP(4e, OP_LSRM ( A           ) ) /* LSR a       */
1881 OP(4f, OP_EOR  ( AL          ) ) /* EOR al  (G) */
1882 OP(50, OP_BCC  ( COND_VC()   ) ) /* BVC         */
1883 OP(51, OP_EOR  ( DIY         ) ) /* EOR diy     */
1884 OP(52, OP_EOR  ( DI          ) ) /* EOR di  (C) */
1885 OP(53, OP_EOR  ( SIY         ) ) /* EOR siy (G) */
1886 OP(54, OP_MVN  (             ) ) /* MVN     (G) */
1887 OP(55, OP_EOR  ( DX          ) ) /* EOR dx      */
1888 OP(56, OP_LSRM ( DX          ) ) /* LSR dx      */
1889 OP(57, OP_EOR  ( DLIY        ) ) /* EOR dliy(G) */
1890 OP(58, OP_CLI  (             ) ) /* CLI         */
1891 OP(59, OP_EOR  ( AY          ) ) /* EOR ay      */
1892 OP(5a, OP_PHX  ( REGISTER_Y       ) ) /* PHY     (C) */
1893 OP(5b, OP_TCD  (             ) ) /* TCD     (G) */
1894 OP(5c, OP_JMPAL(             ) ) /* JMP al  (G) */
1895 OP(5d, OP_EOR  ( AX          ) ) /* EOR ax      */
1896 OP(5e, OP_LSRM ( AX          ) ) /* LSR ax      */
1897 OP(5f, OP_EOR  ( ALX         ) ) /* EOR alx (G) */
1898 OP(60, OP_RTS  (             ) ) /* RTS         */
1899 OP(61, OP_ADC  ( DXI         ) ) /* ADC dxi     */
1900 OP(62, OP_PER  (             ) ) /* PER     (G) */
1901 OP(63, OP_ADC  ( S           ) ) /* ADC s   (G) */
1902 OP(64, OP_STZ  ( D           ) ) /* STZ d   (C) */
1903 OP(65, OP_ADC  ( D           ) ) /* ADC d       */
1904 OP(66, OP_RORM ( D           ) ) /* ROR d       */
1905 OP(67, OP_ADC  ( DLI         ) ) /* ADC dli (G) */
1906 OP(68, OP_PLA  (             ) ) /* PLA         */
1907 OP(69, OP_ADC  ( IMM         ) ) /* ADC imm     */
1908 OP(6a, OP_ROR  (             ) ) /* ROR acc     */
1909 OP(6b, OP_RTL  (             ) ) /* RTL     (G) */
1910 OP(6c, OP_JMP  ( AI          ) ) /* JMP ai      */
1911 OP(6d, OP_ADC  ( A           ) ) /* ADC a       */
1912 OP(6e, OP_RORM ( A           ) ) /* ROR a       */
1913 OP(6f, OP_ADC  ( AL          ) ) /* ADC al  (G) */
1914 OP(70, OP_BCC  ( COND_VS()   ) ) /* BVS         */
1915 OP(71, OP_ADC  ( DIY         ) ) /* ADC diy     */
1916 OP(72, OP_ADC  ( DI          ) ) /* ADC di  (G) */
1917 OP(73, OP_ADC  ( SIY         ) ) /* ADC siy (G) */
1918 OP(74, OP_STZ  ( DX          ) ) /* STZ dx  (C) */
1919 OP(75, OP_ADC  ( DX          ) ) /* ADC dx      */
1920 OP(76, OP_RORM ( DX          ) ) /* ROR dx      */
1921 OP(77, OP_ADC  ( DLIY        ) ) /* ADC dliy(G) */
1922 OP(78, OP_SEI  (             ) ) /* SEI         */
1923 OP(79, OP_ADC  ( AY          ) ) /* ADC ay      */
1924 OP(7a, OP_PLX  ( REGISTER_Y       ) ) /* PLY     (C) */
1925 OP(7b, OP_TDC  (             ) ) /* TDC     (G) */
1926 OP(7c, OP_JMPAXI(            ) ) /* JMP axi (C) */
1927 OP(7d, OP_ADC  ( AX          ) ) /* ADC ax      */
1928 OP(7e, OP_RORM ( AX          ) ) /* ROR ax      */
1929 OP(7f, OP_ADC  ( ALX         ) ) /* ADC alx (G) */
1930 OP(80, OP_BRA  (             ) ) /* BRA     (C) */
1931 OP(81, OP_STA  ( DXI         ) ) /* STA dxi     */
1932 OP(82, OP_BRL  (             ) ) /* BRL     (G) */
1933 OP(83, OP_STA  ( S           ) ) /* STA s   (G) */
1934 OP(84, OP_STX  ( REGISTER_Y, D    ) ) /* STY d       */
1935 OP(85, OP_STA  ( D           ) ) /* STA d       */
1936 OP(86, OP_STX  ( REGISTER_X, D    ) ) /* STX d       */
1937 OP(87, OP_STA  ( DLI         ) ) /* STA dli (G) */
1938 OP(88, OP_DECX ( REGISTER_Y       ) ) /* DEY         */
1939 OP(89, OP_BITI (             ) ) /* BIT imm (C) */
1940 OP(8a, OP_TXA  ( REGISTER_X       ) ) /* TXA         */
1941 OP(8b, OP_PHB  (             ) ) /* PHB     (G) */
1942 OP(8c, OP_STX  ( REGISTER_Y, A    ) ) /* STY a       */
1943 OP(8d, OP_STA  ( A           ) ) /* STA a       */
1944 OP(8e, OP_STX  ( REGISTER_X, A    ) ) /* STX a       */
1945 OP(8f, OP_STA  ( AL          ) ) /* STA al  (G) */
1946 OP(90, OP_BCC  ( COND_CC()   ) ) /* BCC         */
1947 OP(91, OP_STA  ( DIY         ) ) /* STA diy     */
1948 OP(92, OP_STA  ( DI          ) ) /* STA di  (C) */
1949 OP(93, OP_STA  ( SIY         ) ) /* STA siy (G) */
1950 OP(94, OP_STX  ( REGISTER_Y, DX   ) ) /* STY dx      */
1951 OP(95, OP_STA  ( DX          ) ) /* STA dx      */
1952 OP(96, OP_STX  ( REGISTER_X, DY   ) ) /* STX dy      */
1953 OP(97, OP_STA  ( DLIY        ) ) /* STA dliy(G) */
1954 OP(98, OP_TXA  ( REGISTER_Y       ) ) /* TYA         */
1955 OP(99, OP_STA  ( AY          ) ) /* STA ay      */
1956 OP(9a, OP_TXS  (             ) ) /* TXS         */
1957 OP(9b, OP_TXY  (             ) ) /* TXY     (G) */
1958 OP(9c, OP_STZ  ( A           ) ) /* STZ a   (C) */
1959 OP(9d, OP_STA  ( AX          ) ) /* STA ax      */
1960 OP(9e, OP_STZ  ( AX          ) ) /* STZ ax  (C) */
1961 OP(9f, OP_STA  ( ALX         ) ) /* STA alx (G) */
1962 OP(a0, OP_LDX  ( REGISTER_Y, IMM  ) ) /* LDY imm     */
1963 OP(a1, OP_LDA  ( DXI         ) ) /* LDA dxi     */
1964 OP(a2, OP_LDX  ( REGISTER_X, IMM  ) ) /* LDX imm     */
1965 OP(a3, OP_LDA  ( S           ) ) /* LDA s   (G) */
1966 OP(a4, OP_LDX  ( REGISTER_Y, D    ) ) /* LDY d       */
1967 OP(a5, OP_LDA  ( D           ) ) /* LDA d       */
1968 OP(a6, OP_LDX  ( REGISTER_X, D    ) ) /* LDX d       */
1969 OP(a7, OP_LDA  ( DLI         ) ) /* LDA dli (G) */
1970 OP(a8, OP_TAX  ( REGISTER_Y       ) ) /* TAY         */
1971 OP(a9, OP_LDA  ( IMM         ) ) /* LDA imm     */
1972 OP(aa, OP_TAX  ( REGISTER_X       ) ) /* TAX         */
1973 OP(ab, OP_PLB  (             ) ) /* PLB     (G) */
1974 OP(ac, OP_LDX  ( REGISTER_Y, A    ) ) /* LDY a       */
1975 OP(ad, OP_LDA  ( A           ) ) /* LDA a       */
1976 OP(ae, OP_LDX  ( REGISTER_X, A    ) ) /* LDX a       */
1977 OP(af, OP_LDA  ( AL          ) ) /* LDA al  (G) */
1978 OP(b0, OP_BCC  ( COND_CS()   ) ) /* BCS         */
1979 OP(b1, OP_LDA  ( DIY         ) ) /* LDA diy     */
1980 OP(b2, OP_LDA  ( DI          ) ) /* LDA di  (C) */
1981 OP(b3, OP_LDA  ( SIY         ) ) /* LDA siy (G) */
1982 OP(b4, OP_LDX  ( REGISTER_Y, DX   ) ) /* LDY dx      */
1983 OP(b5, OP_LDA  ( DX          ) ) /* LDA dx      */
1984 OP(b6, OP_LDX  ( REGISTER_X, DY   ) ) /* LDX dy      */
1985 OP(b7, OP_LDA  ( DLIY        ) ) /* LDA dliy(G) */
1986 OP(b8, OP_CLV  (             ) ) /* CLV         */
1987 OP(b9, OP_LDA  ( AY          ) ) /* LDA ay      */
1988 OP(ba, OP_TSX  (             ) ) /* TSX         */
1989 OP(bb, OP_TYX  (             ) ) /* TYX     (G) */
1990 OP(bc, OP_LDX  ( REGISTER_Y, AX   ) ) /* LDY ax      */
1991 OP(bd, OP_LDA  ( AX          ) ) /* LDA ax      */
1992 OP(be, OP_LDX  ( REGISTER_X, AY   ) ) /* LDX ay      */
1993 OP(bf, OP_LDA  ( ALX         ) ) /* LDA alx (G) */
1994 OP(c0, OP_CMPX ( REGISTER_Y, IMM  ) ) /* CPY imm     */
1995 OP(c1, OP_CMP  ( DXI         ) ) /* CMP dxi     */
1996 OP(c2, OP_REP  (             ) ) /* REP     (G) */
1997 OP(c3, OP_CMP  ( S           ) ) /* CMP s   (G) */
1998 OP(c4, OP_CMPX ( REGISTER_Y, D    ) ) /* CPY d       */
1999 OP(c5, OP_CMP  ( D           ) ) /* CMP d       */
2000 OP(c6, OP_DECM ( D           ) ) /* DEC d       */
2001 OP(c7, OP_CMP  ( DLI         ) ) /* CMP dli (G) */
2002 OP(c8, OP_INCX ( REGISTER_Y       ) ) /* INY         */
2003 OP(c9, OP_CMP  ( IMM         ) ) /* CMP imm     */
2004 OP(ca, OP_DECX ( REGISTER_X       ) ) /* DEX         */
2005 OP(cb, OP_WAI  (             ) ) /* WAI     (G) */
2006 OP(cc, OP_CMPX ( REGISTER_Y, A    ) ) /* CPY a       */
2007 OP(cd, OP_CMP  ( A           ) ) /* CMP a       */
2008 OP(ce, OP_DECM ( A           ) ) /* DEC a       */
2009 OP(cf, OP_CMP  ( AL          ) ) /* CMP al  (G) */
2010 OP(d0, OP_BCC  ( COND_NE()   ) ) /* BNE         */
2011 OP(d1, OP_CMP  ( DIY         ) ) /* CMP diy     */
2012 OP(d2, OP_CMP  ( DI          ) ) /* CMP di  (C) */
2013 OP(d3, OP_CMP  ( SIY         ) ) /* CMP siy (G) */
2014 OP(d4, OP_PEI  (             ) ) /* PEI     (G) */
2015 OP(d5, OP_CMP  ( DX          ) ) /* CMP dx      */
2016 OP(d6, OP_DECM ( DX          ) ) /* DEC dx      */
2017 OP(d7, OP_CMP  ( DLIY        ) ) /* CMP dliy(G) */
2018 OP(d8, OP_CLD  (             ) ) /* CLD         */
2019 OP(d9, OP_CMP  ( AY          ) ) /* CMP ay      */
2020 OP(da, OP_PHX  ( REGISTER_X       ) ) /* PHX     (C) */
2021 OP(db, OP_STP  (             ) ) /* STP     (G) */
2022 OP(dc, OP_JMLAI(             ) ) /* JML ai  (G) */
2023 OP(dd, OP_CMP  ( AX          ) ) /* CMP ax      */
2024 OP(de, OP_DECM ( AX          ) ) /* DEC ax      */
2025 OP(df, OP_CMP  ( ALX         ) ) /* CMP alx (G) */
2026 OP(e0, OP_CMPX ( REGISTER_X, IMM  ) ) /* CPX imm     */
2027 OP(e1, OP_SBC  ( DXI         ) ) /* SBC dxi     */
2028 OP(e2, OP_SEP  (             ) ) /* SEP imm (G) */
2029 OP(e3, OP_SBC  ( S           ) ) /* SBC s   (G) */
2030 OP(e4, OP_CMPX ( REGISTER_X, D    ) ) /* CPX d       */
2031 OP(e5, OP_SBC  ( D           ) ) /* SBC d       */
2032 OP(e6, OP_INCM ( D           ) ) /* INC d       */
2033 OP(e7, OP_SBC  ( DLI         ) ) /* SBC dli (G) */
2034 OP(e8, OP_INCX ( REGISTER_X       ) ) /* INX         */
2035 OP(e9, OP_SBC  ( IMM         ) ) /* SBC imm     */
2036 OP(ea, OP_NOP  (             ) ) /* NOP         */
2037 OP(eb, OP_XBA  (             ) ) /* XBA     (G) */
2038 OP(ec, OP_CMPX ( REGISTER_X, A    ) ) /* CPX a       */
2039 OP(ed, OP_SBC  ( A           ) ) /* SBC a       */
2040 OP(ee, OP_INCM ( A           ) ) /* INC a       */
2041 OP(ef, OP_SBC  ( AL          ) ) /* SBC al  (G) */
2042 OP(f0, OP_BCC  ( COND_EQ()   ) ) /* BEQ         */
2043 OP(f1, OP_SBC  ( DIY         ) ) /* SBC diy     */
2044 OP(f2, OP_SBC  ( DI          ) ) /* SBC di  (C) */
2045 OP(f3, OP_SBC  ( SIY         ) ) /* SBC siy (G) */
2046 OP(f4, OP_PEA  (             ) ) /* PEA     (G) */
2047 OP(f5, OP_SBC  ( DX          ) ) /* SBC dx      */
2048 OP(f6, OP_INCM ( DX          ) ) /* INC dx      */
2049 OP(f7, OP_SBC  ( DLIY        ) ) /* SBC dliy(G) */
2050 OP(f8, OP_SED  (             ) ) /* SED         */
2051 OP(f9, OP_SBC  ( AY          ) ) /* SBC ay      */
2052 OP(fa, OP_PLX  ( REGISTER_X       ) ) /* PLX     (C) */
2053 OP(fb, OP_XCE  (             ) ) /* XCE     (G) */
2054 OP(fc, OP_JSRAXI(            ) ) /* JSR axi (G) */
2055 OP(fd, OP_SBC  ( AX          ) ) /* SBC ax      */
2056 OP(fe, OP_INCM ( AX          ) ) /* INC ax      */
2057 OP(ff, OP_SBC  ( ALX         ) ) /* SBC alx (G) */
2058 
2059 
2060 
2061 TABLE_OPCODES =
2062 {
2063 	O(00),O(01),O(02),O(03),O(04),O(05),O(06),O(07),
2064 	O(08),O(09),O(0a),O(0b),O(0c),O(0d),O(0e),O(0f),
2065 	O(10),O(11),O(12),O(13),O(14),O(15),O(16),O(17),
2066 	O(18),O(19),O(1a),O(1b),O(1c),O(1d),O(1e),O(1f),
2067 	O(20),O(21),O(22),O(23),O(24),O(25),O(26),O(27),
2068 	O(28),O(29),O(2a),O(2b),O(2c),O(2d),O(2e),O(2f),
2069 	O(30),O(31),O(32),O(33),O(34),O(35),O(36),O(37),
2070 	O(38),O(39),O(3a),O(3b),O(3c),O(3d),O(3e),O(3f),
2071 	O(40),O(41),O(42),O(43),O(44),O(45),O(46),O(47),
2072 	O(48),O(49),O(4a),O(4b),O(4c),O(4d),O(4e),O(4f),
2073 	O(50),O(51),O(52),O(53),O(54),O(55),O(56),O(57),
2074 	O(58),O(59),O(5a),O(5b),O(5c),O(5d),O(5e),O(5f),
2075 	O(60),O(61),O(62),O(63),O(64),O(65),O(66),O(67),
2076 	O(68),O(69),O(6a),O(6b),O(6c),O(6d),O(6e),O(6f),
2077 	O(70),O(71),O(72),O(73),O(74),O(75),O(76),O(77),
2078 	O(78),O(79),O(7a),O(7b),O(7c),O(7d),O(7e),O(7f),
2079 	O(80),O(81),O(82),O(83),O(84),O(85),O(86),O(87),
2080 	O(88),O(89),O(8a),O(8b),O(8c),O(8d),O(8e),O(8f),
2081 	O(90),O(91),O(92),O(93),O(94),O(95),O(96),O(97),
2082 	O(98),O(99),O(9a),O(9b),O(9c),O(9d),O(9e),O(9f),
2083 	O(a0),O(a1),O(a2),O(a3),O(a4),O(a5),O(a6),O(a7),
2084 	O(a8),O(a9),O(aa),O(ab),O(ac),O(ad),O(ae),O(af),
2085 	O(b0),O(b1),O(b2),O(b3),O(b4),O(b5),O(b6),O(b7),
2086 	O(b8),O(b9),O(ba),O(bb),O(bc),O(bd),O(be),O(bf),
2087 	O(c0),O(c1),O(c2),O(c3),O(c4),O(c5),O(c6),O(c7),
2088 	O(c8),O(c9),O(ca),O(cb),O(cc),O(cd),O(ce),O(cf),
2089 	O(d0),O(d1),O(d2),O(d3),O(d4),O(d5),O(d6),O(d7),
2090 	O(d8),O(d9),O(da),O(db),O(dc),O(dd),O(de),O(df),
2091 	O(e0),O(e1),O(e2),O(e3),O(e4),O(e5),O(e6),O(e7),
2092 	O(e8),O(e9),O(ea),O(eb),O(ec),O(ed),O(ee),O(ef),
2093 	O(f0),O(f1),O(f2),O(f3),O(f4),O(f5),O(f6),O(f7),
2094 	O(f8),O(f9),O(fa),O(fb),O(fc),O(fd),O(fe),O(ff)
2095 };
2096 
2097 
2098 
2099 /* Assert or clear a line on the CPU */
2100 TABLE_FUNCTION(void, set_line, (int line, int state))
2101 {
2102 	switch(line)
2103 	{
2104 		case G65816_LINE_IRQ:
2105 			switch(state)
2106 			{
2107 				case CLEAR_LINE:
2108 					LINE_IRQ = 0;
2109 					return;
2110 				case ASSERT_LINE:
2111 				case HOLD_LINE:
2112 					LINE_IRQ = 1;
2113 			}
2114 			if(FLAG_I)
2115 			{
2116 				if(CPU_STOPPED & STOP_LEVEL_WAI)
2117 					CPU_STOPPED &= ~STOP_LEVEL_WAI;
2118 				return;
2119 			}
2120 //			g65816i_interrupt_hardware(VECTOR_IRQ);
2121 			return;
2122 		case G65816_LINE_NMI:
2123 			if(state == CLEAR_LINE)
2124 			{
2125 				LINE_NMI = 0;
2126 				return;
2127 			}
2128 			if(!LINE_NMI)
2129 			{
2130 				LINE_NMI = state != PULSE_LINE;
2131 				CPU_STOPPED &= ~STOP_LEVEL_WAI;
2132 				if(!CPU_STOPPED)
2133 					g65816i_interrupt_nmi();
2134 			}
2135 			return;
2136 		case G65816_LINE_SO:
2137 			FLAG_V = VFLAG_SET;
2138 			break;
2139 		case G65816_LINE_RESET:
2140 		case G65816_LINE_ABORT:
2141 		case G65816_LINE_RDY:
2142 			return;
2143 	}
2144 
2145 	LINE_IRQ=1;
2146 }
2147 
2148 
2149 
2150 /* Get a register from the CPU core */
2151 TABLE_FUNCTION(uint, get_reg, (int regnum))
2152 {
2153 	switch(regnum)
2154 	{
2155 		case G65816_A: return REGISTER_B | REGISTER_A;
2156 		case G65816_X: return REGISTER_X;
2157 		case G65816_Y: return REGISTER_Y;
2158 		case REG_SP: return REGISTER_S;
2159 		case G65816_S: return REGISTER_S;
2160 		case REG_PC: return REGISTER_PC;
2161 		case G65816_PC: return REGISTER_PC;
2162 		case G65816_PB: return REGISTER_PB >> 16;
2163 		case G65816_DB: return REGISTER_DB >> 16;
2164 		case G65816_D: return REGISTER_D;
2165 		case G65816_P: return g65816i_get_reg_p();
2166 		case G65816_NMI_STATE: return LINE_NMI;
2167 		case G65816_IRQ_STATE: return LINE_IRQ;
2168 		case REG_PREVIOUSPC: return REGISTER_PPC;
2169 		default:
2170 			if(regnum <= REG_SP_CONTENTS)
2171 				return read_16_NORM(REGISTER_S + 2 * (REG_SP_CONTENTS - regnum));
2172 	}
2173 	return 0;
2174 }
2175 
2176 
2177 
2178 TABLE_FUNCTION(void, set_reg, (int regnum, uint val))
2179 {
2180 	switch(regnum)
2181 	{
2182 		case REG_PC: case G65816_PC: REGISTER_PC = MAKE_UINT_16(val); break;
2183 #if FLAG_SET_E
2184 		case REG_SP: case G65816_S: REGISTER_S = MAKE_UINT_8(val) | 0x100; break;
2185 #else
2186 		case REG_SP: case G65816_S: REGISTER_S = MAKE_UINT_16(val); break;
2187 #endif
2188 		case G65816_P: g65816i_set_reg_p(val); break;
2189 #if FLAG_SET_M
2190 		case G65816_A: REGISTER_A = MAKE_UINT_8(val); REGISTER_B = val&0xff00; break;
2191 #else
2192 		case G65816_A: REGISTER_A = MAKE_UINT_16(val); break;
2193 #endif
2194 #if FLAG_SET_X
2195 		case G65816_X: REGISTER_X = MAKE_UINT_8(val); break;
2196 		case G65816_Y: REGISTER_Y = MAKE_UINT_8(val); break;
2197 #else
2198 		case G65816_X: REGISTER_X = MAKE_UINT_16(val); break;
2199 		case G65816_Y: REGISTER_Y = MAKE_UINT_16(val); break;
2200 #endif
2201 		case G65816_NMI_STATE: FTABLE_SET_LINE(G65816_LINE_NMI, val == 0 ? CLEAR_LINE : ASSERT_LINE); break;
2202 		case G65816_IRQ_STATE: FTABLE_SET_LINE(G65816_LINE_IRQ, val == 0 ? CLEAR_LINE : ASSERT_LINE); break;
2203 		default:
2204 			if(regnum <= REG_SP_CONTENTS)
2205 				write_16_NORM(REGISTER_S + 2 * (REG_SP_CONTENTS - regnum), val);
2206 	 }
2207 }
2208 
2209 TABLE_FUNCTION(int, execute, (int clocks))
2210 {
2211 	if(!CPU_STOPPED)
2212 	{
2213 		CLOCKS = clocks;
2214 		do
2215 		{
2216 			REGISTER_PPC = REGISTER_PC;
2217 			G65816_CALL_DEBUGGER;
2218 			REGISTER_PC++;
2219 			REGISTER_IR = read_8_IMM(REGISTER_PB | REGISTER_PPC);
2220 			FTABLE_OPCODES[REGISTER_IR]();
2221 			/* Note that I'm doing a per-instruction interrupt
2222 			 * check until this core is working well enough
2223 			 * to start trying fancy stuff.
2224 			 */
2225 			g65816i_check_maskable_interrupt();
2226 		} while(CLOCKS > 0);
2227 		return clocks - CLOCKS;
2228 	}
2229 	return clocks;
2230 }
2231 
2232 
2233 /* ======================================================================== */
2234 /* ================================== EOF ================================= */
2235 /* ======================================================================== */
2236