random bug fixes
[drnoksnes] / spc700.cpp
1 /*
2  * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
3  *
4  * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and
5  *                           Jerremy Koot (jkoot@snes9x.com)
6  *
7  * Super FX C emulator code 
8  * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and
9  *                           Gary Henderson.
10  * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_.
11  *
12  * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson.
13  * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_.
14  * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com).
15  *
16  * DOS port code contains the works of other authors. See headers in
17  * individual files.
18  *
19  * Snes9x homepage: http://www.snes9x.com
20  *
21  * Permission to use, copy, modify and distribute Snes9x in both binary and
22  * source form, for non-commercial purposes, is hereby granted without fee,
23  * providing that this license information and copyright notice appear with
24  * all copies and any derived work.
25  *
26  * This software is provided 'as-is', without any express or implied
27  * warranty. In no event shall the authors be held liable for any damages
28  * arising from the use of this software.
29  *
30  * Snes9x is freeware for PERSONAL USE only. Commercial users should
31  * seek permission of the copyright holders first. Commercial use includes
32  * charging money for Snes9x or software derived from Snes9x.
33  *
34  * The copyright holders request that bug fixes and improvements to the code
35  * should be forwarded to them so everyone can benefit from the modifications
36  * in future versions.
37  *
38  * Super NES and Super Nintendo Entertainment System are trademarks of
39  * Nintendo Co., Limited and its subsidiary companies.
40  */
41 #include "snes9x.h"
42 #include "memmap.h"
43 #include "display.h"
44 #include "cpuexec.h"
45 #include "apu.h"
46 #include "spc700.h"
47
48 // SPC700/Sound DSP chips have a 24.57MHz crystal on their PCB.
49
50 #if defined(ASM_SPC700)
51
52 // we only need the memhandlers
53 #undef INLINE
54 #define INLINE extern "C"
55 #include "apumem.h"
56
57 #else
58
59 #if defined(NO_INLINE_SET_GET)
60 uint8 S9xAPUGetByteZ (uint8 address);
61 uint8 S9xAPUGetByte (uint32 address);
62 void S9xAPUSetByteZ (uint8, uint8 address);
63 void S9xAPUSetByte (uint8, uint32 address);
64 #else
65 #undef INLINE
66 #define INLINE inline
67 #include "apumem.h"
68 #endif
69
70 START_EXTERN_C
71 extern uint8 Work8;
72 extern uint16 Work16;
73 extern uint32 Work32;
74 extern signed char Int8;
75 extern short Int16;
76 extern long Int32;
77 extern short Int16;
78 extern uint8 W1;
79 extern uint8 W2;
80
81 END_EXTERN_C
82
83 #define OP1 (*(IAPU.PC + 1))
84 #define OP2 (*(IAPU.PC + 2))
85
86 #ifdef SPC700_SHUTDOWN
87 #define APUShutdown() \
88     if (Settings.Shutdown && (IAPU.PC == IAPU.WaitAddress1 || IAPU.PC == IAPU.WaitAddress2)) \
89     { \
90                 if (IAPU.WaitCounter == 0) \
91                 { \
92                         if (!ICPU.CPUExecuting) \
93                                 CPU.APU_Cycles = CPU.Cycles = CPU.NextEvent; \
94                         else \
95                                 CPU.APU_APUExecuting = FALSE; \
96                 } \
97                 else \
98                 if (IAPU.WaitCounter >= 2) \
99                         IAPU.WaitCounter = 1; \
100         else \
101             IAPU.WaitCounter--; \
102     }
103 #else
104 #define APUShutdown()
105 #endif
106
107 #define APUSetZN8(b)\
108     IAPU._Zero = (b);
109
110 #define APUSetZN16(w)\
111     IAPU._Zero = ((w) != 0) | ((w) >> 8);
112
113 void STOP (char *s)
114 {
115     char buffer[100];
116
117 #ifdef DEBUGGER
118     S9xAPUOPrint (buffer, IAPU.PC - IAPU.RAM);
119 #endif
120
121     sprintf (String, "Sound CPU in unknown state executing %s at 0x%tx\n%s\n", s, IAPU.PC - IAPU.RAM, buffer);
122     S9xMessage (S9X_ERROR, S9X_APU_STOPPED, String);
123     APU.TimerEnabled[0] = APU.TimerEnabled[1] = APU.TimerEnabled[2] = FALSE;
124     CPU.APU_APUExecuting = FALSE;
125
126 #ifdef DEBUGGER
127     CPU.Flags |= DEBUG_MODE_FLAG;
128 #else
129     abort();
130 #endif
131 }
132
133 #define TCALL(n)\
134 {\
135     PushW ((IAPU.PC - IAPU.RAM + 1)); \
136     IAPU.PC = IAPU.RAM + (APU.ExtraRAM [((15 - n) << 1)] + \
137              (APU.ExtraRAM [((15 - n) << 1) + 1] << 8)); \
138 }
139
140 // XXX: HalfCarry - BJ fixed?
141 #define SBC(a,b)\
142 Int16 = (short) (a) - (short) (b) + (short) (APUCheckCarry ()) - 1;\
143 IAPU._Carry = Int16 >= 0;\
144 if ((((a) ^ (b)) & 0x80) && (((a) ^ (uint8) Int16) & 0x80))\
145     APUSetOverflow ();\
146 else \
147     APUClearOverflow (); \
148 APUSetHalfCarry ();\
149 if(((a) ^ (b) ^ (uint8) Int16) & 0x10)\
150     APUClearHalfCarry ();\
151 (a) = (uint8) Int16;\
152 APUSetZN8 ((uint8) Int16);
153
154 // XXX: HalfCarry - BJ fixed?
155 #define ADC(a,b)\
156 Work16 = (a) + (b) + APUCheckCarry();\
157 IAPU._Carry = Work16 >= 0x100; \
158 if (~((a) ^ (b)) & ((b) ^ (uint8) Work16) & 0x80)\
159     APUSetOverflow ();\
160 else \
161     APUClearOverflow (); \
162 APUClearHalfCarry ();\
163 /*if(((a) ^ (b) ^ (uint8) Int16) & 0x10)  notaz: Int16!? */\
164 if(((a) ^ (b) ^ (uint8) Work16) & 0x10)\
165     APUSetHalfCarry ();\
166 (a) = (uint8) Work16;\
167 APUSetZN8 ((uint8) Work16);
168
169 #define CMP(a,b)\
170 Int16 = (short) (a) - (short) (b);\
171 IAPU._Carry = Int16 >= 0;\
172 APUSetZN8 ((uint8) Int16);
173
174 #define ASL(b)\
175     IAPU._Carry = ((b) & 0x80) != 0; \
176     (b) <<= 1;\
177     APUSetZN8 (b);
178 #define LSR(b)\
179     IAPU._Carry = (b) & 1;\
180     (b) >>= 1;\
181     APUSetZN8 (b);
182 #define ROL(b)\
183     Work16 = ((b) << 1) | APUCheckCarry (); \
184     IAPU._Carry = Work16 >= 0x100; \
185     (b) = (uint8) Work16; \
186     APUSetZN8 (b);
187 #define ROR(b)\
188     Work16 = (b) | ((uint16) APUCheckCarry () << 8); \
189     IAPU._Carry = (uint8) Work16 & 1; \
190     Work16 >>= 1; \
191     (b) = (uint8) Work16; \
192     APUSetZN8 (b);
193
194 #define Push(b)\
195     *(IAPU.RAM + 0x100 + IAPU.S) = b;\
196     IAPU.S--;
197
198 #define Pop(b)\
199     IAPU.S++;\
200     (b) = *(IAPU.RAM + 0x100 + IAPU.S);
201
202 #ifdef FAST_LSB_WORD_ACCESS
203 #define PushW(w)\
204     *(uint16 *) (IAPU.RAM + 0xff + IAPU.S) = w;\
205     IAPU.S -= 2;
206 #define PopW(w)\
207     IAPU.S += 2;\
208     w = *(uint16 *) (IAPU.RAM + 0xff + IAPU.S);
209 #else
210 #define PushW(w)\
211     *(IAPU.RAM + 0xff + IAPU.S) = w;\
212     *(IAPU.RAM + 0x100 + IAPU.S) = (w >> 8);\
213     IAPU.S -= 2;
214 #define PopW(w)\
215     IAPU.S += 2; \
216     (w) = *(IAPU.RAM + 0xff + IAPU.S) + (*(IAPU.RAM + 0x100 + IAPU.S) << 8);
217 #endif
218
219 #define Relative()\
220     Int8 = OP1;\
221     Int16 = (int) (IAPU.PC + 2 - IAPU.RAM) + Int8;
222
223 #define Relative2()\
224     Int8 = OP2;\
225     Int16 = (int) (IAPU.PC + 3 - IAPU.RAM) + Int8;
226
227 #ifdef FAST_LSB_WORD_ACCESS
228 #define IndexedXIndirect()\
229     IAPU.Address = *(uint16 *) (IAPU.DirectPage + ((OP1 + IAPU.X) & 0xff));
230
231 #define Absolute()\
232     IAPU.Address = *(uint16 *) (IAPU.PC + 1);
233
234 #define AbsoluteX()\
235     IAPU.Address = *(uint16 *) (IAPU.PC + 1) + IAPU.X;
236
237 #define AbsoluteY()\
238     IAPU.Address = *(uint16 *) (IAPU.PC + 1) + IAPU.YA.B.Y;
239
240 #define MemBit()\
241     IAPU.Address = *(uint16 *) (IAPU.PC + 1);\
242     IAPU.Bit = (uint8)(IAPU.Address >> 13);\
243     IAPU.Address &= 0x1fff;
244
245 #define IndirectIndexedY()\
246     IAPU.Address = *(uint16 *) (IAPU.DirectPage + OP1) + IAPU.YA.B.Y;
247 #else
248 #define IndexedXIndirect()\
249     IAPU.Address = *(IAPU.DirectPage + ((OP1 + IAPU.X) & 0xff)) + \
250                   (*(IAPU.DirectPage + ((OP1 + IAPU.X + 1) & 0xff)) << 8);
251 #define Absolute()\
252     IAPU.Address = OP1 + (OP2 << 8);
253
254 #define AbsoluteX()\
255     IAPU.Address = OP1 + (OP2 << 8) + IAPU.X;
256
257 #define AbsoluteY()\
258     IAPU.Address = OP1 + (OP2 << 8) + IAPU.YA.B.Y;
259
260 #define MemBit()\
261     IAPU.Address = OP1 + (OP2 << 8);\
262     IAPU.Bit = (int8) (IAPU.Address >> 13);\
263     IAPU.Address &= 0x1fff;
264
265 #define IndirectIndexedY()\
266     IAPU.Address = *(IAPU.DirectPage + OP1) + \
267                   (*(IAPU.DirectPage + OP1 + 1) << 8) + \
268                   IAPU.YA.B.Y;
269 #endif
270
271 void Apu00 ()
272 {
273 // NOP
274     IAPU.PC++;
275 }
276
277 void Apu01 () { TCALL (0) }
278
279 void Apu11 () { TCALL (1) }
280
281 void Apu21 () { TCALL (2) }
282
283 void Apu31 () { TCALL (3) }
284
285 void Apu41 () { TCALL (4) }
286
287 void Apu51 () { TCALL (5) }
288
289 void Apu61 () { TCALL (6) }
290
291 void Apu71 () { TCALL (7) }
292
293 void Apu81 () { TCALL (8) }
294
295 void Apu91 () { TCALL (9) }
296
297 void ApuA1 () { TCALL (10) }
298
299 void ApuB1 () { TCALL (11) }
300
301 void ApuC1 () { TCALL (12) }
302
303 void ApuD1 () { TCALL (13) }
304
305 void ApuE1 () { TCALL (14) }
306
307 void ApuF1 () { TCALL (15) }
308
309 void Apu3F () // CALL absolute
310 {
311     Absolute ();
312     // 0xB6f for Star Fox 2
313     PushW ((IAPU.PC + 3 - IAPU.RAM));
314     IAPU.PC = IAPU.RAM + IAPU.Address;
315 }
316
317 void Apu4F () // PCALL $XX
318 {
319     Work8 = OP1;
320     PushW ((IAPU.PC + 2 - IAPU.RAM));
321     IAPU.PC = IAPU.RAM + 0xff00 + Work8;
322 }
323
324 #define SET(b) \
325 S9xAPUSetByteZ ((uint8) (S9xAPUGetByteZ (OP1 ) | (1 << (b))), OP1); \
326 IAPU.PC += 2
327
328 void Apu02 ()
329 {
330     SET (0);
331 }
332
333 void Apu22 ()
334 {
335     SET (1);
336 }
337
338 void Apu42 ()
339 {
340     SET (2);
341 }
342
343 void Apu62 ()
344 {
345     SET (3);
346 }
347
348 void Apu82 ()
349 {
350     SET (4);
351 }
352
353 void ApuA2 ()
354 {
355     SET (5);
356 }
357
358 void ApuC2 ()
359 {
360     SET (6);
361 }
362
363 void ApuE2 ()
364 {
365     SET (7);
366 }
367
368 #define CLR(b) \
369 S9xAPUSetByteZ ((uint8) (S9xAPUGetByteZ (OP1) & ~(1 << (b))), OP1); \
370 IAPU.PC += 2;
371
372 void Apu12 ()
373 {
374     CLR (0);
375 }
376
377 void Apu32 ()
378 {
379     CLR (1);
380 }
381
382 void Apu52 ()
383 {
384     CLR (2);
385 }
386
387 void Apu72 ()
388 {
389     CLR (3);
390 }
391
392 void Apu92 ()
393 {
394     CLR (4);
395 }
396
397 void ApuB2 ()
398 {
399     CLR (5);
400 }
401
402 void ApuD2 ()
403 {
404     CLR (6);
405 }
406
407 void ApuF2 ()
408 {
409     CLR (7);
410 }
411
412 #define BBS(b) \
413 Work8 = OP1; \
414 Relative2 (); \
415 if (S9xAPUGetByteZ (Work8) & (1 << (b))) \
416 { \
417     IAPU.PC = IAPU.RAM + (uint16) Int16; \
418     CPU.APU_Cycles += IAPU.TwoCycles; \
419 } \
420 else \
421     IAPU.PC += 3
422
423 void Apu03 ()
424 {
425     BBS (0);
426 }
427
428 void Apu23 ()
429 {
430     BBS (1);
431 }
432
433 void Apu43 ()
434 {
435     BBS (2);
436 }
437
438 void Apu63 ()
439 {
440     BBS (3);
441 }
442
443 void Apu83 ()
444 {
445     BBS (4);
446 }
447
448 void ApuA3 ()
449 {
450     BBS (5);
451 }
452
453 void ApuC3 ()
454 {
455     BBS (6);
456 }
457
458 void ApuE3 ()
459 {
460     BBS (7);
461 }
462
463 #define BBC(b) \
464 Work8 = OP1; \
465 Relative2 (); \
466 if (!(S9xAPUGetByteZ (Work8) & (1 << (b)))) \
467 { \
468     IAPU.PC = IAPU.RAM + (uint16) Int16; \
469     CPU.APU_Cycles += IAPU.TwoCycles; \
470 } \
471 else \
472     IAPU.PC += 3
473
474 void Apu13 ()
475 {
476     BBC (0);
477 }
478
479 void Apu33 ()
480 {
481     BBC (1);
482 }
483
484 void Apu53 ()
485 {
486     BBC (2);
487 }
488
489 void Apu73 ()
490 {
491     BBC (3);
492 }
493
494 void Apu93 ()
495 {
496     BBC (4);
497 }
498
499 void ApuB3 ()
500 {
501     BBC (5);
502 }
503
504 void ApuD3 ()
505 {
506     BBC (6);
507 }
508
509 void ApuF3 ()
510 {
511     BBC (7);
512 }
513
514 void Apu04 ()
515 {
516 // OR A,dp
517     IAPU.YA.B.A |= S9xAPUGetByteZ (OP1);
518     APUSetZN8 (IAPU.YA.B.A);
519     IAPU.PC += 2;
520 }
521
522 void Apu05 ()
523 {
524 // OR A,abs
525     Absolute ();
526     IAPU.YA.B.A |= S9xAPUGetByte (IAPU.Address);
527     APUSetZN8 (IAPU.YA.B.A);
528     IAPU.PC += 3;
529 }
530
531 void Apu06 ()
532 {
533 // OR A,(X)
534     IAPU.YA.B.A |= S9xAPUGetByteZ (IAPU.X);
535     APUSetZN8 (IAPU.YA.B.A);
536     IAPU.PC++;
537 }
538
539 void Apu07 ()
540 {
541 // OR A,(dp+X)
542     IndexedXIndirect ();
543     IAPU.YA.B.A |= S9xAPUGetByte (IAPU.Address);
544     APUSetZN8 (IAPU.YA.B.A);
545     IAPU.PC += 2;
546 }
547
548 void Apu08 ()
549 {
550 // OR A,#00
551     IAPU.YA.B.A |= OP1;
552     APUSetZN8 (IAPU.YA.B.A);
553     IAPU.PC += 2;
554 }
555
556 void Apu09 ()
557 {
558 // OR dp(dest),dp(src)
559     Work8 = S9xAPUGetByteZ (OP1);
560     Work8 |= S9xAPUGetByteZ (OP2);
561     S9xAPUSetByteZ (Work8, OP2);
562     APUSetZN8 (Work8);
563     IAPU.PC += 3;
564 }
565
566 void Apu14 ()
567 {
568 // OR A,dp+X
569     IAPU.YA.B.A |= S9xAPUGetByteZ (OP1 + IAPU.X);
570     APUSetZN8 (IAPU.YA.B.A);
571     IAPU.PC += 2;
572 }
573
574 void Apu15 ()
575 {
576 // OR A,abs+X
577     AbsoluteX ();
578     IAPU.YA.B.A |= S9xAPUGetByte (IAPU.Address);
579     APUSetZN8 (IAPU.YA.B.A);
580     IAPU.PC += 3;
581 }
582
583 void Apu16 ()
584 {
585 // OR A,abs+Y
586     AbsoluteY ();
587     IAPU.YA.B.A |= S9xAPUGetByte (IAPU.Address);
588     APUSetZN8 (IAPU.YA.B.A);
589     IAPU.PC += 3;
590 }
591
592 void Apu17 ()
593 {
594 // OR A,(dp)+Y
595     IndirectIndexedY ();
596     IAPU.YA.B.A |= S9xAPUGetByte (IAPU.Address);
597     APUSetZN8 (IAPU.YA.B.A);
598     IAPU.PC += 2;
599 }
600
601 void Apu18 ()
602 {
603 // OR dp,#00
604     Work8 = OP1;
605     Work8 |= S9xAPUGetByteZ (OP2);
606     S9xAPUSetByteZ (Work8, OP2);
607     APUSetZN8 (Work8);
608     IAPU.PC += 3;
609 }
610
611 void Apu19 ()
612 {
613 // OR (X),(Y)
614     Work8 = S9xAPUGetByteZ (IAPU.X) | S9xAPUGetByteZ (IAPU.YA.B.Y);
615     APUSetZN8 (Work8);
616     S9xAPUSetByteZ (Work8, IAPU.X);
617     IAPU.PC++;
618 }
619
620 void Apu0A ()
621 {
622 // OR1 C,membit
623     MemBit ();
624     if (!APUCheckCarry ())
625     {
626         if (S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit))
627             APUSetCarry ();
628     }
629     IAPU.PC += 3;
630 }
631
632 void Apu2A ()
633 {
634 // OR1 C,not membit
635     MemBit ();
636     if (!APUCheckCarry ())
637     {
638         if (!(S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit)))
639             APUSetCarry ();
640     }
641     IAPU.PC += 3;
642 }
643
644 void Apu4A ()
645 {
646 // AND1 C,membit
647     MemBit ();
648     if (APUCheckCarry ())
649     {
650         if (!(S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit)))
651             APUClearCarry ();
652     }
653     IAPU.PC += 3;
654 }
655
656 void Apu6A ()
657 {
658 // AND1 C, not membit
659     MemBit ();
660     if (APUCheckCarry ())
661     {
662         if ((S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit)))
663             APUClearCarry ();
664     }
665     IAPU.PC += 3;
666 }
667
668 void Apu8A ()
669 {
670 // EOR1 C, membit
671     MemBit ();
672     if (APUCheckCarry ())
673     {
674         if (S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit))
675             APUClearCarry ();
676     }
677     else
678     {
679         if (S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit))
680             APUSetCarry ();
681     }
682     IAPU.PC += 3;
683 }
684
685 void ApuAA ()
686 {
687 // MOV1 C,membit
688     MemBit ();
689     if (S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit))
690         APUSetCarry ();
691     else
692         APUClearCarry ();
693     IAPU.PC += 3;
694 }
695
696 void ApuCA ()
697 {
698 // MOV1 membit,C
699     MemBit ();
700     if (APUCheckCarry ())
701     {
702         S9xAPUSetByte (S9xAPUGetByte (IAPU.Address) | (1 << IAPU.Bit), IAPU.Address);
703     }
704     else
705     {
706         S9xAPUSetByte (S9xAPUGetByte (IAPU.Address) & ~(1 << IAPU.Bit), IAPU.Address);
707     }
708     IAPU.PC += 3;
709 }
710
711 void ApuEA ()
712 {
713 // NOT1 membit
714     MemBit ();
715     S9xAPUSetByte (S9xAPUGetByte (IAPU.Address) ^ (1 << IAPU.Bit), IAPU.Address);
716     IAPU.PC += 3;
717 }
718
719 void Apu0B ()
720 {
721 // ASL dp
722     Work8 = S9xAPUGetByteZ (OP1);
723     ASL (Work8);
724     S9xAPUSetByteZ (Work8, OP1);
725     IAPU.PC += 2;
726 }
727
728 void Apu0C ()
729 {
730 // ASL abs
731     Absolute ();
732     Work8 = S9xAPUGetByte (IAPU.Address);
733     ASL (Work8);
734     S9xAPUSetByte (Work8, IAPU.Address);
735     IAPU.PC += 3;
736 }
737
738 void Apu1B ()
739 {
740 // ASL dp+X
741     Work8 = S9xAPUGetByteZ (OP1 + IAPU.X);
742     ASL (Work8);
743     S9xAPUSetByteZ (Work8, OP1 + IAPU.X);
744     IAPU.PC += 2;
745 }
746
747 void Apu1C ()
748 {
749 // ASL A
750     ASL (IAPU.YA.B.A);
751     IAPU.PC++;
752 }
753
754 void Apu0D ()
755 {
756 // PUSH PSW
757     S9xAPUPackStatus ();
758     Push (IAPU.P);
759     IAPU.PC++;
760 }
761
762 void Apu2D ()
763 {
764 // PUSH A
765     Push (IAPU.YA.B.A);
766     IAPU.PC++;
767 }
768
769 void Apu4D ()
770 {
771 // PUSH X
772     Push (IAPU.X);
773     IAPU.PC++;
774 }
775
776 void Apu6D ()
777 {
778 // PUSH Y
779     Push (IAPU.YA.B.Y);
780     IAPU.PC++;
781 }
782
783 void Apu8E ()
784 {
785 // POP PSW
786     Pop (IAPU.P);
787     S9xAPUUnpackStatus ();
788     if (APUCheckDirectPage ())
789         IAPU.DirectPage = IAPU.RAM + 0x100;
790     else
791         IAPU.DirectPage = IAPU.RAM;
792     IAPU.PC++;
793 }
794
795 void ApuAE ()
796 {
797 // POP A
798     Pop (IAPU.YA.B.A);
799     IAPU.PC++;
800 }
801
802 void ApuCE ()
803 {
804 // POP X
805     Pop (IAPU.X);
806     IAPU.PC++;
807 }
808
809 void ApuEE ()
810 {
811 // POP Y
812     Pop (IAPU.YA.B.Y);
813     IAPU.PC++;
814 }
815
816 void Apu0E ()
817 {
818 // TSET1 abs
819     Absolute ();
820     Work8 = S9xAPUGetByte (IAPU.Address);
821     S9xAPUSetByte (Work8 | IAPU.YA.B.A, IAPU.Address);
822     Work8 &= IAPU.YA.B.A;
823     APUSetZN8 (Work8);
824     IAPU.PC += 3;
825 }
826
827 void Apu4E ()
828 {
829 // TCLR1 abs
830     Absolute ();
831     Work8 = S9xAPUGetByte (IAPU.Address);
832     S9xAPUSetByte (Work8 & ~IAPU.YA.B.A, IAPU.Address);
833     Work8 &= IAPU.YA.B.A;
834     APUSetZN8 (Work8);
835     IAPU.PC += 3;
836 }
837
838 void Apu0F ()
839 {
840 // BRK
841
842 #if 0
843     STOP ("BRK");
844 #else
845     PushW ((IAPU.PC + 1 - IAPU.RAM));
846     S9xAPUPackStatus ();
847     Push (IAPU.P);
848     APUSetBreak ();
849     APUClearInterrupt ();
850 // XXX:Where is the BRK vector ???
851     IAPU.PC = IAPU.RAM + APU.ExtraRAM[0x20] + (APU.ExtraRAM[0x21] << 8);
852 #endif
853 }
854
855 void ApuEF ()
856 {
857 // SLEEP
858     // XXX: sleep
859     // STOP ("SLEEP");
860     CPU.APU_APUExecuting = FALSE;
861     IAPU.PC++;
862 }
863
864 void ApuFF ()
865 {
866 // STOP
867     // STOP ("STOP");
868     CPU.APU_APUExecuting = FALSE;
869     IAPU.PC++;
870 }
871
872 void Apu10 ()
873 {
874 // BPL
875     Relative ();
876     if (!APUCheckNegative ())
877     {
878         IAPU.PC = IAPU.RAM + (uint16) Int16;
879         CPU.APU_Cycles += IAPU.TwoCycles;
880         APUShutdown ();
881     }
882     else
883         IAPU.PC += 2;
884 }
885
886 void Apu30 ()
887 {
888 // BMI
889     Relative ();
890     if (APUCheckNegative ())
891     {
892         IAPU.PC = IAPU.RAM + (uint16) Int16;
893         CPU.APU_Cycles += IAPU.TwoCycles;
894         APUShutdown ();
895     }
896     else
897         IAPU.PC += 2;
898 }
899
900 void Apu90 ()
901 {
902 // BCC
903     Relative ();
904     if (!APUCheckCarry ())
905     {
906         IAPU.PC = IAPU.RAM + (uint16) Int16;
907         CPU.APU_Cycles += IAPU.TwoCycles;
908         APUShutdown ();
909     }
910     else
911         IAPU.PC += 2;
912 }
913
914 void ApuB0 ()
915 {
916 // BCS
917     Relative ();
918     if (APUCheckCarry ())
919     {
920         IAPU.PC = IAPU.RAM + (uint16) Int16;
921         CPU.APU_Cycles += IAPU.TwoCycles;
922         APUShutdown ();
923     }
924     else
925         IAPU.PC += 2;
926 }
927
928 void ApuD0 ()
929 {
930 // BNE
931     Relative ();
932     if (!APUCheckZero ())
933     {
934         IAPU.PC = IAPU.RAM + (uint16) Int16;
935         CPU.APU_Cycles += IAPU.TwoCycles;
936         APUShutdown ();
937     }
938     else
939         IAPU.PC += 2;
940 }
941
942 void ApuF0 ()
943 {
944 // BEQ
945     Relative ();
946     if (APUCheckZero ())
947     {
948         IAPU.PC = IAPU.RAM + (uint16) Int16;
949         CPU.APU_Cycles += IAPU.TwoCycles;
950         APUShutdown ();
951     }
952     else
953         IAPU.PC += 2;
954 }
955
956 void Apu50 ()
957 {
958 // BVC
959     Relative ();
960     if (!APUCheckOverflow ())
961     {
962         IAPU.PC = IAPU.RAM + (uint16) Int16;
963         CPU.APU_Cycles += IAPU.TwoCycles;
964     }
965     else
966         IAPU.PC += 2;
967 }
968
969 void Apu70 ()
970 {
971 // BVS
972     Relative ();
973     if (APUCheckOverflow ())
974     {
975         IAPU.PC = IAPU.RAM + (uint16) Int16;
976         CPU.APU_Cycles += IAPU.TwoCycles;
977     }
978     else
979         IAPU.PC += 2;
980 }
981
982 void Apu2F ()
983 {
984 // BRA
985     Relative ();
986     IAPU.PC = IAPU.RAM + (uint16) Int16;
987 }
988
989 void Apu80 ()
990 {
991 // SETC
992     APUSetCarry ();
993     IAPU.PC++;
994 }
995
996 void ApuED ()
997 {
998 // NOTC
999     IAPU._Carry ^= 1;
1000     IAPU.PC++;
1001 }
1002
1003 void Apu40 ()
1004 {
1005 // SETP
1006     APUSetDirectPage ();
1007     IAPU.DirectPage = IAPU.RAM + 0x100;
1008     IAPU.PC++;
1009 }
1010
1011 void Apu1A ()
1012 {
1013 // DECW dp
1014     Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8);
1015     Work16--;
1016     S9xAPUSetByteZ ((uint8) Work16, OP1);
1017     S9xAPUSetByteZ (Work16 >> 8, OP1 + 1);
1018     APUSetZN16 (Work16);
1019     IAPU.PC += 2;
1020 }
1021
1022 void Apu5A ()
1023 {
1024 // CMPW YA,dp
1025     Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8);
1026     Int32 = (long) IAPU.YA.W - (long) Work16;
1027     IAPU._Carry = Int32 >= 0;
1028     APUSetZN16 ((uint16) Int32);
1029     IAPU.PC += 2;
1030 }
1031
1032 void Apu3A ()
1033 {
1034 // INCW dp
1035     Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8);
1036     Work16++;
1037     S9xAPUSetByteZ ((uint8) Work16, OP1);
1038     S9xAPUSetByteZ (Work16 >> 8, OP1 + 1);
1039     APUSetZN16 (Work16);
1040     IAPU.PC += 2;
1041 }
1042
1043 // XXX: HalfCarry - BJ Fixed? Or is it between bits 7 and 8 for ADDW/SUBW?
1044 void Apu7A ()
1045 {
1046 // ADDW YA,dp
1047     Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8);
1048     Work32 = (uint32) IAPU.YA.W + Work16;
1049     IAPU._Carry = Work32 >= 0x10000;
1050     if (~(IAPU.YA.W ^ Work16) & (Work16 ^ (uint16) Work32) & 0x8000)
1051         APUSetOverflow ();
1052     else
1053         APUClearOverflow ();
1054     APUClearHalfCarry ();
1055     if((IAPU.YA.W ^ Work16 ^ (uint16) Work32) & 0x10)
1056         APUSetHalfCarry ();
1057     IAPU.YA.W = (uint16) Work32;
1058     APUSetZN16 (IAPU.YA.W);
1059     IAPU.PC += 2;
1060 }
1061
1062 // XXX: BJ: i think the old HalfCarry behavior was wrong...
1063 // XXX: Or is it between bits 7 and 8 for ADDW/SUBW?
1064 void Apu9A ()
1065 {
1066 // SUBW YA,dp
1067     Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8);
1068     Int32 = (long) IAPU.YA.W - (long) Work16;
1069     APUClearHalfCarry ();
1070     IAPU._Carry = Int32 >= 0;
1071     if (((IAPU.YA.W ^ Work16) & 0x8000) &&
1072             ((IAPU.YA.W ^ (uint16) Int32) & 0x8000))
1073         APUSetOverflow ();
1074     else
1075         APUClearOverflow ();
1076 //    if (((IAPU.YA.W ^ Work16) & 0x0080) &&
1077 //          ((IAPU.YA.W ^ (uint16) Int32) & 0x0080))
1078 //      APUSetHalfCarry ();                              // notaz: strange here
1079     APUSetHalfCarry ();
1080 //    if((IAPU.YA.W ^ Work16 ^ (uint16) Work32) & 0x10) // notaz: Work32?!
1081     if((IAPU.YA.W ^ Work16 ^ (uint16) Int32) & 0x10)
1082         APUClearHalfCarry ();
1083     IAPU.YA.W = (uint16) Int32;
1084     APUSetZN16 (IAPU.YA.W);
1085     IAPU.PC += 2;
1086 }
1087
1088 void ApuBA ()
1089 {
1090 // MOVW YA,dp
1091     IAPU.YA.B.A = S9xAPUGetByteZ (OP1);
1092     IAPU.YA.B.Y = S9xAPUGetByteZ (OP1 + 1);
1093     APUSetZN16 (IAPU.YA.W);
1094     IAPU.PC += 2;
1095 }
1096
1097 void ApuDA ()
1098 {
1099 // MOVW dp,YA
1100     S9xAPUSetByteZ (IAPU.YA.B.A, OP1);
1101     S9xAPUSetByteZ (IAPU.YA.B.Y, OP1 + 1);
1102     IAPU.PC += 2;
1103 }
1104
1105 void Apu64 ()
1106 {
1107 // CMP A,dp
1108     Work8 = S9xAPUGetByteZ (OP1);
1109     CMP (IAPU.YA.B.A, Work8);
1110     IAPU.PC += 2;
1111 }
1112
1113 void Apu65 ()
1114 {
1115 // CMP A,abs
1116     Absolute ();
1117     Work8 = S9xAPUGetByte (IAPU.Address);
1118     CMP (IAPU.YA.B.A, Work8);
1119     IAPU.PC += 3;
1120 }
1121
1122 void Apu66 ()
1123 {
1124 // CMP A,(X)
1125     Work8 = S9xAPUGetByteZ (IAPU.X);
1126     CMP (IAPU.YA.B.A, Work8);
1127     IAPU.PC++;
1128 }
1129
1130 void Apu67 ()
1131 {
1132 // CMP A,(dp+X)
1133     IndexedXIndirect ();
1134     Work8 = S9xAPUGetByte (IAPU.Address);
1135     CMP (IAPU.YA.B.A, Work8);
1136     IAPU.PC += 2;
1137 }
1138
1139 void Apu68 ()
1140 {
1141 // CMP A,#00
1142     Work8 = OP1;
1143     CMP (IAPU.YA.B.A, Work8);
1144     IAPU.PC += 2;
1145 }
1146
1147 void Apu69 ()
1148 {
1149 // CMP dp(dest), dp(src)
1150     W1 = S9xAPUGetByteZ (OP1);
1151     Work8 = S9xAPUGetByteZ (OP2);
1152     CMP (Work8, W1);
1153     IAPU.PC += 3;
1154 }
1155
1156 void Apu74 ()
1157 {
1158 // CMP A, dp+X
1159     Work8 = S9xAPUGetByteZ (OP1 + IAPU.X);
1160     CMP (IAPU.YA.B.A, Work8);
1161     IAPU.PC += 2;
1162 }
1163
1164 void Apu75 ()
1165 {
1166 // CMP A,abs+X
1167     AbsoluteX ();
1168     Work8 = S9xAPUGetByte (IAPU.Address);
1169     CMP (IAPU.YA.B.A, Work8);
1170     IAPU.PC += 3;
1171 }
1172
1173 void Apu76 ()
1174 {
1175 // CMP A, abs+Y
1176     AbsoluteY ();
1177     Work8 = S9xAPUGetByte (IAPU.Address);
1178     CMP (IAPU.YA.B.A, Work8);
1179     IAPU.PC += 3;
1180 }
1181
1182 void Apu77 ()
1183 {
1184 // CMP A,(dp)+Y
1185     IndirectIndexedY ();
1186     Work8 = S9xAPUGetByte (IAPU.Address);
1187     CMP (IAPU.YA.B.A, Work8);
1188     IAPU.PC += 2;
1189 }
1190
1191 void Apu78 ()
1192 {
1193 // CMP dp,#00
1194     Work8 = OP1;
1195     W1 = S9xAPUGetByteZ (OP2);
1196     CMP (W1, Work8);
1197     IAPU.PC += 3;
1198 }
1199
1200 void Apu79 ()
1201 {
1202 // CMP (X),(Y)
1203     W1 = S9xAPUGetByteZ (IAPU.X);
1204     Work8 = S9xAPUGetByteZ (IAPU.YA.B.Y);
1205     CMP (W1, Work8);
1206     IAPU.PC++;
1207 }
1208
1209 void Apu1E ()
1210 {
1211 // CMP X,abs
1212     Absolute ();
1213     Work8 = S9xAPUGetByte (IAPU.Address);
1214     CMP (IAPU.X, Work8);
1215     IAPU.PC += 3;
1216 }
1217
1218 void Apu3E ()
1219 {
1220 // CMP X,dp
1221     Work8 = S9xAPUGetByteZ (OP1);
1222     CMP (IAPU.X, Work8);
1223     IAPU.PC += 2;
1224 }
1225
1226 void ApuC8 ()
1227 {
1228 // CMP X,#00
1229     CMP (IAPU.X, OP1);
1230     IAPU.PC += 2;
1231 }
1232
1233 void Apu5E ()
1234 {
1235 // CMP Y,abs
1236     Absolute ();
1237     Work8 = S9xAPUGetByte (IAPU.Address);
1238     CMP (IAPU.YA.B.Y, Work8);
1239     IAPU.PC += 3;
1240 }
1241
1242 void Apu7E ()
1243 {
1244 // CMP Y,dp
1245     Work8 = S9xAPUGetByteZ (OP1);
1246     CMP (IAPU.YA.B.Y, Work8);
1247     IAPU.PC += 2;
1248 }
1249
1250 void ApuAD ()
1251 {
1252 // CMP Y,#00
1253     Work8 = OP1;
1254     CMP (IAPU.YA.B.Y, Work8);
1255     IAPU.PC += 2;
1256 }
1257
1258 void Apu1F ()
1259 {
1260 // JMP (abs+X)
1261     Absolute ();
1262     IAPU.PC = IAPU.RAM + S9xAPUGetByte (IAPU.Address + IAPU.X) +
1263         (S9xAPUGetByte (IAPU.Address + IAPU.X + 1) << 8);
1264 // XXX: HERE:
1265     // APU.Flags |= TRACE_FLAG;
1266 }
1267
1268 void Apu5F ()
1269 {
1270 // JMP abs
1271     Absolute ();
1272     IAPU.PC = IAPU.RAM + IAPU.Address;
1273 }
1274
1275 void Apu20 ()
1276 {
1277 // CLRP
1278     APUClearDirectPage ();
1279     IAPU.DirectPage = IAPU.RAM;
1280     IAPU.PC++;
1281 }
1282
1283 void Apu60 ()
1284 {
1285 // CLRC
1286     APUClearCarry ();
1287     IAPU.PC++;
1288 }
1289
1290 void ApuE0 ()
1291 {
1292 // CLRV
1293     APUClearHalfCarry ();
1294     APUClearOverflow ();
1295     IAPU.PC++;
1296 }
1297
1298 void Apu24 ()
1299 {
1300 // AND A,dp
1301     IAPU.YA.B.A &= S9xAPUGetByteZ (OP1);
1302     APUSetZN8 (IAPU.YA.B.A);
1303     IAPU.PC += 2;
1304 }
1305
1306 void Apu25 ()
1307 {
1308 // AND A,abs
1309     Absolute ();
1310     IAPU.YA.B.A &= S9xAPUGetByte (IAPU.Address);
1311     APUSetZN8 (IAPU.YA.B.A);
1312     IAPU.PC += 3;
1313 }
1314
1315 void Apu26 ()
1316 {
1317 // AND A,(X)
1318     IAPU.YA.B.A &= S9xAPUGetByteZ (IAPU.X);
1319     APUSetZN8 (IAPU.YA.B.A);
1320     IAPU.PC++;
1321 }
1322
1323 void Apu27 ()
1324 {
1325 // AND A,(dp+X)
1326     IndexedXIndirect ();
1327     IAPU.YA.B.A &= S9xAPUGetByte (IAPU.Address);
1328     APUSetZN8 (IAPU.YA.B.A);
1329     IAPU.PC += 2;
1330 }
1331
1332 void Apu28 ()
1333 {
1334 // AND A,#00
1335     IAPU.YA.B.A &= OP1;
1336     APUSetZN8 (IAPU.YA.B.A);
1337     IAPU.PC += 2;
1338 }
1339
1340 void Apu29 ()
1341 {
1342 // AND dp(dest),dp(src)
1343     Work8 = S9xAPUGetByteZ (OP1);
1344     Work8 &= S9xAPUGetByteZ (OP2);
1345     S9xAPUSetByteZ (Work8, OP2);
1346     APUSetZN8 (Work8);
1347     IAPU.PC += 3;
1348 }
1349
1350 void Apu34 ()
1351 {
1352 // AND A,dp+X
1353     IAPU.YA.B.A &= S9xAPUGetByteZ (OP1 + IAPU.X);
1354     APUSetZN8 (IAPU.YA.B.A);
1355     IAPU.PC += 2;
1356 }
1357
1358 void Apu35 ()
1359 {
1360 // AND A,abs+X
1361     AbsoluteX ();
1362     IAPU.YA.B.A &= S9xAPUGetByte (IAPU.Address);
1363     APUSetZN8 (IAPU.YA.B.A);
1364     IAPU.PC += 3;
1365 }
1366
1367 void Apu36 ()
1368 {
1369 // AND A,abs+Y
1370     AbsoluteY ();
1371     IAPU.YA.B.A &= S9xAPUGetByte (IAPU.Address);
1372     APUSetZN8 (IAPU.YA.B.A);
1373     IAPU.PC += 3;
1374 }
1375
1376 void Apu37 ()
1377 {
1378 // AND A,(dp)+Y
1379     IndirectIndexedY ();
1380     IAPU.YA.B.A &= S9xAPUGetByte (IAPU.Address);
1381     APUSetZN8 (IAPU.YA.B.A);
1382     IAPU.PC += 2;
1383 }
1384
1385 void Apu38 ()
1386 {
1387 // AND dp,#00
1388     Work8 = OP1;
1389     Work8 &= S9xAPUGetByteZ (OP2);
1390     S9xAPUSetByteZ (Work8, OP2);
1391     APUSetZN8 (Work8);
1392     IAPU.PC += 3;
1393 }
1394
1395 void Apu39 ()
1396 {
1397 // AND (X),(Y)
1398     Work8 = S9xAPUGetByteZ (IAPU.X) & S9xAPUGetByteZ (IAPU.YA.B.Y);
1399     APUSetZN8 (Work8);
1400     S9xAPUSetByteZ (Work8, IAPU.X);
1401     IAPU.PC++;
1402 }
1403
1404 void Apu2B ()
1405 {
1406 // ROL dp
1407     Work8 = S9xAPUGetByteZ (OP1);
1408     ROL (Work8);
1409     S9xAPUSetByteZ (Work8, OP1);
1410     IAPU.PC += 2;
1411 }
1412
1413 void Apu2C ()
1414 {
1415 // ROL abs
1416     Absolute ();
1417     Work8 = S9xAPUGetByte (IAPU.Address);
1418     ROL (Work8);
1419     S9xAPUSetByte (Work8, IAPU.Address);
1420     IAPU.PC += 3;
1421 }
1422
1423 void Apu3B ()
1424 {
1425 // ROL dp+X
1426     Work8 = S9xAPUGetByteZ (OP1 + IAPU.X);
1427     ROL (Work8);
1428     S9xAPUSetByteZ (Work8, OP1 + IAPU.X);
1429     IAPU.PC += 2;
1430 }
1431
1432 void Apu3C ()
1433 {
1434 // ROL A
1435     ROL (IAPU.YA.B.A);
1436     IAPU.PC++;
1437 }
1438
1439 void Apu2E ()
1440 {
1441 // CBNE dp,rel
1442     Work8 = OP1;
1443     Relative2 ();
1444     
1445     if (S9xAPUGetByteZ (Work8) != IAPU.YA.B.A)
1446     {
1447         IAPU.PC = IAPU.RAM + (uint16) Int16;
1448         CPU.APU_Cycles += IAPU.TwoCycles;
1449         APUShutdown ();
1450     }
1451     else
1452         IAPU.PC += 3;
1453 }
1454
1455 void ApuDE ()
1456 {
1457 // CBNE dp+X,rel
1458     Work8 = OP1 + IAPU.X;
1459     Relative2 ();
1460
1461     if (S9xAPUGetByteZ (Work8) != IAPU.YA.B.A)
1462     {
1463         IAPU.PC = IAPU.RAM + (uint16) Int16;
1464         CPU.APU_Cycles += IAPU.TwoCycles;
1465         APUShutdown ();
1466     }
1467     else
1468         IAPU.PC += 3;
1469 }
1470
1471 void Apu3D ()
1472 {
1473 // INC X
1474     IAPU.X++;
1475     APUSetZN8 (IAPU.X);
1476
1477 #ifdef SPC700_SHUTDOWN
1478     IAPU.WaitCounter++;
1479 #endif
1480
1481     IAPU.PC++;
1482 }
1483
1484 void ApuFC ()
1485 {
1486 // INC Y
1487     IAPU.YA.B.Y++;
1488     APUSetZN8 (IAPU.YA.B.Y);
1489
1490 #ifdef SPC700_SHUTDOWN
1491     IAPU.WaitCounter++;
1492 #endif
1493
1494     IAPU.PC++;
1495 }
1496
1497 void Apu1D ()
1498 {
1499 // DEC X
1500     IAPU.X--;
1501     APUSetZN8 (IAPU.X);
1502
1503 #ifdef SPC700_SHUTDOWN
1504     IAPU.WaitCounter++;
1505 #endif
1506
1507     IAPU.PC++;
1508 }
1509
1510 void ApuDC ()
1511 {
1512 // DEC Y
1513     IAPU.YA.B.Y--;
1514     APUSetZN8 (IAPU.YA.B.Y);
1515
1516 #ifdef SPC700_SHUTDOWN
1517     IAPU.WaitCounter++;
1518 #endif
1519
1520     IAPU.PC++;
1521 }
1522
1523 void ApuAB ()
1524 {
1525 // INC dp
1526     Work8 = S9xAPUGetByteZ (OP1) + 1;
1527     S9xAPUSetByteZ (Work8, OP1);
1528     APUSetZN8 (Work8);
1529
1530 #ifdef SPC700_SHUTDOWN
1531     IAPU.WaitCounter++;
1532 #endif
1533
1534     IAPU.PC += 2;
1535 }
1536
1537 void ApuAC ()
1538 {
1539 // INC abs
1540     Absolute ();
1541     Work8 = S9xAPUGetByte (IAPU.Address) + 1;
1542     S9xAPUSetByte (Work8, IAPU.Address);
1543     APUSetZN8 (Work8);
1544
1545 #ifdef SPC700_SHUTDOWN
1546     IAPU.WaitCounter++;
1547 #endif
1548
1549     IAPU.PC += 3;
1550 }
1551
1552 void ApuBB ()
1553 {
1554 // INC dp+X
1555     Work8 = S9xAPUGetByteZ (OP1 + IAPU.X) + 1;
1556     S9xAPUSetByteZ (Work8, OP1 + IAPU.X);
1557     APUSetZN8 (Work8);
1558
1559 #ifdef SPC700_SHUTDOWN
1560     IAPU.WaitCounter++;
1561 #endif
1562
1563     IAPU.PC += 2;
1564 }
1565
1566 void ApuBC ()
1567 {
1568 // INC A
1569     IAPU.YA.B.A++;
1570     APUSetZN8 (IAPU.YA.B.A);
1571
1572 #ifdef SPC700_SHUTDOWN
1573     IAPU.WaitCounter++;
1574 #endif
1575
1576     IAPU.PC++;
1577 }
1578
1579 void Apu8B ()
1580 {
1581 // DEC dp
1582     Work8 = S9xAPUGetByteZ (OP1) - 1;
1583     S9xAPUSetByteZ (Work8, OP1);
1584     APUSetZN8 (Work8);
1585
1586 #ifdef SPC700_SHUTDOWN
1587     IAPU.WaitCounter++;
1588 #endif
1589
1590     IAPU.PC += 2;
1591 }
1592
1593 void Apu8C ()
1594 {
1595 // DEC abs
1596     Absolute ();
1597     Work8 = S9xAPUGetByte (IAPU.Address) - 1;
1598     S9xAPUSetByte (Work8, IAPU.Address);
1599     APUSetZN8 (Work8);
1600
1601 #ifdef SPC700_SHUTDOWN
1602     IAPU.WaitCounter++;
1603 #endif
1604
1605     IAPU.PC += 3;
1606 }
1607
1608 void Apu9B ()
1609 {
1610 // DEC dp+X
1611     Work8 = S9xAPUGetByteZ (OP1 + IAPU.X) - 1;
1612     S9xAPUSetByteZ (Work8, OP1 + IAPU.X);
1613     APUSetZN8 (Work8);
1614
1615 #ifdef SPC700_SHUTDOWN
1616     IAPU.WaitCounter++;
1617 #endif
1618
1619     IAPU.PC += 2;
1620 }
1621
1622 void Apu9C ()
1623 {
1624 // DEC A
1625     IAPU.YA.B.A--;
1626     APUSetZN8 (IAPU.YA.B.A);
1627
1628 #ifdef SPC700_SHUTDOWN
1629     IAPU.WaitCounter++;
1630 #endif
1631
1632     IAPU.PC++;
1633 }
1634
1635 void Apu44 ()
1636 {
1637 // EOR A,dp
1638     IAPU.YA.B.A ^= S9xAPUGetByteZ (OP1);
1639     APUSetZN8 (IAPU.YA.B.A);
1640     IAPU.PC += 2;
1641 }
1642
1643 void Apu45 ()
1644 {
1645 // EOR A,abs
1646     Absolute ();
1647     IAPU.YA.B.A ^= S9xAPUGetByte (IAPU.Address);
1648     APUSetZN8 (IAPU.YA.B.A);
1649     IAPU.PC += 3;
1650 }
1651
1652 void Apu46 ()
1653 {
1654 // EOR A,(X)
1655     IAPU.YA.B.A ^= S9xAPUGetByteZ (IAPU.X);
1656     APUSetZN8 (IAPU.YA.B.A);
1657     IAPU.PC++;
1658 }
1659
1660 void Apu47 ()
1661 {
1662 // EOR A,(dp+X)
1663     IndexedXIndirect ();
1664     IAPU.YA.B.A ^= S9xAPUGetByte (IAPU.Address);
1665     APUSetZN8 (IAPU.YA.B.A);
1666     IAPU.PC += 2;
1667 }
1668
1669 void Apu48 ()
1670 {
1671 // EOR A,#00
1672     IAPU.YA.B.A ^= OP1;
1673     APUSetZN8 (IAPU.YA.B.A);
1674     IAPU.PC += 2;
1675 }
1676
1677 void Apu49 ()
1678 {
1679 // EOR dp(dest),dp(src)
1680     Work8 = S9xAPUGetByteZ (OP1);
1681     Work8 ^= S9xAPUGetByteZ (OP2);
1682     S9xAPUSetByteZ (Work8, OP2);
1683     APUSetZN8 (Work8);
1684     IAPU.PC += 3;
1685 }
1686
1687 void Apu54 ()
1688 {
1689 // EOR A,dp+X
1690     IAPU.YA.B.A ^= S9xAPUGetByteZ (OP1 + IAPU.X);
1691     APUSetZN8 (IAPU.YA.B.A);
1692     IAPU.PC += 2;
1693 }
1694
1695 void Apu55 ()
1696 {
1697 // EOR A,abs+X
1698     AbsoluteX ();
1699     IAPU.YA.B.A ^= S9xAPUGetByte (IAPU.Address);
1700     APUSetZN8 (IAPU.YA.B.A);
1701     IAPU.PC += 3;
1702 }
1703
1704 void Apu56 ()
1705 {
1706 // EOR A,abs+Y
1707     AbsoluteY ();
1708     IAPU.YA.B.A ^= S9xAPUGetByte (IAPU.Address);
1709     APUSetZN8 (IAPU.YA.B.A);
1710     IAPU.PC += 3;
1711 }
1712
1713 void Apu57 ()
1714 {
1715 // EOR A,(dp)+Y
1716     IndirectIndexedY ();
1717     IAPU.YA.B.A ^= S9xAPUGetByte (IAPU.Address);
1718     APUSetZN8 (IAPU.YA.B.A);
1719     IAPU.PC += 2;
1720 }
1721
1722 void Apu58 ()
1723 {
1724 // EOR dp,#00
1725     Work8 = OP1;
1726     Work8 ^= S9xAPUGetByteZ (OP2);
1727     S9xAPUSetByteZ (Work8, OP2);
1728     APUSetZN8 (Work8);
1729     IAPU.PC += 3;
1730 }
1731
1732 void Apu59 ()
1733 {
1734 // EOR (X),(Y)
1735     Work8 = S9xAPUGetByteZ (IAPU.X) ^ S9xAPUGetByteZ (IAPU.YA.B.Y);
1736     APUSetZN8 (Work8);
1737     S9xAPUSetByteZ (Work8, IAPU.X);
1738     IAPU.PC++;
1739 }
1740
1741 void Apu4B ()
1742 {
1743 // LSR dp
1744     Work8 = S9xAPUGetByteZ (OP1);
1745     LSR (Work8);
1746     S9xAPUSetByteZ (Work8, OP1);
1747     IAPU.PC += 2;
1748 }
1749
1750 void Apu4C ()
1751 {
1752 // LSR abs
1753     Absolute ();
1754     Work8 = S9xAPUGetByte (IAPU.Address);
1755     LSR (Work8);
1756     S9xAPUSetByte (Work8, IAPU.Address);
1757     IAPU.PC += 3;
1758 }
1759
1760 void Apu5B ()
1761 {
1762 // LSR dp+X
1763     Work8 = S9xAPUGetByteZ (OP1 + IAPU.X);
1764     LSR (Work8);
1765     S9xAPUSetByteZ (Work8, OP1 + IAPU.X);
1766     IAPU.PC += 2;
1767 }
1768
1769 void Apu5C ()
1770 {
1771 // LSR A
1772     LSR (IAPU.YA.B.A);
1773     IAPU.PC++;
1774 }
1775
1776 void Apu7D ()
1777 {
1778 // MOV A,X
1779     IAPU.YA.B.A = IAPU.X;
1780     APUSetZN8 (IAPU.YA.B.A);
1781     IAPU.PC++;
1782 }
1783
1784 void ApuDD ()
1785 {
1786 // MOV A,Y
1787     IAPU.YA.B.A = IAPU.YA.B.Y;
1788     APUSetZN8 (IAPU.YA.B.A);
1789     IAPU.PC++;
1790 }
1791
1792 void Apu5D ()
1793 {
1794 // MOV X,A
1795     IAPU.X = IAPU.YA.B.A;
1796     APUSetZN8 (IAPU.X);
1797     IAPU.PC++;
1798 }
1799
1800 void ApuFD ()
1801 {
1802 // MOV Y,A
1803     IAPU.YA.B.Y = IAPU.YA.B.A;
1804     APUSetZN8 (IAPU.YA.B.Y);
1805     IAPU.PC++;
1806 }
1807
1808 void Apu9D ()
1809 {
1810 //MOV X,SP
1811     IAPU.X = IAPU.S;
1812     APUSetZN8 (IAPU.X);
1813     IAPU.PC++;
1814 }
1815
1816 void ApuBD ()
1817 {
1818 // MOV SP,X
1819     IAPU.S = IAPU.X;
1820     IAPU.PC++;
1821 }
1822
1823 void Apu6B ()
1824 {
1825 // ROR dp
1826     Work8 = S9xAPUGetByteZ (OP1);
1827     ROR (Work8);
1828     S9xAPUSetByteZ (Work8, OP1);
1829     IAPU.PC += 2;
1830 }
1831
1832 void Apu6C ()
1833 {
1834 // ROR abs
1835     Absolute ();
1836     Work8 = S9xAPUGetByte (IAPU.Address);
1837     ROR (Work8);
1838     S9xAPUSetByte (Work8, IAPU.Address);
1839     IAPU.PC += 3;
1840 }
1841
1842 void Apu7B ()
1843 {
1844 // ROR dp+X
1845     Work8 = S9xAPUGetByteZ (OP1 + IAPU.X);
1846     ROR (Work8);
1847     S9xAPUSetByteZ (Work8, OP1 + IAPU.X);
1848     IAPU.PC += 2;
1849 }
1850
1851 void Apu7C ()
1852 {
1853 // ROR A
1854     ROR (IAPU.YA.B.A);
1855     IAPU.PC++;
1856 }
1857
1858 void Apu6E ()
1859 {
1860 // DBNZ dp,rel
1861     Work8 = OP1;
1862     Relative2 ();
1863     W1 = S9xAPUGetByteZ (Work8) - 1;
1864     S9xAPUSetByteZ (W1, Work8);
1865     if (W1 != 0)
1866     {
1867         IAPU.PC = IAPU.RAM + (uint16) Int16;
1868         CPU.APU_Cycles += IAPU.TwoCycles;
1869     }
1870     else
1871         IAPU.PC += 3;
1872 }
1873
1874 void ApuFE ()
1875 {
1876 // DBNZ Y,rel
1877     Relative ();
1878     IAPU.YA.B.Y--;
1879     if (IAPU.YA.B.Y != 0)
1880     {
1881         IAPU.PC = IAPU.RAM + (uint16) Int16;
1882         CPU.APU_Cycles += IAPU.TwoCycles;
1883     }
1884     else
1885         IAPU.PC += 2;
1886 }
1887
1888 void Apu6F ()
1889 {
1890 // RET
1891     PopW (Work16);
1892     IAPU.PC = IAPU.RAM + Work16;
1893 }
1894
1895 void Apu7F ()
1896 {
1897 // RETI
1898     // STOP ("RETI");
1899     Pop (IAPU.P);
1900     S9xAPUUnpackStatus ();
1901     PopW (Work16);
1902     IAPU.PC = IAPU.RAM + Work16;
1903 }
1904
1905 void Apu84 ()
1906 {
1907 // ADC A,dp
1908     Work8 = S9xAPUGetByteZ (OP1);
1909     ADC (IAPU.YA.B.A, Work8);
1910     IAPU.PC += 2;
1911 }
1912
1913 void Apu85 ()
1914 {
1915 // ADC A, abs
1916     Absolute ();
1917     Work8 = S9xAPUGetByte (IAPU.Address);
1918     ADC (IAPU.YA.B.A, Work8);
1919     IAPU.PC += 3;
1920 }
1921
1922 void Apu86 ()
1923 {
1924 // ADC A,(X)
1925     Work8 = S9xAPUGetByteZ (IAPU.X);
1926     ADC (IAPU.YA.B.A, Work8);
1927     IAPU.PC++;
1928 }
1929
1930 void Apu87 ()
1931 {
1932 // ADC A,(dp+X)
1933     IndexedXIndirect ();
1934     Work8 = S9xAPUGetByte (IAPU.Address);
1935     ADC (IAPU.YA.B.A, Work8);
1936     IAPU.PC += 2;
1937 }
1938
1939 void Apu88 ()
1940 {
1941 // ADC A,#00
1942     Work8 = OP1;
1943     ADC (IAPU.YA.B.A, Work8);
1944     IAPU.PC += 2;
1945 }
1946
1947 void Apu89 ()
1948 {
1949 // ADC dp(dest),dp(src)
1950     Work8 = S9xAPUGetByteZ (OP1);
1951     W1 = S9xAPUGetByteZ (OP2);
1952     ADC (W1, Work8);
1953     S9xAPUSetByteZ (W1, OP2);
1954     IAPU.PC += 3;
1955 }
1956
1957 void Apu94 ()
1958 {
1959 // ADC A,dp+X
1960     Work8 = S9xAPUGetByteZ (OP1 + IAPU.X);
1961     ADC (IAPU.YA.B.A, Work8);
1962     IAPU.PC += 2;
1963 }
1964
1965 void Apu95 ()
1966 {
1967 // ADC A, abs+X
1968     AbsoluteX ();
1969     Work8 = S9xAPUGetByte (IAPU.Address);
1970     ADC (IAPU.YA.B.A, Work8);
1971     IAPU.PC += 3;
1972 }
1973
1974 void Apu96 ()
1975 {
1976 // ADC A, abs+Y
1977     AbsoluteY ();
1978     Work8 = S9xAPUGetByte (IAPU.Address);
1979     ADC (IAPU.YA.B.A, Work8);
1980     IAPU.PC += 3;
1981 }
1982
1983 void Apu97 ()
1984 {
1985 // ADC A, (dp)+Y
1986     IndirectIndexedY ();
1987     Work8 = S9xAPUGetByte (IAPU.Address);
1988     ADC (IAPU.YA.B.A, Work8);
1989     IAPU.PC += 2;
1990 }
1991
1992 void Apu98 ()
1993 {
1994 // ADC dp,#00
1995     Work8 = OP1;
1996     W1 = S9xAPUGetByteZ (OP2);
1997     ADC (W1, Work8);
1998     S9xAPUSetByteZ (W1, OP2);
1999     IAPU.PC += 3;
2000 }
2001
2002 void Apu99 ()
2003 {
2004 // ADC (X),(Y)
2005     W1 = S9xAPUGetByteZ (IAPU.X);
2006     Work8 = S9xAPUGetByteZ (IAPU.YA.B.Y);
2007     ADC (W1, Work8);
2008     S9xAPUSetByteZ (W1, IAPU.X);
2009     IAPU.PC++;
2010 }
2011
2012 void Apu8D ()
2013 {
2014 // MOV Y,#00
2015     IAPU.YA.B.Y = OP1;
2016     APUSetZN8 (IAPU.YA.B.Y);
2017     IAPU.PC += 2;
2018 }
2019
2020 void Apu8F ()
2021 {
2022 // MOV dp,#00
2023     Work8 = OP1;
2024     S9xAPUSetByteZ (Work8, OP2);
2025     IAPU.PC += 3;
2026 }
2027
2028 void Apu9E ()
2029 {
2030 // DIV YA,X
2031     if (IAPU.X == 0)
2032     {
2033         APUSetOverflow ();
2034         IAPU.YA.B.Y = 0xff;
2035         IAPU.YA.B.A = 0xff;
2036     }
2037     else
2038     {
2039         APUClearOverflow ();
2040         Work8 = IAPU.YA.W / IAPU.X;
2041         IAPU.YA.B.Y = IAPU.YA.W % IAPU.X;
2042         IAPU.YA.B.A = Work8;
2043     }
2044 // XXX How should Overflow, Half Carry, Zero and Negative flags be set??
2045     // APUSetZN16 (IAPU.YA.W);
2046     APUSetZN8 (IAPU.YA.B.A);
2047     IAPU.PC++;
2048 }
2049
2050 void Apu9F ()
2051 {
2052 // XCN A
2053     IAPU.YA.B.A = (IAPU.YA.B.A >> 4) | (IAPU.YA.B.A << 4);
2054     APUSetZN8 (IAPU.YA.B.A);
2055     IAPU.PC++;
2056 }
2057
2058 void ApuA4 ()
2059 {
2060 // SBC A, dp
2061     Work8 = S9xAPUGetByteZ (OP1);
2062     SBC (IAPU.YA.B.A, Work8);
2063     IAPU.PC += 2;
2064 }
2065
2066 void ApuA5 ()
2067 {
2068 // SBC A, abs
2069     Absolute ();
2070     Work8 = S9xAPUGetByte (IAPU.Address);
2071     SBC (IAPU.YA.B.A, Work8);
2072     IAPU.PC += 3;
2073 }
2074
2075 void ApuA6 ()
2076 {
2077 // SBC A, (X)
2078     Work8 = S9xAPUGetByteZ (IAPU.X);
2079     SBC (IAPU.YA.B.A, Work8);
2080     IAPU.PC++;
2081 }
2082
2083 void ApuA7 ()
2084 {
2085 // SBC A,(dp+X)
2086     IndexedXIndirect ();
2087     Work8 = S9xAPUGetByte (IAPU.Address);
2088     SBC (IAPU.YA.B.A, Work8);
2089     IAPU.PC += 2;
2090 }
2091
2092 void ApuA8 ()
2093 {
2094 // SBC A,#00
2095     Work8 = OP1;
2096     SBC (IAPU.YA.B.A, Work8);
2097     IAPU.PC += 2;
2098 }
2099
2100 void ApuA9 ()
2101 {
2102 // SBC dp(dest), dp(src)
2103     Work8 = S9xAPUGetByteZ (OP1);
2104     W1 = S9xAPUGetByteZ (OP2);
2105     SBC (W1, Work8);
2106     S9xAPUSetByteZ (W1, OP2);
2107     IAPU.PC += 3;
2108 }
2109
2110 void ApuB4 ()
2111 {
2112 // SBC A, dp+X
2113     Work8 = S9xAPUGetByteZ (OP1 + IAPU.X);
2114     SBC (IAPU.YA.B.A, Work8);
2115     IAPU.PC += 2;
2116 }
2117
2118 void ApuB5 ()
2119 {
2120 // SBC A,abs+X
2121     AbsoluteX ();
2122     Work8 = S9xAPUGetByte (IAPU.Address);
2123     SBC (IAPU.YA.B.A, Work8);
2124     IAPU.PC += 3;
2125 }
2126
2127 void ApuB6 ()
2128 {
2129 // SBC A,abs+Y
2130     AbsoluteY ();
2131     Work8 = S9xAPUGetByte (IAPU.Address);
2132     SBC (IAPU.YA.B.A, Work8);
2133     IAPU.PC += 3;
2134 }
2135
2136 void ApuB7 ()
2137 {
2138 // SBC A,(dp)+Y
2139     IndirectIndexedY ();
2140     Work8 = S9xAPUGetByte (IAPU.Address);
2141     SBC (IAPU.YA.B.A, Work8);
2142     IAPU.PC += 2;
2143 }
2144
2145 void ApuB8 ()
2146 {
2147 // SBC dp,#00
2148     Work8 = OP1;
2149     W1 = S9xAPUGetByteZ (OP2);
2150     SBC (W1, Work8);
2151     S9xAPUSetByteZ (W1, OP2);
2152     IAPU.PC += 3;
2153 }
2154
2155 void ApuB9 ()
2156 {
2157 // SBC (X),(Y)
2158     W1 = S9xAPUGetByteZ (IAPU.X);
2159     Work8 = S9xAPUGetByteZ (IAPU.YA.B.Y);
2160     SBC (W1, Work8);
2161     S9xAPUSetByteZ (W1, IAPU.X);
2162     IAPU.PC++;
2163 }
2164
2165 void ApuAF ()
2166 {
2167 // MOV (X)+, A
2168     S9xAPUSetByteZ (IAPU.YA.B.A, IAPU.X++);
2169     IAPU.PC++;
2170 }
2171
2172 void ApuBE ()
2173 {
2174 // DAS
2175     if ((IAPU.YA.B.A & 0x0f) > 9 || !APUCheckHalfCarry())
2176    {
2177         IAPU.YA.B.A -= 6;
2178    }
2179     if (IAPU.YA.B.A > 0x9f || !IAPU._Carry)
2180    {
2181         IAPU.YA.B.A -= 0x60;
2182         APUClearCarry ();
2183    }
2184     else { APUSetCarry (); }
2185     APUSetZN8 (IAPU.YA.B.A);
2186    IAPU.PC++;
2187 }
2188
2189 void ApuBF ()
2190 {
2191 // MOV A,(X)+
2192     IAPU.YA.B.A = S9xAPUGetByteZ (IAPU.X++);
2193     APUSetZN8 (IAPU.YA.B.A);
2194     IAPU.PC++;
2195 }
2196
2197 void ApuC0 ()
2198 {
2199 // DI
2200     APUClearInterrupt ();
2201     IAPU.PC++;
2202 }
2203
2204 void ApuA0 ()
2205 {
2206 // EI
2207     APUSetInterrupt ();
2208     IAPU.PC++;
2209 }
2210
2211 void ApuC4 ()
2212 {
2213 // MOV dp,A
2214     S9xAPUSetByteZ (IAPU.YA.B.A, OP1);
2215     IAPU.PC += 2;
2216 }
2217
2218 void ApuC5 ()
2219 {
2220 // MOV abs,A
2221     Absolute ();
2222     S9xAPUSetByte (IAPU.YA.B.A, IAPU.Address);
2223     IAPU.PC += 3;
2224 }
2225
2226 void ApuC6 ()
2227 {
2228 // MOV (X), A
2229     S9xAPUSetByteZ (IAPU.YA.B.A, IAPU.X);
2230     IAPU.PC++;
2231 }
2232
2233 void ApuC7 ()
2234 {
2235 // MOV (dp+X),A
2236     IndexedXIndirect ();
2237     S9xAPUSetByte (IAPU.YA.B.A, IAPU.Address);
2238     IAPU.PC += 2;
2239 }
2240
2241 void ApuC9 ()
2242 {
2243 // MOV abs,X
2244     Absolute ();
2245     S9xAPUSetByte (IAPU.X, IAPU.Address);
2246     IAPU.PC += 3;
2247 }
2248
2249 void ApuCB ()
2250 {
2251 // MOV dp,Y
2252     S9xAPUSetByteZ (IAPU.YA.B.Y, OP1);
2253     IAPU.PC += 2;
2254 }
2255
2256 void ApuCC ()
2257 {
2258 // MOV abs,Y
2259     Absolute ();
2260     S9xAPUSetByte (IAPU.YA.B.Y, IAPU.Address);
2261     IAPU.PC += 3;
2262 }
2263
2264 void ApuCD ()
2265 {
2266 // MOV X,#00
2267     IAPU.X = OP1;
2268     APUSetZN8 (IAPU.X);
2269     IAPU.PC += 2;
2270 }
2271
2272 void ApuCF ()
2273 {
2274 // MUL YA
2275     IAPU.YA.W = (uint16) IAPU.YA.B.A * IAPU.YA.B.Y;
2276     APUSetZN16 (IAPU.YA.W);
2277     IAPU.PC++;
2278 }
2279
2280 void ApuD4 ()
2281 {
2282 // MOV dp+X, A
2283     S9xAPUSetByteZ (IAPU.YA.B.A, OP1 + IAPU.X);
2284     IAPU.PC += 2;
2285 }
2286
2287 void ApuD5 ()
2288 {
2289 // MOV abs+X,A
2290     AbsoluteX ();
2291     S9xAPUSetByte (IAPU.YA.B.A, IAPU.Address);
2292     IAPU.PC += 3;
2293 }
2294
2295 void ApuD6 ()
2296 {
2297 // MOV abs+Y,A
2298     AbsoluteY ();
2299     S9xAPUSetByte (IAPU.YA.B.A, IAPU.Address);
2300     IAPU.PC += 3;
2301 }
2302
2303 void ApuD7 ()
2304 {
2305 // MOV (dp)+Y,A
2306     IndirectIndexedY ();
2307     S9xAPUSetByte (IAPU.YA.B.A, IAPU.Address);
2308     IAPU.PC += 2;
2309 }
2310
2311 void ApuD8 ()
2312 {
2313 // MOV dp,X
2314     S9xAPUSetByteZ (IAPU.X, OP1);
2315     IAPU.PC += 2;
2316 }
2317
2318 void ApuD9 ()
2319 {
2320 // MOV dp+Y,X
2321     S9xAPUSetByteZ (IAPU.X, OP1 + IAPU.YA.B.Y);
2322     IAPU.PC += 2;
2323 }
2324
2325 void ApuDB ()
2326 {
2327 // MOV dp+X,Y
2328     S9xAPUSetByteZ (IAPU.YA.B.Y, OP1 + IAPU.X);
2329     IAPU.PC += 2;
2330 }
2331
2332 void ApuDF ()
2333 {
2334 // DAA
2335     if ((IAPU.YA.B.A & 0x0f) > 9 || APUCheckHalfCarry())
2336     {
2337         if(IAPU.YA.B.A > 0xf0) APUSetCarry ();
2338         IAPU.YA.B.A += 6;
2339         //APUSetHalfCarry (); Intel procs do this, but this is a Sony proc...
2340     }
2341     //else { APUClearHalfCarry (); } ditto as above
2342     if (IAPU.YA.B.A > 0x9f || IAPU._Carry)
2343     {
2344         IAPU.YA.B.A += 0x60;
2345         APUSetCarry ();
2346     }
2347     else { APUClearCarry (); }
2348     APUSetZN8 (IAPU.YA.B.A);
2349     IAPU.PC++;
2350 }
2351
2352 void ApuE4 ()
2353 {
2354 // MOV A, dp
2355     IAPU.YA.B.A = S9xAPUGetByteZ (OP1);
2356     APUSetZN8 (IAPU.YA.B.A);
2357     IAPU.PC += 2;
2358 }
2359
2360 void ApuE5 ()
2361 {
2362 // MOV A,abs
2363     Absolute ();
2364     IAPU.YA.B.A = S9xAPUGetByte (IAPU.Address);
2365     APUSetZN8 (IAPU.YA.B.A);
2366     IAPU.PC += 3;
2367 }
2368
2369 void ApuE6 ()
2370 {
2371 // MOV A,(X)
2372     IAPU.YA.B.A = S9xAPUGetByteZ (IAPU.X);
2373     APUSetZN8 (IAPU.YA.B.A);
2374     IAPU.PC++;
2375 }
2376
2377 void ApuE7 ()
2378 {
2379 // MOV A,(dp+X)
2380     IndexedXIndirect ();
2381     IAPU.YA.B.A = S9xAPUGetByte (IAPU.Address);
2382     APUSetZN8 (IAPU.YA.B.A);
2383     IAPU.PC += 2;
2384 }
2385
2386 void ApuE8 ()
2387 {
2388 // MOV A,#00
2389     IAPU.YA.B.A = OP1;
2390     APUSetZN8 (IAPU.YA.B.A);
2391     IAPU.PC += 2;
2392 }
2393
2394 void ApuE9 ()
2395 {
2396 // MOV X, abs
2397     Absolute ();
2398     IAPU.X = S9xAPUGetByte (IAPU.Address);
2399     APUSetZN8 (IAPU.X);
2400     IAPU.PC += 3;
2401 }
2402
2403 void ApuEB ()
2404 {
2405 // MOV Y,dp
2406     IAPU.YA.B.Y = S9xAPUGetByteZ (OP1);
2407     APUSetZN8 (IAPU.YA.B.Y);
2408     IAPU.PC += 2;
2409 }
2410
2411 void ApuEC ()
2412 {
2413 // MOV Y,abs
2414     Absolute ();
2415     IAPU.YA.B.Y = S9xAPUGetByte (IAPU.Address);
2416     APUSetZN8 (IAPU.YA.B.Y);
2417     IAPU.PC += 3;
2418 }
2419
2420 void ApuF4 ()
2421 {
2422 // MOV A, dp+X
2423     IAPU.YA.B.A = S9xAPUGetByteZ (OP1 + IAPU.X);
2424     APUSetZN8 (IAPU.YA.B.A);
2425     IAPU.PC += 2;
2426 }
2427
2428 void ApuF5 ()
2429 {
2430 // MOV A, abs+X
2431     AbsoluteX ();
2432     IAPU.YA.B.A = S9xAPUGetByte (IAPU.Address);
2433     APUSetZN8 (IAPU.YA.B.A);
2434     IAPU.PC += 3;
2435 }
2436
2437 void ApuF6 ()
2438 {
2439 // MOV A, abs+Y
2440     AbsoluteY ();
2441     IAPU.YA.B.A = S9xAPUGetByte (IAPU.Address);
2442     APUSetZN8 (IAPU.YA.B.A);
2443     IAPU.PC += 3;
2444 }
2445
2446 void ApuF7 ()
2447 {
2448 // MOV A, (dp)+Y
2449     IndirectIndexedY ();
2450     IAPU.YA.B.A = S9xAPUGetByte (IAPU.Address);
2451     APUSetZN8 (IAPU.YA.B.A);
2452     IAPU.PC += 2;
2453 }
2454
2455 void ApuF8 ()
2456 {
2457 // MOV X,dp
2458     IAPU.X = S9xAPUGetByteZ (OP1);
2459     APUSetZN8 (IAPU.X);
2460     IAPU.PC += 2;
2461 }
2462
2463 void ApuF9 ()
2464 {
2465 // MOV X,dp+Y
2466     IAPU.X = S9xAPUGetByteZ (OP1 + IAPU.YA.B.Y);
2467     APUSetZN8 (IAPU.X);
2468     IAPU.PC += 2;
2469 }
2470
2471 void ApuFA ()
2472 {
2473 // MOV dp(dest),dp(src)
2474     S9xAPUSetByteZ (S9xAPUGetByteZ (OP1), OP2);
2475     IAPU.PC += 3;
2476 }
2477
2478 void ApuFB ()
2479 {
2480 // MOV Y,dp+X
2481     IAPU.YA.B.Y = S9xAPUGetByteZ (OP1 + IAPU.X);
2482     APUSetZN8 (IAPU.YA.B.Y);
2483     IAPU.PC += 2;
2484 }
2485
2486 #if defined(NO_INLINE_SET_GET)
2487 #undef INLINE
2488 #define INLINE
2489 #include "apumem.h"
2490 #endif
2491
2492
2493 void (*S9xApuOpcodes[256]) (void) =
2494 {
2495         Apu00, Apu01, Apu02, Apu03, Apu04, Apu05, Apu06, Apu07,
2496         Apu08, Apu09, Apu0A, Apu0B, Apu0C, Apu0D, Apu0E, Apu0F,
2497         Apu10, Apu11, Apu12, Apu13, Apu14, Apu15, Apu16, Apu17,
2498         Apu18, Apu19, Apu1A, Apu1B, Apu1C, Apu1D, Apu1E, Apu1F,
2499         Apu20, Apu21, Apu22, Apu23, Apu24, Apu25, Apu26, Apu27,
2500         Apu28, Apu29, Apu2A, Apu2B, Apu2C, Apu2D, Apu2E, Apu2F,
2501         Apu30, Apu31, Apu32, Apu33, Apu34, Apu35, Apu36, Apu37,
2502         Apu38, Apu39, Apu3A, Apu3B, Apu3C, Apu3D, Apu3E, Apu3F,
2503         Apu40, Apu41, Apu42, Apu43, Apu44, Apu45, Apu46, Apu47,
2504         Apu48, Apu49, Apu4A, Apu4B, Apu4C, Apu4D, Apu4E, Apu4F,
2505         Apu50, Apu51, Apu52, Apu53, Apu54, Apu55, Apu56, Apu57,
2506         Apu58, Apu59, Apu5A, Apu5B, Apu5C, Apu5D, Apu5E, Apu5F,
2507         Apu60, Apu61, Apu62, Apu63, Apu64, Apu65, Apu66, Apu67,
2508         Apu68, Apu69, Apu6A, Apu6B, Apu6C, Apu6D, Apu6E, Apu6F,
2509         Apu70, Apu71, Apu72, Apu73, Apu74, Apu75, Apu76, Apu77,
2510         Apu78, Apu79, Apu7A, Apu7B, Apu7C, Apu7D, Apu7E, Apu7F,
2511         Apu80, Apu81, Apu82, Apu83, Apu84, Apu85, Apu86, Apu87,
2512         Apu88, Apu89, Apu8A, Apu8B, Apu8C, Apu8D, Apu8E, Apu8F,
2513         Apu90, Apu91, Apu92, Apu93, Apu94, Apu95, Apu96, Apu97,
2514         Apu98, Apu99, Apu9A, Apu9B, Apu9C, Apu9D, Apu9E, Apu9F,
2515         ApuA0, ApuA1, ApuA2, ApuA3, ApuA4, ApuA5, ApuA6, ApuA7,
2516         ApuA8, ApuA9, ApuAA, ApuAB, ApuAC, ApuAD, ApuAE, ApuAF,
2517         ApuB0, ApuB1, ApuB2, ApuB3, ApuB4, ApuB5, ApuB6, ApuB7,
2518         ApuB8, ApuB9, ApuBA, ApuBB, ApuBC, ApuBD, ApuBE, ApuBF,
2519         ApuC0, ApuC1, ApuC2, ApuC3, ApuC4, ApuC5, ApuC6, ApuC7,
2520         ApuC8, ApuC9, ApuCA, ApuCB, ApuCC, ApuCD, ApuCE, ApuCF,
2521         ApuD0, ApuD1, ApuD2, ApuD3, ApuD4, ApuD5, ApuD6, ApuD7,
2522         ApuD8, ApuD9, ApuDA, ApuDB, ApuDC, ApuDD, ApuDE, ApuDF,
2523         ApuE0, ApuE1, ApuE2, ApuE3, ApuE4, ApuE5, ApuE6, ApuE7,
2524         ApuE8, ApuE9, ApuEA, ApuEB, ApuEC, ApuED, ApuEE, ApuEF,
2525         ApuF0, ApuF1, ApuF2, ApuF3, ApuF4, ApuF5, ApuF6, ApuF7,
2526         ApuF8, ApuF9, ApuFA, ApuFB, ApuFC, ApuFD, ApuFE, ApuFF
2527 };
2528
2529 #endif