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.
48 // SPC700/Sound DSP chips have a 24.57MHz crystal on their PCB.
50 #if defined(ASM_SPC700)
52 // we only need the memhandlers
54 #define INLINE extern "C"
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);
74 extern signed char Int8;
83 #define OP1 (*(IAPU.PC + 1))
84 #define OP2 (*(IAPU.PC + 2))
86 #ifdef SPC700_SHUTDOWN
87 #define APUShutdown() \
88 if (Settings.Shutdown && (IAPU.PC == IAPU.WaitAddress1 || IAPU.PC == IAPU.WaitAddress2)) \
90 if (IAPU.WaitCounter == 0) \
92 if (!ICPU.CPUExecuting) \
93 CPU.APU_Cycles = CPU.Cycles = CPU.NextEvent; \
95 CPU.APU_APUExecuting = FALSE; \
98 if (IAPU.WaitCounter >= 2) \
99 IAPU.WaitCounter = 1; \
101 IAPU.WaitCounter--; \
104 #define APUShutdown()
107 #define APUSetZN8(b)\
110 #define APUSetZN16(w)\
111 IAPU._Zero = ((w) != 0) | ((w) >> 8);
118 S9xAPUOPrint (buffer, IAPU.PC - IAPU.RAM);
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;
127 CPU.Flags |= DEBUG_MODE_FLAG;
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)); \
140 // XXX: HalfCarry - BJ fixed?
142 Int16 = (short) (a) - (short) (b) + (short) (APUCheckCarry ()) - 1;\
143 IAPU._Carry = Int16 >= 0;\
144 if ((((a) ^ (b)) & 0x80) && (((a) ^ (uint8) Int16) & 0x80))\
147 APUClearOverflow (); \
149 if(((a) ^ (b) ^ (uint8) Int16) & 0x10)\
150 APUClearHalfCarry ();\
151 (a) = (uint8) Int16;\
152 APUSetZN8 ((uint8) Int16);
154 // XXX: HalfCarry - BJ fixed?
156 Work16 = (a) + (b) + APUCheckCarry();\
157 IAPU._Carry = Work16 >= 0x100; \
158 if (~((a) ^ (b)) & ((b) ^ (uint8) Work16) & 0x80)\
161 APUClearOverflow (); \
162 APUClearHalfCarry ();\
163 /*if(((a) ^ (b) ^ (uint8) Int16) & 0x10) notaz: Int16!? */\
164 if(((a) ^ (b) ^ (uint8) Work16) & 0x10)\
166 (a) = (uint8) Work16;\
167 APUSetZN8 ((uint8) Work16);
170 Int16 = (short) (a) - (short) (b);\
171 IAPU._Carry = Int16 >= 0;\
172 APUSetZN8 ((uint8) Int16);
175 IAPU._Carry = ((b) & 0x80) != 0; \
179 IAPU._Carry = (b) & 1;\
183 Work16 = ((b) << 1) | APUCheckCarry (); \
184 IAPU._Carry = Work16 >= 0x100; \
185 (b) = (uint8) Work16; \
188 Work16 = (b) | ((uint16) APUCheckCarry () << 8); \
189 IAPU._Carry = (uint8) Work16 & 1; \
191 (b) = (uint8) Work16; \
195 *(IAPU.RAM + 0x100 + IAPU.S) = b;\
200 (b) = *(IAPU.RAM + 0x100 + IAPU.S);
202 #ifdef FAST_LSB_WORD_ACCESS
204 *(uint16 *) (IAPU.RAM + 0xff + IAPU.S) = w;\
208 w = *(uint16 *) (IAPU.RAM + 0xff + IAPU.S);
211 *(IAPU.RAM + 0xff + IAPU.S) = w;\
212 *(IAPU.RAM + 0x100 + IAPU.S) = (w >> 8);\
216 (w) = *(IAPU.RAM + 0xff + IAPU.S) + (*(IAPU.RAM + 0x100 + IAPU.S) << 8);
221 Int16 = (int) (IAPU.PC + 2 - IAPU.RAM) + Int8;
225 Int16 = (int) (IAPU.PC + 3 - IAPU.RAM) + Int8;
227 #ifdef FAST_LSB_WORD_ACCESS
228 #define IndexedXIndirect()\
229 IAPU.Address = *(uint16 *) (IAPU.DirectPage + ((OP1 + IAPU.X) & 0xff));
232 IAPU.Address = *(uint16 *) (IAPU.PC + 1);
235 IAPU.Address = *(uint16 *) (IAPU.PC + 1) + IAPU.X;
238 IAPU.Address = *(uint16 *) (IAPU.PC + 1) + IAPU.YA.B.Y;
241 IAPU.Address = *(uint16 *) (IAPU.PC + 1);\
242 IAPU.Bit = (uint8)(IAPU.Address >> 13);\
243 IAPU.Address &= 0x1fff;
245 #define IndirectIndexedY()\
246 IAPU.Address = *(uint16 *) (IAPU.DirectPage + OP1) + IAPU.YA.B.Y;
248 #define IndexedXIndirect()\
249 IAPU.Address = *(IAPU.DirectPage + ((OP1 + IAPU.X) & 0xff)) + \
250 (*(IAPU.DirectPage + ((OP1 + IAPU.X + 1) & 0xff)) << 8);
252 IAPU.Address = OP1 + (OP2 << 8);
255 IAPU.Address = OP1 + (OP2 << 8) + IAPU.X;
258 IAPU.Address = OP1 + (OP2 << 8) + IAPU.YA.B.Y;
261 IAPU.Address = OP1 + (OP2 << 8);\
262 IAPU.Bit = (int8) (IAPU.Address >> 13);\
263 IAPU.Address &= 0x1fff;
265 #define IndirectIndexedY()\
266 IAPU.Address = *(IAPU.DirectPage + OP1) + \
267 (*(IAPU.DirectPage + OP1 + 1) << 8) + \
277 void Apu01 () { TCALL (0) }
279 void Apu11 () { TCALL (1) }
281 void Apu21 () { TCALL (2) }
283 void Apu31 () { TCALL (3) }
285 void Apu41 () { TCALL (4) }
287 void Apu51 () { TCALL (5) }
289 void Apu61 () { TCALL (6) }
291 void Apu71 () { TCALL (7) }
293 void Apu81 () { TCALL (8) }
295 void Apu91 () { TCALL (9) }
297 void ApuA1 () { TCALL (10) }
299 void ApuB1 () { TCALL (11) }
301 void ApuC1 () { TCALL (12) }
303 void ApuD1 () { TCALL (13) }
305 void ApuE1 () { TCALL (14) }
307 void ApuF1 () { TCALL (15) }
309 void Apu3F () // CALL absolute
312 // 0xB6f for Star Fox 2
313 PushW ((IAPU.PC + 3 - IAPU.RAM));
314 IAPU.PC = IAPU.RAM + IAPU.Address;
317 void Apu4F () // PCALL $XX
320 PushW ((IAPU.PC + 2 - IAPU.RAM));
321 IAPU.PC = IAPU.RAM + 0xff00 + Work8;
325 S9xAPUSetByteZ ((uint8) (S9xAPUGetByteZ (OP1 ) | (1 << (b))), OP1); \
369 S9xAPUSetByteZ ((uint8) (S9xAPUGetByteZ (OP1) & ~(1 << (b))), OP1); \
415 if (S9xAPUGetByteZ (Work8) & (1 << (b))) \
417 IAPU.PC = IAPU.RAM + (uint16) Int16; \
418 CPU.APU_Cycles += IAPU.TwoCycles; \
466 if (!(S9xAPUGetByteZ (Work8) & (1 << (b)))) \
468 IAPU.PC = IAPU.RAM + (uint16) Int16; \
469 CPU.APU_Cycles += IAPU.TwoCycles; \
517 IAPU.YA.B.A |= S9xAPUGetByteZ (OP1);
518 APUSetZN8 (IAPU.YA.B.A);
526 IAPU.YA.B.A |= S9xAPUGetByte (IAPU.Address);
527 APUSetZN8 (IAPU.YA.B.A);
534 IAPU.YA.B.A |= S9xAPUGetByteZ (IAPU.X);
535 APUSetZN8 (IAPU.YA.B.A);
543 IAPU.YA.B.A |= S9xAPUGetByte (IAPU.Address);
544 APUSetZN8 (IAPU.YA.B.A);
552 APUSetZN8 (IAPU.YA.B.A);
558 // OR dp(dest),dp(src)
559 Work8 = S9xAPUGetByteZ (OP1);
560 Work8 |= S9xAPUGetByteZ (OP2);
561 S9xAPUSetByteZ (Work8, OP2);
569 IAPU.YA.B.A |= S9xAPUGetByteZ (OP1 + IAPU.X);
570 APUSetZN8 (IAPU.YA.B.A);
578 IAPU.YA.B.A |= S9xAPUGetByte (IAPU.Address);
579 APUSetZN8 (IAPU.YA.B.A);
587 IAPU.YA.B.A |= S9xAPUGetByte (IAPU.Address);
588 APUSetZN8 (IAPU.YA.B.A);
596 IAPU.YA.B.A |= S9xAPUGetByte (IAPU.Address);
597 APUSetZN8 (IAPU.YA.B.A);
605 Work8 |= S9xAPUGetByteZ (OP2);
606 S9xAPUSetByteZ (Work8, OP2);
614 Work8 = S9xAPUGetByteZ (IAPU.X) | S9xAPUGetByteZ (IAPU.YA.B.Y);
616 S9xAPUSetByteZ (Work8, IAPU.X);
624 if (!APUCheckCarry ())
626 if (S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit))
636 if (!APUCheckCarry ())
638 if (!(S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit)))
648 if (APUCheckCarry ())
650 if (!(S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit)))
658 // AND1 C, not membit
660 if (APUCheckCarry ())
662 if ((S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit)))
672 if (APUCheckCarry ())
674 if (S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit))
679 if (S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit))
689 if (S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit))
700 if (APUCheckCarry ())
702 S9xAPUSetByte (S9xAPUGetByte (IAPU.Address) | (1 << IAPU.Bit), IAPU.Address);
706 S9xAPUSetByte (S9xAPUGetByte (IAPU.Address) & ~(1 << IAPU.Bit), IAPU.Address);
715 S9xAPUSetByte (S9xAPUGetByte (IAPU.Address) ^ (1 << IAPU.Bit), IAPU.Address);
722 Work8 = S9xAPUGetByteZ (OP1);
724 S9xAPUSetByteZ (Work8, OP1);
732 Work8 = S9xAPUGetByte (IAPU.Address);
734 S9xAPUSetByte (Work8, IAPU.Address);
741 Work8 = S9xAPUGetByteZ (OP1 + IAPU.X);
743 S9xAPUSetByteZ (Work8, OP1 + IAPU.X);
787 S9xAPUUnpackStatus ();
788 if (APUCheckDirectPage ())
789 IAPU.DirectPage = IAPU.RAM + 0x100;
791 IAPU.DirectPage = IAPU.RAM;
820 Work8 = S9xAPUGetByte (IAPU.Address);
821 S9xAPUSetByte (Work8 | IAPU.YA.B.A, IAPU.Address);
822 Work8 &= IAPU.YA.B.A;
831 Work8 = S9xAPUGetByte (IAPU.Address);
832 S9xAPUSetByte (Work8 & ~IAPU.YA.B.A, IAPU.Address);
833 Work8 &= IAPU.YA.B.A;
845 PushW ((IAPU.PC + 1 - IAPU.RAM));
849 APUClearInterrupt ();
850 // XXX:Where is the BRK vector ???
851 IAPU.PC = IAPU.RAM + APU.ExtraRAM[0x20] + (APU.ExtraRAM[0x21] << 8);
860 CPU.APU_APUExecuting = FALSE;
868 CPU.APU_APUExecuting = FALSE;
876 if (!APUCheckNegative ())
878 IAPU.PC = IAPU.RAM + (uint16) Int16;
879 CPU.APU_Cycles += IAPU.TwoCycles;
890 if (APUCheckNegative ())
892 IAPU.PC = IAPU.RAM + (uint16) Int16;
893 CPU.APU_Cycles += IAPU.TwoCycles;
904 if (!APUCheckCarry ())
906 IAPU.PC = IAPU.RAM + (uint16) Int16;
907 CPU.APU_Cycles += IAPU.TwoCycles;
918 if (APUCheckCarry ())
920 IAPU.PC = IAPU.RAM + (uint16) Int16;
921 CPU.APU_Cycles += IAPU.TwoCycles;
932 if (!APUCheckZero ())
934 IAPU.PC = IAPU.RAM + (uint16) Int16;
935 CPU.APU_Cycles += IAPU.TwoCycles;
948 IAPU.PC = IAPU.RAM + (uint16) Int16;
949 CPU.APU_Cycles += IAPU.TwoCycles;
960 if (!APUCheckOverflow ())
962 IAPU.PC = IAPU.RAM + (uint16) Int16;
963 CPU.APU_Cycles += IAPU.TwoCycles;
973 if (APUCheckOverflow ())
975 IAPU.PC = IAPU.RAM + (uint16) Int16;
976 CPU.APU_Cycles += IAPU.TwoCycles;
986 IAPU.PC = IAPU.RAM + (uint16) Int16;
1006 APUSetDirectPage ();
1007 IAPU.DirectPage = IAPU.RAM + 0x100;
1014 Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8);
1016 S9xAPUSetByteZ ((uint8) Work16, OP1);
1017 S9xAPUSetByteZ (Work16 >> 8, OP1 + 1);
1018 APUSetZN16 (Work16);
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);
1035 Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8);
1037 S9xAPUSetByteZ ((uint8) Work16, OP1);
1038 S9xAPUSetByteZ (Work16 >> 8, OP1 + 1);
1039 APUSetZN16 (Work16);
1043 // XXX: HalfCarry - BJ Fixed? Or is it between bits 7 and 8 for ADDW/SUBW?
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)
1053 APUClearOverflow ();
1054 APUClearHalfCarry ();
1055 if((IAPU.YA.W ^ Work16 ^ (uint16) Work32) & 0x10)
1057 IAPU.YA.W = (uint16) Work32;
1058 APUSetZN16 (IAPU.YA.W);
1062 // XXX: BJ: i think the old HalfCarry behavior was wrong...
1063 // XXX: Or is it between bits 7 and 8 for ADDW/SUBW?
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))
1075 APUClearOverflow ();
1076 // if (((IAPU.YA.W ^ Work16) & 0x0080) &&
1077 // ((IAPU.YA.W ^ (uint16) Int32) & 0x0080))
1078 // APUSetHalfCarry (); // notaz: strange here
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);
1091 IAPU.YA.B.A = S9xAPUGetByteZ (OP1);
1092 IAPU.YA.B.Y = S9xAPUGetByteZ (OP1 + 1);
1093 APUSetZN16 (IAPU.YA.W);
1100 S9xAPUSetByteZ (IAPU.YA.B.A, OP1);
1101 S9xAPUSetByteZ (IAPU.YA.B.Y, OP1 + 1);
1108 Work8 = S9xAPUGetByteZ (OP1);
1109 CMP (IAPU.YA.B.A, Work8);
1117 Work8 = S9xAPUGetByte (IAPU.Address);
1118 CMP (IAPU.YA.B.A, Work8);
1125 Work8 = S9xAPUGetByteZ (IAPU.X);
1126 CMP (IAPU.YA.B.A, Work8);
1133 IndexedXIndirect ();
1134 Work8 = S9xAPUGetByte (IAPU.Address);
1135 CMP (IAPU.YA.B.A, Work8);
1143 CMP (IAPU.YA.B.A, Work8);
1149 // CMP dp(dest), dp(src)
1150 W1 = S9xAPUGetByteZ (OP1);
1151 Work8 = S9xAPUGetByteZ (OP2);
1159 Work8 = S9xAPUGetByteZ (OP1 + IAPU.X);
1160 CMP (IAPU.YA.B.A, Work8);
1168 Work8 = S9xAPUGetByte (IAPU.Address);
1169 CMP (IAPU.YA.B.A, Work8);
1177 Work8 = S9xAPUGetByte (IAPU.Address);
1178 CMP (IAPU.YA.B.A, Work8);
1185 IndirectIndexedY ();
1186 Work8 = S9xAPUGetByte (IAPU.Address);
1187 CMP (IAPU.YA.B.A, Work8);
1195 W1 = S9xAPUGetByteZ (OP2);
1203 W1 = S9xAPUGetByteZ (IAPU.X);
1204 Work8 = S9xAPUGetByteZ (IAPU.YA.B.Y);
1213 Work8 = S9xAPUGetByte (IAPU.Address);
1214 CMP (IAPU.X, Work8);
1221 Work8 = S9xAPUGetByteZ (OP1);
1222 CMP (IAPU.X, Work8);
1237 Work8 = S9xAPUGetByte (IAPU.Address);
1238 CMP (IAPU.YA.B.Y, Work8);
1245 Work8 = S9xAPUGetByteZ (OP1);
1246 CMP (IAPU.YA.B.Y, Work8);
1254 CMP (IAPU.YA.B.Y, Work8);
1262 IAPU.PC = IAPU.RAM + S9xAPUGetByte (IAPU.Address + IAPU.X) +
1263 (S9xAPUGetByte (IAPU.Address + IAPU.X + 1) << 8);
1265 // APU.Flags |= TRACE_FLAG;
1272 IAPU.PC = IAPU.RAM + IAPU.Address;
1278 APUClearDirectPage ();
1279 IAPU.DirectPage = IAPU.RAM;
1293 APUClearHalfCarry ();
1294 APUClearOverflow ();
1301 IAPU.YA.B.A &= S9xAPUGetByteZ (OP1);
1302 APUSetZN8 (IAPU.YA.B.A);
1310 IAPU.YA.B.A &= S9xAPUGetByte (IAPU.Address);
1311 APUSetZN8 (IAPU.YA.B.A);
1318 IAPU.YA.B.A &= S9xAPUGetByteZ (IAPU.X);
1319 APUSetZN8 (IAPU.YA.B.A);
1326 IndexedXIndirect ();
1327 IAPU.YA.B.A &= S9xAPUGetByte (IAPU.Address);
1328 APUSetZN8 (IAPU.YA.B.A);
1336 APUSetZN8 (IAPU.YA.B.A);
1342 // AND dp(dest),dp(src)
1343 Work8 = S9xAPUGetByteZ (OP1);
1344 Work8 &= S9xAPUGetByteZ (OP2);
1345 S9xAPUSetByteZ (Work8, OP2);
1353 IAPU.YA.B.A &= S9xAPUGetByteZ (OP1 + IAPU.X);
1354 APUSetZN8 (IAPU.YA.B.A);
1362 IAPU.YA.B.A &= S9xAPUGetByte (IAPU.Address);
1363 APUSetZN8 (IAPU.YA.B.A);
1371 IAPU.YA.B.A &= S9xAPUGetByte (IAPU.Address);
1372 APUSetZN8 (IAPU.YA.B.A);
1379 IndirectIndexedY ();
1380 IAPU.YA.B.A &= S9xAPUGetByte (IAPU.Address);
1381 APUSetZN8 (IAPU.YA.B.A);
1389 Work8 &= S9xAPUGetByteZ (OP2);
1390 S9xAPUSetByteZ (Work8, OP2);
1398 Work8 = S9xAPUGetByteZ (IAPU.X) & S9xAPUGetByteZ (IAPU.YA.B.Y);
1400 S9xAPUSetByteZ (Work8, IAPU.X);
1407 Work8 = S9xAPUGetByteZ (OP1);
1409 S9xAPUSetByteZ (Work8, OP1);
1417 Work8 = S9xAPUGetByte (IAPU.Address);
1419 S9xAPUSetByte (Work8, IAPU.Address);
1426 Work8 = S9xAPUGetByteZ (OP1 + IAPU.X);
1428 S9xAPUSetByteZ (Work8, OP1 + IAPU.X);
1445 if (S9xAPUGetByteZ (Work8) != IAPU.YA.B.A)
1447 IAPU.PC = IAPU.RAM + (uint16) Int16;
1448 CPU.APU_Cycles += IAPU.TwoCycles;
1458 Work8 = OP1 + IAPU.X;
1461 if (S9xAPUGetByteZ (Work8) != IAPU.YA.B.A)
1463 IAPU.PC = IAPU.RAM + (uint16) Int16;
1464 CPU.APU_Cycles += IAPU.TwoCycles;
1477 #ifdef SPC700_SHUTDOWN
1488 APUSetZN8 (IAPU.YA.B.Y);
1490 #ifdef SPC700_SHUTDOWN
1503 #ifdef SPC700_SHUTDOWN
1514 APUSetZN8 (IAPU.YA.B.Y);
1516 #ifdef SPC700_SHUTDOWN
1526 Work8 = S9xAPUGetByteZ (OP1) + 1;
1527 S9xAPUSetByteZ (Work8, OP1);
1530 #ifdef SPC700_SHUTDOWN
1541 Work8 = S9xAPUGetByte (IAPU.Address) + 1;
1542 S9xAPUSetByte (Work8, IAPU.Address);
1545 #ifdef SPC700_SHUTDOWN
1555 Work8 = S9xAPUGetByteZ (OP1 + IAPU.X) + 1;
1556 S9xAPUSetByteZ (Work8, OP1 + IAPU.X);
1559 #ifdef SPC700_SHUTDOWN
1570 APUSetZN8 (IAPU.YA.B.A);
1572 #ifdef SPC700_SHUTDOWN
1582 Work8 = S9xAPUGetByteZ (OP1) - 1;
1583 S9xAPUSetByteZ (Work8, OP1);
1586 #ifdef SPC700_SHUTDOWN
1597 Work8 = S9xAPUGetByte (IAPU.Address) - 1;
1598 S9xAPUSetByte (Work8, IAPU.Address);
1601 #ifdef SPC700_SHUTDOWN
1611 Work8 = S9xAPUGetByteZ (OP1 + IAPU.X) - 1;
1612 S9xAPUSetByteZ (Work8, OP1 + IAPU.X);
1615 #ifdef SPC700_SHUTDOWN
1626 APUSetZN8 (IAPU.YA.B.A);
1628 #ifdef SPC700_SHUTDOWN
1638 IAPU.YA.B.A ^= S9xAPUGetByteZ (OP1);
1639 APUSetZN8 (IAPU.YA.B.A);
1647 IAPU.YA.B.A ^= S9xAPUGetByte (IAPU.Address);
1648 APUSetZN8 (IAPU.YA.B.A);
1655 IAPU.YA.B.A ^= S9xAPUGetByteZ (IAPU.X);
1656 APUSetZN8 (IAPU.YA.B.A);
1663 IndexedXIndirect ();
1664 IAPU.YA.B.A ^= S9xAPUGetByte (IAPU.Address);
1665 APUSetZN8 (IAPU.YA.B.A);
1673 APUSetZN8 (IAPU.YA.B.A);
1679 // EOR dp(dest),dp(src)
1680 Work8 = S9xAPUGetByteZ (OP1);
1681 Work8 ^= S9xAPUGetByteZ (OP2);
1682 S9xAPUSetByteZ (Work8, OP2);
1690 IAPU.YA.B.A ^= S9xAPUGetByteZ (OP1 + IAPU.X);
1691 APUSetZN8 (IAPU.YA.B.A);
1699 IAPU.YA.B.A ^= S9xAPUGetByte (IAPU.Address);
1700 APUSetZN8 (IAPU.YA.B.A);
1708 IAPU.YA.B.A ^= S9xAPUGetByte (IAPU.Address);
1709 APUSetZN8 (IAPU.YA.B.A);
1716 IndirectIndexedY ();
1717 IAPU.YA.B.A ^= S9xAPUGetByte (IAPU.Address);
1718 APUSetZN8 (IAPU.YA.B.A);
1726 Work8 ^= S9xAPUGetByteZ (OP2);
1727 S9xAPUSetByteZ (Work8, OP2);
1735 Work8 = S9xAPUGetByteZ (IAPU.X) ^ S9xAPUGetByteZ (IAPU.YA.B.Y);
1737 S9xAPUSetByteZ (Work8, IAPU.X);
1744 Work8 = S9xAPUGetByteZ (OP1);
1746 S9xAPUSetByteZ (Work8, OP1);
1754 Work8 = S9xAPUGetByte (IAPU.Address);
1756 S9xAPUSetByte (Work8, IAPU.Address);
1763 Work8 = S9xAPUGetByteZ (OP1 + IAPU.X);
1765 S9xAPUSetByteZ (Work8, OP1 + IAPU.X);
1779 IAPU.YA.B.A = IAPU.X;
1780 APUSetZN8 (IAPU.YA.B.A);
1787 IAPU.YA.B.A = IAPU.YA.B.Y;
1788 APUSetZN8 (IAPU.YA.B.A);
1795 IAPU.X = IAPU.YA.B.A;
1803 IAPU.YA.B.Y = IAPU.YA.B.A;
1804 APUSetZN8 (IAPU.YA.B.Y);
1826 Work8 = S9xAPUGetByteZ (OP1);
1828 S9xAPUSetByteZ (Work8, OP1);
1836 Work8 = S9xAPUGetByte (IAPU.Address);
1838 S9xAPUSetByte (Work8, IAPU.Address);
1845 Work8 = S9xAPUGetByteZ (OP1 + IAPU.X);
1847 S9xAPUSetByteZ (Work8, OP1 + IAPU.X);
1863 W1 = S9xAPUGetByteZ (Work8) - 1;
1864 S9xAPUSetByteZ (W1, Work8);
1867 IAPU.PC = IAPU.RAM + (uint16) Int16;
1868 CPU.APU_Cycles += IAPU.TwoCycles;
1879 if (IAPU.YA.B.Y != 0)
1881 IAPU.PC = IAPU.RAM + (uint16) Int16;
1882 CPU.APU_Cycles += IAPU.TwoCycles;
1892 IAPU.PC = IAPU.RAM + Work16;
1900 S9xAPUUnpackStatus ();
1902 IAPU.PC = IAPU.RAM + Work16;
1908 Work8 = S9xAPUGetByteZ (OP1);
1909 ADC (IAPU.YA.B.A, Work8);
1917 Work8 = S9xAPUGetByte (IAPU.Address);
1918 ADC (IAPU.YA.B.A, Work8);
1925 Work8 = S9xAPUGetByteZ (IAPU.X);
1926 ADC (IAPU.YA.B.A, Work8);
1933 IndexedXIndirect ();
1934 Work8 = S9xAPUGetByte (IAPU.Address);
1935 ADC (IAPU.YA.B.A, Work8);
1943 ADC (IAPU.YA.B.A, Work8);
1949 // ADC dp(dest),dp(src)
1950 Work8 = S9xAPUGetByteZ (OP1);
1951 W1 = S9xAPUGetByteZ (OP2);
1953 S9xAPUSetByteZ (W1, OP2);
1960 Work8 = S9xAPUGetByteZ (OP1 + IAPU.X);
1961 ADC (IAPU.YA.B.A, Work8);
1969 Work8 = S9xAPUGetByte (IAPU.Address);
1970 ADC (IAPU.YA.B.A, Work8);
1978 Work8 = S9xAPUGetByte (IAPU.Address);
1979 ADC (IAPU.YA.B.A, Work8);
1986 IndirectIndexedY ();
1987 Work8 = S9xAPUGetByte (IAPU.Address);
1988 ADC (IAPU.YA.B.A, Work8);
1996 W1 = S9xAPUGetByteZ (OP2);
1998 S9xAPUSetByteZ (W1, OP2);
2005 W1 = S9xAPUGetByteZ (IAPU.X);
2006 Work8 = S9xAPUGetByteZ (IAPU.YA.B.Y);
2008 S9xAPUSetByteZ (W1, IAPU.X);
2016 APUSetZN8 (IAPU.YA.B.Y);
2024 S9xAPUSetByteZ (Work8, OP2);
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;
2044 // XXX How should Overflow, Half Carry, Zero and Negative flags be set??
2045 // APUSetZN16 (IAPU.YA.W);
2046 APUSetZN8 (IAPU.YA.B.A);
2053 IAPU.YA.B.A = (IAPU.YA.B.A >> 4) | (IAPU.YA.B.A << 4);
2054 APUSetZN8 (IAPU.YA.B.A);
2061 Work8 = S9xAPUGetByteZ (OP1);
2062 SBC (IAPU.YA.B.A, Work8);
2070 Work8 = S9xAPUGetByte (IAPU.Address);
2071 SBC (IAPU.YA.B.A, Work8);
2078 Work8 = S9xAPUGetByteZ (IAPU.X);
2079 SBC (IAPU.YA.B.A, Work8);
2086 IndexedXIndirect ();
2087 Work8 = S9xAPUGetByte (IAPU.Address);
2088 SBC (IAPU.YA.B.A, Work8);
2096 SBC (IAPU.YA.B.A, Work8);
2102 // SBC dp(dest), dp(src)
2103 Work8 = S9xAPUGetByteZ (OP1);
2104 W1 = S9xAPUGetByteZ (OP2);
2106 S9xAPUSetByteZ (W1, OP2);
2113 Work8 = S9xAPUGetByteZ (OP1 + IAPU.X);
2114 SBC (IAPU.YA.B.A, Work8);
2122 Work8 = S9xAPUGetByte (IAPU.Address);
2123 SBC (IAPU.YA.B.A, Work8);
2131 Work8 = S9xAPUGetByte (IAPU.Address);
2132 SBC (IAPU.YA.B.A, Work8);
2139 IndirectIndexedY ();
2140 Work8 = S9xAPUGetByte (IAPU.Address);
2141 SBC (IAPU.YA.B.A, Work8);
2149 W1 = S9xAPUGetByteZ (OP2);
2151 S9xAPUSetByteZ (W1, OP2);
2158 W1 = S9xAPUGetByteZ (IAPU.X);
2159 Work8 = S9xAPUGetByteZ (IAPU.YA.B.Y);
2161 S9xAPUSetByteZ (W1, IAPU.X);
2168 S9xAPUSetByteZ (IAPU.YA.B.A, IAPU.X++);
2175 if ((IAPU.YA.B.A & 0x0f) > 9 || !APUCheckHalfCarry())
2179 if (IAPU.YA.B.A > 0x9f || !IAPU._Carry)
2181 IAPU.YA.B.A -= 0x60;
2184 else { APUSetCarry (); }
2185 APUSetZN8 (IAPU.YA.B.A);
2192 IAPU.YA.B.A = S9xAPUGetByteZ (IAPU.X++);
2193 APUSetZN8 (IAPU.YA.B.A);
2200 APUClearInterrupt ();
2214 S9xAPUSetByteZ (IAPU.YA.B.A, OP1);
2222 S9xAPUSetByte (IAPU.YA.B.A, IAPU.Address);
2229 S9xAPUSetByteZ (IAPU.YA.B.A, IAPU.X);
2236 IndexedXIndirect ();
2237 S9xAPUSetByte (IAPU.YA.B.A, IAPU.Address);
2245 S9xAPUSetByte (IAPU.X, IAPU.Address);
2252 S9xAPUSetByteZ (IAPU.YA.B.Y, OP1);
2260 S9xAPUSetByte (IAPU.YA.B.Y, IAPU.Address);
2275 IAPU.YA.W = (uint16) IAPU.YA.B.A * IAPU.YA.B.Y;
2276 APUSetZN16 (IAPU.YA.W);
2283 S9xAPUSetByteZ (IAPU.YA.B.A, OP1 + IAPU.X);
2291 S9xAPUSetByte (IAPU.YA.B.A, IAPU.Address);
2299 S9xAPUSetByte (IAPU.YA.B.A, IAPU.Address);
2306 IndirectIndexedY ();
2307 S9xAPUSetByte (IAPU.YA.B.A, IAPU.Address);
2314 S9xAPUSetByteZ (IAPU.X, OP1);
2321 S9xAPUSetByteZ (IAPU.X, OP1 + IAPU.YA.B.Y);
2328 S9xAPUSetByteZ (IAPU.YA.B.Y, OP1 + IAPU.X);
2335 if ((IAPU.YA.B.A & 0x0f) > 9 || APUCheckHalfCarry())
2337 if(IAPU.YA.B.A > 0xf0) APUSetCarry ();
2339 //APUSetHalfCarry (); Intel procs do this, but this is a Sony proc...
2341 //else { APUClearHalfCarry (); } ditto as above
2342 if (IAPU.YA.B.A > 0x9f || IAPU._Carry)
2344 IAPU.YA.B.A += 0x60;
2347 else { APUClearCarry (); }
2348 APUSetZN8 (IAPU.YA.B.A);
2355 IAPU.YA.B.A = S9xAPUGetByteZ (OP1);
2356 APUSetZN8 (IAPU.YA.B.A);
2364 IAPU.YA.B.A = S9xAPUGetByte (IAPU.Address);
2365 APUSetZN8 (IAPU.YA.B.A);
2372 IAPU.YA.B.A = S9xAPUGetByteZ (IAPU.X);
2373 APUSetZN8 (IAPU.YA.B.A);
2380 IndexedXIndirect ();
2381 IAPU.YA.B.A = S9xAPUGetByte (IAPU.Address);
2382 APUSetZN8 (IAPU.YA.B.A);
2390 APUSetZN8 (IAPU.YA.B.A);
2398 IAPU.X = S9xAPUGetByte (IAPU.Address);
2406 IAPU.YA.B.Y = S9xAPUGetByteZ (OP1);
2407 APUSetZN8 (IAPU.YA.B.Y);
2415 IAPU.YA.B.Y = S9xAPUGetByte (IAPU.Address);
2416 APUSetZN8 (IAPU.YA.B.Y);
2423 IAPU.YA.B.A = S9xAPUGetByteZ (OP1 + IAPU.X);
2424 APUSetZN8 (IAPU.YA.B.A);
2432 IAPU.YA.B.A = S9xAPUGetByte (IAPU.Address);
2433 APUSetZN8 (IAPU.YA.B.A);
2441 IAPU.YA.B.A = S9xAPUGetByte (IAPU.Address);
2442 APUSetZN8 (IAPU.YA.B.A);
2449 IndirectIndexedY ();
2450 IAPU.YA.B.A = S9xAPUGetByte (IAPU.Address);
2451 APUSetZN8 (IAPU.YA.B.A);
2458 IAPU.X = S9xAPUGetByteZ (OP1);
2466 IAPU.X = S9xAPUGetByteZ (OP1 + IAPU.YA.B.Y);
2473 // MOV dp(dest),dp(src)
2474 S9xAPUSetByteZ (S9xAPUGetByteZ (OP1), OP2);
2481 IAPU.YA.B.Y = S9xAPUGetByteZ (OP1 + IAPU.X);
2482 APUSetZN8 (IAPU.YA.B.Y);
2486 #if defined(NO_INLINE_SET_GET)
2493 void (*S9xApuOpcodes[256]) (void) =
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