From 6fb0c7a7a53e1eba7a0f5dc5b1ade312a0d76119 Mon Sep 17 00:00:00 2001 From: Toad King Date: Thu, 14 Jun 2012 03:21:06 -0400 Subject: initial pocketsnes commit --- src/spc700/debug/spc700.cpp | 2600 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2600 insertions(+) create mode 100644 src/spc700/debug/spc700.cpp (limited to 'src/spc700/debug/spc700.cpp') diff --git a/src/spc700/debug/spc700.cpp b/src/spc700/debug/spc700.cpp new file mode 100644 index 0000000..5ab21ab --- /dev/null +++ b/src/spc700/debug/spc700.cpp @@ -0,0 +1,2600 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#include "snes9x.h" +#include "memmap.h" +#include "display.h" +#include "cpuexec.h" +#include "apu.h" +#include "spc700.h" + +// SPC700/Sound DSP chips have a 24.57MHz crystal on their PCB. + +//#if defined(ASM_SPC700) +extern "C" { +uint8 S9xAPUGetByteZ (uint8 address); +uint8 S9xAPUGetByte (uint32 address); +void S9xAPUSetByteZ (uint8, uint8 address); +void S9xAPUSetByte (uint8, uint32 address); +} +/* +#elif defined(NO_INLINE_SET_GET) +uint8 S9xAPUGetByteZ (uint8 address); +uint8 S9xAPUGetByte (uint32 address); +void S9xAPUSetByteZ (uint8, uint8 address); +void S9xAPUSetByte (uint8, uint32 address); + +#else +#undef INLINE +#define INLINE inline +#include "apumem.h" +#endif +*/ + +START_EXTERN_C +extern uint8 Work8; +extern uint16 Work16; +extern uint32 Work32; +extern signed char Int8; +extern short Int16; +extern long Int32; +extern short Int16; +extern uint8 W1; +extern uint8 W2; + +END_EXTERN_C + +#define OP1 (*(pIAPU->PC + 1)) +#define OP2 (*(pIAPU->PC + 2)) + +#ifdef SPC700_SHUTDOWN +#define APUShutdown() \ + if (Settings.Shutdown && (pIAPU->PC == pIAPU->WaitAddress1 || pIAPU->PC == pIAPU->WaitAddress2)) \ + { \ + if (pIAPU->WaitCounter == 0) \ + { \ + if (!ICPU.CPUExecuting) \ + CPU.APU_Cycles = CPU.Cycles = CPU.NextEvent; \ + else \ + CPU.APU_APUExecuting = FALSE; \ + } \ + else \ + if (pIAPU->WaitCounter >= 2) \ + pIAPU->WaitCounter = 1; \ + else \ + pIAPU->WaitCounter--; \ + } +#else +#define APUShutdown() +#endif + +#define APUSetZN8(b)\ + pIAPU->_Zero = (b); + +#define APUSetZN16(w)\ + pIAPU->_Zero = ((w) != 0) | ((w) >> 8); + +void STOP (char *s) +{ + char buffer[100]; + +#ifdef DEBUGGER + S9xAPUOPrint (buffer, pIAPU->PC - pIAPU->RAM); +#endif + + sprintf (String, "Sound CPU in unknown state executing %s at %04lX\n%s\n", s, pIAPU->PC - pIAPU->RAM, buffer); + S9xMessage (S9X_ERROR, S9X_APU_STOPPED, String); + APU.TimerEnabled[0] = APU.TimerEnabled[1] = APU.TimerEnabled[2] = FALSE; + CPU.APU_APUExecuting = FALSE; + +#ifdef DEBUGGER + CPU.Flags |= DEBUG_MODE_FLAG; +#else + S9xExit (); +#endif +} + +#define TCALL(n)\ +{\ + PushW ((pIAPU->PC - pIAPU->RAM + 1)); \ + pIAPU->PC = pIAPU->RAM + (APU.ExtraRAM [((15 - n) << 1)] + \ + (APU.ExtraRAM [((15 - n) << 1) + 1] << 8)); \ +} + +// XXX: HalfCarry - BJ fixed? +#define SBC(a,b)\ +Int16 = (short) (a) - (short) (b) + (short) (APUCheckCarry ()) - 1;\ +pIAPU->_Carry = Int16 >= 0;\ +if ((((a) ^ (b)) & 0x80) && (((a) ^ (uint8) Int16) & 0x80))\ + APUSetOverflow ();\ +else \ + APUClearOverflow (); \ +APUSetHalfCarry ();\ +if(((a) ^ (b) ^ (uint8) Int16) & 0x10)\ + APUClearHalfCarry ();\ +(a) = (uint8) Int16;\ +APUSetZN8 ((uint8) Int16); + +// XXX: HalfCarry - BJ fixed? +#define ADC(a,b)\ +Work16 = (a) + (b) + APUCheckCarry();\ +pIAPU->_Carry = Work16 >= 0x100; \ +if (~((a) ^ (b)) & ((b) ^ (uint8) Work16) & 0x80)\ + APUSetOverflow ();\ +else \ + APUClearOverflow (); \ +APUClearHalfCarry ();\ +/*if(((a) ^ (b) ^ (uint8) Int16) & 0x10) notaz: Int16!? */\ +if(((a) ^ (b) ^ (uint8) Work16) & 0x10)\ + APUSetHalfCarry ();\ +(a) = (uint8) Work16;\ +APUSetZN8 ((uint8) Work16); + +#define CMP(a,b)\ +Int16 = (short) (a) - (short) (b);\ +pIAPU->_Carry = Int16 >= 0;\ +APUSetZN8 ((uint8) Int16); + +#define ASL(b)\ + pIAPU->_Carry = ((b) & 0x80) != 0; \ + (b) <<= 1;\ + APUSetZN8 (b); +#define LSR(b)\ + pIAPU->_Carry = (b) & 1;\ + (b) >>= 1;\ + APUSetZN8 (b); +#define ROL(b)\ + Work16 = ((b) << 1) | APUCheckCarry (); \ + pIAPU->_Carry = Work16 >= 0x100; \ + (b) = (uint8) Work16; \ + APUSetZN8 (b); +#define ROR(b)\ + Work16 = (b) | ((uint16) APUCheckCarry () << 8); \ + pIAPU->_Carry = (uint8) Work16 & 1; \ + Work16 >>= 1; \ + (b) = (uint8) Work16; \ + APUSetZN8 (b); + +#define Push(b)\ + *(pIAPU->RAM + 0x100 + pIAPU->S) = b;\ + pIAPU->S--; + +#define Pop(b)\ + pIAPU->S++;\ + (b) = *(pIAPU->RAM + 0x100 + pIAPU->S); + +#ifdef FAST_LSB_WORD_ACCESS +#define PushW(w)\ + *(uint16 *) (pIAPU->RAM + 0xff + pIAPU->S) = w;\ + pIAPU->S -= 2; +#define PopW(w)\ + pIAPU->S += 2;\ + w = *(uint16 *) (pIAPU->RAM + 0xff + pIAPU->S); +#else +#define PushW(w)\ + *(pIAPU->RAM + 0xff + pIAPU->S) = w;\ + *(pIAPU->RAM + 0x100 + pIAPU->S) = (w >> 8);\ + pIAPU->S -= 2; +#define PopW(w)\ + pIAPU->S += 2; \ + (w) = *(pIAPU->RAM + 0xff + pIAPU->S) + (*(pIAPU->RAM + 0x100 + pIAPU->S) << 8); +#endif + +#define Relative()\ + Int8 = OP1;\ + Int16 = (int) (pIAPU->PC + 2 - pIAPU->RAM) + Int8; + +#define Relative2()\ + Int8 = OP2;\ + Int16 = (int) (pIAPU->PC + 3 - pIAPU->RAM) + Int8; + +#ifdef FAST_LSB_WORD_ACCESS +#define IndexedXIndirect()\ + pIAPU->Address = *(uint16 *) (pIAPU->DirectPage + ((OP1 + pIAPU->X) & 0xff)); + +#define Absolute()\ + pIAPU->Address = *(uint16 *) (pIAPU->PC + 1); + +#define AbsoluteX()\ + pIAPU->Address = *(uint16 *) (pIAPU->PC + 1) + pIAPU->X; + +#define AbsoluteY()\ + pIAPU->Address = *(uint16 *) (pIAPU->PC + 1) + pIAPU->YA.B.Y; + +#define MemBit()\ + pIAPU->Address = *(uint16 *) (pIAPU->PC + 1);\ + pIAPU->Bit = (uint8)(pIAPU->Address >> 13);\ + pIAPU->Address &= 0x1fff; + +#define IndirectIndexedY()\ + pIAPU->Address = *(uint16 *) (pIAPU->DirectPage + OP1) + pIAPU->YA.B.Y; +#else +#define IndexedXIndirect()\ + pIAPU->Address = *(pIAPU->DirectPage + ((OP1 + pIAPU->X) & 0xff)) + \ + (*(pIAPU->DirectPage + ((OP1 + pIAPU->X + 1) & 0xff)) << 8); +#define Absolute()\ + pIAPU->Address = OP1 + (OP2 << 8); + +#define AbsoluteX()\ + pIAPU->Address = OP1 + (OP2 << 8) + pIAPU->X; + +#define AbsoluteY()\ + pIAPU->Address = OP1 + (OP2 << 8) + pIAPU->YA.B.Y; + +#define MemBit()\ + pIAPU->Address = OP1 + (OP2 << 8);\ + pIAPU->Bit = (int8) (pIAPU->Address >> 13);\ + pIAPU->Address &= 0x1fff; + +#define IndirectIndexedY()\ + pIAPU->Address = *(pIAPU->DirectPage + OP1) + \ + (*(pIAPU->DirectPage + OP1 + 1) << 8) + \ + pIAPU->YA.B.Y; +#endif + +void Apu00 () +{ +// NOP + pIAPU->PC++; +} + +void Apu01 () { TCALL (0) } + +void Apu11 () { TCALL (1) } + +void Apu21 () { TCALL (2) } + +void Apu31 () { TCALL (3) } + +void Apu41 () { TCALL (4) } + +void Apu51 () { TCALL (5) } + +void Apu61 () { TCALL (6) } + +void Apu71 () { TCALL (7) } + +void Apu81 () { TCALL (8) } + +void Apu91 () { TCALL (9) } + +void ApuA1 () { TCALL (10) } + +void ApuB1 () { TCALL (11) } + +void ApuC1 () { TCALL (12) } + +void ApuD1 () { TCALL (13) } + +void ApuE1 () { TCALL (14) } + +void ApuF1 () { TCALL (15) } + +void Apu3F () // CALL absolute +{ + Absolute (); + // 0xB6f for Star Fox 2 + PushW ((pIAPU->PC + 3 - pIAPU->RAM)); + pIAPU->PC = pIAPU->RAM + pIAPU->Address; +} + +void Apu4F () // PCALL $XX +{ + Work8 = OP1; + PushW ((pIAPU->PC + 2 - pIAPU->RAM)); + pIAPU->PC = pIAPU->RAM + 0xff00 + Work8; +} + +#define SET(b) \ +S9xAPUSetByteZ ((uint8) (S9xAPUGetByteZ (OP1 ) | (1 << (b))), OP1); \ +pIAPU->PC += 2 + +void Apu02 () +{ + SET (0); +} + +void Apu22 () +{ + SET (1); +} + +void Apu42 () +{ + SET (2); +} + +void Apu62 () +{ + SET (3); +} + +void Apu82 () +{ + SET (4); +} + +void ApuA2 () +{ + SET (5); +} + +void ApuC2 () +{ + SET (6); +} + +void ApuE2 () +{ + SET (7); +} + +#define CLR(b) \ +S9xAPUSetByteZ ((uint8) (S9xAPUGetByteZ (OP1) & ~(1 << (b))), OP1); \ +pIAPU->PC += 2; + +void Apu12 () +{ + CLR (0); +} + +void Apu32 () +{ + CLR (1); +} + +void Apu52 () +{ + CLR (2); +} + +void Apu72 () +{ + CLR (3); +} + +void Apu92 () +{ + CLR (4); +} + +void ApuB2 () +{ + CLR (5); +} + +void ApuD2 () +{ + CLR (6); +} + +void ApuF2 () +{ + CLR (7); +} + +#define BBS(b) \ +Work8 = OP1; \ +Relative2 (); \ +if (S9xAPUGetByteZ (Work8) & (1 << (b))) \ +{ \ + pIAPU->PC = pIAPU->RAM + (uint16) Int16; \ + CPU.APU_Cycles += pIAPU->TwoCycles; \ +} \ +else \ + pIAPU->PC += 3 + +void Apu03 () +{ + BBS (0); +} + +void Apu23 () +{ + BBS (1); +} + +void Apu43 () +{ + BBS (2); +} + +void Apu63 () +{ + BBS (3); +} + +void Apu83 () +{ + BBS (4); +} + +void ApuA3 () +{ + BBS (5); +} + +void ApuC3 () +{ + BBS (6); +} + +void ApuE3 () +{ + BBS (7); +} + +#define BBC(b) \ +Work8 = OP1; \ +Relative2 (); \ +if (!(S9xAPUGetByteZ (Work8) & (1 << (b)))) \ +{ \ + pIAPU->PC = pIAPU->RAM + (uint16) Int16; \ + CPU.APU_Cycles += pIAPU->TwoCycles; \ +} \ +else \ + pIAPU->PC += 3 + +void Apu13 () +{ + BBC (0); +} + +void Apu33 () +{ + BBC (1); +} + +void Apu53 () +{ + BBC (2); +} + +void Apu73 () +{ + BBC (3); +} + +void Apu93 () +{ + BBC (4); +} + +void ApuB3 () +{ + BBC (5); +} + +void ApuD3 () +{ + BBC (6); +} + +void ApuF3 () +{ + BBC (7); +} + +void Apu04 () +{ +// OR A,dp + pIAPU->YA.B.A |= S9xAPUGetByteZ (OP1); + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC += 2; +} + +void Apu05 () +{ +// OR A,abs + Absolute (); + pIAPU->YA.B.A |= S9xAPUGetByte (pIAPU->Address); + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC += 3; +} + +void Apu06 () +{ +// OR A,(X) + pIAPU->YA.B.A |= S9xAPUGetByteZ (pIAPU->X); + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC++; +} + +void Apu07 () +{ +// OR A,(dp+X) + IndexedXIndirect (); + pIAPU->YA.B.A |= S9xAPUGetByte (pIAPU->Address); + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC += 2; +} + +void Apu08 () +{ +// OR A,#00 + pIAPU->YA.B.A |= OP1; + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC += 2; +} + +void Apu09 () +{ +// OR dp(dest),dp(src) + Work8 = S9xAPUGetByteZ (OP1); + Work8 |= S9xAPUGetByteZ (OP2); + S9xAPUSetByteZ (Work8, OP2); + APUSetZN8 (Work8); + pIAPU->PC += 3; +} + +void Apu14 () +{ +// OR A,dp+X + pIAPU->YA.B.A |= S9xAPUGetByteZ (OP1 + pIAPU->X); + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC += 2; +} + +void Apu15 () +{ +// OR A,abs+X + AbsoluteX (); + pIAPU->YA.B.A |= S9xAPUGetByte (pIAPU->Address); + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC += 3; +} + +void Apu16 () +{ +// OR A,abs+Y + AbsoluteY (); + pIAPU->YA.B.A |= S9xAPUGetByte (pIAPU->Address); + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC += 3; +} + +void Apu17 () +{ +// OR A,(dp)+Y + IndirectIndexedY (); + pIAPU->YA.B.A |= S9xAPUGetByte (pIAPU->Address); + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC += 2; +} + +void Apu18 () +{ +// OR dp,#00 + Work8 = OP1; + Work8 |= S9xAPUGetByteZ (OP2); + S9xAPUSetByteZ (Work8, OP2); + APUSetZN8 (Work8); + pIAPU->PC += 3; +} + +void Apu19 () +{ +// OR (X),(Y) + Work8 = S9xAPUGetByteZ (pIAPU->X) | S9xAPUGetByteZ (pIAPU->YA.B.Y); + APUSetZN8 (Work8); + S9xAPUSetByteZ (Work8, pIAPU->X); + pIAPU->PC++; +} + +void Apu0A () +{ +// OR1 C,membit + MemBit (); + if (!APUCheckCarry ()) + { + if (S9xAPUGetByte (pIAPU->Address) & (1 << pIAPU->Bit)) + APUSetCarry (); + } + pIAPU->PC += 3; +} + +void Apu2A () +{ +// OR1 C,not membit + MemBit (); + if (!APUCheckCarry ()) + { + if (!(S9xAPUGetByte (pIAPU->Address) & (1 << pIAPU->Bit))) + APUSetCarry (); + } + pIAPU->PC += 3; +} + +void Apu4A () +{ +// AND1 C,membit + MemBit (); + if (APUCheckCarry ()) + { + if (!(S9xAPUGetByte (pIAPU->Address) & (1 << pIAPU->Bit))) + APUClearCarry (); + } + pIAPU->PC += 3; +} + +void Apu6A () +{ +// AND1 C, not membit + MemBit (); + if (APUCheckCarry ()) + { + if ((S9xAPUGetByte (pIAPU->Address) & (1 << pIAPU->Bit))) + APUClearCarry (); + } + pIAPU->PC += 3; +} + +void Apu8A () +{ +// EOR1 C, membit + MemBit (); + if (APUCheckCarry ()) + { + if (S9xAPUGetByte (pIAPU->Address) & (1 << pIAPU->Bit)) + APUClearCarry (); + } + else + { + if (S9xAPUGetByte (pIAPU->Address) & (1 << pIAPU->Bit)) + APUSetCarry (); + } + pIAPU->PC += 3; +} + +void ApuAA () +{ +// MOV1 C,membit + MemBit (); + if (S9xAPUGetByte (pIAPU->Address) & (1 << pIAPU->Bit)) + APUSetCarry (); + else + APUClearCarry (); + pIAPU->PC += 3; +} + +void ApuCA () +{ +// MOV1 membit,C + MemBit (); + if (APUCheckCarry ()) + { + S9xAPUSetByte (S9xAPUGetByte (pIAPU->Address) | (1 << pIAPU->Bit), pIAPU->Address); + } + else + { + S9xAPUSetByte (S9xAPUGetByte (pIAPU->Address) & ~(1 << pIAPU->Bit), pIAPU->Address); + } + pIAPU->PC += 3; +} + +void ApuEA () +{ +// NOT1 membit + MemBit (); + S9xAPUSetByte (S9xAPUGetByte (pIAPU->Address) ^ (1 << pIAPU->Bit), pIAPU->Address); + pIAPU->PC += 3; +} + +void Apu0B () +{ +// ASL dp + Work8 = S9xAPUGetByteZ (OP1); + ASL (Work8); + S9xAPUSetByteZ (Work8, OP1); + pIAPU->PC += 2; +} + +void Apu0C () +{ +// ASL abs + Absolute (); + Work8 = S9xAPUGetByte (pIAPU->Address); + ASL (Work8); + S9xAPUSetByte (Work8, pIAPU->Address); + pIAPU->PC += 3; +} + +void Apu1B () +{ +// ASL dp+X + Work8 = S9xAPUGetByteZ (OP1 + pIAPU->X); + ASL (Work8); + S9xAPUSetByteZ (Work8, OP1 + pIAPU->X); + pIAPU->PC += 2; +} + +void Apu1C () +{ +// ASL A + ASL (pIAPU->YA.B.A); + pIAPU->PC++; +} + +void Apu0D () +{ +// PUSH PSW + S9xAPUPackStatus (); + Push (pIAPU->P); + pIAPU->PC++; +} + +void Apu2D () +{ +// PUSH A + Push (pIAPU->YA.B.A); + pIAPU->PC++; +} + +void Apu4D () +{ +// PUSH X + Push (pIAPU->X); + pIAPU->PC++; +} + +void Apu6D () +{ +// PUSH Y + Push (pIAPU->YA.B.Y); + pIAPU->PC++; +} + +void Apu8E () +{ +// POP PSW + Pop (pIAPU->P); + S9xAPUUnpackStatus (); + if (APUCheckDirectPage ()) + pIAPU->DirectPage = pIAPU->RAM + 0x100; + else + pIAPU->DirectPage = pIAPU->RAM; + pIAPU->PC++; +} + +void ApuAE () +{ +// POP A + Pop (pIAPU->YA.B.A); + pIAPU->PC++; +} + +void ApuCE () +{ +// POP X + Pop (pIAPU->X); + pIAPU->PC++; +} + +void ApuEE () +{ +// POP Y + Pop (pIAPU->YA.B.Y); + pIAPU->PC++; +} + +void Apu0E () +{ +// TSET1 abs + Absolute (); + Work8 = S9xAPUGetByte (pIAPU->Address); + S9xAPUSetByte (Work8 | pIAPU->YA.B.A, pIAPU->Address); + Work8 &= pIAPU->YA.B.A; + APUSetZN8 (Work8); + pIAPU->PC += 3; +} + +void Apu4E () +{ +// TCLR1 abs + Absolute (); + Work8 = S9xAPUGetByte (pIAPU->Address); + S9xAPUSetByte (Work8 & ~pIAPU->YA.B.A, pIAPU->Address); + Work8 &= pIAPU->YA.B.A; + APUSetZN8 (Work8); + pIAPU->PC += 3; +} + +void Apu0F () +{ +// BRK + +#if 0 + STOP ("BRK"); +#else + PushW ((pIAPU->PC + 1 - pIAPU->RAM)); + S9xAPUPackStatus (); + Push (pIAPU->P); + APUSetBreak (); + APUClearInterrupt (); +// XXX:Where is the BRK vector ??? + pIAPU->PC = pIAPU->RAM + APU.ExtraRAM[0x20] + (APU.ExtraRAM[0x21] << 8); +#endif +} + +void ApuEF () +{ +// SLEEP + // XXX: sleep + // STOP ("SLEEP"); + CPU.APU_APUExecuting = FALSE; + pIAPU->PC++; +} + +void ApuFF () +{ +// STOP + // STOP ("STOP"); + CPU.APU_APUExecuting = FALSE; + pIAPU->PC++; +} + +void Apu10 () +{ +// BPL + Relative (); + if (!APUCheckNegative ()) + { + pIAPU->PC = pIAPU->RAM + (uint16) Int16; + CPU.APU_Cycles += pIAPU->TwoCycles; + APUShutdown (); + } + else + pIAPU->PC += 2; +} + +void Apu30 () +{ +// BMI + Relative (); + if (APUCheckNegative ()) + { + pIAPU->PC = pIAPU->RAM + (uint16) Int16; + CPU.APU_Cycles += pIAPU->TwoCycles; + APUShutdown (); + } + else + pIAPU->PC += 2; +} + +void Apu90 () +{ +// BCC + Relative (); + if (!APUCheckCarry ()) + { + pIAPU->PC = pIAPU->RAM + (uint16) Int16; + CPU.APU_Cycles += pIAPU->TwoCycles; + APUShutdown (); + } + else + pIAPU->PC += 2; +} + +void ApuB0 () +{ +// BCS + Relative (); + if (APUCheckCarry ()) + { + pIAPU->PC = pIAPU->RAM + (uint16) Int16; + CPU.APU_Cycles += pIAPU->TwoCycles; + APUShutdown (); + } + else + pIAPU->PC += 2; +} + +void ApuD0 () +{ +// BNE + Relative (); + if (!APUCheckZero ()) + { + pIAPU->PC = pIAPU->RAM + (uint16) Int16; + CPU.APU_Cycles += pIAPU->TwoCycles; + APUShutdown (); + } + else + pIAPU->PC += 2; +} + +void ApuF0 () +{ +// BEQ + Relative (); + if (APUCheckZero ()) + { + pIAPU->PC = pIAPU->RAM + (uint16) Int16; + CPU.APU_Cycles += pIAPU->TwoCycles; + APUShutdown (); + } + else + pIAPU->PC += 2; +} + +void Apu50 () +{ +// BVC + Relative (); + if (!APUCheckOverflow ()) + { + pIAPU->PC = pIAPU->RAM + (uint16) Int16; + CPU.APU_Cycles += pIAPU->TwoCycles; + } + else + pIAPU->PC += 2; +} + +void Apu70 () +{ +// BVS + Relative (); + if (APUCheckOverflow ()) + { + pIAPU->PC = pIAPU->RAM + (uint16) Int16; + CPU.APU_Cycles += pIAPU->TwoCycles; + } + else + pIAPU->PC += 2; +} + +void Apu2F () +{ +// BRA + Relative (); + pIAPU->PC = pIAPU->RAM + (uint16) Int16; +} + +void Apu80 () +{ +// SETC + APUSetCarry (); + pIAPU->PC++; +} + +void ApuED () +{ +// NOTC + pIAPU->_Carry ^= 1; + pIAPU->PC++; +} + +void Apu40 () +{ +// SETP + APUSetDirectPage (); + pIAPU->DirectPage = pIAPU->RAM + 0x100; + pIAPU->PC++; +} + +void Apu1A () +{ +// DECW dp + Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8); + Work16--; + S9xAPUSetByteZ ((uint8) Work16, OP1); + S9xAPUSetByteZ (Work16 >> 8, OP1 + 1); + APUSetZN16 (Work16); + pIAPU->PC += 2; +} + +void Apu5A () +{ +// CMPW YA,dp + Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8); + Int32 = (long) pIAPU->YA.W - (long) Work16; + pIAPU->_Carry = Int32 >= 0; + APUSetZN16 ((uint16) Int32); + pIAPU->PC += 2; +} + +void Apu3A () +{ +// INCW dp + Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8); + Work16++; + S9xAPUSetByteZ ((uint8) Work16, OP1); + S9xAPUSetByteZ (Work16 >> 8, OP1 + 1); + APUSetZN16 (Work16); + pIAPU->PC += 2; +} + +// XXX: HalfCarry - BJ Fixed? Or is it between bits 7 and 8 for ADDW/SUBW? +void Apu7A () +{ +// ADDW YA,dp + Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8); + Work32 = (uint32) pIAPU->YA.W + Work16; + pIAPU->_Carry = Work32 >= 0x10000; + if (~(pIAPU->YA.W ^ Work16) & (Work16 ^ (uint16) Work32) & 0x8000) + APUSetOverflow (); + else + APUClearOverflow (); + APUClearHalfCarry (); + if((pIAPU->YA.W ^ Work16 ^ (uint16) Work32) & 0x10) + APUSetHalfCarry (); + pIAPU->YA.W = (uint16) Work32; + APUSetZN16 (pIAPU->YA.W); + pIAPU->PC += 2; +} + +// XXX: BJ: i think the old HalfCarry behavior was wrong... +// XXX: Or is it between bits 7 and 8 for ADDW/SUBW? +void Apu9A () +{ +// SUBW YA,dp + Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8); + Int32 = (long) pIAPU->YA.W - (long) Work16; + APUClearHalfCarry (); + pIAPU->_Carry = Int32 >= 0; + if (((pIAPU->YA.W ^ Work16) & 0x8000) && + ((pIAPU->YA.W ^ (uint16) Int32) & 0x8000)) + APUSetOverflow (); + else + APUClearOverflow (); +// if (((pIAPU->YA.W ^ Work16) & 0x0080) && +// ((pIAPU->YA.W ^ (uint16) Int32) & 0x0080)) +// APUSetHalfCarry (); // notaz: strange here + APUSetHalfCarry (); +// if((pIAPU->YA.W ^ Work16 ^ (uint16) Work32) & 0x10) // notaz: Work32?! + if((pIAPU->YA.W ^ Work16 ^ (uint16) Int32) & 0x10) + APUClearHalfCarry (); + pIAPU->YA.W = (uint16) Int32; + APUSetZN16 (pIAPU->YA.W); + pIAPU->PC += 2; +} + +void ApuBA () +{ +// MOVW YA,dp + pIAPU->YA.B.A = S9xAPUGetByteZ (OP1); + pIAPU->YA.B.Y = S9xAPUGetByteZ (OP1 + 1); + APUSetZN16 (pIAPU->YA.W); + pIAPU->PC += 2; +} + +void ApuDA () +{ +// MOVW dp,YA + S9xAPUSetByteZ (pIAPU->YA.B.A, OP1); + S9xAPUSetByteZ (pIAPU->YA.B.Y, OP1 + 1); + pIAPU->PC += 2; +} + +void Apu64 () +{ +// CMP A,dp + Work8 = S9xAPUGetByteZ (OP1); + CMP (pIAPU->YA.B.A, Work8); + pIAPU->PC += 2; +} + +void Apu65 () +{ +// CMP A,abs + Absolute (); + Work8 = S9xAPUGetByte (pIAPU->Address); + CMP (pIAPU->YA.B.A, Work8); + pIAPU->PC += 3; +} + +void Apu66 () +{ +// CMP A,(X) + Work8 = S9xAPUGetByteZ (pIAPU->X); + CMP (pIAPU->YA.B.A, Work8); + pIAPU->PC++; +} + +void Apu67 () +{ +// CMP A,(dp+X) + IndexedXIndirect (); + Work8 = S9xAPUGetByte (pIAPU->Address); + CMP (pIAPU->YA.B.A, Work8); + pIAPU->PC += 2; +} + +void Apu68 () +{ +// CMP A,#00 + Work8 = OP1; + CMP (pIAPU->YA.B.A, Work8); + pIAPU->PC += 2; +} + +void Apu69 () +{ +// CMP dp(dest), dp(src) + W1 = S9xAPUGetByteZ (OP1); + Work8 = S9xAPUGetByteZ (OP2); + CMP (Work8, W1); + pIAPU->PC += 3; +} + +void Apu74 () +{ +// CMP A, dp+X + Work8 = S9xAPUGetByteZ (OP1 + pIAPU->X); + CMP (pIAPU->YA.B.A, Work8); + pIAPU->PC += 2; +} + +void Apu75 () +{ +// CMP A,abs+X + AbsoluteX (); + Work8 = S9xAPUGetByte (pIAPU->Address); + CMP (pIAPU->YA.B.A, Work8); + pIAPU->PC += 3; +} + +void Apu76 () +{ +// CMP A, abs+Y + AbsoluteY (); + Work8 = S9xAPUGetByte (pIAPU->Address); + CMP (pIAPU->YA.B.A, Work8); + pIAPU->PC += 3; +} + +void Apu77 () +{ +// CMP A,(dp)+Y + IndirectIndexedY (); + Work8 = S9xAPUGetByte (pIAPU->Address); + CMP (pIAPU->YA.B.A, Work8); + pIAPU->PC += 2; +} + +void Apu78 () +{ +// CMP dp,#00 + Work8 = OP1; + W1 = S9xAPUGetByteZ (OP2); + CMP (W1, Work8); + pIAPU->PC += 3; +} + +void Apu79 () +{ +// CMP (X),(Y) + W1 = S9xAPUGetByteZ (pIAPU->X); + Work8 = S9xAPUGetByteZ (pIAPU->YA.B.Y); + CMP (W1, Work8); + pIAPU->PC++; +} + +void Apu1E () +{ +// CMP X,abs + Absolute (); + Work8 = S9xAPUGetByte (pIAPU->Address); + CMP (pIAPU->X, Work8); + pIAPU->PC += 3; +} + +void Apu3E () +{ +// CMP X,dp + Work8 = S9xAPUGetByteZ (OP1); + CMP (pIAPU->X, Work8); + pIAPU->PC += 2; +} + +void ApuC8 () +{ +// CMP X,#00 + CMP (pIAPU->X, OP1); + pIAPU->PC += 2; +} + +void Apu5E () +{ +// CMP Y,abs + Absolute (); + Work8 = S9xAPUGetByte (pIAPU->Address); + CMP (pIAPU->YA.B.Y, Work8); + pIAPU->PC += 3; +} + +void Apu7E () +{ +// CMP Y,dp + Work8 = S9xAPUGetByteZ (OP1); + CMP (pIAPU->YA.B.Y, Work8); + pIAPU->PC += 2; +} + +void ApuAD () +{ +// CMP Y,#00 + Work8 = OP1; + CMP (pIAPU->YA.B.Y, Work8); + pIAPU->PC += 2; +} + +void Apu1F () +{ +// JMP (abs+X) + Absolute (); + pIAPU->PC = pIAPU->RAM + S9xAPUGetByte (pIAPU->Address + pIAPU->X) + + (S9xAPUGetByte (pIAPU->Address + pIAPU->X + 1) << 8); +// XXX: HERE: + // APU.Flags |= TRACE_FLAG; +} + +void Apu5F () +{ +// JMP abs + Absolute (); + pIAPU->PC = pIAPU->RAM + pIAPU->Address; +} + +void Apu20 () +{ +// CLRP + APUClearDirectPage (); + pIAPU->DirectPage = pIAPU->RAM; + pIAPU->PC++; +} + +void Apu60 () +{ +// CLRC + APUClearCarry (); + pIAPU->PC++; +} + +void ApuE0 () +{ +// CLRV + APUClearHalfCarry (); + APUClearOverflow (); + pIAPU->PC++; +} + +void Apu24 () +{ +// AND A,dp + pIAPU->YA.B.A &= S9xAPUGetByteZ (OP1); + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC += 2; +} + +void Apu25 () +{ +// AND A,abs + Absolute (); + pIAPU->YA.B.A &= S9xAPUGetByte (pIAPU->Address); + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC += 3; +} + +void Apu26 () +{ +// AND A,(X) + pIAPU->YA.B.A &= S9xAPUGetByteZ (pIAPU->X); + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC++; +} + +void Apu27 () +{ +// AND A,(dp+X) + IndexedXIndirect (); + pIAPU->YA.B.A &= S9xAPUGetByte (pIAPU->Address); + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC += 2; +} + +void Apu28 () +{ +// AND A,#00 + pIAPU->YA.B.A &= OP1; + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC += 2; +} + +void Apu29 () +{ +// AND dp(dest),dp(src) + Work8 = S9xAPUGetByteZ (OP1); + Work8 &= S9xAPUGetByteZ (OP2); + S9xAPUSetByteZ (Work8, OP2); + APUSetZN8 (Work8); + pIAPU->PC += 3; +} + +void Apu34 () +{ +// AND A,dp+X + pIAPU->YA.B.A &= S9xAPUGetByteZ (OP1 + pIAPU->X); + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC += 2; +} + +void Apu35 () +{ +// AND A,abs+X + AbsoluteX (); + pIAPU->YA.B.A &= S9xAPUGetByte (pIAPU->Address); + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC += 3; +} + +void Apu36 () +{ +// AND A,abs+Y + AbsoluteY (); + pIAPU->YA.B.A &= S9xAPUGetByte (pIAPU->Address); + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC += 3; +} + +void Apu37 () +{ +// AND A,(dp)+Y + IndirectIndexedY (); + pIAPU->YA.B.A &= S9xAPUGetByte (pIAPU->Address); + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC += 2; +} + +void Apu38 () +{ +// AND dp,#00 + Work8 = OP1; + Work8 &= S9xAPUGetByteZ (OP2); + S9xAPUSetByteZ (Work8, OP2); + APUSetZN8 (Work8); + pIAPU->PC += 3; +} + +void Apu39 () +{ +// AND (X),(Y) + Work8 = S9xAPUGetByteZ (pIAPU->X) & S9xAPUGetByteZ (pIAPU->YA.B.Y); + APUSetZN8 (Work8); + S9xAPUSetByteZ (Work8, pIAPU->X); + pIAPU->PC++; +} + +void Apu2B () +{ +// ROL dp + Work8 = S9xAPUGetByteZ (OP1); + ROL (Work8); + S9xAPUSetByteZ (Work8, OP1); + pIAPU->PC += 2; +} + +void Apu2C () +{ +// ROL abs + Absolute (); + Work8 = S9xAPUGetByte (pIAPU->Address); + ROL (Work8); + S9xAPUSetByte (Work8, pIAPU->Address); + pIAPU->PC += 3; +} + +void Apu3B () +{ +// ROL dp+X + Work8 = S9xAPUGetByteZ (OP1 + pIAPU->X); + ROL (Work8); + S9xAPUSetByteZ (Work8, OP1 + pIAPU->X); + pIAPU->PC += 2; +} + +void Apu3C () +{ +// ROL A + ROL (pIAPU->YA.B.A); + pIAPU->PC++; +} + +void Apu2E () +{ +// CBNE dp,rel + Work8 = OP1; + Relative2 (); + + if (S9xAPUGetByteZ (Work8) != pIAPU->YA.B.A) + { + pIAPU->PC = pIAPU->RAM + (uint16) Int16; + CPU.APU_Cycles += pIAPU->TwoCycles; + APUShutdown (); + } + else + pIAPU->PC += 3; +} + +void ApuDE () +{ +// CBNE dp+X,rel + Work8 = OP1 + pIAPU->X; + Relative2 (); + + if (S9xAPUGetByteZ (Work8) != pIAPU->YA.B.A) + { + pIAPU->PC = pIAPU->RAM + (uint16) Int16; + CPU.APU_Cycles += pIAPU->TwoCycles; + APUShutdown (); + } + else + pIAPU->PC += 3; +} + +void Apu3D () +{ +// INC X + pIAPU->X++; + APUSetZN8 (pIAPU->X); + +#ifdef SPC700_SHUTDOWN + pIAPU->WaitCounter++; +#endif + + pIAPU->PC++; +} + +void ApuFC () +{ +// INC Y + pIAPU->YA.B.Y++; + APUSetZN8 (pIAPU->YA.B.Y); + +#ifdef SPC700_SHUTDOWN + pIAPU->WaitCounter++; +#endif + + pIAPU->PC++; +} + +void Apu1D () +{ +// DEC X + pIAPU->X--; + APUSetZN8 (pIAPU->X); + +#ifdef SPC700_SHUTDOWN + pIAPU->WaitCounter++; +#endif + + pIAPU->PC++; +} + +void ApuDC () +{ +// DEC Y + pIAPU->YA.B.Y--; + APUSetZN8 (pIAPU->YA.B.Y); + +#ifdef SPC700_SHUTDOWN + pIAPU->WaitCounter++; +#endif + + pIAPU->PC++; +} + +void ApuAB () +{ +// INC dp + Work8 = S9xAPUGetByteZ (OP1) + 1; + S9xAPUSetByteZ (Work8, OP1); + APUSetZN8 (Work8); + +#ifdef SPC700_SHUTDOWN + pIAPU->WaitCounter++; +#endif + + pIAPU->PC += 2; +} + +void ApuAC () +{ +// INC abs + Absolute (); + Work8 = S9xAPUGetByte (pIAPU->Address) + 1; + S9xAPUSetByte (Work8, pIAPU->Address); + APUSetZN8 (Work8); + +#ifdef SPC700_SHUTDOWN + pIAPU->WaitCounter++; +#endif + + pIAPU->PC += 3; +} + +void ApuBB () +{ +// INC dp+X + Work8 = S9xAPUGetByteZ (OP1 + pIAPU->X) + 1; + S9xAPUSetByteZ (Work8, OP1 + pIAPU->X); + APUSetZN8 (Work8); + +#ifdef SPC700_SHUTDOWN + pIAPU->WaitCounter++; +#endif + + pIAPU->PC += 2; +} + +void ApuBC () +{ +// INC A + pIAPU->YA.B.A++; + APUSetZN8 (pIAPU->YA.B.A); + +#ifdef SPC700_SHUTDOWN + pIAPU->WaitCounter++; +#endif + + pIAPU->PC++; +} + +void Apu8B () +{ +// DEC dp + Work8 = S9xAPUGetByteZ (OP1) - 1; + S9xAPUSetByteZ (Work8, OP1); + APUSetZN8 (Work8); + +#ifdef SPC700_SHUTDOWN + pIAPU->WaitCounter++; +#endif + + pIAPU->PC += 2; +} + +void Apu8C () +{ +// DEC abs + Absolute (); + Work8 = S9xAPUGetByte (pIAPU->Address) - 1; + S9xAPUSetByte (Work8, pIAPU->Address); + APUSetZN8 (Work8); + +#ifdef SPC700_SHUTDOWN + pIAPU->WaitCounter++; +#endif + + pIAPU->PC += 3; +} + +void Apu9B () +{ +// DEC dp+X + Work8 = S9xAPUGetByteZ (OP1 + pIAPU->X) - 1; + S9xAPUSetByteZ (Work8, OP1 + pIAPU->X); + APUSetZN8 (Work8); + +#ifdef SPC700_SHUTDOWN + pIAPU->WaitCounter++; +#endif + + pIAPU->PC += 2; +} + +void Apu9C () +{ +// DEC A + pIAPU->YA.B.A--; + APUSetZN8 (pIAPU->YA.B.A); + +#ifdef SPC700_SHUTDOWN + pIAPU->WaitCounter++; +#endif + + pIAPU->PC++; +} + +void Apu44 () +{ +// EOR A,dp + pIAPU->YA.B.A ^= S9xAPUGetByteZ (OP1); + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC += 2; +} + +void Apu45 () +{ +// EOR A,abs + Absolute (); + pIAPU->YA.B.A ^= S9xAPUGetByte (pIAPU->Address); + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC += 3; +} + +void Apu46 () +{ +// EOR A,(X) + pIAPU->YA.B.A ^= S9xAPUGetByteZ (pIAPU->X); + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC++; +} + +void Apu47 () +{ +// EOR A,(dp+X) + IndexedXIndirect (); + pIAPU->YA.B.A ^= S9xAPUGetByte (pIAPU->Address); + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC += 2; +} + +void Apu48 () +{ +// EOR A,#00 + pIAPU->YA.B.A ^= OP1; + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC += 2; +} + +void Apu49 () +{ +// EOR dp(dest),dp(src) + Work8 = S9xAPUGetByteZ (OP1); + Work8 ^= S9xAPUGetByteZ (OP2); + S9xAPUSetByteZ (Work8, OP2); + APUSetZN8 (Work8); + pIAPU->PC += 3; +} + +void Apu54 () +{ +// EOR A,dp+X + pIAPU->YA.B.A ^= S9xAPUGetByteZ (OP1 + pIAPU->X); + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC += 2; +} + +void Apu55 () +{ +// EOR A,abs+X + AbsoluteX (); + pIAPU->YA.B.A ^= S9xAPUGetByte (pIAPU->Address); + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC += 3; +} + +void Apu56 () +{ +// EOR A,abs+Y + AbsoluteY (); + pIAPU->YA.B.A ^= S9xAPUGetByte (pIAPU->Address); + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC += 3; +} + +void Apu57 () +{ +// EOR A,(dp)+Y + IndirectIndexedY (); + pIAPU->YA.B.A ^= S9xAPUGetByte (pIAPU->Address); + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC += 2; +} + +void Apu58 () +{ +// EOR dp,#00 + Work8 = OP1; + Work8 ^= S9xAPUGetByteZ (OP2); + S9xAPUSetByteZ (Work8, OP2); + APUSetZN8 (Work8); + pIAPU->PC += 3; +} + +void Apu59 () +{ +// EOR (X),(Y) + Work8 = S9xAPUGetByteZ (pIAPU->X) ^ S9xAPUGetByteZ (pIAPU->YA.B.Y); + APUSetZN8 (Work8); + S9xAPUSetByteZ (Work8, pIAPU->X); + pIAPU->PC++; +} + +void Apu4B () +{ +// LSR dp + Work8 = S9xAPUGetByteZ (OP1); + LSR (Work8); + S9xAPUSetByteZ (Work8, OP1); + pIAPU->PC += 2; +} + +void Apu4C () +{ +// LSR abs + Absolute (); + Work8 = S9xAPUGetByte (pIAPU->Address); + LSR (Work8); + S9xAPUSetByte (Work8, pIAPU->Address); + pIAPU->PC += 3; +} + +void Apu5B () +{ +// LSR dp+X + Work8 = S9xAPUGetByteZ (OP1 + pIAPU->X); + LSR (Work8); + S9xAPUSetByteZ (Work8, OP1 + pIAPU->X); + pIAPU->PC += 2; +} + +void Apu5C () +{ +// LSR A + LSR (pIAPU->YA.B.A); + pIAPU->PC++; +} + +void Apu7D () +{ +// MOV A,X + pIAPU->YA.B.A = pIAPU->X; + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC++; +} + +void ApuDD () +{ +// MOV A,Y + pIAPU->YA.B.A = pIAPU->YA.B.Y; + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC++; +} + +void Apu5D () +{ +// MOV X,A + pIAPU->X = pIAPU->YA.B.A; + APUSetZN8 (pIAPU->X); + pIAPU->PC++; +} + +void ApuFD () +{ +// MOV Y,A + pIAPU->YA.B.Y = pIAPU->YA.B.A; + APUSetZN8 (pIAPU->YA.B.Y); + pIAPU->PC++; +} + +void Apu9D () +{ +//MOV X,SP + pIAPU->X = pIAPU->S; + APUSetZN8 (pIAPU->X); + pIAPU->PC++; +} + +void ApuBD () +{ +// MOV SP,X + pIAPU->S = pIAPU->X; + pIAPU->PC++; +} + +void Apu6B () +{ +// ROR dp + Work8 = S9xAPUGetByteZ (OP1); + ROR (Work8); + S9xAPUSetByteZ (Work8, OP1); + pIAPU->PC += 2; +} + +void Apu6C () +{ +// ROR abs + Absolute (); + Work8 = S9xAPUGetByte (pIAPU->Address); + ROR (Work8); + S9xAPUSetByte (Work8, pIAPU->Address); + pIAPU->PC += 3; +} + +void Apu7B () +{ +// ROR dp+X + Work8 = S9xAPUGetByteZ (OP1 + pIAPU->X); + ROR (Work8); + S9xAPUSetByteZ (Work8, OP1 + pIAPU->X); + pIAPU->PC += 2; +} + +void Apu7C () +{ +// ROR A + ROR (pIAPU->YA.B.A); + pIAPU->PC++; +} + +void Apu6E () +{ +// DBNZ dp,rel + Work8 = OP1; + Relative2 (); + W1 = S9xAPUGetByteZ (Work8) - 1; + S9xAPUSetByteZ (W1, Work8); + if (W1 != 0) + { + pIAPU->PC = pIAPU->RAM + (uint16) Int16; + CPU.APU_Cycles += pIAPU->TwoCycles; + } + else + pIAPU->PC += 3; +} + +void ApuFE () +{ +// DBNZ Y,rel + Relative (); + pIAPU->YA.B.Y--; + if (pIAPU->YA.B.Y != 0) + { + pIAPU->PC = pIAPU->RAM + (uint16) Int16; + CPU.APU_Cycles += pIAPU->TwoCycles; + } + else + pIAPU->PC += 2; +} + +void Apu6F () +{ +// RET + PopW (Work16); + pIAPU->PC = pIAPU->RAM + Work16; +} + +void Apu7F () +{ +// RETI + // STOP ("RETI"); + Pop (pIAPU->P); + S9xAPUUnpackStatus (); + PopW (Work16); + pIAPU->PC = pIAPU->RAM + Work16; +} + +void Apu84 () +{ +// ADC A,dp + Work8 = S9xAPUGetByteZ (OP1); + ADC (pIAPU->YA.B.A, Work8); + pIAPU->PC += 2; +} + +void Apu85 () +{ +// ADC A, abs + Absolute (); + Work8 = S9xAPUGetByte (pIAPU->Address); + ADC (pIAPU->YA.B.A, Work8); + pIAPU->PC += 3; +} + +void Apu86 () +{ +// ADC A,(X) + Work8 = S9xAPUGetByteZ (pIAPU->X); + ADC (pIAPU->YA.B.A, Work8); + pIAPU->PC++; +} + +void Apu87 () +{ +// ADC A,(dp+X) + IndexedXIndirect (); + Work8 = S9xAPUGetByte (pIAPU->Address); + ADC (pIAPU->YA.B.A, Work8); + pIAPU->PC += 2; +} + +void Apu88 () +{ +// ADC A,#00 + Work8 = OP1; + ADC (pIAPU->YA.B.A, Work8); + pIAPU->PC += 2; +} + +void Apu89 () +{ +// ADC dp(dest),dp(src) + Work8 = S9xAPUGetByteZ (OP1); + W1 = S9xAPUGetByteZ (OP2); + ADC (W1, Work8); + S9xAPUSetByteZ (W1, OP2); + pIAPU->PC += 3; +} + +void Apu94 () +{ +// ADC A,dp+X + Work8 = S9xAPUGetByteZ (OP1 + pIAPU->X); + ADC (pIAPU->YA.B.A, Work8); + pIAPU->PC += 2; +} + +void Apu95 () +{ +// ADC A, abs+X + AbsoluteX (); + Work8 = S9xAPUGetByte (pIAPU->Address); + ADC (pIAPU->YA.B.A, Work8); + pIAPU->PC += 3; +} + +void Apu96 () +{ +// ADC A, abs+Y + AbsoluteY (); + Work8 = S9xAPUGetByte (pIAPU->Address); + ADC (pIAPU->YA.B.A, Work8); + pIAPU->PC += 3; +} + +void Apu97 () +{ +// ADC A, (dp)+Y + IndirectIndexedY (); + Work8 = S9xAPUGetByte (pIAPU->Address); + ADC (pIAPU->YA.B.A, Work8); + pIAPU->PC += 2; +} + +void Apu98 () +{ +// ADC dp,#00 + Work8 = OP1; + W1 = S9xAPUGetByteZ (OP2); + ADC (W1, Work8); + S9xAPUSetByteZ (W1, OP2); + pIAPU->PC += 3; +} + +void Apu99 () +{ +// ADC (X),(Y) + W1 = S9xAPUGetByteZ (pIAPU->X); + Work8 = S9xAPUGetByteZ (pIAPU->YA.B.Y); + ADC (W1, Work8); + S9xAPUSetByteZ (W1, pIAPU->X); + pIAPU->PC++; +} + +void Apu8D () +{ +// MOV Y,#00 + pIAPU->YA.B.Y = OP1; + APUSetZN8 (pIAPU->YA.B.Y); + pIAPU->PC += 2; +} + +void Apu8F () +{ +// MOV dp,#00 + Work8 = OP1; + S9xAPUSetByteZ (Work8, OP2); + pIAPU->PC += 3; +} + +void Apu9E () +{ +// DIV YA,X + if (pIAPU->X == 0) + { + APUSetOverflow (); + pIAPU->YA.B.Y = 0xff; + pIAPU->YA.B.A = 0xff; + } + else + { + APUClearOverflow (); + Work8 = pIAPU->YA.W / pIAPU->X; + pIAPU->YA.B.Y = pIAPU->YA.W % pIAPU->X; + pIAPU->YA.B.A = Work8; + } +// XXX How should Overflow, Half Carry, Zero and Negative flags be set?? + // APUSetZN16 (pIAPU->YA.W); + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC++; +} + +void Apu9F () +{ +// XCN A + pIAPU->YA.B.A = (pIAPU->YA.B.A >> 4) | (pIAPU->YA.B.A << 4); + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC++; +} + +void ApuA4 () +{ +// SBC A, dp + Work8 = S9xAPUGetByteZ (OP1); + SBC (pIAPU->YA.B.A, Work8); + pIAPU->PC += 2; +} + +void ApuA5 () +{ +// SBC A, abs + Absolute (); + Work8 = S9xAPUGetByte (pIAPU->Address); + SBC (pIAPU->YA.B.A, Work8); + pIAPU->PC += 3; +} + +void ApuA6 () +{ +// SBC A, (X) + Work8 = S9xAPUGetByteZ (pIAPU->X); + SBC (pIAPU->YA.B.A, Work8); + pIAPU->PC++; +} + +void ApuA7 () +{ +// SBC A,(dp+X) + IndexedXIndirect (); + Work8 = S9xAPUGetByte (pIAPU->Address); + SBC (pIAPU->YA.B.A, Work8); + pIAPU->PC += 2; +} + +void ApuA8 () +{ +// SBC A,#00 + Work8 = OP1; + SBC (pIAPU->YA.B.A, Work8); + pIAPU->PC += 2; +} + +void ApuA9 () +{ +// SBC dp(dest), dp(src) + Work8 = S9xAPUGetByteZ (OP1); + W1 = S9xAPUGetByteZ (OP2); + SBC (W1, Work8); + S9xAPUSetByteZ (W1, OP2); + pIAPU->PC += 3; +} + +void ApuB4 () +{ +// SBC A, dp+X + Work8 = S9xAPUGetByteZ (OP1 + pIAPU->X); + SBC (pIAPU->YA.B.A, Work8); + pIAPU->PC += 2; +} + +void ApuB5 () +{ +// SBC A,abs+X + AbsoluteX (); + Work8 = S9xAPUGetByte (pIAPU->Address); + SBC (pIAPU->YA.B.A, Work8); + pIAPU->PC += 3; +} + +void ApuB6 () +{ +// SBC A,abs+Y + AbsoluteY (); + Work8 = S9xAPUGetByte (pIAPU->Address); + SBC (pIAPU->YA.B.A, Work8); + pIAPU->PC += 3; +} + +void ApuB7 () +{ +// SBC A,(dp)+Y + IndirectIndexedY (); + Work8 = S9xAPUGetByte (pIAPU->Address); + SBC (pIAPU->YA.B.A, Work8); + pIAPU->PC += 2; +} + +void ApuB8 () +{ +// SBC dp,#00 + Work8 = OP1; + W1 = S9xAPUGetByteZ (OP2); + SBC (W1, Work8); + S9xAPUSetByteZ (W1, OP2); + pIAPU->PC += 3; +} + +void ApuB9 () +{ +// SBC (X),(Y) + W1 = S9xAPUGetByteZ (pIAPU->X); + Work8 = S9xAPUGetByteZ (pIAPU->YA.B.Y); + SBC (W1, Work8); + S9xAPUSetByteZ (W1, pIAPU->X); + pIAPU->PC++; +} + +void ApuAF () +{ +// MOV (X)+, A + S9xAPUSetByteZ (pIAPU->YA.B.A, pIAPU->X++); + pIAPU->PC++; +} + +void ApuBE () +{ +// DAS + if ((pIAPU->YA.B.A & 0x0f) > 9 || !APUCheckHalfCarry()) + { + pIAPU->YA.B.A -= 6; + } + if (pIAPU->YA.B.A > 0x9f || !pIAPU->_Carry) + { + pIAPU->YA.B.A -= 0x60; + APUClearCarry (); + } + else { APUSetCarry (); } + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC++; +} + +void ApuBF () +{ +// MOV A,(X)+ + pIAPU->YA.B.A = S9xAPUGetByteZ (pIAPU->X++); + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC++; +} + +void ApuC0 () +{ +// DI + APUClearInterrupt (); + pIAPU->PC++; +} + +void ApuA0 () +{ +// EI + APUSetInterrupt (); + pIAPU->PC++; +} + +void ApuC4 () +{ +// MOV dp,A + S9xAPUSetByteZ (pIAPU->YA.B.A, OP1); + pIAPU->PC += 2; +} + +void ApuC5 () +{ +// MOV abs,A + Absolute (); + S9xAPUSetByte (pIAPU->YA.B.A, pIAPU->Address); + pIAPU->PC += 3; +} + +void ApuC6 () +{ +// MOV (X), A + S9xAPUSetByteZ (pIAPU->YA.B.A, pIAPU->X); + pIAPU->PC++; +} + +void ApuC7 () +{ +// MOV (dp+X),A + IndexedXIndirect (); + S9xAPUSetByte (pIAPU->YA.B.A, pIAPU->Address); + pIAPU->PC += 2; +} + +void ApuC9 () +{ +// MOV abs,X + Absolute (); + S9xAPUSetByte (pIAPU->X, pIAPU->Address); + pIAPU->PC += 3; +} + +void ApuCB () +{ +// MOV dp,Y + S9xAPUSetByteZ (pIAPU->YA.B.Y, OP1); + pIAPU->PC += 2; +} + +void ApuCC () +{ +// MOV abs,Y + Absolute (); + S9xAPUSetByte (pIAPU->YA.B.Y, pIAPU->Address); + pIAPU->PC += 3; +} + +void ApuCD () +{ +// MOV X,#00 + pIAPU->X = OP1; + APUSetZN8 (pIAPU->X); + pIAPU->PC += 2; +} + +void ApuCF () +{ +// MUL YA + pIAPU->YA.W = (uint16) pIAPU->YA.B.A * pIAPU->YA.B.Y; + APUSetZN16 (pIAPU->YA.W); + pIAPU->PC++; +} + +void ApuD4 () +{ +// MOV dp+X, A + S9xAPUSetByteZ (pIAPU->YA.B.A, OP1 + pIAPU->X); + pIAPU->PC += 2; +} + +void ApuD5 () +{ +// MOV abs+X,A + AbsoluteX (); + S9xAPUSetByte (pIAPU->YA.B.A, pIAPU->Address); + pIAPU->PC += 3; +} + +void ApuD6 () +{ +// MOV abs+Y,A + AbsoluteY (); + S9xAPUSetByte (pIAPU->YA.B.A, pIAPU->Address); + pIAPU->PC += 3; +} + +void ApuD7 () +{ +// MOV (dp)+Y,A + IndirectIndexedY (); + S9xAPUSetByte (pIAPU->YA.B.A, pIAPU->Address); + pIAPU->PC += 2; +} + +void ApuD8 () +{ +// MOV dp,X + S9xAPUSetByteZ (pIAPU->X, OP1); + pIAPU->PC += 2; +} + +void ApuD9 () +{ +// MOV dp+Y,X + S9xAPUSetByteZ (pIAPU->X, OP1 + pIAPU->YA.B.Y); + pIAPU->PC += 2; +} + +void ApuDB () +{ +// MOV dp+X,Y + S9xAPUSetByteZ (pIAPU->YA.B.Y, OP1 + pIAPU->X); + pIAPU->PC += 2; +} + +void ApuDF () +{ +// DAA + if ((pIAPU->YA.B.A & 0x0f) > 9 || APUCheckHalfCarry()) + { + if(pIAPU->YA.B.A > 0xf0) APUSetCarry (); + pIAPU->YA.B.A += 6; + //APUSetHalfCarry (); Intel procs do this, but this is a Sony proc... + } + //else { APUClearHalfCarry (); } ditto as above + if (pIAPU->YA.B.A > 0x9f || pIAPU->_Carry) + { + pIAPU->YA.B.A += 0x60; + APUSetCarry (); + } + else { APUClearCarry (); } + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC++; +} + +void ApuE4 () +{ +// MOV A, dp + pIAPU->YA.B.A = S9xAPUGetByteZ (OP1); + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC += 2; +} + +void ApuE5 () +{ +// MOV A,abs + Absolute (); + pIAPU->YA.B.A = S9xAPUGetByte (pIAPU->Address); + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC += 3; +} + +void ApuE6 () +{ +// MOV A,(X) + pIAPU->YA.B.A = S9xAPUGetByteZ (pIAPU->X); + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC++; +} + +void ApuE7 () +{ +// MOV A,(dp+X) + IndexedXIndirect (); + pIAPU->YA.B.A = S9xAPUGetByte (pIAPU->Address); + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC += 2; +} + +void ApuE8 () +{ +// MOV A,#00 + pIAPU->YA.B.A = OP1; + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC += 2; +} + +void ApuE9 () +{ +// MOV X, abs + Absolute (); + pIAPU->X = S9xAPUGetByte (pIAPU->Address); + APUSetZN8 (pIAPU->X); + pIAPU->PC += 3; +} + +void ApuEB () +{ +// MOV Y,dp + pIAPU->YA.B.Y = S9xAPUGetByteZ (OP1); + APUSetZN8 (pIAPU->YA.B.Y); + pIAPU->PC += 2; +} + +void ApuEC () +{ +// MOV Y,abs + Absolute (); + pIAPU->YA.B.Y = S9xAPUGetByte (pIAPU->Address); + APUSetZN8 (pIAPU->YA.B.Y); + pIAPU->PC += 3; +} + +void ApuF4 () +{ +// MOV A, dp+X + pIAPU->YA.B.A = S9xAPUGetByteZ (OP1 + pIAPU->X); + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC += 2; +} + +void ApuF5 () +{ +// MOV A, abs+X + AbsoluteX (); + pIAPU->YA.B.A = S9xAPUGetByte (pIAPU->Address); + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC += 3; +} + +void ApuF6 () +{ +// MOV A, abs+Y + AbsoluteY (); + pIAPU->YA.B.A = S9xAPUGetByte (pIAPU->Address); + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC += 3; +} + +void ApuF7 () +{ +// MOV A, (dp)+Y + IndirectIndexedY (); + pIAPU->YA.B.A = S9xAPUGetByte (pIAPU->Address); + APUSetZN8 (pIAPU->YA.B.A); + pIAPU->PC += 2; +} + +void ApuF8 () +{ +// MOV X,dp + pIAPU->X = S9xAPUGetByteZ (OP1); + APUSetZN8 (pIAPU->X); + pIAPU->PC += 2; +} + +void ApuF9 () +{ +// MOV X,dp+Y + pIAPU->X = S9xAPUGetByteZ (OP1 + pIAPU->YA.B.Y); + APUSetZN8 (pIAPU->X); + pIAPU->PC += 2; +} + +void ApuFA () +{ +// MOV dp(dest),dp(src) + S9xAPUSetByteZ (S9xAPUGetByteZ (OP1), OP2); + pIAPU->PC += 3; +} + +void ApuFB () +{ +// MOV Y,dp+X + pIAPU->YA.B.Y = S9xAPUGetByteZ (OP1 + pIAPU->X); + APUSetZN8 (pIAPU->YA.B.Y); + pIAPU->PC += 2; +} + +//#if defined(ASM_SPC700) +#undef INLINE +#define INLINE extern "C" +#include "apumem.h" +/* +#elif defined(NO_INLINE_SET_GET) +#undef INLINE +#define INLINE +#include "apumem.h" +#endif +*/ + +void (*S9xApuOpcodes[256]) (void) = +{ + Apu00, Apu01, Apu02, Apu03, Apu04, Apu05, Apu06, Apu07, + Apu08, Apu09, Apu0A, Apu0B, Apu0C, Apu0D, Apu0E, Apu0F, + Apu10, Apu11, Apu12, Apu13, Apu14, Apu15, Apu16, Apu17, + Apu18, Apu19, Apu1A, Apu1B, Apu1C, Apu1D, Apu1E, Apu1F, + Apu20, Apu21, Apu22, Apu23, Apu24, Apu25, Apu26, Apu27, + Apu28, Apu29, Apu2A, Apu2B, Apu2C, Apu2D, Apu2E, Apu2F, + Apu30, Apu31, Apu32, Apu33, Apu34, Apu35, Apu36, Apu37, + Apu38, Apu39, Apu3A, Apu3B, Apu3C, Apu3D, Apu3E, Apu3F, + Apu40, Apu41, Apu42, Apu43, Apu44, Apu45, Apu46, Apu47, + Apu48, Apu49, Apu4A, Apu4B, Apu4C, Apu4D, Apu4E, Apu4F, + Apu50, Apu51, Apu52, Apu53, Apu54, Apu55, Apu56, Apu57, + Apu58, Apu59, Apu5A, Apu5B, Apu5C, Apu5D, Apu5E, Apu5F, + Apu60, Apu61, Apu62, Apu63, Apu64, Apu65, Apu66, Apu67, + Apu68, Apu69, Apu6A, Apu6B, Apu6C, Apu6D, Apu6E, Apu6F, + Apu70, Apu71, Apu72, Apu73, Apu74, Apu75, Apu76, Apu77, + Apu78, Apu79, Apu7A, Apu7B, Apu7C, Apu7D, Apu7E, Apu7F, + Apu80, Apu81, Apu82, Apu83, Apu84, Apu85, Apu86, Apu87, + Apu88, Apu89, Apu8A, Apu8B, Apu8C, Apu8D, Apu8E, Apu8F, + Apu90, Apu91, Apu92, Apu93, Apu94, Apu95, Apu96, Apu97, + Apu98, Apu99, Apu9A, Apu9B, Apu9C, Apu9D, Apu9E, Apu9F, + ApuA0, ApuA1, ApuA2, ApuA3, ApuA4, ApuA5, ApuA6, ApuA7, + ApuA8, ApuA9, ApuAA, ApuAB, ApuAC, ApuAD, ApuAE, ApuAF, + ApuB0, ApuB1, ApuB2, ApuB3, ApuB4, ApuB5, ApuB6, ApuB7, + ApuB8, ApuB9, ApuBA, ApuBB, ApuBC, ApuBD, ApuBE, ApuBF, + ApuC0, ApuC1, ApuC2, ApuC3, ApuC4, ApuC5, ApuC6, ApuC7, + ApuC8, ApuC9, ApuCA, ApuCB, ApuCC, ApuCD, ApuCE, ApuCF, + ApuD0, ApuD1, ApuD2, ApuD3, ApuD4, ApuD5, ApuD6, ApuD7, + ApuD8, ApuD9, ApuDA, ApuDB, ApuDC, ApuDD, ApuDE, ApuDF, + ApuE0, ApuE1, ApuE2, ApuE3, ApuE4, ApuE5, ApuE6, ApuE7, + ApuE8, ApuE9, ApuEA, ApuEB, ApuEC, ApuED, ApuEE, ApuEF, + ApuF0, ApuF1, ApuF2, ApuF3, ApuF4, ApuF5, ApuF6, ApuF7, + ApuF8, ApuF9, ApuFA, ApuFB, ApuFC, ApuFD, ApuFE, ApuFF +}; + + +struct SIAPU IAPU2; +struct SIAPU *pIAPU; + +void APUCompare() +{ + IAPU.icount++; + + if(IAPU.PC != IAPU2.PC) { + dprintf("!%02X %5i PC %08X vs %08X", IAPU.opcode, IAPU.icount, IAPU.PC, IAPU2.PC); + exit(1); + } + + if(IAPU.YA.W != IAPU2.YA.W) { + dprintf("!%02X %5i YA %04X vs %04X", IAPU.opcode, IAPU.icount, IAPU.YA.W, IAPU2.YA.W); + dprintf(" (%04X / %02X)", IAPU.ya_prev, IAPU.x_prev); + exit(1); + } + + if((IAPU.P&0x7d) != (IAPU2.P&0x7d)) { + dprintf("!%02X %5i P %02X vs %02X", IAPU.opcode, IAPU.icount, IAPU.P, IAPU2.P); + exit(1); + } + + if(IAPU.X != IAPU2.X) { + dprintf("!%02X %5i X %02X vs %02X", IAPU.opcode, IAPU.icount, IAPU.X, IAPU2.X); + exit(1); + } + + if(IAPU.S != IAPU2.S) { + dprintf("!%02X %5i S %02X vs %02X", IAPU.opcode, IAPU.icount, IAPU.S, IAPU2.S); + exit(1); + } + + if((IAPU._Zero == 0) != (IAPU2._Zero == 0)) { + dprintf("!%02X %5i _Zero %02X vs %02X", IAPU.opcode, IAPU.icount, IAPU._Zero, IAPU2._Zero); + exit(1); + } + + if((IAPU._Zero & 0x80) != (IAPU2._Zero & 0x80)) { + dprintf("!%02X %5i _Zero(n) %02X vs %02X", IAPU.opcode, IAPU.icount, IAPU._Zero, IAPU2._Zero); + exit(1); + } + + if(IAPU.memread_addr != IAPU2.memread_addr) { + dprintf("!%02X %5i memread_addr %04X vs %04X", IAPU.opcode, IAPU.icount, IAPU.memread_addr, IAPU2.memread_addr); + exit(1); + } + + if(IAPU.memread_data != IAPU2.memread_data) { + dprintf("!%02X %5i memread_data %02X@%04X vs %02X@%04X", IAPU.opcode, IAPU.icount, IAPU.memread_data, IAPU.memread_addr, IAPU2.memread_data, IAPU2.memread_addr); + exit(1); + } + + if(IAPU.memwrite_addr != IAPU2.memwrite_addr) { + dprintf("!%02X %5i memwrite_addr %04X vs %04X", IAPU.opcode, IAPU.icount, IAPU.memwrite_addr, IAPU2.memwrite_addr); + exit(1); + } + + if(IAPU.memwrite_data != IAPU2.memwrite_data) { + dprintf("!%02X %5i memwrite_data %02X@%04X vs %02X@%04X", IAPU.opcode, IAPU.icount, IAPU.memwrite_data, IAPU.memwrite_addr, IAPU2.memwrite_data, IAPU2.memwrite_addr); + exit(1); + } +} + + -- cgit v1.2.3