2 * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
4 * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and
5 * Jerremy Koot (jkoot@snes9x.com)
7 * Super FX C emulator code
8 * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and
10 * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_.
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).
16 * DOS port code contains the works of other authors. See headers in
19 * Snes9x homepage: http://www.snes9x.com
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.
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.
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.
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
38 * Super NES and Super Nintendo Entertainment System are trademarks of
39 * Nintendo Co., Limited and its subsidiary companies.
47 // SPC700/Sound DSP chips have a 24.57MHz crystal on their PCB.
49 #if defined(ASM_SPC700)
51 // we only need the memhandlers
53 #define INLINE extern "C"
58 #if defined(NO_INLINE_SET_GET)
59 uint8 S9xAPUGetByteZ (uint8 address);
60 uint8 S9xAPUGetByte (uint32 address);
61 void S9xAPUSetByteZ (uint8, uint8 address);
62 void S9xAPUSetByte (uint8, uint32 address);
73 extern signed char Int8;
82 #define OP1 (*(IAPU.PC + 1))
83 #define OP2 (*(IAPU.PC + 2))
85 #ifdef SPC700_SHUTDOWN
86 #define APUShutdown() \
87 if (Settings.Shutdown && (IAPU.PC == IAPU.WaitAddress1 || IAPU.PC == IAPU.WaitAddress2)) \
89 if (IAPU.WaitCounter == 0) \
91 if (!ICPU.CPUExecuting) \
92 CPU.APU_Cycles = CPU.Cycles = CPU.NextEvent; \
94 CPU.APU_APUExecuting = FALSE; \
97 if (IAPU.WaitCounter >= 2) \
98 IAPU.WaitCounter = 1; \
100 IAPU.WaitCounter--; \
103 #define APUShutdown()
106 #define APUSetZN8(b)\
109 #define APUSetZN16(w)\
110 IAPU._Zero = ((w) != 0) | ((w) >> 8);
117 S9xAPUOPrint (buffer, IAPU.PC - IAPU.RAM);
120 sprintf (String, "Sound CPU in unknown state executing %s at 0x%tx\n%s\n", s, IAPU.PC - IAPU.RAM, buffer);
121 S9xMessage (S9X_ERROR, S9X_APU_STOPPED, String);
122 APU.TimerEnabled[0] = APU.TimerEnabled[1] = APU.TimerEnabled[2] = FALSE;
123 CPU.APU_APUExecuting = FALSE;
126 CPU.Flags |= DEBUG_MODE_FLAG;
134 PushW ((IAPU.PC - IAPU.RAM + 1)); \
135 IAPU.PC = IAPU.RAM + (APU.ExtraRAM [((15 - n) << 1)] + \
136 (APU.ExtraRAM [((15 - n) << 1) + 1] << 8)); \
139 // XXX: HalfCarry - BJ fixed?
141 Int16 = (short) (a) - (short) (b) + (short) (APUCheckCarry ()) - 1;\
142 IAPU._Carry = Int16 >= 0;\
143 if ((((a) ^ (b)) & 0x80) && (((a) ^ (uint8) Int16) & 0x80))\
146 APUClearOverflow (); \
148 if(((a) ^ (b) ^ (uint8) Int16) & 0x10)\
149 APUClearHalfCarry ();\
150 (a) = (uint8) Int16;\
151 APUSetZN8 ((uint8) Int16);
153 // XXX: HalfCarry - BJ fixed?
155 Work16 = (a) + (b) + APUCheckCarry();\
156 IAPU._Carry = Work16 >= 0x100; \
157 if (~((a) ^ (b)) & ((b) ^ (uint8) Work16) & 0x80)\
160 APUClearOverflow (); \
161 APUClearHalfCarry ();\
162 /*if(((a) ^ (b) ^ (uint8) Int16) & 0x10) notaz: Int16!? */\
163 if(((a) ^ (b) ^ (uint8) Work16) & 0x10)\
165 (a) = (uint8) Work16;\
166 APUSetZN8 ((uint8) Work16);
169 Int16 = (short) (a) - (short) (b);\
170 IAPU._Carry = Int16 >= 0;\
171 APUSetZN8 ((uint8) Int16);
174 IAPU._Carry = ((b) & 0x80) != 0; \
178 IAPU._Carry = (b) & 1;\
182 Work16 = ((b) << 1) | APUCheckCarry (); \
183 IAPU._Carry = Work16 >= 0x100; \
184 (b) = (uint8) Work16; \
187 Work16 = (b) | ((uint16) APUCheckCarry () << 8); \
188 IAPU._Carry = (uint8) Work16 & 1; \
190 (b) = (uint8) Work16; \
194 *(IAPU.RAM + 0x100 + IAPU.S) = b;\
199 (b) = *(IAPU.RAM + 0x100 + IAPU.S);
201 #ifdef FAST_LSB_WORD_ACCESS
203 *(uint16 *) (IAPU.RAM + 0xff + IAPU.S) = w;\
207 w = *(uint16 *) (IAPU.RAM + 0xff + IAPU.S);
210 *(IAPU.RAM + 0xff + IAPU.S) = w;\
211 *(IAPU.RAM + 0x100 + IAPU.S) = (w >> 8);\
215 (w) = *(IAPU.RAM + 0xff + IAPU.S) + (*(IAPU.RAM + 0x100 + IAPU.S) << 8);
220 Int16 = (int) (IAPU.PC + 2 - IAPU.RAM) + Int8;
224 Int16 = (int) (IAPU.PC + 3 - IAPU.RAM) + Int8;
226 #ifdef FAST_LSB_WORD_ACCESS
227 #define IndexedXIndirect()\
228 IAPU.Address = *(uint16 *) (IAPU.DirectPage + ((OP1 + IAPU.X) & 0xff));
231 IAPU.Address = *(uint16 *) (IAPU.PC + 1);
234 IAPU.Address = *(uint16 *) (IAPU.PC + 1) + IAPU.X;
237 IAPU.Address = *(uint16 *) (IAPU.PC + 1) + IAPU.YA.B.Y;
240 IAPU.Address = *(uint16 *) (IAPU.PC + 1);\
241 IAPU.Bit = (uint8)(IAPU.Address >> 13);\
242 IAPU.Address &= 0x1fff;
244 #define IndirectIndexedY()\
245 IAPU.Address = *(uint16 *) (IAPU.DirectPage + OP1) + IAPU.YA.B.Y;
247 #define IndexedXIndirect()\
248 IAPU.Address = *(IAPU.DirectPage + ((OP1 + IAPU.X) & 0xff)) + \
249 (*(IAPU.DirectPage + ((OP1 + IAPU.X + 1) & 0xff)) << 8);
251 IAPU.Address = OP1 + (OP2 << 8);
254 IAPU.Address = OP1 + (OP2 << 8) + IAPU.X;
257 IAPU.Address = OP1 + (OP2 << 8) + IAPU.YA.B.Y;
260 IAPU.Address = OP1 + (OP2 << 8);\
261 IAPU.Bit = (int8) (IAPU.Address >> 13);\
262 IAPU.Address &= 0x1fff;
264 #define IndirectIndexedY()\
265 IAPU.Address = *(IAPU.DirectPage + OP1) + \
266 (*(IAPU.DirectPage + OP1 + 1) << 8) + \
276 void Apu01 () { TCALL (0) }
278 void Apu11 () { TCALL (1) }
280 void Apu21 () { TCALL (2) }
282 void Apu31 () { TCALL (3) }
284 void Apu41 () { TCALL (4) }
286 void Apu51 () { TCALL (5) }
288 void Apu61 () { TCALL (6) }
290 void Apu71 () { TCALL (7) }
292 void Apu81 () { TCALL (8) }
294 void Apu91 () { TCALL (9) }
296 void ApuA1 () { TCALL (10) }
298 void ApuB1 () { TCALL (11) }
300 void ApuC1 () { TCALL (12) }
302 void ApuD1 () { TCALL (13) }
304 void ApuE1 () { TCALL (14) }
306 void ApuF1 () { TCALL (15) }
308 void Apu3F () // CALL absolute
311 // 0xB6f for Star Fox 2
312 PushW ((IAPU.PC + 3 - IAPU.RAM));
313 IAPU.PC = IAPU.RAM + IAPU.Address;
316 void Apu4F () // PCALL $XX
319 PushW ((IAPU.PC + 2 - IAPU.RAM));
320 IAPU.PC = IAPU.RAM + 0xff00 + Work8;
324 S9xAPUSetByteZ ((uint8) (S9xAPUGetByteZ (OP1 ) | (1 << (b))), OP1); \
368 S9xAPUSetByteZ ((uint8) (S9xAPUGetByteZ (OP1) & ~(1 << (b))), OP1); \
414 if (S9xAPUGetByteZ (Work8) & (1 << (b))) \
416 IAPU.PC = IAPU.RAM + (uint16) Int16; \
417 CPU.APU_Cycles += IAPU.TwoCycles; \
465 if (!(S9xAPUGetByteZ (Work8) & (1 << (b)))) \
467 IAPU.PC = IAPU.RAM + (uint16) Int16; \
468 CPU.APU_Cycles += IAPU.TwoCycles; \
516 IAPU.YA.B.A |= S9xAPUGetByteZ (OP1);
517 APUSetZN8 (IAPU.YA.B.A);
525 IAPU.YA.B.A |= S9xAPUGetByte (IAPU.Address);
526 APUSetZN8 (IAPU.YA.B.A);
533 IAPU.YA.B.A |= S9xAPUGetByteZ (IAPU.X);
534 APUSetZN8 (IAPU.YA.B.A);
542 IAPU.YA.B.A |= S9xAPUGetByte (IAPU.Address);
543 APUSetZN8 (IAPU.YA.B.A);
551 APUSetZN8 (IAPU.YA.B.A);
557 // OR dp(dest),dp(src)
558 Work8 = S9xAPUGetByteZ (OP1);
559 Work8 |= S9xAPUGetByteZ (OP2);
560 S9xAPUSetByteZ (Work8, OP2);
568 IAPU.YA.B.A |= S9xAPUGetByteZ (OP1 + IAPU.X);
569 APUSetZN8 (IAPU.YA.B.A);
577 IAPU.YA.B.A |= S9xAPUGetByte (IAPU.Address);
578 APUSetZN8 (IAPU.YA.B.A);
586 IAPU.YA.B.A |= S9xAPUGetByte (IAPU.Address);
587 APUSetZN8 (IAPU.YA.B.A);
595 IAPU.YA.B.A |= S9xAPUGetByte (IAPU.Address);
596 APUSetZN8 (IAPU.YA.B.A);
604 Work8 |= S9xAPUGetByteZ (OP2);
605 S9xAPUSetByteZ (Work8, OP2);
613 Work8 = S9xAPUGetByteZ (IAPU.X) | S9xAPUGetByteZ (IAPU.YA.B.Y);
615 S9xAPUSetByteZ (Work8, IAPU.X);
623 if (!APUCheckCarry ())
625 if (S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit))
635 if (!APUCheckCarry ())
637 if (!(S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit)))
647 if (APUCheckCarry ())
649 if (!(S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit)))
657 // AND1 C, not membit
659 if (APUCheckCarry ())
661 if ((S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit)))
671 if (APUCheckCarry ())
673 if (S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit))
678 if (S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit))
688 if (S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit))
699 if (APUCheckCarry ())
701 S9xAPUSetByte (S9xAPUGetByte (IAPU.Address) | (1 << IAPU.Bit), IAPU.Address);
705 S9xAPUSetByte (S9xAPUGetByte (IAPU.Address) & ~(1 << IAPU.Bit), IAPU.Address);
714 S9xAPUSetByte (S9xAPUGetByte (IAPU.Address) ^ (1 << IAPU.Bit), IAPU.Address);
721 Work8 = S9xAPUGetByteZ (OP1);
723 S9xAPUSetByteZ (Work8, OP1);
731 Work8 = S9xAPUGetByte (IAPU.Address);
733 S9xAPUSetByte (Work8, IAPU.Address);
740 Work8 = S9xAPUGetByteZ (OP1 + IAPU.X);
742 S9xAPUSetByteZ (Work8, OP1 + IAPU.X);
786 S9xAPUUnpackStatus ();
787 if (APUCheckDirectPage ())
788 IAPU.DirectPage = IAPU.RAM + 0x100;
790 IAPU.DirectPage = IAPU.RAM;
819 Work8 = S9xAPUGetByte (IAPU.Address);
820 S9xAPUSetByte (Work8 | IAPU.YA.B.A, IAPU.Address);
821 Work8 &= IAPU.YA.B.A;
830 Work8 = S9xAPUGetByte (IAPU.Address);
831 S9xAPUSetByte (Work8 & ~IAPU.YA.B.A, IAPU.Address);
832 Work8 &= IAPU.YA.B.A;
844 PushW ((IAPU.PC + 1 - IAPU.RAM));
848 APUClearInterrupt ();
849 // XXX:Where is the BRK vector ???
850 IAPU.PC = IAPU.RAM + APU.ExtraRAM[0x20] + (APU.ExtraRAM[0x21] << 8);
859 CPU.APU_APUExecuting = FALSE;
867 CPU.APU_APUExecuting = FALSE;
875 if (!APUCheckNegative ())
877 IAPU.PC = IAPU.RAM + (uint16) Int16;
878 CPU.APU_Cycles += IAPU.TwoCycles;
889 if (APUCheckNegative ())
891 IAPU.PC = IAPU.RAM + (uint16) Int16;
892 CPU.APU_Cycles += IAPU.TwoCycles;
903 if (!APUCheckCarry ())
905 IAPU.PC = IAPU.RAM + (uint16) Int16;
906 CPU.APU_Cycles += IAPU.TwoCycles;
917 if (APUCheckCarry ())
919 IAPU.PC = IAPU.RAM + (uint16) Int16;
920 CPU.APU_Cycles += IAPU.TwoCycles;
931 if (!APUCheckZero ())
933 IAPU.PC = IAPU.RAM + (uint16) Int16;
934 CPU.APU_Cycles += IAPU.TwoCycles;
947 IAPU.PC = IAPU.RAM + (uint16) Int16;
948 CPU.APU_Cycles += IAPU.TwoCycles;
959 if (!APUCheckOverflow ())
961 IAPU.PC = IAPU.RAM + (uint16) Int16;
962 CPU.APU_Cycles += IAPU.TwoCycles;
972 if (APUCheckOverflow ())
974 IAPU.PC = IAPU.RAM + (uint16) Int16;
975 CPU.APU_Cycles += IAPU.TwoCycles;
985 IAPU.PC = IAPU.RAM + (uint16) Int16;
1005 APUSetDirectPage ();
1006 IAPU.DirectPage = IAPU.RAM + 0x100;
1013 Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8);
1015 S9xAPUSetByteZ ((uint8) Work16, OP1);
1016 S9xAPUSetByteZ (Work16 >> 8, OP1 + 1);
1017 APUSetZN16 (Work16);
1024 Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8);
1025 Int32 = (long) IAPU.YA.W - (long) Work16;
1026 IAPU._Carry = Int32 >= 0;
1027 APUSetZN16 ((uint16) Int32);
1034 Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8);
1036 S9xAPUSetByteZ ((uint8) Work16, OP1);
1037 S9xAPUSetByteZ (Work16 >> 8, OP1 + 1);
1038 APUSetZN16 (Work16);
1042 // XXX: HalfCarry - BJ Fixed? Or is it between bits 7 and 8 for ADDW/SUBW?
1046 Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8);
1047 Work32 = (uint32) IAPU.YA.W + Work16;
1048 IAPU._Carry = Work32 >= 0x10000;
1049 if (~(IAPU.YA.W ^ Work16) & (Work16 ^ (uint16) Work32) & 0x8000)
1052 APUClearOverflow ();
1053 APUClearHalfCarry ();
1054 if((IAPU.YA.W ^ Work16 ^ (uint16) Work32) & 0x10)
1056 IAPU.YA.W = (uint16) Work32;
1057 APUSetZN16 (IAPU.YA.W);
1061 // XXX: BJ: i think the old HalfCarry behavior was wrong...
1062 // XXX: Or is it between bits 7 and 8 for ADDW/SUBW?
1066 Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8);
1067 Int32 = (long) IAPU.YA.W - (long) Work16;
1068 APUClearHalfCarry ();
1069 IAPU._Carry = Int32 >= 0;
1070 if (((IAPU.YA.W ^ Work16) & 0x8000) &&
1071 ((IAPU.YA.W ^ (uint16) Int32) & 0x8000))
1074 APUClearOverflow ();
1075 // if (((IAPU.YA.W ^ Work16) & 0x0080) &&
1076 // ((IAPU.YA.W ^ (uint16) Int32) & 0x0080))
1077 // APUSetHalfCarry (); // notaz: strange here
1079 // if((IAPU.YA.W ^ Work16 ^ (uint16) Work32) & 0x10) // notaz: Work32?!
1080 if((IAPU.YA.W ^ Work16 ^ (uint16) Int32) & 0x10)
1081 APUClearHalfCarry ();
1082 IAPU.YA.W = (uint16) Int32;
1083 APUSetZN16 (IAPU.YA.W);
1090 IAPU.YA.B.A = S9xAPUGetByteZ (OP1);
1091 IAPU.YA.B.Y = S9xAPUGetByteZ (OP1 + 1);
1092 APUSetZN16 (IAPU.YA.W);
1099 S9xAPUSetByteZ (IAPU.YA.B.A, OP1);
1100 S9xAPUSetByteZ (IAPU.YA.B.Y, OP1 + 1);
1107 Work8 = S9xAPUGetByteZ (OP1);
1108 CMP (IAPU.YA.B.A, Work8);
1116 Work8 = S9xAPUGetByte (IAPU.Address);
1117 CMP (IAPU.YA.B.A, Work8);
1124 Work8 = S9xAPUGetByteZ (IAPU.X);
1125 CMP (IAPU.YA.B.A, Work8);
1132 IndexedXIndirect ();
1133 Work8 = S9xAPUGetByte (IAPU.Address);
1134 CMP (IAPU.YA.B.A, Work8);
1142 CMP (IAPU.YA.B.A, Work8);
1148 // CMP dp(dest), dp(src)
1149 W1 = S9xAPUGetByteZ (OP1);
1150 Work8 = S9xAPUGetByteZ (OP2);
1158 Work8 = S9xAPUGetByteZ (OP1 + IAPU.X);
1159 CMP (IAPU.YA.B.A, Work8);
1167 Work8 = S9xAPUGetByte (IAPU.Address);
1168 CMP (IAPU.YA.B.A, Work8);
1176 Work8 = S9xAPUGetByte (IAPU.Address);
1177 CMP (IAPU.YA.B.A, Work8);
1184 IndirectIndexedY ();
1185 Work8 = S9xAPUGetByte (IAPU.Address);
1186 CMP (IAPU.YA.B.A, Work8);
1194 W1 = S9xAPUGetByteZ (OP2);
1202 W1 = S9xAPUGetByteZ (IAPU.X);
1203 Work8 = S9xAPUGetByteZ (IAPU.YA.B.Y);
1212 Work8 = S9xAPUGetByte (IAPU.Address);
1213 CMP (IAPU.X, Work8);
1220 Work8 = S9xAPUGetByteZ (OP1);
1221 CMP (IAPU.X, Work8);
1236 Work8 = S9xAPUGetByte (IAPU.Address);
1237 CMP (IAPU.YA.B.Y, Work8);
1244 Work8 = S9xAPUGetByteZ (OP1);
1245 CMP (IAPU.YA.B.Y, Work8);
1253 CMP (IAPU.YA.B.Y, Work8);
1261 IAPU.PC = IAPU.RAM + S9xAPUGetByte (IAPU.Address + IAPU.X) +
1262 (S9xAPUGetByte (IAPU.Address + IAPU.X + 1) << 8);
1264 // APU.Flags |= TRACE_FLAG;
1271 IAPU.PC = IAPU.RAM + IAPU.Address;
1277 APUClearDirectPage ();
1278 IAPU.DirectPage = IAPU.RAM;
1292 APUClearHalfCarry ();
1293 APUClearOverflow ();
1300 IAPU.YA.B.A &= S9xAPUGetByteZ (OP1);
1301 APUSetZN8 (IAPU.YA.B.A);
1309 IAPU.YA.B.A &= S9xAPUGetByte (IAPU.Address);
1310 APUSetZN8 (IAPU.YA.B.A);
1317 IAPU.YA.B.A &= S9xAPUGetByteZ (IAPU.X);
1318 APUSetZN8 (IAPU.YA.B.A);
1325 IndexedXIndirect ();
1326 IAPU.YA.B.A &= S9xAPUGetByte (IAPU.Address);
1327 APUSetZN8 (IAPU.YA.B.A);
1335 APUSetZN8 (IAPU.YA.B.A);
1341 // AND dp(dest),dp(src)
1342 Work8 = S9xAPUGetByteZ (OP1);
1343 Work8 &= S9xAPUGetByteZ (OP2);
1344 S9xAPUSetByteZ (Work8, OP2);
1352 IAPU.YA.B.A &= S9xAPUGetByteZ (OP1 + IAPU.X);
1353 APUSetZN8 (IAPU.YA.B.A);
1361 IAPU.YA.B.A &= S9xAPUGetByte (IAPU.Address);
1362 APUSetZN8 (IAPU.YA.B.A);
1370 IAPU.YA.B.A &= S9xAPUGetByte (IAPU.Address);
1371 APUSetZN8 (IAPU.YA.B.A);
1378 IndirectIndexedY ();
1379 IAPU.YA.B.A &= S9xAPUGetByte (IAPU.Address);
1380 APUSetZN8 (IAPU.YA.B.A);
1388 Work8 &= S9xAPUGetByteZ (OP2);
1389 S9xAPUSetByteZ (Work8, OP2);
1397 Work8 = S9xAPUGetByteZ (IAPU.X) & S9xAPUGetByteZ (IAPU.YA.B.Y);
1399 S9xAPUSetByteZ (Work8, IAPU.X);
1406 Work8 = S9xAPUGetByteZ (OP1);
1408 S9xAPUSetByteZ (Work8, OP1);
1416 Work8 = S9xAPUGetByte (IAPU.Address);
1418 S9xAPUSetByte (Work8, IAPU.Address);
1425 Work8 = S9xAPUGetByteZ (OP1 + IAPU.X);
1427 S9xAPUSetByteZ (Work8, OP1 + IAPU.X);
1444 if (S9xAPUGetByteZ (Work8) != IAPU.YA.B.A)
1446 IAPU.PC = IAPU.RAM + (uint16) Int16;
1447 CPU.APU_Cycles += IAPU.TwoCycles;
1457 Work8 = OP1 + IAPU.X;
1460 if (S9xAPUGetByteZ (Work8) != IAPU.YA.B.A)
1462 IAPU.PC = IAPU.RAM + (uint16) Int16;
1463 CPU.APU_Cycles += IAPU.TwoCycles;
1476 #ifdef SPC700_SHUTDOWN
1487 APUSetZN8 (IAPU.YA.B.Y);
1489 #ifdef SPC700_SHUTDOWN
1502 #ifdef SPC700_SHUTDOWN
1513 APUSetZN8 (IAPU.YA.B.Y);
1515 #ifdef SPC700_SHUTDOWN
1525 Work8 = S9xAPUGetByteZ (OP1) + 1;
1526 S9xAPUSetByteZ (Work8, OP1);
1529 #ifdef SPC700_SHUTDOWN
1540 Work8 = S9xAPUGetByte (IAPU.Address) + 1;
1541 S9xAPUSetByte (Work8, IAPU.Address);
1544 #ifdef SPC700_SHUTDOWN
1554 Work8 = S9xAPUGetByteZ (OP1 + IAPU.X) + 1;
1555 S9xAPUSetByteZ (Work8, OP1 + IAPU.X);
1558 #ifdef SPC700_SHUTDOWN
1569 APUSetZN8 (IAPU.YA.B.A);
1571 #ifdef SPC700_SHUTDOWN
1581 Work8 = S9xAPUGetByteZ (OP1) - 1;
1582 S9xAPUSetByteZ (Work8, OP1);
1585 #ifdef SPC700_SHUTDOWN
1596 Work8 = S9xAPUGetByte (IAPU.Address) - 1;
1597 S9xAPUSetByte (Work8, IAPU.Address);
1600 #ifdef SPC700_SHUTDOWN
1610 Work8 = S9xAPUGetByteZ (OP1 + IAPU.X) - 1;
1611 S9xAPUSetByteZ (Work8, OP1 + IAPU.X);
1614 #ifdef SPC700_SHUTDOWN
1625 APUSetZN8 (IAPU.YA.B.A);
1627 #ifdef SPC700_SHUTDOWN
1637 IAPU.YA.B.A ^= S9xAPUGetByteZ (OP1);
1638 APUSetZN8 (IAPU.YA.B.A);
1646 IAPU.YA.B.A ^= S9xAPUGetByte (IAPU.Address);
1647 APUSetZN8 (IAPU.YA.B.A);
1654 IAPU.YA.B.A ^= S9xAPUGetByteZ (IAPU.X);
1655 APUSetZN8 (IAPU.YA.B.A);
1662 IndexedXIndirect ();
1663 IAPU.YA.B.A ^= S9xAPUGetByte (IAPU.Address);
1664 APUSetZN8 (IAPU.YA.B.A);
1672 APUSetZN8 (IAPU.YA.B.A);
1678 // EOR dp(dest),dp(src)
1679 Work8 = S9xAPUGetByteZ (OP1);
1680 Work8 ^= S9xAPUGetByteZ (OP2);
1681 S9xAPUSetByteZ (Work8, OP2);
1689 IAPU.YA.B.A ^= S9xAPUGetByteZ (OP1 + IAPU.X);
1690 APUSetZN8 (IAPU.YA.B.A);
1698 IAPU.YA.B.A ^= S9xAPUGetByte (IAPU.Address);
1699 APUSetZN8 (IAPU.YA.B.A);
1707 IAPU.YA.B.A ^= S9xAPUGetByte (IAPU.Address);
1708 APUSetZN8 (IAPU.YA.B.A);
1715 IndirectIndexedY ();
1716 IAPU.YA.B.A ^= S9xAPUGetByte (IAPU.Address);
1717 APUSetZN8 (IAPU.YA.B.A);
1725 Work8 ^= S9xAPUGetByteZ (OP2);
1726 S9xAPUSetByteZ (Work8, OP2);
1734 Work8 = S9xAPUGetByteZ (IAPU.X) ^ S9xAPUGetByteZ (IAPU.YA.B.Y);
1736 S9xAPUSetByteZ (Work8, IAPU.X);
1743 Work8 = S9xAPUGetByteZ (OP1);
1745 S9xAPUSetByteZ (Work8, OP1);
1753 Work8 = S9xAPUGetByte (IAPU.Address);
1755 S9xAPUSetByte (Work8, IAPU.Address);
1762 Work8 = S9xAPUGetByteZ (OP1 + IAPU.X);
1764 S9xAPUSetByteZ (Work8, OP1 + IAPU.X);
1778 IAPU.YA.B.A = IAPU.X;
1779 APUSetZN8 (IAPU.YA.B.A);
1786 IAPU.YA.B.A = IAPU.YA.B.Y;
1787 APUSetZN8 (IAPU.YA.B.A);
1794 IAPU.X = IAPU.YA.B.A;
1802 IAPU.YA.B.Y = IAPU.YA.B.A;
1803 APUSetZN8 (IAPU.YA.B.Y);
1825 Work8 = S9xAPUGetByteZ (OP1);
1827 S9xAPUSetByteZ (Work8, OP1);
1835 Work8 = S9xAPUGetByte (IAPU.Address);
1837 S9xAPUSetByte (Work8, IAPU.Address);
1844 Work8 = S9xAPUGetByteZ (OP1 + IAPU.X);
1846 S9xAPUSetByteZ (Work8, OP1 + IAPU.X);
1862 W1 = S9xAPUGetByteZ (Work8) - 1;
1863 S9xAPUSetByteZ (W1, Work8);
1866 IAPU.PC = IAPU.RAM + (uint16) Int16;
1867 CPU.APU_Cycles += IAPU.TwoCycles;
1878 if (IAPU.YA.B.Y != 0)
1880 IAPU.PC = IAPU.RAM + (uint16) Int16;
1881 CPU.APU_Cycles += IAPU.TwoCycles;
1891 IAPU.PC = IAPU.RAM + Work16;
1899 S9xAPUUnpackStatus ();
1901 IAPU.PC = IAPU.RAM + Work16;
1907 Work8 = S9xAPUGetByteZ (OP1);
1908 ADC (IAPU.YA.B.A, Work8);
1916 Work8 = S9xAPUGetByte (IAPU.Address);
1917 ADC (IAPU.YA.B.A, Work8);
1924 Work8 = S9xAPUGetByteZ (IAPU.X);
1925 ADC (IAPU.YA.B.A, Work8);
1932 IndexedXIndirect ();
1933 Work8 = S9xAPUGetByte (IAPU.Address);
1934 ADC (IAPU.YA.B.A, Work8);
1942 ADC (IAPU.YA.B.A, Work8);
1948 // ADC dp(dest),dp(src)
1949 Work8 = S9xAPUGetByteZ (OP1);
1950 W1 = S9xAPUGetByteZ (OP2);
1952 S9xAPUSetByteZ (W1, OP2);
1959 Work8 = S9xAPUGetByteZ (OP1 + IAPU.X);
1960 ADC (IAPU.YA.B.A, Work8);
1968 Work8 = S9xAPUGetByte (IAPU.Address);
1969 ADC (IAPU.YA.B.A, Work8);
1977 Work8 = S9xAPUGetByte (IAPU.Address);
1978 ADC (IAPU.YA.B.A, Work8);
1985 IndirectIndexedY ();
1986 Work8 = S9xAPUGetByte (IAPU.Address);
1987 ADC (IAPU.YA.B.A, Work8);
1995 W1 = S9xAPUGetByteZ (OP2);
1997 S9xAPUSetByteZ (W1, OP2);
2004 W1 = S9xAPUGetByteZ (IAPU.X);
2005 Work8 = S9xAPUGetByteZ (IAPU.YA.B.Y);
2007 S9xAPUSetByteZ (W1, IAPU.X);
2015 APUSetZN8 (IAPU.YA.B.Y);
2023 S9xAPUSetByteZ (Work8, OP2);
2038 APUClearOverflow ();
2039 Work8 = IAPU.YA.W / IAPU.X;
2040 IAPU.YA.B.Y = IAPU.YA.W % IAPU.X;
2041 IAPU.YA.B.A = Work8;
2043 // XXX How should Overflow, Half Carry, Zero and Negative flags be set??
2044 // APUSetZN16 (IAPU.YA.W);
2045 APUSetZN8 (IAPU.YA.B.A);
2052 IAPU.YA.B.A = (IAPU.YA.B.A >> 4) | (IAPU.YA.B.A << 4);
2053 APUSetZN8 (IAPU.YA.B.A);
2060 Work8 = S9xAPUGetByteZ (OP1);
2061 SBC (IAPU.YA.B.A, Work8);
2069 Work8 = S9xAPUGetByte (IAPU.Address);
2070 SBC (IAPU.YA.B.A, Work8);
2077 Work8 = S9xAPUGetByteZ (IAPU.X);
2078 SBC (IAPU.YA.B.A, Work8);
2085 IndexedXIndirect ();
2086 Work8 = S9xAPUGetByte (IAPU.Address);
2087 SBC (IAPU.YA.B.A, Work8);
2095 SBC (IAPU.YA.B.A, Work8);
2101 // SBC dp(dest), dp(src)
2102 Work8 = S9xAPUGetByteZ (OP1);
2103 W1 = S9xAPUGetByteZ (OP2);
2105 S9xAPUSetByteZ (W1, OP2);
2112 Work8 = S9xAPUGetByteZ (OP1 + IAPU.X);
2113 SBC (IAPU.YA.B.A, Work8);
2121 Work8 = S9xAPUGetByte (IAPU.Address);
2122 SBC (IAPU.YA.B.A, Work8);
2130 Work8 = S9xAPUGetByte (IAPU.Address);
2131 SBC (IAPU.YA.B.A, Work8);
2138 IndirectIndexedY ();
2139 Work8 = S9xAPUGetByte (IAPU.Address);
2140 SBC (IAPU.YA.B.A, Work8);
2148 W1 = S9xAPUGetByteZ (OP2);
2150 S9xAPUSetByteZ (W1, OP2);
2157 W1 = S9xAPUGetByteZ (IAPU.X);
2158 Work8 = S9xAPUGetByteZ (IAPU.YA.B.Y);
2160 S9xAPUSetByteZ (W1, IAPU.X);
2167 S9xAPUSetByteZ (IAPU.YA.B.A, IAPU.X++);
2174 if ((IAPU.YA.B.A & 0x0f) > 9 || !APUCheckHalfCarry())
2178 if (IAPU.YA.B.A > 0x9f || !IAPU._Carry)
2180 IAPU.YA.B.A -= 0x60;
2183 else { APUSetCarry (); }
2184 APUSetZN8 (IAPU.YA.B.A);
2191 IAPU.YA.B.A = S9xAPUGetByteZ (IAPU.X++);
2192 APUSetZN8 (IAPU.YA.B.A);
2199 APUClearInterrupt ();
2213 S9xAPUSetByteZ (IAPU.YA.B.A, OP1);
2221 S9xAPUSetByte (IAPU.YA.B.A, IAPU.Address);
2228 S9xAPUSetByteZ (IAPU.YA.B.A, IAPU.X);
2235 IndexedXIndirect ();
2236 S9xAPUSetByte (IAPU.YA.B.A, IAPU.Address);
2244 S9xAPUSetByte (IAPU.X, IAPU.Address);
2251 S9xAPUSetByteZ (IAPU.YA.B.Y, OP1);
2259 S9xAPUSetByte (IAPU.YA.B.Y, IAPU.Address);
2274 IAPU.YA.W = (uint16) IAPU.YA.B.A * IAPU.YA.B.Y;
2275 APUSetZN16 (IAPU.YA.W);
2282 S9xAPUSetByteZ (IAPU.YA.B.A, OP1 + IAPU.X);
2290 S9xAPUSetByte (IAPU.YA.B.A, IAPU.Address);
2298 S9xAPUSetByte (IAPU.YA.B.A, IAPU.Address);
2305 IndirectIndexedY ();
2306 S9xAPUSetByte (IAPU.YA.B.A, IAPU.Address);
2313 S9xAPUSetByteZ (IAPU.X, OP1);
2320 S9xAPUSetByteZ (IAPU.X, OP1 + IAPU.YA.B.Y);
2327 S9xAPUSetByteZ (IAPU.YA.B.Y, OP1 + IAPU.X);
2334 if ((IAPU.YA.B.A & 0x0f) > 9 || APUCheckHalfCarry())
2336 if(IAPU.YA.B.A > 0xf0) APUSetCarry ();
2338 //APUSetHalfCarry (); Intel procs do this, but this is a Sony proc...
2340 //else { APUClearHalfCarry (); } ditto as above
2341 if (IAPU.YA.B.A > 0x9f || IAPU._Carry)
2343 IAPU.YA.B.A += 0x60;
2346 else { APUClearCarry (); }
2347 APUSetZN8 (IAPU.YA.B.A);
2354 IAPU.YA.B.A = S9xAPUGetByteZ (OP1);
2355 APUSetZN8 (IAPU.YA.B.A);
2363 IAPU.YA.B.A = S9xAPUGetByte (IAPU.Address);
2364 APUSetZN8 (IAPU.YA.B.A);
2371 IAPU.YA.B.A = S9xAPUGetByteZ (IAPU.X);
2372 APUSetZN8 (IAPU.YA.B.A);
2379 IndexedXIndirect ();
2380 IAPU.YA.B.A = S9xAPUGetByte (IAPU.Address);
2381 APUSetZN8 (IAPU.YA.B.A);
2389 APUSetZN8 (IAPU.YA.B.A);
2397 IAPU.X = S9xAPUGetByte (IAPU.Address);
2405 IAPU.YA.B.Y = S9xAPUGetByteZ (OP1);
2406 APUSetZN8 (IAPU.YA.B.Y);
2414 IAPU.YA.B.Y = S9xAPUGetByte (IAPU.Address);
2415 APUSetZN8 (IAPU.YA.B.Y);
2422 IAPU.YA.B.A = S9xAPUGetByteZ (OP1 + IAPU.X);
2423 APUSetZN8 (IAPU.YA.B.A);
2431 IAPU.YA.B.A = S9xAPUGetByte (IAPU.Address);
2432 APUSetZN8 (IAPU.YA.B.A);
2440 IAPU.YA.B.A = S9xAPUGetByte (IAPU.Address);
2441 APUSetZN8 (IAPU.YA.B.A);
2448 IndirectIndexedY ();
2449 IAPU.YA.B.A = S9xAPUGetByte (IAPU.Address);
2450 APUSetZN8 (IAPU.YA.B.A);
2457 IAPU.X = S9xAPUGetByteZ (OP1);
2465 IAPU.X = S9xAPUGetByteZ (OP1 + IAPU.YA.B.Y);
2472 // MOV dp(dest),dp(src)
2473 S9xAPUSetByteZ (S9xAPUGetByteZ (OP1), OP2);
2480 IAPU.YA.B.Y = S9xAPUGetByteZ (OP1 + IAPU.X);
2481 APUSetZN8 (IAPU.YA.B.Y);
2485 #if defined(NO_INLINE_SET_GET)
2492 void (*S9xApuOpcodes[256]) (void) =
2494 Apu00, Apu01, Apu02, Apu03, Apu04, Apu05, Apu06, Apu07,
2495 Apu08, Apu09, Apu0A, Apu0B, Apu0C, Apu0D, Apu0E, Apu0F,
2496 Apu10, Apu11, Apu12, Apu13, Apu14, Apu15, Apu16, Apu17,
2497 Apu18, Apu19, Apu1A, Apu1B, Apu1C, Apu1D, Apu1E, Apu1F,
2498 Apu20, Apu21, Apu22, Apu23, Apu24, Apu25, Apu26, Apu27,
2499 Apu28, Apu29, Apu2A, Apu2B, Apu2C, Apu2D, Apu2E, Apu2F,
2500 Apu30, Apu31, Apu32, Apu33, Apu34, Apu35, Apu36, Apu37,
2501 Apu38, Apu39, Apu3A, Apu3B, Apu3C, Apu3D, Apu3E, Apu3F,
2502 Apu40, Apu41, Apu42, Apu43, Apu44, Apu45, Apu46, Apu47,
2503 Apu48, Apu49, Apu4A, Apu4B, Apu4C, Apu4D, Apu4E, Apu4F,
2504 Apu50, Apu51, Apu52, Apu53, Apu54, Apu55, Apu56, Apu57,
2505 Apu58, Apu59, Apu5A, Apu5B, Apu5C, Apu5D, Apu5E, Apu5F,
2506 Apu60, Apu61, Apu62, Apu63, Apu64, Apu65, Apu66, Apu67,
2507 Apu68, Apu69, Apu6A, Apu6B, Apu6C, Apu6D, Apu6E, Apu6F,
2508 Apu70, Apu71, Apu72, Apu73, Apu74, Apu75, Apu76, Apu77,
2509 Apu78, Apu79, Apu7A, Apu7B, Apu7C, Apu7D, Apu7E, Apu7F,
2510 Apu80, Apu81, Apu82, Apu83, Apu84, Apu85, Apu86, Apu87,
2511 Apu88, Apu89, Apu8A, Apu8B, Apu8C, Apu8D, Apu8E, Apu8F,
2512 Apu90, Apu91, Apu92, Apu93, Apu94, Apu95, Apu96, Apu97,
2513 Apu98, Apu99, Apu9A, Apu9B, Apu9C, Apu9D, Apu9E, Apu9F,
2514 ApuA0, ApuA1, ApuA2, ApuA3, ApuA4, ApuA5, ApuA6, ApuA7,
2515 ApuA8, ApuA9, ApuAA, ApuAB, ApuAC, ApuAD, ApuAE, ApuAF,
2516 ApuB0, ApuB1, ApuB2, ApuB3, ApuB4, ApuB5, ApuB6, ApuB7,
2517 ApuB8, ApuB9, ApuBA, ApuBB, ApuBC, ApuBD, ApuBE, ApuBF,
2518 ApuC0, ApuC1, ApuC2, ApuC3, ApuC4, ApuC5, ApuC6, ApuC7,
2519 ApuC8, ApuC9, ApuCA, ApuCB, ApuCC, ApuCD, ApuCE, ApuCF,
2520 ApuD0, ApuD1, ApuD2, ApuD3, ApuD4, ApuD5, ApuD6, ApuD7,
2521 ApuD8, ApuD9, ApuDA, ApuDB, ApuDC, ApuDD, ApuDE, ApuDF,
2522 ApuE0, ApuE1, ApuE2, ApuE3, ApuE4, ApuE5, ApuE6, ApuE7,
2523 ApuE8, ApuE9, ApuEA, ApuEB, ApuEC, ApuED, ApuEE, ApuEF,
2524 ApuF0, ApuF1, ApuF2, ApuF3, ApuF4, ApuF5, ApuF6, ApuF7,
2525 ApuF8, ApuF9, ApuFA, ApuFB, ApuFC, ApuFD, ApuFE, ApuFF