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