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/Makefile | 13 + src/spc700/Makefile.win | 15 + src/spc700/debug/apu.h | 195 ++++ src/spc700/debug/apumem.h | 222 ++++ src/spc700/debug/port.h | 497 +++++++++ src/spc700/debug/spc700.cpp | 2600 +++++++++++++++++++++++++++++++++++++++++++ src/spc700/debug/spc700.h | 172 +++ src/spc700/spcgen.c | 2164 +++++++++++++++++++++++++++++++++++ src/spc700/spcgen.dsp | 88 ++ src/spc700/spcgen.dsw | 29 + src/spc700/spcgen.ncb | Bin 0 -> 41984 bytes src/spc700/spcgen.opt | Bin 0 -> 53760 bytes src/spc700/spcgen.plg | 32 + 13 files changed, 6027 insertions(+) create mode 100644 src/spc700/Makefile create mode 100644 src/spc700/Makefile.win create mode 100644 src/spc700/debug/apu.h create mode 100644 src/spc700/debug/apumem.h create mode 100644 src/spc700/debug/port.h create mode 100644 src/spc700/debug/spc700.cpp create mode 100644 src/spc700/debug/spc700.h create mode 100644 src/spc700/spcgen.c create mode 100644 src/spc700/spcgen.dsp create mode 100644 src/spc700/spcgen.dsw create mode 100644 src/spc700/spcgen.ncb create mode 100644 src/spc700/spcgen.opt create mode 100644 src/spc700/spcgen.plg (limited to 'src/spc700') diff --git a/src/spc700/Makefile b/src/spc700/Makefile new file mode 100644 index 0000000..e412de9 --- /dev/null +++ b/src/spc700/Makefile @@ -0,0 +1,13 @@ +CFLAGS = -Wall + +all : spc700a.s + +spc700a.s : spcgen + ./spcgen + +spcgen : spcgen.o + + +clean : + $(RM) spc700a.s spcgen spcgen.o + diff --git a/src/spc700/Makefile.win b/src/spc700/Makefile.win new file mode 100644 index 0000000..06095b0 --- /dev/null +++ b/src/spc700/Makefile.win @@ -0,0 +1,15 @@ +# Makefile for MS Visual C + +ALL : spc700a.s + +spc700a.s : spcgen.exe + spcgen.exe + +spcgen.exe : + cl /W3 spcgen.c + + +CLEAN : + -@erase spc700a.s + -@erase spcgen.exe + -@erase spcgen.obj diff --git a/src/spc700/debug/apu.h b/src/spc700/debug/apu.h new file mode 100644 index 0000000..dd0451c --- /dev/null +++ b/src/spc700/debug/apu.h @@ -0,0 +1,195 @@ +/* + * 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. + */ +#ifndef _apu_h_ +#define _apu_h_ + +#include "spc700.h" + +/* +typedef union +{ + struct { uint8 A, Y; } B; + uint16 W; +} YAndA; +*/ + +struct SIAPU +{ + uint8 *DirectPage; // 0x00 + uint32 Address; // 0x04 c core only + uint8 *WaitAddress1; // 0x08 + uint8 *WaitAddress2; // 0x0C + uint32 WaitCounter; // 0x10 + uint8 *ShadowRAM; // 0x14 + uint8 *CachedSamples; // 0x18 + uint8 _Carry; // 0x1C c core only + uint8 _Overflow; // 0x1D c core only + uint8 Bit; // 0x1E c core only + uint8 pad0; + uint32 TimerErrorCounter; // 0x20 + uint32 Scanline; // 0x24 + int32 OneCycle; // 0x28 + int32 TwoCycles; // 0x2C + // notaz: reordered and moved everything here, for faster context load/save + uint32 *asmJumpTab; // 0x30 + uint8 *PC; // 0x34 + YAndA YA; // 0x38 0x0000YYAA + uint8 P; // 0x3C flags: NODBHIZC + uint8 pad1; + uint8 pad2; + uint8 _Zero; // 0x3F Z=0, when this!=0; also stores neg flag in &0x80 + uint8 X; // 0x40 + uint8 S; // 0x41 stack pointer, default: 0xff + uint16 pad3; + uint8 *RAM; // 0x44 + uint8 *ExtraRAM; // 0x48 shortcut to APU.ExtraRAM + + uint16 memread_addr; + uint8 memread_data; + uint16 memwrite_addr; + uint8 memwrite_data; + int icount; + uint8 opcode; + uint16 ya_prev; + uint8 x_prev; +}; + +struct SAPU +{ + int32 Cycles; + bool8 ShowROM; + uint8 Flags; + uint8 KeyedChannels; + uint8 OutPorts [4]; + uint8 DSP [0x80]; + uint8 ExtraRAM [64]; + uint16 Timer [3]; + uint16 TimerTarget [3]; + bool8 TimerEnabled [3]; + bool8 TimerValueWritten [3]; +}; + +EXTERN_C struct SAPU APU; +EXTERN_C struct SIAPU IAPU; +EXTERN_C struct SIAPU IAPU2; +EXTERN_C struct SIAPU *pIAPU; + +STATIC inline void S9xAPUUnpackStatus() +{ + IAPU._Zero =((IAPU.P & Zero) == 0) | (IAPU.P & Negative); + IAPU._Carry = (IAPU.P & Carry); + IAPU._Overflow = (IAPU.P & Overflow); +} + +STATIC inline void S9xAPUPackStatus() +{ + IAPU.P &= ~(Zero | Negative | Carry | Overflow); + if(IAPU._Carry) IAPU.P |= Carry; + if(!IAPU._Zero) IAPU.P |= Zero; + if(IAPU._Overflow) IAPU.P |= Overflow; + if(IAPU._Zero & 0x80) IAPU.P |= Negative; +} + +START_EXTERN_C +void S9xResetAPU (void); +bool8 S9xInitAPU (); +void S9xDeinitAPU (); +void S9xDecacheSamples (); +int S9xTraceAPU (); +int S9xAPUOPrint (char *buffer, uint16 Address); +void S9xSetAPUControl (uint8 byte); +void S9xSetAPUDSP (uint8 byte); +uint8 S9xGetAPUDSP (); +void S9xSetAPUTimer (uint16 Address, uint8 byte); +bool8 S9xInitSound (int quality, bool8 stereo, int buffer_size); +void S9xOpenCloseSoundTracingFile (bool8); +void S9xPrintAPUState (); +extern int32 S9xAPUCycles [256]; // Scaled cycle lengths +extern int32 S9xAPUCycleLengths [256]; // Raw data. +extern void (*S9xApuOpcodes [256]) (void); +extern void (*S9xApuOpcodesReal [256]) (void); +void APUCompare(); +END_EXTERN_C + + +#define APU_VOL_LEFT 0x00 +#define APU_VOL_RIGHT 0x01 +#define APU_P_LOW 0x02 +#define APU_P_HIGH 0x03 +#define APU_SRCN 0x04 +#define APU_ADSR1 0x05 +#define APU_ADSR2 0x06 +#define APU_GAIN 0x07 +#define APU_ENVX 0x08 +#define APU_OUTX 0x09 + +#define APU_MVOL_LEFT 0x0c +#define APU_MVOL_RIGHT 0x1c +#define APU_EVOL_LEFT 0x2c +#define APU_EVOL_RIGHT 0x3c +#define APU_KON 0x4c +#define APU_KOFF 0x5c +#define APU_FLG 0x6c +#define APU_ENDX 0x7c + +#define APU_EFB 0x0d +#define APU_PMON 0x2d +#define APU_NON 0x3d +#define APU_EON 0x4d +#define APU_DIR 0x5d +#define APU_ESA 0x6d +#define APU_EDL 0x7d + +#define APU_C0 0x0f +#define APU_C1 0x1f +#define APU_C2 0x2f +#define APU_C3 0x3f +#define APU_C4 0x4f +#define APU_C5 0x5f +#define APU_C6 0x6f +#define APU_C7 0x7f + +#define APU_SOFT_RESET 0x80 +#define APU_MUTE 0x40 +#define APU_ECHO_DISABLED 0x20 + +#define FREQUENCY_MASK 0x3fff +#endif diff --git a/src/spc700/debug/apumem.h b/src/spc700/debug/apumem.h new file mode 100644 index 0000000..b1b5f65 --- /dev/null +++ b/src/spc700/debug/apumem.h @@ -0,0 +1,222 @@ +/* + * 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. + */ +#ifndef _apumemory_h_ +#define _apumemory_h_ + +START_EXTERN_C +extern uint8 W4; +extern uint8 APUROM[64]; +END_EXTERN_C + +// TODO: restore nondebug version + +INLINE uint8 S9xAPUGetByteZ (uint8 Address) +{ + uint8 res = 0; + pIAPU->memread_addr = Address; + + if (Address >= 0xf0 && pIAPU->DirectPage == pIAPU->RAM) + { + if (Address >= 0xf4 && Address <= 0xf7) + { +#ifdef SPC700_SHUTDOWN + pIAPU->WaitAddress2 = pIAPU->WaitAddress1; + pIAPU->WaitAddress1 = pIAPU->PC; +#endif + res = (pIAPU->RAM [Address]); + } + else if (Address >= 0xfd) + { +#ifdef SPC700_SHUTDOWN + pIAPU->WaitAddress2 = pIAPU->WaitAddress1; + pIAPU->WaitAddress1 = pIAPU->PC; +#endif + uint8 t = pIAPU->RAM [Address]; + if(pIAPU != &IAPU) + pIAPU->RAM [Address] = 0; + res = (t); + } + else if (Address == 0xf3) { + res = (S9xGetAPUDSP ()); + } + else res = (pIAPU->RAM [Address]); + } + else + res = (pIAPU->DirectPage [Address]); + + pIAPU->memread_data = res; + return res; +} + +INLINE void S9xAPUSetByteZ (uint8 val, uint8 Address) +{ + pIAPU->memwrite_addr = Address; + pIAPU->memwrite_data = val; + + if(pIAPU == &IAPU) return; + + if (Address >= 0xf0 && pIAPU->DirectPage == pIAPU->RAM) + { + if (Address == 0xf3) + S9xSetAPUDSP (val); + else + if (Address >= 0xf4 && Address <= 0xf7) + APU.OutPorts [Address - 0xf4] = val; + else + if (Address == 0xf1) + S9xSetAPUControl (val); + else + if (Address < 0xfd) + { + pIAPU->RAM [Address] = val; + if (Address >= 0xfa) + { + if (val == 0) + APU.TimerTarget [Address - 0xfa] = 0x100; + else + APU.TimerTarget [Address - 0xfa] = val; + } + } + } + else + pIAPU->DirectPage [Address] = val; +} + +INLINE uint8 S9xAPUGetByte (uint32 Address) +{ + Address &= 0xffff; + uint8 res = 0; + pIAPU->memread_addr = Address; + + if (Address <= 0xff && Address >= 0xf0) + { + if (Address >= 0xf4 && Address <= 0xf7) + { +#ifdef SPC700_SHUTDOWN + pIAPU->WaitAddress2 = pIAPU->WaitAddress1; + pIAPU->WaitAddress1 = pIAPU->PC; +#endif + res = (pIAPU->RAM [Address]); + } + else if (Address == 0xf3) { + res = (S9xGetAPUDSP ()); + } + else if (Address >= 0xfd) + { +#ifdef SPC700_SHUTDOWN + pIAPU->WaitAddress2 = pIAPU->WaitAddress1; + pIAPU->WaitAddress1 = pIAPU->PC; +#endif + uint8 t = pIAPU->RAM [Address]; + if(pIAPU != &IAPU) + pIAPU->RAM [Address] = 0; + res = (t); + } + else res = (pIAPU->RAM [Address]); + } + else + res = (pIAPU->RAM [Address]); + + pIAPU->memread_data = res; + return res; +} + +INLINE void S9xAPUSetByte (uint8 val, uint32 Address) +{ + Address &= 0xffff; + pIAPU->memwrite_addr = Address; + pIAPU->memwrite_data = val; + + if(pIAPU == &IAPU) return; + + if (Address <= 0xff && Address >= 0xf0) + { + if (Address == 0xf3) + S9xSetAPUDSP (val); + else + if (Address >= 0xf4 && Address <= 0xf7) + APU.OutPorts [Address - 0xf4] = val; + else + if (Address == 0xf1) + S9xSetAPUControl (val); + else + if (Address < 0xfd) + { + pIAPU->RAM [Address] = val; + if (Address >= 0xfa) + { + if (val == 0) + APU.TimerTarget [Address - 0xfa] = 0x100; + else + APU.TimerTarget [Address - 0xfa] = val; + } + } + } + else + { +#if 0 +if (Address >= 0x2500 && Address <= 0x2504) +printf ("%06d %04x <- %02x\n", ICPU.Scanline, Address, val); +if (Address == 0x26c6) +{ + extern FILE *apu_trace; + extern FILE *trace; + APU.Flags |= TRACE_FLAG; + CPU.Flags |= TRACE_FLAG; + if (apu_trace == NULL) + apu_trace = fopen ("aputrace.log", "wb"); + if (trace == NULL) + trace = fopen ("trace.log", "wb"); + printf ("TRACING SWITCHED ON\n"); +} +#endif + if (Address < 0xffc0) + pIAPU->RAM [Address] = val; + else + { + APU.ExtraRAM [Address - 0xffc0] = val; + if (!APU.ShowROM) + pIAPU->RAM [Address] = val; + } + } +} + +#endif diff --git a/src/spc700/debug/port.h b/src/spc700/debug/port.h new file mode 100644 index 0000000..4d7eede --- /dev/null +++ b/src/spc700/debug/port.h @@ -0,0 +1,497 @@ +/* + * 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. + */ +#ifndef _PORT_H_ +#define _PORT_H_ + + +// horrible mess here + +int yo_rand(void); + +#ifdef __SYMBIAN32__ + +// debug +#ifdef __DEBUG_PRINT +#undef printf +extern "C" void dprintf(char *format, ...); +#define printf dprintf +#else +#define printf(x...) +#define dprintf(x...) +#endif + +#include + +#define PIXEL_FORMAT RGB565 +#undef GFX_MULTI_FORMAT + +#ifndef snes9x_types_defined +#define snes9x_types_defined + +typedef unsigned char bool8; +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef signed char int8; +typedef signed short int16; +typedef signed int int32; +typedef unsigned int uint32; +typedef long long int64; // correct? +#endif + +#include "pixform.h" + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#if defined(__cplusplus) || defined(c_plusplus) +#define EXTERN_C extern "C" +#define START_EXTERN_C extern "C" { +#define END_EXTERN_C } +#else +#define EXTERN_C extern +#define START_EXTERN_C +#define END_EXTERN_C +#endif + + +#ifndef PATH_MAX +#define PATH_MAX 0x100 // == KMaxFileName +#endif + +/* +#define _MAX_DIR PATH_MAX +#define _MAX_DRIVE 1 +#define _MAX_FNAME PATH_MAX +#define _MAX_EXT 3 +*/ +#define _MAX_PATH PATH_MAX + + +#define ZeroMemory(a,b) memset((a),0,(b)) + +EXTERN_C void S9xGenerateSound (); + +#define SLASH_STR "\\" +#define SLASH_CHAR '\\' + +#define LSB_FIRST +#define STATIC static +#define FASTCALL +#define INLINE inline +#define VOID void +#define PACKING __attribute__ ((packed)) +#define ALIGN_BY_ONE __attribute__ ((aligned (1), packed)) +#define gp32_pause() +#define gm_memset memset +#define CHECK_SOUND() +#define CPU_SHUTDOWN +#define VAR_CYCLES +#define SPC700_C +#define EXECUTE_SUPERFX_PER_LINE +#define OLD_COLOUR_BLENDING +#define _NEWPPU_ +#define gp32_atoi atoi +//#define SPC700_SHUTDOWN // incompatible with ASM_SPC700 +// notaz +//#define ASM_SPC700 +#define SUPER_FX + +#ifndef TITLE +#define TITLE "Snes9x" +#endif + + +#else // __SYMBIAN32__ + + +//#include + +#ifdef __GP32__ + + +//#define __GP32_APUCACHE__ + +#define CHECK_SOUND() + +#define VERSION_MAJOR 0 +#define VERSION_MINOR 3 + +long *gp32_fopen (char *fname,char *mode); +void gp32_fclose (long *s); +long gp32_fread (unsigned char *ptr,long lg,long *s); +long gp32_fwrite (unsigned char *ptr,long lg,long *s); +void gp32_fseek (long position,int ref,long *s); + + +//#undef ZLIB +//#define ZLIB +#define UNZIP_SUPPORT + + +#define SPC700_SHUTDOWN +#define CPU_SHUTDOWN +#define VAR_CYCLES +#define SPC700_C +//#define ZSNES_C4 +//#define ZSNES_FX +#define EXECUTE_SUPERFX_PER_LINE +//#define THREADCPU + + +//#define USE_GLIDE +//#define USE_OPENGL +//#define NETPLAY_SUPPORT +//#define FMOD_SUPPORT +#define OLD_COLOUR_BLENDING + +#endif // __GP32__ + +#ifndef STORM +#ifdef __GP32__ + +extern "C" +{ +#include "gpdef.h" +#include "gpstdlib.h" +#include "gpgraphic.h" +#include "gpfont.h" +#include "gpmm.h" +#include "gpmem.h" +#include "gpstdio.h" +} + +#undef byte +#undef word +#undef dword +#undef qword + +/*typedef unsigned long bool8_32; +typedef unsigned long uint8_32; +typedef unsigned long uint16_32; +typedef long int8_32; +typedef long int16_32;*/ + +#undef time_t +#define time_t long + +char *gp32_strrchr(char *s, char c); +char gp32_toupper(char c); +char *gp32_strupr(char *s); +char *gp32_strlwr(char *s); +int gp32_memcmp(char *s1,char *s2, int lg); +int gp32_strncmp(char *s1,char *s2, int lg); +int gp32_strcasecmp(const char *s1, const char *s2 ); +int gp32_strncasecmp(const char *s1, const char *s2, unsigned n); +long gp32_time(void); +int gp32_pause(void); +int gp32_atoi(char *s); + +#define malloc gm_malloc +#define free gm_free +#define memcpy gm_memcpy + +#define strcpy gm_strcpy +#define strncpy gm_strncpy +#define strcat gm_strcat +#define memset gm_memset +#define memmove gm_memcpy +#define strlen gm_lstrlen +#define strcmp gm_compare +#define memcmp(a,b,c) gp32_memcmp((char*)a,(char*)b,c) +#define strrchr(a,b) gp32_strrchr((char*)a,(char)b) +#define strncmp(a,b,c) gp32_strncmp((char*)a,(char*)b,(int)c) +#define strlwr gp32_strlwr +//#define atoi gp32_atoi + +#define islower(a) ((a>='a')&&(a<='z')) +#define isdigit(a) ((a>='0')&&(a<='9')) +#define isalpha(a) (((a>='0')&&(a<='9'))||((a>='0')&&(a<='9'))||((a>='A')&&(a<='Z'))) +#define toupper(a) (islower(a)?a+'A'-'a':a) + +#define sprintf gm_sprintf + + + +void gp32_printf(char *a); +void gp32_GpTextOut(unsigned char *buffer,int X,int Y,char *A,int col,int bold); +void gp32_GpTextOutBig(unsigned char *buffer,int X,int Y,char *A,int col,int bold); +#define printf //(a) gp32_printf(a) + +#define strcasecmp gp32_strcasecmp +#define strncasecmp gp32_strncasecmp + +#define time(a) gp32_time() + +#define _NEWPPU_ + +//#define PROFILING + +#ifdef PROFILING +void gp32_profile_start(int a); +void gp32_profile_end(int a); +#define PROF_START(a) gp32_profile_start(a) +#define PROF_END(a) gp32_profile_end(a) +#endif + +#elif defined(__SYMBIAN32__) // /__GP32__ +#include +#else +#include +#include +#endif +#else // #ifndef STORM +#include +#include +#endif + +//#include + +#define PIXEL_FORMAT RGB565 +#undef GFX_MULTI_FORMAT + +#if defined(TARGET_OS_MAC) && TARGET_OS_MAC + +#include "zlib.h" +#define ZLIB +#define EXECUTE_SUPERFX_PER_LINE +#define SOUND +#define VAR_CYCLES +#define CPU_SHUTDOWN +#define SPC700_SHUTDOWN +#define PIXEL_FORMAT RGB555 +#define CHECK_SOUND() +#define M_PI 3.14159265359 +#undef _MAX_PATH + +#undef DEBUGGER // Apple Universal Headers sometimes #define DEBUGGER +#undef GFX_MULTI_FORMAT + +int strncasecmp(const char *s1, const char *s2, unsigned n); +int strcasecmp(const char *s1, const char *s2 ); + +#endif + +#ifndef snes9x_types_defined +#define snes9x_types_defined + +typedef unsigned char bool8; + +#ifndef __WIN32kk__ +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef signed char int8; +typedef signed short int16; +typedef signed int int32; +typedef unsigned int uint32; +#ifdef __GP32__ +typedef signed __int64 int64; +//typedef signed long int64; +#else +typedef long long int64; +#endif +#else // __WIN32kk__ + +#ifdef __BORLANDC__ +#include +#else + +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef signed char int8; +typedef short int16; + +#ifndef WSAAPI +// winsock2.h typedefs int32 as well. +typedef long int32; +#endif + +typedef unsigned int uint32; + +#endif // __BORLANDC__ + +typedef __int64 int64; + +#endif // __WIN32kk__ +#endif // snes9x_types_defined +#include "pixform.h" + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifdef STORM +#define EXTERN_C +#define START_EXTERN_C +#define END_EXTERN_C +#else +#if defined(__cplusplus) || defined(c_plusplus) +#define EXTERN_C extern "C" +#define START_EXTERN_C extern "C" { +#define END_EXTERN_C } +#else +#define EXTERN_C extern +#define START_EXTERN_C +#define END_EXTERN_C +#endif +#endif + +#ifndef __WIN32kk__ + +#ifndef PATH_MAX +#define PATH_MAX 1024 +#endif + +#define _MAX_DIR PATH_MAX +#define _MAX_DRIVE 1 +#define _MAX_FNAME PATH_MAX +#define _MAX_EXT PATH_MAX +#define _MAX_PATH PATH_MAX + +#define ZeroMemory(a,b) memset((a),0,(b)) + +#ifndef __WIN32__ +void _makepath (char *path, const char *drive, const char *dir, const char *fname, const char *ext); +void _splitpath (const char *path, char *drive, char *dir, char *fname, char *ext); +#endif + +#else // __WIN32kk__ +#define strcasecmp stricmp +#define strncasecmp strnicmp +#endif + +EXTERN_C void S9xGenerateSound (); + +#ifdef STORM +EXTERN_C int soundsignal; +EXTERN_C void MixSound(void); +//Yes, CHECK_SOUND is getting defined correctly! +#define CHECK_SOUND if (Settings.APUEnabled) if(SetSignalPPC(0L, soundsignal) & soundsignal) MixSound +#else +#ifndef __GP32__ +#define CHECK_SOUND() +#endif +#endif + +#if defined (__DJGPP)||defined(__GP32__) +#define SLASH_STR "\\" +#define SLASH_CHAR '\\' +#else +#define SLASH_STR "/" +#define SLASH_CHAR '/' +#endif + +#ifdef __linux +typedef void (*SignalHandler)(int); +#define SIG_PF SignalHandler +#endif + +#if defined(__i386__) || defined(__i486__) || defined(__i586__) || \ + defined(__WIN32kk__) || defined(__alpha__) +#define LSB_FIRST +#define FAST_LSB_WORD_ACCESS +#define PACKING +#define ALIGN_BY_ONE + +#else + +#ifdef __GP32__ +#define LSB_FIRST +#define STATIC static +#define FASTCALL +#define INLINE inline +#define VOID void +#else +// must be gp2x +#define LSB_FIRST +#define STATIC static +#define FASTCALL +#define INLINE inline +#define VOID void +#define PACKING __attribute__ ((packed)) +#define ALIGN_BY_ONE __attribute__ ((aligned (1), packed)) +#define gp32_pause() +#define gm_memset memset +#define CHECK_SOUND() +#define VERSION_MAJOR 0 +#define VERSION_MINOR 3 +#define SPC700_SHUTDOWN +#define CPU_SHUTDOWN +#define VAR_CYCLES +#define SPC700_C +#define EXECUTE_SUPERFX_PER_LINE +#define OLD_COLOUR_BLENDING +#define _NEWPPU_ +#define gp32_atoi atoi +#endif + +#endif + +#ifdef __sun +#define TITLE "Snes9X: Solaris" +#endif + +#ifdef __linux +#define TITLE "Snes9X: Linux" +#endif + +#ifndef TITLE +#define TITLE "Snes9x" +#endif + +#ifdef STORM +#define STATIC +#define strncasecmp strnicmp +#else +#define STATIC static +#endif + +#endif // !defined(__SYMBIAN32__) + +#endif // _PORT_H_ 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); + } +} + + diff --git a/src/spc700/debug/spc700.h b/src/spc700/debug/spc700.h new file mode 100644 index 0000000..507c247 --- /dev/null +++ b/src/spc700/debug/spc700.h @@ -0,0 +1,172 @@ +/* + * 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. + */ +#ifndef _SPC700_H_ +#define _SPC700_H_ + +#ifdef SPCTOOL +#define NO_CHANNEL_STRUCT +#include "spctool/dsp.h" +#include "spctool/spc700.h" +#include "spctool/soundmod.h" +#endif + + +#define Carry 1 +#define Zero 2 +#define Interrupt 4 +#define HalfCarry 8 +#define BreakFlag 16 +#define DirectPageFlag 32 +#define Overflow 64 +#define Negative 128 + +#define APUClearCarry() (pIAPU->_Carry = 0) +#define APUSetCarry() (pIAPU->_Carry = 1) +#define APUSetInterrupt() (pIAPU->P |= Interrupt) +#define APUClearInterrupt() (pIAPU->P &= ~Interrupt) +#define APUSetHalfCarry() (pIAPU->P |= HalfCarry) +#define APUClearHalfCarry() (pIAPU->P &= ~HalfCarry) +#define APUSetBreak() (pIAPU->P |= BreakFlag) +#define APUClearBreak() (pIAPU->P &= ~BreakFlag) +#define APUSetDirectPage() (pIAPU->P |= DirectPageFlag) +#define APUClearDirectPage() (pIAPU->P &= ~DirectPageFlag) +#define APUSetOverflow() (pIAPU->_Overflow = 1) +#define APUClearOverflow() (pIAPU->_Overflow = 0) + +#define APUCheckZero() (pIAPU->_Zero == 0) +#define APUCheckCarry() (pIAPU->_Carry) +#define APUCheckInterrupt() (pIAPU->P & Interrupt) +#define APUCheckHalfCarry() (pIAPU->P & HalfCarry) +#define APUCheckBreak() (pIAPU->P & BreakFlag) +#define APUCheckDirectPage() (pIAPU->P & DirectPageFlag) +#define APUCheckOverflow() (pIAPU->_Overflow) +#define APUCheckNegative() (pIAPU->_Zero & 0x80) + +//#define APUClearFlags(f) (IAPU.P &= ~(f)) +//#define APUSetFlags(f) (IAPU.P |= (f)) +//#define APUCheckFlag(f) (IAPU.P & (f)) + +typedef union +{ +#ifdef LSB_FIRST + struct { uint8 A, Y; } B; +#else + struct { uint8 Y, A; } B; +#endif + uint16 W; + uint32 _padder; // make sure this whole thing takes 4 bytes +} YAndA; + +struct SAPURegisters{ + uint8 P; + YAndA YA; + uint8 X; + uint8 S; + uint16 PC; +}; + +//EXTERN_C struct SAPURegisters APURegisters; + +// Needed by ILLUSION OF GAIA +//#define ONE_APU_CYCLE 14 +#define ONE_APU_CYCLE 21 + +// Needed by all games written by the software company called Human +//#define ONE_APU_CYCLE_HUMAN 17 +#define ONE_APU_CYCLE_HUMAN 21 + +// 1.953us := 1.024065.54MHz + +// return cycles left (always negative) +extern "C" int spc700_execute(int cycles); +extern "C" uint32 Spc700JumpTab; + +#ifdef SPCTOOL +EXTERN_C int32 ESPC (int32); + +#define APU_EXECUTE() \ +{ \ + int32 l = (CPU.Cycles - CPU.APU_Cycles) / 14; \ + if (l > 0) \ + { \ + l -= _EmuSPC(l); \ + CPU.APU_Cycles += l * 14; \ + } \ +} + +#else + +#ifdef DEBUGGER +#define APU_EXECUTE1() \ +{ \ + if (APU.Flags & TRACE_FLAG) \ + S9xTraceAPU ();\ + CPU.APU_Cycles += S9xAPUCycles [*IAPU.PC]; \ + (*S9xApuOpcodes[*IAPU.PC]) (); \ +} +#else +#define APU_EXECUTE1() \ +{ \ + IAPU.asmJumpTab = &Spc700JumpTab; \ + memcpy(&IAPU2, &IAPU, sizeof(IAPU)); \ + CPU.APU_Cycles += S9xAPUCycles [*IAPU.PC]; \ + IAPU.opcode = *IAPU.PC; \ + pIAPU = &IAPU; \ + (*S9xApuOpcodes[*IAPU.PC]) (); \ + if(IAPU._Carry) IAPU.P |= Carry; else IAPU.P &= ~Carry; \ + if(IAPU._Overflow) IAPU.P |= Overflow; else IAPU.P &= ~Overflow; \ + pIAPU = &IAPU2; \ + spc700_execute(0); \ + APUCompare(); \ + IAPU.ya_prev = IAPU.YA.W; \ + IAPU.x_prev = IAPU.X; \ +} +#endif + +#define APU_EXECUTE(mode) \ +if (CPU.APU_APUExecuting == mode) \ +{\ + while (CPU.APU_Cycles <= CPU.Cycles) \ + APU_EXECUTE1(); \ +} +#endif + +#endif diff --git a/src/spc700/spcgen.c b/src/spc700/spcgen.c new file mode 100644 index 0000000..5a15bd7 --- /dev/null +++ b/src/spc700/spcgen.c @@ -0,0 +1,2164 @@ +// notaz's SPC700 Emulator +// (c) Copyright 2006 notaz, All rights reserved. +// +// Added some modifications by Bitrider 2010-2011. +// +// this is a rewrite of spc700.cpp in ARM asm, inspired by other asm CPU cores like +// Cyclone and DrZ80. It is meant to be used in Snes9x emulator ports for ARM platforms. +// +// notes: +// "Shutdown" mechanism is not supported, so undefine SPC700_SHUTDOWN in your port.h +// code branches backwards over start of memory are not supported +// (never seen any game doing that) +// +// license: +// the code is released under Snes9x license. It would be nice if the word "notaz" +// would appear somewhere in your documentation or your program's "about" screen +// if you use this :) + +/* + * 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. + */ + +int one_apu_cycle[] = {13, 14, 15, 21}; +int current_cycles; + + +// settings +#define VERSION "0.12" +#define APU_EXECUTING_OFF 124 +//#define SPC_DEBUG + + +// includes +#include +#include +#include +#include + + +// timings +int S9xAPUCycles [256] = +{ + /* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f, */ + /* 00 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 6, 8, + /* 10 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 4, 6, + /* 20 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 5, 4, + /* 30 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 3, 8, + /* 40 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 6, 6, + /* 50 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 4, 5, 2, 2, 4, 3, + /* 60 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 5, 5, + /* 70 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 6, + /* 80 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 2, 4, 5, + /* 90 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2,12, 5, + /* a0 */ 3, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 2, 4, 4, + /* b0 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 4, + /* c0 */ 3, 8, 4, 5, 4, 5, 4, 7, 2, 5, 6, 4, 5, 2, 4, 9, + /* d0 */ 2, 8, 4, 5, 5, 6, 6, 7, 4, 5, 4, 5, 2, 2, 6, 3, + /* e0 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 4, 5, 3, 4, 3, 4, 3, + /* f0 */ 2, 8, 4, 5, 4, 5, 5, 6, 3, 4, 5, 4, 2, 2, 4, 3 +}; + + +// stuff +static FILE *AsmFile=NULL; +static int opcode=0; // 0-0xff +static int ibuffer = 0; +static char buff[1024]; + + +void ot(char *format, ...) +{ + va_list valist=NULL; + int i, len; + + // notaz: stop me from leaving newlines in the middle of format string + // and generating bad code + for(i=0, len=strlen(format); i < len && format[i] != '\n'; i++); + if(i < len-1 && format[len-1] != '\n') printf("\nWARNING: possible improper newline placement:\n%s\n", format); + + va_start(valist,format); + if (AsmFile) vfprintf(AsmFile,format,valist); + va_end(valist); +} + +// ot buffered +void otb(char *format, ...) +{ + va_list valist=NULL; + int i, len; + + // notaz: stop me from leaving newlines in the middle of format string + // and generating bad code + for(i=0, len=strlen(format); i < len && format[i] != '\n'; i++); + if(i < len-1 && format[len-1] != '\n') printf(buff, "\nWARNING: possible improper newline placement:\n%s\n", format); + + va_start(valist,format); + if (AsmFile) vsprintf(buff,format,valist); + ibuffer = 1; + va_end(valist); +} + +void flush_buffer() { + if (ibuffer != 0) { + ot(buff); + ibuffer = 0; + } +} + +// trashes: r0, r1, r2 +// return: r0 +// exit at label "2" +static void GetAPUDSP() { + ot("GetAPUDSP: \n"); + ot(" ldrb r1, [spc_ram, #0xf2] \n"); + // r1 = IAPU.RAM [0xf2] + + ot(" mov r0, #0\n"); + ot(" and r2, r1, #0X0f \n"); + // switch (reg & 0xf) { + ot(" cmp r2, #0x08\n"); + ot(" bxeq lr\n"); // APU_ENVX = 8 + // r1 = IAPU.RAM [0xf2] & 0x7f; + + ot(" cmp r2, #0x09\n"); + // return APU.DSP [reg]; + ot(" ldrne r2, .APU_DSP\n"); + ot(" and r1, r1, #0X7f \n"); // r1 = IAPU.RAM[0xf2] & 0x7f + ot(" ldrneb r0, [r2, r1] \n"); + ot(" bxne lr \n"); + + // APU_OUTX = 9 + // if (SoundData.channels [reg >> 4].state == SOUND_SILENT) return 0; + // return ((SoundData.channels [reg >> 4].sample >> 8) | (SoundData.channels [reg >> 4].sample & 0x + ot(" ldr r2, .SOUNDDATA_CHANNELS\n"); + ot(" mov r1, r1, lsr #4 \n"); + //ot(" add r1, r2, r1, asl #8\n"); + //ot(" ldr r0, [r1, #0x0] \n"); // r0 = SoundData.channels[reg >> 4].state + ot(" ldr r0, [r2, r1, asl #8] \n"); + ot(" add r1, r2, r1, asl #8\n"); + ot(" cmp r0, #0 \n"); // SOUND_SILENT = 0 + ot(" ldrneh r1, [r1, #0x48] \n"); // r1 = SoundData.channels[reg >> 4].sample + ot(" bxeq lr \n"); + + ot(" and r0, r1, #0xff\n"); + ot(" orr r0, r0, r1, lsr #8\n"); + ot(" bx lr \n"); + + ot(".APU_DSP:\n"); + ot(" .long APU + 0x0b\n"); // &APU.DSP + ot(".SOUNDDATA_CHANNELS:\n"); + ot(" .long SoundData + 0x30\n"); // &SoundData.channels[0] +} + + +// bitrider +// macros +static void GetByte() { + ot(" mov r1, r0\n"); + + ot(" ldrb r0, [spc_ram, r1] \n"); + + ot(" cmp r1, #0x0ff\n"); + ot(" bhi 1f \n"); + + ot(" cmp r1, #0xf3 \n"); + ot(" addeq lr, pc, #12 \n"); // lr = &ExitPoint + ot(" beq GetAPUDSP \n"); + + ot(" cmp r1, #0xfd \n"); + ot(" movhs r2, #0 \n"); + ot(" strhsb r2, [spc_ram, r1] \n"); + ot("1:\n"); + + +} + +// trashes: r0, r1, r14 +static void GetByteZ() { + ot(" mov r1, r0\n"); + + ot(" cmp r1, #0xf3 \n"); + ot(" addeq lr, pc, #20 \n"); // lr = &ExitPoint + ot(" beq GetAPUDSP \n"); + + ot(" ldr r14, [context, #iapu_directpage]\n"); + ot(" cmp r1, #0xfd \n"); + ot(" ldrb r0, [r14, r1] \n"); + ot(" movhs r2, #0 \n"); + ot(" strhsb r2, [r14, r1] \n"); +} + +static void SetByte(int restore) { + // Still should check for ShowRom + ot(" add r2, r1, #40 \n"); + ot(" tst r2, #0x10000 \n"); + ot(" bne 1f \n"); + + ot(" bic r2, r1, #0x0f\n"); + ot(" cmp r2, #0xf0\n"); + ot(" strneb r0, [spc_ram, r1] \n"); + ot(" bne 3f\n"); + + ot(" add lr, pc, #20\n"); + + ot(" cmp r1, #0xf1 \n"); + ot(" beq S9xSetAPUControl \n"); + + ot(" cmp r1, #0xf3 \n"); // pc + 4 + ot(" beq S9xSetAPUDSP \n"); // pc + 8 + ot(" b S9xAPUSetByteFFtoF0 \n"); // pc + 12 + + ot("1: \n"); + ot(" bl S9xAPUSetByteFFC0 \n"); + ot(" ldr spc_ram, [context, #iapu_ram] \n"); + ot("3: \n"); + +} + +static void SetByteZ(int restore) { + ot(" ldr r2, [context, #iapu_directpage] \n"); + ot(" cmp r2, spc_ram \n"); + ot(" bne 2f \n"); + + ot(" cmp r1, #0xf0 \n"); + ot(" blo 2f \n"); + + ot(" cmp r1, #0xfe \n"); + ot(" bhs 1f \n"); + + if (restore) ot(" add lr, pc, #16\n"); + else ot(" add lr, pc, #20\n"); + + ot(" cmp r1, #0xf1 \n"); + ot(" beq S9xSetAPUControl \n"); + + ot(" cmp r1, #0xf3 \n"); // pc + 4 + ot(" beq S9xSetAPUDSP \n"); // pc + 8 + ot(" b S9xAPUSetByteFFtoF0 \n"); // pc + 12 + //ot("6: \n"); // pc + 16 + if (restore) { + ot(" ldr spc_ram, [context, #iapu_ram] \n"); + ot(" b 1f \n"); + } + ot("2: \n"); + ot(" strb r0, [r2, r1] \n"); + ot("1: \n"); +} + + +// r0-2: Temporary registers +// r3 : current opcode or temp +// r4 : Cycles remaining +// r5 : Pointer to IAPU structure +// r6 : Pointer to Opcode Jump table +// r7 : Current PC +// r8 : YA +// r9 : P (nzzzzzzz ........ ........ NODBHIZC; nzzzzzzz - NZ flag in use (for a little speedup) + +// r10 : X +// r11 : S +// r14 : temp +// lr : RAM pointer + +static void PrintFramework() +{ + + +#ifndef SPC_DEBUG + ot(" .extern IAPU\n"); +#else + ot(" .extern IAPU2\n"); +#endif + ot(" .extern CPU @ for STOP and SLEEP\n"); + ot(" .extern S9xAPUGetByte\n"); + ot(" .extern S9xAPUSetByte\n"); + ot(" .extern S9xAPUGetByteZ\n"); + ot(" .extern S9xAPUSetByteZ\n\n"); + + // bitrider + ot(" .extern S9xGetAPUDSP\n"); + ot(" .extern S9xSetAPUDSP\n"); + ot(" .extern S9xSetAPUControl\n"); + ot(" .extern S9xAPUSetByteFFC0\n"); + ot(" .extern S9xAPUSetByteFFtoF0\n"); + + ot(" .global spc700_execute @ int cycles\n"); + //ot(" .global Spc700JumpTab\n\n"); + for (current_cycles=0; current_cycles < (sizeof(one_apu_cycle) / sizeof(int)); current_cycles++) + ot(" .global Spc700JumpTab_%i\n", one_apu_cycle[current_cycles]); + ot("\n"); + + + ot(" opcode .req r3\n"); + ot(" cycles .req r4\n"); + ot(" context .req r5\n"); + ot(" opcodes .req r6\n"); + ot(" spc_pc .req r7\n"); + ot(" spc_ya .req r8\n"); + ot(" spc_p .req r9\n"); + ot(" spc_x .req r10\n"); + ot(" spc_s .req r11\n"); + ot(" spc_ram .req r12\n\n"); + + ot(" .equ iapu_directpage, 0x00\n"); + ot(" .equ iapu_ram, 0x44\n"); + ot(" .equ iapu_extraram, 0x48\n"); + ot(" .equ iapu_allregs_load, 0x30\n"); + ot(" .equ iapu_allregs_save, 0x34\n\n"); + + ot(" .equ flag_c, 0x01\n"); + ot(" .equ flag_z, 0x02\n"); + ot(" .equ flag_i, 0x04\n"); + ot(" .equ flag_h, 0x08\n"); + ot(" .equ flag_b, 0x10\n"); + ot(" .equ flag_d, 0x20\n"); + ot(" .equ flag_o, 0x40\n"); + ot(" .equ flag_n, 0x80\n\n"); + + ot(" .equ cpu_apu_executing, %i \n\n", APU_EXECUTING_OFF); + // tmp +// ot(" .equ iapu_carry, 0x24\n"); +// ot(" .equ iapu_overflow, 0x26\n\n"); + + ot("@ --------------------------- Framework --------------------------\n"); + ot(" .align 4\n"); + ot("spc700_execute: @ int cycles\n"); + + ot(" stmfd sp!,{r4-r11,lr}\n"); + +#ifndef SPC_DEBUG + ot(" ldr context,=IAPU @ Pointer to SIAPU struct\n"); +#else + ot(" ldr context,=IAPU2 @ Pointer to SIAPU struct\n"); +#endif + ot(" mov cycles,r0 @ Cycles\n"); + ot(" add r0,context,#iapu_allregs_load\n"); + ot(" ldmia r0,{opcodes,spc_pc,spc_ya,spc_p,spc_x,spc_ram}\n"); + + ot(" ldrb opcode,[spc_pc],#1 @ Fetch first opcode\n"); + ot(" mov spc_s,spc_x,lsr #8\n"); + ot(" and spc_x,spc_x,#0xff\n"); + ot("\n"); + + ot(" ldr pc,[opcodes,opcode,lsl #2] @ Jump to opcode handler\n"); + ot("\n\n"); + + + ot("@ We come back here after execution\n"); + ot("spc700End:\n"); + ot(" orr spc_x,spc_x,spc_s,lsl #8\n"); + ot(" add r0,context,#iapu_allregs_save\n"); + ot(" stmia r0,{spc_pc,spc_ya,spc_p,spc_x}\n"); + ot(" mov r0,cycles\n"); + ot(" ldmfd sp!,{r4-r11,pc}\n"); + ot("\n"); + + ot(" .ltorg\n"); + ot("\n"); + + GetAPUDSP(); +} + + +// --------------------------------------------------------------------------- + +// Trashes r0-r3 +static void MemHandler(int set, int z, int save) +{ + //if(set) ot(" bl S9xAPUSetByte%s\n", z ? "Z" : ""); + //else ot(" bl S9xAPUGetByte%s\n", z ? "Z" : ""); + + //if(set) ot(" asm_S9xAPUSetByte%s\n", z ? "Z" : ""); + //else ot(" asm_S9xAPUGetByte%s\n", z ? "Z" : ""); + if(set) { + if (z) SetByteZ(save); + else SetByte(save); + } else { + if (z) GetByteZ(); + else GetByte(); + } + + //if(save) ot(" ldr spc_ram,[context,#iapu_ram]\n"); +} + +// pushes reg, trashes r1 +static void Push(char *reg) +{ + ot(" add r1,spc_ram,spc_s\n"); + ot(" strb %s,[r1,#0x100]\n", reg); + ot(" sub spc_s,spc_s,#1\n"); +} + +// pushes r0, trashes r0,r1 +static void PushW() +{ + ot(" add r1,spc_ram,spc_s\n"); + ot(" sub spc_s,spc_s,#2\n"); + ot(" strb r0,[r1,#0xff]\n"); + ot(" mov r0,r0,lsr #8\n"); + ot(" strb r0,[r1,#0x100]\n"); +} + +// pops to reg +static void Pop(char *reg) +{ + ot(" add %s,spc_ram,spc_s\n", reg); + ot(" ldrb %s,[%s,#(0x100 + 1)]\n", reg, reg); + ot(" add spc_s,spc_s,#1\n"); +} + +// pops to r0, trashes r1 +static void PopW() +{ + ot(" add r1,spc_ram,spc_s\n"); + ot(" ldrb r0,[r1,#(0xff + 2)]\n"); + ot(" ldrb r1,[r1,#(0x100 + 2)]\n"); + ot(" add spc_s,spc_s,#2\n"); + ot(" orr r0,r0,r1,lsl #8\n"); +} + +// // rr <- absolute, trashes r14 +// rr <- absolute + +static void AbsoluteAdd(int r, char *rAdd) +{ + ot(" ldrb r%i,[spc_pc],#1\n", r); + ot(" ldrb r14,[spc_pc],#1\n"); + if (rAdd) ot(" add r%i,r%i,%s\n", r, r, rAdd); + ot(" add r%i,r%i,r14,lsl #8\n", r, r); +} + +// // rr <- absolute, trashes r14 +// rr <- absolute +static void Absolute(int r) +{ + //ot(" ldrb r%i,[spc_pc],#1\n", r); + //ot(" ldrb r14,[spc_pc],#1\n"); + //ot(" orr r%i,r%i,r14,lsl #8\n", r, r); + AbsoluteAdd(r, NULL); +} + + +// rr <- absoluteX, trashes r14 +static void AbsoluteX(int r) +{ + //Absolute(r); + //ot(" ldrb r%i,[spc_pc],#1\n", r); + //ot(" ldrb r14,[spc_pc],#1\n"); + //ot(" add r%i,r%i,spc_x\n", r, r); + //ot(" add r%i,r%i,r14,lsl #8\n", r, r); + AbsoluteAdd(r, "spc_x"); +} + +// r0 <- absoluteY, trashes r1 +static void AbsoluteY(int r) +{ + //Absolute(r); + //ot(" ldrb r%i,[spc_pc],#1\n", r); + //ot(" ldrb r14,[spc_pc],#1\n"); + //ot(" add r%i,r%i,spc_ya,lsr #8\n", r, r); + //ot(" add r%i,r%i,r14,lsl #8\n", r, r); + AbsoluteAdd(r, "spc_ya, lsr #8"); +} + +// rr <- IndirectIndexedY, trashes r14 +static void IndirectIndexedY(int r) +{ + ot(" ldrb r%i,[spc_pc],#1\n", r); + ot(" ldr r14,[context,#iapu_directpage]\n"); + ot(" ldrb r%i,[r14,r%i]!\n", r, r); + ot(" ldrb r14,[r14,#1]\n"); + //ot(" orr r%i,r%i,r14,lsl #8\n", r, r); + ot(" add r%i,r%i,spc_ya,lsr #8\n", r, r); + ot(" add r%i,r%i,r14,lsl #8\n", r, r); +} + +// rr <- address, trashes r14 +static void IndexedXIndirect(int r) +{ + ot(" ldrb r%i,[spc_pc],#1\n", r); + ot(" ldr r14,[context,#iapu_directpage]\n"); // again, interlocks are bad + ot(" add r%i,r%i,spc_x\n", r, r); + ot(" and r%i,r%i,#0xff\n", r, r); + ot(" ldrb r%i,[r14,r%i]!\n", r, r); + ot(" ldrb r14,[r14,#1]\n"); + ot(" orr r%i,r%i,r14,lsl #8\n", r, r); +} + +// sets ZN for reg in *reg, not suitable for Y +static void SetZN8(char *reg) +{ + ot(" and spc_p,spc_p,#0xff\n"); + ot(" orr spc_p,spc_p,%s,lsl #24\n", reg); +} + +// sets ZN for reg in *reg +static void SetZN16(char *reg) +{ + ot(" and spc_p,spc_p,#0xff\n"); + ot(" orr spc_p,spc_p,%s,lsl #16\n", reg); + ot(" tst %s,#0xff\n", reg); + ot(" orrne spc_p,spc_p,#0x01000000\n"); +} + +// does ROL on r0, sets flags +static void Rol() +{ + ot(" mov r0,r0,lsl #1\n"); + ot(" tst spc_p,#flag_c\n"); + ot(" orrne r0,r0,#1\n"); + ot(" tst r0,#0x100\n"); + ot(" orrne spc_p,spc_p,#flag_c\n"); + ot(" biceq spc_p,spc_p,#flag_c\n"); + SetZN8("r0"); +} + +// does ROR on r0, sets flags +static void Ror() +{ + ot(" tst spc_p,#flag_c\n"); + ot(" orrne r0,r0,#0x100\n"); + ot(" movs r0,r0,lsr #1\n"); + ot(" orrcs spc_p,spc_p,#flag_c\n"); + ot(" biccc spc_p,spc_p,#flag_c\n"); + SetZN8("r0"); +} + +// does ASL on r0, sets flags but doesn't cut the shifted bits +static void Asl() +{ + ot(" tst r0,#0x80\n"); + ot(" orrne spc_p,spc_p,#flag_c\n"); + ot(" biceq spc_p,spc_p,#flag_c\n"); + ot(" mov r0,r0,lsl #1\n"); + SetZN8("r0"); +} + +// does LSR on r0, sets flags +static void Lsr() +{ + ot(" tst r0,#0x01\n"); + ot(" orrne spc_p,spc_p,#flag_c\n"); + ot(" biceq spc_p,spc_p,#flag_c\n"); + ot(" mov r0,r0,lsr #1\n"); + SetZN8("r0"); +} + +// CMP rr0,rr1; trashes r14 +static void Cmp(char *r0, char *r1, int and_r0) +{ + char *lop = r0; + + if(and_r0) { ot(" and r14,%s,#0xff\n", r0); lop = "r14"; } + ot(" subs r14,%s,%s\n", lop, r1); + //ot(" orrge spc_p,spc_p,#flag_c\n"); + //ot(" biclt spc_p,spc_p,#flag_c\n"); + ot(" orrcs spc_p,spc_p,#flag_c\n"); + ot(" biccc spc_p,spc_p,#flag_c\n"); + SetZN8("r14"); +} + +// ADC rr0,rr1 -> rr0, trashes r2,r14, does not mask to byte +static void Adc(char *r0, char *r1) +{ + ot(" eor r2,%s,%s\n", r0, r1); // r3=(a) ^ (b) + ot(" movs r14, spc_p, lsr #1\n"); + ot(" adc %s, %s, %s\n", r0, r0, r1); + //ot(" add %s,%s,%s\n", r0, r0, r1); + //ot(" tst spc_p,#flag_c\n"); + //ot(" addne %s,%s,#1\n", r0, r0); + ot(" movs r14,%s,lsr #8\n", r0); + ot(" orrne spc_p,spc_p,#flag_c\n"); + ot(" biceq spc_p,spc_p,#flag_c\n"); + ot(" eor r14,%s,%s\n", r0, r1); // r14=(b) ^ Work16 + ot(" bic r14,r14,r2\n"); // ((b) ^ Work16) & ~((a) ^ (b)) + ot(" tst r14,#0x80\n"); + ot(" orrne spc_p,spc_p,#flag_o\n"); + ot(" biceq spc_p,spc_p,#flag_o\n"); + ot(" eor r14,r2,%s\n", r0); + ot(" tst r14,#0x10\n"); + ot(" orrne spc_p,spc_p,#flag_h\n"); + ot(" biceq spc_p,spc_p,#flag_h\n"); +} + +// SBC rr0,rr1 -> rr0, trashes r2,r3,r14, does not mask to byte +static void Sbc(char *r0, char *r1) +{ + ot(" movs r14,spc_p,lsr #1\n"); + ot(" sbcs r2,%s,%s\n", r0, r1); + ot(" orrge spc_p,spc_p,#flag_c\n"); + ot(" biclt spc_p,spc_p,#flag_c\n"); + ot(" eor r14,%s,r2\n", r0); // r14=(a) ^ Int16 + ot(" eor r3,%s,%s\n", r0, r1); // r3=(a) ^ (b) + ot(" and r14,r14,r3\n"); // ((a) ^ Work16) & ((a) ^ (b)) + ot(" tst r14,#0x80\n"); + ot(" orrne spc_p,spc_p,#flag_o\n"); + ot(" biceq spc_p,spc_p,#flag_o\n"); + ot(" eor r14,r3,r2\n"); + ot(" tst r14,#0x10\n"); + ot(" orreq spc_p,spc_p,#flag_h\n"); + ot(" bicne spc_p,spc_p,#flag_h\n"); + ot(" mov %s,r2\n", r0); +} + + +// +static void TCall() +{ + ot(" sub r0,spc_pc,spc_ram\n"); + PushW(); + ot(" ldr r0,[context,#iapu_extraram]\n"); + ot(" ldrh r0,[r0,#0x%x]\n", (15-(opcode>>4))<<1); + ot(" add spc_pc,spc_ram,r0\n"); +} + +// +static void SetClr1() +{ + ot(" ldrb r0,[spc_pc]\n"); + MemHandler(0, 1, 0); + ot(" %s r0,r0,#0x%02x\n", opcode & 0x10 ? "bic" : "orr", 1<<(opcode>>5)); + ot(" ldrb r1,[spc_pc],#1\n"); + MemHandler(1, 1, 1); +} + +// +static void BssBbc() +{ + ot(" ldrb r0,[spc_pc],#1\n"); + MemHandler(0, 1, 1); + ot(" tst r0,#0x%02x\n", 1<<(opcode>>5)); + ot(" add%s spc_pc,spc_pc,#1\n", opcode & 0x10 ? "ne" : "eq"); + ot(" ldr%ssb r0,[spc_pc],#1\n", opcode & 0x10 ? "eq" : "ne"); + ot(" sub%s cycles,cycles,#%i\n",opcode & 0x10 ? "eq" : "ne", one_apu_cycle[current_cycles]*2); + ot(" add%s spc_pc,spc_pc,r0\n", opcode & 0x10 ? "eq" : "ne"); +} + +// +static void Membit() +{ + ot(" ldrb r0,[spc_pc], #1\n"); + ot(" ldrb r3,[spc_pc], #1\n"); + //ot(" orr spc_x,spc_x,r1,lsl #(29-5) + ot(" add r3,r0,r3,lsl #8\n"); //@ store membit where it can survive memhandler call\n"); // saving bit 12 ? + //ot(" mov r1,r1,lsr #5\n"); + //ot(" mov r0,r0,lsl #19\n"); + //ot(" mov r0,r0,lsr #19\n"); + //if((opcode >> 4) >= 0xC) ot(" mov r3, r0\n"); //ot(" stmfd sp!,{r0}\n"); // membit + ot(" bic r0, r3, #0xe000\n"); // Clear bits 15, 14 & 13 => r0 = r0 & 0x1fff + MemHandler(0, 0, 0); + //ot(" mov r1,spc_x,lsr #29\n"); + //ot(" and spc_x,spc_x,#0xff\n"); + ot(" mov r1, r3, lsr #13\n"); // membit = bits[15:13] of memory address + if((opcode >> 4) < 0xC) { + ot(" mov r0,r0,lsr r1\n"); + ot(" tst r0,#1\n"); + switch(opcode >> 4) { + case 0x0: ot(" orrne spc_p,spc_p,#flag_c\n"); break; // OR1 C,membit + case 0x2: ot(" orreq spc_p,spc_p,#flag_c\n"); break; // OR1 C,not membit + case 0x4: ot(" biceq spc_p,spc_p,#flag_c\n"); break; // AND1 C,membit + case 0x6: ot(" bicne spc_p,spc_p,#flag_c\n"); break; // AND1 C, not membit + case 0x8: ot(" eorne spc_p,spc_p,#flag_c\n"); break; // EOR1 C, membit + case 0xA: ot(" orrne spc_p,spc_p,#flag_c\n"); // MOV1 C,membit + ot(" biceq spc_p,spc_p,#flag_c\n"); break; + } + } else { + ot(" mov r2,#1\n"); + ot(" mov r2,r2,lsl r1\n"); + if((opcode >> 4) == 0xC) { // MOV1 membit,C + ot(" tst spc_p,#flag_c\n"); + ot(" orrne r0,r0,r2\n"); + ot(" biceq r0,r0,r2\n"); + } else { // NOT1 membit + ot(" eor r0,r0,r2\n"); + } + //ot(" ldmfd sp!,{r1}\n"); + ot(" bic r1, r3, #0xe000\n"); // Clear bits 15, 14 & 13 => r0 = r0 & 0x1fff + MemHandler(1, 0, 0); + } + //ot(" ldr spc_ram,[context,#iapu_ram] @ restore what memhandler(s) messed up\n"); +} + +// +static void CBranch() +{ + int tests[] = { 0x80000000, 0x40, 0x01, 0xff000000 }; // NOCZ + char *eq = "eq"; + char *ne = "ne"; + + if((opcode>>6) == 3) { // zero test inverts everything + eq = "ne"; + ne = "eq"; + } + + ot(" tst spc_p,#0x%08X\n", tests[opcode>>6]); + ot(" add%s spc_pc,spc_pc,#1\n", opcode & 0x20 ? eq : ne); +/* + ot(" b%s Apu%02X\n", opcode & 0x20 ? eq : ne, opcode); + ot(" sub r0,spc_pc,spc_ram\n"); + ot(" ldrsb r1,[spc_pc],#1\n"); + ot(" add r0,r0,r1\n"); + ot(" mov r0,r0,lsl #16\n"); + ot(" add spc_pc,spc_ram,r0,lsr #16\n"); +*/ + ot(" ldr%ssb r0,[spc_pc],#1\n", opcode & 0x20 ? ne : eq); + + ot(" sub%s cycles,cycles,#%i\n", opcode & 0x20 ? ne : eq, one_apu_cycle[current_cycles]*2); + ot(" add%s spc_pc,spc_pc,r0\n", opcode & 0x20 ? ne : eq); +// ot("Apu%02X:\n", opcode); +} + +// NeededOperation spc_ya,r0 -> spc_ya +static void ArithOpToA() +{ + // special A pre-processing + if((opcode>>5) == 4 || (opcode>>5) == 5) { + ot(" and r1,spc_ya,#0xff00\n"); + ot(" and spc_ya,spc_ya,#0xff\n"); + } + + switch(opcode>>5) { + case 0: ot(" orr spc_ya,spc_ya,r0\n"); break; // OR + case 1: ot(" orr r0,r0,#0xff00\n"); + ot(" and spc_ya,spc_ya,r0\n"); break; // AND + case 2: ot(" eor spc_ya,spc_ya,r0\n"); break; // EOR + case 3: Cmp("spc_ya", "r0", 1); break; // CMP + case 4: Adc("spc_ya", "r0"); break; // ADC + case 5: Sbc("spc_ya", "r0"); break; // SBC + case 6: printf("MOV (reversed)!?\n"); break; // MOV (reversed) + case 7: ot(" and spc_ya,spc_ya,#0xff00\n"); + ot(" orr spc_ya,spc_ya,r0\n"); break; // MOV + } + + if((opcode>>5) != 3) SetZN8("spc_ya"); // only if not Cmp + + // special A post-processing + if((opcode>>5) == 4 || (opcode>>5) == 5) { + ot(" and spc_ya,spc_ya,#0xff\n"); + ot(" orr spc_ya,spc_ya,r1\n"); + } +} + +// +static void ArithmeticToA() +{ + switch(opcode&0x1f) { + case 0x04: // OP A,dp + ot(" ldrb r0,[spc_pc],#1\n"); + MemHandler(0, 1, 1); + ArithOpToA(); + break; + + case 0x05: // OP A,abs + Absolute(0); + MemHandler(0, 0, 1); + ArithOpToA(); + break; + + case 0x06: // OP A,(X) + ot(" mov r0,spc_x\n"); + MemHandler(0, 1, 1); + ArithOpToA(); + break; + + case 0x07: // OP A,(dp+X) + IndexedXIndirect(0); + MemHandler(0, 0, 1); + ArithOpToA(); + break; + + case 0x08: // OP A,#00 + ot(" ldrb r0,[spc_pc],#1\n"); + ArithOpToA(); + break; + + case 0x14: // OP A,dp+X + ot(" ldrb r0,[spc_pc],#1\n"); + ot(" add r0,r0,spc_x\n"); + MemHandler(0, 1, 1); + ArithOpToA(); + break; + + case 0x15: // OP A,abs+X + AbsoluteX(0); + MemHandler(0, 0, 1); + ArithOpToA(); + break; + + case 0x16: // OP A,abs+Y + AbsoluteY(0); + MemHandler(0, 0, 1); + ArithOpToA(); + break; + + case 0x17: // OP A,(dp)+Y + IndirectIndexedY(0); + MemHandler(0, 0, 1); + ArithOpToA(); + break; + + default: + printf("Op %02X - arithmetic??\n", opcode); + } +} + +void printOpcodes(int apu_cycles) { + for(opcode = 0; opcode < 0x100; opcode++) { + printf("%02X", opcode); + + ot("\n\n"); + //tmp_prologue(); + ot("Apu%02X_%i:\n", opcode, apu_cycles); + + if((opcode & 0x1f) == 0x10) CBranch(); // BXX + if((opcode & 0x0f) == 0x01) TCall(); // TCALL X + if((opcode & 0x0f) == 0x02) SetClr1(); // SET1/CLR1 direct page bit X + if((opcode & 0x0f) == 0x03) BssBbc(); // BBS/BBC direct page bit X + if((opcode & 0x1f) == 0x0A) Membit(); // membit ops + if((opcode & 0x0f) >= 0x04 && (opcode & 0x0f) <= 0x08 && (opcode & 0x1f) != 0x18 && (opcode >> 5) != 6) + ArithmeticToA(); + + + switch(opcode) { + case 0x00: // NOP + break; + + case 0x3F: // CALL absolute + Absolute(2); + ot(" sub r0,spc_pc,spc_ram\n"); + PushW(); + ot(" add spc_pc,spc_ram,r2\n"); + break; + + case 0x4F: // PCALL $XX + ot(" ldrb r2,[spc_pc],#1\n"); + ot(" sub r0,spc_pc,spc_ram\n"); + PushW(); + ot(" add spc_pc,spc_ram,r2\n"); + ot(" add spc_pc,spc_pc,#0xff00\n"); + break; + + case 0x09: // OR dp(dest),dp(src) + ot(" ldrb r0,[spc_pc],#1\n"); + MemHandler(0, 1, 0); + //ot(" orr spc_x,spc_x,r0,lsl #24 @ save from harm\n"); + ot(" mov r3, r0\n"); + ot(" ldrb r0,[spc_pc]\n"); + MemHandler(0, 1, 0); + ot(" orr r0, r0, r3\n"); + //ot(" orr r0,r0,spc_x,lsr #24\n"); + //ot(" and spc_x,spc_x,#0xff\n"); + SetZN8("r0"); + ot(" ldrb r1,[spc_pc],#1\n"); + MemHandler(1, 1, 1); + break; + + case 0x18: // OR dp,#00 + ot(" ldrb r0,[spc_pc,#1]\n"); + MemHandler(0, 1, 0); + ot(" ldrb r1,[spc_pc],#1\n"); + ot(" orr r0,r0,r1\n"); + SetZN8("r0"); + ot(" ldrb r1,[spc_pc],#1\n"); + MemHandler(1, 1, 1); + break; + + case 0x19: // OR (X),(Y) + ot(" mov r0,spc_x\n"); + MemHandler(0, 1, 0); + //ot(" orr spc_x,spc_x,r0,lsl #24\n"); + ot(" mov r3, r0\n"); + ot(" mov r0,spc_ya,lsr #8\n"); + MemHandler(0, 1, 0); + ot(" orr r0, r3, r0\n"); + //ot(" orr r0,r0,spc_x,lsr #24\n"); + //ot(" and spc_x,spc_x,#0xff\n"); + SetZN8("r0"); + ot(" mov r1,spc_x\n"); + MemHandler(1, 1, 1); + break; + + case 0x0B: // ASL dp + ot(" ldrb r0,[spc_pc]\n"); + MemHandler(0, 1, 0); + Asl(); + ot(" ldrb r1,[spc_pc],#1\n"); + MemHandler(1, 1, 1); + break; + + case 0x0C: // ASL abs + Absolute(0); + //ot(" stmfd sp!,{r0}\n"); + ot(" mov r3, r0\n"); + MemHandler(0, 0, 0); + Asl(); + //ot(" ldmfd sp!,{r1}\n"); + ot(" mov r1, r3\n"); + MemHandler(1, 0, 1); + break; + + case 0x1B: // ASL dp+X + ot(" ldrb r0,[spc_pc],#1\n"); + ot(" add r0,r0,spc_x\n"); + //ot(" stmfd sp!,{r0}\n"); + ot(" mov r3, r0\n"); + MemHandler(0, 1, 0); + Asl(); + //ot(" ldmfd sp!,{r1}\n"); + ot(" mov r1, r3\n"); + MemHandler(1, 1, 1); + break; + + case 0x1C: // ASL A + ot(" tst spc_ya,#0x80\n"); + ot(" orrne spc_p,spc_p,#flag_c\n"); + ot(" biceq spc_p,spc_p,#flag_c\n"); + ot(" and r0,spc_ya,#0x7f\n"); + ot(" and spc_ya,spc_ya,#0xff00\n"); + ot(" orr spc_ya,spc_ya,r0,lsl #1\n"); + SetZN8("spc_ya"); + break; + + case 0x0D: // PUSH PSW + ot(" mov r0,spc_p,lsr #24\n"); + ot(" and r1,r0,#0x80\n"); + ot(" tst r0,r0\n"); + ot(" orreq r1,r1,#flag_z\n"); + ot(" and spc_p,spc_p,#0x7d @ clear N & Z\n"); + ot(" orr spc_p,spc_p,r1\n"); + Push("spc_p"); + otb(" orr spc_p,spc_p,r0,lsl #24\n"); + break; + + case 0x2D: // PUSH A + Push("spc_ya"); + break; + + case 0x4D: // PUSH X + Push("spc_x"); + break; + + case 0x6D: // PUSH Y + ot(" mov r0,spc_ya,lsr #8\n"); + Push("r0"); + break; + + case 0x8E: // POP PSW + Pop("spc_p"); + ot(" and r0,spc_p,#(flag_z|flag_n)\n"); + ot(" eor r0,r0,#flag_z\n"); + ot(" orr spc_p,spc_p,r0,lsl #24\n"); + ot(" tst spc_p,#flag_d\n"); + ot(" addne r0,spc_ram,#0x100\n"); + ot(" moveq r0,spc_ram\n"); + otb(" str r0,[context,#iapu_directpage]\n"); + break; + + case 0xAE: // POP A + Pop("r0"); + ot(" and spc_ya,spc_ya,#0xff00\n"); + otb(" orr spc_ya,spc_ya,r0\n"); + break; + + case 0xCE: // POP X + Pop("spc_x"); + break; + + case 0xEE: // POP X + Pop("r0"); + ot(" and spc_ya,spc_ya,#0xff\n"); + otb(" orr spc_ya,spc_ya,r0,lsl #8\n"); + break; + + case 0x0E: // TSET1 abs + Absolute(0); + ot(" mov r3, r0\n"); + //ot(" orr spc_x,spc_x,r0,lsl #16 @ save from memhandler\n"); + MemHandler(0, 0, 0); + ot(" and r2,r0,spc_ya\n"); + SetZN8("r2"); + ot(" orr r0,r0,spc_ya\n"); + ot(" mov r1, r3\n"); + //ot(" mov r1,spc_x,lsr #16\n"); + //ot(" and spc_x,spc_x,#0xff\n"); + MemHandler(1, 0, 1); + break; + + case 0x4E: // TCLR1 abs + Absolute(0); + ot(" mov r3, r0\n"); + //ot(" orr spc_x,spc_x,r0,lsl #16 @ save from memhandler\n"); + MemHandler(0, 0, 0); + ot(" and r2,r0,spc_ya\n"); + SetZN8("r2"); + ot(" bic r0,r0,spc_ya\n"); + ot(" mov r1, r3\n"); + //ot(" mov r1,spc_x,lsr #16\n"); + //ot(" and spc_x,spc_x,#0xff\n"); + MemHandler(1, 0, 1); + break; + + case 0x0F: // BRK + ot(" sub r0,spc_pc,spc_ram\n"); + PushW(); + ot(" mov r0,spc_p,lsr #24\n"); + ot(" and r1,r0,#0x80\n"); + ot(" tst r0,r0\n"); + ot(" orrne r1,r1,#flag_z\n"); + ot(" and spc_p,spc_p,#0x7d @ clear N & Z\n"); + ot(" orr spc_p,spc_p,r1\n"); + Push("spc_p"); + ot(" orr spc_p,spc_p,#flag_b\n"); + ot(" bic spc_p,spc_p,#flag_i\n"); + ot(" ldr r0,[context,#iapu_extraram]\n"); + ot(" ldrh r0,[r0,#0x20]\n"); + ot(" add spc_pc,spc_ram,r0\n"); + break; + + case 0xEF: // SLEEP + case 0xFF: // STOP: this is to be compatible with yoyofr's code + //ot(" ldr r0,=CPU\n"); + ot(" ldr r0, 5001f\n", apu_cycles); + ot(" mov r1,#0\n"); + //otb(" strb r1,[r0,#122]\n"); + otb(" str r1,[r0,#cpu_apu_executing]\n"); + //tmp_epilogue(); + ot(" subs cycles,cycles,#%i\n", S9xAPUCycles[opcode] * one_apu_cycle[current_cycles]); + ot(" ldrgeb opcode,[spc_pc],#1\n"); + flush_buffer(); + ot(" ldrge pc,[opcodes,opcode,lsl #2]\n"); + ot(" b spc700End\n"); + // don't let code flow until here + ot("5001:\n", apu_cycles); + ot(" .long CPU \n"); + break; + + case 0x2F: // BRA + ot(" ldrsb r0,[spc_pc],#1\n"); + ot(" add spc_pc,spc_pc,r0\n"); + break; + + case 0x80: // SETC + otb(" orr spc_p,spc_p,#flag_c\n"); + break; + + case 0xED: // NOTC + otb(" eor spc_p,spc_p,#flag_c\n"); + break; + + case 0x40: // SETP + ot(" orr spc_p,spc_p,#flag_d\n"); + ot(" add r0,spc_ram,#0x100\n"); + otb(" str r0,[context,#iapu_directpage]\n"); + break; + + case 0x1A: // DECW dp + ot(" ldrb r0,[spc_pc]\n"); + MemHandler(0, 1, 0); + //ot(" stmfd sp!,{r0}\n"); + ot(" mov r3, r0\n"); + ot(" ldrb r0,[spc_pc]\n"); + ot(" add r0,r0,#1\n"); + MemHandler(0, 1, 0); + //ot(" ldmfd sp!,{r1}\n"); + ot(" orr r1,r3,r0,lsl #8\n"); + ot(" sub r0,r1,#1\n"); + SetZN16("r0"); + ot(" stmfd sp!,{r0}\n"); + ot(" ldrb r1,[spc_pc]\n"); + MemHandler(1, 1, 0); + ot(" ldmfd sp!,{r0}\n"); + ot(" mov r0,r0,lsr #8\n"); + ot(" ldrb r1,[spc_pc],#1\n"); + + ot(" add r1,r1,#1\n"); + MemHandler(1, 1, 1); + break; + + case 0x5A: // CMPW YA,dp + ot(" ldrb r0,[spc_pc]\n"); + MemHandler(0, 1, 0); + //ot(" stmfd sp!,{r0}\n"); + ot(" mov r3, r0\n"); + ot(" ldrb r0,[spc_pc],#1\n"); + ot(" add r0,r0,#1\n"); + MemHandler(0, 1, 1); + //ot(" ldmfd sp!,{r1}\n"); + ot(" orr r1,r3,r0,lsl #8\n"); + ot(" subs r0,spc_ya,r1\n"); + ot(" orrge spc_p,spc_p,#flag_c\n"); + ot(" biclt spc_p,spc_p,#flag_c\n"); + SetZN16("r0"); + break; + + case 0x3A: // INCW dp + ot(" ldrb r0,[spc_pc]\n"); + MemHandler(0, 1, 0); + //ot(" stmfd sp!,{r0}\n"); + ot(" mov r3, r0\n"); + ot(" ldrb r0,[spc_pc]\n"); + ot(" add r0,r0,#1\n"); + MemHandler(0, 1, 0); + //ot(" ldmfd sp!,{r1}\n"); + ot(" orr r1,r3,r0,lsl #8\n"); + ot(" add r0,r1,#1\n"); + SetZN16("r0"); + ot(" stmfd sp!,{r0}\n"); + ot(" ldrb r1,[spc_pc]\n"); + MemHandler(1, 1, 0); + ot(" ldmfd sp!,{r0}\n"); + ot(" mov r0,r0,lsr #8\n"); + ot(" ldrb r1,[spc_pc],#1\n"); + ot(" add r1,r1,#1\n"); + MemHandler(1, 1, 1); + break; + + case 0x7A: // ADDW YA,dp + ot(" ldrb r0,[spc_pc]\n"); + MemHandler(0, 1, 0); + //ot(" stmfd sp!,{r0}\n"); + ot(" mov r3, r0\n"); + ot(" ldrb r0,[spc_pc],#1\n"); + ot(" add r0,r0,#1\n"); + MemHandler(0, 1, 1); + //ot(" ldmfd sp!,{r1}\n"); + ot(" orr r1,r3,r0,lsl #8\n"); + ot(" add r0,spc_ya,r1\n"); + ot(" movs r2,r0,lsr #16\n"); + ot(" orrne spc_p,spc_p,#flag_c\n"); + ot(" biceq spc_p,spc_p,#flag_c\n"); + ot(" bic r2,r0,#0x00ff0000\n"); + ot(" eor r3,r1,r2\n"); // Work16 ^ (uint16) Work32 + ot(" eor r14,spc_ya,r1\n"); + ot(" mvn r14,r14\n"); // ~(pIAPU->YA.W ^ Work16) + ot(" and r14,r14,r3\n"); + ot(" tst r14,#0x8000\n"); + ot(" orrne spc_p,spc_p,#flag_o\n"); + ot(" biceq spc_p,spc_p,#flag_o\n"); + ot(" eor r14,r3,spc_ya\n"); + ot(" tst r14,#0x10\n"); + ot(" orrne spc_p,spc_p,#flag_h\n"); + ot(" biceq spc_p,spc_p,#flag_h\n"); + ot(" mov spc_ya,r2\n"); + SetZN16("spc_ya"); + + break; + + case 0x9A: // SUBW YA,dp + ot(" ldrb r0,[spc_pc]\n"); + MemHandler(0, 1, 0); + //ot(" stmfd sp!,{r0}\n"); + ot(" mov r3, r0\n"); + ot(" ldrb r0,[spc_pc],#1\n"); + ot(" add r0,r0,#1\n"); + MemHandler(0, 1, 1); + //ot(" ldmfd sp!,{r1}\n"); + ot(" orr r1,r3,r0,lsl #8\n"); + ot(" subs r0,spc_ya,r1\n"); + ot(" orrge spc_p,spc_p,#flag_c\n"); + ot(" biclt spc_p,spc_p,#flag_c\n"); + ot(" mov r2,r0,lsl #16\n"); + ot(" mov r2,r2,lsr #16\n"); // r2=(uint16) Int32 + ot(" eor r3,spc_ya,r2\n"); // r3=pIAPU->YA.W ^ (uint16) Int32 + ot(" eor r14,spc_ya,r1\n"); + ot(" and r14,r14,r3\n"); + ot(" tst r14,#0x8000\n"); + ot(" orrne spc_p,spc_p,#flag_o\n"); + ot(" biceq spc_p,spc_p,#flag_o\n"); + ot(" eor r14,r3,r1\n"); + ot(" tst r14,#0x10\n"); + ot(" bicne spc_p,spc_p,#flag_h\n"); + ot(" orreq spc_p,spc_p,#flag_h\n"); + ot(" mov spc_ya,r2\n"); + SetZN16("spc_ya"); + break; + + case 0xBA: // MOVW YA,dp + ot(" ldrb r0,[spc_pc]\n"); + MemHandler(0, 1, 0); + ot(" ldrb r1, [spc_pc],#1\n"); + ot(" mov spc_ya, r0\n"); // avoiding inter-locks + ot(" add r0, r1, #1\n"); + MemHandler(0, 1, 1); + ot(" orr spc_ya,spc_ya,r0,lsl #8\n"); + SetZN16("spc_ya"); + break; + + case 0xDA: // MOVW dp,YA + ot(" ldrb r1,[spc_pc]\n"); + ot(" mov r0,spc_ya\n"); + MemHandler(1, 1, 0); + ot(" ldrb r1,[spc_pc],#1\n"); + ot(" mov r0,spc_ya,lsr #8\n"); // avoiding inter-locks + ot(" add r1,r1,#1\n"); + MemHandler(1, 1, 1); + break; + + case 0x69: // CMP dp(dest), dp(src) + ot(" ldrb r0,[spc_pc],#1\n"); + MemHandler(0, 1, 0); + ot(" orr spc_x,spc_x,r0,lsl #24\n"); + ot(" ldrb r0,[spc_pc],#1\n"); + MemHandler(0, 1, 1); + ot(" mov r1,spc_x,lsr #24\n"); + Cmp("r0", "r1", 0); + otb(" and spc_x,spc_x,#0xff\n"); + break; + + case 0x78: // CMP dp,#00 + ot(" ldrb r0,[spc_pc,#1]\n"); + MemHandler(0, 1, 1); + ot(" ldrb r1,[spc_pc],#2\n"); + Cmp("r0", "r1", 0); + break; + + case 0x79: // CMP (X),(Y) + ot(" mov r0,spc_x\n"); + MemHandler(0, 1, 0); + ot(" orr spc_x,spc_x,r0,lsl #24\n"); + ot(" mov r0,spc_ya,lsr #8\n"); + MemHandler(0, 1, 1); + ot(" mov r1,spc_x,lsr #24\n"); + Cmp("r1", "r0", 0); + otb(" and spc_x,spc_x,#0xff\n"); + break; + + case 0x1E: // CMP X,abs + Absolute(0); + MemHandler(0, 0, 1); + Cmp("spc_x", "r0", 0); + break; + + case 0x3E: // CMP X,dp + ot(" ldrb r0,[spc_pc],#1\n"); + + MemHandler(0, 1, 1); + Cmp("spc_x", "r0", 0); + break; + + case 0xC8: // CMP X,#00 + ot(" ldrb r0,[spc_pc],#1\n"); + Cmp("spc_x", "r0", 0); + break; + + case 0x5E: // CMP Y,abs + Absolute(0); + MemHandler(0, 0, 1); + ot(" mov r1,spc_ya,lsr #8\n"); + Cmp("r1", "r0", 0); + break; + + case 0x7E: // CMP Y,dp + ot(" ldrb r0,[spc_pc],#1\n"); + MemHandler(0, 1, 1); + ot(" mov r1,spc_ya,lsr #8\n"); + Cmp("r1", "r0", 0); + break; + + case 0xAD: // CMP Y,#00 + ot(" ldrb r0,[spc_pc],#1\n"); + ot(" mov r1,spc_ya,lsr #8\n"); + Cmp("r1", "r0", 0); + break; + + case 0x1F: // JMP (abs+X) + AbsoluteX(0); + ot(" sub sp,sp,#8\n"); + ot(" str r0,[sp,#4]\n"); + MemHandler(0, 0, 0); + ot(" str r0,[sp]\n"); + ot(" ldr r0,[sp,#4]\n"); + ot(" add r0,r0,#1\n"); + MemHandler(0, 0, 1); + ot(" ldr r1,[sp],#8\n"); + ot(" orr r0,r1,r0,lsl #8\n"); + ot(" add spc_pc,spc_ram,r0\n"); + break; + + case 0x5F: // JMP abs + //Absolute(0); + //ot(" add spc_pc,spc_ram,r0\n"); + ot(" ldrb r0, [spc_pc], #1\n"); + ot(" ldrb r14, [spc_pc], #1\n"); + ot(" add spc_pc, r0, spc_ram\n"); + ot(" add spc_pc, spc_pc, r14, lsl #8\n"); + break; + + case 0x20: // CLRP + ot(" bic spc_p,spc_p,#flag_d\n"); + otb(" str spc_ram,[context,#iapu_directpage]\n"); + break; + + case 0x60: // CLRC + otb(" bic spc_p,spc_p,#flag_c\n"); + break; + + case 0xE0: // CLRV + otb(" bic spc_p,spc_p,#(flag_o|flag_h)\n"); + break; + + case 0x29: // AND dp(dest), dp(src) + ot(" ldrb r0,[spc_pc],#1\n"); + MemHandler(0, 1, 0); + //ot(" stmfd sp!,{r0}\n"); + ot(" mov r3, r0\n"); + ot(" ldrb r0,[spc_pc]\n"); + MemHandler(0, 1, 0); + //ot(" ldmfd sp!,{r1}\n"); + ot(" and r0,r0,r3\n"); + SetZN8("r0"); + ot(" ldrb r1,[spc_pc],#1\n"); + MemHandler(1, 1, 1); + break; + + case 0x38: // AND dp,#00 + ot(" ldrb r0,[spc_pc,#1]\n"); + MemHandler(0, 1, 0); + ot(" ldrb r1,[spc_pc],#2\n"); + ot(" and r0,r0,r1\n"); + SetZN8("r0"); + ot(" ldrb r1,[spc_pc,#-1]\n"); + MemHandler(1, 1, 1); + break; + + case 0x39: // AND (X),(Y) + ot(" mov r0,spc_x\n"); + MemHandler(0, 1, 0); + //ot(" stmfd sp!,{r0}\n"); + ot(" mov r3, r0\n"); + ot(" mov r0,spc_ya,lsr #8\n"); + MemHandler(0, 1, 0); + //ot(" ldmfd sp!,{r1}\n"); + ot(" and r0,r0,r3\n"); + SetZN8("r0"); + ot(" mov r1,spc_x\n"); + MemHandler(1, 1, 1); + break; + + case 0x2B: // ROL dp + ot(" ldrb r0,[spc_pc]\n"); + MemHandler(0, 1, 0); + Rol(); + ot(" ldrb r1,[spc_pc],#1\n"); + MemHandler(1, 1, 1); + break; + + case 0x2C: // ROL abs + Absolute(0); + //ot(" stmfd sp!,{r0}\n"); + ot(" mov r3, r0\n"); + MemHandler(0, 0, 0); + Rol(); + //ot(" ldmfd sp!,{r1}\n"); + ot(" mov r1, r3\n"); + MemHandler(1, 0, 1); + break; + + case 0x3B: // ROL dp+X + ot(" ldrb r0,[spc_pc]\n"); + ot(" add r0,r0,spc_x\n"); + MemHandler(0, 1, 0); + Rol(); + ot(" ldrb r1,[spc_pc],#1\n"); + ot(" add r1,r1,spc_x\n"); + MemHandler(1, 1, 1); + break; + + case 0x3C: // ROL A + ot(" and r0,spc_ya,#0xff\n"); + Rol(); + ot(" and r0,r0,#0xff\n"); + ot(" mov spc_ya,spc_ya,lsr #8\n"); + otb(" orr spc_ya,r0,spc_ya,lsl #8\n"); + break; + + case 0x2E: // CBNE dp,rel + ot(" ldrb r0,[spc_pc],#1\n"); + MemHandler(0, 1, 1); + ot(" and r1,spc_ya,#0xff\n"); + ot(" cmp r0,r1\n"); + ot(" addeq spc_pc,spc_pc,#1\n"); + ot(" ldrnesb r0,[spc_pc],#1\n"); + ot(" subne cycles,cycles,#%i\n", one_apu_cycle[current_cycles]*2); + ot(" addne spc_pc,spc_pc,r0\n"); + break; + + case 0xDE: // CBNE dp+X,rel + ot(" ldrb r0,[spc_pc],#1\n"); + ot(" add r0,r0,spc_x\n"); + MemHandler(0, 1, 1); + ot(" and r1,spc_ya,#0xff\n"); + ot(" cmp r0,r1\n"); + ot(" addeq spc_pc,spc_pc,#1\n"); + ot(" ldrnesb r0,[spc_pc],#1\n"); + ot(" addne spc_pc,spc_pc,r0\n"); + ot(" subne cycles,cycles,#%i\n", one_apu_cycle[current_cycles]*2); + break; + + case 0x3D: // INC X + ot(" add spc_x,spc_x,#1\n"); + ot(" and spc_x,spc_x,#0xff\n"); + SetZN8("spc_x"); + break; + + case 0xFC: // INC Y + ot(" mov r0,spc_ya,lsr #8\n"); + ot(" add r0,r0,#1\n"); + ot(" and r0,r0,#0xff\n"); + SetZN8("r0"); + ot(" and spc_ya,spc_ya,#0xff\n"); + otb(" orr spc_ya,spc_ya,r0,lsl #8\n"); + break; + + case 0x1D: // DEC X + ot(" sub spc_x,spc_x,#1\n"); + ot(" and spc_x,spc_x,#0xff\n"); + SetZN8("spc_x"); + break; + + case 0xDC: // DEC Y + ot(" mov r0,spc_ya,lsr #8\n"); + ot(" sub r0,r0,#1\n"); + ot(" and r0,r0,#0xff\n"); + SetZN8("r0"); + ot(" and spc_ya,spc_ya,#0xff\n"); + otb(" orr spc_ya,spc_ya,r0,lsl #8\n"); + break; + + case 0xAB: // INC dp + ot(" ldrb r0,[spc_pc]\n"); + MemHandler(0, 1, 0); + ot(" add r0,r0,#1\n"); + SetZN8("r0"); + ot(" ldrb r1,[spc_pc],#1\n"); + MemHandler(1, 1, 1); + break; + + case 0xAC: // INC abs + Absolute(0); + //ot(" stmfd sp!,{r0}\n"); + ot(" mov r3, r0\n"); + MemHandler(0, 0, 0); + ot(" add r0,r0,#1\n"); + SetZN8("r0"); + //ot(" ldmfd sp!,{r1}\n"); + ot(" mov r1, r3\n"); + MemHandler(1, 0, 1); + break; + + case 0xBB: // INC dp+X + ot(" ldrb r0,[spc_pc]\n"); + ot(" add r0,r0,spc_x\n"); + MemHandler(0, 1, 0); + ot(" add r0,r0,#1\n"); + SetZN8("r0"); + ot(" ldrb r1,[spc_pc],#1\n"); + ot(" add r1,r1,spc_x\n"); + MemHandler(1, 1, 1); + break; + + case 0xBC: // INC A + ot(" and r0,spc_ya,#0xff\n"); + ot(" add r0,r0,#1\n"); + SetZN8("r0"); + ot(" and r0,r0,#0xff\n"); + ot(" mov spc_ya,spc_ya,lsr #8\n"); + otb(" orr spc_ya,r0,spc_ya,lsl #8\n"); + break; + + case 0x8B: // DEC dp + ot(" ldrb r0,[spc_pc]\n"); + MemHandler(0, 1, 0); + ot(" sub r0,r0,#1\n"); + SetZN8("r0"); + ot(" ldrb r1,[spc_pc],#1\n"); + MemHandler(1, 1, 1); + break; + + case 0x8C: // DEC abs + Absolute(0); + //ot(" stmfd sp!,{r0}\n"); + ot(" mov r3, r0\n"); + MemHandler(0, 0, 0); + ot(" sub r0,r0,#1\n"); + SetZN8("r0"); + //ot(" ldmfd sp!,{r1}\n"); + ot(" mov r1, r3\n"); + MemHandler(1, 0, 1); + break; + + case 0x9B: // DEC dp+X + ot(" ldrb r0,[spc_pc]\n"); + ot(" add r0,r0,spc_x\n"); + MemHandler(0, 1, 0); + ot(" sub r0,r0,#1\n"); + SetZN8("r0"); + ot(" ldrb r1,[spc_pc],#1\n"); + + ot(" add r1,r1,spc_x\n"); + MemHandler(1, 1, 1); + break; + + case 0x9C: // DEC A + ot(" and r0,spc_ya,#0xff\n"); + ot(" sub r0,r0,#1\n"); + SetZN8("r0"); + ot(" and r0,r0,#0xff\n"); + ot(" mov spc_ya,spc_ya,lsr #8\n"); + otb(" orr spc_ya,r0,spc_ya,lsl #8\n"); + break; + + case 0x49: // EOR dp(dest), dp(src) + ot(" ldrb r0,[spc_pc],#1\n"); + MemHandler(0, 1, 0); + //ot(" stmfd sp!,{r0}\n"); + ot(" mov r3, r0\n"); + ot(" ldrb r0,[spc_pc]\n"); + MemHandler(0, 1, 0); + //ot(" ldmfd sp!,{r1}\n"); + ot(" eor r0,r0,r3\n"); + SetZN8("r0"); + ot(" ldrb r1,[spc_pc],#1\n"); + MemHandler(1, 1, 1); + break; + + case 0x58: // EOR dp,#00 + ot(" ldrb r0,[spc_pc,#1]\n"); + MemHandler(0, 1, 0); + ot(" ldrb r1,[spc_pc],#2\n"); + ot(" eor r0,r0,r1\n"); + SetZN8("r0"); + ot(" ldrb r1,[spc_pc,#-1]\n"); + MemHandler(1, 1, 1); + break; + + case 0x59: // EOR (X),(Y) + ot(" mov r0,spc_x\n"); + MemHandler(0, 1, 0); + //ot(" stmfd sp!,{r0}\n"); + ot(" mov r3, r0\n"); + ot(" mov r0,spc_ya,lsr #8\n"); + MemHandler(0, 1, 0); + //ot(" ldmfd sp!,{r1}\n"); + ot(" eor r0,r0,r3\n"); + SetZN8("r0"); + ot(" mov r1,spc_x\n"); + MemHandler(1, 1, 1); + break; + + case 0x4B: // LSR dp + ot(" ldrb r0,[spc_pc]\n"); + MemHandler(0, 1, 0); + Lsr(); + ot(" ldrb r1,[spc_pc],#1\n"); + MemHandler(1, 1, 1); + break; + + case 0x4C: // LSR abs + Absolute(0); + //ot(" stmfd sp!,{r0}\n"); + ot(" mov r3, r0\n"); + MemHandler(0, 0, 0); + Lsr(); + //ot(" ldmfd sp!,{r1}\n"); + ot(" mov r1, r3\n"); + MemHandler(1, 0, 1); + break; + + case 0x5B: // LSR dp+X + ot(" ldrb r0,[spc_pc]\n"); + ot(" add r0,r0,spc_x\n"); + MemHandler(0, 1, 0); + Lsr(); + ot(" ldrb r1,[spc_pc],#1\n"); + ot(" add r1,r1,spc_x\n"); + MemHandler(1, 1, 1); + break; + + case 0x5C: // LSR A + ot(" and r0,spc_ya,#0xff\n"); + Lsr(); + ot(" mov spc_ya,spc_ya,lsr #8\n"); + otb(" orr spc_ya,r0,spc_ya,lsl #8\n"); + break; + + case 0x7D: // MOV A,X + ot(" and spc_ya,spc_ya,#0xff00\n"); + ot(" orr spc_ya,spc_ya,spc_x\n"); + SetZN8("spc_ya"); + break; + + case 0xDD: // MOV A,Y + ot(" and spc_ya,spc_ya,#0xff00\n"); + ot(" orr spc_ya,spc_ya,spc_ya,lsr #8\n"); + SetZN8("spc_ya"); + break; + + case 0x5D: // MOV X,A + ot(" and spc_x,spc_ya,#0xff\n"); + SetZN8("spc_x"); + break; + + case 0xFD: // MOV Y,A + ot(" and spc_ya,spc_ya,#0xff\n"); + ot(" orr spc_ya,spc_ya,spc_ya,lsl #8\n"); + SetZN8("spc_ya"); + break; + + case 0x9D: // MOV X,SP + ot(" mov spc_x,spc_s\n"); + SetZN8("spc_x"); + break; + + case 0xBD: // SP,X + otb(" mov spc_s,spc_x\n"); + break; + + case 0x6B: // ROR dp + ot(" ldrb r0,[spc_pc]\n"); + MemHandler(0, 1, 0); + Ror(); + ot(" ldrb r1,[spc_pc],#1\n"); + MemHandler(1, 1, 1); + break; + + case 0x6C: // ROR abs + Absolute(0); + //ot(" stmfd sp!,{r0}\n"); + ot(" mov r3, r0\n"); + MemHandler(0, 0, 0); + Ror(); + ot(" mov r1, r3\n"); + //ot(" ldmfd sp!,{r1}\n"); + MemHandler(1, 0, 1); + break; + + case 0x7B: // ROR dp+X + ot(" ldrb r0,[spc_pc]\n"); + ot(" add r0,r0,spc_x\n"); + MemHandler(0, 1, 0); + Ror(); + ot(" ldrb r1,[spc_pc],#1\n"); + ot(" add r1,r1,spc_x\n"); + MemHandler(1, 1, 1); + break; + + case 0x7C: // ROR A + ot(" and r0,spc_ya,#0xff\n"); + Ror(); + ot(" mov spc_ya,spc_ya,lsr #8\n"); + otb(" orr spc_ya,r0,spc_ya,lsl #8\n"); + break; + + case 0x6E: // DBNZ dp,rel + ot(" ldrb r0,[spc_pc]\n"); + MemHandler(0, 1, 0); + ot(" ldrb r1,[spc_pc],#1\n"); + ot(" sub r0,r0,#1\n"); + ot(" tst r0,r0\n"); + ot(" addeq spc_pc,spc_pc,#1\n"); + ot(" ldrnesb r2,[spc_pc],#1\n"); + ot(" addne spc_pc,spc_pc,r2\n"); + ot(" subne cycles,cycles,#%i\n", one_apu_cycle[current_cycles]*2); + MemHandler(1, 1, 1); + break; + + case 0xFE: // DBNZ Y,rel + ot(" sub spc_ya,spc_ya,#0x100\n"); + ot(" mov spc_ya,spc_ya,lsl #16\n"); + ot(" mov spc_ya,spc_ya,lsr #16\n"); + ot(" movs r0,spc_ya,lsr #8\n"); + ot(" addeq spc_pc,spc_pc,#1\n"); + ot(" ldrnesb r0,[spc_pc],#1\n"); + ot(" addne spc_pc,spc_pc,r0\n"); + ot(" subne cycles,cycles,#%i\n", one_apu_cycle[current_cycles]*2); + break; + + case 0x6F: // RET + PopW(); + ot(" add spc_pc,spc_ram,r0\n"); + break; + + case 0x7F: // RETI + Pop("spc_p"); + ot(" and r0,spc_p,#(flag_z|flag_n)\n"); + ot(" eor r0,r0,#flag_z\n"); + ot(" orr spc_p,spc_p,r0,lsl #24\n"); + ot(" tst spc_p,#flag_d\n"); + ot(" addne r0,spc_ram,#0x100\n"); + ot(" moveq r0,spc_ram\n"); + ot(" str r0,[context,#iapu_directpage]\n"); + PopW(); + ot(" add spc_pc,spc_ram,r0\n"); + break; + + case 0x89: // ADC dp(dest), dp(src) + ot(" ldrb r0,[spc_pc],#1\n"); + MemHandler(0, 1, 0); + //ot(" stmfd sp!,{r0}\n"); + ot(" mov r3, r0\n"); + ot(" ldrb r0,[spc_pc]\n"); + MemHandler(0, 1, 0); + //ot(" ldmfd sp!,{r1}\n"); + //ot(" mov r1, r3\n"); + Adc("r0", "r3"); + SetZN8("r0"); + ot(" ldrb r1,[spc_pc],#1\n"); + MemHandler(1, 1, 1); + break; + + case 0x98: // ADC dp,#00 + ot(" ldrb r0,[spc_pc,#1]\n"); + MemHandler(0, 1, 0); + ot(" ldrb r1,[spc_pc],#2\n"); + Adc("r0", "r1"); + SetZN8("r0"); + ot(" ldrb r1,[spc_pc,#-1]\n"); + MemHandler(1, 1, 1); + break; + + case 0x99: // ADC (X),(Y) + ot(" mov r0,spc_x\n"); + MemHandler(0, 1, 0); + //ot(" stmfd sp!,{r0}\n"); + ot(" mov r3, r0\n"); + ot(" mov r0,spc_ya,lsr #8\n"); + MemHandler(0, 1, 0); + //ot(" ldmfd sp!,{r1}\n"); + //ot(" mov r1, r3\n"); + Adc("r0", "r3"); + SetZN8("r0"); + ot(" mov r1,spc_x\n"); + MemHandler(1, 1, 1); + break; + + case 0x8D: // MOV Y,#00 //-REVISAR + ot(" ldrb r0,[spc_pc],#1\n"); + ot(" and spc_ya,spc_ya,#0xff\n"); + ot(" orr spc_ya,spc_ya,r0,lsl #8\n"); + SetZN8("r0"); + break; + + case 0x8F: // MOV dp,#00 //-REVISAR + ot(" ldrb r0,[spc_pc],#1\n"); + ot(" ldrb r1,[spc_pc],#1\n"); + MemHandler(1, 1, 1); + break; + + case 0x9E: // DIV YA,X + ot(" tst spc_x,spc_x @ div by 0?\n"); + ot(" orreq spc_ya,spc_ya,#0xff00\n"); + ot(" orreq spc_ya,spc_ya,#0x00ff\n"); + ot(" orreq spc_p,spc_p,#flag_o\n"); + ot(" beq 1002f\n"); + ot(" bic spc_p,spc_p,#flag_o\n"); + + // division algo from Cyclone (result in r3, remainder instead of divident) + ot("@ Divide spc_ya by spc_x\n"); + ot(" mov r3,#0\n"); + ot(" mov r1,spc_x\n"); + ot("\n"); + + // + /*ot("@ Shift up divisor till it's just less than numerator\n"); + ot("divshift:\n"); + ot(" cmp r1,spc_ya,lsr #1\n"); + ot(" movls r1,r1,lsl #1\n"); + ot(" bcc divshift\n"); + ot("\n");*/ + + //optimised version of code provided by William Blair + ot("@ Shift up divisor till it's just less than numerator\n"); + ot("cmp spc_ya,r1,lsl #8\n"); + ot("movge r1,r1,lsl #8\n"); + ot("cmp spc_ya,r1,lsl #4\n"); + ot("movge r1,r1,lsl #4\n"); + ot("cmp spc_ya,r1,lsl #2\n"); + ot("movge r1,r1,lsl #2\n"); + ot("cmp spc_ya,r1,lsl #1\n"); + ot("movge r1,r1,lsl #1\n"); + + ot("1001:\n"); + ot(" cmp spc_ya,r1\n"); + ot(" adc r3,r3,r3 ;@ Double r3 and add 1 if carry set\n"); + ot(" subcs spc_ya,spc_ya,r1\n"); + ot(" teq r1,spc_x\n"); + ot(" movne r1,r1,lsr #1\n"); + ot(" bne 1001b\n"); + ot("\n"); + + ot(" and spc_ya,spc_ya,#0xff\n"); + ot(" and r3,r3,#0xff\n"); + ot(" orr spc_ya,r3,spc_ya,lsl #8\n"); + + ot("1002:\n"); + SetZN8("spc_ya"); + break; + + case 0x9F: // XCN A + ot(" and r0,spc_ya,#0xff\n"); + ot(" mov r1,r0,lsl #28\n"); + ot(" orr r0,r1,r0,lsl #20\n"); + ot(" and spc_ya,spc_ya,#0xff00\n"); + ot(" orr spc_ya,spc_ya,r0,lsr #24\n"); + SetZN8("spc_ya"); + break; + + case 0xA9: // SBC dp(dest), dp(src) + ot(" ldrb r0,[spc_pc],#1\n"); + MemHandler(0, 1, 0); + //ot(" stmfd sp!,{r0}\n"); + ot(" mov r3, r0\n"); + ot(" ldrb r0,[spc_pc]\n"); + MemHandler(0, 1, 0); + //ot(" ldmfd sp!,{r1}\n"); + //ot(" mov r1, r3\n"); + Sbc("r0", "r3"); + SetZN8("r0"); + ot(" ldrb r1,[spc_pc],#1\n"); + MemHandler(1, 1, 1); + break; + + case 0xB8: // SBC dp,#00 + ot(" ldrb r0,[spc_pc,#1]\n"); + MemHandler(0, 1, 0); + ot(" ldrb r1,[spc_pc],#2\n"); + Sbc("r0", "r1"); + SetZN8("r0"); + ot(" ldrb r1,[spc_pc,#-1]\n"); + MemHandler(1, 1, 1); + break; + + case 0xB9: // SBC (X),(Y) + ot(" mov r0,spc_x\n"); + MemHandler(0, 1, 0); + //ot(" stmfd sp!,{r0}\n"); + ot(" mov r3, r0\n"); + ot(" mov r0,spc_ya,lsr #8\n"); + MemHandler(0, 1, 0); + //ot(" ldmfd sp!,{r1}\n"); + //ot(" mov r1, r3\n"); + Sbc("r0", "r3"); + SetZN8("r0"); + ot(" mov r1,spc_x\n"); + MemHandler(1, 1, 1); + break; + + case 0xAF: // MOV (X)+, A + ot(" mov r0,spc_ya\n"); + ot(" mov r1,spc_x\n"); + MemHandler(1, 1, 1); + ot(" add spc_x,spc_x,#1\n"); + otb(" and spc_x,spc_x,#0xff\n"); + break; + + case 0xBE: // DAS + ot(" and r0,spc_ya,#0xff\n"); + ot(" and r1,spc_ya,#0x0f\n"); + ot(" cmp r1,#9\n"); + ot(" subhi r0,r0,#6\n"); + ot(" tstls spc_p,#flag_h\n"); + ot(" subeq r0,r0,#6\n"); + ot(" cmp r0,#0x9f\n"); + ot(" bhi 2001f\n"); + ot(" tst spc_p,#flag_c\n"); + ot(" beq 2001f\n"); + ot(" orr spc_p,spc_p,#flag_c\n"); + ot(" b 2002f\n"); + ot("2001:\n"); // tens + ot(" sub r0,r0,#0x60\n"); + ot(" bic spc_p,spc_p,#flag_c\n"); + + ot("2002:\n"); // end + ot(" and spc_ya,spc_ya,#0xff00\n"); + ot(" orr spc_ya,spc_ya,r0\n"); + SetZN8("spc_ya"); + break; + + case 0xBF: // MOV A,(X)+ + ot(" mov r0,spc_x\n"); + MemHandler(0, 1, 1); + ot(" and spc_ya,spc_ya,#0xff00\n"); + ot(" orr spc_ya,spc_ya,r0\n"); + ot(" add spc_x,spc_x,#1\n"); + ot(" and spc_x,spc_x,#0xff\n"); + SetZN8("spc_ya"); + break; + + case 0xC0: // DI + otb(" bic spc_p,spc_p,#flag_i\n"); + break; + + case 0xA0: // EI + otb(" orr spc_p,spc_p,#flag_i\n"); + break; + + case 0xC4: // MOV dp,A + ot(" ldrb r1,[spc_pc],#1\n"); + ot(" mov r0,spc_ya\n"); + MemHandler(1, 1, 1); + break; + + case 0xC5: // MOV abs,A + Absolute(1); + ot(" mov r0,spc_ya\n"); + MemHandler(1, 0, 1); + break; + + case 0xC6: // MOV (X),A + ot(" mov r0,spc_ya\n"); + ot(" mov r1,spc_x\n"); + MemHandler(1, 1, 1); + break; + + case 0xC7: // MOV (dp+X),A + IndexedXIndirect(1); + ot(" mov r0,spc_ya\n"); + MemHandler(1, 0, 1); + break; + + case 0xC9: // MOV abs,X + Absolute(1); + ot(" mov r0,spc_x\n"); + MemHandler(1, 0, 1); + break; + + case 0xCB: // MOV dp,Y + ot(" ldrb r1,[spc_pc],#1\n"); + ot(" mov r0,spc_ya,lsr #8\n"); + MemHandler(1, 1, 1); + break; + + case 0xCC: // MOV abs,Y + + Absolute(1); + ot(" mov r0,spc_ya,lsr #8\n"); + MemHandler(1, 0, 1); + break; + + case 0xCD: // MOV X,#00 + ot(" ldrb spc_x,[spc_pc],#1\n"); + SetZN8("spc_x"); + break; + + case 0xCF: // MUL YA + ot(" mov r0,spc_ya,lsr #8\n"); + ot(" and spc_ya,spc_ya,#0xff\n"); + ot(" mul spc_ya,r0,spc_ya\n"); + SetZN16("spc_ya"); + break; + + case 0xD4: // MOV dp+X, A + ot(" ldrb r1,[spc_pc],#1\n"); + ot(" mov r0,spc_ya\n"); + ot(" add r1,r1,spc_x\n"); + MemHandler(1, 1, 1); + break; + + case 0xD5: // MOV abs+X,A + AbsoluteX(1); + ot(" mov r0,spc_ya\n"); + MemHandler(1, 0, 1); + break; + + case 0xD6: // MOV abs+Y,A + AbsoluteY(1); + ot(" mov r0,spc_ya\n"); + MemHandler(1, 0, 1); + break; + + case 0xD7: // MOV (dp)+Y,A + IndirectIndexedY(1); + ot(" mov r0,spc_ya\n"); + MemHandler(1, 0, 1); + break; + + case 0xD8: // MOV dp,X + ot(" ldrb r1,[spc_pc],#1\n"); + ot(" mov r0,spc_x\n"); + MemHandler(1, 1, 1); + break; + + case 0xD9: // MOV dp+Y,X + ot(" ldrb r1,[spc_pc],#1\n"); + ot(" mov r0,spc_x\n"); + ot(" add r1,r1,spc_ya,lsr #8\n"); + MemHandler(1, 1, 1); + break; + + case 0xDB: // MOV dp+X,Y + ot(" ldrb r1,[spc_pc],#1\n"); + ot(" mov r0,spc_ya,lsr #8\n"); + ot(" add r1,r1,spc_x\n"); + MemHandler(1, 1, 1); + break; + + case 0xDF: // DAA + ot(" and r0,spc_ya,#0xff\n"); + ot(" and r1,spc_ya,#0x0f\n"); + ot(" cmp r1,#9\n"); + ot(" addhi r0,r0,#6\n"); + ot(" bls 3001f\n"); + ot(" cmphi r0,#0xf0\n"); + ot(" orrhi spc_p,spc_p,#flag_c\n"); + ot(" b 3002f\n"); + ot("3001:\n"); // testHc + ot(" tst spc_p,#flag_h\n"); + ot(" addne r0,r0,#6\n"); + ot(" beq 3002f\n"); + ot(" cmp r0,#0xf0\n"); + ot(" orrhi spc_p,spc_p,#flag_c\n"); + ot("3002:\n"); // test2 + ot(" tst spc_p,#flag_c\n"); + ot(" addne r0,r0,#0x60\n"); + ot(" bne 3003f\n"); + ot(" cmp r0,#0x9f\n"); + ot(" addhi r0,r0,#0x60\n"); + ot(" orrhi spc_p,spc_p,#flag_c\n"); + ot(" bicls spc_p,spc_p,#flag_c\n"); + ot("3003:\n"); // end + ot(" and spc_ya,spc_ya,#0xff00\n"); + ot(" orr spc_ya,spc_ya,r0\n"); + SetZN8("spc_ya"); + break; + + case 0xE9: // MOV X, abs + Absolute(0); + MemHandler(0, 0, 1); + ot(" mov spc_x,r0\n"); + SetZN8("spc_x"); + break; + + case 0xEB: // MOV Y,dp + ot(" ldrb r0,[spc_pc],#1\n"); + MemHandler(0, 1, 1); + ot(" and spc_ya,spc_ya,#0xff\n"); + ot(" orr spc_ya,spc_ya,r0,lsl #8\n"); + SetZN8("r0"); + break; + + case 0xEC: // MOV Y,abs + Absolute(0); + MemHandler(0, 0, 1); + ot(" and spc_ya,spc_ya,#0xff\n"); + ot(" orr spc_ya,spc_ya,r0,lsl #8\n"); + SetZN8("r0"); + break; + + case 0xF8: // MOV X,dp + ot(" ldrb r0,[spc_pc],#1\n"); + MemHandler(0, 1, 1); + ot(" mov spc_x,r0\n"); + SetZN8("spc_x"); + break; + + case 0xF9: // MOV X,dp+Y + ot(" ldrb r0,[spc_pc],#1\n"); + ot(" add r0,r0,spc_ya,lsr #8\n"); + MemHandler(0, 1, 1); + ot(" mov spc_x,r0\n"); + SetZN8("spc_x"); + break; + + case 0xFA: // MOV dp(dest),dp(src) + ot(" ldrb r0,[spc_pc],#1\n"); + MemHandler(0, 1, 0); + ot(" ldrb r1,[spc_pc],#1\n"); + MemHandler(1, 1, 1); + break; + + case 0xFB: // MOV Y,dp+X + ot(" ldrb r0,[spc_pc],#1\n"); + ot(" add r0,r0,spc_x\n"); + MemHandler(0, 1, 1); + ot(" and spc_ya,spc_ya,#0xff\n"); + ot(" orr spc_ya,spc_ya,r0,lsl #8\n"); + SetZN8("r0"); + break; + } + + //tmp_epilogue(); + ot(" subs cycles,cycles,#%i\n", S9xAPUCycles[opcode] * one_apu_cycle[current_cycles]); + ot(" ldrgeb opcode,[spc_pc],#1\n"); + flush_buffer(); + ot(" ldrge pc,[opcodes,opcode,lsl #2]\n"); + ot(" b spc700End\n"); + + printf("\b\b"); + } + + + ot("\n\n"); + +} + + +void printJumpTable(int apu_cycles) { + int i; + ot("@ -------------------------- Jump Table %i --------------------------\n", apu_cycles); + ot("Spc700JumpTab_%i:\n", apu_cycles); + + for (i=0; i < 0x100; i++) + { + if ((i&7)==0) ot(" .long "); + + ot("Apu%02X_%i", i, apu_cycles); + + if ((i&7)==7) ot(" @ %02x\n",i-7); + else if (i+1 < 0x100) ot(", "); + } + +} + +int main() +{ + printf("\n notaz's SPC700 Emulator v%s - Core Creator\n\n", VERSION); + + // Open the assembly file + AsmFile=fopen("spc700a.s", "wt"); if (AsmFile==NULL) return 1; + + ot("@ notaz's SPC700 Emulator v%s - Assembler Output\n\n", VERSION); + ot("@ (c) Copyright 2006 notaz, All rights reserved.\n\n"); + ot("@ Modified by bitrider 2010 - 2011\n\n"); + ot("@ this is a rewrite of spc700.cpp in ARM asm, inspired by other asm CPU cores like\n"); + ot("@ Cyclone and DrZ80. It is meant to be used in Snes9x emulator ports for ARM platforms.\n\n"); + ot("@ the code is released under Snes9x license. See spcgen.c or any other source file\n@ from Snes9x source tree.\n\n\n"); + + PrintFramework(); + + ot(" .align 4\n"); + + for (current_cycles=0; current_cycles < (sizeof(one_apu_cycle) / sizeof(int)); current_cycles++) { + printOpcodes(one_apu_cycle[current_cycles]); + printJumpTable(one_apu_cycle[current_cycles]); + } + + + fclose(AsmFile); AsmFile=NULL; + + printf("Assembling...\n"); + // Assemble the file + //system("as -marmv4t -mthumb-interwork -o spc700a.o spc700a.S"); + printf("Done!\n\n"); + + return 0; +} diff --git a/src/spc700/spcgen.dsp b/src/spc700/spcgen.dsp new file mode 100644 index 0000000..a6bf264 --- /dev/null +++ b/src/spc700/spcgen.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="spcgen" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=spcgen - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "spcgen.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "spcgen.mak" CFG="spcgen - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "spcgen - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "spcgen - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "spcgen - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "spcgen - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "spcgen - Win32 Release" +# Name "spcgen - Win32 Debug" +# Begin Source File + +SOURCE=.\spcgen.c +# End Source File +# End Target +# End Project diff --git a/src/spc700/spcgen.dsw b/src/spc700/spcgen.dsw new file mode 100644 index 0000000..7b947fc --- /dev/null +++ b/src/spc700/spcgen.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "spcgen"=.\spcgen.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/src/spc700/spcgen.ncb b/src/spc700/spcgen.ncb new file mode 100644 index 0000000..22b2108 Binary files /dev/null and b/src/spc700/spcgen.ncb differ diff --git a/src/spc700/spcgen.opt b/src/spc700/spcgen.opt new file mode 100644 index 0000000..673f065 Binary files /dev/null and b/src/spc700/spcgen.opt differ diff --git a/src/spc700/spcgen.plg b/src/spc700/spcgen.plg new file mode 100644 index 0000000..8db8f5e --- /dev/null +++ b/src/spc700/spcgen.plg @@ -0,0 +1,32 @@ + + +
+

Build Log

+

+--------------------Configuration: spcgen - Win32 Debug-------------------- +

+

Command Lines

+Creating temporary file "C:\DOCUME~1\Dave\LOCALS~1\Temp\RSP2C.tmp" with contents +[ +/nologo /MLd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Fp"Debug/spcgen.pch" /YX /Fo"Debug/" /Fd"Debug/" /FD /GZ /c +"C:\Downloads\squidgesnes0392src\squidgesnes\spc700\spcgen.c" +] +Creating command line "cl.exe @C:\DOCUME~1\Dave\LOCALS~1\Temp\RSP2C.tmp" +Creating temporary file "C:\DOCUME~1\Dave\LOCALS~1\Temp\RSP2E.tmp" with contents +[ +kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:yes /pdb:"Debug/spcgen.pdb" /debug /machine:I386 /out:"Debug/spcgen.exe" /pdbtype:sept +.\Debug\spcgen.obj +] +Creating command line "link.exe @C:\DOCUME~1\Dave\LOCALS~1\Temp\RSP2E.tmp" +

Output Window

+Compiling... +spcgen.c +Linking... + + + +

Results

+spcgen.exe - 0 error(s), 0 warning(s) +
+ + -- cgit v1.2.3