mirror of
https://github.com/dborth/snes9xgx.git
synced 2024-11-27 13:04:21 +01:00
revert trunk
This commit is contained in:
parent
ad09c5e12f
commit
b0dc24689f
11
Makefile.gc
11
Makefile.gc
@ -19,16 +19,19 @@ TARGET := snes9xgx-gc
|
|||||||
TARGETDIR := executables
|
TARGETDIR := executables
|
||||||
BUILD := build_gc
|
BUILD := build_gc
|
||||||
SOURCES := source/ngc/images source/ngc/sounds source/ngc/fonts \
|
SOURCES := source/ngc/images source/ngc/sounds source/ngc/fonts \
|
||||||
source/ngc/gui source/ngc source/snes9x source/snes9x/apu \
|
source/ngc/gui source/ngc source/snes9x source/sz
|
||||||
source/sz
|
|
||||||
INCLUDES := source/snes9x source/ngc
|
INCLUDES := source/snes9x source/ngc
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# options for code generation
|
# options for code generation
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
|
|
||||||
CFLAGS = -g -O3 -Wall $(MACHDEP) $(INCLUDE) -DNO_SOUND \
|
CFLAGS = -g -O3 -Wall $(MACHDEP) $(INCLUDE) \
|
||||||
-DZLIB -DRIGHTSHIFT_IS_SAR -DCPU_SHUTDOWN -DCORRECT_VRAM_READS \
|
-DNGC -DNO_SOUND \
|
||||||
|
-DNO_ASM -DRIGHTSHIFT_IS_SAR \
|
||||||
|
-DCPU_SHUTDOWN -DSPC700_SHUTDOWN \
|
||||||
|
-DSPC700_C -DSDD1_DECOMP \
|
||||||
|
-DCORRECT_VRAM_READS -DNEW_COLOUR_BLENDING \
|
||||||
-D_SZ_ONE_DIRECTORY -D_LZMA_IN_CB -D_LZMA_OUT_READ \
|
-D_SZ_ONE_DIRECTORY -D_LZMA_IN_CB -D_LZMA_OUT_READ \
|
||||||
-fomit-frame-pointer \
|
-fomit-frame-pointer \
|
||||||
-Wno-unused-parameter -Wno-strict-aliasing \
|
-Wno-unused-parameter -Wno-strict-aliasing \
|
||||||
|
@ -19,8 +19,7 @@ TARGET := snes9xgx-wii
|
|||||||
TARGETDIR := executables
|
TARGETDIR := executables
|
||||||
BUILD := build_wii
|
BUILD := build_wii
|
||||||
SOURCES := source/ngc/images source/ngc/sounds source/ngc/fonts \
|
SOURCES := source/ngc/images source/ngc/sounds source/ngc/fonts \
|
||||||
source/ngc/gui source/ngc source/snes9x source/snes9x/apu \
|
source/ngc/gui source/ngc source/snes9x source/sz source/unzip
|
||||||
source/sz source/unzip
|
|
||||||
INCLUDES := source/snes9x source/ngc source/unzip
|
INCLUDES := source/snes9x source/ngc source/unzip
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
@ -28,7 +27,11 @@ INCLUDES := source/snes9x source/ngc source/unzip
|
|||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
|
|
||||||
CFLAGS = -g -O3 -Wall $(MACHDEP) $(INCLUDE) \
|
CFLAGS = -g -O3 -Wall $(MACHDEP) $(INCLUDE) \
|
||||||
-DZLIB -DRIGHTSHIFT_IS_SAR -DCPU_SHUTDOWN -DCORRECT_VRAM_READS \
|
-DNGC \
|
||||||
|
-DNO_ASM -DRIGHTSHIFT_IS_SAR \
|
||||||
|
-DCPU_SHUTDOWN -DSPC700_SHUTDOWN \
|
||||||
|
-DSPC700_C -DSDD1_DECOMP \
|
||||||
|
-DCORRECT_VRAM_READS -DNEW_COLOUR_BLENDING \
|
||||||
-D_SZ_ONE_DIRECTORY -D_LZMA_IN_CB -D_LZMA_OUT_READ \
|
-D_SZ_ONE_DIRECTORY -D_LZMA_IN_CB -D_LZMA_OUT_READ \
|
||||||
-fomit-frame-pointer \
|
-fomit-frame-pointer \
|
||||||
-Wno-unused-parameter -Wno-strict-aliasing \
|
-Wno-unused-parameter -Wno-strict-aliasing \
|
||||||
|
@ -18,11 +18,14 @@
|
|||||||
|
|
||||||
#include "snes9x.h"
|
#include "snes9x.h"
|
||||||
#include "memmap.h"
|
#include "memmap.h"
|
||||||
|
#include "s9xdebug.h"
|
||||||
#include "cpuexec.h"
|
#include "cpuexec.h"
|
||||||
#include "ppu.h"
|
#include "ppu.h"
|
||||||
#include "apu/apu.h"
|
#include "apu.h"
|
||||||
#include "display.h"
|
#include "display.h"
|
||||||
#include "gfx.h"
|
#include "gfx.h"
|
||||||
|
#include "soundux.h"
|
||||||
|
#include "spc700.h"
|
||||||
#include "spc7110.h"
|
#include "spc7110.h"
|
||||||
#include "controls.h"
|
#include "controls.h"
|
||||||
|
|
||||||
@ -39,7 +42,6 @@ static int whichab = 0; /*** Audio buffer flip switch ***/
|
|||||||
static lwpq_t audioqueue;
|
static lwpq_t audioqueue;
|
||||||
static lwp_t athread;
|
static lwp_t athread;
|
||||||
static uint8 astack[AUDIOSTACK];
|
static uint8 astack[AUDIOSTACK];
|
||||||
static mutex_t audiomutex = LWP_MUTEX_NULL;
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Audio Threading
|
* Audio Threading
|
||||||
@ -56,9 +58,8 @@ AudioThread (void *arg)
|
|||||||
memset (soundbuffer[whichab], 0, AUDIOBUFFER);
|
memset (soundbuffer[whichab], 0, AUDIOBUFFER);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LWP_MutexLock(audiomutex);
|
so.samples_mixed_so_far = so.play_position = 0;
|
||||||
S9xMixSamples (soundbuffer[whichab], AUDIOBUFFER >> 1);
|
S9xMixSamples (soundbuffer[whichab], AUDIOBUFFER >> 1);
|
||||||
LWP_MutexUnlock(audiomutex);
|
|
||||||
}
|
}
|
||||||
LWP_ThreadSleep (audioqueue);
|
LWP_ThreadSleep (audioqueue);
|
||||||
}
|
}
|
||||||
@ -84,13 +85,6 @@ GCMixSamples ()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FinalizeSamplesCallback (void *data)
|
|
||||||
{
|
|
||||||
LWP_MutexLock(audiomutex);
|
|
||||||
S9xFinalizeSamples();
|
|
||||||
LWP_MutexUnlock(audiomutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* InitAudio
|
* InitAudio
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
@ -104,7 +98,6 @@ InitAudio ()
|
|||||||
#else
|
#else
|
||||||
ASND_Init();
|
ASND_Init();
|
||||||
#endif
|
#endif
|
||||||
LWP_MutexInit(&audiomutex, false);
|
|
||||||
LWP_CreateThread (&athread, AudioThread, NULL, astack, AUDIOSTACK, 70);
|
LWP_CreateThread (&athread, AudioThread, NULL, astack, AUDIOSTACK, 70);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,11 +117,9 @@ SwitchAudioMode(int mode)
|
|||||||
AUDIO_SetDSPSampleRate(AI_SAMPLERATE_32KHZ);
|
AUDIO_SetDSPSampleRate(AI_SAMPLERATE_32KHZ);
|
||||||
AUDIO_RegisterDMACallback(GCMixSamples);
|
AUDIO_RegisterDMACallback(GCMixSamples);
|
||||||
#endif
|
#endif
|
||||||
S9xSetSamplesAvailableCallback(FinalizeSamplesCallback, NULL);
|
|
||||||
}
|
}
|
||||||
else // menu
|
else // menu
|
||||||
{
|
{
|
||||||
S9xSetSamplesAvailableCallback(NULL, NULL);
|
|
||||||
#ifndef NO_SOUND
|
#ifndef NO_SOUND
|
||||||
ASND_Init();
|
ASND_Init();
|
||||||
ASND_Pause(0);
|
ASND_Pause(0);
|
||||||
|
@ -453,39 +453,6 @@ int BrowserLoadSz()
|
|||||||
return szfiles;
|
return szfiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
int WiiFileLoader()
|
|
||||||
{
|
|
||||||
int size;
|
|
||||||
char filepath[1024];
|
|
||||||
|
|
||||||
memset(Memory.NSRTHeader, 0, sizeof(Memory.NSRTHeader));
|
|
||||||
Memory.HeaderCount = 0;
|
|
||||||
|
|
||||||
if(!inSz)
|
|
||||||
{
|
|
||||||
if(!MakeFilePath(filepath, FILE_ROM))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
size = LoadFile ((char *)Memory.ROM, filepath, browserList[browser.selIndex].length, NOTSILENT);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
size = LoadSzFile(szpath, (unsigned char *)Memory.ROM);
|
|
||||||
|
|
||||||
if(size <= 0)
|
|
||||||
{
|
|
||||||
browser.selIndex = 0;
|
|
||||||
BrowserChangeFolder();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(size <= 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
SNESROMSize = Memory.HeaderRemove(size, Memory.HeaderCount, Memory.ROM);
|
|
||||||
return SNESROMSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* BrowserLoadFile
|
* BrowserLoadFile
|
||||||
*
|
*
|
||||||
@ -493,9 +460,11 @@ int WiiFileLoader()
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
int BrowserLoadFile()
|
int BrowserLoadFile()
|
||||||
{
|
{
|
||||||
|
char filepath[1024];
|
||||||
int loaded = 0;
|
int loaded = 0;
|
||||||
|
|
||||||
int device;
|
int device;
|
||||||
|
|
||||||
if(!FindDevice(browser.dir, &device))
|
if(!FindDevice(browser.dir, &device))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -508,7 +477,24 @@ int BrowserLoadFile()
|
|||||||
|
|
||||||
SNESROMSize = 0;
|
SNESROMSize = 0;
|
||||||
S9xDeleteCheats();
|
S9xDeleteCheats();
|
||||||
Memory.LoadROM("ROM");
|
|
||||||
|
if(!inSz)
|
||||||
|
{
|
||||||
|
if(!MakeFilePath(filepath, FILE_ROM))
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
SNESROMSize = LoadFile ((char *)Memory.ROM, filepath, browserList[browser.selIndex].length, NOTSILENT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SNESROMSize = LoadSzFile(szpath, (unsigned char *)Memory.ROM);
|
||||||
|
|
||||||
|
if(SNESROMSize <= 0)
|
||||||
|
{
|
||||||
|
browser.selIndex = 0;
|
||||||
|
BrowserChangeFolder();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (SNESROMSize <= 0)
|
if (SNESROMSize <= 0)
|
||||||
{
|
{
|
||||||
@ -516,12 +502,21 @@ int BrowserLoadFile()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// load UPS/IPS/PPF patch
|
||||||
|
WiiLoadPatch();
|
||||||
|
|
||||||
|
Memory.LoadROM ("BLANK.SMC");
|
||||||
|
Memory.LoadSRAM ("BLANK");
|
||||||
|
|
||||||
// load SRAM or snapshot
|
// load SRAM or snapshot
|
||||||
if (GCSettings.AutoLoad == 1)
|
if (GCSettings.AutoLoad == 1)
|
||||||
LoadSRAMAuto(SILENT);
|
LoadSRAMAuto(SILENT);
|
||||||
else if (GCSettings.AutoLoad == 2)
|
else if (GCSettings.AutoLoad == 2)
|
||||||
LoadSnapshotAuto(SILENT);
|
LoadSnapshotAuto(SILENT);
|
||||||
|
|
||||||
|
// setup cheats
|
||||||
|
WiiSetupCheats();
|
||||||
|
|
||||||
ResetBrowser();
|
ResetBrowser();
|
||||||
loaded = 1;
|
loaded = 1;
|
||||||
}
|
}
|
||||||
|
@ -7,41 +7,121 @@
|
|||||||
* Tantric 2008-2009
|
* Tantric 2008-2009
|
||||||
*
|
*
|
||||||
* freeze.cpp
|
* freeze.cpp
|
||||||
|
*
|
||||||
|
* Snapshots Memory File System
|
||||||
|
*
|
||||||
|
* This is a single global memory file controller.
|
||||||
|
* Don't even think of opening two at the same time!
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <gccore.h>
|
#include <gccore.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <fat.h>
|
||||||
|
#include <zlib.h>
|
||||||
|
|
||||||
#include "snes9x.h"
|
#include "snes9x.h"
|
||||||
#include "port.h"
|
|
||||||
#include "memmap.h"
|
#include "memmap.h"
|
||||||
|
#include "soundux.h"
|
||||||
#include "snapshot.h"
|
#include "snapshot.h"
|
||||||
|
#include "srtc.h"
|
||||||
|
|
||||||
#include "snes9xGX.h"
|
#include "snes9xGX.h"
|
||||||
|
#include "freeze.h"
|
||||||
#include "fileop.h"
|
#include "fileop.h"
|
||||||
#include "filebrowser.h"
|
#include "filebrowser.h"
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
#include "pngu.h"
|
#include "pngu.h"
|
||||||
|
|
||||||
bool8 S9xOpenSnapshotFile(const char *filepath, bool8 readonly, STREAM *file)
|
extern void S9xSRTCPreSaveState ();
|
||||||
|
extern void NGCFreezeStruct ();
|
||||||
|
extern bool8 S9xUnfreezeGame (const char *filename);
|
||||||
|
|
||||||
|
static int bufoffset;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* GetMem
|
||||||
|
*
|
||||||
|
* Return x bytes from memory buffer
|
||||||
|
***************************************************************************/
|
||||||
|
int
|
||||||
|
GetMem (char *buffer, int len)
|
||||||
{
|
{
|
||||||
return FALSE;
|
memcpy (buffer, savebuffer + bufoffset, len);
|
||||||
|
bufoffset += len;
|
||||||
|
|
||||||
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xCloseSnapshotFile(STREAM s)
|
/****************************************************************************
|
||||||
|
* PutMem
|
||||||
|
*
|
||||||
|
* Put some values in memory buffer
|
||||||
|
***************************************************************************/
|
||||||
|
static void
|
||||||
|
PutMem (char *buffer, int len)
|
||||||
{
|
{
|
||||||
|
memcpy (savebuffer + bufoffset, buffer, len);
|
||||||
|
bufoffset += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NGCFreezeBlock (char *name, uint8 * block, int size)
|
||||||
|
{
|
||||||
|
char buffer[512];
|
||||||
|
sprintf (buffer, "%s:%06d:", name, size);
|
||||||
|
PutMem (buffer, strlen (buffer));
|
||||||
|
PutMem ((char *) block, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* NGCFreezeMembuffer
|
||||||
|
*
|
||||||
|
* Copies a snapshot of Snes9x state into memory
|
||||||
|
***************************************************************************/
|
||||||
|
static int
|
||||||
|
NGCFreezeMemBuffer ()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char buffer[1024];
|
||||||
|
|
||||||
|
bufoffset = 0;
|
||||||
|
|
||||||
|
S9xUpdateRTC ();
|
||||||
|
S9xSRTCPreSaveState ();
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
SoundData.channels[i].previous16[0] =
|
||||||
|
(int16) SoundData.channels[i].previous[0];
|
||||||
|
SoundData.channels[i].previous16[1] =
|
||||||
|
(int16) SoundData.channels[i].previous[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf (buffer, "%s:%04d\n", SNAPSHOT_MAGIC, SNAPSHOT_VERSION);
|
||||||
|
PutMem (buffer, strlen (buffer));
|
||||||
|
sprintf (buffer, "NAM:%06d:%s%c", (int) strlen (Memory.ROMFilename) + 1,
|
||||||
|
Memory.ROMFilename, 0);
|
||||||
|
|
||||||
|
PutMem (buffer, strlen (buffer) + 1);
|
||||||
|
|
||||||
|
NGCFreezeStruct ();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* SaveSnapshot
|
* SaveSnapshot
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
int
|
int
|
||||||
SaveSnapshot (char * filepath, bool silent)
|
SaveSnapshot (char * filepath, bool silent)
|
||||||
{
|
{
|
||||||
|
int offset = 0; // bytes written (actual)
|
||||||
|
int woffset = 0; // bytes written (expected)
|
||||||
int imgSize = 0; // image screenshot bytes written
|
int imgSize = 0; // image screenshot bytes written
|
||||||
int device;
|
int device;
|
||||||
|
|
||||||
@ -73,21 +153,28 @@ SaveSnapshot (char * filepath, bool silent)
|
|||||||
FreeSaveBuffer ();
|
FreeSaveBuffer ();
|
||||||
}
|
}
|
||||||
|
|
||||||
STREAM fp = OPEN_STREAM(filepath, "wb");
|
S9xSetSoundMute (TRUE);
|
||||||
|
S9xPrepareSoundForSnapshotSave (FALSE);
|
||||||
if(!fp)
|
|
||||||
|
AllocSaveBuffer ();
|
||||||
|
// copy freeze mem into savebuffer - bufoffset contains # bytes written
|
||||||
|
NGCFreezeMemBuffer ();
|
||||||
|
woffset = bufoffset;
|
||||||
|
|
||||||
|
S9xPrepareSoundForSnapshotSave (TRUE);
|
||||||
|
S9xSetSoundMute (FALSE);
|
||||||
|
|
||||||
|
offset = SaveFile(filepath, woffset, silent);
|
||||||
|
|
||||||
|
FreeSaveBuffer ();
|
||||||
|
|
||||||
|
if(offset > 0) // save successful!
|
||||||
{
|
{
|
||||||
if(!silent)
|
if(!silent)
|
||||||
ErrorPrompt("Save failed!");
|
InfoPrompt("Save successful");
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
S9xFreezeToStream(fp);
|
|
||||||
CLOSE_STREAM(fp);
|
|
||||||
|
|
||||||
if(!silent)
|
|
||||||
InfoPrompt("Save successful");
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -101,48 +188,76 @@ SaveSnapshotAuto (bool silent)
|
|||||||
return SaveSnapshot(filepath, silent);
|
return SaveSnapshot(filepath, silent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* NGCUnFreezeBlock
|
||||||
|
***************************************************************************/
|
||||||
|
int
|
||||||
|
NGCUnFreezeBlock (char *name, uint8 * block, int size)
|
||||||
|
{
|
||||||
|
char buffer[20], *e;
|
||||||
|
int len = 0;
|
||||||
|
int rem = 0;
|
||||||
|
|
||||||
|
GetMem (buffer, 11);
|
||||||
|
|
||||||
|
if (strncmp (buffer, name, 3) != 0 || buffer[3] != ':' ||
|
||||||
|
buffer[10] != ':' || (len = strtol (&buffer[4], &e, 10)) == 0 ||
|
||||||
|
e != buffer + 10)
|
||||||
|
{
|
||||||
|
bufoffset -= 11; // go back to where we started
|
||||||
|
return WRONG_FORMAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len > size)
|
||||||
|
{
|
||||||
|
rem = len - size;
|
||||||
|
len = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZeroMemory (block, size);
|
||||||
|
|
||||||
|
GetMem ((char *) block, len);
|
||||||
|
|
||||||
|
if (rem)
|
||||||
|
{
|
||||||
|
bufoffset += rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* LoadSnapshot
|
* LoadSnapshot
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
int
|
int
|
||||||
LoadSnapshot (char * filepath, bool silent)
|
LoadSnapshot (char * filepath, bool silent)
|
||||||
{
|
{
|
||||||
|
int offset = 0;
|
||||||
|
int result = 0;
|
||||||
|
bufoffset = 0;
|
||||||
int device;
|
int device;
|
||||||
|
|
||||||
if(!FindDevice(filepath, &device))
|
if(!FindDevice(filepath, &device))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
AllocSaveBuffer();
|
||||||
|
|
||||||
STREAM fp = OPEN_STREAM(filepath, "rb");
|
offset = LoadFile(filepath, silent);
|
||||||
|
|
||||||
if(!fp)
|
if(offset > 0)
|
||||||
|
{
|
||||||
|
if (S9xUnfreezeGame ("AGAME") == SUCCESS)
|
||||||
|
result = 1;
|
||||||
|
else
|
||||||
|
ErrorPrompt("Error thawing");
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if(!silent)
|
if(!silent)
|
||||||
ErrorPrompt("Unable to open snapshot!");
|
ErrorPrompt("Freeze file not found");
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
FreeSaveBuffer();
|
||||||
int result = S9xUnfreezeFromStream(fp);
|
return result;
|
||||||
CLOSE_STREAM(fp);
|
|
||||||
|
|
||||||
if (result == SUCCESS)
|
|
||||||
return 1;
|
|
||||||
/*
|
|
||||||
switch (result)
|
|
||||||
{
|
|
||||||
case WRONG_FORMAT:
|
|
||||||
S9xMessage(S9X_ERROR, S9X_WRONG_FORMAT, SAVE_ERR_WRONG_FORMAT);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WRONG_VERSION:
|
|
||||||
S9xMessage(S9X_ERROR, S9X_WRONG_VERSION, SAVE_ERR_WRONG_VERSION);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SNAPSHOT_INCONSISTENT:
|
|
||||||
S9xMessage(S9X_ERROR, S9X_SNAPSHOT_INCONSISTENT, MOVIE_ERR_SNAPSHOT_INCONSISTENT);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -7,11 +7,27 @@
|
|||||||
* Tantric August 2008
|
* Tantric August 2008
|
||||||
*
|
*
|
||||||
* freeze.h
|
* freeze.h
|
||||||
|
*
|
||||||
|
* Snapshots Memory File System
|
||||||
|
*
|
||||||
|
* This is a single global memory file controller.
|
||||||
|
* Don't even think of opening two at the same time!
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#ifndef _FREEZE_H_
|
#ifndef _FREEZE_H_
|
||||||
#define _FREEZE_H_
|
#define _FREEZE_H_
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char filename[512]; /*** Way over size - but who cares -;) ***/
|
||||||
|
int filehandle;
|
||||||
|
int currpos;
|
||||||
|
int length;
|
||||||
|
int mode;
|
||||||
|
char *buffer; /*** Memspace for read / write ***/
|
||||||
|
}
|
||||||
|
MEMFILE;
|
||||||
|
|
||||||
int SaveSnapshot (char * filepath, bool silent);
|
int SaveSnapshot (char * filepath, bool silent);
|
||||||
int SaveSnapshotAuto (bool silent);
|
int SaveSnapshotAuto (bool silent);
|
||||||
int LoadSnapshot (char * filepath, bool silent);
|
int LoadSnapshot (char * filepath, bool silent);
|
||||||
|
@ -41,6 +41,8 @@
|
|||||||
#include "gui/gui.h"
|
#include "gui/gui.h"
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
|
|
||||||
|
extern SCheatData Cheat;
|
||||||
|
|
||||||
#define THREAD_SLEEP 100
|
#define THREAD_SLEEP 100
|
||||||
|
|
||||||
#ifdef HW_RVL
|
#ifdef HW_RVL
|
||||||
|
@ -103,21 +103,28 @@ DefaultSettings ()
|
|||||||
memset (&Settings, 0, sizeof (Settings));
|
memset (&Settings, 0, sizeof (Settings));
|
||||||
|
|
||||||
// General
|
// General
|
||||||
|
|
||||||
Settings.MouseMaster = false;
|
Settings.MouseMaster = false;
|
||||||
Settings.SuperScopeMaster = false;
|
Settings.SuperScopeMaster = false;
|
||||||
Settings.MultiPlayer5Master = false;
|
Settings.MultiPlayer5Master = false;
|
||||||
Settings.JustifierMaster = false;
|
Settings.JustifierMaster = false;
|
||||||
Settings.ShutdownMaster = true; // needs to be on for ActRaiser 2
|
Settings.ShutdownMaster = true; // needs to be on for ActRaiser 2
|
||||||
Settings.BlockInvalidVRAMAccessMaster = false;
|
|
||||||
Settings.HDMATimingHack = 100;
|
|
||||||
Settings.ApplyCheats = true;
|
Settings.ApplyCheats = true;
|
||||||
Settings.DontSaveOopsSnapshot = true;
|
|
||||||
|
|
||||||
// Sound
|
Settings.BlockInvalidVRAMAccess = false;
|
||||||
|
Settings.HDMATimingHack = 100;
|
||||||
|
|
||||||
|
// Sound defaults. On GC this is 32Khz/16bit/Stereo/InterpolatedSound
|
||||||
|
Settings.APUEnabled = true;
|
||||||
|
Settings.NextAPUEnabled = true;
|
||||||
Settings.SoundPlaybackRate = 32000;
|
Settings.SoundPlaybackRate = 32000;
|
||||||
Settings.Stereo = true;
|
Settings.Stereo = true;
|
||||||
Settings.SixteenBitSound = true;
|
Settings.SixteenBitSound = true;
|
||||||
|
Settings.SoundEnvelopeHeightReading = true;
|
||||||
Settings.SoundSync = true;
|
Settings.SoundSync = true;
|
||||||
|
Settings.FixFrequency = false;
|
||||||
|
Settings.DisableSampleCaching = true;
|
||||||
|
Settings.InterpolatedSound = true;
|
||||||
Settings.ReverseStereo = true;
|
Settings.ReverseStereo = true;
|
||||||
|
|
||||||
// Graphics
|
// Graphics
|
||||||
@ -133,14 +140,22 @@ DefaultSettings ()
|
|||||||
Settings.FrameTimePAL = 20000;
|
Settings.FrameTimePAL = 20000;
|
||||||
Settings.FrameTimeNTSC = 16667;
|
Settings.FrameTimeNTSC = 16667;
|
||||||
|
|
||||||
|
// SDD1 - Star Ocean Returns
|
||||||
|
Settings.SDD1Pack = true;
|
||||||
|
|
||||||
Settings.ForceNTSC = 0;
|
Settings.ForceNTSC = 0;
|
||||||
Settings.ForcePAL = 0;
|
Settings.ForcePAL = 0;
|
||||||
Settings.ForceHiROM = 0;
|
Settings.ForceHiROM = 0;
|
||||||
Settings.ForceLoROM = 0;
|
Settings.ForceLoROM = 0;
|
||||||
Settings.ForceHeader = 0;
|
Settings.ForceHeader = 0;
|
||||||
Settings.ForceNoHeader = 0;
|
Settings.ForceNoHeader = 0;
|
||||||
|
Settings.ForceTransparency = 0;
|
||||||
Settings.ForceInterleaved = 0;
|
Settings.ForceInterleaved = 0;
|
||||||
Settings.ForceInterleaved2 = 0;
|
Settings.ForceInterleaved2 = 0;
|
||||||
Settings.ForceInterleaveGD24 = 0;
|
Settings.ForceInterleaveGD24 = 0;
|
||||||
Settings.ForceNotInterleaved = 0;
|
Settings.ForceNotInterleaved = 0;
|
||||||
|
Settings.ForceNoSuperFX = 0;
|
||||||
|
Settings.ForceSuperFX = 0;
|
||||||
|
Settings.ForceDSP1 = 0;
|
||||||
|
Settings.ForceNoDSP1 = 0;
|
||||||
}
|
}
|
||||||
|
@ -21,8 +21,15 @@
|
|||||||
|
|
||||||
#include "snes9x.h"
|
#include "snes9x.h"
|
||||||
#include "memmap.h"
|
#include "memmap.h"
|
||||||
|
#include "s9xdebug.h"
|
||||||
|
#include "cpuexec.h"
|
||||||
|
#include "ppu.h"
|
||||||
|
#include "apu.h"
|
||||||
#include "display.h"
|
#include "display.h"
|
||||||
#include "apu/apu.h"
|
#include "gfx.h"
|
||||||
|
#include "soundux.h"
|
||||||
|
#include "spc700.h"
|
||||||
|
#include "spc7110.h"
|
||||||
#include "controls.h"
|
#include "controls.h"
|
||||||
|
|
||||||
#include "snes9xGX.h"
|
#include "snes9xGX.h"
|
||||||
@ -56,14 +63,11 @@ void S9xAutoSaveSRAM()
|
|||||||
/*** Sound based functions ***/
|
/*** Sound based functions ***/
|
||||||
void S9xToggleSoundChannel(int c)
|
void S9xToggleSoundChannel(int c)
|
||||||
{
|
{
|
||||||
static int sound_switch = 255;
|
if (c == 8)
|
||||||
|
so.sound_switch = 255;
|
||||||
if (c == 8)
|
else
|
||||||
sound_switch = 255;
|
so.sound_switch ^= 1 << c;
|
||||||
else
|
S9xSetSoundControl(so.sound_switch);
|
||||||
sound_switch ^= 1 << c;
|
|
||||||
|
|
||||||
S9xSetSoundControl (sound_switch);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -71,12 +75,25 @@ void S9xToggleSoundChannel(int c)
|
|||||||
*
|
*
|
||||||
* Main initialisation for Wii sound system
|
* Main initialisation for Wii sound system
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
bool8 S9xOpenSoundDevice(int buffer_size)
|
bool8 S9xOpenSoundDevice(int mode, bool8 stereo, int buffer_size)
|
||||||
{
|
{
|
||||||
|
so.stereo = TRUE;
|
||||||
|
so.playback_rate = 32000;
|
||||||
|
so.sixteen_bit = TRUE;
|
||||||
|
so.encoded = 0;
|
||||||
|
so.buffer_size = 4096;
|
||||||
|
so.sound_switch = 255;
|
||||||
|
S9xSetPlaybackRate(so.playback_rate);
|
||||||
|
|
||||||
InitAudio();
|
InitAudio();
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*** Deprecated function. NGC uses threaded sound ***/
|
||||||
|
void S9xGenerateSound()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/* eke-eke */
|
/* eke-eke */
|
||||||
void S9xInitSync()
|
void S9xInitSync()
|
||||||
{
|
{
|
||||||
@ -196,6 +213,21 @@ bool S9xPollPointer(uint32 id, int16 * x, int16 * y)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void S9xLoadSDD1Data()
|
||||||
|
{
|
||||||
|
Memory.FreeSDD1Data();
|
||||||
|
|
||||||
|
Settings.SDD1Pack = FALSE;
|
||||||
|
|
||||||
|
if (strncmp(Memory.ROMName, "Star Ocean", 10) == 0)
|
||||||
|
Settings.SDD1Pack = TRUE;
|
||||||
|
|
||||||
|
if (strncmp(Memory.ROMName, "STREET FIGHTER ALPHA2", 21) == 0)
|
||||||
|
Settings.SDD1Pack = TRUE;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Note that these are DUMMY functions, and only allow Snes9x to
|
* Note that these are DUMMY functions, and only allow Snes9x to
|
||||||
* compile. Where possible, they will return an error signal.
|
* compile. Where possible, they will return an error signal.
|
||||||
@ -231,18 +263,12 @@ const char * S9xGetFilenameInc(const char *e, enum s9x_getdirtype dirtype)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char * S9xBasename(const char *name)
|
char * S9xBasename(char *name)
|
||||||
{
|
{
|
||||||
ExitApp();
|
ExitApp();
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char * S9xStringInput (const char * s)
|
|
||||||
{
|
|
||||||
ExitApp();
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _splitpath(char const *buf, char *drive, char *dir, char *fname, char *ext)
|
void _splitpath(char const *buf, char *drive, char *dir, char *fname, char *ext)
|
||||||
{
|
{
|
||||||
ExitApp();
|
ExitApp();
|
||||||
@ -253,15 +279,3 @@ void _makepath(char *filename, const char *drive, const char *dir,
|
|||||||
{
|
{
|
||||||
ExitApp();
|
ExitApp();
|
||||||
}
|
}
|
||||||
|
|
||||||
int dup(int fildes)
|
|
||||||
{
|
|
||||||
ExitApp();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int access(const char *pathname, int mode)
|
|
||||||
{
|
|
||||||
ExitApp();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
@ -31,7 +31,15 @@
|
|||||||
|
|
||||||
#include "snes9x.h"
|
#include "snes9x.h"
|
||||||
#include "memmap.h"
|
#include "memmap.h"
|
||||||
#include "apu/apu.h"
|
#include "s9xdebug.h"
|
||||||
|
#include "cpuexec.h"
|
||||||
|
#include "ppu.h"
|
||||||
|
#include "apu.h"
|
||||||
|
#include "display.h"
|
||||||
|
#include "gfx.h"
|
||||||
|
#include "soundux.h"
|
||||||
|
#include "spc700.h"
|
||||||
|
#include "spc7110.h"
|
||||||
#include "controls.h"
|
#include "controls.h"
|
||||||
|
|
||||||
#include "snes9xGX.h"
|
#include "snes9xGX.h"
|
||||||
@ -337,7 +345,7 @@ void USBGeckoOutput()
|
|||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
USBGeckoOutput(); // uncomment to enable USB gecko output
|
//USBGeckoOutput(); // uncomment to enable USB gecko output
|
||||||
__exception_setreload(8);
|
__exception_setreload(8);
|
||||||
|
|
||||||
#ifdef HW_DOL
|
#ifdef HW_DOL
|
||||||
@ -377,7 +385,6 @@ main(int argc, char *argv[])
|
|||||||
|
|
||||||
S9xUnmapAllControls ();
|
S9xUnmapAllControls ();
|
||||||
SetDefaultButtonMap ();
|
SetDefaultButtonMap ();
|
||||||
S9xReportControllers();
|
|
||||||
|
|
||||||
// Allocate SNES Memory
|
// Allocate SNES Memory
|
||||||
if (!Memory.Init ())
|
if (!Memory.Init ())
|
||||||
@ -390,14 +397,15 @@ main(int argc, char *argv[])
|
|||||||
// Set Pixel Renderer to match 565
|
// Set Pixel Renderer to match 565
|
||||||
S9xSetRenderPixelFormat (RGB565);
|
S9xSetRenderPixelFormat (RGB565);
|
||||||
|
|
||||||
// Initialise Sound System
|
// Initialise Snes Sound System
|
||||||
S9xInitSound (512, 0);
|
S9xInitSound (5, TRUE, 1024);
|
||||||
|
|
||||||
// Initialise Graphics
|
// Initialise Graphics
|
||||||
setGFX ();
|
setGFX ();
|
||||||
if (!S9xGraphicsInit ())
|
if (!S9xGraphicsInit ())
|
||||||
ExitApp();
|
ExitApp();
|
||||||
|
|
||||||
|
S9xSetSoundMute (TRUE);
|
||||||
S9xInitSync(); // initialize frame sync
|
S9xInitSync(); // initialize frame sync
|
||||||
|
|
||||||
// Initialize font system
|
// Initialize font system
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
#define SILENT 1
|
#define SILENT 1
|
||||||
|
|
||||||
const char pathPrefix[9][8] =
|
const char pathPrefix[9][8] =
|
||||||
{ "", "sd:/", "usb:/", "dvd:/", "smb:/", "carda:/", "cardb:/" };
|
{ "", "sd:/", "usb:/", "dvd:/", "smb:/", "mca:/", "mcb:/", "carda:/", "cardb:/" };
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
DEVICE_AUTO,
|
DEVICE_AUTO,
|
||||||
@ -36,6 +36,8 @@ enum {
|
|||||||
DEVICE_USB,
|
DEVICE_USB,
|
||||||
DEVICE_DVD,
|
DEVICE_DVD,
|
||||||
DEVICE_SMB,
|
DEVICE_SMB,
|
||||||
|
DEVICE_MC_SLOTA,
|
||||||
|
DEVICE_MC_SLOTB,
|
||||||
DEVICE_SD_SLOTA,
|
DEVICE_SD_SLOTA,
|
||||||
DEVICE_SD_SLOTB
|
DEVICE_SD_SLOTB
|
||||||
};
|
};
|
||||||
@ -77,6 +79,7 @@ struct SGCSettings{
|
|||||||
|
|
||||||
float zoomHor; // horizontal zoom amount
|
float zoomHor; // horizontal zoom amount
|
||||||
float zoomVert; // vertical zoom amount
|
float zoomVert; // vertical zoom amount
|
||||||
|
int VerifySaves;
|
||||||
int videomode; // 0 - automatic, 1 - NTSC (480i), 2 - Progressive (480p), 3 - PAL (50Hz), 4 - PAL (60Hz)
|
int videomode; // 0 - automatic, 1 - NTSC (480i), 2 - Progressive (480p), 3 - PAL (50Hz), 4 - PAL (60Hz)
|
||||||
int render; // 0 - original, 1 - filtered, 2 - unfiltered
|
int render; // 0 - original, 1 - filtered, 2 - unfiltered
|
||||||
int FilterMethod; // convert to RenderFilter
|
int FilterMethod; // convert to RenderFilter
|
||||||
@ -101,4 +104,7 @@ extern int ExitRequested;
|
|||||||
extern char appPath[];
|
extern char appPath[];
|
||||||
extern FreeTypeGX *fontSystem[];
|
extern FreeTypeGX *fontSystem[];
|
||||||
|
|
||||||
|
void WiiSetupCheats();
|
||||||
|
void WiiLoadPatch();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -54,14 +54,6 @@ LoadSRAM (char * filepath, bool silent)
|
|||||||
if (len - size == 512)
|
if (len - size == 512)
|
||||||
memmove(Memory.SRAM, Memory.SRAM + 512, size);
|
memmove(Memory.SRAM, Memory.SRAM + 512, size);
|
||||||
|
|
||||||
if (Settings.SRTC || Settings.SPC7110RTC)
|
|
||||||
{
|
|
||||||
int pathlen = strlen(filepath);
|
|
||||||
filepath[pathlen-3] = 'r';
|
|
||||||
filepath[pathlen-2] = 't';
|
|
||||||
filepath[pathlen-1] = 'c';
|
|
||||||
LoadFile((char *)RTCData.reg, filepath, 20, silent);
|
|
||||||
}
|
|
||||||
result = true;
|
result = true;
|
||||||
}
|
}
|
||||||
else if(!silent)
|
else if(!silent)
|
||||||
@ -128,15 +120,6 @@ SaveSRAM (char * filepath, bool silent)
|
|||||||
if (size > 0)
|
if (size > 0)
|
||||||
{
|
{
|
||||||
offset = SaveFile((char *)Memory.SRAM, filepath, size, silent);
|
offset = SaveFile((char *)Memory.SRAM, filepath, size, silent);
|
||||||
|
|
||||||
if (Settings.SRTC || Settings.SPC7110RTC)
|
|
||||||
{
|
|
||||||
int pathlen = strlen(filepath);
|
|
||||||
filepath[pathlen-3] = 'r';
|
|
||||||
filepath[pathlen-2] = 't';
|
|
||||||
filepath[pathlen-1] = 'c';
|
|
||||||
SaveFile((char *)RTCData.reg, filepath, 20, silent);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (offset > 0)
|
if (offset > 0)
|
||||||
{
|
{
|
||||||
|
@ -159,55 +159,67 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#include "snes9x.h"
|
|
||||||
#include "memmap.h"
|
|
||||||
#ifdef DEBUGGER
|
#ifndef _3D_H_
|
||||||
#include "missing.h"
|
#define _3D_H_
|
||||||
|
|
||||||
|
#if defined(USE_OPENGL)
|
||||||
|
#include <GL/gl.h>
|
||||||
|
#include <GL/glu.h>
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
#include <GL/glx.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint8 (*GetDSP) (uint16) = NULL;
|
typedef struct
|
||||||
void (*SetDSP) (uint8, uint16) = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
void S9xResetDSP (void)
|
|
||||||
{
|
{
|
||||||
memset(&DSP1, 0, sizeof(DSP1));
|
bool8 packed_pixels_extension_present;
|
||||||
DSP1.waiting4command = TRUE;
|
bool8 draw_cube;
|
||||||
DSP1.first_parameter = TRUE;
|
uint32 version;
|
||||||
|
// Texture format
|
||||||
|
GLint internal_format;
|
||||||
|
GLint format;
|
||||||
|
GLint type;
|
||||||
|
|
||||||
memset(&DSP2, 0, sizeof(DSP2));
|
GLint max_texture_size;// 256 or 512
|
||||||
DSP2.waiting4command = TRUE;
|
GLint texture_size;
|
||||||
|
uint32 num_textures; // 1 if max_texture_size == 256, 2 otherwise
|
||||||
|
GLuint textures [2];
|
||||||
|
bool8 initialized;
|
||||||
|
} OpenGLData;
|
||||||
|
|
||||||
memset(&DSP3, 0, sizeof(DSP3));
|
extern OpenGLData OpenGL;
|
||||||
DSP3_Reset();
|
|
||||||
|
|
||||||
memset(&DSP4, 0, sizeof(DSP4));
|
bool8 S9xOpenGLInit ();
|
||||||
DSP4.waiting4command = TRUE;
|
bool8 S9xOpenGLInit2 ();
|
||||||
}
|
void S9xOpenGLPutImage (int width, int height);
|
||||||
|
void S9xOpenGLDeinit ();
|
||||||
|
|
||||||
uint8 S9xGetDSP (uint16 address)
|
|
||||||
{
|
|
||||||
#ifdef DEBUGGER
|
|
||||||
if (Settings.TraceDSP)
|
|
||||||
{
|
|
||||||
sprintf(String, "DSP read: 0x%04X", address);
|
|
||||||
S9xMessage(S9X_TRACE, S9X_TRACE_DSP1, String);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return ((*GetDSP)(address));
|
#ifdef USE_GLIDE
|
||||||
}
|
#include <glide.h>
|
||||||
|
|
||||||
void S9xSetDSP (uint8 byte, uint16 address)
|
typedef struct
|
||||||
{
|
{
|
||||||
#ifdef DEBUGGER
|
bool8 voodoo_present;
|
||||||
missing.unknowndsp_write = address;
|
GrVertex sq[4];
|
||||||
if (Settings.TraceDSP)
|
GrTexInfo texture;
|
||||||
{
|
int32 texture_mem_size;
|
||||||
sprintf(String, "DSP write: 0x%04X=0x%02X", address, byte);
|
int32 texture_mem_start;
|
||||||
S9xMessage(S9X_TRACE, S9X_TRACE_DSP1, String);
|
float x_offset, y_offset;
|
||||||
}
|
float x_scale, y_scale;
|
||||||
|
float voodoo_width;
|
||||||
|
float voodoo_height;
|
||||||
|
} GlideData;
|
||||||
|
|
||||||
|
extern GlideData Glide;
|
||||||
|
bool8 S9xGlideEnable (bool8 enable);
|
||||||
|
void S9xGlideDeinit ();
|
||||||
|
bool8 S9xGlideInit ();
|
||||||
|
bool8 S9xVoodooInitialise ();
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
(*SetDSP)(byte, address);
|
|
||||||
}
|
|
@ -159,102 +159,104 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _65C816_H_
|
|
||||||
#define _65C816_H_
|
|
||||||
|
|
||||||
#define Carry 1
|
|
||||||
#define Zero 2
|
|
||||||
#define IRQ 4
|
|
||||||
#define Decimal 8
|
|
||||||
#define IndexFlag 16
|
|
||||||
#define MemoryFlag 32
|
|
||||||
#define Overflow 64
|
|
||||||
#define Negative 128
|
|
||||||
#define Emulation 256
|
|
||||||
|
|
||||||
#define SetCarry() (ICPU._Carry = 1)
|
#ifndef _65c816_h_
|
||||||
#define ClearCarry() (ICPU._Carry = 0)
|
#define _65c816_h_
|
||||||
#define SetZero() (ICPU._Zero = 0)
|
|
||||||
#define ClearZero() (ICPU._Zero = 1)
|
|
||||||
#define SetIRQ() (Registers.PL |= IRQ)
|
|
||||||
#define ClearIRQ() (Registers.PL &= ~IRQ)
|
|
||||||
#define SetDecimal() (Registers.PL |= Decimal)
|
|
||||||
#define ClearDecimal() (Registers.PL &= ~Decimal)
|
|
||||||
#define SetIndex() (Registers.PL |= IndexFlag)
|
|
||||||
#define ClearIndex() (Registers.PL &= ~IndexFlag)
|
|
||||||
#define SetMemory() (Registers.PL |= MemoryFlag)
|
|
||||||
#define ClearMemory() (Registers.PL &= ~MemoryFlag)
|
|
||||||
#define SetOverflow() (ICPU._Overflow = 1)
|
|
||||||
#define ClearOverflow() (ICPU._Overflow = 0)
|
|
||||||
#define SetNegative() (ICPU._Negative = 0x80)
|
|
||||||
#define ClearNegative() (ICPU._Negative = 0)
|
|
||||||
|
|
||||||
#define CheckCarry() (ICPU._Carry)
|
#define AL A.B.l
|
||||||
#define CheckZero() (ICPU._Zero == 0)
|
#define AH A.B.h
|
||||||
#define CheckIRQ() (Registers.PL & IRQ)
|
#define XL X.B.l
|
||||||
#define CheckDecimal() (Registers.PL & Decimal)
|
#define XH X.B.h
|
||||||
#define CheckIndex() (Registers.PL & IndexFlag)
|
#define YL Y.B.l
|
||||||
#define CheckMemory() (Registers.PL & MemoryFlag)
|
#define YH Y.B.h
|
||||||
#define CheckOverflow() (ICPU._Overflow)
|
#define SL S.B.l
|
||||||
#define CheckNegative() (ICPU._Negative & 0x80)
|
#define SH S.B.h
|
||||||
#define CheckEmulation() (Registers.P.W & Emulation)
|
#define DL D.B.l
|
||||||
|
#define DH D.B.h
|
||||||
|
#define PL P.B.l
|
||||||
|
#define PH P.B.h
|
||||||
|
|
||||||
#define SetFlags(f) (Registers.P.W |= (f))
|
#define Carry 1
|
||||||
#define ClearFlags(f) (Registers.P.W &= ~(f))
|
#define Zero 2
|
||||||
#define CheckFlag(f) (Registers.PL & (f))
|
#define IRQ 4
|
||||||
|
#define Decimal 8
|
||||||
|
#define IndexFlag 16
|
||||||
|
#define MemoryFlag 32
|
||||||
|
#define Overflow 64
|
||||||
|
#define Negative 128
|
||||||
|
#define Emulation 256
|
||||||
|
|
||||||
|
#define ClearCarry() (ICPU._Carry = 0)
|
||||||
|
#define SetCarry() (ICPU._Carry = 1)
|
||||||
|
#define SetZero() (ICPU._Zero = 0)
|
||||||
|
#define ClearZero() (ICPU._Zero = 1)
|
||||||
|
#define SetIRQ() (Registers.PL |= IRQ)
|
||||||
|
#define ClearIRQ() (Registers.PL &= ~IRQ)
|
||||||
|
#define SetDecimal() (Registers.PL |= Decimal)
|
||||||
|
#define ClearDecimal() (Registers.PL &= ~Decimal)
|
||||||
|
#define SetIndex() (Registers.PL |= IndexFlag)
|
||||||
|
#define ClearIndex() (Registers.PL &= ~IndexFlag)
|
||||||
|
#define SetMemory() (Registers.PL |= MemoryFlag)
|
||||||
|
#define ClearMemory() (Registers.PL &= ~MemoryFlag)
|
||||||
|
#define SetOverflow() (ICPU._Overflow = 1)
|
||||||
|
#define ClearOverflow() (ICPU._Overflow = 0)
|
||||||
|
#define SetNegative() (ICPU._Negative = 0x80)
|
||||||
|
#define ClearNegative() (ICPU._Negative = 0)
|
||||||
|
|
||||||
|
#define CheckZero() (ICPU._Zero == 0)
|
||||||
|
#define CheckCarry() (ICPU._Carry)
|
||||||
|
#define CheckIRQ() (Registers.PL & IRQ)
|
||||||
|
#define CheckDecimal() (Registers.PL & Decimal)
|
||||||
|
#define CheckIndex() (Registers.PL & IndexFlag)
|
||||||
|
#define CheckMemory() (Registers.PL & MemoryFlag)
|
||||||
|
#define CheckOverflow() (ICPU._Overflow)
|
||||||
|
#define CheckNegative() (ICPU._Negative & 0x80)
|
||||||
|
#define CheckEmulation() (Registers.P.W & Emulation)
|
||||||
|
|
||||||
|
#define ClearFlags(f) (Registers.P.W &= ~(f))
|
||||||
|
#define SetFlags(f) (Registers.P.W |= (f))
|
||||||
|
#define CheckFlag(f) (Registers.PL & (f))
|
||||||
|
|
||||||
typedef union
|
typedef union
|
||||||
{
|
{
|
||||||
#ifdef LSB_FIRST
|
#ifdef LSB_FIRST
|
||||||
struct { uint8 l, h; } B;
|
struct { uint8 l,h; } B;
|
||||||
#else
|
#else
|
||||||
struct { uint8 h, l; } B;
|
struct { uint8 h,l; } B;
|
||||||
#endif
|
#endif
|
||||||
uint16 W;
|
uint16 W;
|
||||||
} pair;
|
} pair;
|
||||||
|
|
||||||
typedef union
|
typedef union {
|
||||||
{
|
|
||||||
#ifdef LSB_FIRST
|
#ifdef LSB_FIRST
|
||||||
struct { uint8 xPCl, xPCh, xPB, z; } B;
|
struct { uint8 xPCl, xPCh, xPB, z; } B;
|
||||||
struct { uint16 xPC, d; } W;
|
struct { uint16 xPC, d; } W;
|
||||||
#else
|
#else
|
||||||
struct { uint8 z, xPB, xPCh, xPCl; } B;
|
struct { uint8 z, xPB, xPCh, xPCl; } B;
|
||||||
struct { uint16 d, xPC; } W;
|
struct { uint16 d, xPC; } W;
|
||||||
#endif
|
#endif
|
||||||
uint32 xPBPC;
|
uint32 xPBPC;
|
||||||
} PC_t;
|
} PC_t;
|
||||||
|
|
||||||
struct SRegisters
|
struct SRegisters{
|
||||||
{
|
uint8 DB;
|
||||||
uint8 DB;
|
pair P;
|
||||||
pair P;
|
pair A;
|
||||||
pair A;
|
pair D;
|
||||||
pair D;
|
pair S;
|
||||||
pair S;
|
pair X;
|
||||||
pair X;
|
pair Y;
|
||||||
pair Y;
|
PC_t PC;
|
||||||
PC_t PC;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define AL A.B.l
|
#define PBPC PC.xPBPC
|
||||||
#define AH A.B.h
|
#define PCw PC.W.xPC
|
||||||
#define XL X.B.l
|
#define PCh PC.B.xPCh
|
||||||
#define XH X.B.h
|
#define PCl PC.B.xPCl
|
||||||
#define YL Y.B.l
|
#define PB PC.B.xPB
|
||||||
#define YH Y.B.h
|
|
||||||
#define SL S.B.l
|
|
||||||
#define SH S.B.h
|
|
||||||
#define DL D.B.l
|
|
||||||
#define DH D.B.h
|
|
||||||
#define PL P.B.l
|
|
||||||
#define PH P.B.h
|
|
||||||
#define PBPC PC.xPBPC
|
|
||||||
#define PCw PC.W.xPC
|
|
||||||
#define PCh PC.B.xPCh
|
|
||||||
#define PCl PC.B.xPCl
|
|
||||||
#define PB PC.B.xPB
|
|
||||||
|
|
||||||
extern struct SRegisters Registers;
|
EXTERN_C struct SRegisters Registers;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
1054
source/snes9x/apu.cpp
Normal file
1054
source/snes9x/apu.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -159,43 +159,139 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _APU_H_
|
|
||||||
#define _APU_H_
|
|
||||||
|
|
||||||
#include "snes9x.h"
|
|
||||||
#include "SNES_SPC.h"
|
|
||||||
|
|
||||||
typedef void (*apu_callback) (void *);
|
#ifndef _apu_h_
|
||||||
|
#define _apu_h_
|
||||||
|
|
||||||
#define SPC_SAVE_STATE_BLOCK_SIZE (SNES_SPC::state_size + 8)
|
#include "spc700.h"
|
||||||
|
|
||||||
bool8 S9xInitAPU (void);
|
struct SIAPU
|
||||||
void S9xDeinitAPU (void);
|
{
|
||||||
|
uint8 *PC;
|
||||||
|
uint8 *RAM;
|
||||||
|
uint8 *DirectPage;
|
||||||
|
bool8 APUExecuting;
|
||||||
|
uint8 Bit;
|
||||||
|
uint32 Address;
|
||||||
|
uint8 *WaitAddress1;
|
||||||
|
uint8 *WaitAddress2;
|
||||||
|
uint32 WaitCounter;
|
||||||
|
uint8 *ShadowRAM; // unused
|
||||||
|
uint8 *CachedSamples; // unused
|
||||||
|
uint8 _Carry;
|
||||||
|
uint8 _Zero;
|
||||||
|
uint8 _Overflow;
|
||||||
|
uint32 TimerErrorCounter;
|
||||||
|
uint32 Scanline;
|
||||||
|
int32 OneCycle;
|
||||||
|
int32 TwoCycles;
|
||||||
|
bool8 KONNotifier;
|
||||||
|
bool8 KOFFNotifier;
|
||||||
|
bool8 OUTXNotifier;
|
||||||
|
bool8 ENVXNotifier;
|
||||||
|
bool8 ENDXNotifier;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SAPU
|
||||||
|
{
|
||||||
|
int32 OldCycles; // unused
|
||||||
|
bool8 ShowROM;
|
||||||
|
uint32 Flags;
|
||||||
|
uint8 KeyedChannels;
|
||||||
|
uint8 OutPorts [4];
|
||||||
|
uint8 DSP [0x80];
|
||||||
|
uint8 ExtraRAM [64];
|
||||||
|
uint16 Timer [3];
|
||||||
|
uint16 TimerTarget [3];
|
||||||
|
bool8 TimerEnabled [3];
|
||||||
|
bool8 TimerValueWritten [3];
|
||||||
|
int32 Cycles;
|
||||||
|
int32 NextAPUTimerPos;
|
||||||
|
int32 APUTimerCounter;
|
||||||
|
};
|
||||||
|
|
||||||
|
EXTERN_C struct SAPU APU;
|
||||||
|
EXTERN_C struct SIAPU IAPU;
|
||||||
|
extern int spc_is_dumping;
|
||||||
|
extern int spc_is_dumping_temp;
|
||||||
|
extern uint8 spc_dump_dsp[0x100];
|
||||||
|
STATIC inline void S9xAPUUnpackStatus()
|
||||||
|
{
|
||||||
|
IAPU._Zero = ((APURegisters.P & Zero) == 0) | (APURegisters.P & Negative);
|
||||||
|
IAPU._Carry = (APURegisters.P & Carry);
|
||||||
|
IAPU._Overflow = (APURegisters.P & Overflow) >> 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC inline void S9xAPUPackStatus()
|
||||||
|
{
|
||||||
|
APURegisters.P &= ~(Zero | Negative | Carry | Overflow);
|
||||||
|
APURegisters.P |= IAPU._Carry | ((IAPU._Zero == 0) << 1) |
|
||||||
|
(IAPU._Zero & 0x80) | (IAPU._Overflow << 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
START_EXTERN_C
|
||||||
void S9xResetAPU (void);
|
void S9xResetAPU (void);
|
||||||
void S9xSoftResetAPU (void);
|
bool8 S9xInitAPU ();
|
||||||
uint8 S9xAPUReadPort (int);
|
void S9xDeinitAPU ();
|
||||||
void S9xAPUWritePort (int, uint8);
|
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);
|
||||||
void S9xAPUExecute (void);
|
void S9xAPUExecute (void);
|
||||||
void S9xAPUEndScanline (void);
|
bool8 S9xInitSound (int quality, bool8 stereo, int buffer_size);
|
||||||
void S9xAPUSetReferenceTime (int32);
|
void S9xOpenCloseSoundTracingFile (bool8);
|
||||||
void S9xAPUTimingSetSpeedup (int);
|
void S9xPrintAPUState ();
|
||||||
void S9xAPULoadState (uint8 *);
|
extern int32 S9xAPUCycles [256]; // Scaled cycle lengths
|
||||||
void S9xAPUSaveState (uint8 *);
|
extern int32 S9xAPUCycleLengths [256]; // Raw data.
|
||||||
void S9xDumpSPCSnapshot (void);
|
extern void (*S9xApuOpcodes [256]) (void);
|
||||||
|
END_EXTERN_C
|
||||||
|
|
||||||
bool8 S9xInitSound (int, int);
|
|
||||||
bool8 S9xOpenSoundDevice (int);
|
|
||||||
|
|
||||||
bool8 S9xSyncSound (void);
|
#define APU_VOL_LEFT 0x00
|
||||||
int S9xGetSampleCount (void);
|
#define APU_VOL_RIGHT 0x01
|
||||||
void S9xSetSoundControl (uint8);
|
#define APU_P_LOW 0x02
|
||||||
void S9xSetSoundMute (bool8);
|
#define APU_P_HIGH 0x03
|
||||||
void S9xLandSamples (void);
|
#define APU_SRCN 0x04
|
||||||
void S9xFinalizeSamples (void);
|
#define APU_ADSR1 0x05
|
||||||
void S9xClearSamples (void);
|
#define APU_ADSR2 0x06
|
||||||
bool8 S9xMixSamples (uint8 *, int);
|
#define APU_GAIN 0x07
|
||||||
void S9xSetSamplesAvailableCallback (apu_callback, void *);
|
#define APU_ENVX 0x08
|
||||||
|
#define APU_OUTX 0x09
|
||||||
|
|
||||||
extern SNES_SPC *spc_core;
|
#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
|
#endif
|
||||||
|
|
@ -1,564 +0,0 @@
|
|||||||
// Core SPC emulation: CPU, timers, SMP registers, memory
|
|
||||||
|
|
||||||
// snes_spc 0.9.0. http://www.slack.net/~ant/
|
|
||||||
|
|
||||||
#include "SNES_SPC.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
/* Copyright (C) 2004-2007 Shay Green. This module is free software; you
|
|
||||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
|
||||||
General Public License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version. This
|
|
||||||
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
||||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
|
||||||
details. You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this module; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
|
||||||
|
|
||||||
#include "blargg_source.h"
|
|
||||||
|
|
||||||
#define RAM (m.ram.ram)
|
|
||||||
#define REGS (m.smp_regs [0])
|
|
||||||
#define REGS_IN (m.smp_regs [1])
|
|
||||||
|
|
||||||
// (n ? n : 256)
|
|
||||||
#define IF_0_THEN_256( n ) ((uint8_t) ((n) - 1) + 1)
|
|
||||||
|
|
||||||
// Note: SPC_MORE_ACCURACY exists mainly so I can run my validation tests, which
|
|
||||||
// do crazy echo buffer accesses.
|
|
||||||
#ifndef SPC_MORE_ACCURACY
|
|
||||||
#define SPC_MORE_ACCURACY 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef BLARGG_ENABLE_OPTIMIZER
|
|
||||||
#include BLARGG_ENABLE_OPTIMIZER
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
//// Timers
|
|
||||||
|
|
||||||
#if SPC_DISABLE_TEMPO
|
|
||||||
#define TIMER_DIV( t, n ) ((n) >> t->prescaler)
|
|
||||||
#define TIMER_MUL( t, n ) ((n) << t->prescaler)
|
|
||||||
#else
|
|
||||||
#define TIMER_DIV( t, n ) ((n) / t->prescaler)
|
|
||||||
#define TIMER_MUL( t, n ) ((n) * t->prescaler)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SNES_SPC::Timer* SNES_SPC::run_timer_( Timer* t, rel_time_t time )
|
|
||||||
{
|
|
||||||
int elapsed = TIMER_DIV( t, time - t->next_time ) + 1;
|
|
||||||
t->next_time += TIMER_MUL( t, elapsed );
|
|
||||||
|
|
||||||
if ( t->enabled )
|
|
||||||
{
|
|
||||||
int remain = IF_0_THEN_256( t->period - t->divider );
|
|
||||||
int divider = t->divider + elapsed;
|
|
||||||
int over = elapsed - remain;
|
|
||||||
if ( over >= 0 )
|
|
||||||
{
|
|
||||||
int n = over / t->period;
|
|
||||||
t->counter = (t->counter + 1 + n) & 0x0F;
|
|
||||||
divider = over - n * t->period;
|
|
||||||
}
|
|
||||||
t->divider = (uint8_t) divider;
|
|
||||||
}
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline SNES_SPC::Timer* SNES_SPC::run_timer( Timer* t, rel_time_t time )
|
|
||||||
{
|
|
||||||
if ( time >= t->next_time )
|
|
||||||
t = run_timer_( t, time );
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//// ROM
|
|
||||||
|
|
||||||
void SNES_SPC::enable_rom( int enable )
|
|
||||||
{
|
|
||||||
if ( m.rom_enabled != enable )
|
|
||||||
{
|
|
||||||
m.rom_enabled = enable;
|
|
||||||
if ( enable )
|
|
||||||
memcpy( m.hi_ram, &RAM [rom_addr], sizeof m.hi_ram );
|
|
||||||
memcpy( &RAM [rom_addr], (enable ? m.rom : m.hi_ram), rom_size );
|
|
||||||
// TODO: ROM can still get overwritten when DSP writes to echo buffer
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//// DSP
|
|
||||||
|
|
||||||
#if SPC_LESS_ACCURATE
|
|
||||||
int const max_reg_time = 29;
|
|
||||||
|
|
||||||
signed char const SNES_SPC::reg_times_ [256] =
|
|
||||||
{
|
|
||||||
-1, 0,-11,-10,-15,-11, -2, -2, 4, 3, 14, 14, 26, 26, 14, 22,
|
|
||||||
2, 3, 0, 1,-12, 0, 1, 1, 7, 6, 14, 14, 27, 14, 14, 23,
|
|
||||||
5, 6, 3, 4, -1, 3, 4, 4, 10, 9, 14, 14, 26, -5, 14, 23,
|
|
||||||
8, 9, 6, 7, 2, 6, 7, 7, 13, 12, 14, 14, 27, -4, 14, 24,
|
|
||||||
11, 12, 9, 10, 5, 9, 10, 10, 16, 15, 14, 14, -2, -4, 14, 24,
|
|
||||||
14, 15, 12, 13, 8, 12, 13, 13, 19, 18, 14, 14, -2,-36, 14, 24,
|
|
||||||
17, 18, 15, 16, 11, 15, 16, 16, 22, 21, 14, 14, 28, -3, 14, 25,
|
|
||||||
20, 21, 18, 19, 14, 18, 19, 19, 25, 24, 14, 14, 14, 29, 14, 25,
|
|
||||||
|
|
||||||
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
|
|
||||||
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
|
|
||||||
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
|
|
||||||
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
|
|
||||||
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
|
|
||||||
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
|
|
||||||
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
|
|
||||||
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
|
|
||||||
};
|
|
||||||
|
|
||||||
#define RUN_DSP( time, offset ) \
|
|
||||||
int count = (time) - (offset) - m.dsp_time;\
|
|
||||||
if ( count >= 0 )\
|
|
||||||
{\
|
|
||||||
int clock_count = (count & ~(clocks_per_sample - 1)) + clocks_per_sample;\
|
|
||||||
m.dsp_time += clock_count;\
|
|
||||||
dsp.run( clock_count );\
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#define RUN_DSP( time, offset ) \
|
|
||||||
{\
|
|
||||||
int count = (time) - m.dsp_time;\
|
|
||||||
if ( !SPC_MORE_ACCURACY || count )\
|
|
||||||
{\
|
|
||||||
assert( count > 0 );\
|
|
||||||
m.dsp_time = (time);\
|
|
||||||
dsp.run( count );\
|
|
||||||
}\
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int SNES_SPC::dsp_read( rel_time_t time )
|
|
||||||
{
|
|
||||||
RUN_DSP( time, reg_times [REGS [r_dspaddr] & 0x7F] );
|
|
||||||
|
|
||||||
int result = dsp.read( REGS [r_dspaddr] & 0x7F );
|
|
||||||
|
|
||||||
#ifdef SPC_DSP_READ_HOOK
|
|
||||||
SPC_DSP_READ_HOOK( spc_time + time, (REGS [r_dspaddr] & 0x7F), result );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void SNES_SPC::dsp_write( int data, rel_time_t time )
|
|
||||||
{
|
|
||||||
RUN_DSP( time, reg_times [REGS [r_dspaddr]] )
|
|
||||||
#if SPC_LESS_ACCURATE
|
|
||||||
else if ( m.dsp_time == skipping_time )
|
|
||||||
{
|
|
||||||
int r = REGS [r_dspaddr];
|
|
||||||
if ( r == SPC_DSP::r_kon )
|
|
||||||
m.skipped_kon |= data & ~dsp.read( SPC_DSP::r_koff );
|
|
||||||
|
|
||||||
if ( r == SPC_DSP::r_koff )
|
|
||||||
{
|
|
||||||
m.skipped_koff |= data;
|
|
||||||
m.skipped_kon &= ~data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SPC_DSP_WRITE_HOOK
|
|
||||||
SPC_DSP_WRITE_HOOK( m.spc_time + time, REGS [r_dspaddr], (uint8_t) data );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if ( REGS [r_dspaddr] <= 0x7F )
|
|
||||||
dsp.write( REGS [r_dspaddr], data );
|
|
||||||
else if ( !SPC_MORE_ACCURACY )
|
|
||||||
dprintf( "SPC wrote to DSP register > $7F\n" );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//// Memory access extras
|
|
||||||
|
|
||||||
#if SPC_MORE_ACCURACY
|
|
||||||
#define MEM_ACCESS( time, addr ) \
|
|
||||||
{\
|
|
||||||
if ( time >= m.dsp_time )\
|
|
||||||
{\
|
|
||||||
RUN_DSP( time, max_reg_time );\
|
|
||||||
}\
|
|
||||||
}
|
|
||||||
#elif !defined (NDEBUG)
|
|
||||||
// Debug-only check for read/write within echo buffer, since this might result in
|
|
||||||
// inaccurate emulation due to the DSP not being caught up to the present.
|
|
||||||
|
|
||||||
bool SNES_SPC::check_echo_access( int addr )
|
|
||||||
{
|
|
||||||
if ( !(dsp.read( SPC_DSP::r_flg ) & 0x20) )
|
|
||||||
{
|
|
||||||
int start = 0x100 * dsp.read( SPC_DSP::r_esa );
|
|
||||||
int size = 0x800 * (dsp.read( SPC_DSP::r_edl ) & 0x0F);
|
|
||||||
int end = start + (size ? size : 4);
|
|
||||||
if ( start <= addr && addr < end )
|
|
||||||
{
|
|
||||||
if ( !m.echo_accessed )
|
|
||||||
{
|
|
||||||
m.echo_accessed = 1;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define MEM_ACCESS( time, addr ) check( !check_echo_access( (uint16_t) addr ) );
|
|
||||||
#else
|
|
||||||
#define MEM_ACCESS( time, addr )
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
//// CPU write
|
|
||||||
|
|
||||||
#if SPC_MORE_ACCURACY
|
|
||||||
static unsigned char const glitch_probs [3] [256] =
|
|
||||||
{
|
|
||||||
0xC3,0x92,0x5B,0x1C,0xD1,0x92,0x5B,0x1C,0xDB,0x9C,0x72,0x18,0xCD,0x5C,0x38,0x0B,
|
|
||||||
0xE1,0x9C,0x74,0x17,0xCF,0x75,0x45,0x0C,0xCF,0x6E,0x4A,0x0D,0xA3,0x3A,0x1D,0x08,
|
|
||||||
0xDB,0xA0,0x82,0x19,0xD9,0x73,0x3C,0x0E,0xCB,0x76,0x52,0x0B,0xA5,0x46,0x1D,0x09,
|
|
||||||
0xDA,0x74,0x55,0x0F,0xA2,0x3F,0x21,0x05,0x9A,0x40,0x20,0x07,0x63,0x1E,0x10,0x01,
|
|
||||||
0xDF,0xA9,0x85,0x1D,0xD3,0x84,0x4B,0x0E,0xCF,0x6F,0x49,0x0F,0xB3,0x48,0x1E,0x05,
|
|
||||||
0xD8,0x77,0x52,0x12,0xB7,0x49,0x23,0x06,0xAA,0x45,0x28,0x07,0x7D,0x28,0x0F,0x07,
|
|
||||||
0xCC,0x7B,0x4A,0x0E,0xB2,0x4F,0x24,0x07,0xAD,0x43,0x2C,0x06,0x86,0x29,0x11,0x07,
|
|
||||||
0xAE,0x48,0x1F,0x0A,0x76,0x21,0x19,0x05,0x76,0x21,0x14,0x05,0x44,0x11,0x0B,0x01,
|
|
||||||
0xE7,0xAD,0x96,0x23,0xDC,0x86,0x59,0x0E,0xDC,0x7C,0x5F,0x15,0xBB,0x53,0x2E,0x09,
|
|
||||||
0xD6,0x7C,0x4A,0x16,0xBB,0x4A,0x25,0x08,0xB3,0x4F,0x28,0x0B,0x8E,0x23,0x15,0x08,
|
|
||||||
0xCF,0x7F,0x57,0x11,0xB5,0x4A,0x23,0x0A,0xAA,0x42,0x28,0x05,0x7D,0x22,0x12,0x03,
|
|
||||||
0xA6,0x49,0x28,0x09,0x82,0x2B,0x0D,0x04,0x7A,0x20,0x0F,0x04,0x3D,0x0F,0x09,0x03,
|
|
||||||
0xD1,0x7C,0x4C,0x0F,0xAF,0x4E,0x21,0x09,0xA8,0x46,0x2A,0x07,0x85,0x1F,0x0E,0x07,
|
|
||||||
0xA6,0x3F,0x26,0x07,0x7C,0x24,0x14,0x07,0x78,0x22,0x16,0x04,0x46,0x12,0x0A,0x02,
|
|
||||||
0xA6,0x41,0x2C,0x0A,0x7E,0x28,0x11,0x05,0x73,0x1B,0x14,0x05,0x3D,0x11,0x0A,0x02,
|
|
||||||
0x70,0x22,0x17,0x05,0x48,0x13,0x08,0x03,0x3C,0x07,0x0D,0x07,0x26,0x07,0x06,0x01,
|
|
||||||
|
|
||||||
0xE0,0x9F,0xDA,0x7C,0x4F,0x18,0x28,0x0D,0xE9,0x9F,0xDA,0x7C,0x4F,0x18,0x1F,0x07,
|
|
||||||
0xE6,0x97,0xD8,0x72,0x64,0x13,0x26,0x09,0xDC,0x67,0xA9,0x38,0x21,0x07,0x15,0x06,
|
|
||||||
0xE9,0x91,0xD2,0x6B,0x63,0x14,0x2B,0x0E,0xD6,0x61,0xB7,0x41,0x2B,0x0E,0x10,0x09,
|
|
||||||
0xCF,0x59,0xB0,0x2F,0x35,0x08,0x0F,0x07,0xB6,0x30,0x7A,0x21,0x17,0x07,0x09,0x03,
|
|
||||||
0xE7,0xA3,0xE5,0x6B,0x65,0x1F,0x34,0x09,0xD8,0x6B,0xBE,0x45,0x27,0x07,0x10,0x07,
|
|
||||||
0xDA,0x54,0xB1,0x39,0x2E,0x0E,0x17,0x08,0xA9,0x3C,0x86,0x22,0x16,0x06,0x07,0x03,
|
|
||||||
0xD4,0x51,0xBC,0x3D,0x38,0x0A,0x13,0x06,0xB2,0x37,0x79,0x1C,0x17,0x05,0x0E,0x06,
|
|
||||||
0xA7,0x31,0x74,0x1C,0x11,0x06,0x0C,0x02,0x6D,0x1A,0x38,0x10,0x0B,0x05,0x06,0x03,
|
|
||||||
0xEB,0x9A,0xE1,0x7A,0x6F,0x13,0x34,0x0E,0xE6,0x75,0xC5,0x45,0x3E,0x0B,0x1A,0x05,
|
|
||||||
0xD8,0x63,0xC1,0x40,0x3C,0x1B,0x19,0x06,0xB3,0x42,0x83,0x29,0x18,0x0A,0x08,0x04,
|
|
||||||
0xD4,0x58,0xBA,0x43,0x3F,0x0A,0x1F,0x09,0xB1,0x33,0x8A,0x1F,0x1F,0x06,0x0D,0x05,
|
|
||||||
0xAF,0x3C,0x7A,0x1F,0x16,0x08,0x0A,0x01,0x72,0x1B,0x52,0x0D,0x0B,0x09,0x06,0x01,
|
|
||||||
0xCF,0x63,0xB7,0x47,0x40,0x10,0x14,0x06,0xC0,0x41,0x96,0x20,0x1C,0x09,0x10,0x05,
|
|
||||||
0xA6,0x35,0x82,0x1A,0x20,0x0C,0x0E,0x04,0x80,0x1F,0x53,0x0F,0x0B,0x02,0x06,0x01,
|
|
||||||
0xA6,0x31,0x81,0x1B,0x1D,0x01,0x08,0x08,0x7B,0x20,0x4D,0x19,0x0E,0x05,0x07,0x03,
|
|
||||||
0x6B,0x17,0x49,0x07,0x0E,0x03,0x0A,0x05,0x37,0x0B,0x1F,0x06,0x04,0x02,0x07,0x01,
|
|
||||||
|
|
||||||
0xF0,0xD6,0xED,0xAD,0xEC,0xB1,0xEB,0x79,0xAC,0x22,0x47,0x1E,0x6E,0x1B,0x32,0x0A,
|
|
||||||
0xF0,0xD6,0xEA,0xA4,0xED,0xC4,0xDE,0x82,0x98,0x1F,0x50,0x13,0x52,0x15,0x2A,0x0A,
|
|
||||||
0xF1,0xD1,0xEB,0xA2,0xEB,0xB7,0xD8,0x69,0xA2,0x1F,0x5B,0x18,0x55,0x18,0x2C,0x0A,
|
|
||||||
0xED,0xB5,0xDE,0x7E,0xE6,0x85,0xD3,0x59,0x59,0x0F,0x2C,0x09,0x24,0x07,0x15,0x09,
|
|
||||||
0xF1,0xD6,0xEA,0xA0,0xEC,0xBB,0xDA,0x77,0xA9,0x23,0x58,0x14,0x5D,0x12,0x2F,0x09,
|
|
||||||
0xF1,0xC1,0xE3,0x86,0xE4,0x87,0xD2,0x4E,0x68,0x15,0x26,0x0B,0x27,0x09,0x15,0x02,
|
|
||||||
0xEE,0xA6,0xE0,0x5C,0xE0,0x77,0xC3,0x41,0x67,0x1B,0x3C,0x07,0x2A,0x06,0x19,0x07,
|
|
||||||
0xE4,0x75,0xC6,0x43,0xCC,0x50,0x95,0x23,0x35,0x09,0x14,0x04,0x15,0x05,0x0B,0x04,
|
|
||||||
0xEE,0xD6,0xED,0xAD,0xEC,0xB1,0xEB,0x79,0xAC,0x22,0x56,0x14,0x5A,0x12,0x26,0x0A,
|
|
||||||
0xEE,0xBB,0xE7,0x7E,0xE9,0x8D,0xCB,0x49,0x67,0x11,0x34,0x07,0x2B,0x0B,0x14,0x07,
|
|
||||||
0xED,0xA7,0xE5,0x76,0xE3,0x7E,0xC4,0x4B,0x77,0x14,0x34,0x08,0x27,0x07,0x14,0x04,
|
|
||||||
0xE7,0x8B,0xD2,0x4C,0xCA,0x56,0x9E,0x31,0x36,0x0C,0x11,0x07,0x14,0x04,0x0A,0x02,
|
|
||||||
0xF0,0x9B,0xEA,0x6F,0xE5,0x81,0xC4,0x43,0x74,0x10,0x30,0x0B,0x2D,0x08,0x1B,0x06,
|
|
||||||
0xE6,0x83,0xCA,0x48,0xD9,0x56,0xA7,0x23,0x3B,0x09,0x12,0x09,0x15,0x07,0x0A,0x03,
|
|
||||||
0xE5,0x5F,0xCB,0x3C,0xCF,0x48,0x91,0x22,0x31,0x0A,0x17,0x08,0x15,0x04,0x0D,0x02,
|
|
||||||
0xD1,0x43,0x91,0x20,0xA9,0x2D,0x54,0x12,0x17,0x07,0x09,0x02,0x0C,0x04,0x05,0x03,
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// divided into multiple functions to keep rarely-used functionality separate
|
|
||||||
// so often-used functionality can be optimized better by compiler
|
|
||||||
|
|
||||||
// If write isn't preceded by read, data has this added to it
|
|
||||||
int const no_read_before_write = 0x2000;
|
|
||||||
|
|
||||||
void SNES_SPC::cpu_write_smp_reg_( int data, rel_time_t time, int addr )
|
|
||||||
{
|
|
||||||
switch ( addr )
|
|
||||||
{
|
|
||||||
case r_t0target:
|
|
||||||
case r_t1target:
|
|
||||||
case r_t2target: {
|
|
||||||
Timer* t = &m.timers [addr - r_t0target];
|
|
||||||
int period = IF_0_THEN_256( data );
|
|
||||||
if ( t->period != period )
|
|
||||||
{
|
|
||||||
t = run_timer( t, time );
|
|
||||||
#if SPC_MORE_ACCURACY
|
|
||||||
// Insane behavior when target is written just after counter is
|
|
||||||
// clocked and counter matches new period and new period isn't 1, 2, 4, or 8
|
|
||||||
if ( t->divider == (period & 0xFF) &&
|
|
||||||
t->next_time == time + TIMER_MUL( t, 1 ) &&
|
|
||||||
((period - 1) | ~0x0F) & period )
|
|
||||||
{
|
|
||||||
//dprintf( "SPC pathological timer target write\n" );
|
|
||||||
|
|
||||||
// If the period is 3, 5, or 9, there's a probability this behavior won't occur,
|
|
||||||
// based on the previous period
|
|
||||||
int prob = 0xFF;
|
|
||||||
int old_period = t->period & 0xFF;
|
|
||||||
if ( period == 3 ) prob = glitch_probs [0] [old_period];
|
|
||||||
if ( period == 5 ) prob = glitch_probs [1] [old_period];
|
|
||||||
if ( period == 9 ) prob = glitch_probs [2] [old_period];
|
|
||||||
|
|
||||||
// The glitch suppresses incrementing of one of the counter bits, based on
|
|
||||||
// the lowest set bit in the new period
|
|
||||||
int b = 1;
|
|
||||||
while ( !(period & b) )
|
|
||||||
b <<= 1;
|
|
||||||
|
|
||||||
if ( (rand() >> 4 & 0xFF) <= prob )
|
|
||||||
t->divider = (t->divider - b) & 0xFF;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
t->period = period;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case r_t0out:
|
|
||||||
case r_t1out:
|
|
||||||
case r_t2out:
|
|
||||||
if ( !SPC_MORE_ACCURACY )
|
|
||||||
dprintf( "SPC wrote to counter %d\n", (int) addr - r_t0out );
|
|
||||||
|
|
||||||
if ( data < no_read_before_write / 2 )
|
|
||||||
run_timer( &m.timers [addr - r_t0out], time - 1 )->counter = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Registers that act like RAM
|
|
||||||
case 0x8:
|
|
||||||
case 0x9:
|
|
||||||
REGS_IN [addr] = (uint8_t) data;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case r_test:
|
|
||||||
if ( (uint8_t) data != 0x0A )
|
|
||||||
dprintf( "SPC wrote to test register\n" );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case r_control:
|
|
||||||
// port clears
|
|
||||||
if ( data & 0x10 )
|
|
||||||
{
|
|
||||||
REGS_IN [r_cpuio0] = 0;
|
|
||||||
REGS_IN [r_cpuio1] = 0;
|
|
||||||
}
|
|
||||||
if ( data & 0x20 )
|
|
||||||
{
|
|
||||||
REGS_IN [r_cpuio2] = 0;
|
|
||||||
REGS_IN [r_cpuio3] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// timers
|
|
||||||
{
|
|
||||||
for ( int i = 0; i < timer_count; i++ )
|
|
||||||
{
|
|
||||||
Timer* t = &m.timers [i];
|
|
||||||
int enabled = data >> i & 1;
|
|
||||||
if ( t->enabled != enabled )
|
|
||||||
{
|
|
||||||
t = run_timer( t, time );
|
|
||||||
t->enabled = enabled;
|
|
||||||
if ( enabled )
|
|
||||||
{
|
|
||||||
t->divider = 0;
|
|
||||||
t->counter = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
enable_rom( data & 0x80 );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SNES_SPC::cpu_write_smp_reg( int data, rel_time_t time, int addr )
|
|
||||||
{
|
|
||||||
if ( addr == r_dspdata ) // 99%
|
|
||||||
dsp_write( data, time );
|
|
||||||
else
|
|
||||||
cpu_write_smp_reg_( data, time, addr );
|
|
||||||
}
|
|
||||||
|
|
||||||
void SNES_SPC::cpu_write_high( int data, int i, rel_time_t time )
|
|
||||||
{
|
|
||||||
if ( i < rom_size )
|
|
||||||
{
|
|
||||||
m.hi_ram [i] = (uint8_t) data;
|
|
||||||
if ( m.rom_enabled )
|
|
||||||
RAM [i + rom_addr] = m.rom [i]; // restore overwritten ROM
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
assert( RAM [i + rom_addr] == (uint8_t) data );
|
|
||||||
RAM [i + rom_addr] = cpu_pad_fill; // restore overwritten padding
|
|
||||||
cpu_write( data, i + rom_addr - 0x10000, time );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int const bits_in_int = CHAR_BIT * sizeof (int);
|
|
||||||
|
|
||||||
void SNES_SPC::cpu_write( int data, int addr, rel_time_t time )
|
|
||||||
{
|
|
||||||
MEM_ACCESS( time, addr )
|
|
||||||
|
|
||||||
// RAM
|
|
||||||
RAM [addr] = (uint8_t) data;
|
|
||||||
int reg = addr - 0xF0;
|
|
||||||
if ( reg >= 0 ) // 64%
|
|
||||||
{
|
|
||||||
// $F0-$FF
|
|
||||||
if ( reg < reg_count ) // 87%
|
|
||||||
{
|
|
||||||
REGS [reg] = (uint8_t) data;
|
|
||||||
|
|
||||||
// Ports
|
|
||||||
#ifdef SPC_PORT_WRITE_HOOK
|
|
||||||
if ( (unsigned) (reg - r_cpuio0) < port_count )
|
|
||||||
SPC_PORT_WRITE_HOOK( m.spc_time + time, (reg - r_cpuio0),
|
|
||||||
(uint8_t) data, ®S [r_cpuio0] );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Registers other than $F2 and $F4-$F7
|
|
||||||
//if ( reg != 2 && reg != 4 && reg != 5 && reg != 6 && reg != 7 )
|
|
||||||
// TODO: this is a bit on the fragile side
|
|
||||||
if ( ((~0x2F00 << (bits_in_int - 16)) << reg) < 0 ) // 36%
|
|
||||||
cpu_write_smp_reg( data, time, reg );
|
|
||||||
}
|
|
||||||
// High mem/address wrap-around
|
|
||||||
else
|
|
||||||
{
|
|
||||||
reg -= rom_addr - 0xF0;
|
|
||||||
if ( reg >= 0 ) // 1% in IPL ROM area or address wrapped around
|
|
||||||
cpu_write_high( data, reg, time );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//// CPU read
|
|
||||||
|
|
||||||
inline int SNES_SPC::cpu_read_smp_reg( int reg, rel_time_t time )
|
|
||||||
{
|
|
||||||
int result = REGS_IN [reg];
|
|
||||||
reg -= r_dspaddr;
|
|
||||||
// DSP addr and data
|
|
||||||
if ( (unsigned) reg <= 1 ) // 4% 0xF2 and 0xF3
|
|
||||||
{
|
|
||||||
result = REGS [r_dspaddr];
|
|
||||||
if ( (unsigned) reg == 1 )
|
|
||||||
result = dsp_read( time ); // 0xF3
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SNES_SPC::cpu_read( int addr, rel_time_t time )
|
|
||||||
{
|
|
||||||
MEM_ACCESS( time, addr )
|
|
||||||
|
|
||||||
// RAM
|
|
||||||
int result = RAM [addr];
|
|
||||||
int reg = addr - 0xF0;
|
|
||||||
if ( reg >= 0 ) // 40%
|
|
||||||
{
|
|
||||||
reg -= 0x10;
|
|
||||||
if ( (unsigned) reg >= 0xFF00 ) // 21%
|
|
||||||
{
|
|
||||||
reg += 0x10 - r_t0out;
|
|
||||||
|
|
||||||
// Timers
|
|
||||||
if ( (unsigned) reg < timer_count ) // 90%
|
|
||||||
{
|
|
||||||
Timer* t = &m.timers [reg];
|
|
||||||
if ( time >= t->next_time )
|
|
||||||
t = run_timer_( t, time );
|
|
||||||
result = t->counter;
|
|
||||||
t->counter = 0;
|
|
||||||
}
|
|
||||||
// Other registers
|
|
||||||
else if ( reg < 0 ) // 10%
|
|
||||||
{
|
|
||||||
result = cpu_read_smp_reg( reg + r_t0out, time );
|
|
||||||
}
|
|
||||||
else // 1%
|
|
||||||
{
|
|
||||||
assert( reg + (r_t0out + 0xF0 - 0x10000) < 0x100 );
|
|
||||||
result = cpu_read( reg + (r_t0out + 0xF0 - 0x10000), time );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//// Run
|
|
||||||
|
|
||||||
// Prefix and suffix for CPU emulator function
|
|
||||||
#define SPC_CPU_RUN_FUNC \
|
|
||||||
BOOST::uint8_t* SNES_SPC::run_until_( time_t end_time )\
|
|
||||||
{\
|
|
||||||
rel_time_t rel_time = m.spc_time - end_time;\
|
|
||||||
assert( rel_time <= 0 );\
|
|
||||||
m.spc_time = end_time;\
|
|
||||||
m.dsp_time += rel_time;\
|
|
||||||
m.timers [0].next_time += rel_time;\
|
|
||||||
m.timers [1].next_time += rel_time;\
|
|
||||||
m.timers [2].next_time += rel_time;
|
|
||||||
|
|
||||||
#define SPC_CPU_RUN_FUNC_END \
|
|
||||||
m.spc_time += rel_time;\
|
|
||||||
m.dsp_time -= rel_time;\
|
|
||||||
m.timers [0].next_time -= rel_time;\
|
|
||||||
m.timers [1].next_time -= rel_time;\
|
|
||||||
m.timers [2].next_time -= rel_time;\
|
|
||||||
assert( m.spc_time <= end_time );\
|
|
||||||
return ®S [r_cpuio0];\
|
|
||||||
}
|
|
||||||
|
|
||||||
int const cpu_lag_max = 12 - 1; // DIV YA,X takes 12 clocks
|
|
||||||
|
|
||||||
void SNES_SPC::end_frame( time_t end_time )
|
|
||||||
{
|
|
||||||
// Catch CPU up to as close to end as possible. If final instruction
|
|
||||||
// would exceed end, does NOT execute it and leaves m.spc_time < end.
|
|
||||||
if ( end_time > m.spc_time )
|
|
||||||
run_until_( end_time );
|
|
||||||
|
|
||||||
m.spc_time -= end_time;
|
|
||||||
m.extra_clocks += end_time;
|
|
||||||
|
|
||||||
// Greatest number of clocks early that emulation can stop early due to
|
|
||||||
// not being able to execute current instruction without going over
|
|
||||||
// allowed time.
|
|
||||||
assert( -cpu_lag_max <= m.spc_time && m.spc_time <= 0 );
|
|
||||||
|
|
||||||
// Catch timers up to CPU
|
|
||||||
for ( int i = 0; i < timer_count; i++ )
|
|
||||||
run_timer( &m.timers [i], 0 );
|
|
||||||
|
|
||||||
// Catch DSP up to CPU
|
|
||||||
if ( m.dsp_time < 0 )
|
|
||||||
{
|
|
||||||
RUN_DSP( 0, max_reg_time );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save any extra samples beyond what should be generated
|
|
||||||
if ( m.buf_begin )
|
|
||||||
save_extra();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inclusion here allows static memory access functions and better optimization
|
|
||||||
#include "SPC_CPU.h"
|
|
@ -1,287 +0,0 @@
|
|||||||
// SNES SPC-700 APU emulator
|
|
||||||
|
|
||||||
// snes_spc 0.9.0
|
|
||||||
#ifndef SNES_SPC_H
|
|
||||||
#define SNES_SPC_H
|
|
||||||
|
|
||||||
#include "SPC_DSP.h"
|
|
||||||
#include "blargg_endian.h"
|
|
||||||
|
|
||||||
struct SNES_SPC {
|
|
||||||
public:
|
|
||||||
typedef BOOST::uint8_t uint8_t;
|
|
||||||
|
|
||||||
// Must be called once before using
|
|
||||||
blargg_err_t init();
|
|
||||||
|
|
||||||
// Sample pairs generated per second
|
|
||||||
enum { sample_rate = 32000 };
|
|
||||||
|
|
||||||
// Emulator use
|
|
||||||
|
|
||||||
// Sets IPL ROM data. Library does not include ROM data. Most SPC music files
|
|
||||||
// don't need ROM, but a full emulator must provide this.
|
|
||||||
enum { rom_size = 0x40 };
|
|
||||||
void init_rom( uint8_t const rom [rom_size] );
|
|
||||||
|
|
||||||
// Sets destination for output samples
|
|
||||||
typedef short sample_t;
|
|
||||||
void set_output( sample_t* out, int out_size );
|
|
||||||
|
|
||||||
// Number of samples written to output since last set
|
|
||||||
int sample_count() const;
|
|
||||||
|
|
||||||
// Resets SPC to power-on state. This resets your output buffer, so you must
|
|
||||||
// call set_output() after this.
|
|
||||||
void reset();
|
|
||||||
|
|
||||||
// Emulates pressing reset switch on SNES. This resets your output buffer, so
|
|
||||||
// you must call set_output() after this.
|
|
||||||
void soft_reset();
|
|
||||||
|
|
||||||
// 1024000 SPC clocks per second, sample pair every 32 clocks
|
|
||||||
typedef int time_t;
|
|
||||||
enum { clock_rate = 1024000 };
|
|
||||||
enum { clocks_per_sample = 32 };
|
|
||||||
|
|
||||||
// Emulated port read/write at specified time
|
|
||||||
enum { port_count = 4 };
|
|
||||||
int read_port ( time_t, int port );
|
|
||||||
void write_port( time_t, int port, int data );
|
|
||||||
|
|
||||||
// Runs SPC to end_time and starts a new time frame at 0
|
|
||||||
void end_frame( time_t end_time );
|
|
||||||
|
|
||||||
// Sound control
|
|
||||||
|
|
||||||
// Mutes voices corresponding to non-zero bits in mask (issues repeated KOFF events).
|
|
||||||
// Reduces emulation accuracy.
|
|
||||||
enum { voice_count = 8 };
|
|
||||||
void mute_voices( int mask );
|
|
||||||
|
|
||||||
// If true, prevents channels and global volumes from being phase-negated.
|
|
||||||
// Only supported by fast DSP.
|
|
||||||
void disable_surround( bool disable = true );
|
|
||||||
|
|
||||||
// Sets tempo, where tempo_unit = normal, tempo_unit / 2 = half speed, etc.
|
|
||||||
enum { tempo_unit = 0x100 };
|
|
||||||
void set_tempo( int );
|
|
||||||
|
|
||||||
// SPC music files
|
|
||||||
|
|
||||||
// Loads SPC data into emulator
|
|
||||||
enum { spc_min_file_size = 0x10180 };
|
|
||||||
enum { spc_file_size = 0x10200 };
|
|
||||||
blargg_err_t load_spc( void const* in, long size );
|
|
||||||
|
|
||||||
// Clears echo region. Useful after loading an SPC as many have garbage in echo.
|
|
||||||
void clear_echo();
|
|
||||||
|
|
||||||
// Plays for count samples and write samples to out. Discards samples if out
|
|
||||||
// is NULL. Count must be a multiple of 2 since output is stereo.
|
|
||||||
blargg_err_t play( int count, sample_t* out );
|
|
||||||
|
|
||||||
// Skips count samples. Several times faster than play() when using fast DSP.
|
|
||||||
blargg_err_t skip( int count );
|
|
||||||
|
|
||||||
// State save/load (only available with accurate DSP)
|
|
||||||
|
|
||||||
#if !SPC_NO_COPY_STATE_FUNCS
|
|
||||||
// Saves/loads state
|
|
||||||
enum { state_size = 68 * 1024L }; // maximum space needed when saving
|
|
||||||
typedef SPC_DSP::copy_func_t copy_func_t;
|
|
||||||
void copy_state( unsigned char** io, copy_func_t );
|
|
||||||
|
|
||||||
// Writes minimal header to spc_out
|
|
||||||
static void init_header( void* spc_out );
|
|
||||||
|
|
||||||
// Saves emulator state as SPC file data. Writes spc_file_size bytes to spc_out.
|
|
||||||
// Does not set up SPC header; use init_header() for that.
|
|
||||||
void save_spc( void* spc_out );
|
|
||||||
|
|
||||||
// Returns true if new key-on events occurred since last check. Useful for
|
|
||||||
// trimming silence while saving an SPC.
|
|
||||||
bool check_kon();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//// Snes9x Accessor
|
|
||||||
|
|
||||||
void dsp_set_spc_snapshot_callback( void (*callback) (void) );
|
|
||||||
void dsp_dump_spc_snapshot( void );
|
|
||||||
void dsp_set_stereo_switch( int );
|
|
||||||
uint8_t dsp_reg_value( int, int );
|
|
||||||
int dsp_envx_value( int );
|
|
||||||
|
|
||||||
public:
|
|
||||||
BLARGG_DISABLE_NOTHROW
|
|
||||||
|
|
||||||
typedef BOOST::uint16_t uint16_t;
|
|
||||||
|
|
||||||
// Time relative to m_spc_time. Speeds up code a bit by eliminating need to
|
|
||||||
// constantly add m_spc_time to time from CPU. CPU uses time that ends at
|
|
||||||
// 0 to eliminate reloading end time every instruction. It pays off.
|
|
||||||
typedef int rel_time_t;
|
|
||||||
|
|
||||||
struct Timer
|
|
||||||
{
|
|
||||||
rel_time_t next_time; // time of next event
|
|
||||||
int prescaler;
|
|
||||||
int period;
|
|
||||||
int divider;
|
|
||||||
int enabled;
|
|
||||||
int counter;
|
|
||||||
};
|
|
||||||
enum { reg_count = 0x10 };
|
|
||||||
enum { timer_count = 3 };
|
|
||||||
enum { extra_size = SPC_DSP::extra_size };
|
|
||||||
|
|
||||||
enum { signature_size = 35 };
|
|
||||||
|
|
||||||
private:
|
|
||||||
SPC_DSP dsp;
|
|
||||||
|
|
||||||
#if SPC_LESS_ACCURATE
|
|
||||||
static signed char const reg_times_ [256];
|
|
||||||
signed char reg_times [256];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct state_t
|
|
||||||
{
|
|
||||||
Timer timers [timer_count];
|
|
||||||
|
|
||||||
uint8_t smp_regs [2] [reg_count];
|
|
||||||
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
int pc;
|
|
||||||
int a;
|
|
||||||
int x;
|
|
||||||
int y;
|
|
||||||
int psw;
|
|
||||||
int sp;
|
|
||||||
} cpu_regs;
|
|
||||||
|
|
||||||
rel_time_t dsp_time;
|
|
||||||
time_t spc_time;
|
|
||||||
bool echo_accessed;
|
|
||||||
|
|
||||||
int tempo;
|
|
||||||
int skipped_kon;
|
|
||||||
int skipped_koff;
|
|
||||||
const char* cpu_error;
|
|
||||||
|
|
||||||
int extra_clocks;
|
|
||||||
sample_t* buf_begin;
|
|
||||||
sample_t const* buf_end;
|
|
||||||
sample_t* extra_pos;
|
|
||||||
sample_t extra_buf [extra_size];
|
|
||||||
|
|
||||||
int rom_enabled;
|
|
||||||
uint8_t rom [rom_size];
|
|
||||||
uint8_t hi_ram [rom_size];
|
|
||||||
|
|
||||||
unsigned char cycle_table [256];
|
|
||||||
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
// padding to neutralize address overflow
|
|
||||||
union {
|
|
||||||
uint8_t padding1 [0x100];
|
|
||||||
uint16_t align; // makes compiler align data for 16-bit access
|
|
||||||
} padding1 [1];
|
|
||||||
uint8_t ram [0x10000];
|
|
||||||
uint8_t padding2 [0x100];
|
|
||||||
} ram;
|
|
||||||
};
|
|
||||||
state_t m;
|
|
||||||
|
|
||||||
enum { rom_addr = 0xFFC0 };
|
|
||||||
|
|
||||||
enum { skipping_time = 127 };
|
|
||||||
|
|
||||||
// Value that padding should be filled with
|
|
||||||
enum { cpu_pad_fill = 0xFF };
|
|
||||||
|
|
||||||
enum {
|
|
||||||
r_test = 0x0, r_control = 0x1,
|
|
||||||
r_dspaddr = 0x2, r_dspdata = 0x3,
|
|
||||||
r_cpuio0 = 0x4, r_cpuio1 = 0x5,
|
|
||||||
r_cpuio2 = 0x6, r_cpuio3 = 0x7,
|
|
||||||
r_f8 = 0x8, r_f9 = 0x9,
|
|
||||||
r_t0target = 0xA, r_t1target = 0xB, r_t2target = 0xC,
|
|
||||||
r_t0out = 0xD, r_t1out = 0xE, r_t2out = 0xF
|
|
||||||
};
|
|
||||||
|
|
||||||
void timers_loaded();
|
|
||||||
void enable_rom( int enable );
|
|
||||||
void reset_buf();
|
|
||||||
void save_extra();
|
|
||||||
void load_regs( uint8_t const in [reg_count] );
|
|
||||||
void ram_loaded();
|
|
||||||
void regs_loaded();
|
|
||||||
void reset_time_regs();
|
|
||||||
void reset_common( int timer_counter_init );
|
|
||||||
|
|
||||||
Timer* run_timer_ ( Timer* t, rel_time_t );
|
|
||||||
Timer* run_timer ( Timer* t, rel_time_t );
|
|
||||||
int dsp_read ( rel_time_t );
|
|
||||||
void dsp_write ( int data, rel_time_t );
|
|
||||||
void cpu_write_smp_reg_( int data, rel_time_t, int addr );
|
|
||||||
void cpu_write_smp_reg ( int data, rel_time_t, int addr );
|
|
||||||
void cpu_write_high ( int data, int i, rel_time_t );
|
|
||||||
void cpu_write ( int data, int addr, rel_time_t );
|
|
||||||
int cpu_read_smp_reg ( int i, rel_time_t );
|
|
||||||
int cpu_read ( int addr, rel_time_t );
|
|
||||||
unsigned CPU_mem_bit ( uint8_t const* pc, rel_time_t );
|
|
||||||
|
|
||||||
bool check_echo_access ( int addr );
|
|
||||||
uint8_t* run_until_( time_t end_time );
|
|
||||||
|
|
||||||
struct spc_file_t
|
|
||||||
{
|
|
||||||
char signature [signature_size];
|
|
||||||
uint8_t has_id666;
|
|
||||||
uint8_t version;
|
|
||||||
uint8_t pcl, pch;
|
|
||||||
uint8_t a;
|
|
||||||
uint8_t x;
|
|
||||||
uint8_t y;
|
|
||||||
uint8_t psw;
|
|
||||||
uint8_t sp;
|
|
||||||
char text [212];
|
|
||||||
uint8_t ram [0x10000];
|
|
||||||
uint8_t dsp [128];
|
|
||||||
uint8_t unused [0x40];
|
|
||||||
uint8_t ipl_rom [0x40];
|
|
||||||
};
|
|
||||||
|
|
||||||
static char const signature [signature_size + 1];
|
|
||||||
|
|
||||||
void save_regs( uint8_t out [reg_count] );
|
|
||||||
};
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
inline int SNES_SPC::sample_count() const { return (m.extra_clocks >> 5) * 2; }
|
|
||||||
|
|
||||||
inline int SNES_SPC::read_port( time_t t, int port )
|
|
||||||
{
|
|
||||||
assert( (unsigned) port < port_count );
|
|
||||||
return run_until_( t ) [port];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void SNES_SPC::write_port( time_t t, int port, int data )
|
|
||||||
{
|
|
||||||
assert( (unsigned) port < port_count );
|
|
||||||
run_until_( t ) [0x10 + port] = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void SNES_SPC::mute_voices( int mask ) { dsp.mute_voices( mask ); }
|
|
||||||
|
|
||||||
inline void SNES_SPC::disable_surround( bool disable ) { dsp.disable_surround( disable ); }
|
|
||||||
|
|
||||||
#if !SPC_NO_COPY_STATE_FUNCS
|
|
||||||
inline bool SNES_SPC::check_kon() { return dsp.check_kon(); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,407 +0,0 @@
|
|||||||
// SPC emulation support: init, sample buffering, reset, SPC loading
|
|
||||||
|
|
||||||
// snes_spc 0.9.0. http://www.slack.net/~ant/
|
|
||||||
|
|
||||||
#include "SNES_SPC.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
/* Copyright (C) 2004-2007 Shay Green. This module is free software; you
|
|
||||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
|
||||||
General Public License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version. This
|
|
||||||
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
||||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
|
||||||
details. You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this module; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
|
||||||
|
|
||||||
#include "blargg_source.h"
|
|
||||||
|
|
||||||
#define RAM (m.ram.ram)
|
|
||||||
#define REGS (m.smp_regs [0])
|
|
||||||
#define REGS_IN (m.smp_regs [1])
|
|
||||||
|
|
||||||
// (n ? n : 256)
|
|
||||||
#define IF_0_THEN_256( n ) ((uint8_t) ((n) - 1) + 1)
|
|
||||||
|
|
||||||
|
|
||||||
//// Init
|
|
||||||
|
|
||||||
blargg_err_t SNES_SPC::init()
|
|
||||||
{
|
|
||||||
memset( &m, 0, sizeof m );
|
|
||||||
dsp.init( RAM );
|
|
||||||
|
|
||||||
m.tempo = tempo_unit;
|
|
||||||
|
|
||||||
// Most SPC music doesn't need ROM, and almost all the rest only rely
|
|
||||||
// on these two bytes
|
|
||||||
m.rom [0x3E] = 0xFF;
|
|
||||||
m.rom [0x3F] = 0xC0;
|
|
||||||
|
|
||||||
static unsigned char const cycle_table [128] =
|
|
||||||
{// 01 23 45 67 89 AB CD EF
|
|
||||||
0x28,0x47,0x34,0x36,0x26,0x54,0x54,0x68, // 0
|
|
||||||
0x48,0x47,0x45,0x56,0x55,0x65,0x22,0x46, // 1
|
|
||||||
0x28,0x47,0x34,0x36,0x26,0x54,0x54,0x74, // 2
|
|
||||||
0x48,0x47,0x45,0x56,0x55,0x65,0x22,0x38, // 3
|
|
||||||
0x28,0x47,0x34,0x36,0x26,0x44,0x54,0x66, // 4
|
|
||||||
0x48,0x47,0x45,0x56,0x55,0x45,0x22,0x43, // 5
|
|
||||||
0x28,0x47,0x34,0x36,0x26,0x44,0x54,0x75, // 6
|
|
||||||
0x48,0x47,0x45,0x56,0x55,0x55,0x22,0x36, // 7
|
|
||||||
0x28,0x47,0x34,0x36,0x26,0x54,0x52,0x45, // 8
|
|
||||||
0x48,0x47,0x45,0x56,0x55,0x55,0x22,0xC5, // 9
|
|
||||||
0x38,0x47,0x34,0x36,0x26,0x44,0x52,0x44, // A
|
|
||||||
0x48,0x47,0x45,0x56,0x55,0x55,0x22,0x34, // B
|
|
||||||
0x38,0x47,0x45,0x47,0x25,0x64,0x52,0x49, // C
|
|
||||||
0x48,0x47,0x56,0x67,0x45,0x55,0x22,0x83, // D
|
|
||||||
0x28,0x47,0x34,0x36,0x24,0x53,0x43,0x40, // E
|
|
||||||
0x48,0x47,0x45,0x56,0x34,0x54,0x22,0x60, // F
|
|
||||||
};
|
|
||||||
|
|
||||||
// unpack cycle table
|
|
||||||
for ( int i = 0; i < 128; i++ )
|
|
||||||
{
|
|
||||||
int n = cycle_table [i];
|
|
||||||
m.cycle_table [i * 2 + 0] = n >> 4;
|
|
||||||
m.cycle_table [i * 2 + 1] = n & 0x0F;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if SPC_LESS_ACCURATE
|
|
||||||
memcpy( reg_times, reg_times_, sizeof reg_times );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
reset();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SNES_SPC::init_rom( uint8_t const in [rom_size] )
|
|
||||||
{
|
|
||||||
memcpy( m.rom, in, sizeof m.rom );
|
|
||||||
}
|
|
||||||
|
|
||||||
void SNES_SPC::set_tempo( int t )
|
|
||||||
{
|
|
||||||
m.tempo = t;
|
|
||||||
int const timer2_shift = 4; // 64 kHz
|
|
||||||
int const other_shift = 3; // 8 kHz
|
|
||||||
|
|
||||||
#if SPC_DISABLE_TEMPO
|
|
||||||
m.timers [2].prescaler = timer2_shift;
|
|
||||||
m.timers [1].prescaler = timer2_shift + other_shift;
|
|
||||||
m.timers [0].prescaler = timer2_shift + other_shift;
|
|
||||||
#else
|
|
||||||
if ( !t )
|
|
||||||
t = 1;
|
|
||||||
int const timer2_rate = 1 << timer2_shift;
|
|
||||||
int rate = (timer2_rate * tempo_unit + (t >> 1)) / t;
|
|
||||||
if ( rate < timer2_rate / 4 )
|
|
||||||
rate = timer2_rate / 4; // max 4x tempo
|
|
||||||
m.timers [2].prescaler = rate;
|
|
||||||
m.timers [1].prescaler = rate << other_shift;
|
|
||||||
m.timers [0].prescaler = rate << other_shift;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Timer registers have been loaded. Applies these to the timers. Does not
|
|
||||||
// reset timer prescalers or dividers.
|
|
||||||
void SNES_SPC::timers_loaded()
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for ( i = 0; i < timer_count; i++ )
|
|
||||||
{
|
|
||||||
Timer* t = &m.timers [i];
|
|
||||||
t->period = IF_0_THEN_256( REGS [r_t0target + i] );
|
|
||||||
t->enabled = REGS [r_control] >> i & 1;
|
|
||||||
t->counter = REGS_IN [r_t0out + i] & 0x0F;
|
|
||||||
}
|
|
||||||
|
|
||||||
set_tempo( m.tempo );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Loads registers from unified 16-byte format
|
|
||||||
void SNES_SPC::load_regs( uint8_t const in [reg_count] )
|
|
||||||
{
|
|
||||||
memcpy( REGS, in, reg_count );
|
|
||||||
//memcpy( REGS_IN, REGS, reg_count );
|
|
||||||
|
|
||||||
// These always read back as 0
|
|
||||||
REGS_IN [r_test ] = 0;
|
|
||||||
REGS_IN [r_control ] = 0;
|
|
||||||
REGS_IN [r_t0target] = 0;
|
|
||||||
REGS_IN [r_t1target] = 0;
|
|
||||||
REGS_IN [r_t2target] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// RAM was just loaded from SPC, with $F0-$FF containing SMP registers
|
|
||||||
// and timer counts. Copies these to proper registers.
|
|
||||||
void SNES_SPC::ram_loaded()
|
|
||||||
{
|
|
||||||
m.rom_enabled = 0;
|
|
||||||
load_regs( &RAM [0xF0] );
|
|
||||||
|
|
||||||
// Put STOP instruction around memory to catch PC underflow/overflow
|
|
||||||
memset( m.ram.padding1, cpu_pad_fill, sizeof m.ram.padding1 );
|
|
||||||
memset( m.ram.padding2, cpu_pad_fill, sizeof m.ram.padding2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Registers were just loaded. Applies these new values.
|
|
||||||
void SNES_SPC::regs_loaded()
|
|
||||||
{
|
|
||||||
enable_rom( REGS [r_control] & 0x80 );
|
|
||||||
timers_loaded();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SNES_SPC::reset_time_regs()
|
|
||||||
{
|
|
||||||
m.cpu_error = 0;
|
|
||||||
m.echo_accessed = 0;
|
|
||||||
m.spc_time = 0;
|
|
||||||
m.dsp_time = 0;
|
|
||||||
#if SPC_LESS_ACCURATE
|
|
||||||
m.dsp_time = clocks_per_sample + 1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for ( int i = 0; i < timer_count; i++ )
|
|
||||||
{
|
|
||||||
Timer* t = &m.timers [i];
|
|
||||||
t->next_time = 1;
|
|
||||||
t->divider = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
regs_loaded();
|
|
||||||
|
|
||||||
m.extra_clocks = 0;
|
|
||||||
reset_buf();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SNES_SPC::reset_common( int timer_counter_init )
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for ( i = 0; i < timer_count; i++ )
|
|
||||||
REGS_IN [r_t0out + i] = timer_counter_init;
|
|
||||||
|
|
||||||
// Run IPL ROM
|
|
||||||
memset( &m.cpu_regs, 0, sizeof m.cpu_regs );
|
|
||||||
m.cpu_regs.pc = rom_addr;
|
|
||||||
|
|
||||||
REGS [r_test ] = 0x0A;
|
|
||||||
REGS [r_control] = 0xB0; // ROM enabled, clear ports
|
|
||||||
for ( i = 0; i < port_count; i++ )
|
|
||||||
REGS_IN [r_cpuio0 + i] = 0;
|
|
||||||
|
|
||||||
reset_time_regs();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SNES_SPC::soft_reset()
|
|
||||||
{
|
|
||||||
reset_common( 0 );
|
|
||||||
dsp.soft_reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SNES_SPC::reset()
|
|
||||||
{
|
|
||||||
memset( RAM, 0xFF, 0x10000 );
|
|
||||||
ram_loaded();
|
|
||||||
reset_common( 0x0F );
|
|
||||||
dsp.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
char const SNES_SPC::signature [signature_size + 1] =
|
|
||||||
"SNES-SPC700 Sound File Data v0.30\x1A\x1A";
|
|
||||||
|
|
||||||
blargg_err_t SNES_SPC::load_spc( void const* data, long size )
|
|
||||||
{
|
|
||||||
spc_file_t const* const spc = (spc_file_t const*) data;
|
|
||||||
|
|
||||||
// be sure compiler didn't insert any padding into fle_t
|
|
||||||
assert( sizeof (spc_file_t) == spc_min_file_size + 0x80 );
|
|
||||||
|
|
||||||
// Check signature and file size
|
|
||||||
if ( size < signature_size || memcmp( spc, signature, 27 ) )
|
|
||||||
return "Not an SPC file";
|
|
||||||
|
|
||||||
if ( size < spc_min_file_size )
|
|
||||||
return "Corrupt SPC file";
|
|
||||||
|
|
||||||
// CPU registers
|
|
||||||
m.cpu_regs.pc = spc->pch * 0x100 + spc->pcl;
|
|
||||||
m.cpu_regs.a = spc->a;
|
|
||||||
m.cpu_regs.x = spc->x;
|
|
||||||
m.cpu_regs.y = spc->y;
|
|
||||||
m.cpu_regs.psw = spc->psw;
|
|
||||||
m.cpu_regs.sp = spc->sp;
|
|
||||||
|
|
||||||
// RAM and registers
|
|
||||||
memcpy( RAM, spc->ram, 0x10000 );
|
|
||||||
ram_loaded();
|
|
||||||
|
|
||||||
// DSP registers
|
|
||||||
dsp.load( spc->dsp );
|
|
||||||
|
|
||||||
reset_time_regs();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SNES_SPC::clear_echo()
|
|
||||||
{
|
|
||||||
if ( !(dsp.read( SPC_DSP::r_flg ) & 0x20) )
|
|
||||||
{
|
|
||||||
int addr = 0x100 * dsp.read( SPC_DSP::r_esa );
|
|
||||||
int end = addr + 0x800 * (dsp.read( SPC_DSP::r_edl ) & 0x0F);
|
|
||||||
if ( end > 0x10000 )
|
|
||||||
end = 0x10000;
|
|
||||||
memset( &RAM [addr], 0xFF, end - addr );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//// Sample output
|
|
||||||
|
|
||||||
void SNES_SPC::reset_buf()
|
|
||||||
{
|
|
||||||
// Start with half extra buffer of silence
|
|
||||||
sample_t* out = m.extra_buf;
|
|
||||||
while ( out < &m.extra_buf [extra_size / 2] )
|
|
||||||
*out++ = 0;
|
|
||||||
|
|
||||||
m.extra_pos = out;
|
|
||||||
m.buf_begin = 0;
|
|
||||||
|
|
||||||
dsp.set_output( 0, 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
void SNES_SPC::set_output( sample_t* out, int size )
|
|
||||||
{
|
|
||||||
require( (size & 1) == 0 ); // size must be even
|
|
||||||
|
|
||||||
m.extra_clocks &= clocks_per_sample - 1;
|
|
||||||
if ( out )
|
|
||||||
{
|
|
||||||
sample_t const* out_end = out + size;
|
|
||||||
m.buf_begin = out;
|
|
||||||
m.buf_end = out_end;
|
|
||||||
|
|
||||||
// Copy extra to output
|
|
||||||
sample_t const* in = m.extra_buf;
|
|
||||||
while ( in < m.extra_pos && out < out_end )
|
|
||||||
*out++ = *in++;
|
|
||||||
|
|
||||||
// Handle output being full already
|
|
||||||
if ( out >= out_end )
|
|
||||||
{
|
|
||||||
// Have DSP write to remaining extra space
|
|
||||||
out = dsp.extra();
|
|
||||||
out_end = &dsp.extra() [extra_size];
|
|
||||||
|
|
||||||
// Copy any remaining extra samples as if DSP wrote them
|
|
||||||
while ( in < m.extra_pos )
|
|
||||||
*out++ = *in++;
|
|
||||||
assert( out <= out_end );
|
|
||||||
}
|
|
||||||
|
|
||||||
dsp.set_output( out, out_end - out );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
reset_buf();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SNES_SPC::save_extra()
|
|
||||||
{
|
|
||||||
// Get end pointers
|
|
||||||
sample_t const* main_end = m.buf_end; // end of data written to buf
|
|
||||||
sample_t const* dsp_end = dsp.out_pos(); // end of data written to dsp.extra()
|
|
||||||
if ( m.buf_begin <= dsp_end && dsp_end <= main_end )
|
|
||||||
{
|
|
||||||
main_end = dsp_end;
|
|
||||||
dsp_end = dsp.extra(); // nothing in DSP's extra
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy any extra samples at these ends into extra_buf
|
|
||||||
sample_t* out = m.extra_buf;
|
|
||||||
sample_t const* in;
|
|
||||||
for ( in = m.buf_begin + sample_count(); in < main_end; in++ )
|
|
||||||
*out++ = *in;
|
|
||||||
for ( in = dsp.extra(); in < dsp_end ; in++ )
|
|
||||||
*out++ = *in;
|
|
||||||
|
|
||||||
m.extra_pos = out;
|
|
||||||
assert( out <= &m.extra_buf [extra_size] );
|
|
||||||
}
|
|
||||||
|
|
||||||
blargg_err_t SNES_SPC::play( int count, sample_t* out )
|
|
||||||
{
|
|
||||||
require( (count & 1) == 0 ); // must be even
|
|
||||||
if ( count )
|
|
||||||
{
|
|
||||||
set_output( out, count );
|
|
||||||
end_frame( count * (clocks_per_sample / 2) );
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* err = m.cpu_error;
|
|
||||||
m.cpu_error = 0;
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
blargg_err_t SNES_SPC::skip( int count )
|
|
||||||
{
|
|
||||||
#if SPC_LESS_ACCURATE
|
|
||||||
if ( count > 2 * sample_rate * 2 )
|
|
||||||
{
|
|
||||||
set_output( 0, 0 );
|
|
||||||
|
|
||||||
// Skip a multiple of 4 samples
|
|
||||||
time_t end = count;
|
|
||||||
count = (count & 3) + 1 * sample_rate * 2;
|
|
||||||
end = (end - count) * (clocks_per_sample / 2);
|
|
||||||
|
|
||||||
m.skipped_kon = 0;
|
|
||||||
m.skipped_koff = 0;
|
|
||||||
|
|
||||||
// Preserve DSP and timer synchronization
|
|
||||||
// TODO: verify that this really preserves it
|
|
||||||
int old_dsp_time = m.dsp_time + m.spc_time;
|
|
||||||
m.dsp_time = end - m.spc_time + skipping_time;
|
|
||||||
end_frame( end );
|
|
||||||
m.dsp_time = m.dsp_time - skipping_time + old_dsp_time;
|
|
||||||
|
|
||||||
dsp.write( SPC_DSP::r_koff, m.skipped_koff & ~m.skipped_kon );
|
|
||||||
dsp.write( SPC_DSP::r_kon , m.skipped_kon );
|
|
||||||
clear_echo();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return play( count, 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
//// Snes9x Accessor
|
|
||||||
|
|
||||||
void SNES_SPC::dsp_set_spc_snapshot_callback( void (*callback) (void) )
|
|
||||||
{
|
|
||||||
dsp.set_spc_snapshot_callback( callback );
|
|
||||||
}
|
|
||||||
|
|
||||||
void SNES_SPC::dsp_dump_spc_snapshot( void )
|
|
||||||
{
|
|
||||||
dsp.dump_spc_snapshot();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SNES_SPC::dsp_set_stereo_switch( int value )
|
|
||||||
{
|
|
||||||
dsp.set_stereo_switch( value );
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t SNES_SPC::dsp_reg_value( int ch, int addr )
|
|
||||||
{
|
|
||||||
return dsp.reg_value( ch, addr );
|
|
||||||
}
|
|
||||||
|
|
||||||
int SNES_SPC::dsp_envx_value( int ch )
|
|
||||||
{
|
|
||||||
return dsp.envx_value( ch );
|
|
||||||
}
|
|
@ -1,142 +0,0 @@
|
|||||||
// SPC emulation state save/load: copy_state(), save_spc()
|
|
||||||
// Separate file to avoid linking in unless needed
|
|
||||||
|
|
||||||
// snes_spc 0.9.0. http://www.slack.net/‾ant/
|
|
||||||
|
|
||||||
#include "SNES_SPC.h"
|
|
||||||
|
|
||||||
#if !SPC_NO_COPY_STATE_FUNCS
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
/* Copyright (C) 2004-2007 Shay Green. This module is free software; you
|
|
||||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
|
||||||
General Public License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version. This
|
|
||||||
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
||||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
|
||||||
details. You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this module; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "blargg_source.h"
|
|
||||||
|
|
||||||
#define RAM (m.ram.ram)
|
|
||||||
#define REGS (m.smp_regs [0])
|
|
||||||
#define REGS_IN (m.smp_regs [1])
|
|
||||||
|
|
||||||
void SNES_SPC::save_regs( uint8_t out [reg_count] )
|
|
||||||
{
|
|
||||||
// Use current timer counter values
|
|
||||||
for ( int i = 0; i < timer_count; i++ )
|
|
||||||
out [r_t0out + i] = m.timers [i].counter;
|
|
||||||
|
|
||||||
// Last written values
|
|
||||||
memcpy( out, REGS, r_t0out );
|
|
||||||
}
|
|
||||||
|
|
||||||
void SNES_SPC::init_header( void* spc_out )
|
|
||||||
{
|
|
||||||
spc_file_t* const spc = (spc_file_t*) spc_out;
|
|
||||||
|
|
||||||
spc->has_id666 = 26; // has none
|
|
||||||
spc->version = 30;
|
|
||||||
memcpy( spc, signature, sizeof spc->signature );
|
|
||||||
memset( spc->text, 0, sizeof spc->text );
|
|
||||||
}
|
|
||||||
|
|
||||||
void SNES_SPC::save_spc( void* spc_out )
|
|
||||||
{
|
|
||||||
spc_file_t* const spc = (spc_file_t*) spc_out;
|
|
||||||
|
|
||||||
// CPU
|
|
||||||
spc->pcl = (uint8_t) (m.cpu_regs.pc >> 0);
|
|
||||||
spc->pch = (uint8_t) (m.cpu_regs.pc >> 8);
|
|
||||||
spc->a = m.cpu_regs.a;
|
|
||||||
spc->x = m.cpu_regs.x;
|
|
||||||
spc->y = m.cpu_regs.y;
|
|
||||||
spc->psw = m.cpu_regs.psw;
|
|
||||||
spc->sp = m.cpu_regs.sp;
|
|
||||||
|
|
||||||
// RAM, ROM
|
|
||||||
memcpy( spc->ram, RAM, sizeof spc->ram );
|
|
||||||
if ( m.rom_enabled )
|
|
||||||
memcpy( spc->ram + rom_addr, m.hi_ram, sizeof m.hi_ram );
|
|
||||||
memset( spc->unused, 0, sizeof spc->unused );
|
|
||||||
memcpy( spc->ipl_rom, m.rom, sizeof spc->ipl_rom );
|
|
||||||
|
|
||||||
// SMP registers
|
|
||||||
save_regs( &spc->ram [0xF0] );
|
|
||||||
int i;
|
|
||||||
for ( i = 0; i < port_count; i++ )
|
|
||||||
spc->ram [0xF0 + r_cpuio0 + i] = REGS_IN [r_cpuio0 + i];
|
|
||||||
|
|
||||||
// DSP registers
|
|
||||||
for ( i = 0; i < SPC_DSP::register_count; i++ )
|
|
||||||
spc->dsp [i] = dsp.read( i );
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef IF_0_THEN_256
|
|
||||||
#define IF_0_THEN_256( n ) ((uint8_t) ((n) - 1) + 1)
|
|
||||||
void SNES_SPC::copy_state( unsigned char** io, copy_func_t copy )
|
|
||||||
{
|
|
||||||
SPC_State_Copier copier( io, copy );
|
|
||||||
|
|
||||||
// Make state data more readable by putting 64K RAM, 16 SMP registers,
|
|
||||||
// then DSP (with its 128 registers) first
|
|
||||||
|
|
||||||
// RAM
|
|
||||||
enable_rom( 0 ); // will get re-enabled if necessary in regs_loaded() below
|
|
||||||
copier.copy( RAM, 0x10000 );
|
|
||||||
|
|
||||||
{
|
|
||||||
// SMP registers
|
|
||||||
uint8_t regs [reg_count];
|
|
||||||
uint8_t regs_in [reg_count];
|
|
||||||
|
|
||||||
memcpy( regs, REGS, reg_count );
|
|
||||||
memcpy( regs_in, REGS_IN, reg_count );
|
|
||||||
|
|
||||||
copier.copy( regs, sizeof regs );
|
|
||||||
copier.copy( regs_in, sizeof regs_in );
|
|
||||||
|
|
||||||
memcpy( REGS, regs, reg_count);
|
|
||||||
memcpy( REGS_IN, regs_in, reg_count );
|
|
||||||
|
|
||||||
enable_rom( REGS [r_control] & 0x80 );
|
|
||||||
}
|
|
||||||
|
|
||||||
// CPU registers
|
|
||||||
SPC_COPY( uint16_t, m.cpu_regs.pc );
|
|
||||||
SPC_COPY( uint8_t, m.cpu_regs.a );
|
|
||||||
SPC_COPY( uint8_t, m.cpu_regs.x );
|
|
||||||
SPC_COPY( uint8_t, m.cpu_regs.y );
|
|
||||||
SPC_COPY( uint8_t, m.cpu_regs.psw );
|
|
||||||
SPC_COPY( uint8_t, m.cpu_regs.sp );
|
|
||||||
copier.extra();
|
|
||||||
|
|
||||||
SPC_COPY( int16_t, m.spc_time );
|
|
||||||
SPC_COPY( int16_t, m.dsp_time );
|
|
||||||
|
|
||||||
// DSP
|
|
||||||
dsp.copy_state( io, copy );
|
|
||||||
|
|
||||||
// Timers
|
|
||||||
for ( int i = 0; i < timer_count; i++ )
|
|
||||||
{
|
|
||||||
Timer* t = &m.timers [i];
|
|
||||||
t->period = IF_0_THEN_256( REGS [r_t0target + i] );
|
|
||||||
t->enabled = REGS [r_control] >> i & 1;
|
|
||||||
SPC_COPY( int16_t, t->next_time );
|
|
||||||
SPC_COPY( uint8_t, t->divider );
|
|
||||||
SPC_COPY( uint8_t, t->counter );
|
|
||||||
copier.extra();
|
|
||||||
}
|
|
||||||
|
|
||||||
set_tempo( m.tempo );
|
|
||||||
|
|
||||||
copier.extra();
|
|
||||||
}
|
|
||||||
#endif
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,317 +0,0 @@
|
|||||||
// Highly accurate SNES SPC-700 DSP emulator
|
|
||||||
|
|
||||||
// snes_spc 0.9.0
|
|
||||||
#ifndef SPC_DSP_H
|
|
||||||
#define SPC_DSP_H
|
|
||||||
|
|
||||||
#include "blargg_common.h"
|
|
||||||
|
|
||||||
extern "C" { typedef void (*dsp_copy_func_t)( unsigned char** io, void* state, size_t ); }
|
|
||||||
|
|
||||||
class SPC_DSP {
|
|
||||||
public:
|
|
||||||
typedef BOOST::uint8_t uint8_t;
|
|
||||||
|
|
||||||
// Setup
|
|
||||||
|
|
||||||
// Initializes DSP and has it use the 64K RAM provided
|
|
||||||
void init( void* ram_64k );
|
|
||||||
|
|
||||||
// Sets destination for output samples. If out is NULL or out_size is 0,
|
|
||||||
// doesn't generate any.
|
|
||||||
typedef short sample_t;
|
|
||||||
void set_output( sample_t* out, int out_size );
|
|
||||||
|
|
||||||
// Number of samples written to output since it was last set, always
|
|
||||||
// a multiple of 2. Undefined if more samples were generated than
|
|
||||||
// output buffer could hold.
|
|
||||||
int sample_count() const;
|
|
||||||
|
|
||||||
// Emulation
|
|
||||||
|
|
||||||
// Resets DSP to power-on state
|
|
||||||
void reset();
|
|
||||||
|
|
||||||
// Emulates pressing reset switch on SNES
|
|
||||||
void soft_reset();
|
|
||||||
|
|
||||||
// Reads/writes DSP registers. For accuracy, you must first call run()
|
|
||||||
// to catch the DSP up to present.
|
|
||||||
int read ( int addr ) const;
|
|
||||||
void write( int addr, int data );
|
|
||||||
|
|
||||||
// Runs DSP for specified number of clocks (~1024000 per second). Every 32 clocks
|
|
||||||
// a pair of samples is be generated.
|
|
||||||
void run( int clock_count );
|
|
||||||
|
|
||||||
// Sound control
|
|
||||||
|
|
||||||
// Mutes voices corresponding to non-zero bits in mask (issues repeated KOFF events).
|
|
||||||
// Reduces emulation accuracy.
|
|
||||||
enum { voice_count = 8 };
|
|
||||||
void mute_voices( int mask );
|
|
||||||
|
|
||||||
// State
|
|
||||||
|
|
||||||
// Resets DSP and uses supplied values to initialize registers
|
|
||||||
enum { register_count = 128 };
|
|
||||||
void load( uint8_t const regs [register_count] );
|
|
||||||
|
|
||||||
// Saves/loads exact emulator state
|
|
||||||
enum { state_size = 640 }; // maximum space needed when saving
|
|
||||||
typedef dsp_copy_func_t copy_func_t;
|
|
||||||
void copy_state( unsigned char** io, copy_func_t );
|
|
||||||
|
|
||||||
// Returns non-zero if new key-on events occurred since last call
|
|
||||||
bool check_kon();
|
|
||||||
|
|
||||||
// Snes9x Accessor
|
|
||||||
|
|
||||||
int stereo_switch;
|
|
||||||
int take_spc_snapshot;
|
|
||||||
void (*spc_snapshot_callback) (void);
|
|
||||||
|
|
||||||
void set_spc_snapshot_callback( void (*callback) (void) );
|
|
||||||
void dump_spc_snapshot( void );
|
|
||||||
void set_stereo_switch( int );
|
|
||||||
uint8_t reg_value( int, int );
|
|
||||||
int envx_value( int );
|
|
||||||
|
|
||||||
// DSP register addresses
|
|
||||||
|
|
||||||
// Global registers
|
|
||||||
enum {
|
|
||||||
r_mvoll = 0x0C, r_mvolr = 0x1C,
|
|
||||||
r_evoll = 0x2C, r_evolr = 0x3C,
|
|
||||||
r_kon = 0x4C, r_koff = 0x5C,
|
|
||||||
r_flg = 0x6C, r_endx = 0x7C,
|
|
||||||
r_efb = 0x0D, r_pmon = 0x2D,
|
|
||||||
r_non = 0x3D, r_eon = 0x4D,
|
|
||||||
r_dir = 0x5D, r_esa = 0x6D,
|
|
||||||
r_edl = 0x7D,
|
|
||||||
r_fir = 0x0F // 8 coefficients at 0x0F, 0x1F ... 0x7F
|
|
||||||
};
|
|
||||||
|
|
||||||
// Voice registers
|
|
||||||
enum {
|
|
||||||
v_voll = 0x00, v_volr = 0x01,
|
|
||||||
v_pitchl = 0x02, v_pitchh = 0x03,
|
|
||||||
v_srcn = 0x04, v_adsr0 = 0x05,
|
|
||||||
v_adsr1 = 0x06, v_gain = 0x07,
|
|
||||||
v_envx = 0x08, v_outx = 0x09
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
enum { extra_size = 16 };
|
|
||||||
sample_t* extra() { return m.extra; }
|
|
||||||
sample_t const* out_pos() const { return m.out; }
|
|
||||||
void disable_surround( bool ) { } // not supported
|
|
||||||
public:
|
|
||||||
BLARGG_DISABLE_NOTHROW
|
|
||||||
|
|
||||||
typedef BOOST::int8_t int8_t;
|
|
||||||
typedef BOOST::int16_t int16_t;
|
|
||||||
|
|
||||||
enum { echo_hist_size = 8 };
|
|
||||||
|
|
||||||
enum env_mode_t { env_release, env_attack, env_decay, env_sustain };
|
|
||||||
enum { brr_buf_size = 12 };
|
|
||||||
struct voice_t
|
|
||||||
{
|
|
||||||
int buf [brr_buf_size*2];// decoded samples (twice the size to simplify wrap handling)
|
|
||||||
int buf_pos; // place in buffer where next samples will be decoded
|
|
||||||
int interp_pos; // relative fractional position in sample (0x1000 = 1.0)
|
|
||||||
int brr_addr; // address of current BRR block
|
|
||||||
int brr_offset; // current decoding offset in BRR block
|
|
||||||
uint8_t* regs; // pointer to voice's DSP registers
|
|
||||||
int vbit; // bitmask for voice: 0x01 for voice 0, 0x02 for voice 1, etc.
|
|
||||||
int kon_delay; // KON delay/current setup phase
|
|
||||||
env_mode_t env_mode;
|
|
||||||
int env; // current envelope level
|
|
||||||
int hidden_env; // used by GAIN mode 7, very obscure quirk
|
|
||||||
uint8_t t_envx_out;
|
|
||||||
int voice_number;
|
|
||||||
};
|
|
||||||
private:
|
|
||||||
enum { brr_block_size = 9 };
|
|
||||||
|
|
||||||
struct state_t
|
|
||||||
{
|
|
||||||
uint8_t regs [register_count];
|
|
||||||
|
|
||||||
// Echo history keeps most recent 8 samples (twice the size to simplify wrap handling)
|
|
||||||
int echo_hist [echo_hist_size * 2] [2];
|
|
||||||
int (*echo_hist_pos) [2]; // &echo_hist [0 to 7]
|
|
||||||
|
|
||||||
int every_other_sample; // toggles every sample
|
|
||||||
int kon; // KON value when last checked
|
|
||||||
int noise;
|
|
||||||
int counter;
|
|
||||||
int echo_offset; // offset from ESA in echo buffer
|
|
||||||
int echo_length; // number of bytes that echo_offset will stop at
|
|
||||||
int phase; // next clock cycle to run (0-31)
|
|
||||||
bool kon_check; // set when a new KON occurs
|
|
||||||
|
|
||||||
// Hidden registers also written to when main register is written to
|
|
||||||
int new_kon;
|
|
||||||
uint8_t endx_buf;
|
|
||||||
uint8_t envx_buf;
|
|
||||||
uint8_t outx_buf;
|
|
||||||
|
|
||||||
// Temporary state between clocks
|
|
||||||
|
|
||||||
// read once per sample
|
|
||||||
int t_pmon;
|
|
||||||
int t_non;
|
|
||||||
int t_eon;
|
|
||||||
int t_dir;
|
|
||||||
int t_koff;
|
|
||||||
|
|
||||||
// read a few clocks ahead then used
|
|
||||||
int t_brr_next_addr;
|
|
||||||
int t_adsr0;
|
|
||||||
int t_brr_header;
|
|
||||||
int t_brr_byte;
|
|
||||||
int t_srcn;
|
|
||||||
int t_esa;
|
|
||||||
int t_echo_enabled;
|
|
||||||
|
|
||||||
// internal state that is recalculated every sample
|
|
||||||
int t_dir_addr;
|
|
||||||
int t_pitch;
|
|
||||||
int t_output;
|
|
||||||
int t_looped;
|
|
||||||
int t_echo_ptr;
|
|
||||||
|
|
||||||
// left/right sums
|
|
||||||
int t_main_out [2];
|
|
||||||
int t_echo_out [2];
|
|
||||||
int t_echo_in [2];
|
|
||||||
|
|
||||||
voice_t voices [voice_count];
|
|
||||||
|
|
||||||
// non-emulation state
|
|
||||||
uint8_t* ram; // 64K shared RAM between DSP and SMP
|
|
||||||
int mute_mask;
|
|
||||||
sample_t* out;
|
|
||||||
sample_t* out_end;
|
|
||||||
sample_t* out_begin;
|
|
||||||
sample_t extra [extra_size];
|
|
||||||
};
|
|
||||||
state_t m;
|
|
||||||
|
|
||||||
void init_counter();
|
|
||||||
void run_counters();
|
|
||||||
unsigned read_counter( int rate );
|
|
||||||
|
|
||||||
int interpolate( voice_t const* v );
|
|
||||||
void run_envelope( voice_t* const v );
|
|
||||||
void decode_brr( voice_t* v );
|
|
||||||
|
|
||||||
void misc_27();
|
|
||||||
void misc_28();
|
|
||||||
void misc_29();
|
|
||||||
void misc_30();
|
|
||||||
|
|
||||||
void voice_output( voice_t const* v, int ch );
|
|
||||||
void voice_V1( voice_t* const );
|
|
||||||
void voice_V2( voice_t* const );
|
|
||||||
void voice_V3( voice_t* const );
|
|
||||||
void voice_V3a( voice_t* const );
|
|
||||||
void voice_V3b( voice_t* const );
|
|
||||||
void voice_V3c( voice_t* const );
|
|
||||||
void voice_V4( voice_t* const );
|
|
||||||
void voice_V5( voice_t* const );
|
|
||||||
void voice_V6( voice_t* const );
|
|
||||||
void voice_V7( voice_t* const );
|
|
||||||
void voice_V8( voice_t* const );
|
|
||||||
void voice_V9( voice_t* const );
|
|
||||||
void voice_V7_V4_V1( voice_t* const );
|
|
||||||
void voice_V8_V5_V2( voice_t* const );
|
|
||||||
void voice_V9_V6_V3( voice_t* const );
|
|
||||||
|
|
||||||
void echo_read( int ch );
|
|
||||||
int echo_output( int ch );
|
|
||||||
void echo_write( int ch );
|
|
||||||
void echo_22();
|
|
||||||
void echo_23();
|
|
||||||
void echo_24();
|
|
||||||
void echo_25();
|
|
||||||
void echo_26();
|
|
||||||
void echo_27();
|
|
||||||
void echo_28();
|
|
||||||
void echo_29();
|
|
||||||
void echo_30();
|
|
||||||
|
|
||||||
void soft_reset_common();
|
|
||||||
};
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
inline int SPC_DSP::sample_count() const { return m.out - m.out_begin; }
|
|
||||||
|
|
||||||
inline int SPC_DSP::read( int addr ) const
|
|
||||||
{
|
|
||||||
assert( (unsigned) addr < register_count );
|
|
||||||
return m.regs [addr];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void SPC_DSP::write( int addr, int data )
|
|
||||||
{
|
|
||||||
assert( (unsigned) addr < register_count );
|
|
||||||
|
|
||||||
m.regs [addr] = (uint8_t) data;
|
|
||||||
switch ( addr & 0x0F )
|
|
||||||
{
|
|
||||||
case v_envx:
|
|
||||||
m.envx_buf = (uint8_t) data;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case v_outx:
|
|
||||||
m.outx_buf = (uint8_t) data;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x0C:
|
|
||||||
if ( addr == r_kon )
|
|
||||||
m.new_kon = (uint8_t) data;
|
|
||||||
|
|
||||||
if ( addr == r_endx ) // always cleared, regardless of data written
|
|
||||||
{
|
|
||||||
m.endx_buf = 0;
|
|
||||||
m.regs [r_endx] = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void SPC_DSP::mute_voices( int mask ) { m.mute_mask = mask; }
|
|
||||||
|
|
||||||
inline bool SPC_DSP::check_kon()
|
|
||||||
{
|
|
||||||
bool old = m.kon_check;
|
|
||||||
m.kon_check = 0;
|
|
||||||
return old;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !SPC_NO_COPY_STATE_FUNCS
|
|
||||||
|
|
||||||
class SPC_State_Copier {
|
|
||||||
SPC_DSP::copy_func_t func;
|
|
||||||
unsigned char** buf;
|
|
||||||
public:
|
|
||||||
SPC_State_Copier( unsigned char** p, SPC_DSP::copy_func_t f ) { func = f; buf = p; }
|
|
||||||
void copy( void* state, size_t size );
|
|
||||||
int copy_int( int state, int size );
|
|
||||||
void skip( int count );
|
|
||||||
void extra();
|
|
||||||
};
|
|
||||||
|
|
||||||
#define SPC_COPY( type, state )\
|
|
||||||
{\
|
|
||||||
state = (BOOST::type) copier.copy_int( state, sizeof (BOOST::type) );\
|
|
||||||
assert( (BOOST::type) state == state );\
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,68 +0,0 @@
|
|||||||
// snes_spc 0.9.0. http://www.slack.net/~ant/
|
|
||||||
|
|
||||||
#include "SPC_Filter.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
/* Copyright (C) 2007 Shay Green. This module is free software; you
|
|
||||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
|
||||||
General Public License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version. This
|
|
||||||
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
||||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
|
||||||
details. You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this module; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
|
||||||
|
|
||||||
#include "blargg_source.h"
|
|
||||||
|
|
||||||
void SPC_Filter::clear() { memset( ch, 0, sizeof ch ); }
|
|
||||||
|
|
||||||
SPC_Filter::SPC_Filter()
|
|
||||||
{
|
|
||||||
gain = gain_unit;
|
|
||||||
bass = bass_norm;
|
|
||||||
clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SPC_Filter::run( short* io, int count )
|
|
||||||
{
|
|
||||||
require( (count & 1) == 0 ); // must be even
|
|
||||||
|
|
||||||
int const gain = this->gain;
|
|
||||||
int const bass = this->bass;
|
|
||||||
chan_t* c = &ch [2];
|
|
||||||
do
|
|
||||||
{
|
|
||||||
// cache in registers
|
|
||||||
int sum = (--c)->sum;
|
|
||||||
int pp1 = c->pp1;
|
|
||||||
int p1 = c->p1;
|
|
||||||
|
|
||||||
for ( int i = 0; i < count; i += 2 )
|
|
||||||
{
|
|
||||||
// Low-pass filter (two point FIR with coeffs 0.25, 0.75)
|
|
||||||
int f = io [i] + p1;
|
|
||||||
p1 = io [i] * 3;
|
|
||||||
|
|
||||||
// High-pass filter ("leaky integrator")
|
|
||||||
int delta = f - pp1;
|
|
||||||
pp1 = f;
|
|
||||||
int s = sum >> (gain_bits + 2);
|
|
||||||
sum += (delta * gain) - (sum >> bass);
|
|
||||||
|
|
||||||
// Clamp to 16 bits
|
|
||||||
if ( (short) s != s )
|
|
||||||
s = (s >> 31) ^ 0x7FFF;
|
|
||||||
|
|
||||||
io [i] = (short) s;
|
|
||||||
}
|
|
||||||
|
|
||||||
c->p1 = p1;
|
|
||||||
c->pp1 = pp1;
|
|
||||||
c->sum = sum;
|
|
||||||
++io;
|
|
||||||
}
|
|
||||||
while ( c != ch );
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
// Simple low-pass and high-pass filter to better match sound output of a SNES
|
|
||||||
|
|
||||||
// snes_spc 0.9.0
|
|
||||||
#ifndef SPC_FILTER_H
|
|
||||||
#define SPC_FILTER_H
|
|
||||||
|
|
||||||
#include "blargg_common.h"
|
|
||||||
|
|
||||||
struct SPC_Filter {
|
|
||||||
public:
|
|
||||||
|
|
||||||
// Filters count samples of stereo sound in place. Count must be a multiple of 2.
|
|
||||||
typedef short sample_t;
|
|
||||||
void run( sample_t* io, int count );
|
|
||||||
|
|
||||||
// Optional features
|
|
||||||
|
|
||||||
// Clears filter to silence
|
|
||||||
void clear();
|
|
||||||
|
|
||||||
// Sets gain (volume), where gain_unit is normal. Gains greater than gain_unit
|
|
||||||
// are fine, since output is clamped to 16-bit sample range.
|
|
||||||
enum { gain_unit = 0x100 };
|
|
||||||
void set_gain( int gain );
|
|
||||||
|
|
||||||
// Sets amount of bass (logarithmic scale)
|
|
||||||
enum { bass_none = 0 };
|
|
||||||
enum { bass_norm = 8 }; // normal amount
|
|
||||||
enum { bass_max = 31 };
|
|
||||||
void set_bass( int bass );
|
|
||||||
|
|
||||||
public:
|
|
||||||
SPC_Filter();
|
|
||||||
BLARGG_DISABLE_NOTHROW
|
|
||||||
private:
|
|
||||||
enum { gain_bits = 8 };
|
|
||||||
int gain;
|
|
||||||
int bass;
|
|
||||||
struct chan_t { int p1, pp1, sum; };
|
|
||||||
chan_t ch [2];
|
|
||||||
};
|
|
||||||
|
|
||||||
inline void SPC_Filter::set_gain( int g ) { gain = g; }
|
|
||||||
|
|
||||||
inline void SPC_Filter::set_bass( int b ) { bass = b; }
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,633 +0,0 @@
|
|||||||
/**********************************************************************************
|
|
||||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
|
||||||
|
|
||||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
|
||||||
Jerremy Koot (jkoot@snes9x.com)
|
|
||||||
|
|
||||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
|
||||||
|
|
||||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
|
||||||
|
|
||||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
|
||||||
|
|
||||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
|
||||||
|
|
||||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
|
||||||
Kris Bleakley (codeviolation@hotmail.com)
|
|
||||||
|
|
||||||
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
|
|
||||||
Nach (n-a-c-h@users.sourceforge.net),
|
|
||||||
zones (kasumitokoduck@yahoo.com)
|
|
||||||
|
|
||||||
(c) Copyright 2006 - 2007 nitsuja
|
|
||||||
|
|
||||||
|
|
||||||
BS-X C emulator code
|
|
||||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
|
||||||
zones
|
|
||||||
|
|
||||||
C4 x86 assembler and some C emulation code
|
|
||||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
|
||||||
Nach,
|
|
||||||
zsKnight (zsknight@zsnes.com)
|
|
||||||
|
|
||||||
C4 C++ code
|
|
||||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
|
||||||
Nach
|
|
||||||
|
|
||||||
DSP-1 emulator code
|
|
||||||
(c) Copyright 1998 - 2006 _Demo_,
|
|
||||||
Andreas Naive (andreasnaive@gmail.com)
|
|
||||||
Gary Henderson,
|
|
||||||
Ivar (ivar@snes9x.com),
|
|
||||||
John Weidman,
|
|
||||||
Kris Bleakley,
|
|
||||||
Matthew Kendora,
|
|
||||||
Nach,
|
|
||||||
neviksti (neviksti@hotmail.com)
|
|
||||||
|
|
||||||
DSP-2 emulator code
|
|
||||||
(c) Copyright 2003 John Weidman,
|
|
||||||
Kris Bleakley,
|
|
||||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
|
||||||
Matthew Kendora,
|
|
||||||
neviksti
|
|
||||||
|
|
||||||
|
|
||||||
DSP-3 emulator code
|
|
||||||
(c) Copyright 2003 - 2006 John Weidman,
|
|
||||||
Kris Bleakley,
|
|
||||||
Lancer,
|
|
||||||
z80 gaiden
|
|
||||||
|
|
||||||
DSP-4 emulator code
|
|
||||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
|
||||||
John Weidman,
|
|
||||||
Kris Bleakley,
|
|
||||||
Nach,
|
|
||||||
z80 gaiden
|
|
||||||
|
|
||||||
OBC1 emulator code
|
|
||||||
(c) Copyright 2001 - 2004 zsKnight,
|
|
||||||
pagefault (pagefault@zsnes.com),
|
|
||||||
Kris Bleakley,
|
|
||||||
Ported from x86 assembler to C by sanmaiwashi
|
|
||||||
|
|
||||||
SPC7110 and RTC C++ emulator code
|
|
||||||
(c) Copyright 2002 Matthew Kendora with research by
|
|
||||||
zsKnight,
|
|
||||||
John Weidman,
|
|
||||||
Dark Force
|
|
||||||
|
|
||||||
S-DD1 C emulator code
|
|
||||||
(c) Copyright 2003 Brad Jorsch with research by
|
|
||||||
Andreas Naive,
|
|
||||||
John Weidman
|
|
||||||
|
|
||||||
S-RTC C emulator code
|
|
||||||
(c) Copyright 2001-2006 byuu,
|
|
||||||
John Weidman
|
|
||||||
|
|
||||||
ST010 C++ emulator code
|
|
||||||
(c) Copyright 2003 Feather,
|
|
||||||
John Weidman,
|
|
||||||
Kris Bleakley,
|
|
||||||
Matthew Kendora
|
|
||||||
|
|
||||||
Super FX x86 assembler emulator code
|
|
||||||
(c) Copyright 1998 - 2003 _Demo_,
|
|
||||||
pagefault,
|
|
||||||
zsKnight,
|
|
||||||
|
|
||||||
Super FX C emulator code
|
|
||||||
(c) Copyright 1997 - 1999 Ivar,
|
|
||||||
Gary Henderson,
|
|
||||||
John Weidman
|
|
||||||
|
|
||||||
Sound DSP emulator code is derived from SNEeSe and OpenSPC:
|
|
||||||
(c) Copyright 1998 - 2003 Brad Martin
|
|
||||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
|
||||||
|
|
||||||
SH assembler code partly based on x86 assembler code
|
|
||||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
|
||||||
|
|
||||||
2xSaI filter
|
|
||||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
|
||||||
|
|
||||||
HQ2x, HQ3x, HQ4x filters
|
|
||||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
|
||||||
|
|
||||||
Win32 GUI code
|
|
||||||
(c) Copyright 2003 - 2006 blip,
|
|
||||||
funkyass,
|
|
||||||
Matthew Kendora,
|
|
||||||
Nach,
|
|
||||||
nitsuja
|
|
||||||
|
|
||||||
Mac OS GUI code
|
|
||||||
(c) Copyright 1998 - 2001 John Stiles
|
|
||||||
(c) Copyright 2001 - 2007 zones
|
|
||||||
|
|
||||||
|
|
||||||
Specific ports contains the works of other authors. See headers in
|
|
||||||
individual files.
|
|
||||||
|
|
||||||
|
|
||||||
Snes9x homepage: http://www.snes9x.com
|
|
||||||
|
|
||||||
Permission to use, copy, modify and/or 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 or it's derivatives.
|
|
||||||
|
|
||||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
|
||||||
seek permission of the copyright holders first. Commercial use includes,
|
|
||||||
but is not limited to, charging money for Snes9x or software derived from
|
|
||||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
|
||||||
using Snes9x as a promotion for your commercial product.
|
|
||||||
|
|
||||||
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 <math.h>
|
|
||||||
#include "snes9x.h"
|
|
||||||
#include "apu.h"
|
|
||||||
#include "snapshot.h"
|
|
||||||
#include "display.h"
|
|
||||||
#include "resampler.h"
|
|
||||||
|
|
||||||
#define APU_DEFAULT_INPUT_RATE 32000
|
|
||||||
#define APU_MINIMUM_SAMPLE_COUNT 512
|
|
||||||
#define APU_MINIMUM_SAMPLE_BLOCK 128
|
|
||||||
#define APU_NUMERATOR_NTSC 5632
|
|
||||||
#define APU_DENOMINATOR_NTSC 118125
|
|
||||||
#define APU_NUMERATOR_PAL 102400
|
|
||||||
#define APU_DENOMINATOR_PAL 2128137
|
|
||||||
|
|
||||||
SNES_SPC *spc_core = NULL;
|
|
||||||
|
|
||||||
static uint8 APUROM[64] =
|
|
||||||
{
|
|
||||||
0xCD, 0xEF, 0xBD, 0xE8, 0x00, 0xC6, 0x1D, 0xD0,
|
|
||||||
0xFC, 0x8F, 0xAA, 0xF4, 0x8F, 0xBB, 0xF5, 0x78,
|
|
||||||
0xCC, 0xF4, 0xD0, 0xFB, 0x2F, 0x19, 0xEB, 0xF4,
|
|
||||||
0xD0, 0xFC, 0x7E, 0xF4, 0xD0, 0x0B, 0xE4, 0xF5,
|
|
||||||
0xCB, 0xF4, 0xD7, 0x00, 0xFC, 0xD0, 0xF3, 0xAB,
|
|
||||||
0x01, 0x10, 0xEF, 0x7E, 0xF4, 0x10, 0xEB, 0xBA,
|
|
||||||
0xF6, 0xDA, 0x00, 0xBA, 0xF4, 0xC4, 0xF4, 0xDD,
|
|
||||||
0x5D, 0xD0, 0xDB, 0x1F, 0x00, 0x00, 0xC0, 0xFF
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace spc
|
|
||||||
{
|
|
||||||
static apu_callback sa_callback = NULL;
|
|
||||||
static void *extra_data = NULL;
|
|
||||||
|
|
||||||
static bool8 sound_in_sync = TRUE;
|
|
||||||
static bool8 sound_enabled = FALSE;
|
|
||||||
|
|
||||||
static int buffer_size;
|
|
||||||
static int lag_master = 0;
|
|
||||||
static int lag = 0;
|
|
||||||
|
|
||||||
static uint8 *landing_buffer = NULL;
|
|
||||||
static uint8 *shrink_buffer = NULL;
|
|
||||||
|
|
||||||
static Resampler *resampler = NULL;
|
|
||||||
|
|
||||||
static int32 reference_time;
|
|
||||||
static uint32 remainder;
|
|
||||||
|
|
||||||
static const int32 timing_hack_numerator = SNES_SPC::tempo_unit;
|
|
||||||
static int32 timing_hack_denominator = SNES_SPC::tempo_unit;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void EightBitize (uint8 *, int);
|
|
||||||
static void DeStereo (uint8 *, int);
|
|
||||||
static void ReverseStereo (uint8 *, int);
|
|
||||||
static void UpdatePlaybackRate (void);
|
|
||||||
static void from_apu_to_state (uint8 **, void *, size_t);
|
|
||||||
static void to_apu_from_state (uint8 **, void *, size_t);
|
|
||||||
static void SPCSnapshotCallback (void);
|
|
||||||
static inline int S9xAPUGetClock (int32);
|
|
||||||
static inline int S9xAPUGetClockRemainder (int32);
|
|
||||||
|
|
||||||
|
|
||||||
static void EightBitize (uint8 *buffer, int sample_count)
|
|
||||||
{
|
|
||||||
uint8 *buf8 = (uint8 *) buffer;
|
|
||||||
int16 *buf16 = (int16 *) buffer;
|
|
||||||
|
|
||||||
for (int i = 0; i < sample_count; i++)
|
|
||||||
buf8[i] = (uint8) ((buf16[i] / 256) + 128);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DeStereo (uint8 *buffer, int sample_count)
|
|
||||||
{
|
|
||||||
int16 *buf = (int16 *) buffer;
|
|
||||||
int32 s1, s2;
|
|
||||||
|
|
||||||
for (int i = 0; i < sample_count >> 1; i++)
|
|
||||||
{
|
|
||||||
s1 = (int32) buf[2 * i];
|
|
||||||
s2 = (int32) buf[2 * i + 1];
|
|
||||||
buf[i] = (int16) ((s1 + s2) >> 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ReverseStereo (uint8 *src_buffer, int sample_count)
|
|
||||||
{
|
|
||||||
int16 *buffer = (int16 *) src_buffer;
|
|
||||||
|
|
||||||
for (int i = 0; i < sample_count; i += 2)
|
|
||||||
{
|
|
||||||
buffer[i + 1] ^= buffer[i];
|
|
||||||
buffer[i] ^= buffer[i + 1];
|
|
||||||
buffer[i + 1] ^= buffer[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool8 S9xMixSamples (uint8 *buffer, int sample_count)
|
|
||||||
{
|
|
||||||
static int shrink_buffer_size = -1;
|
|
||||||
uint8 *dest;
|
|
||||||
|
|
||||||
if (!Settings.SixteenBitSound || !Settings.Stereo)
|
|
||||||
{
|
|
||||||
/* We still need both stereo samples for generating the mono sample */
|
|
||||||
if (!Settings.Stereo)
|
|
||||||
sample_count <<= 1;
|
|
||||||
|
|
||||||
/* We still have to generate 16-bit samples for bit-dropping, too */
|
|
||||||
if (shrink_buffer_size < (sample_count << 1))
|
|
||||||
{
|
|
||||||
delete[] spc::shrink_buffer;
|
|
||||||
spc::shrink_buffer = new uint8[sample_count << 1];
|
|
||||||
shrink_buffer_size = sample_count << 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
dest = spc::shrink_buffer;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
dest = buffer;
|
|
||||||
|
|
||||||
if (Settings.Mute)
|
|
||||||
{
|
|
||||||
memset(dest, 0, sample_count << 1);
|
|
||||||
spc::resampler->clear();
|
|
||||||
|
|
||||||
return (FALSE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (spc::resampler->avail() >= (sample_count + spc::lag))
|
|
||||||
{
|
|
||||||
spc::resampler->read((short *) dest, sample_count);
|
|
||||||
if (spc::lag == spc::lag_master)
|
|
||||||
spc::lag = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
memset(buffer, (Settings.SixteenBitSound ? 0 : 128), (sample_count << (Settings.SixteenBitSound ? 1 : 0)) >> (Settings.Stereo ? 0 : 1));
|
|
||||||
if (spc::lag == 0)
|
|
||||||
spc::lag = spc::lag_master;
|
|
||||||
|
|
||||||
return (FALSE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Settings.ReverseStereo && Settings.Stereo)
|
|
||||||
ReverseStereo(dest, sample_count);
|
|
||||||
|
|
||||||
if (!Settings.Stereo || !Settings.SixteenBitSound)
|
|
||||||
{
|
|
||||||
if (!Settings.Stereo)
|
|
||||||
{
|
|
||||||
DeStereo(dest, sample_count);
|
|
||||||
sample_count >>= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Settings.SixteenBitSound)
|
|
||||||
EightBitize(dest, sample_count);
|
|
||||||
|
|
||||||
memcpy(buffer, dest, (sample_count << (Settings.SixteenBitSound ? 1 : 0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
return (TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
int S9xGetSampleCount (void)
|
|
||||||
{
|
|
||||||
return (spc::resampler->avail());
|
|
||||||
}
|
|
||||||
|
|
||||||
void S9xFinalizeSamples (void)
|
|
||||||
{
|
|
||||||
if (!Settings.Mute)
|
|
||||||
{
|
|
||||||
if (!spc::resampler->push((short *) spc::landing_buffer, spc_core->sample_count()))
|
|
||||||
{
|
|
||||||
/* We weren't able to process the entire buffer. Potential overrun. */
|
|
||||||
spc::sound_in_sync = FALSE;
|
|
||||||
|
|
||||||
if (Settings.SoundSync && !Settings.TurboMode)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Settings.SoundSync || Settings.TurboMode || Settings.Mute)
|
|
||||||
spc::sound_in_sync = TRUE;
|
|
||||||
else
|
|
||||||
if (spc::resampler->space_empty() >= spc::resampler->space_filled())
|
|
||||||
spc::sound_in_sync = TRUE;
|
|
||||||
else
|
|
||||||
spc::sound_in_sync = FALSE;
|
|
||||||
|
|
||||||
spc_core->set_output((SNES_SPC::sample_t *) spc::landing_buffer, spc::buffer_size >> 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void S9xLandSamples (void)
|
|
||||||
{
|
|
||||||
if (spc::sa_callback != NULL)
|
|
||||||
spc::sa_callback(spc::extra_data);
|
|
||||||
else
|
|
||||||
S9xFinalizeSamples();
|
|
||||||
}
|
|
||||||
|
|
||||||
void S9xClearSamples (void)
|
|
||||||
{
|
|
||||||
spc::resampler->clear();
|
|
||||||
spc::lag = spc::lag_master;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool8 S9xSyncSound (void)
|
|
||||||
{
|
|
||||||
if (!Settings.SoundSync || spc::sound_in_sync)
|
|
||||||
return (TRUE);
|
|
||||||
|
|
||||||
S9xLandSamples();
|
|
||||||
|
|
||||||
return (spc::sound_in_sync);
|
|
||||||
}
|
|
||||||
|
|
||||||
void S9xSetSamplesAvailableCallback (apu_callback callback, void *data)
|
|
||||||
{
|
|
||||||
spc::sa_callback = callback;
|
|
||||||
spc::extra_data = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void UpdatePlaybackRate (void)
|
|
||||||
{
|
|
||||||
if (Settings.SoundInputRate == 0)
|
|
||||||
Settings.SoundInputRate = APU_DEFAULT_INPUT_RATE;
|
|
||||||
|
|
||||||
double time_ratio = (double) Settings.SoundInputRate * spc::timing_hack_numerator / (Settings.SoundPlaybackRate * spc::timing_hack_denominator);
|
|
||||||
spc::resampler->time_ratio(time_ratio);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool8 S9xInitSound (int sample_count, int lag_sample_count)
|
|
||||||
{
|
|
||||||
// sample_count : buffer size given in samples in one channel
|
|
||||||
// lag_sample_count: allowable time-lag given in samples in one channel
|
|
||||||
|
|
||||||
spc::lag_master = lag_sample_count;
|
|
||||||
if (Settings.Stereo)
|
|
||||||
spc::lag_master <<= 1;
|
|
||||||
spc::lag = spc::lag_master;
|
|
||||||
|
|
||||||
if (sample_count < APU_MINIMUM_SAMPLE_COUNT)
|
|
||||||
sample_count = APU_MINIMUM_SAMPLE_COUNT;
|
|
||||||
|
|
||||||
spc::buffer_size = sample_count;
|
|
||||||
if (Settings.Stereo)
|
|
||||||
spc::buffer_size <<= 1;
|
|
||||||
if (Settings.SixteenBitSound)
|
|
||||||
spc::buffer_size <<= 1;
|
|
||||||
|
|
||||||
if (spc::landing_buffer)
|
|
||||||
delete[] spc::landing_buffer;
|
|
||||||
spc::landing_buffer = new uint8[spc::buffer_size * 2];
|
|
||||||
if (!spc::landing_buffer)
|
|
||||||
return (FALSE);
|
|
||||||
|
|
||||||
/* The resampler and spc unit use samples (16-bit short) as
|
|
||||||
arguments. Use 2x in the resampler for buffer leveling with SoundSync */
|
|
||||||
if (!spc::resampler)
|
|
||||||
{
|
|
||||||
spc::resampler = new Resampler(spc::buffer_size >> (Settings.SoundSync ? 0 : 1));
|
|
||||||
if (!spc::resampler)
|
|
||||||
{
|
|
||||||
delete[] spc::landing_buffer;
|
|
||||||
return (FALSE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
spc::resampler->resize(spc::buffer_size >> (Settings.SoundSync ? 0 : 1));
|
|
||||||
|
|
||||||
spc_core->set_output((SNES_SPC::sample_t *) spc::landing_buffer, spc::buffer_size >> 1);
|
|
||||||
|
|
||||||
UpdatePlaybackRate();
|
|
||||||
|
|
||||||
spc::sound_enabled = S9xOpenSoundDevice(spc::buffer_size);
|
|
||||||
|
|
||||||
return (spc::sound_enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
void S9xSetSoundControl (uint8 voice_switch)
|
|
||||||
{
|
|
||||||
spc_core->dsp_set_stereo_switch(voice_switch << 8 | voice_switch);
|
|
||||||
}
|
|
||||||
|
|
||||||
void S9xSetSoundMute (bool8 mute)
|
|
||||||
{
|
|
||||||
Settings.Mute = mute;
|
|
||||||
if (!spc::sound_enabled)
|
|
||||||
Settings.Mute = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void S9xDumpSPCSnapshot (void)
|
|
||||||
{
|
|
||||||
spc_core->dsp_dump_spc_snapshot();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void SPCSnapshotCallback (void)
|
|
||||||
{
|
|
||||||
S9xSPCDump(S9xGetFilenameInc((".spc"), SPC_DIR));
|
|
||||||
printf("Dumped key-on triggered spc snapshot.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool8 S9xInitAPU (void)
|
|
||||||
{
|
|
||||||
spc_core = new SNES_SPC;
|
|
||||||
if (!spc_core)
|
|
||||||
return (FALSE);
|
|
||||||
|
|
||||||
spc_core->init();
|
|
||||||
spc_core->init_rom(APUROM);
|
|
||||||
|
|
||||||
spc_core->dsp_set_spc_snapshot_callback(SPCSnapshotCallback);
|
|
||||||
|
|
||||||
spc::landing_buffer = NULL;
|
|
||||||
spc::shrink_buffer = NULL;
|
|
||||||
spc::resampler = NULL;
|
|
||||||
|
|
||||||
return (TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void S9xDeinitAPU (void)
|
|
||||||
{
|
|
||||||
if (spc_core)
|
|
||||||
{
|
|
||||||
delete spc_core;
|
|
||||||
spc_core = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (spc::resampler)
|
|
||||||
{
|
|
||||||
delete spc::resampler;
|
|
||||||
spc::resampler = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (spc::landing_buffer)
|
|
||||||
{
|
|
||||||
delete[] spc::landing_buffer;
|
|
||||||
spc::landing_buffer = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (spc::shrink_buffer)
|
|
||||||
{
|
|
||||||
delete[] spc::shrink_buffer;
|
|
||||||
spc::shrink_buffer = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int S9xAPUGetClock (int32 cpucycles)
|
|
||||||
{
|
|
||||||
if (Settings.PAL)
|
|
||||||
return floor((double) APU_NUMERATOR_PAL * spc::timing_hack_numerator * (cpucycles - spc::reference_time) + spc::remainder) /
|
|
||||||
(APU_DENOMINATOR_PAL * spc::timing_hack_denominator);
|
|
||||||
else
|
|
||||||
return (APU_NUMERATOR_NTSC * spc::timing_hack_numerator * (cpucycles - spc::reference_time) + spc::remainder) /
|
|
||||||
(APU_DENOMINATOR_NTSC * spc::timing_hack_denominator);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int S9xAPUGetClockRemainder (int32 cpucycles)
|
|
||||||
{
|
|
||||||
if (Settings.PAL)
|
|
||||||
return fmod ((double) APU_NUMERATOR_PAL * spc::timing_hack_numerator * (cpucycles - spc::reference_time) + spc::remainder,
|
|
||||||
APU_DENOMINATOR_PAL * spc::timing_hack_denominator);
|
|
||||||
else
|
|
||||||
return (APU_NUMERATOR_NTSC * spc::timing_hack_numerator * (cpucycles - spc::reference_time) + spc::remainder) %
|
|
||||||
(APU_DENOMINATOR_NTSC * spc::timing_hack_denominator);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8 S9xAPUReadPort (int port)
|
|
||||||
{
|
|
||||||
return ((uint8) spc_core->read_port(S9xAPUGetClock(CPU.Cycles), port));
|
|
||||||
}
|
|
||||||
|
|
||||||
void S9xAPUWritePort (int port, uint8 byte)
|
|
||||||
{
|
|
||||||
spc_core->write_port(S9xAPUGetClock(CPU.Cycles), port, byte);
|
|
||||||
}
|
|
||||||
|
|
||||||
void S9xAPUSetReferenceTime (int32 cpucycles)
|
|
||||||
{
|
|
||||||
spc::reference_time = cpucycles;
|
|
||||||
}
|
|
||||||
|
|
||||||
void S9xAPUExecute (void)
|
|
||||||
{
|
|
||||||
/* Accumulate partial APU cycles */
|
|
||||||
spc_core->end_frame(S9xAPUGetClock(CPU.Cycles));
|
|
||||||
|
|
||||||
spc::remainder = S9xAPUGetClockRemainder(CPU.Cycles);
|
|
||||||
|
|
||||||
S9xAPUSetReferenceTime(CPU.Cycles);
|
|
||||||
}
|
|
||||||
|
|
||||||
void S9xAPUEndScanline (void)
|
|
||||||
{
|
|
||||||
S9xAPUExecute();
|
|
||||||
|
|
||||||
if (spc_core->sample_count() >= APU_MINIMUM_SAMPLE_BLOCK || !spc::sound_in_sync)
|
|
||||||
S9xLandSamples();
|
|
||||||
}
|
|
||||||
|
|
||||||
void S9xAPUTimingSetSpeedup (int ticks)
|
|
||||||
{
|
|
||||||
if (ticks != 0)
|
|
||||||
printf("APU speedup hack: %d\n", ticks);
|
|
||||||
|
|
||||||
spc_core->set_tempo(SNES_SPC::tempo_unit - ticks);
|
|
||||||
|
|
||||||
spc::timing_hack_denominator = SNES_SPC::tempo_unit - ticks;
|
|
||||||
|
|
||||||
UpdatePlaybackRate();
|
|
||||||
}
|
|
||||||
|
|
||||||
void S9xResetAPU (void)
|
|
||||||
{
|
|
||||||
spc::reference_time = 0;
|
|
||||||
spc::remainder = 0;
|
|
||||||
spc_core->reset();
|
|
||||||
spc_core->set_output((SNES_SPC::sample_t *) spc::landing_buffer, spc::buffer_size >> 1);
|
|
||||||
|
|
||||||
spc::resampler->clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void S9xSoftResetAPU (void)
|
|
||||||
{
|
|
||||||
spc::reference_time = 0;
|
|
||||||
spc::remainder = 0;
|
|
||||||
spc_core->soft_reset();
|
|
||||||
spc_core->set_output((SNES_SPC::sample_t *) spc::landing_buffer, spc::buffer_size >> 1);
|
|
||||||
|
|
||||||
spc::resampler->clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void from_apu_to_state (uint8 **buf, void *var, size_t size)
|
|
||||||
{
|
|
||||||
memcpy(*buf, var, size);
|
|
||||||
*buf += size;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void to_apu_from_state (uint8 **buf, void *var, size_t size)
|
|
||||||
{
|
|
||||||
memcpy(var, *buf, size);
|
|
||||||
*buf += size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void S9xAPUSaveState (uint8 *block)
|
|
||||||
{
|
|
||||||
uint8 *ptr = block;
|
|
||||||
|
|
||||||
spc_core->copy_state(&ptr, from_apu_to_state);
|
|
||||||
|
|
||||||
SET_LE32(ptr, spc::reference_time);
|
|
||||||
ptr += sizeof(int32);
|
|
||||||
SET_LE32(ptr, spc::remainder);
|
|
||||||
}
|
|
||||||
|
|
||||||
void S9xAPULoadState (uint8 *block)
|
|
||||||
{
|
|
||||||
uint8 *ptr = block;
|
|
||||||
|
|
||||||
S9xResetAPU();
|
|
||||||
|
|
||||||
spc_core->copy_state(&ptr, to_apu_from_state);
|
|
||||||
|
|
||||||
spc::reference_time = GET_LE32(ptr);
|
|
||||||
ptr += sizeof(int32);
|
|
||||||
spc::remainder = GET_LE32(ptr);
|
|
||||||
}
|
|
@ -1,187 +0,0 @@
|
|||||||
// Sets up common environment for Shay Green's libraries.
|
|
||||||
// To change configuration options, modify blargg_config.h, not this file.
|
|
||||||
|
|
||||||
// snes_spc 0.9.0
|
|
||||||
#ifndef BLARGG_COMMON_H
|
|
||||||
#define BLARGG_COMMON_H
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#undef BLARGG_COMMON_H
|
|
||||||
// allow blargg_config.h to #include blargg_common.h
|
|
||||||
#include "blargg_config.h"
|
|
||||||
#ifndef BLARGG_COMMON_H
|
|
||||||
#define BLARGG_COMMON_H
|
|
||||||
|
|
||||||
// BLARGG_RESTRICT: equivalent to restrict, where supported
|
|
||||||
#if defined (__GNUC__) || _MSC_VER >= 1100
|
|
||||||
#define BLARGG_RESTRICT __restrict
|
|
||||||
#else
|
|
||||||
#define BLARGG_RESTRICT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// STATIC_CAST(T,expr): Used in place of static_cast<T> (expr)
|
|
||||||
#ifndef STATIC_CAST
|
|
||||||
#define STATIC_CAST(T,expr) ((T) (expr))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// blargg_err_t (0 on success, otherwise error string)
|
|
||||||
#ifndef blargg_err_t
|
|
||||||
typedef const char* blargg_err_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// blargg_vector - very lightweight vector of POD types (no constructor/destructor)
|
|
||||||
template<class T>
|
|
||||||
class blargg_vector {
|
|
||||||
T* begin_;
|
|
||||||
size_t size_;
|
|
||||||
public:
|
|
||||||
blargg_vector() : begin_( 0 ), size_( 0 ) { }
|
|
||||||
~blargg_vector() { free( begin_ ); }
|
|
||||||
size_t size() const { return size_; }
|
|
||||||
T* begin() const { return begin_; }
|
|
||||||
T* end() const { return begin_ + size_; }
|
|
||||||
blargg_err_t resize( size_t n )
|
|
||||||
{
|
|
||||||
// TODO: blargg_common.cpp to hold this as an outline function, ugh
|
|
||||||
void* p = realloc( begin_, n * sizeof (T) );
|
|
||||||
if ( p )
|
|
||||||
begin_ = (T*) p;
|
|
||||||
else if ( n > size_ ) // realloc failure only a problem if expanding
|
|
||||||
return "Out of memory";
|
|
||||||
size_ = n;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
void clear() { void* p = begin_; begin_ = 0; size_ = 0; free( p ); }
|
|
||||||
T& operator [] ( size_t n ) const
|
|
||||||
{
|
|
||||||
assert( n <= size_ ); // <= to allow past-the-end value
|
|
||||||
return begin_ [n];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifndef BLARGG_DISABLE_NOTHROW
|
|
||||||
// throw spec mandatory in ISO C++ if operator new can return NULL
|
|
||||||
#if __cplusplus >= 199711 || defined (__GNUC__)
|
|
||||||
#define BLARGG_THROWS( spec ) throw spec
|
|
||||||
#else
|
|
||||||
#define BLARGG_THROWS( spec )
|
|
||||||
#endif
|
|
||||||
#define BLARGG_DISABLE_NOTHROW \
|
|
||||||
void* operator new ( size_t s ) BLARGG_THROWS(()) { return malloc( s ); }\
|
|
||||||
void operator delete ( void* p ) { free( p ); }
|
|
||||||
#define BLARGG_NEW new
|
|
||||||
#else
|
|
||||||
#include <new>
|
|
||||||
#define BLARGG_NEW new (std::nothrow)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// BLARGG_4CHAR('a','b','c','d') = 'abcd' (four character integer constant)
|
|
||||||
#define BLARGG_4CHAR( a, b, c, d ) \
|
|
||||||
((a&0xFF)*0x1000000L + (b&0xFF)*0x10000L + (c&0xFF)*0x100L + (d&0xFF))
|
|
||||||
|
|
||||||
// BOOST_STATIC_ASSERT( expr ): Generates compile error if expr is 0.
|
|
||||||
#ifndef BOOST_STATIC_ASSERT
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
// MSVC6 (_MSC_VER < 1300) fails for use of __LINE__ when /Zl is specified
|
|
||||||
#define BOOST_STATIC_ASSERT( expr ) \
|
|
||||||
void blargg_failed_( int (*arg) [2 / (int) !!(expr) - 1] )
|
|
||||||
#else
|
|
||||||
// Some other compilers fail when declaring same function multiple times in class,
|
|
||||||
// so differentiate them by line
|
|
||||||
#define BOOST_STATIC_ASSERT( expr ) \
|
|
||||||
void blargg_failed_( int (*arg) [2 / !!(expr) - 1] [__LINE__] )
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// BLARGG_COMPILER_HAS_BOOL: If 0, provides bool support for old compiler. If 1,
|
|
||||||
// compiler is assumed to support bool. If undefined, availability is determined.
|
|
||||||
#ifndef BLARGG_COMPILER_HAS_BOOL
|
|
||||||
#if defined (__MWERKS__)
|
|
||||||
#if !__option(bool)
|
|
||||||
#define BLARGG_COMPILER_HAS_BOOL 0
|
|
||||||
#endif
|
|
||||||
#elif defined (_MSC_VER)
|
|
||||||
#if _MSC_VER < 1100
|
|
||||||
#define BLARGG_COMPILER_HAS_BOOL 0
|
|
||||||
#endif
|
|
||||||
#elif defined (__GNUC__)
|
|
||||||
// supports bool
|
|
||||||
#elif __cplusplus < 199711
|
|
||||||
#define BLARGG_COMPILER_HAS_BOOL 0
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#if defined (BLARGG_COMPILER_HAS_BOOL) && !BLARGG_COMPILER_HAS_BOOL
|
|
||||||
// If you get errors here, modify your blargg_config.h file
|
|
||||||
typedef int bool;
|
|
||||||
const bool true = 1;
|
|
||||||
const bool false = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// blargg_long/blargg_ulong = at least 32 bits, int if it's big enough
|
|
||||||
|
|
||||||
#if INT_MAX < 0x7FFFFFFF || LONG_MAX == 0x7FFFFFFF
|
|
||||||
typedef long blargg_long;
|
|
||||||
#else
|
|
||||||
typedef int blargg_long;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if UINT_MAX < 0xFFFFFFFF || ULONG_MAX == 0xFFFFFFFF
|
|
||||||
typedef unsigned long blargg_ulong;
|
|
||||||
#else
|
|
||||||
typedef unsigned blargg_ulong;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// BOOST::int8_t etc.
|
|
||||||
|
|
||||||
// HAVE_STDINT_H: If defined, use <stdint.h> for int8_t etc.
|
|
||||||
#if defined (HAVE_STDINT_H)
|
|
||||||
#include <stdint.h>
|
|
||||||
#define BOOST
|
|
||||||
|
|
||||||
// HAVE_INTTYPES_H: If defined, use <stdint.h> for int8_t etc.
|
|
||||||
#elif defined (HAVE_INTTYPES_H)
|
|
||||||
#include <inttypes.h>
|
|
||||||
#define BOOST
|
|
||||||
|
|
||||||
#else
|
|
||||||
struct BOOST
|
|
||||||
{
|
|
||||||
#if UCHAR_MAX == 0xFF && SCHAR_MAX == 0x7F
|
|
||||||
typedef signed char int8_t;
|
|
||||||
typedef unsigned char uint8_t;
|
|
||||||
#else
|
|
||||||
// No suitable 8-bit type available
|
|
||||||
typedef struct see_blargg_common_h int8_t;
|
|
||||||
typedef struct see_blargg_common_h uint8_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if USHRT_MAX == 0xFFFF
|
|
||||||
typedef short int16_t;
|
|
||||||
typedef unsigned short uint16_t;
|
|
||||||
#else
|
|
||||||
// No suitable 16-bit type available
|
|
||||||
typedef struct see_blargg_common_h int16_t;
|
|
||||||
typedef struct see_blargg_common_h uint16_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if ULONG_MAX == 0xFFFFFFFF
|
|
||||||
typedef long int32_t;
|
|
||||||
typedef unsigned long uint32_t;
|
|
||||||
#elif UINT_MAX == 0xFFFFFFFF
|
|
||||||
typedef int int32_t;
|
|
||||||
typedef unsigned int uint32_t;
|
|
||||||
#else
|
|
||||||
// No suitable 32-bit type available
|
|
||||||
typedef struct see_blargg_common_h int32_t;
|
|
||||||
typedef struct see_blargg_common_h uint32_t;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif
|
|
@ -1,24 +0,0 @@
|
|||||||
// snes_spc 0.9.0 user configuration file. Don't replace when updating library.
|
|
||||||
|
|
||||||
// snes_spc 0.9.0
|
|
||||||
#ifndef BLARGG_CONFIG_H
|
|
||||||
#define BLARGG_CONFIG_H
|
|
||||||
|
|
||||||
// Uncomment to disable debugging checks
|
|
||||||
//#define NDEBUG 1
|
|
||||||
|
|
||||||
// Uncomment to enable platform-specific (and possibly non-portable) optimizations
|
|
||||||
//#define BLARGG_NONPORTABLE 1
|
|
||||||
|
|
||||||
// Uncomment if automatic byte-order determination doesn't work
|
|
||||||
//#define BLARGG_BIG_ENDIAN 1
|
|
||||||
|
|
||||||
// Uncomment if you get errors in the bool section of blargg_common.h
|
|
||||||
//#define BLARGG_COMPILER_HAS_BOOL 1
|
|
||||||
|
|
||||||
// Use standard config.h if present
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,185 +0,0 @@
|
|||||||
// CPU Byte Order Utilities
|
|
||||||
|
|
||||||
// snes_spc 0.9.0
|
|
||||||
#ifndef BLARGG_ENDIAN
|
|
||||||
#define BLARGG_ENDIAN
|
|
||||||
|
|
||||||
#include "blargg_common.h"
|
|
||||||
|
|
||||||
// BLARGG_CPU_CISC: Defined if CPU has very few general-purpose registers (< 16)
|
|
||||||
#if defined (_M_IX86) || defined (_M_IA64) || defined (__i486__) || \
|
|
||||||
defined (__x86_64__) || defined (__ia64__) || defined (__i386__)
|
|
||||||
#define BLARGG_CPU_X86 1
|
|
||||||
#define BLARGG_CPU_CISC 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined (__powerpc__) || defined (__ppc__) || defined (__POWERPC__) || defined (__powerc)
|
|
||||||
#define BLARGG_CPU_POWERPC 1
|
|
||||||
#define BLARGG_CPU_RISC 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// BLARGG_BIG_ENDIAN, BLARGG_LITTLE_ENDIAN: Determined automatically, otherwise only
|
|
||||||
// one may be #defined to 1. Only needed if something actually depends on byte order.
|
|
||||||
#if !defined (BLARGG_BIG_ENDIAN) && !defined (BLARGG_LITTLE_ENDIAN)
|
|
||||||
#ifdef __GLIBC__
|
|
||||||
// GCC handles this for us
|
|
||||||
#include <endian.h>
|
|
||||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
|
||||||
#define BLARGG_LITTLE_ENDIAN 1
|
|
||||||
#elif __BYTE_ORDER == __BIG_ENDIAN
|
|
||||||
#define BLARGG_BIG_ENDIAN 1
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
|
|
||||||
#if defined (LSB_FIRST) || defined (__LITTLE_ENDIAN__) || BLARGG_CPU_X86 || \
|
|
||||||
(defined (LITTLE_ENDIAN) && LITTLE_ENDIAN+0 != 1234)
|
|
||||||
#define BLARGG_LITTLE_ENDIAN 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined (MSB_FIRST) || defined (__BIG_ENDIAN__) || defined (WORDS_BIGENDIAN) || \
|
|
||||||
defined (__sparc__) || BLARGG_CPU_POWERPC || \
|
|
||||||
(defined (BIG_ENDIAN) && BIG_ENDIAN+0 != 4321)
|
|
||||||
#define BLARGG_BIG_ENDIAN 1
|
|
||||||
#elif !defined (__mips__)
|
|
||||||
// No endian specified; assume little-endian, since it's most common
|
|
||||||
#define BLARGG_LITTLE_ENDIAN 1
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BLARGG_LITTLE_ENDIAN && BLARGG_BIG_ENDIAN
|
|
||||||
#undef BLARGG_LITTLE_ENDIAN
|
|
||||||
#undef BLARGG_BIG_ENDIAN
|
|
||||||
#endif
|
|
||||||
|
|
||||||
inline void blargg_verify_byte_order()
|
|
||||||
{
|
|
||||||
#ifndef NDEBUG
|
|
||||||
#if BLARGG_BIG_ENDIAN
|
|
||||||
volatile int i = 1;
|
|
||||||
assert( *(volatile char*) &i == 0 );
|
|
||||||
#elif BLARGG_LITTLE_ENDIAN
|
|
||||||
volatile int i = 1;
|
|
||||||
assert( *(volatile char*) &i != 0 );
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
inline unsigned get_le16( void const* p )
|
|
||||||
{
|
|
||||||
return (unsigned) ((unsigned char const*) p) [1] << 8 |
|
|
||||||
(unsigned) ((unsigned char const*) p) [0];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline unsigned get_be16( void const* p )
|
|
||||||
{
|
|
||||||
return (unsigned) ((unsigned char const*) p) [0] << 8 |
|
|
||||||
(unsigned) ((unsigned char const*) p) [1];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline blargg_ulong get_le32( void const* p )
|
|
||||||
{
|
|
||||||
return (blargg_ulong) ((unsigned char const*) p) [3] << 24 |
|
|
||||||
(blargg_ulong) ((unsigned char const*) p) [2] << 16 |
|
|
||||||
(blargg_ulong) ((unsigned char const*) p) [1] << 8 |
|
|
||||||
(blargg_ulong) ((unsigned char const*) p) [0];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline blargg_ulong get_be32( void const* p )
|
|
||||||
{
|
|
||||||
return (blargg_ulong) ((unsigned char const*) p) [0] << 24 |
|
|
||||||
(blargg_ulong) ((unsigned char const*) p) [1] << 16 |
|
|
||||||
(blargg_ulong) ((unsigned char const*) p) [2] << 8 |
|
|
||||||
(blargg_ulong) ((unsigned char const*) p) [3];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void set_le16( void* p, unsigned n )
|
|
||||||
{
|
|
||||||
((unsigned char*) p) [1] = (unsigned char) (n >> 8);
|
|
||||||
((unsigned char*) p) [0] = (unsigned char) n;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void set_be16( void* p, unsigned n )
|
|
||||||
{
|
|
||||||
((unsigned char*) p) [0] = (unsigned char) (n >> 8);
|
|
||||||
((unsigned char*) p) [1] = (unsigned char) n;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void set_le32( void* p, blargg_ulong n )
|
|
||||||
{
|
|
||||||
((unsigned char*) p) [0] = (unsigned char) n;
|
|
||||||
((unsigned char*) p) [1] = (unsigned char) (n >> 8);
|
|
||||||
((unsigned char*) p) [2] = (unsigned char) (n >> 16);
|
|
||||||
((unsigned char*) p) [3] = (unsigned char) (n >> 24);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void set_be32( void* p, blargg_ulong n )
|
|
||||||
{
|
|
||||||
((unsigned char*) p) [3] = (unsigned char) n;
|
|
||||||
((unsigned char*) p) [2] = (unsigned char) (n >> 8);
|
|
||||||
((unsigned char*) p) [1] = (unsigned char) (n >> 16);
|
|
||||||
((unsigned char*) p) [0] = (unsigned char) (n >> 24);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if BLARGG_NONPORTABLE
|
|
||||||
// Optimized implementation if byte order is known
|
|
||||||
#if BLARGG_LITTLE_ENDIAN
|
|
||||||
#define GET_LE16( addr ) (*(BOOST::uint16_t*) (addr))
|
|
||||||
#define GET_LE32( addr ) (*(BOOST::uint32_t*) (addr))
|
|
||||||
#define SET_LE16( addr, data ) (void) (*(BOOST::uint16_t*) (addr) = (data))
|
|
||||||
#define SET_LE32( addr, data ) (void) (*(BOOST::uint32_t*) (addr) = (data))
|
|
||||||
#elif BLARGG_BIG_ENDIAN
|
|
||||||
#define GET_BE16( addr ) (*(BOOST::uint16_t*) (addr))
|
|
||||||
#define GET_BE32( addr ) (*(BOOST::uint32_t*) (addr))
|
|
||||||
#define SET_BE16( addr, data ) (void) (*(BOOST::uint16_t*) (addr) = (data))
|
|
||||||
#define SET_BE32( addr, data ) (void) (*(BOOST::uint32_t*) (addr) = (data))
|
|
||||||
|
|
||||||
#if BLARGG_CPU_POWERPC
|
|
||||||
// PowerPC has special byte-reversed instructions
|
|
||||||
#if defined (__MWERKS__)
|
|
||||||
#define GET_LE16( addr ) (__lhbrx( addr, 0 ))
|
|
||||||
#define GET_LE32( addr ) (__lwbrx( addr, 0 ))
|
|
||||||
#define SET_LE16( addr, in ) (__sthbrx( in, addr, 0 ))
|
|
||||||
#define SET_LE32( addr, in ) (__stwbrx( in, addr, 0 ))
|
|
||||||
#elif defined (__GNUC__)
|
|
||||||
#define GET_LE16( addr ) ({unsigned ppc_lhbrx_; asm( "lhbrx %0,0,%1" : "=r" (ppc_lhbrx_) : "r" (addr), "0" (ppc_lhbrx_) ); ppc_lhbrx_;})
|
|
||||||
#define GET_LE32( addr ) ({unsigned ppc_lwbrx_; asm( "lwbrx %0,0,%1" : "=r" (ppc_lwbrx_) : "r" (addr), "0" (ppc_lwbrx_) ); ppc_lwbrx_;})
|
|
||||||
#define SET_LE16( addr, in ) ({asm( "sthbrx %0,0,%1" : : "r" (in), "r" (addr) );})
|
|
||||||
#define SET_LE32( addr, in ) ({asm( "stwbrx %0,0,%1" : : "r" (in), "r" (addr) );})
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef GET_LE16
|
|
||||||
#define GET_LE16( addr ) get_le16( addr )
|
|
||||||
#define SET_LE16( addr, data ) set_le16( addr, data )
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef GET_LE32
|
|
||||||
#define GET_LE32( addr ) get_le32( addr )
|
|
||||||
#define SET_LE32( addr, data ) set_le32( addr, data )
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef GET_BE16
|
|
||||||
#define GET_BE16( addr ) get_be16( addr )
|
|
||||||
#define SET_BE16( addr, data ) set_be16( addr, data )
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef GET_BE32
|
|
||||||
#define GET_BE32( addr ) get_be32( addr )
|
|
||||||
#define SET_BE32( addr, data ) set_be32( addr, data )
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// auto-selecting versions
|
|
||||||
|
|
||||||
inline void set_le( BOOST::uint16_t* p, unsigned n ) { SET_LE16( p, n ); }
|
|
||||||
inline void set_le( BOOST::uint32_t* p, blargg_ulong n ) { SET_LE32( p, n ); }
|
|
||||||
inline void set_be( BOOST::uint16_t* p, unsigned n ) { SET_BE16( p, n ); }
|
|
||||||
inline void set_be( BOOST::uint32_t* p, blargg_ulong n ) { SET_BE32( p, n ); }
|
|
||||||
inline unsigned get_le( BOOST::uint16_t* p ) { return GET_LE16( p ); }
|
|
||||||
inline blargg_ulong get_le( BOOST::uint32_t* p ) { return GET_LE32( p ); }
|
|
||||||
inline unsigned get_be( BOOST::uint16_t* p ) { return GET_BE16( p ); }
|
|
||||||
inline blargg_ulong get_be( BOOST::uint32_t* p ) { return GET_BE32( p ); }
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,100 +0,0 @@
|
|||||||
/* Included at the beginning of library source files, after all other #include lines.
|
|
||||||
Sets up helpful macros and services used in my source code. They don't need
|
|
||||||
module an annoying module prefix on their names since they are defined after
|
|
||||||
all other #include lines. */
|
|
||||||
|
|
||||||
// snes_spc 0.9.0
|
|
||||||
#ifndef BLARGG_SOURCE_H
|
|
||||||
#define BLARGG_SOURCE_H
|
|
||||||
|
|
||||||
// If debugging is enabled, abort program if expr is false. Meant for checking
|
|
||||||
// internal state and consistency. A failed assertion indicates a bug in the module.
|
|
||||||
// void assert( bool expr );
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
// If debugging is enabled and expr is false, abort program. Meant for checking
|
|
||||||
// caller-supplied parameters and operations that are outside the control of the
|
|
||||||
// module. A failed requirement indicates a bug outside the module.
|
|
||||||
// void require( bool expr );
|
|
||||||
#undef require
|
|
||||||
#define require( expr ) assert( expr )
|
|
||||||
|
|
||||||
// Like printf() except output goes to debug log file. Might be defined to do
|
|
||||||
// nothing (not even evaluate its arguments).
|
|
||||||
// void dprintf( const char* format, ... );
|
|
||||||
static inline void blargg_dprintf_( const char*, ... ) { }
|
|
||||||
#undef dprintf
|
|
||||||
#define dprintf (1) ? (void) 0 : blargg_dprintf_
|
|
||||||
|
|
||||||
// If enabled, evaluate expr and if false, make debug log entry with source file
|
|
||||||
// and line. Meant for finding situations that should be examined further, but that
|
|
||||||
// don't indicate a problem. In all cases, execution continues normally.
|
|
||||||
#undef check
|
|
||||||
#define check( expr ) ((void) 0)
|
|
||||||
|
|
||||||
// If expr yields error string, return it from current function, otherwise continue.
|
|
||||||
#undef RETURN_ERR
|
|
||||||
#define RETURN_ERR( expr ) do { \
|
|
||||||
blargg_err_t blargg_return_err_ = (expr); \
|
|
||||||
if ( blargg_return_err_ ) return blargg_return_err_; \
|
|
||||||
} while ( 0 )
|
|
||||||
|
|
||||||
// If ptr is 0, return out of memory error string.
|
|
||||||
#undef CHECK_ALLOC
|
|
||||||
#define CHECK_ALLOC( ptr ) do { if ( (ptr) == 0 ) return "Out of memory"; } while ( 0 )
|
|
||||||
|
|
||||||
// Avoid any macros which evaluate their arguments multiple times
|
|
||||||
#undef min
|
|
||||||
#undef max
|
|
||||||
|
|
||||||
#define DEF_MIN_MAX( type ) \
|
|
||||||
static inline type min( type x, type y ) { if ( x < y ) return x; return y; }\
|
|
||||||
static inline type max( type x, type y ) { if ( y < x ) return x; return y; }
|
|
||||||
|
|
||||||
DEF_MIN_MAX( int )
|
|
||||||
DEF_MIN_MAX( unsigned )
|
|
||||||
DEF_MIN_MAX( long )
|
|
||||||
DEF_MIN_MAX( unsigned long )
|
|
||||||
DEF_MIN_MAX( float )
|
|
||||||
DEF_MIN_MAX( double )
|
|
||||||
|
|
||||||
#undef DEF_MIN_MAX
|
|
||||||
|
|
||||||
/*
|
|
||||||
// using const references generates crappy code, and I am currenly only using these
|
|
||||||
// for built-in types, so they take arguments by value
|
|
||||||
|
|
||||||
// TODO: remove
|
|
||||||
inline int min( int x, int y )
|
|
||||||
template<class T>
|
|
||||||
inline T min( T x, T y )
|
|
||||||
{
|
|
||||||
if ( x < y )
|
|
||||||
return x;
|
|
||||||
return y;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
inline T max( T x, T y )
|
|
||||||
{
|
|
||||||
if ( x < y )
|
|
||||||
return y;
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// TODO: good idea? bad idea?
|
|
||||||
#undef byte
|
|
||||||
#define byte byte_
|
|
||||||
typedef unsigned char byte;
|
|
||||||
|
|
||||||
// deprecated
|
|
||||||
#define BLARGG_CHECK_ALLOC CHECK_ALLOC
|
|
||||||
#define BLARGG_RETURN_ERR RETURN_ERR
|
|
||||||
|
|
||||||
// BLARGG_SOURCE_BEGIN: If defined, #included, allowing redefition of dprintf and check
|
|
||||||
#ifdef BLARGG_SOURCE_BEGIN
|
|
||||||
#include BLARGG_SOURCE_BEGIN
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,504 +0,0 @@
|
|||||||
GNU LESSER GENERAL PUBLIC LICENSE
|
|
||||||
Version 2.1, February 1999
|
|
||||||
|
|
||||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
|
||||||
of this license document, but changing it is not allowed.
|
|
||||||
|
|
||||||
[This is the first released version of the Lesser GPL. It also counts
|
|
||||||
as the successor of the GNU Library Public License, version 2, hence
|
|
||||||
the version number 2.1.]
|
|
||||||
|
|
||||||
Preamble
|
|
||||||
|
|
||||||
The licenses for most software are designed to take away your
|
|
||||||
freedom to share and change it. By contrast, the GNU General Public
|
|
||||||
Licenses are intended to guarantee your freedom to share and change
|
|
||||||
free software--to make sure the software is free for all its users.
|
|
||||||
|
|
||||||
This license, the Lesser General Public License, applies to some
|
|
||||||
specially designated software packages--typically libraries--of the
|
|
||||||
Free Software Foundation and other authors who decide to use it. You
|
|
||||||
can use it too, but we suggest you first think carefully about whether
|
|
||||||
this license or the ordinary General Public License is the better
|
|
||||||
strategy to use in any particular case, based on the explanations below.
|
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom of use,
|
|
||||||
not price. Our General Public Licenses are designed to make sure that
|
|
||||||
you have the freedom to distribute copies of free software (and charge
|
|
||||||
for this service if you wish); that you receive source code or can get
|
|
||||||
it if you want it; that you can change the software and use pieces of
|
|
||||||
it in new free programs; and that you are informed that you can do
|
|
||||||
these things.
|
|
||||||
|
|
||||||
To protect your rights, we need to make restrictions that forbid
|
|
||||||
distributors to deny you these rights or to ask you to surrender these
|
|
||||||
rights. These restrictions translate to certain responsibilities for
|
|
||||||
you if you distribute copies of the library or if you modify it.
|
|
||||||
|
|
||||||
For example, if you distribute copies of the library, whether gratis
|
|
||||||
or for a fee, you must give the recipients all the rights that we gave
|
|
||||||
you. You must make sure that they, too, receive or can get the source
|
|
||||||
code. If you link other code with the library, you must provide
|
|
||||||
complete object files to the recipients, so that they can relink them
|
|
||||||
with the library after making changes to the library and recompiling
|
|
||||||
it. And you must show them these terms so they know their rights.
|
|
||||||
|
|
||||||
We protect your rights with a two-step method: (1) we copyright the
|
|
||||||
library, and (2) we offer you this license, which gives you legal
|
|
||||||
permission to copy, distribute and/or modify the library.
|
|
||||||
|
|
||||||
To protect each distributor, we want to make it very clear that
|
|
||||||
there is no warranty for the free library. Also, if the library is
|
|
||||||
modified by someone else and passed on, the recipients should know
|
|
||||||
that what they have is not the original version, so that the original
|
|
||||||
author's reputation will not be affected by problems that might be
|
|
||||||
introduced by others.
|
|
||||||
|
|
||||||
Finally, software patents pose a constant threat to the existence of
|
|
||||||
any free program. We wish to make sure that a company cannot
|
|
||||||
effectively restrict the users of a free program by obtaining a
|
|
||||||
restrictive license from a patent holder. Therefore, we insist that
|
|
||||||
any patent license obtained for a version of the library must be
|
|
||||||
consistent with the full freedom of use specified in this license.
|
|
||||||
|
|
||||||
Most GNU software, including some libraries, is covered by the
|
|
||||||
ordinary GNU General Public License. This license, the GNU Lesser
|
|
||||||
General Public License, applies to certain designated libraries, and
|
|
||||||
is quite different from the ordinary General Public License. We use
|
|
||||||
this license for certain libraries in order to permit linking those
|
|
||||||
libraries into non-free programs.
|
|
||||||
|
|
||||||
When a program is linked with a library, whether statically or using
|
|
||||||
a shared library, the combination of the two is legally speaking a
|
|
||||||
combined work, a derivative of the original library. The ordinary
|
|
||||||
General Public License therefore permits such linking only if the
|
|
||||||
entire combination fits its criteria of freedom. The Lesser General
|
|
||||||
Public License permits more lax criteria for linking other code with
|
|
||||||
the library.
|
|
||||||
|
|
||||||
We call this license the "Lesser" General Public License because it
|
|
||||||
does Less to protect the user's freedom than the ordinary General
|
|
||||||
Public License. It also provides other free software developers Less
|
|
||||||
of an advantage over competing non-free programs. These disadvantages
|
|
||||||
are the reason we use the ordinary General Public License for many
|
|
||||||
libraries. However, the Lesser license provides advantages in certain
|
|
||||||
special circumstances.
|
|
||||||
|
|
||||||
For example, on rare occasions, there may be a special need to
|
|
||||||
encourage the widest possible use of a certain library, so that it becomes
|
|
||||||
a de-facto standard. To achieve this, non-free programs must be
|
|
||||||
allowed to use the library. A more frequent case is that a free
|
|
||||||
library does the same job as widely used non-free libraries. In this
|
|
||||||
case, there is little to gain by limiting the free library to free
|
|
||||||
software only, so we use the Lesser General Public License.
|
|
||||||
|
|
||||||
In other cases, permission to use a particular library in non-free
|
|
||||||
programs enables a greater number of people to use a large body of
|
|
||||||
free software. For example, permission to use the GNU C Library in
|
|
||||||
non-free programs enables many more people to use the whole GNU
|
|
||||||
operating system, as well as its variant, the GNU/Linux operating
|
|
||||||
system.
|
|
||||||
|
|
||||||
Although the Lesser General Public License is Less protective of the
|
|
||||||
users' freedom, it does ensure that the user of a program that is
|
|
||||||
linked with the Library has the freedom and the wherewithal to run
|
|
||||||
that program using a modified version of the Library.
|
|
||||||
|
|
||||||
The precise terms and conditions for copying, distribution and
|
|
||||||
modification follow. Pay close attention to the difference between a
|
|
||||||
"work based on the library" and a "work that uses the library". The
|
|
||||||
former contains code derived from the library, whereas the latter must
|
|
||||||
be combined with the library in order to run.
|
|
||||||
|
|
||||||
GNU LESSER GENERAL PUBLIC LICENSE
|
|
||||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
|
||||||
|
|
||||||
0. This License Agreement applies to any software library or other
|
|
||||||
program which contains a notice placed by the copyright holder or
|
|
||||||
other authorized party saying it may be distributed under the terms of
|
|
||||||
this Lesser General Public License (also called "this License").
|
|
||||||
Each licensee is addressed as "you".
|
|
||||||
|
|
||||||
A "library" means a collection of software functions and/or data
|
|
||||||
prepared so as to be conveniently linked with application programs
|
|
||||||
(which use some of those functions and data) to form executables.
|
|
||||||
|
|
||||||
The "Library", below, refers to any such software library or work
|
|
||||||
which has been distributed under these terms. A "work based on the
|
|
||||||
Library" means either the Library or any derivative work under
|
|
||||||
copyright law: that is to say, a work containing the Library or a
|
|
||||||
portion of it, either verbatim or with modifications and/or translated
|
|
||||||
straightforwardly into another language. (Hereinafter, translation is
|
|
||||||
included without limitation in the term "modification".)
|
|
||||||
|
|
||||||
"Source code" for a work means the preferred form of the work for
|
|
||||||
making modifications to it. For a library, complete source code means
|
|
||||||
all the source code for all modules it contains, plus any associated
|
|
||||||
interface definition files, plus the scripts used to control compilation
|
|
||||||
and installation of the library.
|
|
||||||
|
|
||||||
Activities other than copying, distribution and modification are not
|
|
||||||
covered by this License; they are outside its scope. The act of
|
|
||||||
running a program using the Library is not restricted, and output from
|
|
||||||
such a program is covered only if its contents constitute a work based
|
|
||||||
on the Library (independent of the use of the Library in a tool for
|
|
||||||
writing it). Whether that is true depends on what the Library does
|
|
||||||
and what the program that uses the Library does.
|
|
||||||
|
|
||||||
1. You may copy and distribute verbatim copies of the Library's
|
|
||||||
complete source code as you receive it, in any medium, provided that
|
|
||||||
you conspicuously and appropriately publish on each copy an
|
|
||||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
|
||||||
all the notices that refer to this License and to the absence of any
|
|
||||||
warranty; and distribute a copy of this License along with the
|
|
||||||
Library.
|
|
||||||
|
|
||||||
You may charge a fee for the physical act of transferring a copy,
|
|
||||||
and you may at your option offer warranty protection in exchange for a
|
|
||||||
fee.
|
|
||||||
|
|
||||||
2. You may modify your copy or copies of the Library or any portion
|
|
||||||
of it, thus forming a work based on the Library, and copy and
|
|
||||||
distribute such modifications or work under the terms of Section 1
|
|
||||||
above, provided that you also meet all of these conditions:
|
|
||||||
|
|
||||||
a) The modified work must itself be a software library.
|
|
||||||
|
|
||||||
b) You must cause the files modified to carry prominent notices
|
|
||||||
stating that you changed the files and the date of any change.
|
|
||||||
|
|
||||||
c) You must cause the whole of the work to be licensed at no
|
|
||||||
charge to all third parties under the terms of this License.
|
|
||||||
|
|
||||||
d) If a facility in the modified Library refers to a function or a
|
|
||||||
table of data to be supplied by an application program that uses
|
|
||||||
the facility, other than as an argument passed when the facility
|
|
||||||
is invoked, then you must make a good faith effort to ensure that,
|
|
||||||
in the event an application does not supply such function or
|
|
||||||
table, the facility still operates, and performs whatever part of
|
|
||||||
its purpose remains meaningful.
|
|
||||||
|
|
||||||
(For example, a function in a library to compute square roots has
|
|
||||||
a purpose that is entirely well-defined independent of the
|
|
||||||
application. Therefore, Subsection 2d requires that any
|
|
||||||
application-supplied function or table used by this function must
|
|
||||||
be optional: if the application does not supply it, the square
|
|
||||||
root function must still compute square roots.)
|
|
||||||
|
|
||||||
These requirements apply to the modified work as a whole. If
|
|
||||||
identifiable sections of that work are not derived from the Library,
|
|
||||||
and can be reasonably considered independent and separate works in
|
|
||||||
themselves, then this License, and its terms, do not apply to those
|
|
||||||
sections when you distribute them as separate works. But when you
|
|
||||||
distribute the same sections as part of a whole which is a work based
|
|
||||||
on the Library, the distribution of the whole must be on the terms of
|
|
||||||
this License, whose permissions for other licensees extend to the
|
|
||||||
entire whole, and thus to each and every part regardless of who wrote
|
|
||||||
it.
|
|
||||||
|
|
||||||
Thus, it is not the intent of this section to claim rights or contest
|
|
||||||
your rights to work written entirely by you; rather, the intent is to
|
|
||||||
exercise the right to control the distribution of derivative or
|
|
||||||
collective works based on the Library.
|
|
||||||
|
|
||||||
In addition, mere aggregation of another work not based on the Library
|
|
||||||
with the Library (or with a work based on the Library) on a volume of
|
|
||||||
a storage or distribution medium does not bring the other work under
|
|
||||||
the scope of this License.
|
|
||||||
|
|
||||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
|
||||||
License instead of this License to a given copy of the Library. To do
|
|
||||||
this, you must alter all the notices that refer to this License, so
|
|
||||||
that they refer to the ordinary GNU General Public License, version 2,
|
|
||||||
instead of to this License. (If a newer version than version 2 of the
|
|
||||||
ordinary GNU General Public License has appeared, then you can specify
|
|
||||||
that version instead if you wish.) Do not make any other change in
|
|
||||||
these notices.
|
|
||||||
|
|
||||||
Once this change is made in a given copy, it is irreversible for
|
|
||||||
that copy, so the ordinary GNU General Public License applies to all
|
|
||||||
subsequent copies and derivative works made from that copy.
|
|
||||||
|
|
||||||
This option is useful when you wish to copy part of the code of
|
|
||||||
the Library into a program that is not a library.
|
|
||||||
|
|
||||||
4. You may copy and distribute the Library (or a portion or
|
|
||||||
derivative of it, under Section 2) in object code or executable form
|
|
||||||
under the terms of Sections 1 and 2 above provided that you accompany
|
|
||||||
it with the complete corresponding machine-readable source code, which
|
|
||||||
must be distributed under the terms of Sections 1 and 2 above on a
|
|
||||||
medium customarily used for software interchange.
|
|
||||||
|
|
||||||
If distribution of object code is made by offering access to copy
|
|
||||||
from a designated place, then offering equivalent access to copy the
|
|
||||||
source code from the same place satisfies the requirement to
|
|
||||||
distribute the source code, even though third parties are not
|
|
||||||
compelled to copy the source along with the object code.
|
|
||||||
|
|
||||||
5. A program that contains no derivative of any portion of the
|
|
||||||
Library, but is designed to work with the Library by being compiled or
|
|
||||||
linked with it, is called a "work that uses the Library". Such a
|
|
||||||
work, in isolation, is not a derivative work of the Library, and
|
|
||||||
therefore falls outside the scope of this License.
|
|
||||||
|
|
||||||
However, linking a "work that uses the Library" with the Library
|
|
||||||
creates an executable that is a derivative of the Library (because it
|
|
||||||
contains portions of the Library), rather than a "work that uses the
|
|
||||||
library". The executable is therefore covered by this License.
|
|
||||||
Section 6 states terms for distribution of such executables.
|
|
||||||
|
|
||||||
When a "work that uses the Library" uses material from a header file
|
|
||||||
that is part of the Library, the object code for the work may be a
|
|
||||||
derivative work of the Library even though the source code is not.
|
|
||||||
Whether this is true is especially significant if the work can be
|
|
||||||
linked without the Library, or if the work is itself a library. The
|
|
||||||
threshold for this to be true is not precisely defined by law.
|
|
||||||
|
|
||||||
If such an object file uses only numerical parameters, data
|
|
||||||
structure layouts and accessors, and small macros and small inline
|
|
||||||
functions (ten lines or less in length), then the use of the object
|
|
||||||
file is unrestricted, regardless of whether it is legally a derivative
|
|
||||||
work. (Executables containing this object code plus portions of the
|
|
||||||
Library will still fall under Section 6.)
|
|
||||||
|
|
||||||
Otherwise, if the work is a derivative of the Library, you may
|
|
||||||
distribute the object code for the work under the terms of Section 6.
|
|
||||||
Any executables containing that work also fall under Section 6,
|
|
||||||
whether or not they are linked directly with the Library itself.
|
|
||||||
|
|
||||||
6. As an exception to the Sections above, you may also combine or
|
|
||||||
link a "work that uses the Library" with the Library to produce a
|
|
||||||
work containing portions of the Library, and distribute that work
|
|
||||||
under terms of your choice, provided that the terms permit
|
|
||||||
modification of the work for the customer's own use and reverse
|
|
||||||
engineering for debugging such modifications.
|
|
||||||
|
|
||||||
You must give prominent notice with each copy of the work that the
|
|
||||||
Library is used in it and that the Library and its use are covered by
|
|
||||||
this License. You must supply a copy of this License. If the work
|
|
||||||
during execution displays copyright notices, you must include the
|
|
||||||
copyright notice for the Library among them, as well as a reference
|
|
||||||
directing the user to the copy of this License. Also, you must do one
|
|
||||||
of these things:
|
|
||||||
|
|
||||||
a) Accompany the work with the complete corresponding
|
|
||||||
machine-readable source code for the Library including whatever
|
|
||||||
changes were used in the work (which must be distributed under
|
|
||||||
Sections 1 and 2 above); and, if the work is an executable linked
|
|
||||||
with the Library, with the complete machine-readable "work that
|
|
||||||
uses the Library", as object code and/or source code, so that the
|
|
||||||
user can modify the Library and then relink to produce a modified
|
|
||||||
executable containing the modified Library. (It is understood
|
|
||||||
that the user who changes the contents of definitions files in the
|
|
||||||
Library will not necessarily be able to recompile the application
|
|
||||||
to use the modified definitions.)
|
|
||||||
|
|
||||||
b) Use a suitable shared library mechanism for linking with the
|
|
||||||
Library. A suitable mechanism is one that (1) uses at run time a
|
|
||||||
copy of the library already present on the user's computer system,
|
|
||||||
rather than copying library functions into the executable, and (2)
|
|
||||||
will operate properly with a modified version of the library, if
|
|
||||||
the user installs one, as long as the modified version is
|
|
||||||
interface-compatible with the version that the work was made with.
|
|
||||||
|
|
||||||
c) Accompany the work with a written offer, valid for at
|
|
||||||
least three years, to give the same user the materials
|
|
||||||
specified in Subsection 6a, above, for a charge no more
|
|
||||||
than the cost of performing this distribution.
|
|
||||||
|
|
||||||
d) If distribution of the work is made by offering access to copy
|
|
||||||
from a designated place, offer equivalent access to copy the above
|
|
||||||
specified materials from the same place.
|
|
||||||
|
|
||||||
e) Verify that the user has already received a copy of these
|
|
||||||
materials or that you have already sent this user a copy.
|
|
||||||
|
|
||||||
For an executable, the required form of the "work that uses the
|
|
||||||
Library" must include any data and utility programs needed for
|
|
||||||
reproducing the executable from it. However, as a special exception,
|
|
||||||
the materials to be distributed need not include anything that is
|
|
||||||
normally distributed (in either source or binary form) with the major
|
|
||||||
components (compiler, kernel, and so on) of the operating system on
|
|
||||||
which the executable runs, unless that component itself accompanies
|
|
||||||
the executable.
|
|
||||||
|
|
||||||
It may happen that this requirement contradicts the license
|
|
||||||
restrictions of other proprietary libraries that do not normally
|
|
||||||
accompany the operating system. Such a contradiction means you cannot
|
|
||||||
use both them and the Library together in an executable that you
|
|
||||||
distribute.
|
|
||||||
|
|
||||||
7. You may place library facilities that are a work based on the
|
|
||||||
Library side-by-side in a single library together with other library
|
|
||||||
facilities not covered by this License, and distribute such a combined
|
|
||||||
library, provided that the separate distribution of the work based on
|
|
||||||
the Library and of the other library facilities is otherwise
|
|
||||||
permitted, and provided that you do these two things:
|
|
||||||
|
|
||||||
a) Accompany the combined library with a copy of the same work
|
|
||||||
based on the Library, uncombined with any other library
|
|
||||||
facilities. This must be distributed under the terms of the
|
|
||||||
Sections above.
|
|
||||||
|
|
||||||
b) Give prominent notice with the combined library of the fact
|
|
||||||
that part of it is a work based on the Library, and explaining
|
|
||||||
where to find the accompanying uncombined form of the same work.
|
|
||||||
|
|
||||||
8. You may not copy, modify, sublicense, link with, or distribute
|
|
||||||
the Library except as expressly provided under this License. Any
|
|
||||||
attempt otherwise to copy, modify, sublicense, link with, or
|
|
||||||
distribute the Library is void, and will automatically terminate your
|
|
||||||
rights under this License. However, parties who have received copies,
|
|
||||||
or rights, from you under this License will not have their licenses
|
|
||||||
terminated so long as such parties remain in full compliance.
|
|
||||||
|
|
||||||
9. You are not required to accept this License, since you have not
|
|
||||||
signed it. However, nothing else grants you permission to modify or
|
|
||||||
distribute the Library or its derivative works. These actions are
|
|
||||||
prohibited by law if you do not accept this License. Therefore, by
|
|
||||||
modifying or distributing the Library (or any work based on the
|
|
||||||
Library), you indicate your acceptance of this License to do so, and
|
|
||||||
all its terms and conditions for copying, distributing or modifying
|
|
||||||
the Library or works based on it.
|
|
||||||
|
|
||||||
10. Each time you redistribute the Library (or any work based on the
|
|
||||||
Library), the recipient automatically receives a license from the
|
|
||||||
original licensor to copy, distribute, link with or modify the Library
|
|
||||||
subject to these terms and conditions. You may not impose any further
|
|
||||||
restrictions on the recipients' exercise of the rights granted herein.
|
|
||||||
You are not responsible for enforcing compliance by third parties with
|
|
||||||
this License.
|
|
||||||
|
|
||||||
11. If, as a consequence of a court judgment or allegation of patent
|
|
||||||
infringement or for any other reason (not limited to patent issues),
|
|
||||||
conditions are imposed on you (whether by court order, agreement or
|
|
||||||
otherwise) that contradict the conditions of this License, they do not
|
|
||||||
excuse you from the conditions of this License. If you cannot
|
|
||||||
distribute so as to satisfy simultaneously your obligations under this
|
|
||||||
License and any other pertinent obligations, then as a consequence you
|
|
||||||
may not distribute the Library at all. For example, if a patent
|
|
||||||
license would not permit royalty-free redistribution of the Library by
|
|
||||||
all those who receive copies directly or indirectly through you, then
|
|
||||||
the only way you could satisfy both it and this License would be to
|
|
||||||
refrain entirely from distribution of the Library.
|
|
||||||
|
|
||||||
If any portion of this section is held invalid or unenforceable under any
|
|
||||||
particular circumstance, the balance of the section is intended to apply,
|
|
||||||
and the section as a whole is intended to apply in other circumstances.
|
|
||||||
|
|
||||||
It is not the purpose of this section to induce you to infringe any
|
|
||||||
patents or other property right claims or to contest validity of any
|
|
||||||
such claims; this section has the sole purpose of protecting the
|
|
||||||
integrity of the free software distribution system which is
|
|
||||||
implemented by public license practices. Many people have made
|
|
||||||
generous contributions to the wide range of software distributed
|
|
||||||
through that system in reliance on consistent application of that
|
|
||||||
system; it is up to the author/donor to decide if he or she is willing
|
|
||||||
to distribute software through any other system and a licensee cannot
|
|
||||||
impose that choice.
|
|
||||||
|
|
||||||
This section is intended to make thoroughly clear what is believed to
|
|
||||||
be a consequence of the rest of this License.
|
|
||||||
|
|
||||||
12. If the distribution and/or use of the Library is restricted in
|
|
||||||
certain countries either by patents or by copyrighted interfaces, the
|
|
||||||
original copyright holder who places the Library under this License may add
|
|
||||||
an explicit geographical distribution limitation excluding those countries,
|
|
||||||
so that distribution is permitted only in or among countries not thus
|
|
||||||
excluded. In such case, this License incorporates the limitation as if
|
|
||||||
written in the body of this License.
|
|
||||||
|
|
||||||
13. The Free Software Foundation may publish revised and/or new
|
|
||||||
versions of the Lesser General Public License from time to time.
|
|
||||||
Such new versions will be similar in spirit to the present version,
|
|
||||||
but may differ in detail to address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the Library
|
|
||||||
specifies a version number of this License which applies to it and
|
|
||||||
"any later version", you have the option of following the terms and
|
|
||||||
conditions either of that version or of any later version published by
|
|
||||||
the Free Software Foundation. If the Library does not specify a
|
|
||||||
license version number, you may choose any version ever published by
|
|
||||||
the Free Software Foundation.
|
|
||||||
|
|
||||||
14. If you wish to incorporate parts of the Library into other free
|
|
||||||
programs whose distribution conditions are incompatible with these,
|
|
||||||
write to the author to ask for permission. For software which is
|
|
||||||
copyrighted by the Free Software Foundation, write to the Free
|
|
||||||
Software Foundation; we sometimes make exceptions for this. Our
|
|
||||||
decision will be guided by the two goals of preserving the free status
|
|
||||||
of all derivatives of our free software and of promoting the sharing
|
|
||||||
and reuse of software generally.
|
|
||||||
|
|
||||||
NO WARRANTY
|
|
||||||
|
|
||||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
|
||||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
|
||||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
|
||||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
|
||||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
|
||||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
|
||||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
|
||||||
|
|
||||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
|
||||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
|
||||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
|
||||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
|
||||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
|
||||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
|
||||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
|
||||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
|
||||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
|
||||||
DAMAGES.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
How to Apply These Terms to Your New Libraries
|
|
||||||
|
|
||||||
If you develop a new library, and you want it to be of the greatest
|
|
||||||
possible use to the public, we recommend making it free software that
|
|
||||||
everyone can redistribute and change. You can do so by permitting
|
|
||||||
redistribution under these terms (or, alternatively, under the terms of the
|
|
||||||
ordinary General Public License).
|
|
||||||
|
|
||||||
To apply these terms, attach the following notices to the library. It is
|
|
||||||
safest to attach them to the start of each source file to most effectively
|
|
||||||
convey the exclusion of warranty; and each file should have at least the
|
|
||||||
"copyright" line and a pointer to where the full notice is found.
|
|
||||||
|
|
||||||
<one line to give the library's name and a brief idea of what it does.>
|
|
||||||
Copyright (C) <year> <name of author>
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
|
||||||
|
|
||||||
You should also get your employer (if you work as a programmer) or your
|
|
||||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
|
||||||
necessary. Here is a sample; alter the names:
|
|
||||||
|
|
||||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
|
||||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
|
||||||
|
|
||||||
<signature of Ty Coon>, 1 April 1990
|
|
||||||
Ty Coon, President of Vice
|
|
||||||
|
|
||||||
That's all there is to it!
|
|
||||||
|
|
||||||
|
|
@ -1,161 +0,0 @@
|
|||||||
/* Simple resampler based on bsnes's ruby audio library */
|
|
||||||
|
|
||||||
#ifndef __RESAMPLER_H
|
|
||||||
#define __RESAMPLER_H
|
|
||||||
|
|
||||||
#include "ring_buffer.h"
|
|
||||||
|
|
||||||
#undef MIN
|
|
||||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
|
||||||
|
|
||||||
#undef CLAMP
|
|
||||||
#undef short_clamp
|
|
||||||
#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
|
|
||||||
#define short_clamp(n) ((short) CLAMP((n), -32768, 32767))
|
|
||||||
|
|
||||||
class Resampler : public ring_buffer
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
|
|
||||||
double r_step;
|
|
||||||
double r_frac;
|
|
||||||
int r_left[4], r_right[4];
|
|
||||||
|
|
||||||
double
|
|
||||||
hermite (double mu1, double a, double b, double c, double d)
|
|
||||||
{
|
|
||||||
const double tension = 0.0; //-1 = low, 0 = normal, 1 = high
|
|
||||||
const double bias = 0.0; //-1 = left, 0 = even, 1 = right
|
|
||||||
|
|
||||||
double mu2, mu3, m0, m1, a0, a1, a2, a3;
|
|
||||||
|
|
||||||
mu2 = mu1 * mu1;
|
|
||||||
mu3 = mu2 * mu1;
|
|
||||||
|
|
||||||
m0 = (b - a) * (1 + bias) * (1 - tension) / 2;
|
|
||||||
m0 += (c - b) * (1 - bias) * (1 - tension) / 2;
|
|
||||||
m1 = (c - b) * (1 + bias) * (1 - tension) / 2;
|
|
||||||
m1 += (d - c) * (1 - bias) * (1 - tension) / 2;
|
|
||||||
|
|
||||||
a0 = +2 * mu3 - 3 * mu2 + 1;
|
|
||||||
a1 = mu3 - 2 * mu2 + mu1;
|
|
||||||
a2 = mu3 - mu2;
|
|
||||||
a3 = -2 * mu3 + 3 * mu2;
|
|
||||||
|
|
||||||
return (a0 * b) + (a1 * m0) + (a2 * m1) + (a3 * c);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
Resampler (int num_samples) : ring_buffer (num_samples << 1)
|
|
||||||
{
|
|
||||||
r_frac = 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
~Resampler ()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
time_ratio (double ratio)
|
|
||||||
{
|
|
||||||
r_step = ratio;
|
|
||||||
clear ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
clear (void)
|
|
||||||
{
|
|
||||||
ring_buffer::clear ();
|
|
||||||
r_frac = 0;
|
|
||||||
r_left [0] = r_left [1] = r_left [2] = r_left [3] = 0;
|
|
||||||
r_right[0] = r_right[1] = r_right[2] = r_right[3] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
read (short *data, int num_samples)
|
|
||||||
{
|
|
||||||
int i_position = start >> 1;
|
|
||||||
short *internal_buffer = (short *) buffer;
|
|
||||||
int o_position = 0;
|
|
||||||
int consumed = 0;
|
|
||||||
|
|
||||||
while (o_position < num_samples && consumed < buffer_size)
|
|
||||||
{
|
|
||||||
int s_left = internal_buffer[i_position];
|
|
||||||
int s_right = internal_buffer[i_position + 1];
|
|
||||||
|
|
||||||
if (r_step == 1.0)
|
|
||||||
{
|
|
||||||
data[o_position] = (short) s_left;
|
|
||||||
data[o_position + 1] = (short) s_right;
|
|
||||||
|
|
||||||
o_position += 2;
|
|
||||||
i_position = (i_position + 2) % (buffer_size >> 1);
|
|
||||||
consumed += 2;
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
r_left [0] = r_left [1];
|
|
||||||
r_left [1] = r_left [2];
|
|
||||||
r_left [2] = r_left [3];
|
|
||||||
r_left [3] = s_left;
|
|
||||||
|
|
||||||
r_right[0] = r_right[1];
|
|
||||||
r_right[1] = r_right[2];
|
|
||||||
r_right[2] = r_right[3];
|
|
||||||
r_right[3] = s_right;
|
|
||||||
|
|
||||||
while (r_frac <= 1.0 && o_position < num_samples)
|
|
||||||
{
|
|
||||||
data[o_position] = short_clamp (hermite (r_frac, r_left [0], r_left [1], r_left [2], r_left [3]));
|
|
||||||
data[o_position + 1] = short_clamp (hermite (r_frac, r_right[0], r_right[1], r_right[2], r_right[3]));
|
|
||||||
|
|
||||||
o_position += 2;
|
|
||||||
|
|
||||||
r_frac += r_step;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r_frac > 1.0)
|
|
||||||
{
|
|
||||||
r_frac -= 1.0;
|
|
||||||
i_position = (i_position + 2) % (buffer_size >> 1);
|
|
||||||
consumed += 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
size -= consumed << 1;
|
|
||||||
start = (start + (consumed << 1)) % buffer_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
push (short *src, int num_samples)
|
|
||||||
{
|
|
||||||
if (max_write () < num_samples)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
ring_buffer::push ((unsigned char *) src, num_samples << 1);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
max_write (void)
|
|
||||||
{
|
|
||||||
return space_empty () >> 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
resize (int num_samples)
|
|
||||||
{
|
|
||||||
ring_buffer::resize (num_samples << 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
avail (void)
|
|
||||||
{
|
|
||||||
return (int) floor (((size >> 2) - r_frac) / r_step) * 2;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* __RESAMPLER_H */
|
|
@ -1,111 +0,0 @@
|
|||||||
/* Simple byte-based ring buffer. Licensed under public domain (C) BearOso. */
|
|
||||||
|
|
||||||
#ifndef __RING_BUFFER_H
|
|
||||||
#define __RING_BUFFER_H
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#undef MIN
|
|
||||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
|
||||||
|
|
||||||
class ring_buffer
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
int size;
|
|
||||||
int buffer_size;
|
|
||||||
int start;
|
|
||||||
unsigned char *buffer;
|
|
||||||
|
|
||||||
public:
|
|
||||||
ring_buffer (int buffer_size)
|
|
||||||
{
|
|
||||||
this->buffer_size = buffer_size;
|
|
||||||
buffer = new unsigned char[this->buffer_size];
|
|
||||||
memset (buffer, 0, this->buffer_size);
|
|
||||||
|
|
||||||
size = 0;
|
|
||||||
start = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
~ring_buffer (void)
|
|
||||||
{
|
|
||||||
delete[] buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
push (unsigned char *src, int bytes)
|
|
||||||
{
|
|
||||||
if (space_empty () < bytes)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
int end = (start + size) % buffer_size;
|
|
||||||
int first_write_size = MIN (bytes, buffer_size - end);
|
|
||||||
|
|
||||||
memcpy (buffer + end, src, first_write_size);
|
|
||||||
|
|
||||||
if (bytes > first_write_size)
|
|
||||||
memcpy (buffer, src + first_write_size, bytes - first_write_size);
|
|
||||||
|
|
||||||
size += bytes;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
pull (unsigned char *dst, int bytes)
|
|
||||||
{
|
|
||||||
if (space_filled () < bytes)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
memcpy (dst, buffer + start, MIN (bytes, buffer_size - start));
|
|
||||||
|
|
||||||
if (bytes > (buffer_size - start))
|
|
||||||
memcpy (dst + (buffer_size - start), buffer, bytes - (buffer_size - start));
|
|
||||||
|
|
||||||
start = (start + bytes) % buffer_size;
|
|
||||||
size -= bytes;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int
|
|
||||||
space_empty (void)
|
|
||||||
{
|
|
||||||
return buffer_size - size;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int
|
|
||||||
space_filled (void)
|
|
||||||
{
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
clear (void)
|
|
||||||
{
|
|
||||||
start = 0;
|
|
||||||
size = 0;
|
|
||||||
memset (buffer, 0, buffer_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
resize (int size)
|
|
||||||
{
|
|
||||||
delete[] buffer;
|
|
||||||
buffer_size = size;
|
|
||||||
buffer = new unsigned char[buffer_size];
|
|
||||||
memset (buffer, 0, this->buffer_size);
|
|
||||||
|
|
||||||
size = 0;
|
|
||||||
start = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
|
||||||
cache_silence (void)
|
|
||||||
{
|
|
||||||
clear ();
|
|
||||||
size = buffer_size;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
509
source/snes9x/apudebug.cpp
Normal file
509
source/snes9x/apudebug.cpp
Normal file
@ -0,0 +1,509 @@
|
|||||||
|
/**********************************************************************************
|
||||||
|
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||||
|
|
||||||
|
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||||
|
Jerremy Koot (jkoot@snes9x.com)
|
||||||
|
|
||||||
|
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||||
|
|
||||||
|
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||||
|
|
||||||
|
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||||
|
|
||||||
|
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||||
|
|
||||||
|
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||||
|
Kris Bleakley (codeviolation@hotmail.com)
|
||||||
|
|
||||||
|
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
|
||||||
|
Nach (n-a-c-h@users.sourceforge.net),
|
||||||
|
zones (kasumitokoduck@yahoo.com)
|
||||||
|
|
||||||
|
(c) Copyright 2006 - 2007 nitsuja
|
||||||
|
|
||||||
|
|
||||||
|
BS-X C emulator code
|
||||||
|
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||||
|
zones
|
||||||
|
|
||||||
|
C4 x86 assembler and some C emulation code
|
||||||
|
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||||
|
Nach,
|
||||||
|
zsKnight (zsknight@zsnes.com)
|
||||||
|
|
||||||
|
C4 C++ code
|
||||||
|
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||||
|
Nach
|
||||||
|
|
||||||
|
DSP-1 emulator code
|
||||||
|
(c) Copyright 1998 - 2006 _Demo_,
|
||||||
|
Andreas Naive (andreasnaive@gmail.com)
|
||||||
|
Gary Henderson,
|
||||||
|
Ivar (ivar@snes9x.com),
|
||||||
|
John Weidman,
|
||||||
|
Kris Bleakley,
|
||||||
|
Matthew Kendora,
|
||||||
|
Nach,
|
||||||
|
neviksti (neviksti@hotmail.com)
|
||||||
|
|
||||||
|
DSP-2 emulator code
|
||||||
|
(c) Copyright 2003 John Weidman,
|
||||||
|
Kris Bleakley,
|
||||||
|
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||||
|
Matthew Kendora,
|
||||||
|
neviksti
|
||||||
|
|
||||||
|
|
||||||
|
DSP-3 emulator code
|
||||||
|
(c) Copyright 2003 - 2006 John Weidman,
|
||||||
|
Kris Bleakley,
|
||||||
|
Lancer,
|
||||||
|
z80 gaiden
|
||||||
|
|
||||||
|
DSP-4 emulator code
|
||||||
|
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||||
|
John Weidman,
|
||||||
|
Kris Bleakley,
|
||||||
|
Nach,
|
||||||
|
z80 gaiden
|
||||||
|
|
||||||
|
OBC1 emulator code
|
||||||
|
(c) Copyright 2001 - 2004 zsKnight,
|
||||||
|
pagefault (pagefault@zsnes.com),
|
||||||
|
Kris Bleakley,
|
||||||
|
Ported from x86 assembler to C by sanmaiwashi
|
||||||
|
|
||||||
|
SPC7110 and RTC C++ emulator code
|
||||||
|
(c) Copyright 2002 Matthew Kendora with research by
|
||||||
|
zsKnight,
|
||||||
|
John Weidman,
|
||||||
|
Dark Force
|
||||||
|
|
||||||
|
S-DD1 C emulator code
|
||||||
|
(c) Copyright 2003 Brad Jorsch with research by
|
||||||
|
Andreas Naive,
|
||||||
|
John Weidman
|
||||||
|
|
||||||
|
S-RTC C emulator code
|
||||||
|
(c) Copyright 2001-2006 byuu,
|
||||||
|
John Weidman
|
||||||
|
|
||||||
|
ST010 C++ emulator code
|
||||||
|
(c) Copyright 2003 Feather,
|
||||||
|
John Weidman,
|
||||||
|
Kris Bleakley,
|
||||||
|
Matthew Kendora
|
||||||
|
|
||||||
|
Super FX x86 assembler emulator code
|
||||||
|
(c) Copyright 1998 - 2003 _Demo_,
|
||||||
|
pagefault,
|
||||||
|
zsKnight,
|
||||||
|
|
||||||
|
Super FX C emulator code
|
||||||
|
(c) Copyright 1997 - 1999 Ivar,
|
||||||
|
Gary Henderson,
|
||||||
|
John Weidman
|
||||||
|
|
||||||
|
Sound DSP emulator code is derived from SNEeSe and OpenSPC:
|
||||||
|
(c) Copyright 1998 - 2003 Brad Martin
|
||||||
|
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||||
|
|
||||||
|
SH assembler code partly based on x86 assembler code
|
||||||
|
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||||
|
|
||||||
|
2xSaI filter
|
||||||
|
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||||
|
|
||||||
|
HQ2x, HQ3x, HQ4x filters
|
||||||
|
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||||
|
|
||||||
|
Win32 GUI code
|
||||||
|
(c) Copyright 2003 - 2006 blip,
|
||||||
|
funkyass,
|
||||||
|
Matthew Kendora,
|
||||||
|
Nach,
|
||||||
|
nitsuja
|
||||||
|
|
||||||
|
Mac OS GUI code
|
||||||
|
(c) Copyright 1998 - 2001 John Stiles
|
||||||
|
(c) Copyright 2001 - 2007 zones
|
||||||
|
|
||||||
|
|
||||||
|
Specific ports contains the works of other authors. See headers in
|
||||||
|
individual files.
|
||||||
|
|
||||||
|
|
||||||
|
Snes9x homepage: http://www.snes9x.com
|
||||||
|
|
||||||
|
Permission to use, copy, modify and/or 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 or it's derivatives.
|
||||||
|
|
||||||
|
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||||
|
seek permission of the copyright holders first. Commercial use includes,
|
||||||
|
but is not limited to, charging money for Snes9x or software derived from
|
||||||
|
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||||
|
using Snes9x as a promotion for your commercial product.
|
||||||
|
|
||||||
|
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 "spc700.h"
|
||||||
|
#include "apu.h"
|
||||||
|
#include "soundux.h"
|
||||||
|
#include "cpuexec.h"
|
||||||
|
|
||||||
|
#ifdef DEBUGGER
|
||||||
|
extern int32 env_counter_table[32];
|
||||||
|
|
||||||
|
FILE *apu_trace = NULL;
|
||||||
|
|
||||||
|
static char *S9xMnemonics [256] = {
|
||||||
|
"NOP", "TCALL 0", "SET1 $%02X.0", "BBS $%02X.0,$%04X",
|
||||||
|
"OR A,$%02X", "OR A,!$%04X", "OR A,(X)", "OR A,[$%02X+X]",
|
||||||
|
"OR A,#$%02X", "OR $%02X,$%02X", "OR1 C,$%04X.%d", "ASL $%02X",
|
||||||
|
"MOV !$%04X,Y", "PUSH PSW", "TSET1 !$%04X", "BRK",
|
||||||
|
"BPL $%04X", "TCALL 1", "CLR1 $%02X.0", "BBC $%02X.0,$%04X",
|
||||||
|
"OR A,$%02X+X", "OR A,!$%04X+X", "OR A,!$%04X+Y", "OR A,[$%02X]+Y",
|
||||||
|
"OR $%02X,#$%02X", "OR (X),(Y)", "DECW $%02X", "ASL $%02X+X",
|
||||||
|
"ASL A", "DEC X", "CMP X,!$%04X", "JMP [!$%04X+X]",
|
||||||
|
"CLRP", "TCALL 2", "SET1 $%02X.1", "BBS $%02X.1,$%04X",
|
||||||
|
"AND A,$%02X", "AND A,!$%04X", "AND A,(X)", "AND A,[$%02X+X]",
|
||||||
|
"AND A,#$%02X", "AND $%02X,$%02X", "OR1 C,/$%04X.%d", "ROL $%02X",
|
||||||
|
"ROL !$%04X", "PUSH A", "CBNE $%02X,$%04X", "BRA $%04X",
|
||||||
|
"BMI $%04X", "TCALL 3", "CLR1 $%02X.1", "BBC $%02X.1,$%04X",
|
||||||
|
"AND A,$%02X+X", "AND A,!$%04X+X", "AND A,!$%04X+Y", "AND A,[$%02X]+Y",
|
||||||
|
"AND $%02X,#$%02X", "AND (X),(Y)", "INCW $%02X", "ROL $%02X+X",
|
||||||
|
"ROL A", "INC X", "CMP X,$%02X", "CALL !$%04X",
|
||||||
|
"SETP", "TCALL 4", "SET1 $%02X.2", "BBS $%02X.2,$%04X",
|
||||||
|
"EOR A,$%02X", "EOR A,!$%04X", "EOR A,(X)", "EOR A,[$%02X+X]",
|
||||||
|
"EOR A,#$%02X", "EOR $%02X,$%02X", "AND1 C,$%04X.%d", "LSR $%02X",
|
||||||
|
"LSR !$%04X", "PUSH X", "TCLR1 !$%04X", "PCALL $%02X",
|
||||||
|
"BVC $%04X", "TCALL 5", "CLR1 $%02X.2", "BBC $%02X.2,$%04X",
|
||||||
|
"EOR A,$%02X+X", "EOR A,!$%04X+X", "EOR A,!$%04X+Y", "EOR A,[$%02X]+Y",
|
||||||
|
"EOR $%02X,#$%02X", "EOR (X),(Y)", "CMPW YA,$%02X", "LSR $%02X+X",
|
||||||
|
"LSR A", "MOV X,A", "CMP Y,!$%04X", "JMP !$%04X",
|
||||||
|
"CLRC", "TCALL 6", "SET1 $%02X.3", "BBS $%02X.3,$%04X",
|
||||||
|
"CMP A,$%02X", "CMP A,!$%04X", "CMP A,(X)", "CMP A,[$%02X+X]",
|
||||||
|
"CMP A,#$%02X", "CMP $%02X,$%02X", "AND1 C,/$%04X.%d", "ROR $%02X",
|
||||||
|
"ROR !$%04X", "PUSH Y", "DBNZ $%02X,$%04X", "RET",
|
||||||
|
"BVS $%04X", "TCALL 7", "CLR1 $%02X.3", "BBC $%02X.3,$%04X",
|
||||||
|
"CMP A,$%02X+X", "CMP A,!$%04X+X", "CMP A,!$%04X+Y", "CMP A,[$%02X]+Y",
|
||||||
|
"CMP $%02X,#$%02X", "CMP (X),(Y)", "ADDW YA,$%02X", "ROR $%02X+X",
|
||||||
|
"ROR A", "MOV A,X", "CMP Y,$%02X", "RET1",
|
||||||
|
"SETC", "TCALL 8", "SET1 $%02X.4", "BBS $%02X.4,$%04X",
|
||||||
|
"ADC A,$%02X", "ADC A,!$%04X", "ADC A,(X)", "ADC A,[$%02X+X]",
|
||||||
|
"ADC A,#$%02X", "ADC $%02X,$%02X", "EOR1 C,$%04X.%d", "DEC $%02X",
|
||||||
|
"DEC !$%04X", "MOV Y,#$%02X", "POP PSW", "MOV $%02X,#$%02X",
|
||||||
|
"BCC $%04X", "TCALL 9", "CLR1 $%02X.4", "BBC $%02X.4,$%04X",
|
||||||
|
"ADC A,$%02X+X", "ADC A,!$%04X+X", "ADC A,!$%04X+Y", "ADC A,[$%02X]+Y",
|
||||||
|
"ADC $%02X,#$%02X", "ADC (X),(Y)", "SUBW YA,$%02X", "DEC $%02X+X",
|
||||||
|
"DEC A", "MOV X,SP", "DIV YA,X", "XCN A",
|
||||||
|
"EI", "TCALL 10", "SET1 $%02X.5", "BBS $%02X.5,$%04X",
|
||||||
|
"SBC A,$%02X", "SBC A,!$%04X", "SBC A,(X)", "SBC A,[$%02X+X]",
|
||||||
|
"SBC A,#$%02X", "SBC $%02X,$%02X", "MOV1 C,$%04X.%d", "INC $%02X",
|
||||||
|
"INC !$%04X", "CMP Y,#$%02X", "POP A", "MOV (X)+,A",
|
||||||
|
"BCS $%04X", "TCALL 11", "CLR1 $%02X.5", "BBC $%02X.5,$%04X",
|
||||||
|
"SBC A,$%02X+X", "SBC A,!$%04X+X", "SBC A,!$%04X+Y", "SBC A,[$%02X]+Y",
|
||||||
|
"SBC $%02X,#$%02X", "SBC (X),(Y)", "MOVW YA,$%02X", "INC $%02X+X",
|
||||||
|
"INC A", "MOV SP,X", "DAS A", "MOV A,(X)+",
|
||||||
|
"DI", "TCALL 12", "SET1 $%02X.6", "BBS $%02X.6,$%04X",
|
||||||
|
"MOV $%02X,A", "MOV !$%04X,A", "MOV (X),A", "MOV [$%02X+X],A",
|
||||||
|
"CMP X,#$%02X", "MOV !$%04X,X", "MOV1 $%04X.%d,C", "MOV $%02X,Y",
|
||||||
|
"ASL !$%04X", "MOV X,#$%02X", "POP X", "MUL YA",
|
||||||
|
"BNE $%04X", "TCALL 13", "CLR1 $%02X.6", "BBC $%02X.6,$%04X",
|
||||||
|
"MOV $%02X+X,A", "MOV !$%04X+X,A", "MOV !$%04X+Y,A", "MOV [$%02X]+Y,A",
|
||||||
|
"MOV $%02X,X", "MOV $%02X+Y,X", "MOVW $%02X,YA", "MOV $%02X+X,Y",
|
||||||
|
"DEC Y", "MOV A,Y", "CBNE $%02X+X,$%04X", "DAA A",
|
||||||
|
"CLRV", "TCALL 14", "SET1 $%02X.7", "BBS $%02X.7,$%04X",
|
||||||
|
"MOV A,$%02X", "MOV A,!$%04X", "MOV A,(X)", "MOV A,[$%02X+X]",
|
||||||
|
"MOV A,#$%02X", "MOV X,!$%04X", "NOT1 $%04X.%d", "MOV Y,$%02X",
|
||||||
|
"MOV Y,!$%04X", "NOTC", "POP Y", "SLEEP",
|
||||||
|
"BEQ $%04X", "TCALL 15", "CLR1 $%02X.7", "BBC $%02X.7,$%04X",
|
||||||
|
"MOV A,$%02X+X", "MOV A,!$%04X+X", "MOV A,!$%04X+Y", "MOV A,[$%02X]+Y",
|
||||||
|
"MOV X,$%02X", "MOV X,$%02X+Y", "MOV $%02X,$%02X", "MOV Y,$%02X+X",
|
||||||
|
"INC Y", "MOV Y,A", "DBNZ Y,$%04X", "STOP"
|
||||||
|
};
|
||||||
|
|
||||||
|
#undef ABS
|
||||||
|
|
||||||
|
#define DP 0
|
||||||
|
#define ABS 1
|
||||||
|
#define IM 2
|
||||||
|
#define DP2DP 3
|
||||||
|
#define DPIM 4
|
||||||
|
#define DPREL 5
|
||||||
|
#define ABSBIT 6
|
||||||
|
#define REL 7
|
||||||
|
|
||||||
|
static uint8 Modes [256] = {
|
||||||
|
IM, IM, DP, DPREL,
|
||||||
|
DP, ABS, IM, DP,
|
||||||
|
DP, DP2DP, ABSBIT, DP,
|
||||||
|
ABS, IM, ABS, IM,
|
||||||
|
REL, IM, DP, DPREL,
|
||||||
|
DP, ABS, ABS, DP,
|
||||||
|
DPIM, IM, DP, DP,
|
||||||
|
IM, IM, ABS, ABS,
|
||||||
|
IM, IM, DP, DPREL,
|
||||||
|
DP, ABS, IM, DP,
|
||||||
|
DP, DP2DP, ABSBIT, DP,
|
||||||
|
ABS, IM, DPREL, REL,
|
||||||
|
REL, IM, DP, DPREL,
|
||||||
|
DP, ABS, ABS, DP,
|
||||||
|
DPIM, IM, DP, DP,
|
||||||
|
IM, IM, DP, ABS,
|
||||||
|
IM, IM, DP, DPREL,
|
||||||
|
DP, ABS, IM, DP,
|
||||||
|
DP, DP2DP, ABSBIT, DP,
|
||||||
|
ABS, IM, ABS, DP,
|
||||||
|
REL, IM, DP, DPREL,
|
||||||
|
DP, ABS, ABS, DP,
|
||||||
|
DPIM, IM, DP, DP,
|
||||||
|
IM, IM, ABS, ABS,
|
||||||
|
IM, IM, DP, DPREL,
|
||||||
|
DP, ABS, IM, DP,
|
||||||
|
DP, DP2DP, ABSBIT, DP,
|
||||||
|
ABS, IM, DPREL, IM,
|
||||||
|
REL, IM, DP, DPREL,
|
||||||
|
DP, ABS, ABS, DP,
|
||||||
|
DPIM, IM, DP, DP,
|
||||||
|
IM, IM, DP, IM,
|
||||||
|
IM, IM, DP, DPREL,
|
||||||
|
DP, ABS, IM, DP,
|
||||||
|
DP, DP2DP, ABSBIT, DP,
|
||||||
|
ABS, DP, IM, DPIM,
|
||||||
|
REL, IM, DP, DPREL,
|
||||||
|
DP, ABS, ABS, DP,
|
||||||
|
DPIM, IM, DP, DP,
|
||||||
|
IM, IM, IM, IM,
|
||||||
|
IM, IM, DP, DPREL,
|
||||||
|
DP, ABS, IM, DP,
|
||||||
|
DP, DP2DP, ABSBIT, DP,
|
||||||
|
ABS, DP, IM, IM,
|
||||||
|
REL, IM, DP, DPREL,
|
||||||
|
DP, ABS, ABS, DP,
|
||||||
|
DPIM, IM, DP, DP,
|
||||||
|
IM, IM, IM, IM,
|
||||||
|
IM, IM, DP, DPREL,
|
||||||
|
DP, ABS, IM, DP,
|
||||||
|
DP, ABS, ABSBIT, DP,
|
||||||
|
ABS, DP, IM, IM,
|
||||||
|
REL, IM, DP, DPREL,
|
||||||
|
DP, ABS, ABS, DP,
|
||||||
|
DP, DP, DP, DP,
|
||||||
|
IM, IM, DPREL, IM,
|
||||||
|
IM, IM, DP, DPREL,
|
||||||
|
DP, ABS, IM, DP,
|
||||||
|
DP, ABS, ABSBIT, DP,
|
||||||
|
ABS, IM, IM, IM,
|
||||||
|
REL, IM, DP, DPREL,
|
||||||
|
DP, ABS, ABS, DP,
|
||||||
|
DP, DP, DP2DP, DP,
|
||||||
|
IM, IM, REL, IM
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint8 ModesToBytes [] = {
|
||||||
|
2, 3, 1, 3, 3, 3, 3, 2
|
||||||
|
};
|
||||||
|
|
||||||
|
static FILE *SoundTracing = NULL;
|
||||||
|
|
||||||
|
void S9xOpenCloseSoundTracingFile (bool8 open)
|
||||||
|
{
|
||||||
|
if (open && !SoundTracing)
|
||||||
|
{
|
||||||
|
SoundTracing = fopen ("sound_trace.log", "w");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (!open && SoundTracing)
|
||||||
|
{
|
||||||
|
fclose (SoundTracing);
|
||||||
|
SoundTracing = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void S9xTraceSoundDSP (const char *s, int i1 = 0, int i2 = 0, int i3 = 0,
|
||||||
|
int i4 = 0, int i5 = 0, int i6 = 0, int i7 = 0)
|
||||||
|
{
|
||||||
|
fprintf (SoundTracing, s, i1, i2, i3, i4, i5, i6, i7);
|
||||||
|
}
|
||||||
|
|
||||||
|
int S9xTraceAPU ()
|
||||||
|
{
|
||||||
|
char buffer [200];
|
||||||
|
|
||||||
|
uint8 b = S9xAPUOPrint (buffer, IAPU.PC - IAPU.RAM);
|
||||||
|
if (apu_trace == NULL)
|
||||||
|
apu_trace = fopen ("apu_trace.log", "wb");
|
||||||
|
|
||||||
|
fprintf (apu_trace, "%s\n", buffer);
|
||||||
|
return (b);
|
||||||
|
}
|
||||||
|
|
||||||
|
int S9xAPUOPrint (char *buffer, uint16 Address)
|
||||||
|
{
|
||||||
|
char mnem [100];
|
||||||
|
uint8 *p = IAPU.RAM + Address;
|
||||||
|
int mode = Modes [*p];
|
||||||
|
int bytes = ModesToBytes [mode];
|
||||||
|
|
||||||
|
switch (bytes)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
sprintf (buffer, "%04X %02X ", p - IAPU.RAM, *p);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
sprintf (buffer, "%04X %02X %02X ", p - IAPU.RAM, *p,
|
||||||
|
*(p + 1));
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
sprintf (buffer, "%04X %02X %02X %02X ", p - IAPU.RAM, *p,
|
||||||
|
*(p + 1), *(p + 2));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case DP:
|
||||||
|
sprintf (mnem, S9xMnemonics [*p], *(p + 1));
|
||||||
|
break;
|
||||||
|
case ABS:
|
||||||
|
sprintf (mnem, S9xMnemonics [*p], *(p + 1) + (*(p + 2) << 8));
|
||||||
|
break;
|
||||||
|
case IM:
|
||||||
|
sprintf (mnem, S9xMnemonics [*p]);
|
||||||
|
break;
|
||||||
|
case DP2DP:
|
||||||
|
sprintf (mnem, S9xMnemonics [*p], *(p + 2), *(p + 1));;
|
||||||
|
break;
|
||||||
|
case DPIM:
|
||||||
|
sprintf (mnem, S9xMnemonics [*p], *(p + 2), *(p + 1));;
|
||||||
|
break;
|
||||||
|
case DPREL:
|
||||||
|
sprintf (mnem, S9xMnemonics [*p], *(p + 1),
|
||||||
|
(int) (p + 3 - IAPU.RAM) + (signed char) *(p + 2));
|
||||||
|
break;
|
||||||
|
case ABSBIT:
|
||||||
|
sprintf (mnem, S9xMnemonics [*p], (*(p + 1) + (*(p + 2) << 8)) & 0x1fff,
|
||||||
|
*(p + 2) >> 5);
|
||||||
|
break;
|
||||||
|
case REL:
|
||||||
|
sprintf (mnem, S9xMnemonics [*p],
|
||||||
|
(int) (p + 2 - IAPU.RAM) + (signed char) *(p + 1));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf (buffer, "%s %-20s A:%02X X:%02X Y:%02X S:%02X P:%c%c%c%c%c%c%c%c %03ld %04ld %04d",
|
||||||
|
buffer, mnem,
|
||||||
|
APURegisters.YA.B.A, APURegisters.X, APURegisters.YA.B.Y,
|
||||||
|
APURegisters.S,
|
||||||
|
APUCheckNegative () ? 'N' : 'n',
|
||||||
|
APUCheckOverflow () ? 'V' : 'v',
|
||||||
|
APUCheckDirectPage () ? 'P' : 'p',
|
||||||
|
APUCheckBreak () ? 'B' : 'b',
|
||||||
|
APUCheckHalfCarry () ? 'H' : 'h',
|
||||||
|
APUCheckInterrupt () ? 'I' : 'i',
|
||||||
|
APUCheckZero () ? 'Z' : 'z',
|
||||||
|
APUCheckCarry () ? 'C' : 'c',
|
||||||
|
CPU.V_Counter,
|
||||||
|
CPU.Cycles,
|
||||||
|
APU.Cycles >> SNES_APU_ACCURACY);
|
||||||
|
|
||||||
|
return (bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *as_binary (uint8 data)
|
||||||
|
{
|
||||||
|
static char buf [9];
|
||||||
|
|
||||||
|
for (int i = 7; i >= 0; i--)
|
||||||
|
buf [7 - i] = ((data & (1 << i)) != 0) + '0';
|
||||||
|
|
||||||
|
buf [8] = 0;
|
||||||
|
return (buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void S9xPrintAPUState ()
|
||||||
|
{
|
||||||
|
printf ("Master volume left: %d, right: %d\n",
|
||||||
|
SoundData.master_volume_left, SoundData.master_volume_right);
|
||||||
|
printf ("Echo: %s %s, Delay: %d Feedback: %d Left: %d Right: %d\n",
|
||||||
|
SoundData.echo_write_enabled ? "on" : "off",
|
||||||
|
as_binary (SoundData.echo_enable),
|
||||||
|
SoundData.echo_buffer_size >> 9,
|
||||||
|
SoundData.echo_feedback, SoundData.echo_volume_left,
|
||||||
|
SoundData.echo_volume_right);
|
||||||
|
|
||||||
|
printf ("Noise: %s, Frequency: %d, Pitch mod: %s\n", as_binary (APU.DSP [APU_NON]),
|
||||||
|
env_counter_table [APU.DSP [APU_FLG] & 0x1f],
|
||||||
|
as_binary (SoundData.pitch_mod));
|
||||||
|
extern int FilterTaps [8];
|
||||||
|
|
||||||
|
printf ("Filter: ");
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
printf ("%03d, ", FilterTaps [i]);
|
||||||
|
printf ("\n");
|
||||||
|
for (int J = 0; J < 8; J++)
|
||||||
|
{
|
||||||
|
register Channel *ch = &SoundData.channels[J];
|
||||||
|
|
||||||
|
printf ("%d: ", J);
|
||||||
|
if (ch->state == SOUND_SILENT)
|
||||||
|
{
|
||||||
|
printf ("off\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (!(so.sound_switch & (1 << J)))
|
||||||
|
printf ("muted by user using channel on/off toggle\n");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int freq = ch->hertz;
|
||||||
|
if (APU.DSP [APU_NON] & (1 << J)) //ch->type == SOUND_NOISE)
|
||||||
|
{
|
||||||
|
freq = env_counter_table [APU.DSP [APU_FLG] & 0x1f];
|
||||||
|
printf ("noise, ");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf ("sample %d, ", APU.DSP [APU_SRCN + J * 0x10]);
|
||||||
|
|
||||||
|
printf ("freq: %d", freq);
|
||||||
|
if (J > 0 && (SoundData.pitch_mod & (1 << J)) &&
|
||||||
|
ch->type != SOUND_NOISE)
|
||||||
|
{
|
||||||
|
printf ("(mod), ");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf (", ");
|
||||||
|
|
||||||
|
printf ("left: %d, right: %d, ",
|
||||||
|
ch->volume_left, ch->volume_right);
|
||||||
|
|
||||||
|
static char* envelope [] =
|
||||||
|
{
|
||||||
|
"silent", "attack", "decay", "sustain", "release", "gain",
|
||||||
|
"inc_lin", "inc_bent", "dec_lin", "dec_exp"
|
||||||
|
};
|
||||||
|
printf ("%s envx: %d, target: %d, %ld", ch->state > 9 ? "???" : envelope [ch->state],
|
||||||
|
ch->envx, ch->envx_target, ch->erate);
|
||||||
|
printf ("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
@ -158,180 +158,153 @@
|
|||||||
Nintendo Co., Limited and its subsidiary companies.
|
Nintendo Co., Limited and its subsidiary companies.
|
||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
// Abstract the details of reading from zip files versus FILE *'s.
|
|
||||||
|
|
||||||
|
|
||||||
#include <string>
|
#ifndef _apumemory_h_
|
||||||
#ifdef UNZIP_SUPPORT
|
#define _apumemory_h_
|
||||||
#include "unzip.h"
|
|
||||||
#endif
|
|
||||||
#include "snes9x.h"
|
|
||||||
#include "reader.h"
|
|
||||||
|
|
||||||
|
START_EXTERN_C
|
||||||
|
extern uint8 APUROM[64];
|
||||||
|
END_EXTERN_C
|
||||||
|
|
||||||
// Generic constructor/destructor
|
static INLINE uint8 apu_get_reg (uint8 Address)
|
||||||
|
|
||||||
Reader::Reader (void)
|
|
||||||
{
|
{
|
||||||
return;
|
switch (Address)
|
||||||
}
|
|
||||||
|
|
||||||
Reader::~Reader (void)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generic getline function, based on gets. Reimlpement if you can do better.
|
|
||||||
|
|
||||||
char * Reader::getline (void)
|
|
||||||
{
|
|
||||||
bool eof;
|
|
||||||
std::string ret;
|
|
||||||
|
|
||||||
ret = getline(eof);
|
|
||||||
if (ret.size() == 0 && eof)
|
|
||||||
return (NULL);
|
|
||||||
|
|
||||||
return (strdup(ret.c_str()));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Reader::getline (bool &eof)
|
|
||||||
{
|
|
||||||
char buf[1024];
|
|
||||||
std::string ret;
|
|
||||||
|
|
||||||
eof = false;
|
|
||||||
ret.clear();
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
if (gets(buf, sizeof(buf)) == NULL)
|
case 0xf0: // -w TEST
|
||||||
{
|
return 0;
|
||||||
eof = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret.append(buf);
|
case 0xf1: // -w CONTROL
|
||||||
}
|
return 0;
|
||||||
while (*ret.rbegin() != '\n');
|
|
||||||
|
|
||||||
return (ret);
|
case 0xf2: // rw DSPADDR
|
||||||
}
|
return (IAPU.RAM[Address]);
|
||||||
|
|
||||||
// snes9x.h STREAM reader
|
case 0xf3: // rw DSPDATA
|
||||||
|
return (S9xGetAPUDSP());
|
||||||
|
|
||||||
fReader::fReader (STREAM f)
|
case 0xf4: // r- CPUI0
|
||||||
{
|
case 0xf5: // r- CPUI1
|
||||||
fp = f;
|
case 0xf6: // r- CPUI2
|
||||||
}
|
case 0xf7: // r- CPUI3
|
||||||
|
#ifdef SPC700_SHUTDOWN
|
||||||
|
IAPU.WaitAddress2 = IAPU.WaitAddress1;
|
||||||
|
IAPU.WaitAddress1 = IAPU.PC;
|
||||||
|
#endif
|
||||||
|
return (IAPU.RAM[Address]);
|
||||||
|
|
||||||
fReader::~fReader (void)
|
case 0xf8: // rw - Normal RAM
|
||||||
{
|
case 0xf9: // rw - Normal RAM
|
||||||
return;
|
return (IAPU.RAM[Address]);
|
||||||
}
|
|
||||||
|
|
||||||
int fReader::get_char (void)
|
case 0xfa: // -w T0TARGET
|
||||||
{
|
case 0xfb: // -w T1TARGET
|
||||||
return (GETC_STREAM(fp));
|
case 0xfc: // -w T2TARGET
|
||||||
}
|
return 0;
|
||||||
|
|
||||||
char * fReader::gets (char *buf, size_t len)
|
case 0xfd: // r- T0OUT
|
||||||
{
|
case 0xfe: // r- T1OUT
|
||||||
return (GETS_STREAM(buf, len, fp));
|
case 0xff: // r- T2OUT
|
||||||
}
|
#ifdef SPC700_SHUTDOWN
|
||||||
|
IAPU.WaitAddress2 = IAPU.WaitAddress1;
|
||||||
size_t fReader::read (char *buf, size_t len)
|
IAPU.WaitAddress1 = IAPU.PC;
|
||||||
{
|
#endif
|
||||||
return (READ_STREAM(buf, len, fp));
|
uint8 t = IAPU.RAM[Address] & 0xF;
|
||||||
}
|
IAPU.RAM[Address] = 0;
|
||||||
|
return (t);
|
||||||
// unzip reader
|
|
||||||
|
|
||||||
#ifdef UNZIP_SUPPORT
|
|
||||||
|
|
||||||
unzReader::unzReader (unzFile &v)
|
|
||||||
{
|
|
||||||
file = v;
|
|
||||||
head = NULL;
|
|
||||||
numbytes = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
unzReader::~unzReader (void)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int unzReader::get_char (void)
|
|
||||||
{
|
|
||||||
unsigned char c;
|
|
||||||
|
|
||||||
if (numbytes <= 0)
|
|
||||||
{
|
|
||||||
numbytes = unzReadCurrentFile(file, buffer, unz_BUFFSIZ);
|
|
||||||
if (numbytes <= 0)
|
|
||||||
return (EOF);
|
|
||||||
head = buffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
c = *head;
|
return 0;
|
||||||
head++;
|
|
||||||
numbytes--;
|
|
||||||
|
|
||||||
return ((int) c);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char * unzReader::gets (char *buf, size_t len)
|
static INLINE void apu_set_reg (uint8 byte, uint8 Address)
|
||||||
{
|
{
|
||||||
size_t i;
|
switch (Address)
|
||||||
int c;
|
|
||||||
|
|
||||||
for (i = 0; i < len - 1; i++)
|
|
||||||
{
|
{
|
||||||
c = get_char();
|
case 0xf0: // -w TEST
|
||||||
if (c == EOF)
|
//printf("Write %02X to APU 0xF0!\n", byte);
|
||||||
{
|
return;
|
||||||
if (i == 0)
|
|
||||||
return (NULL);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
buf[i] = (char) c;
|
case 0xf1: // -w CONTROL
|
||||||
if (buf[i] == '\n')
|
S9xSetAPUControl(byte);
|
||||||
break;
|
return;
|
||||||
|
|
||||||
|
case 0xf2: // rw DSPADDR
|
||||||
|
IAPU.RAM[Address] = byte;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case 0xf3: // rw DSPDATA
|
||||||
|
S9xSetAPUDSP(byte);
|
||||||
|
return;
|
||||||
|
|
||||||
|
case 0xf4: // -w CPUO0
|
||||||
|
case 0xf5: // -w CPUO1
|
||||||
|
case 0xf6: // -w CPUO2
|
||||||
|
case 0xf7: // -w CPUO3
|
||||||
|
APU.OutPorts[Address - 0xf4] = byte;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case 0xf8: // rw - Normal RAM
|
||||||
|
case 0xf9: // rw - Normal RAM
|
||||||
|
IAPU.RAM[Address] = byte;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case 0xfa: // -w T0TARGET
|
||||||
|
case 0xfb: // -w T1TARGET
|
||||||
|
case 0xfc: // -w T2TARGET
|
||||||
|
IAPU.RAM[Address] = byte;
|
||||||
|
if (byte == 0)
|
||||||
|
APU.TimerTarget[Address - 0xfa] = 0x100;
|
||||||
|
else
|
||||||
|
APU.TimerTarget[Address - 0xfa] = byte;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case 0xfd: // r- T0OUT
|
||||||
|
case 0xfe: // r- T1OUT
|
||||||
|
case 0xff: // r- T2OUT
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf[i] = '\0';
|
|
||||||
|
|
||||||
return (buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t unzReader::read (char *buf, size_t len)
|
INLINE uint8 S9xAPUGetByteZ (uint8 Address)
|
||||||
{
|
{
|
||||||
if (len == 0)
|
if (Address >= 0xf0 && IAPU.DirectPage == IAPU.RAM)
|
||||||
return (len);
|
return (apu_get_reg(Address));
|
||||||
|
else
|
||||||
if (len <= numbytes)
|
return (IAPU.DirectPage[Address]);
|
||||||
{
|
|
||||||
memcpy(buf, head, len);
|
|
||||||
numbytes -= len;
|
|
||||||
head += len;
|
|
||||||
return (len);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t numread = 0;
|
|
||||||
if (numbytes > 0)
|
|
||||||
{
|
|
||||||
memcpy(buf, head, numbytes);
|
|
||||||
numread += numbytes;
|
|
||||||
head = NULL;
|
|
||||||
numbytes = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int l = unzReadCurrentFile(file, buf + numread, len - numread);
|
|
||||||
if (l > 0)
|
|
||||||
numread += l;
|
|
||||||
|
|
||||||
return (numread);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
INLINE void S9xAPUSetByteZ (uint8 byte, uint8 Address)
|
||||||
|
{
|
||||||
|
if (Address >= 0xf0 && IAPU.DirectPage == IAPU.RAM)
|
||||||
|
apu_set_reg(byte, Address);
|
||||||
|
else
|
||||||
|
IAPU.DirectPage[Address] = byte;
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE uint8 S9xAPUGetByte (uint32 Address)
|
||||||
|
{
|
||||||
|
Address &= 0xffff;
|
||||||
|
if (Address <= 0xff && Address >= 0xf0)
|
||||||
|
return (apu_get_reg(Address & 0xff));
|
||||||
|
else
|
||||||
|
return (IAPU.RAM[Address]);
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE void S9xAPUSetByte (uint8 byte, uint32 Address)
|
||||||
|
{
|
||||||
|
Address &= 0xffff;
|
||||||
|
if (Address <= 0xff && Address >= 0xf0)
|
||||||
|
apu_set_reg(byte, Address & 0xff);
|
||||||
|
else
|
||||||
|
if (Address < 0xffc0)
|
||||||
|
IAPU.RAM[Address] = byte;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
APU.ExtraRAM[Address - 0xffc0] = byte;
|
||||||
|
if (!APU.ShowROM)
|
||||||
|
IAPU.RAM[Address] = byte;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // _apumemory_h_
|
@ -158,47 +158,49 @@
|
|||||||
Nintendo Co., Limited and its subsidiary companies.
|
Nintendo Co., Limited and its subsidiary companies.
|
||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
// Dreamer Nom wrote:
|
|
||||||
|
|
||||||
|
|
||||||
|
// Anonymous wrote:
|
||||||
// Large thanks to John Weidman for all his initial research
|
// Large thanks to John Weidman for all his initial research
|
||||||
// Thanks to Seph3 for his modem notes
|
// Thanks to Seph3 for his modem notes
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
#include "snes9x.h"
|
|
||||||
#include "memmap.h"
|
#include "memmap.h"
|
||||||
#include "display.h"
|
#include "display.h"
|
||||||
|
#include "bsx.h"
|
||||||
|
|
||||||
//#define BSX_DEBUG
|
//#define BSX_DEBUG
|
||||||
|
|
||||||
#define BIOS_SIZE 0x100000
|
#define BIOS_SIZE 0x100000
|
||||||
#define FLASH_SIZE 0x200000
|
#define FLASH_SIZE 0x200000
|
||||||
#define PSRAM_SIZE 0x80000
|
#define PSRAM_SIZE 0x80000
|
||||||
|
|
||||||
#define Map Memory.Map
|
#define Map Memory.Map
|
||||||
#define BlockIsRAM Memory.BlockIsRAM
|
#define BlockIsRAM Memory.BlockIsRAM
|
||||||
#define BlockIsROM Memory.BlockIsROM
|
#define BlockIsROM Memory.BlockIsROM
|
||||||
#define RAM Memory.RAM
|
#define RAM Memory.RAM
|
||||||
#define SRAM Memory.SRAM
|
#define SRAM Memory.SRAM
|
||||||
#define PSRAM Memory.BSRAM
|
#define PSRAM Memory.BSRAM
|
||||||
#define BIOSROM Memory.BIOSROM
|
#define BIOSROM Memory.BIOSROM
|
||||||
#define MAP_BSX Memory.MAP_BSX
|
#define MAP_BSX Memory.MAP_BSX
|
||||||
#define MAP_CPU Memory.MAP_CPU
|
#define MAP_CPU Memory.MAP_CPU
|
||||||
#define MAP_PPU Memory.MAP_PPU
|
#define MAP_PPU Memory.MAP_PPU
|
||||||
#define MAP_NONE Memory.MAP_NONE
|
#define MAP_NONE Memory.MAP_NONE
|
||||||
|
|
||||||
#define BSXPPUBASE 0x2180
|
|
||||||
|
|
||||||
struct SBSX_RTC
|
struct SBSX_RTC
|
||||||
{
|
{
|
||||||
int hours;
|
int hours;
|
||||||
int minutes;
|
int minutes;
|
||||||
int seconds;
|
int seconds;
|
||||||
int ticks;
|
int ticks;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct SBSX_RTC BSX_RTC;
|
struct SBSX_RTC BSX_RTC;
|
||||||
|
|
||||||
// flash card vendor information
|
// flash card vendor information
|
||||||
static const uint8 flashcard[20] =
|
const uint8 flashcard[20] =
|
||||||
{
|
{
|
||||||
0x4D, 0x00, 0x50, 0x00, // vendor id
|
0x4D, 0x00, 0x50, 0x00, // vendor id
|
||||||
0x00, 0x00, // ?
|
0x00, 0x00, // ?
|
||||||
@ -207,7 +209,7 @@ static const uint8 flashcard[20] =
|
|||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint8 init2192[32] = // FIXME
|
const uint8 init2192[32] = // FIXME
|
||||||
{
|
{
|
||||||
00, 00, 00, 00, 00, // unknown
|
00, 00, 00, 00, 00, // unknown
|
||||||
01, 01, 00, 00, 00,
|
01, 01, 00, 00, 00,
|
||||||
@ -219,29 +221,29 @@ static const uint8 init2192[32] = // FIXME
|
|||||||
00, 00, 00, 00, 00, 00, 00, 00, 00
|
00, 00, 00, 00, 00, 00, 00, 00, 00
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool8 FlashMode;
|
bool8 FlashMode;
|
||||||
static uint32 FlashSize;
|
uint32 FlashSize;
|
||||||
static uint8 *MapROM, *FlashROM;
|
uint8 *MapROM, *FlashROM;
|
||||||
|
|
||||||
static void BSX_Map_SNES (void);
|
static void BSX_Map_SNES(void);
|
||||||
static void BSX_Map_LoROM (void);
|
static void BSX_Map_LoROM(void);
|
||||||
static void BSX_Map_HiROM (void);
|
static void BSX_Map_HiROM(void);
|
||||||
static void BSX_Map_MMC (void);
|
static void BSX_Map_MMC(void);
|
||||||
static void BSX_Map_FlashIO (void);
|
static void BSX_Map_FlashIO(void);
|
||||||
static void BSX_Map_SRAM (void);
|
static void BSX_Map_SRAM(void);
|
||||||
static void BSX_Map_PSRAM (void);
|
static void BSX_Map_PSRAM(void);
|
||||||
static void BSX_Map_BIOS (void);
|
static void BSX_Map_BIOS(void);
|
||||||
static void BSX_Map_RAM (void);
|
static void BSX_Map_RAM(void);
|
||||||
static void BSX_Map_Dirty (void);
|
static void BSX_Map_Dirty(void);
|
||||||
static void BSX_Map (void);
|
static void BSX_Map(void);
|
||||||
static void BSX_Set_Bypass_FlashIO (uint16, uint8);
|
static void BSX_Set_Bypass_FlashIO(uint16, uint8);
|
||||||
static uint8 BSX_Get_Bypass_FlashIO (uint16);
|
static uint8 BSX_Get_Bypass_FlashIO(uint16);
|
||||||
static bool8 BSX_LoadBIOS (void);
|
static bool8 BSX_LoadBIOS(void);
|
||||||
static void map_psram_mirror_sub (uint32);
|
static void map_psram_mirror_sub(uint32);
|
||||||
static int is_bsx (unsigned char *);
|
static int is_bsx(unsigned char *);
|
||||||
|
|
||||||
|
|
||||||
static void BSX_Map_SNES (void)
|
static void BSX_Map_SNES(void)
|
||||||
{
|
{
|
||||||
// These maps will be partially overwritten
|
// These maps will be partially overwritten
|
||||||
|
|
||||||
@ -264,7 +266,7 @@ static void BSX_Map_SNES (void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void BSX_Map_LoROM (void)
|
static void BSX_Map_LoROM(void)
|
||||||
{
|
{
|
||||||
// These maps will be partially overwritten
|
// These maps will be partially overwritten
|
||||||
|
|
||||||
@ -298,7 +300,7 @@ static void BSX_Map_LoROM (void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void BSX_Map_HiROM (void)
|
static void BSX_Map_HiROM(void)
|
||||||
{
|
{
|
||||||
// These maps will be partially overwritten
|
// These maps will be partially overwritten
|
||||||
|
|
||||||
@ -327,7 +329,7 @@ static void BSX_Map_HiROM (void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void BSX_Map_MMC (void)
|
static void BSX_Map_MMC(void)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
@ -339,7 +341,7 @@ static void BSX_Map_MMC (void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void BSX_Map_FlashIO (void)
|
static void BSX_Map_FlashIO(void)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
@ -355,7 +357,7 @@ static void BSX_Map_FlashIO (void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void BSX_Map_SRAM (void)
|
static void BSX_Map_SRAM(void)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
@ -368,7 +370,7 @@ static void BSX_Map_SRAM (void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void map_psram_mirror_sub (uint32 bank)
|
static void map_psram_mirror_sub(uint32 bank)
|
||||||
{
|
{
|
||||||
int i, c;
|
int i, c;
|
||||||
|
|
||||||
@ -405,7 +407,7 @@ static void map_psram_mirror_sub (uint32 bank)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void BSX_Map_PSRAM (void)
|
static void BSX_Map_PSRAM(void)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
@ -443,7 +445,7 @@ static void BSX_Map_PSRAM (void)
|
|||||||
map_psram_mirror_sub(0x60);
|
map_psram_mirror_sub(0x60);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void BSX_Map_BIOS (void)
|
static void BSX_Map_BIOS(void)
|
||||||
{
|
{
|
||||||
int i,c;
|
int i,c;
|
||||||
|
|
||||||
@ -476,7 +478,7 @@ static void BSX_Map_BIOS (void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void BSX_Map_RAM (void)
|
static void BSX_Map_RAM(void)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
@ -492,7 +494,7 @@ static void BSX_Map_RAM (void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void BSX_Map_Dirty (void)
|
static void BSX_Map_Dirty(void)
|
||||||
{
|
{
|
||||||
// for the quick bank change
|
// for the quick bank change
|
||||||
|
|
||||||
@ -525,7 +527,7 @@ static void BSX_Map_Dirty (void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void BSX_Map (void)
|
static void BSX_Map(void)
|
||||||
{
|
{
|
||||||
#ifdef BSX_DEBUG
|
#ifdef BSX_DEBUG
|
||||||
printf("BS: Remapping\n");
|
printf("BS: Remapping\n");
|
||||||
@ -580,20 +582,20 @@ static void BSX_Map (void)
|
|||||||
Memory.map_WriteProtectROM();
|
Memory.map_WriteProtectROM();
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8 BSX_Get_Bypass_FlashIO (uint16 offset)
|
static uint8 BSX_Get_Bypass_FlashIO(uint16 offset)
|
||||||
{
|
{
|
||||||
if (BSX.MMC[0x02])
|
if (BSX.MMC[0x02])
|
||||||
return (MapROM[offset]);
|
return MapROM[offset];
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (offset < 0x8000)
|
if (offset < 0x8000)
|
||||||
return (MapROM[offset]);
|
return MapROM[offset];
|
||||||
else
|
else
|
||||||
return (MapROM[offset - 0x8000]);
|
return MapROM[offset - 0x8000];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void BSX_Set_Bypass_FlashIO (uint16 offset, uint8 byte)
|
static void BSX_Set_Bypass_FlashIO(uint16 offset, uint8 byte)
|
||||||
{
|
{
|
||||||
if (BSX.MMC[0x02])
|
if (BSX.MMC[0x02])
|
||||||
MapROM[offset] = byte;
|
MapROM[offset] = byte;
|
||||||
@ -606,7 +608,7 @@ static void BSX_Set_Bypass_FlashIO (uint16 offset, uint8 byte)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 S9xGetBSX (uint32 address)
|
uint8 S9xGetBSX(uint32 address)
|
||||||
{
|
{
|
||||||
uint8 bank = (address >> 16) & 0xFF;
|
uint8 bank = (address >> 16) & 0xFF;
|
||||||
uint16 offset = address & 0xFFFF;
|
uint16 offset = address & 0xFFFF;
|
||||||
@ -614,7 +616,7 @@ uint8 S9xGetBSX (uint32 address)
|
|||||||
|
|
||||||
// MMC
|
// MMC
|
||||||
if ((bank >= 0x01 && bank <= 0x0E) && (offset == 0x5000))
|
if ((bank >= 0x01 && bank <= 0x0E) && (offset == 0x5000))
|
||||||
return (BSX.MMC[bank]);
|
return BSX.MMC[bank];
|
||||||
|
|
||||||
// Flash IO
|
// Flash IO
|
||||||
if (bank == 0xC0)
|
if (bank == 0xC0)
|
||||||
@ -652,10 +654,10 @@ uint8 S9xGetBSX (uint32 address)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (t);
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xSetBSX (uint8 byte, uint32 address)
|
void S9xSetBSX(uint8 byte, uint32 address)
|
||||||
{
|
{
|
||||||
uint8 bank = (address >> 16) & 0xFF;
|
uint8 bank = (address >> 16) & 0xFF;
|
||||||
uint16 offset = address & 0xFFFF;
|
uint16 offset = address & 0xFFFF;
|
||||||
@ -774,207 +776,210 @@ void S9xSetBSX (uint8 byte, uint32 address)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 S9xGetBSXPPU (uint16 address)
|
uint8 S9xGetBSXPPU(uint16 address)
|
||||||
{
|
{
|
||||||
uint8 t;
|
uint8 t = 0;
|
||||||
|
|
||||||
// known read registers
|
if (address >= 0x2188 && address <= 0x219F)
|
||||||
switch (address)
|
|
||||||
{
|
{
|
||||||
// Test register low? (r/w)
|
// known read registers
|
||||||
case 0x2188:
|
switch(address)
|
||||||
t = BSX.PPU[0x2188 - BSXPPUBASE];
|
{
|
||||||
break;
|
// Test register low? (r/w)
|
||||||
|
case 0x2188:
|
||||||
|
t = BSX.PPU[0x2188];
|
||||||
|
break;
|
||||||
|
|
||||||
// Test register high? (r/w)
|
// Test register high? (r/w)
|
||||||
case 0x2189:
|
case 0x2189:
|
||||||
t = BSX.PPU[0x2189 - BSXPPUBASE];
|
t = BSX.PPU[0x2189];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x218A:
|
case 0x218A:
|
||||||
t = BSX.PPU[0x218A - BSXPPUBASE];
|
t = BSX.PPU[0x218A];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x218C:
|
case 0x218C:
|
||||||
t = BSX.PPU[0x218C - BSXPPUBASE];
|
t = BSX.PPU[0x218C];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Transmission number low? (r/w)
|
// Transmission number low? (r/w)
|
||||||
case 0x218E:
|
case 0x218E:
|
||||||
t = BSX.PPU[0x218E - BSXPPUBASE];
|
t = BSX.PPU[0x218E];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Transmission number high? (r/w)
|
// Transmission number high? (r/w)
|
||||||
case 0x218F:
|
case 0x218F:
|
||||||
t = BSX.PPU[0x218F - BSXPPUBASE];
|
t = BSX.PPU[0x218F];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Status register? (r)
|
// Status register? (r)
|
||||||
case 0x2190:
|
case 0x2190:
|
||||||
t = BSX.PPU[0x2190 - BSXPPUBASE];
|
t = BSX.PPU[0x2190];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Data register? (r/w)
|
// Data register? (r/w)
|
||||||
case 0x2192:
|
case 0x2192:
|
||||||
t = BSX.PPU[0x2192 - BSXPPUBASE];
|
t = BSX.PPU[0x2192];
|
||||||
|
|
||||||
// test
|
// test
|
||||||
t = BSX.test2192[BSX.out_index++];
|
t = BSX.test2192[BSX.out_index++];
|
||||||
if (BSX.out_index == 32)
|
if (BSX.out_index == 32)
|
||||||
|
BSX.out_index = 0;
|
||||||
|
|
||||||
|
BSX_RTC.ticks++;
|
||||||
|
if (BSX_RTC.ticks >= 1000)
|
||||||
|
{
|
||||||
|
BSX_RTC.ticks = 0;
|
||||||
|
BSX_RTC.seconds++;
|
||||||
|
}
|
||||||
|
if (BSX_RTC.seconds >= 60)
|
||||||
|
{
|
||||||
|
BSX_RTC.seconds = 0;
|
||||||
|
BSX_RTC.minutes++;
|
||||||
|
}
|
||||||
|
if (BSX_RTC.minutes >= 60)
|
||||||
|
{
|
||||||
|
BSX_RTC.minutes = 0;
|
||||||
|
BSX_RTC.hours++;
|
||||||
|
}
|
||||||
|
if (BSX_RTC.hours >= 24)
|
||||||
|
BSX_RTC.hours = 0;
|
||||||
|
|
||||||
|
BSX.test2192[10] = BSX_RTC.seconds;
|
||||||
|
BSX.test2192[11] = BSX_RTC.minutes;
|
||||||
|
BSX.test2192[12] = BSX_RTC.hours;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Transmission status? (r/w)
|
||||||
|
case 0x2193:
|
||||||
|
// Data ready when bits 2/3 clear?
|
||||||
|
t = BSX.PPU[0x2193] & ~0x0C;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Reset? (r/w)
|
||||||
|
case 0x2194:
|
||||||
|
t = BSX.PPU[0x2194];
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Unknown (r)
|
||||||
|
case 0x2196:
|
||||||
|
t = BSX.PPU[0x2196];
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Unknown (r/w)
|
||||||
|
case 0x2197:
|
||||||
|
t = BSX.PPU[0x2197];
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Modem protocol? (r/w)
|
||||||
|
case 0x2199:
|
||||||
|
t = BSX.PPU[0x2199];
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
t = OpenBus;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
void S9xSetBSXPPU(uint8 byte, uint16 address)
|
||||||
|
{
|
||||||
|
if (address >= 0x2188 && address <= 0x219F)
|
||||||
|
{
|
||||||
|
// known write registers
|
||||||
|
switch(address)
|
||||||
|
{
|
||||||
|
// Test register low? (r/w)
|
||||||
|
case 0x2188:
|
||||||
|
BSX.PPU[0x2188] = byte;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Test register high? (r/w)
|
||||||
|
case 0x2189:
|
||||||
|
BSX.PPU[0x2189] = byte;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x218A:
|
||||||
|
BSX.PPU[0x218A] = byte;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x218B:
|
||||||
|
BSX.PPU[0x218B] = byte;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x218C:
|
||||||
|
BSX.PPU[0x218C] = byte;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Transmission number low? (r/w)
|
||||||
|
case 0x218E:
|
||||||
|
BSX.PPU[0x218E] = byte;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Transmission number high? (r/w)
|
||||||
|
case 0x218F:
|
||||||
|
BSX.PPU[0x218F] = byte;
|
||||||
|
|
||||||
|
// ?
|
||||||
|
BSX.PPU[0x218E] >>= 1;
|
||||||
|
BSX.PPU[0x218E] = BSX.PPU[0x218F] - BSX.PPU[0x218E];
|
||||||
|
BSX.PPU[0x218F] >>= 1;
|
||||||
|
|
||||||
|
BSX.PPU[0x2190] = 0x80; // ?
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Strobe assert? (w)
|
||||||
|
case 0x2191:
|
||||||
|
BSX.PPU[0x2191] = byte;
|
||||||
BSX.out_index = 0;
|
BSX.out_index = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
BSX_RTC.ticks++;
|
// Data register? (r/w)
|
||||||
if (BSX_RTC.ticks >= 1000)
|
case 0x2192:
|
||||||
{
|
BSX.PPU[0x2192] = 0x01; // ?
|
||||||
BSX_RTC.ticks = 0;
|
BSX.PPU[0x2190] = 0x80; // ?
|
||||||
BSX_RTC.seconds++;
|
break;
|
||||||
}
|
|
||||||
if (BSX_RTC.seconds >= 60)
|
|
||||||
{
|
|
||||||
BSX_RTC.seconds = 0;
|
|
||||||
BSX_RTC.minutes++;
|
|
||||||
}
|
|
||||||
if (BSX_RTC.minutes >= 60)
|
|
||||||
{
|
|
||||||
BSX_RTC.minutes = 0;
|
|
||||||
BSX_RTC.hours++;
|
|
||||||
}
|
|
||||||
if (BSX_RTC.hours >= 24)
|
|
||||||
BSX_RTC.hours = 0;
|
|
||||||
|
|
||||||
BSX.test2192[10] = BSX_RTC.seconds;
|
// Transmission status? (r/w)
|
||||||
BSX.test2192[11] = BSX_RTC.minutes;
|
case 0x2193:
|
||||||
BSX.test2192[12] = BSX_RTC.hours;
|
BSX.PPU[0x2193] = byte;
|
||||||
|
break;
|
||||||
|
|
||||||
break;
|
// Reset? (r/w)
|
||||||
|
case 0x2194:
|
||||||
|
BSX.PPU[0x2194] = byte;
|
||||||
|
break;
|
||||||
|
|
||||||
// Transmission status? (r/w)
|
// Unknown (r/w)
|
||||||
case 0x2193:
|
case 0x2197:
|
||||||
// Data ready when bits 2/3 clear?
|
BSX.PPU[0x2197] = byte;
|
||||||
t = BSX.PPU[0x2193 - BSXPPUBASE] & ~0x0C;
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
// Reset? (r/w)
|
// Modem protocol? (r/w)
|
||||||
case 0x2194:
|
case 0x2199:
|
||||||
t = BSX.PPU[0x2194 - BSXPPUBASE];
|
// Lots of modem strings written here when
|
||||||
break;
|
// connection is lost or no uplink established
|
||||||
|
BSX.PPU[0x2199] = byte;
|
||||||
// Unknown (r)
|
break;
|
||||||
case 0x2196:
|
}
|
||||||
t = BSX.PPU[0x2196 - BSXPPUBASE];
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Unknown (r/w)
|
|
||||||
case 0x2197:
|
|
||||||
t = BSX.PPU[0x2197 - BSXPPUBASE];
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Modem protocol? (r/w)
|
|
||||||
case 0x2199:
|
|
||||||
t = BSX.PPU[0x2199 - BSXPPUBASE];
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
t = OpenBus;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (t);
|
|
||||||
}
|
|
||||||
|
|
||||||
void S9xSetBSXPPU (uint8 byte, uint16 address)
|
|
||||||
{
|
|
||||||
// known write registers
|
|
||||||
switch (address)
|
|
||||||
{
|
|
||||||
// Test register low? (r/w)
|
|
||||||
case 0x2188:
|
|
||||||
BSX.PPU[0x2188 - BSXPPUBASE] = byte;
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Test register high? (r/w)
|
|
||||||
case 0x2189:
|
|
||||||
BSX.PPU[0x2189 - BSXPPUBASE] = byte;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x218A:
|
|
||||||
BSX.PPU[0x218A - BSXPPUBASE] = byte;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x218B:
|
|
||||||
BSX.PPU[0x218B - BSXPPUBASE] = byte;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x218C:
|
|
||||||
BSX.PPU[0x218C - BSXPPUBASE] = byte;
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Transmission number low? (r/w)
|
|
||||||
case 0x218E:
|
|
||||||
BSX.PPU[0x218E - BSXPPUBASE] = byte;
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Transmission number high? (r/w)
|
|
||||||
case 0x218F:
|
|
||||||
BSX.PPU[0x218F - BSXPPUBASE] = byte;
|
|
||||||
|
|
||||||
// ?
|
|
||||||
BSX.PPU[0x218E - BSXPPUBASE] >>= 1;
|
|
||||||
BSX.PPU[0x218E - BSXPPUBASE] = BSX.PPU[0x218F - BSXPPUBASE] - BSX.PPU[0x218E - BSXPPUBASE];
|
|
||||||
BSX.PPU[0x218F - BSXPPUBASE] >>= 1;
|
|
||||||
|
|
||||||
BSX.PPU[0x2190 - BSXPPUBASE] = 0x80; // ?
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Strobe assert? (w)
|
|
||||||
case 0x2191:
|
|
||||||
BSX.PPU[0x2191 - BSXPPUBASE] = byte;
|
|
||||||
BSX.out_index = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Data register? (r/w)
|
|
||||||
case 0x2192:
|
|
||||||
BSX.PPU[0x2192 - BSXPPUBASE] = 0x01; // ?
|
|
||||||
BSX.PPU[0x2190 - BSXPPUBASE] = 0x80; // ?
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Transmission status? (r/w)
|
|
||||||
case 0x2193:
|
|
||||||
BSX.PPU[0x2193 - BSXPPUBASE] = byte;
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Reset? (r/w)
|
|
||||||
case 0x2194:
|
|
||||||
BSX.PPU[0x2194 - BSXPPUBASE] = byte;
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Unknown (r/w)
|
|
||||||
case 0x2197:
|
|
||||||
BSX.PPU[0x2197 - BSXPPUBASE] = byte;
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Modem protocol? (r/w)
|
|
||||||
case 0x2199:
|
|
||||||
// Lots of modem strings written here when
|
|
||||||
// connection is lost or no uplink established
|
|
||||||
BSX.PPU[0x2199 - BSXPPUBASE] = byte;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 * S9xGetBasePointerBSX (uint32 address)
|
uint8 * S9xGetBasePointerBSX(uint32 address)
|
||||||
{
|
{
|
||||||
return (MapROM);
|
return MapROM;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool8 BSX_LoadBIOS (void)
|
static bool8 BSX_LoadBIOS(void)
|
||||||
{
|
{
|
||||||
#ifdef GEKKO
|
|
||||||
return FALSE; // We're not loading the BIOS!
|
return FALSE; // We're not loading the BIOS!
|
||||||
#endif
|
|
||||||
|
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char path[PATH_MAX + 1], name[PATH_MAX + 1];
|
char path[_MAX_PATH + 1], name[_MAX_PATH + 1];
|
||||||
bool8 r = FALSE;
|
bool8 r = FALSE;
|
||||||
|
|
||||||
strcpy(path, S9xGetDirectory(BIOS_DIR));
|
strcpy(path, S9xGetDirectory(BIOS_DIR));
|
||||||
@ -1007,10 +1012,10 @@ static bool8 BSX_LoadBIOS (void)
|
|||||||
printf("BS: BIOS not found!\n");
|
printf("BS: BIOS not found!\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return (r);
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xInitBSX (void)
|
void S9xInitBSX(void)
|
||||||
{
|
{
|
||||||
Settings.BS = FALSE;
|
Settings.BS = FALSE;
|
||||||
|
|
||||||
@ -1092,7 +1097,7 @@ void S9xInitBSX (void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xResetBSX (void)
|
void S9xResetBSX(void)
|
||||||
{
|
{
|
||||||
if (Settings.BSXItself)
|
if (Settings.BSXItself)
|
||||||
memset(Memory.ROM, 0, FLASH_SIZE);
|
memset(Memory.ROM, 0, FLASH_SIZE);
|
||||||
@ -1144,7 +1149,7 @@ void S9xResetBSX (void)
|
|||||||
BSX_Map();
|
BSX_Map();
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xBSXPostLoadState (void)
|
void S9xFixBSXAfterSnapshotLoad(void)
|
||||||
{
|
{
|
||||||
uint8 temp[16];
|
uint8 temp[16];
|
||||||
bool8 pd1, pd2;
|
bool8 pd1, pd2;
|
||||||
@ -1161,30 +1166,34 @@ void S9xBSXPostLoadState (void)
|
|||||||
BSX.dirty2 = pd2;
|
BSX.dirty2 = pd2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool valid_normal_bank (unsigned char bankbyte)
|
static bool valid_normal_bank(unsigned char bankbyte)
|
||||||
{
|
{
|
||||||
switch (bankbyte)
|
switch (bankbyte)
|
||||||
{
|
{
|
||||||
case 32: case 33: case 48: case 49:
|
case 32: case 33: case 48: case 49:
|
||||||
return (true);
|
return(true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
return(false);
|
||||||
return (false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int is_bsx (unsigned char *p)
|
static int is_bsx(unsigned char *p)
|
||||||
{
|
{
|
||||||
if ((p[26] == 0x33 || p[26] == 0xFF) && (!p[21] || (p[21] & 131) == 128) && valid_normal_bank(p[24]))
|
if ((p[26] == 0x33 || p[26] == 0xFF) &&
|
||||||
{
|
(!p[21] || (p[21] & 131) == 128) &&
|
||||||
unsigned char m = p[22];
|
valid_normal_bank(p[24]))
|
||||||
|
{
|
||||||
if (!m && !p[23])
|
unsigned char m = p[22];
|
||||||
return (2);
|
if (!m && !p[23])
|
||||||
|
{
|
||||||
if ((m == 0xFF && p[23] == 0xFF) || (!(m & 0xF) && ((m >> 4) - 1 < 12)))
|
return(2);
|
||||||
return (1);
|
}
|
||||||
}
|
if ((m == 0xFF && p[23] == 0xFF) ||
|
||||||
|
(!(m & 0xF) && ((m >> 4) - 1 < 12)))
|
||||||
return (0);
|
{
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,6 +159,8 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _BSX_H_
|
#ifndef _BSX_H_
|
||||||
#define _BSX_H_
|
#define _BSX_H_
|
||||||
|
|
||||||
@ -181,15 +183,17 @@ struct SBSX
|
|||||||
uint8 test2192[32];
|
uint8 test2192[32];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
START_EXTERN_C
|
||||||
extern struct SBSX BSX;
|
extern struct SBSX BSX;
|
||||||
|
|
||||||
uint8 S9xGetBSX (uint32);
|
uint8 S9xGetBSX(uint32);
|
||||||
void S9xSetBSX (uint8, uint32);
|
void S9xSetBSX(uint8, uint32);
|
||||||
uint8 S9xGetBSXPPU (uint16);
|
uint8 S9xGetBSXPPU(uint16);
|
||||||
void S9xSetBSXPPU (uint8, uint16);
|
void S9xSetBSXPPU(uint8, uint16);
|
||||||
uint8 * S9xGetBasePointerBSX (uint32);
|
uint8 * S9xGetBasePointerBSX(uint32);
|
||||||
void S9xInitBSX (void);
|
void S9xInitBSX(void);
|
||||||
void S9xResetBSX (void);
|
void S9xResetBSX(void);
|
||||||
void S9xBSXPostLoadState (void);
|
void S9xFixBSXAfterSnapshotLoad(void);
|
||||||
|
END_EXTERN_C
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -159,146 +159,155 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include "snes9x.h"
|
#include <stdlib.h>
|
||||||
|
#include "c4.h"
|
||||||
#include "memmap.h"
|
#include "memmap.h"
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
#define C4_PI 3.14159265
|
short C4WFXVal;
|
||||||
|
short C4WFYVal;
|
||||||
|
short C4WFZVal;
|
||||||
|
short C4WFX2Val;
|
||||||
|
short C4WFY2Val;
|
||||||
|
short C4WFDist;
|
||||||
|
short C4WFScale;
|
||||||
|
|
||||||
int16 C4WFXVal;
|
static double tanval;
|
||||||
int16 C4WFYVal;
|
static double c4x, c4y, c4z;
|
||||||
int16 C4WFZVal;
|
static double c4x2, c4y2, c4z2;
|
||||||
int16 C4WFX2Val;
|
|
||||||
int16 C4WFY2Val;
|
|
||||||
int16 C4WFDist;
|
|
||||||
int16 C4WFScale;
|
|
||||||
int16 C41FXVal;
|
|
||||||
int16 C41FYVal;
|
|
||||||
int16 C41FAngleRes;
|
|
||||||
int16 C41FDist;
|
|
||||||
int16 C41FDistVal;
|
|
||||||
|
|
||||||
static double tanval;
|
void C4TransfWireFrame ()
|
||||||
static double c4x, c4y, c4z;
|
|
||||||
static double c4x2, c4y2, c4z2;
|
|
||||||
|
|
||||||
|
|
||||||
void C4TransfWireFrame (void)
|
|
||||||
{
|
{
|
||||||
c4x = (double) C4WFXVal;
|
c4x = (double) C4WFXVal;
|
||||||
c4y = (double) C4WFYVal;
|
c4y = (double) C4WFYVal;
|
||||||
c4z = (double) C4WFZVal - 0x95;
|
c4z = (double) C4WFZVal - 0x95;
|
||||||
|
|
||||||
// Rotate X
|
// Rotate X
|
||||||
tanval = -(double) C4WFX2Val * C4_PI * 2 / 128;
|
tanval = -(double) C4WFX2Val * 3.14159265 * 2 / 128;
|
||||||
c4y2 = c4y * cos(tanval) - c4z * sin(tanval);
|
c4y2 = c4y * cos (tanval) - c4z * sin (tanval);
|
||||||
c4z2 = c4y * sin(tanval) + c4z * cos(tanval);
|
c4z2 = c4y * sin (tanval) + c4z * cos (tanval);
|
||||||
|
|
||||||
// Rotate Y
|
// Rotate Y
|
||||||
tanval = -(double) C4WFY2Val * C4_PI * 2 / 128;
|
tanval = -(double)C4WFY2Val*3.14159265*2/128;
|
||||||
c4x2 = c4x * cos(tanval) + c4z2 * sin(tanval);
|
c4x2 = c4x * cos (tanval) + c4z2 * sin (tanval);
|
||||||
c4z = c4x * -sin(tanval) + c4z2 * cos(tanval);
|
c4z = c4x * - sin (tanval) + c4z2 * cos (tanval);
|
||||||
|
|
||||||
// Rotate Z
|
// Rotate Z
|
||||||
tanval = -(double) C4WFDist * C4_PI * 2 / 128;
|
tanval = -(double) C4WFDist * 3.14159265*2 / 128;
|
||||||
c4x = c4x2 * cos(tanval) - c4y2 * sin(tanval);
|
c4x = c4x2 * cos (tanval) - c4y2 * sin (tanval);
|
||||||
c4y = c4x2 * sin(tanval) + c4y2 * cos(tanval);
|
c4y = c4x2 * sin (tanval) + c4y2 * cos (tanval);
|
||||||
|
|
||||||
// Scale
|
// Scale
|
||||||
C4WFXVal = (int16) (c4x * (double) C4WFScale / (0x90 * (c4z + 0x95)) * 0x95);
|
C4WFXVal = (short) (c4x*(double)C4WFScale/(0x90*(c4z+0x95))*0x95);
|
||||||
C4WFYVal = (int16) (c4y * (double) C4WFScale / (0x90 * (c4z + 0x95)) * 0x95);
|
C4WFYVal = (short) (c4y*(double)C4WFScale/(0x90*(c4z+0x95))*0x95);
|
||||||
}
|
}
|
||||||
|
|
||||||
void C4TransfWireFrame2 (void)
|
void C4TransfWireFrame2 ()
|
||||||
{
|
{
|
||||||
c4x = (double) C4WFXVal;
|
c4x = (double)C4WFXVal;
|
||||||
c4y = (double) C4WFYVal;
|
c4y = (double)C4WFYVal;
|
||||||
c4z = (double) C4WFZVal;
|
c4z = (double)C4WFZVal;
|
||||||
|
|
||||||
// Rotate X
|
// Rotate X
|
||||||
tanval = -(double) C4WFX2Val * C4_PI * 2 / 128;
|
tanval = -(double) C4WFX2Val * 3.14159265 * 2 / 128;
|
||||||
c4y2 = c4y * cos(tanval) - c4z * sin(tanval);
|
c4y2 = c4y * cos (tanval) - c4z * sin (tanval);
|
||||||
c4z2 = c4y * sin(tanval) + c4z * cos(tanval);
|
c4z2 = c4y * sin (tanval) + c4z * cos (tanval);
|
||||||
|
|
||||||
// Rotate Y
|
// Rotate Y
|
||||||
tanval = -(double) C4WFY2Val * C4_PI * 2 / 128;
|
tanval = -(double) C4WFY2Val * 3.14159265 * 2 / 128;
|
||||||
c4x2 = c4x * cos(tanval) + c4z2 * sin(tanval);
|
c4x2 = c4x * cos (tanval) + c4z2 * sin (tanval);
|
||||||
c4z = c4x * -sin(tanval) + c4z2 * cos(tanval);
|
c4z = c4x * -sin (tanval) + c4z2 * cos (tanval);
|
||||||
|
|
||||||
// Rotate Z
|
// Rotate Z
|
||||||
tanval = -(double) C4WFDist * C4_PI * 2 / 128;
|
tanval = -(double)C4WFDist * 3.14159265 * 2 / 128;
|
||||||
c4x = c4x2 * cos(tanval) - c4y2 * sin(tanval);
|
c4x = c4x2 * cos (tanval) - c4y2 * sin (tanval);
|
||||||
c4y = c4x2 * sin(tanval) + c4y2 * cos(tanval);
|
c4y = c4x2 * sin (tanval) + c4y2 * cos (tanval);
|
||||||
|
|
||||||
// Scale
|
// Scale
|
||||||
C4WFXVal = (int16) (c4x * (double) C4WFScale / 0x100);
|
C4WFXVal =(short)(c4x * (double)C4WFScale / 0x100);
|
||||||
C4WFYVal = (int16) (c4y * (double) C4WFScale / 0x100);
|
C4WFYVal =(short)(c4y * (double)C4WFScale / 0x100);
|
||||||
}
|
}
|
||||||
|
|
||||||
void C4CalcWireFrame (void)
|
void C4CalcWireFrame ()
|
||||||
{
|
{
|
||||||
C4WFXVal = C4WFX2Val - C4WFXVal;
|
C4WFXVal = C4WFX2Val - C4WFXVal;
|
||||||
C4WFYVal = C4WFY2Val - C4WFYVal;
|
C4WFYVal = C4WFY2Val - C4WFYVal;
|
||||||
|
if (abs (C4WFXVal) > abs (C4WFYVal))
|
||||||
if (abs(C4WFXVal) > abs(C4WFYVal))
|
{
|
||||||
{
|
C4WFDist = abs (C4WFXVal) + 1;
|
||||||
C4WFDist = abs(C4WFXVal) + 1;
|
C4WFYVal = (short) (256 * (double) C4WFYVal / abs (C4WFXVal));
|
||||||
C4WFYVal = (int16) (256 * (double) C4WFYVal / abs(C4WFXVal));
|
if (C4WFXVal < 0)
|
||||||
if (C4WFXVal < 0)
|
C4WFXVal = -256;
|
||||||
C4WFXVal = -256;
|
else
|
||||||
else
|
C4WFXVal = 256;
|
||||||
C4WFXVal = 256;
|
}
|
||||||
}
|
else
|
||||||
else
|
{
|
||||||
{
|
if (C4WFYVal != 0)
|
||||||
if (C4WFYVal != 0)
|
{
|
||||||
{
|
C4WFDist = abs(C4WFYVal)+1;
|
||||||
C4WFDist = abs(C4WFYVal) + 1;
|
C4WFXVal = (short) (256 * (double)C4WFXVal / abs (C4WFYVal));
|
||||||
C4WFXVal = (int16) (256 * (double) C4WFXVal / abs(C4WFYVal));
|
if (C4WFYVal < 0)
|
||||||
if (C4WFYVal < 0)
|
C4WFYVal = -256;
|
||||||
C4WFYVal = -256;
|
else
|
||||||
else
|
C4WFYVal = 256;
|
||||||
C4WFYVal = 256;
|
}
|
||||||
}
|
else
|
||||||
else
|
C4WFDist = 0;
|
||||||
C4WFDist = 0;
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void C4Op1F (void)
|
short C41FXVal;
|
||||||
|
short C41FYVal;
|
||||||
|
short C41FAngleRes;
|
||||||
|
short C41FDist;
|
||||||
|
short C41FDistVal;
|
||||||
|
|
||||||
|
void C4Op1F ()
|
||||||
{
|
{
|
||||||
if (C41FXVal == 0)
|
if (C41FXVal == 0)
|
||||||
{
|
{
|
||||||
if (C41FYVal > 0)
|
if (C41FYVal > 0)
|
||||||
C41FAngleRes = 0x80;
|
C41FAngleRes = 0x80;
|
||||||
else
|
else
|
||||||
C41FAngleRes = 0x180;
|
C41FAngleRes = 0x180;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tanval = (double) C41FYVal / C41FXVal;
|
tanval = (double) C41FYVal / C41FXVal;
|
||||||
C41FAngleRes = (int16) (atan(tanval) / (C4_PI * 2) * 512);
|
C41FAngleRes = (short) (atan (tanval) / (3.141592675 * 2) * 512);
|
||||||
C41FAngleRes = C41FAngleRes;
|
C41FAngleRes = C41FAngleRes;
|
||||||
if (C41FXVal< 0)
|
if (C41FXVal< 0)
|
||||||
C41FAngleRes += 0x100;
|
C41FAngleRes += 0x100;
|
||||||
C41FAngleRes &= 0x1FF;
|
C41FAngleRes &= 0x1FF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void C4Op15 (void)
|
void C4Op15()
|
||||||
{
|
{
|
||||||
tanval = sqrt((double) C41FYVal * C41FYVal + (double) C41FXVal * C41FXVal);
|
tanval = sqrt ((double) C41FYVal * C41FYVal + (double) C41FXVal * C41FXVal);
|
||||||
C41FDist = (int16) tanval;
|
C41FDist = (short) tanval;
|
||||||
}
|
}
|
||||||
|
|
||||||
void C4Op0D (void)
|
void C4Op0D()
|
||||||
{
|
{
|
||||||
tanval = sqrt((double) C41FYVal * C41FYVal + (double) C41FXVal * C41FXVal);
|
tanval = sqrt ((double) C41FYVal * C41FYVal + (double) C41FXVal * C41FXVal);
|
||||||
tanval = C41FDistVal / tanval;
|
tanval = C41FDistVal / tanval;
|
||||||
C41FYVal = (int16) (C41FYVal * tanval * 0.99);
|
C41FYVal = (short) (C41FYVal * tanval * 0.99);
|
||||||
C41FXVal = (int16) (C41FXVal * tanval * 0.98);
|
C41FXVal = (short) (C41FXVal * tanval * 0.98);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ZSNES_C4
|
||||||
|
EXTERN_C void C4LoaDMem(char *C4RAM)
|
||||||
|
{
|
||||||
|
memmove(C4RAM+(READ_WORD(C4RAM+0x1f45)&0x1fff),
|
||||||
|
C4GetMemPointer(READ_3WORD(C4RAM+0x1f40)),
|
||||||
|
READ_WORD(C4RAM+0x1f43));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
uint8 * S9xGetBasePointerC4 (uint16 Address)
|
uint8 * S9xGetBasePointerC4 (uint16 Address)
|
||||||
{
|
{
|
||||||
if (Address >= 0x7f40 && Address <= 0x7f5e)
|
if (Address >= 0x7f40 && Address <= 0x7f5e)
|
||||||
@ -313,13 +322,4 @@ uint8 * S9xGetMemPointerC4 (uint16 Address)
|
|||||||
return (Memory.C4RAM - 0x6000 + (Address & 0xffff));
|
return (Memory.C4RAM - 0x6000 + (Address & 0xffff));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ZSNES_C4
|
}//end extern C
|
||||||
START_EXTERN_C
|
|
||||||
|
|
||||||
void C4LoaDMem (char *C4RAM)
|
|
||||||
{
|
|
||||||
memmove(C4RAM + (READ_WORD(C4RAM + 0x1f45) & 0x1fff), C4GetMemPointer(READ_3WORD(C4RAM + 0x1f40)), READ_WORD(C4RAM + 0x1f43));
|
|
||||||
}
|
|
||||||
|
|
||||||
END_EXTERN_C
|
|
||||||
#endif
|
|
||||||
|
@ -159,50 +159,45 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _C4_H_
|
#ifndef _C4_H_
|
||||||
#define _C4_H_
|
#define _C4_H_
|
||||||
|
|
||||||
extern int16 C4WFXVal;
|
#include "port.h"
|
||||||
extern int16 C4WFYVal;
|
#include "memmap.h"
|
||||||
extern int16 C4WFZVal;
|
|
||||||
extern int16 C4WFX2Val;
|
|
||||||
extern int16 C4WFY2Val;
|
|
||||||
extern int16 C4WFDist;
|
|
||||||
extern int16 C4WFScale;
|
|
||||||
extern int16 C41FXVal;
|
|
||||||
extern int16 C41FYVal;
|
|
||||||
extern int16 C41FAngleRes;
|
|
||||||
extern int16 C41FDist;
|
|
||||||
extern int16 C41FDistVal;
|
|
||||||
|
|
||||||
#ifdef ZSNES_C4
|
extern "C" {
|
||||||
extern uint8 *C4Ram;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ZSNES_C4
|
extern int16 C4WFXVal;
|
||||||
START_EXTERN_C
|
extern int16 C4WFYVal;
|
||||||
#endif
|
extern int16 C4WFZVal;
|
||||||
|
extern int16 C4WFX2Val;
|
||||||
|
extern int16 C4WFY2Val;
|
||||||
|
extern int16 C4WFDist;
|
||||||
|
extern int16 C4WFScale;
|
||||||
|
|
||||||
void C4TransfWireFrame (void);
|
void C4TransfWireFrame();
|
||||||
void C4TransfWireFrame2 (void);
|
void C4TransfWireFrame2();
|
||||||
void C4CalcWireFrame (void);
|
void C4CalcWireFrame();
|
||||||
void C4Op0D (void);
|
|
||||||
void C4Op15 (void);
|
|
||||||
void C4Op1F (void);
|
|
||||||
void S9xInitC4 (void);
|
|
||||||
void S9xSetC4 (uint8, uint16);
|
|
||||||
uint8 S9xGetC4 (uint16);
|
|
||||||
|
|
||||||
#ifdef ZSNES_C4
|
extern int16 C41FXVal;
|
||||||
END_EXTERN_C
|
extern int16 C41FYVal;
|
||||||
#endif
|
extern int16 C41FAngleRes;
|
||||||
|
extern int16 C41FDist;
|
||||||
|
extern int16 C41FDistVal;
|
||||||
|
|
||||||
uint8 * S9xGetBasePointerC4 (uint16);
|
void C4Op1F();
|
||||||
uint8 * S9xGetMemPointerC4 (uint16);
|
void C4Op15();
|
||||||
|
void C4Op0D();
|
||||||
|
|
||||||
static inline uint8 * C4GetMemPointer (uint32 Address)
|
extern int16 C4CosTable[];
|
||||||
{
|
extern int16 C4SinTable[];
|
||||||
return (Memory.ROM + ((Address & 0xff0000) >> 1) + (Address & 0x7fff));
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint8 *C4GetMemPointer(uint32 Address){
|
||||||
|
return (Memory.ROM + ((Address&0xff0000)>>1) + (Address&0x7fff));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -159,404 +159,426 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <string.h>
|
||||||
#include "snes9x.h"
|
#include "snes9x.h"
|
||||||
#include "memmap.h"
|
|
||||||
#include "cheats.h"
|
#include "cheats.h"
|
||||||
|
#include "memmap.h"
|
||||||
#define WRAM_BITS ALL_BITS
|
|
||||||
#define SRAM_BITS ALL_BITS + (0x20000 >> 5)
|
|
||||||
#define IRAM_BITS ALL_BITS + (0x30000 >> 5)
|
|
||||||
|
|
||||||
#define BIT_CLEAR(a, v) (a)[(v) >> 5] &= ~(1 << ((v) & 31))
|
|
||||||
|
|
||||||
#define TEST_BIT(a, v) ((a)[(v) >> 5] & (1 << ((v) & 31)))
|
|
||||||
|
|
||||||
#define _S9XCHTC(c, a, b) \
|
|
||||||
((c) == S9X_LESS_THAN ? (a) < (b) : \
|
|
||||||
(c) == S9X_GREATER_THAN ? (a) > (b) : \
|
|
||||||
(c) == S9X_LESS_THAN_OR_EQUAL ? (a) <= (b) : \
|
|
||||||
(c) == S9X_GREATER_THAN_OR_EQUAL ? (a) >= (b) : \
|
|
||||||
(c) == S9X_EQUAL ? (a) == (b) : \
|
|
||||||
(a) != (b))
|
|
||||||
|
|
||||||
#define _S9XCHTD(s, m, o) \
|
|
||||||
((s) == S9X_8_BITS ? ((uint8) (*((m) + (o)))) : \
|
|
||||||
(s) == S9X_16_BITS ? ((uint16) (*((m) + (o)) + (*((m) + (o) + 1) << 8))) : \
|
|
||||||
(s) == S9X_24_BITS ? ((uint32) (*((m) + (o)) + (*((m) + (o) + 1) << 8) + (*((m) + (o) + 2) << 16))) : \
|
|
||||||
((uint32) (*((m) + (o)) + (*((m) + (o) + 1) << 8) + (*((m) + (o) + 2) << 16) + (*((m) + (o) + 3) << 24))))
|
|
||||||
|
|
||||||
#define _S9XCHTDS(s, m, o) \
|
|
||||||
((s) == S9X_8_BITS ? ((int8) (*((m) + (o)))) : \
|
|
||||||
(s) == S9X_16_BITS ? ((int16) (*((m) + (o)) + (*((m) + (o) + 1) << 8))) : \
|
|
||||||
(s) == S9X_24_BITS ? (((int32) ((*((m) + (o)) + (*((m) + (o) + 1) << 8) + (*((m) + (o) + 2) << 16)) << 8)) >> 8): \
|
|
||||||
((int32) (*((m) + (o)) + (*((m) + (o) + 1) << 8) + (*((m) + (o) + 2) << 16) + (*((m) + (o) + 3) << 24))))
|
|
||||||
|
|
||||||
static bool8 S9xAllHex (const char *, int);
|
|
||||||
|
|
||||||
|
|
||||||
static bool8 S9xAllHex (const char *code, int len)
|
static bool8 S9xAllHex (const char *code, int len)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < len; i++)
|
for (int i = 0; i < len; i++)
|
||||||
if ((code[i] < '0' || code[i] > '9') && (code[i] < 'a' || code[i] > 'f') && (code[i] < 'A' || code[i] > 'F'))
|
if ((code [i] < '0' || code [i] > '9') &&
|
||||||
return (FALSE);
|
(code [i] < 'a' || code [i] > 'f') &&
|
||||||
|
(code [i] < 'A' || code [i] > 'F'))
|
||||||
|
return (FALSE);
|
||||||
|
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char * S9xProActionReplayToRaw (const char *code, uint32 &address, uint8 &byte)
|
const char *S9xProActionReplayToRaw (const char *code, uint32 &address, uint8 &byte)
|
||||||
{
|
{
|
||||||
uint32 data = 0;
|
uint32 data = 0;
|
||||||
|
if (strlen (code) != 8 || !S9xAllHex (code, 8) ||
|
||||||
|
sscanf (code, "%x", &data) != 1)
|
||||||
|
return ("Invalid Pro Action Replay code - should be 8 hex digits in length.");
|
||||||
|
|
||||||
if (strlen(code) != 8 || !S9xAllHex(code, 8) || sscanf(code, "%x", &data) != 1)
|
address = data >> 8;
|
||||||
return ("Invalid Pro Action Replay code - should be 8 hex digits in length.");
|
byte = (uint8) data;
|
||||||
|
return (NULL);
|
||||||
address = data >> 8;
|
|
||||||
byte = (uint8) data;
|
|
||||||
|
|
||||||
return (NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char * S9xGoldFingerToRaw (const char *code, uint32 &address, bool8 &sram, uint8 &num_bytes, uint8 bytes[3])
|
const char *S9xGoldFingerToRaw (const char *code, uint32 &address, bool8 &sram,
|
||||||
|
uint8 &num_bytes, uint8 bytes[3])
|
||||||
{
|
{
|
||||||
char tmp[15];
|
char tmp [15];
|
||||||
int i;
|
if (strlen (code) != 14)
|
||||||
|
return ("Invalid Gold Finger code should be 14 hex digits in length.");
|
||||||
|
|
||||||
if (strlen(code) != 14)
|
strncpy (tmp, code, 5);
|
||||||
return ("Invalid Gold Finger code - should be 14 hex digits in length.");
|
tmp [5] = 0;
|
||||||
|
if (sscanf (tmp, "%x", &address) != 1)
|
||||||
|
return ("Invalid Gold Finger code.");
|
||||||
|
|
||||||
strncpy(tmp, code, 5);
|
int i;
|
||||||
tmp[5] = 0;
|
for (i = 0; i < 3; i++)
|
||||||
if (sscanf(tmp, "%x", &address) != 1)
|
{
|
||||||
return ("Invalid Gold Finger code.");
|
strncpy (tmp, code + 5 + i * 2, 2);
|
||||||
|
tmp [2] = 0;
|
||||||
|
unsigned int byte;
|
||||||
|
if (sscanf (tmp, "%x", &byte) != 1)
|
||||||
|
break;
|
||||||
|
bytes [i] = (uint8) byte;
|
||||||
|
}
|
||||||
|
num_bytes = i;
|
||||||
|
sram = code [13] == '1';
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < 3; i++)
|
const char *S9xGameGenieToRaw (const char *code, uint32 &address, uint8 &byte)
|
||||||
|
{
|
||||||
|
char new_code [12];
|
||||||
|
|
||||||
|
if (strlen (code) != 9 || *(code + 4) != '-' || !S9xAllHex (code, 4) ||
|
||||||
|
!S9xAllHex (code + 5, 4))
|
||||||
|
return ("Invalid Game Genie(tm) code - should be 'xxxx-xxxx'.");
|
||||||
|
|
||||||
|
strcpy (new_code, "0x");
|
||||||
|
strncpy (new_code + 2, code, 4);
|
||||||
|
strcpy (new_code + 6, code + 5);
|
||||||
|
|
||||||
|
static char *real_hex = "0123456789ABCDEF";
|
||||||
|
static char *genie_hex = "DF4709156BC8A23E";
|
||||||
|
|
||||||
|
for (int i = 2; i < 10; i++)
|
||||||
|
{
|
||||||
|
if (islower (new_code [i]))
|
||||||
|
new_code [i] = toupper (new_code [i]);
|
||||||
|
int j;
|
||||||
|
for (j = 0; j < 16; j++)
|
||||||
{
|
{
|
||||||
unsigned int byte;
|
if (new_code [i] == genie_hex [j])
|
||||||
|
{
|
||||||
strncpy(tmp, code + 5 + i * 2, 2);
|
new_code [i] = real_hex [j];
|
||||||
tmp[2] = 0;
|
break;
|
||||||
if (sscanf(tmp, "%x", &byte) != 1)
|
}
|
||||||
break;
|
|
||||||
bytes[i] = (uint8) byte;
|
|
||||||
}
|
}
|
||||||
|
if (j == 16)
|
||||||
|
return ("Invalid hex-character in Game Genie(tm) code");
|
||||||
|
}
|
||||||
|
uint32 data = 0;
|
||||||
|
sscanf (new_code, "%x", &data);
|
||||||
|
byte = (uint8)(data >> 24);
|
||||||
|
address = data & 0xffffff;
|
||||||
|
address = ((address & 0x003c00) << 10) +
|
||||||
|
((address & 0x00003c) << 14) +
|
||||||
|
((address & 0xf00000) >> 8) +
|
||||||
|
((address & 0x000003) << 10) +
|
||||||
|
((address & 0x00c000) >> 6) +
|
||||||
|
((address & 0x0f0000) >> 12) +
|
||||||
|
((address & 0x0003c0) >> 6);
|
||||||
|
|
||||||
num_bytes = i;
|
return (NULL);
|
||||||
sram = code[13] == '1';
|
|
||||||
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char * S9xGameGenieToRaw (const char *code, uint32 &address, uint8 &byte)
|
|
||||||
{
|
|
||||||
char new_code[12];
|
|
||||||
|
|
||||||
if (strlen(code) != 9 || *(code + 4) != '-' || !S9xAllHex(code, 4) || !S9xAllHex(code + 5, 4))
|
|
||||||
return ("Invalid Game Genie(tm) code - should be 'xxxx-xxxx'.");
|
|
||||||
|
|
||||||
strcpy(new_code, "0x");
|
|
||||||
strncpy(new_code + 2, code, 4);
|
|
||||||
strcpy(new_code + 6, code + 5);
|
|
||||||
|
|
||||||
static const char *real_hex = "0123456789ABCDEF";
|
|
||||||
static const char *genie_hex = "DF4709156BC8A23E";
|
|
||||||
|
|
||||||
for (int i = 2; i < 10; i++)
|
|
||||||
{
|
|
||||||
if (islower(new_code[i]))
|
|
||||||
new_code[i] = toupper(new_code[i]);
|
|
||||||
|
|
||||||
int j;
|
|
||||||
for (j = 0; j < 16; j++)
|
|
||||||
{
|
|
||||||
if (new_code[i] == genie_hex[j])
|
|
||||||
{
|
|
||||||
new_code[i] = real_hex[j];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (j == 16)
|
|
||||||
return ("Invalid hex-character in Game Genie(tm) code.");
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 data = 0;
|
|
||||||
sscanf(new_code, "%x", &data);
|
|
||||||
byte = (uint8) (data >> 24);
|
|
||||||
address = data & 0xffffff;
|
|
||||||
address = ((address & 0x003c00) << 10) +
|
|
||||||
((address & 0x00003c) << 14) +
|
|
||||||
((address & 0xf00000) >> 8) +
|
|
||||||
((address & 0x000003) << 10) +
|
|
||||||
((address & 0x00c000) >> 6) +
|
|
||||||
((address & 0x0f0000) >> 12) +
|
|
||||||
((address & 0x0003c0) >> 6);
|
|
||||||
|
|
||||||
return (NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xStartCheatSearch (SCheatData *d)
|
void S9xStartCheatSearch (SCheatData *d)
|
||||||
{
|
{
|
||||||
memmove(d->CWRAM, d->RAM, 0x20000);
|
memmove (d->CWRAM, d->RAM, 0x20000);
|
||||||
memmove(d->CSRAM, d->SRAM, 0x10000);
|
memmove (d->CSRAM, d->SRAM, 0x10000);
|
||||||
memmove(d->CIRAM, &d->FillRAM[0x3000], 0x2000);
|
memmove (d->CIRAM, &d->FillRAM [0x3000], 0x2000);
|
||||||
memset((char *) d->ALL_BITS, 0xff, 0x32000 >> 3);
|
memset ((char *) d->ALL_BITS, 0xff, 0x32000 >> 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xSearchForChange (SCheatData *d, S9xCheatComparisonType cmp, S9xCheatDataSize size, bool8 is_signed, bool8 update)
|
#define BIT_CLEAR(a,v) \
|
||||||
|
(a)[(v) >> 5] &= ~(1 << ((v) & 31))
|
||||||
|
|
||||||
|
#define BIT_SET(a,v) \
|
||||||
|
(a)[(v) >> 5] |= 1 << ((v) & 31)
|
||||||
|
|
||||||
|
#define TEST_BIT(a,v) \
|
||||||
|
((a)[(v) >> 5] & (1 << ((v) & 31)))
|
||||||
|
|
||||||
|
#ifdef NGC
|
||||||
|
#undef _C /*** Stops powerpc-gekko-g++ complaining -;) ***/
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define _C(c,a,b) \
|
||||||
|
((c) == S9X_LESS_THAN ? (a) < (b) : \
|
||||||
|
(c) == S9X_GREATER_THAN ? (a) > (b) : \
|
||||||
|
(c) == S9X_LESS_THAN_OR_EQUAL ? (a) <= (b) : \
|
||||||
|
(c) == S9X_GREATER_THAN_OR_EQUAL ? (a) >= (b) : \
|
||||||
|
(c) == S9X_EQUAL ? (a) == (b) : \
|
||||||
|
(a) != (b))
|
||||||
|
|
||||||
|
#define _D(s,m,o) \
|
||||||
|
((s) == S9X_8_BITS ? (uint8) (*((m) + (o))) : \
|
||||||
|
(s) == S9X_16_BITS ? ((uint16) (*((m) + (o)) + (*((m) + (o) + 1) << 8))) : \
|
||||||
|
(s) == S9X_24_BITS ? ((uint32) (*((m) + (o)) + (*((m) + (o) + 1) << 8) + (*((m) + (o) + 2) << 16))) : \
|
||||||
|
((uint32) (*((m) + (o)) + (*((m) + (o) + 1) << 8) + (*((m) + (o) + 2) << 16) + (*((m) + (o) + 3) << 24))))
|
||||||
|
|
||||||
|
#define _DS(s,m,o) \
|
||||||
|
((s) == S9X_8_BITS ? ((int8) *((m) + (o))) : \
|
||||||
|
(s) == S9X_16_BITS ? ((int16) (*((m) + (o)) + (*((m) + (o) + 1) << 8))) : \
|
||||||
|
(s) == S9X_24_BITS ? (((int32) ((*((m) + (o)) + (*((m) + (o) + 1) << 8) + (*((m) + (o) + 2) << 16)) << 8)) >> 8): \
|
||||||
|
((int32) (*((m) + (o)) + (*((m) + (o) + 1) << 8) + (*((m) + (o) + 2) << 16) + (*((m) + (o) + 3) << 24))))
|
||||||
|
|
||||||
|
void S9xSearchForChange (SCheatData *d, S9xCheatComparisonType cmp,
|
||||||
|
S9xCheatDataSize size, bool8 is_signed, bool8 update)
|
||||||
{
|
{
|
||||||
int l, i;
|
int l;
|
||||||
|
|
||||||
switch (size)
|
switch (size)
|
||||||
{
|
{
|
||||||
case S9X_8_BITS: l = 0; break;
|
case S9X_8_BITS: l = 0; break;
|
||||||
case S9X_16_BITS: l = 1; break;
|
case S9X_16_BITS: l = 1; break;
|
||||||
case S9X_24_BITS: l = 2; break;
|
case S9X_24_BITS: l = 2; break;
|
||||||
default:
|
default:
|
||||||
case S9X_32_BITS: l = 3; break;
|
case S9X_32_BITS: l = 3; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_signed)
|
int i;
|
||||||
{
|
if (is_signed)
|
||||||
for (i = 0; i < 0x20000 - l; i++)
|
{
|
||||||
{
|
for (i = 0; i < 0x20000 - l; i++)
|
||||||
if (TEST_BIT(d->WRAM_BITS, i) && _S9XCHTC(cmp, _S9XCHTDS(size, d->RAM, i), _S9XCHTDS(size, d->CWRAM, i)))
|
{
|
||||||
{
|
if (TEST_BIT (d->WRAM_BITS, i) &&
|
||||||
if (update)
|
_C(cmp, _DS(size, d->RAM, i), _DS(size, d->CWRAM, i)))
|
||||||
d->CWRAM[i] = d->RAM[i];
|
{
|
||||||
}
|
if (update)
|
||||||
else
|
d->CWRAM [i] = d->RAM [i];
|
||||||
BIT_CLEAR(d->WRAM_BITS, i);
|
}
|
||||||
}
|
else
|
||||||
|
BIT_CLEAR (d->WRAM_BITS, i);
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < 0x10000 - l; i++)
|
for (i = 0; i < 0x10000 - l; i++)
|
||||||
{
|
{
|
||||||
if (TEST_BIT(d->SRAM_BITS, i) && _S9XCHTC(cmp, _S9XCHTDS(size, d->SRAM, i), _S9XCHTDS(size, d->CSRAM, i)))
|
if (TEST_BIT (d->SRAM_BITS, i) &&
|
||||||
{
|
_C(cmp, _DS(size, d->SRAM, i), _DS(size, d->CSRAM, i)))
|
||||||
if (update)
|
{
|
||||||
d->CSRAM[i] = d->SRAM[i];
|
if (update)
|
||||||
}
|
d->CSRAM [i] = d->SRAM [i];
|
||||||
else
|
}
|
||||||
BIT_CLEAR(d->SRAM_BITS, i);
|
else
|
||||||
}
|
BIT_CLEAR (d->SRAM_BITS, i);
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < 0x2000 - l; i++)
|
for (i = 0; i < 0x2000 - l; i++)
|
||||||
{
|
{
|
||||||
if (TEST_BIT(d->IRAM_BITS, i) && _S9XCHTC(cmp, _S9XCHTDS(size, d->FillRAM + 0x3000, i), _S9XCHTDS(size, d->CIRAM, i)))
|
if (TEST_BIT (d->IRAM_BITS, i) &&
|
||||||
{
|
_C(cmp, _DS(size, d->FillRAM + 0x3000, i), _DS(size, d->CIRAM, i)))
|
||||||
if (update)
|
{
|
||||||
d->CIRAM[i] = d->FillRAM[i + 0x3000];
|
if (update)
|
||||||
}
|
d->CIRAM [i] = d->FillRAM [i + 0x3000];
|
||||||
else
|
}
|
||||||
BIT_CLEAR(d->IRAM_BITS, i);
|
else
|
||||||
}
|
BIT_CLEAR (d->IRAM_BITS, i);
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
{
|
else
|
||||||
for (i = 0; i < 0x20000 - l; i++)
|
{
|
||||||
{
|
for (i = 0; i < 0x20000 - l; i++)
|
||||||
if (TEST_BIT(d->WRAM_BITS, i) && _S9XCHTC(cmp, _S9XCHTD(size, d->RAM, i), _S9XCHTD(size, d->CWRAM, i)))
|
{
|
||||||
{
|
if (TEST_BIT (d->WRAM_BITS, i) &&
|
||||||
if (update)
|
_C(cmp, _D(size, d->RAM, i), _D(size, d->CWRAM, i)))
|
||||||
d->CWRAM[i] = d->RAM[i];
|
{
|
||||||
}
|
if (update)
|
||||||
else
|
d->CWRAM [i] = d->RAM [i];
|
||||||
BIT_CLEAR(d->WRAM_BITS, i);
|
}
|
||||||
}
|
else
|
||||||
|
BIT_CLEAR (d->WRAM_BITS, i);
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < 0x10000 - l; i++)
|
for (i = 0; i < 0x10000 - l; i++)
|
||||||
{
|
{
|
||||||
if (TEST_BIT(d->SRAM_BITS, i) && _S9XCHTC(cmp, _S9XCHTD(size, d->SRAM, i), _S9XCHTD(size, d->CSRAM, i)))
|
if (TEST_BIT (d->SRAM_BITS, i) &&
|
||||||
{
|
_C(cmp, _D(size, d->SRAM, i), _D(size, d->CSRAM, i)))
|
||||||
if (update)
|
{
|
||||||
d->CSRAM[i] = d->SRAM[i];
|
if (update)
|
||||||
}
|
d->CSRAM [i] = d->SRAM [i];
|
||||||
else
|
}
|
||||||
BIT_CLEAR(d->SRAM_BITS, i);
|
else
|
||||||
}
|
BIT_CLEAR (d->SRAM_BITS, i);
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < 0x2000 - l; i++)
|
for (i = 0; i < 0x2000 - l; i++)
|
||||||
{
|
{
|
||||||
if (TEST_BIT(d->IRAM_BITS, i) && _S9XCHTC(cmp, _S9XCHTD(size, d->FillRAM + 0x3000, i), _S9XCHTD(size, d->CIRAM, i)))
|
if (TEST_BIT (d->IRAM_BITS, i) &&
|
||||||
{
|
_C(cmp, _D(size, d->FillRAM + 0x3000, i), _D(size, d->CIRAM, i)))
|
||||||
if (update)
|
{
|
||||||
d->CIRAM[i] = d->FillRAM[i + 0x3000];
|
if (update)
|
||||||
}
|
d->CIRAM [i] = d->FillRAM [i + 0x3000];
|
||||||
else
|
}
|
||||||
BIT_CLEAR(d->IRAM_BITS, i);
|
else
|
||||||
}
|
BIT_CLEAR (d->IRAM_BITS, i);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
for (i = 0x20000 - l; i < 0x20000; i++)
|
for (i = 0x20000 - l; i < 0x20000; i++)
|
||||||
BIT_CLEAR(d->WRAM_BITS, i);
|
BIT_CLEAR (d->WRAM_BITS, i);
|
||||||
|
for (i = 0x10000 - l; i < 0x10000; i++)
|
||||||
for (i = 0x10000 - l; i < 0x10000; i++)
|
BIT_CLEAR (d->SRAM_BITS, i);
|
||||||
BIT_CLEAR(d->SRAM_BITS, i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xSearchForValue (SCheatData *d, S9xCheatComparisonType cmp, S9xCheatDataSize size, uint32 value, bool8 is_signed, bool8 update)
|
void S9xSearchForValue (SCheatData *d, S9xCheatComparisonType cmp,
|
||||||
|
S9xCheatDataSize size, uint32 value,
|
||||||
|
bool8 is_signed, bool8 update)
|
||||||
{
|
{
|
||||||
int l, i;
|
int l;
|
||||||
|
|
||||||
switch (size)
|
switch (size)
|
||||||
{
|
{
|
||||||
case S9X_8_BITS: l = 0; break;
|
case S9X_8_BITS: l = 0; break;
|
||||||
case S9X_16_BITS: l = 1; break;
|
case S9X_16_BITS: l = 1; break;
|
||||||
case S9X_24_BITS: l = 2; break;
|
case S9X_24_BITS: l = 2; break;
|
||||||
default:
|
default:
|
||||||
case S9X_32_BITS: l = 3; break;
|
case S9X_32_BITS: l = 3; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_signed)
|
int i;
|
||||||
{
|
|
||||||
for (i = 0; i < 0x20000 - l; i++)
|
|
||||||
{
|
|
||||||
if (TEST_BIT(d->WRAM_BITS, i) && _S9XCHTC(cmp, _S9XCHTDS(size, d->RAM, i), (int32) value))
|
|
||||||
{
|
|
||||||
if (update)
|
|
||||||
d->CWRAM[i] = d->RAM[i];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
BIT_CLEAR(d->WRAM_BITS, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < 0x10000 - l; i++)
|
if (is_signed)
|
||||||
{
|
{
|
||||||
if (TEST_BIT(d->SRAM_BITS, i) && _S9XCHTC(cmp, _S9XCHTDS(size, d->SRAM, i), (int32) value))
|
for (i = 0; i < 0x20000 - l; i++)
|
||||||
{
|
{
|
||||||
if (update)
|
if (TEST_BIT (d->WRAM_BITS, i) &&
|
||||||
d->CSRAM[i] = d->SRAM[i];
|
_C(cmp, _DS(size, d->RAM, i), (int32) value))
|
||||||
}
|
{
|
||||||
else
|
if (update)
|
||||||
BIT_CLEAR(d->SRAM_BITS, i);
|
d->CWRAM [i] = d->RAM [i];
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
BIT_CLEAR (d->WRAM_BITS, i);
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < 0x2000 - l; i++)
|
for (i = 0; i < 0x10000 - l; i++)
|
||||||
{
|
{
|
||||||
if (TEST_BIT(d->IRAM_BITS, i) && _S9XCHTC(cmp, _S9XCHTDS(size, d->FillRAM + 0x3000, i), (int32) value))
|
if (TEST_BIT (d->SRAM_BITS, i) &&
|
||||||
{
|
_C(cmp, _DS(size, d->SRAM, i), (int32) value))
|
||||||
if (update)
|
{
|
||||||
d->CIRAM[i] = d->FillRAM[i + 0x3000];
|
if (update)
|
||||||
}
|
d->CSRAM [i] = d->SRAM [i];
|
||||||
else
|
}
|
||||||
BIT_CLEAR(d->IRAM_BITS, i);
|
else
|
||||||
}
|
BIT_CLEAR (d->SRAM_BITS, i);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
for (i = 0; i < 0x20000 - l; i++)
|
|
||||||
{
|
|
||||||
if (TEST_BIT(d->WRAM_BITS, i) && _S9XCHTC(cmp, _S9XCHTD(size, d->RAM, i), value))
|
|
||||||
{
|
|
||||||
if (update)
|
|
||||||
d->CWRAM[i] = d->RAM[i];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
BIT_CLEAR(d->WRAM_BITS, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < 0x10000 - l; i++)
|
for (i = 0; i < 0x2000 - l; i++)
|
||||||
{
|
{
|
||||||
if (TEST_BIT(d->SRAM_BITS, i) && _S9XCHTC(cmp, _S9XCHTD(size, d->SRAM, i), value))
|
if (TEST_BIT (d->IRAM_BITS, i) &&
|
||||||
{
|
_C(cmp, _DS(size, d->FillRAM + 0x3000, i), (int32) value))
|
||||||
if (update)
|
{
|
||||||
d->CSRAM[i] = d->SRAM[i];
|
if (update)
|
||||||
}
|
d->CIRAM [i] = d->FillRAM [i + 0x3000];
|
||||||
else
|
}
|
||||||
BIT_CLEAR(d->SRAM_BITS, i);
|
else
|
||||||
}
|
BIT_CLEAR (d->IRAM_BITS, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < 0x20000 - l; i++)
|
||||||
|
{
|
||||||
|
if (TEST_BIT (d->WRAM_BITS, i) &&
|
||||||
|
_C(cmp, _D(size, d->RAM, i), value))
|
||||||
|
{
|
||||||
|
if (update)
|
||||||
|
d->CWRAM [i] = d->RAM [i];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
BIT_CLEAR (d->WRAM_BITS, i);
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < 0x2000 - l; i++)
|
for (i = 0; i < 0x10000 - l; i++)
|
||||||
{
|
{
|
||||||
if (TEST_BIT(d->IRAM_BITS, i) && _S9XCHTC(cmp, _S9XCHTD(size, d->FillRAM + 0x3000, i), value))
|
if (TEST_BIT (d->SRAM_BITS, i) &&
|
||||||
{
|
_C(cmp, _D(size, d->SRAM, i), value))
|
||||||
if (update)
|
{
|
||||||
d->CIRAM[i] = d->FillRAM[i + 0x3000];
|
if (update)
|
||||||
}
|
d->CSRAM [i] = d->SRAM [i];
|
||||||
else
|
}
|
||||||
BIT_CLEAR(d->IRAM_BITS, i);
|
else
|
||||||
}
|
BIT_CLEAR (d->SRAM_BITS, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0x20000 - l; i < 0x20000; i++)
|
for (i = 0; i < 0x2000 - l; i++)
|
||||||
BIT_CLEAR(d->WRAM_BITS, i);
|
{
|
||||||
|
if (TEST_BIT (d->IRAM_BITS, i) &&
|
||||||
for (i = 0x10000 - l; i < 0x10000; i++)
|
_C(cmp, _D(size, d->FillRAM + 0x3000, i), value))
|
||||||
BIT_CLEAR(d->SRAM_BITS, i);
|
{
|
||||||
|
if (update)
|
||||||
|
d->CIRAM [i] = d->FillRAM [i + 0x3000];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
BIT_CLEAR (d->IRAM_BITS, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0x20000 - l; i < 0x20000; i++)
|
||||||
|
BIT_CLEAR (d->WRAM_BITS, i);
|
||||||
|
for (i = 0x10000 - l; i < 0x10000; i++)
|
||||||
|
BIT_CLEAR (d->SRAM_BITS, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xSearchForAddress (SCheatData *d, S9xCheatComparisonType cmp, S9xCheatDataSize size, uint32 value, bool8 update)
|
void S9xSearchForAddress (SCheatData *d, S9xCheatComparisonType cmp,
|
||||||
|
S9xCheatDataSize size, uint32 value, bool8 update)
|
||||||
{
|
{
|
||||||
int l, i;
|
int l;
|
||||||
|
|
||||||
switch (size)
|
switch (size)
|
||||||
{
|
{
|
||||||
case S9X_8_BITS: l = 0; break;
|
case S9X_8_BITS: l = 0; break;
|
||||||
case S9X_16_BITS: l = 1; break;
|
case S9X_16_BITS: l = 1; break;
|
||||||
case S9X_24_BITS: l = 2; break;
|
case S9X_24_BITS: l = 2; break;
|
||||||
default:
|
default:
|
||||||
case S9X_32_BITS: l = 3; break;
|
case S9X_32_BITS: l = 3; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < 0x20000 - l; i++)
|
int i;
|
||||||
{
|
|
||||||
if (TEST_BIT(d->WRAM_BITS, i) && _S9XCHTC(cmp, i, (int32) value))
|
|
||||||
{
|
|
||||||
if (update)
|
|
||||||
d->CWRAM[i] = d->RAM[i];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
BIT_CLEAR(d->WRAM_BITS, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < 0x10000 - l; i++)
|
{
|
||||||
{
|
|
||||||
if (TEST_BIT(d->SRAM_BITS, i) && _S9XCHTC(cmp, i + 0x20000, (int32) value))
|
|
||||||
{
|
|
||||||
if (update)
|
|
||||||
d->CSRAM[i] = d->SRAM[i];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
BIT_CLEAR(d->SRAM_BITS, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < 0x2000 - l; i++)
|
for (i = 0; i < 0x20000 - l; i++)
|
||||||
{
|
{
|
||||||
if (TEST_BIT(d->IRAM_BITS, i) && _S9XCHTC(cmp, i + 0x30000, (int32) value))
|
if (TEST_BIT (d->WRAM_BITS, i) &&
|
||||||
{
|
_C(cmp, i, (int)value))
|
||||||
if (update)
|
{
|
||||||
d->CIRAM[i] = d->FillRAM[i + 0x3000];
|
if (update)
|
||||||
}
|
d->CWRAM [i] = d->RAM [i];
|
||||||
else
|
}
|
||||||
BIT_CLEAR(d->IRAM_BITS, i);
|
else
|
||||||
}
|
BIT_CLEAR (d->WRAM_BITS, i);
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0x20000 - l; i < 0x20000; i++)
|
for (i = 0; i < 0x10000 - l; i++)
|
||||||
BIT_CLEAR(d->WRAM_BITS, i);
|
{
|
||||||
|
if (TEST_BIT (d->SRAM_BITS, i) &&
|
||||||
|
_C(cmp, i+0x20000, (int)value))
|
||||||
|
{
|
||||||
|
if (update)
|
||||||
|
d->CSRAM [i] = d->SRAM [i];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
BIT_CLEAR (d->SRAM_BITS, i);
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0x10000 - l; i < 0x10000; i++)
|
for (i = 0; i < 0x2000 - l; i++)
|
||||||
BIT_CLEAR(d->SRAM_BITS, i);
|
{
|
||||||
|
if (TEST_BIT (d->IRAM_BITS, i) &&
|
||||||
|
_C(cmp, i+0x30000, (int)value))
|
||||||
|
{
|
||||||
|
if (update)
|
||||||
|
d->CIRAM [i] = d->FillRAM [i + 0x3000];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
BIT_CLEAR (d->IRAM_BITS, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0x20000 - l; i < 0x20000; i++)
|
||||||
|
BIT_CLEAR (d->WRAM_BITS, i);
|
||||||
|
for (i = 0x10000 - l; i < 0x10000; i++)
|
||||||
|
BIT_CLEAR (d->SRAM_BITS, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xOutputCheatSearchResults (SCheatData *d)
|
void S9xOutputCheatSearchResults (SCheatData *d)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
for (i = 0; i < 0x20000; i++)
|
||||||
|
{
|
||||||
|
if (TEST_BIT (d->WRAM_BITS, i))
|
||||||
|
printf ("WRAM: %05x: %02x\n", i, d->RAM [i]);
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < 0x20000; i++)
|
for (i = 0; i < 0x10000; i++)
|
||||||
{
|
{
|
||||||
if (TEST_BIT(d->WRAM_BITS, i))
|
if (TEST_BIT (d->SRAM_BITS, i))
|
||||||
printf("WRAM: %05x: %02x\n", i, d->RAM[i]);
|
printf ("SRAM: %04x: %02x\n", i, d->SRAM [i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < 0x10000; i++)
|
for (i = 0; i < 0x2000; i++)
|
||||||
{
|
{
|
||||||
if (TEST_BIT(d->SRAM_BITS, i))
|
if (TEST_BIT (d->IRAM_BITS, i))
|
||||||
printf("SRAM: %04x: %02x\n", i, d->SRAM[i]);
|
printf ("IRAM: %05x: %02x\n", i, d->FillRAM [i + 0x3000]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < 0x2000; i++)
|
|
||||||
{
|
|
||||||
if (TEST_BIT(d->IRAM_BITS, i))
|
|
||||||
printf("IRAM: %05x: %02x\n", i, d->FillRAM[i + 0x3000]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,88 +159,89 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _CHEATS_H_
|
#ifndef _CHEATS_H_
|
||||||
#define _CHEATS_H_
|
#define _CHEATS_H_
|
||||||
|
|
||||||
#define MAX_CHEATS 150
|
|
||||||
|
|
||||||
struct SCheat
|
struct SCheat
|
||||||
{
|
{
|
||||||
uint32 address;
|
uint32 address;
|
||||||
uint8 byte;
|
uint8 byte;
|
||||||
uint8 saved_byte;
|
uint8 saved_byte;
|
||||||
bool8 enabled;
|
bool8 enabled;
|
||||||
bool8 saved;
|
bool8 saved;
|
||||||
char name[22];
|
char name [22];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define MAX_CHEATS 150
|
||||||
|
|
||||||
struct SCheatData
|
struct SCheatData
|
||||||
{
|
{
|
||||||
struct SCheat c[MAX_CHEATS];
|
struct SCheat c [MAX_CHEATS];
|
||||||
uint32 num_cheats;
|
uint32 num_cheats;
|
||||||
uint8 CWRAM[0x20000];
|
uint8 CWRAM [0x20000];
|
||||||
uint8 CSRAM[0x10000];
|
uint8 CSRAM [0x10000];
|
||||||
uint8 CIRAM[0x2000];
|
uint8 CIRAM [0x2000];
|
||||||
uint8 *RAM;
|
uint8 *RAM;
|
||||||
uint8 *FillRAM;
|
uint8 *FillRAM;
|
||||||
uint8 *SRAM;
|
uint8 *SRAM;
|
||||||
uint32 ALL_BITS[0x32000 >> 5];
|
uint32 ALL_BITS [(0x32000 >> 5)];
|
||||||
uint8 CWatchRAM[0x32000];
|
#define WRAM_BITS ALL_BITS
|
||||||
|
#define SRAM_BITS ALL_BITS + (0x20000 >> 5)
|
||||||
|
#define IRAM_BITS ALL_BITS + (0x30000 >> 5)
|
||||||
|
uint8 CWatchRAM [0x32000];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Watch
|
|
||||||
{
|
struct Watch {
|
||||||
bool on;
|
bool on;
|
||||||
int size;
|
int size;
|
||||||
int format;
|
int format;
|
||||||
uint32 address;
|
uint32 address;
|
||||||
char buf[12];
|
char buf[12];
|
||||||
char desc[32];
|
char desc[32];
|
||||||
};
|
};
|
||||||
|
extern Watch watches [16];
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
S9X_LESS_THAN,
|
S9X_LESS_THAN, S9X_GREATER_THAN, S9X_LESS_THAN_OR_EQUAL,
|
||||||
S9X_GREATER_THAN,
|
S9X_GREATER_THAN_OR_EQUAL, S9X_EQUAL, S9X_NOT_EQUAL
|
||||||
S9X_LESS_THAN_OR_EQUAL,
|
} S9xCheatComparisonType;
|
||||||
S9X_GREATER_THAN_OR_EQUAL,
|
|
||||||
S9X_EQUAL,
|
|
||||||
S9X_NOT_EQUAL
|
|
||||||
} S9xCheatComparisonType;
|
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
S9X_8_BITS,
|
S9X_8_BITS, S9X_16_BITS, S9X_24_BITS, S9X_32_BITS
|
||||||
S9X_16_BITS,
|
} S9xCheatDataSize;
|
||||||
S9X_24_BITS,
|
|
||||||
S9X_32_BITS
|
|
||||||
} S9xCheatDataSize;
|
|
||||||
|
|
||||||
extern SCheatData Cheat;
|
void S9xInitCheatData ();
|
||||||
extern Watch watches[16];
|
|
||||||
|
|
||||||
void S9xApplyCheat (uint32);
|
const char *S9xGameGenieToRaw (const char *code, uint32 &address, uint8 &byte);
|
||||||
void S9xApplyCheats (void);
|
const char *S9xProActionReplayToRaw (const char *code, uint32 &address, uint8 &byte);
|
||||||
void S9xRemoveCheat (uint32);
|
const char *S9xGoldFingerToRaw (const char *code, uint32 &address, bool8 &sram,
|
||||||
void S9xRemoveCheats (void);
|
uint8 &num_bytes, uint8 bytes[3]);
|
||||||
void S9xDeleteCheat (uint32);
|
void S9xApplyCheats ();
|
||||||
void S9xDeleteCheats (void);
|
void S9xApplyCheat (uint32 which1);
|
||||||
void S9xEnableCheat (uint32);
|
void S9xRemoveCheats ();
|
||||||
void S9xDisableCheat (uint32);
|
void S9xRemoveCheat (uint32 which1);
|
||||||
void S9xAddCheat (bool8, bool8, uint32, uint8);
|
void S9xEnableCheat (uint32 which1);
|
||||||
void S9xInitCheatData (void);
|
void S9xDisableCheat (uint32 which1);
|
||||||
void S9xInitWatchedAddress (void);
|
void S9xAddCheat (bool8 enable, bool8 save_current_value, uint32 address,
|
||||||
bool8 S9xLoadCheatFile (const char *);
|
uint8 byte);
|
||||||
bool8 S9xSaveCheatFile (const char *);
|
void S9xDeleteCheats ();
|
||||||
|
void S9xDeleteCheat (uint32 which1);
|
||||||
|
bool8 S9xLoadCheatFile (const char *filename);
|
||||||
|
bool8 S9xSaveCheatFile (const char *filename);
|
||||||
|
|
||||||
void S9xStartCheatSearch (SCheatData *);
|
void S9xStartCheatSearch (SCheatData *);
|
||||||
void S9xSearchForChange (SCheatData *, S9xCheatComparisonType, S9xCheatDataSize, bool8, bool8);
|
void S9xSearchForChange (SCheatData *, S9xCheatComparisonType cmp,
|
||||||
void S9xSearchForValue (SCheatData *, S9xCheatComparisonType, S9xCheatDataSize, uint32, bool8, bool8);
|
S9xCheatDataSize size, bool8 is_signed, bool8 update);
|
||||||
void S9xSearchForAddress (SCheatData *, S9xCheatComparisonType, S9xCheatDataSize, uint32, bool8);
|
void S9xSearchForValue (SCheatData *, S9xCheatComparisonType cmp,
|
||||||
|
S9xCheatDataSize size, uint32 value,
|
||||||
|
bool8 is_signed, bool8 update);
|
||||||
|
void S9xSearchForAddress (SCheatData *, S9xCheatComparisonType cmp,
|
||||||
|
S9xCheatDataSize size, uint32 address, bool8 update);
|
||||||
void S9xOutputCheatSearchResults (SCheatData *);
|
void S9xOutputCheatSearchResults (SCheatData *);
|
||||||
|
|
||||||
const char * S9xGameGenieToRaw (const char *, uint32 &, uint8 &);
|
|
||||||
const char * S9xProActionReplayToRaw (const char *, uint32 &, uint8 &);
|
|
||||||
const char * S9xGoldFingerToRaw (const char *, uint32 &, bool8 &, uint8 &, uint8 bytes[3]);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -159,232 +159,223 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <string.h>
|
||||||
#include "snes9x.h"
|
#include "snes9x.h"
|
||||||
#include "memmap.h"
|
|
||||||
#include "cheats.h"
|
#include "cheats.h"
|
||||||
|
#include "memmap.h"
|
||||||
|
|
||||||
static uint8 S9xGetByteFree (uint32);
|
#ifndef INLINE
|
||||||
static void S9xSetByteFree (uint8, uint32);
|
#define INLINE inline
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern SCheatData Cheat;
|
||||||
|
Watch watches [16];
|
||||||
|
|
||||||
static uint8 S9xGetByteFree (uint32 address)
|
// read a byte without altering CPU
|
||||||
|
INLINE uint8 S9xGetByteFree (uint32 Address)
|
||||||
{
|
{
|
||||||
uint32 Cycles = CPU.Cycles;
|
uint32 Cycles = CPU.Cycles;
|
||||||
uint32 WaitAddress = CPU.WaitAddress;
|
uint32 WaitAddress = CPU.WaitAddress;
|
||||||
uint8 byte;
|
uint8 rv = S9xGetByte (Address);
|
||||||
|
|
||||||
byte = S9xGetByte(address);
|
|
||||||
|
|
||||||
CPU.WaitAddress = WaitAddress;
|
CPU.WaitAddress = WaitAddress;
|
||||||
CPU.Cycles = Cycles;
|
CPU.Cycles = Cycles;
|
||||||
|
return rv;
|
||||||
return (byte);
|
|
||||||
}
|
}
|
||||||
|
INLINE void S9xSetByteFree (uint8 Byte, uint32 Address)
|
||||||
static void S9xSetByteFree (uint8 byte, uint32 address)
|
|
||||||
{
|
{
|
||||||
uint32 Cycles = CPU.Cycles;
|
uint32 Cycles = CPU.Cycles;
|
||||||
uint32 WaitAddress = CPU.WaitAddress;
|
uint32 WaitAddress = CPU.WaitAddress;
|
||||||
|
S9xSetByte (Byte, Address);
|
||||||
S9xSetByte(byte, address);
|
|
||||||
|
|
||||||
CPU.WaitAddress = WaitAddress;
|
CPU.WaitAddress = WaitAddress;
|
||||||
CPU.Cycles = Cycles;
|
CPU.Cycles = Cycles;
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xInitWatchedAddress (void)
|
void S9xInitCheatData ()
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < sizeof(watches) / sizeof(watches[0]); i++)
|
Cheat.RAM = Memory.RAM;
|
||||||
watches[i].on = false;
|
Cheat.SRAM = Memory.SRAM;
|
||||||
|
Cheat.FillRAM = Memory.FillRAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xInitCheatData (void)
|
void S9xAddCheat (bool8 enable, bool8 save_current_value,
|
||||||
|
uint32 address, uint8 byte)
|
||||||
{
|
{
|
||||||
Cheat.RAM = Memory.RAM;
|
if (Cheat.num_cheats < sizeof (Cheat.c) / sizeof (Cheat. c [0]))
|
||||||
Cheat.SRAM = Memory.SRAM;
|
{
|
||||||
Cheat.FillRAM = Memory.FillRAM;
|
Cheat.c [Cheat.num_cheats].address = address;
|
||||||
}
|
Cheat.c [Cheat.num_cheats].byte = byte;
|
||||||
|
#ifdef __MACOSX__
|
||||||
void S9xAddCheat (bool8 enable, bool8 save_current_value, uint32 address, uint8 byte)
|
Cheat.c [Cheat.num_cheats].enabled = enable;
|
||||||
{
|
#else
|
||||||
if (Cheat.num_cheats < sizeof(Cheat.c) / sizeof(Cheat.c[0]))
|
Cheat.c [Cheat.num_cheats].enabled = TRUE;
|
||||||
|
#endif
|
||||||
|
if (save_current_value)
|
||||||
{
|
{
|
||||||
Cheat.c[Cheat.num_cheats].address = address;
|
Cheat.c [Cheat.num_cheats].saved_byte = S9xGetByteFree (address);
|
||||||
Cheat.c[Cheat.num_cheats].byte = byte;
|
Cheat.c [Cheat.num_cheats].saved = TRUE;
|
||||||
Cheat.c[Cheat.num_cheats].enabled = enable;
|
|
||||||
|
|
||||||
if (save_current_value)
|
|
||||||
{
|
|
||||||
Cheat.c[Cheat.num_cheats].saved_byte = S9xGetByteFree(address);
|
|
||||||
Cheat.c[Cheat.num_cheats].saved = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
Cheat.num_cheats++;
|
|
||||||
}
|
}
|
||||||
|
Cheat.num_cheats++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xDeleteCheat (uint32 which1)
|
void S9xDeleteCheat (uint32 which1)
|
||||||
{
|
{
|
||||||
if (which1 < Cheat.num_cheats)
|
if (which1 < Cheat.num_cheats)
|
||||||
{
|
{
|
||||||
if (Cheat.c[which1].enabled)
|
if (Cheat.c [which1].enabled)
|
||||||
S9xRemoveCheat(which1);
|
S9xRemoveCheat (which1);
|
||||||
|
|
||||||
memmove(&Cheat.c[which1], &Cheat.c[which1 + 1], sizeof(Cheat.c[0]) * (Cheat.num_cheats - which1 - 1));
|
memmove (&Cheat.c [which1], &Cheat.c [which1 + 1],
|
||||||
|
sizeof (Cheat.c [0]) * (Cheat.num_cheats - which1 - 1));
|
||||||
Cheat.num_cheats--;
|
Cheat.num_cheats--; //MK: This used to set it to 0??
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xDeleteCheats (void)
|
void S9xDeleteCheats ()
|
||||||
{
|
{
|
||||||
S9xRemoveCheats();
|
S9xRemoveCheats ();
|
||||||
Cheat.num_cheats = 0;
|
Cheat.num_cheats = 0;
|
||||||
}
|
|
||||||
|
|
||||||
void S9xRemoveCheat (uint32 which1)
|
|
||||||
{
|
|
||||||
if (Cheat.c[which1].saved)
|
|
||||||
{
|
|
||||||
uint32 address = Cheat.c[which1].address;
|
|
||||||
|
|
||||||
int block = (address & 0xffffff) >> MEMMAP_SHIFT;
|
|
||||||
uint8 *ptr = Memory.Map[block];
|
|
||||||
|
|
||||||
if (ptr >= (uint8 *) CMemory::MAP_LAST)
|
|
||||||
*(ptr + (address & 0xffff)) = Cheat.c[which1].saved_byte;
|
|
||||||
else
|
|
||||||
S9xSetByteFree(Cheat.c[which1].saved_byte, address);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void S9xRemoveCheats (void)
|
|
||||||
{
|
|
||||||
for (uint32 i = 0; i < Cheat.num_cheats; i++)
|
|
||||||
if (Cheat.c[i].enabled)
|
|
||||||
S9xRemoveCheat(i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xEnableCheat (uint32 which1)
|
void S9xEnableCheat (uint32 which1)
|
||||||
{
|
{
|
||||||
if (which1 < Cheat.num_cheats && !Cheat.c[which1].enabled)
|
if (which1 < Cheat.num_cheats && !Cheat.c [which1].enabled)
|
||||||
{
|
{
|
||||||
Cheat.c[which1].enabled = TRUE;
|
Cheat.c [which1].enabled = TRUE;
|
||||||
S9xApplyCheat(which1);
|
S9xApplyCheat (which1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xDisableCheat (uint32 which1)
|
void S9xDisableCheat (uint32 which1)
|
||||||
{
|
{
|
||||||
if (which1 < Cheat.num_cheats && Cheat.c[which1].enabled)
|
if (which1 < Cheat.num_cheats && Cheat.c [which1].enabled)
|
||||||
{
|
{
|
||||||
S9xRemoveCheat(which1);
|
S9xRemoveCheat (which1);
|
||||||
Cheat.c[which1].enabled = FALSE;
|
Cheat.c [which1].enabled = FALSE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void S9xRemoveCheat (uint32 which1)
|
||||||
|
{
|
||||||
|
if (Cheat.c [which1].saved)
|
||||||
|
{
|
||||||
|
uint32 address = Cheat.c [which1].address;
|
||||||
|
|
||||||
|
int block = ((address&0xffffff) >> MEMMAP_SHIFT);
|
||||||
|
uint8 *ptr = Memory.Map [block];
|
||||||
|
|
||||||
|
if (ptr >= (uint8 *) CMemory::MAP_LAST)
|
||||||
|
*(ptr + (address & 0xffff)) = Cheat.c [which1].saved_byte;
|
||||||
|
else
|
||||||
|
S9xSetByte (Cheat.c [which1].saved_byte, address);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xApplyCheat (uint32 which1)
|
void S9xApplyCheat (uint32 which1)
|
||||||
{
|
{
|
||||||
uint32 address = Cheat.c[which1].address;
|
uint32 address = Cheat.c [which1].address;
|
||||||
|
|
||||||
if (!Cheat.c[which1].saved)
|
if (!Cheat.c [which1].saved)
|
||||||
{
|
Cheat.c [which1].saved_byte = S9xGetByteFree (address);
|
||||||
Cheat.c[which1].saved_byte = S9xGetByteFree(address);
|
|
||||||
Cheat.c[which1].saved = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int block = (address & 0xffffff) >> MEMMAP_SHIFT;
|
int block = ((address&0xffffff) >> MEMMAP_SHIFT);
|
||||||
uint8 *ptr = Memory.Map[block];
|
uint8 *ptr = Memory.Map [block];
|
||||||
|
|
||||||
if (ptr >= (uint8 *) CMemory::MAP_LAST)
|
if (ptr >= (uint8 *) CMemory::MAP_LAST)
|
||||||
*(ptr + (address & 0xffff)) = Cheat.c[which1].byte;
|
*(ptr + (address & 0xffff)) = Cheat.c [which1].byte;
|
||||||
else
|
else
|
||||||
S9xSetByteFree(Cheat.c[which1].byte, address);
|
S9xSetByte (Cheat.c [which1].byte, address);
|
||||||
|
Cheat.c [which1].saved = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xApplyCheats (void)
|
void S9xApplyCheats ()
|
||||||
{
|
{
|
||||||
if (Settings.ApplyCheats)
|
if (Settings.ApplyCheats)
|
||||||
{
|
{
|
||||||
for (uint32 i = 0; i < Cheat.num_cheats; i++)
|
for (uint32 i = 0; i < Cheat.num_cheats; i++)
|
||||||
if (Cheat.c[i].enabled)
|
if (Cheat.c [i].enabled)
|
||||||
S9xApplyCheat(i);
|
S9xApplyCheat (i);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void S9xRemoveCheats ()
|
||||||
|
{
|
||||||
|
for (uint32 i = 0; i < Cheat.num_cheats; i++)
|
||||||
|
if (Cheat.c [i].enabled)
|
||||||
|
S9xRemoveCheat (i);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool8 S9xLoadCheatFile (const char *filename)
|
bool8 S9xLoadCheatFile (const char *filename)
|
||||||
{
|
{
|
||||||
FILE *fs;
|
Cheat.num_cheats = 0;
|
||||||
uint8 data[28];
|
|
||||||
|
|
||||||
Cheat.num_cheats = 0;
|
FILE *fs = fopen (filename, "rb");
|
||||||
|
uint8 data [28];
|
||||||
|
|
||||||
fs = fopen(filename, "rb");
|
if (!fs)
|
||||||
if (!fs)
|
return (FALSE);
|
||||||
return (FALSE);
|
|
||||||
|
|
||||||
while (fread((void *) data, 1, 28, fs) == 28)
|
while (fread ((void *) data, 1, 28, fs) == 28)
|
||||||
{
|
{
|
||||||
Cheat.c[Cheat.num_cheats].enabled = (data[0] & 4) == 0;
|
Cheat.c [Cheat.num_cheats].enabled = (data [0] & 4) == 0;
|
||||||
Cheat.c[Cheat.num_cheats].byte = data[1];
|
Cheat.c [Cheat.num_cheats].byte = data [1];
|
||||||
Cheat.c[Cheat.num_cheats].address = data[2] | (data[3] << 8) | (data[4] << 16);
|
Cheat.c [Cheat.num_cheats].address = data [2] | (data [3] << 8) | (data [4] << 16);
|
||||||
Cheat.c[Cheat.num_cheats].saved_byte = data[5];
|
Cheat.c [Cheat.num_cheats].saved_byte = data [5];
|
||||||
Cheat.c[Cheat.num_cheats].saved = (data[0] & 8) != 0;
|
Cheat.c [Cheat.num_cheats].saved = (data [0] & 8) != 0;
|
||||||
memmove(Cheat.c[Cheat.num_cheats].name, &data[8], 20);
|
memmove (Cheat.c [Cheat.num_cheats].name, &data [8], 20);
|
||||||
Cheat.c[Cheat.num_cheats++].name[20] = 0;
|
Cheat.c [Cheat.num_cheats++].name [20] = 0;
|
||||||
}
|
}
|
||||||
|
fclose (fs);
|
||||||
|
|
||||||
fclose(fs);
|
return (TRUE);
|
||||||
|
|
||||||
return (TRUE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool8 S9xSaveCheatFile (const char *filename)
|
bool8 S9xSaveCheatFile (const char *filename)
|
||||||
{
|
{
|
||||||
if (Cheat.num_cheats == 0)
|
if (Cheat.num_cheats == 0)
|
||||||
|
{
|
||||||
|
(void) remove (filename);
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *fs = fopen (filename, "wb");
|
||||||
|
uint8 data [28];
|
||||||
|
|
||||||
|
if (!fs)
|
||||||
|
return (FALSE);
|
||||||
|
|
||||||
|
uint32 i;
|
||||||
|
for (i = 0; i < Cheat.num_cheats; i++)
|
||||||
|
{
|
||||||
|
memset (data, 0, 28);
|
||||||
|
if (i == 0)
|
||||||
{
|
{
|
||||||
remove(filename);
|
data [6] = 254;
|
||||||
return (TRUE);
|
data [7] = 252;
|
||||||
}
|
}
|
||||||
|
if (!Cheat.c [i].enabled)
|
||||||
|
data [0] |= 4;
|
||||||
|
|
||||||
FILE *fs;
|
if (Cheat.c [i].saved)
|
||||||
uint8 data[28];
|
data [0] |= 8;
|
||||||
|
|
||||||
fs = fopen(filename, "wb");
|
data [1] = Cheat.c [i].byte;
|
||||||
if (!fs)
|
data [2] = (uint8) Cheat.c [i].address;
|
||||||
return (FALSE);
|
data [3] = (uint8) (Cheat.c [i].address >> 8);
|
||||||
|
data [4] = (uint8) (Cheat.c [i].address >> 16);
|
||||||
|
data [5] = Cheat.c [i].saved_byte;
|
||||||
|
|
||||||
for (uint32 i = 0; i < Cheat.num_cheats; i++)
|
memmove (&data [8], Cheat.c [i].name, 19);
|
||||||
|
if (fwrite (data, 28, 1, fs) != 1)
|
||||||
{
|
{
|
||||||
ZeroMemory(data, 28);
|
fclose (fs);
|
||||||
|
return (FALSE);
|
||||||
if (i == 0)
|
|
||||||
{
|
|
||||||
data[6] = 254;
|
|
||||||
data[7] = 252;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Cheat.c[i].enabled)
|
|
||||||
data[0] |= 4;
|
|
||||||
|
|
||||||
if (Cheat.c[i].saved)
|
|
||||||
data[0] |= 8;
|
|
||||||
|
|
||||||
data[1] = Cheat.c[i].byte;
|
|
||||||
data[2] = (uint8) (Cheat.c[i].address >> 0);
|
|
||||||
data[3] = (uint8) (Cheat.c[i].address >> 8);
|
|
||||||
data[4] = (uint8) (Cheat.c[i].address >> 16);
|
|
||||||
data[5] = Cheat.c[i].saved_byte;
|
|
||||||
|
|
||||||
memmove(&data[8], Cheat.c[i].name, 19);
|
|
||||||
|
|
||||||
if (fwrite(data, 28, 1, fs) != 1)
|
|
||||||
{
|
|
||||||
fclose(fs);
|
|
||||||
return (FALSE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return (fclose(fs) == 0);
|
return (fclose (fs) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -159,231 +159,189 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "snes9x.h"
|
#include "snes9x.h"
|
||||||
#include "memmap.h"
|
#include "memmap.h"
|
||||||
|
#include "ppu.h"
|
||||||
|
|
||||||
static uint8 region_map[6][6] =
|
static uint8 region_map[6][6]={
|
||||||
{
|
{0, 0x01, 0x03, 0x07, 0x0f, 0x1f },
|
||||||
{ 0, 0x01, 0x03, 0x07, 0x0f, 0x1f },
|
{0, 0, 0x02, 0x06, 0x0e, 0x1e },
|
||||||
{ 0, 0, 0x02, 0x06, 0x0e, 0x1e },
|
{0, 0, 0, 0x04, 0x0c, 0x1c },
|
||||||
{ 0, 0, 0, 0x04, 0x0c, 0x1c },
|
{0, 0, 0, 0, 0x08, 0x18 },
|
||||||
{ 0, 0, 0, 0, 0x08, 0x18 },
|
{0, 0, 0, 0, 0, 0x10 }
|
||||||
{ 0, 0, 0, 0, 0, 0x10 }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline uint8 CalcWindowMask (int, uint8, uint8);
|
static inline uint8 CalcWindowMask(int i, uint8 W1, uint8 W2){
|
||||||
static inline void StoreWindowRegions (uint8, struct ClipData *, int, int16 *, uint8 *, bool8, bool8 s = FALSE);
|
if(!PPU.ClipWindow1Enable[i]){
|
||||||
|
if(!PPU.ClipWindow2Enable[i]){
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
if(!PPU.ClipWindow2Inside[i]) return ~W2;
|
||||||
|
return W2;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(!PPU.ClipWindow2Enable[i]){
|
||||||
|
if(!PPU.ClipWindow1Inside[i]) return ~W1;
|
||||||
|
return W1;
|
||||||
|
} else {
|
||||||
|
if(!PPU.ClipWindow1Inside[i]) W1=~W1;
|
||||||
|
if(!PPU.ClipWindow2Inside[i]) W2=~W2;
|
||||||
|
switch(PPU.ClipWindowOverlapLogic[i]){
|
||||||
|
case 0: // OR
|
||||||
|
return W1|W2;
|
||||||
|
case 1: // AND
|
||||||
|
return W1&W2;
|
||||||
|
case 2: // XOR
|
||||||
|
return W1^W2;
|
||||||
|
case 3: // XNOR
|
||||||
|
return ~(W1^W2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Never get here
|
||||||
static inline uint8 CalcWindowMask (int i, uint8 W1, uint8 W2)
|
return 0;
|
||||||
{
|
|
||||||
if (!PPU.ClipWindow1Enable[i])
|
|
||||||
{
|
|
||||||
if (!PPU.ClipWindow2Enable[i])
|
|
||||||
return (0);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!PPU.ClipWindow2Inside[i])
|
|
||||||
return (~W2);
|
|
||||||
return (W2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!PPU.ClipWindow2Enable[i])
|
|
||||||
{
|
|
||||||
if (!PPU.ClipWindow1Inside[i])
|
|
||||||
return (~W1);
|
|
||||||
return (W1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!PPU.ClipWindow1Inside[i])
|
|
||||||
W1 = ~W1;
|
|
||||||
if (!PPU.ClipWindow2Inside[i])
|
|
||||||
W2 = ~W2;
|
|
||||||
|
|
||||||
switch (PPU.ClipWindowOverlapLogic[i])
|
|
||||||
{
|
|
||||||
case 0: // OR
|
|
||||||
return (W1 | W2);
|
|
||||||
|
|
||||||
case 1: // AND
|
|
||||||
return (W1 & W2);
|
|
||||||
|
|
||||||
case 2: // XOR
|
|
||||||
return (W1 ^ W2);
|
|
||||||
|
|
||||||
case 3: // XNOR
|
|
||||||
return (~(W1 ^ W2));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Never get here
|
|
||||||
return (0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void StoreWindowRegions (uint8 Mask, struct ClipData *Clip, int n_regions, int16 *windows, uint8 *drawing_modes, bool8 sub, bool8 StoreMode0)
|
static inline void StoreWindowRegions(uint8 Mask, struct ClipData *Clip, int n_regions, int16 *windows, uint8 *drawing_modes, bool8 sub, bool8 StoreMode0=FALSE){
|
||||||
{
|
int ct=0;
|
||||||
int ct = 0;
|
for(int j=0; j<n_regions; j++){
|
||||||
|
int DrawMode=drawing_modes[j];
|
||||||
for (int j = 0; j < n_regions; j++)
|
if(sub) DrawMode|=1;
|
||||||
{
|
if((Mask&(1<<j))) DrawMode=0;
|
||||||
int DrawMode = drawing_modes[j];
|
if(!StoreMode0 && !DrawMode) continue;
|
||||||
if (sub)
|
if(ct>0 && Clip->Right[ct-1]==windows[j] && Clip->DrawMode[ct-1]==DrawMode){
|
||||||
DrawMode |= 1;
|
// This region borders with and has the same drawing mode as the
|
||||||
if (Mask & (1 << j))
|
// previous region: merge them.
|
||||||
DrawMode = 0;
|
Clip->Right[ct-1]=windows[j+1];
|
||||||
|
} else {
|
||||||
if (!StoreMode0 && !DrawMode)
|
// Add a new region to the BG
|
||||||
continue;
|
Clip->Left[ct]=windows[j];
|
||||||
|
Clip->Right[ct]=windows[j+1];
|
||||||
if (ct > 0 && Clip->Right[ct - 1] == windows[j] && Clip->DrawMode[ct - 1] == DrawMode)
|
Clip->DrawMode[ct]=DrawMode;
|
||||||
Clip->Right[ct - 1] = windows[j + 1]; // This region borders with and has the same drawing mode as the previous region: merge them.
|
ct++;
|
||||||
else
|
}
|
||||||
{
|
}
|
||||||
// Add a new region to the BG
|
Clip->Count=ct;
|
||||||
Clip->Left[ct] = windows[j];
|
|
||||||
Clip->Right[ct] = windows[j + 1];
|
|
||||||
Clip->DrawMode[ct] = DrawMode;
|
|
||||||
ct++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Clip->Count = ct;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xComputeClipWindows (void)
|
void ComputeClipWindows () {
|
||||||
{
|
int16 windows[6]={0,256,256,256,256,256};
|
||||||
int16 windows[6] = { 0, 256, 256, 256, 256, 256 };
|
uint8 drawing_modes[5]={0,0,0,0,0};
|
||||||
uint8 drawing_modes[5] = { 0, 0, 0, 0, 0 };
|
int n_regions=1;
|
||||||
int n_regions = 1;
|
int i, j;
|
||||||
int i, j;
|
|
||||||
|
|
||||||
// Calculate window regions. We have at most 5 regions, because we have 6 control points
|
// Calculate window regions. We have at most 5 regions, because we have 6
|
||||||
// (screen edges, window 1 left & right, and window 2 left & right).
|
// control points (screen edges, window 1 left & right, and window 2 left &
|
||||||
|
// right).
|
||||||
|
if(PPU.Window1Left<=PPU.Window1Right){
|
||||||
|
if(PPU.Window1Left>0){
|
||||||
|
windows[2]=256;
|
||||||
|
windows[1]=PPU.Window1Left;
|
||||||
|
n_regions=2;
|
||||||
|
}
|
||||||
|
if(PPU.Window1Right<255){
|
||||||
|
windows[n_regions+1]=256;
|
||||||
|
windows[n_regions]=PPU.Window1Right+1;
|
||||||
|
n_regions++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(PPU.Window2Left<=PPU.Window2Right){
|
||||||
|
for(i=0; i<=n_regions; i++){
|
||||||
|
if(PPU.Window2Left==windows[i]) break;
|
||||||
|
if(PPU.Window2Left<windows[i]){
|
||||||
|
for(j=n_regions; j>=i; j--){
|
||||||
|
windows[j+1]=windows[j];
|
||||||
|
}
|
||||||
|
windows[i]=PPU.Window2Left;
|
||||||
|
n_regions++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(; i<=n_regions; i++){
|
||||||
|
if(PPU.Window2Right+1==windows[i]) break;
|
||||||
|
if(PPU.Window2Right+1<windows[i]){
|
||||||
|
for(j=n_regions; j>=i; j--){
|
||||||
|
windows[j+1]=windows[j];
|
||||||
|
}
|
||||||
|
windows[i]=PPU.Window2Right+1;
|
||||||
|
n_regions++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (PPU.Window1Left <= PPU.Window1Right)
|
// Get a bitmap of which regions correspond to each window.
|
||||||
{
|
uint8 W1, W2;
|
||||||
if (PPU.Window1Left > 0)
|
|
||||||
{
|
|
||||||
windows[2] = 256;
|
|
||||||
windows[1] = PPU.Window1Left;
|
|
||||||
n_regions = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PPU.Window1Right < 255)
|
if(PPU.Window1Left<=PPU.Window1Right){
|
||||||
{
|
for(i=0; windows[i]!=PPU.Window1Left; i++);
|
||||||
windows[n_regions + 1] = 256;
|
for(j=i; windows[j]!=PPU.Window1Right+1; j++);
|
||||||
windows[n_regions] = PPU.Window1Right + 1;
|
W1=region_map[i][j];
|
||||||
n_regions++;
|
} else {
|
||||||
}
|
W1=0;
|
||||||
}
|
}
|
||||||
|
if(PPU.Window2Left<=PPU.Window2Right){
|
||||||
|
for(i=0; windows[i]!=PPU.Window2Left; i++);
|
||||||
|
for(j=i; windows[j]!=PPU.Window2Right+1; j++);
|
||||||
|
W2=region_map[i][j];
|
||||||
|
} else {
|
||||||
|
W2=0;
|
||||||
|
}
|
||||||
|
|
||||||
if (PPU.Window2Left <= PPU.Window2Right)
|
// Color Window affects the drawing mode for each region. Modes are: 3=Draw
|
||||||
{
|
// as normal, 2=clip color (math only), 1=no math (draw only), 0=nothing.
|
||||||
for (i = 0; i <= n_regions; i++)
|
uint8 CW_color=0, CW_math=0;
|
||||||
{
|
uint8 CW=CalcWindowMask(5,W1,W2);
|
||||||
if (PPU.Window2Left == windows[i])
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (PPU.Window2Left < windows[i])
|
switch(Memory.FillRAM[0x2130]&0xc0){
|
||||||
{
|
case 0x00:
|
||||||
for (j = n_regions; j >= i; j--)
|
CW_color=0;
|
||||||
windows[j + 1] = windows[j];
|
break;
|
||||||
|
case 0x40:
|
||||||
|
CW_color=~CW;
|
||||||
|
break;
|
||||||
|
case 0x80:
|
||||||
|
CW_color=CW;
|
||||||
|
break;
|
||||||
|
case 0xc0:
|
||||||
|
CW_color=0xff;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch(Memory.FillRAM[0x2130]&0x30){
|
||||||
|
case 0x00:
|
||||||
|
CW_math=0;
|
||||||
|
break;
|
||||||
|
case 0x10:
|
||||||
|
CW_math=~CW;
|
||||||
|
break;
|
||||||
|
case 0x20:
|
||||||
|
CW_math=CW;
|
||||||
|
break;
|
||||||
|
case 0x30:
|
||||||
|
CW_math=0xff;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for(i=0; i<n_regions; i++){
|
||||||
|
if(!(CW_color&(1<<i))) drawing_modes[i]|=1;
|
||||||
|
if(!(CW_math&(1<<i))) drawing_modes[i]|=2;
|
||||||
|
}
|
||||||
|
|
||||||
windows[i] = PPU.Window2Left;
|
// Store backdrop clip window (draw everywhere color window allows)
|
||||||
n_regions++;
|
StoreWindowRegions(0, &IPPU.Clip[0][5], n_regions, windows, drawing_modes, FALSE, TRUE);
|
||||||
break;
|
StoreWindowRegions(0, &IPPU.Clip[1][5], n_regions, windows, drawing_modes, TRUE, TRUE);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; i <= n_regions; i++)
|
// Store per-BG and OBJ clip windows
|
||||||
{
|
for(j=0; j<5; j++){
|
||||||
if (PPU.Window2Right + 1 == windows[i])
|
uint8 W=Settings.DisableGraphicWindows?0:CalcWindowMask(j,W1,W2);
|
||||||
break;
|
for(int sub=0; sub<2; sub++){
|
||||||
|
if(Memory.FillRAM[sub+0x212e]&(1<<j)){
|
||||||
if (PPU.Window2Right + 1 < windows[i])
|
StoreWindowRegions(W, &IPPU.Clip[sub][j], n_regions, windows, drawing_modes, sub);
|
||||||
{
|
} else {
|
||||||
for (j = n_regions; j >= i; j--)
|
StoreWindowRegions(0, &IPPU.Clip[sub][j], n_regions, windows, drawing_modes, sub);
|
||||||
windows[j + 1] = windows[j];
|
}
|
||||||
|
}
|
||||||
windows[i] = PPU.Window2Right + 1;
|
}
|
||||||
n_regions++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get a bitmap of which regions correspond to each window.
|
|
||||||
|
|
||||||
uint8 W1, W2;
|
|
||||||
|
|
||||||
if (PPU.Window1Left <= PPU.Window1Right)
|
|
||||||
{
|
|
||||||
for (i = 0; windows[i] != PPU.Window1Left; i++) ;
|
|
||||||
for (j = i; windows[j] != PPU.Window1Right + 1; j++) ;
|
|
||||||
W1 = region_map[i][j];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
W1 = 0;
|
|
||||||
|
|
||||||
if (PPU.Window2Left <= PPU.Window2Right)
|
|
||||||
{
|
|
||||||
for (i = 0; windows[i] != PPU.Window2Left; i++) ;
|
|
||||||
for (j = i; windows[j] != PPU.Window2Right + 1; j++) ;
|
|
||||||
W2 = region_map[i][j];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
W2 = 0;
|
|
||||||
|
|
||||||
// Color Window affects the drawing mode for each region.
|
|
||||||
// Modes are: 3=Draw as normal, 2=clip color (math only), 1=no math (draw only), 0=nothing.
|
|
||||||
|
|
||||||
uint8 CW_color = 0, CW_math = 0;
|
|
||||||
uint8 CW = CalcWindowMask(5, W1, W2);
|
|
||||||
|
|
||||||
switch (Memory.FillRAM[0x2130] & 0xc0)
|
|
||||||
{
|
|
||||||
case 0x00: CW_color = 0; break;
|
|
||||||
case 0x40: CW_color = ~CW; break;
|
|
||||||
case 0x80: CW_color = CW; break;
|
|
||||||
case 0xc0: CW_color = 0xff; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (Memory.FillRAM[0x2130] & 0x30)
|
|
||||||
{
|
|
||||||
case 0x00: CW_math = 0; break;
|
|
||||||
case 0x10: CW_math = ~CW; break;
|
|
||||||
case 0x20: CW_math = CW; break;
|
|
||||||
case 0x30: CW_math = 0xff; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < n_regions; i++)
|
|
||||||
{
|
|
||||||
if (!(CW_color & (1 << i)))
|
|
||||||
drawing_modes[i] |= 1;
|
|
||||||
if (!(CW_math & (1 << i)))
|
|
||||||
drawing_modes[i] |= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store backdrop clip window (draw everywhere color window allows)
|
|
||||||
|
|
||||||
StoreWindowRegions(0, &IPPU.Clip[0][5], n_regions, windows, drawing_modes, FALSE, TRUE);
|
|
||||||
StoreWindowRegions(0, &IPPU.Clip[1][5], n_regions, windows, drawing_modes, TRUE, TRUE);
|
|
||||||
|
|
||||||
// Store per-BG and OBJ clip windows
|
|
||||||
|
|
||||||
for (j = 0; j < 5; j++)
|
|
||||||
{
|
|
||||||
uint8 W = Settings.DisableGraphicWindows ? 0 : CalcWindowMask(j, W1, W2);
|
|
||||||
for (int sub = 0; sub < 2; sub++)
|
|
||||||
{
|
|
||||||
if (Memory.FillRAM[sub + 0x212e] & (1 << j))
|
|
||||||
StoreWindowRegions(W, &IPPU.Clip[sub][j], n_regions, windows, drawing_modes, sub);
|
|
||||||
else
|
|
||||||
StoreWindowRegions(0, &IPPU.Clip[sub][j], n_regions, windows, drawing_modes, sub);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -159,279 +159,292 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _CONTROLS_H_
|
|
||||||
#define _CONTROLS_H_
|
|
||||||
|
|
||||||
#define S9xNoMapping 0
|
#ifndef FOO_H
|
||||||
#define S9xButtonJoypad 1
|
#define FOO_H
|
||||||
#define S9xButtonMouse 2
|
|
||||||
#define S9xButtonSuperscope 3
|
|
||||||
#define S9xButtonJustifier 4
|
|
||||||
#define S9xButtonCommand 5
|
|
||||||
#define S9xButtonMulti 6
|
|
||||||
#define S9xAxisJoypad 7
|
|
||||||
#define S9xPointer 8
|
|
||||||
|
|
||||||
#define S9xButtonPseudopointer 254
|
#include "port.h"
|
||||||
#define S9xAxisPseudopointer 253
|
|
||||||
#define S9xAxisPseudobuttons 252
|
|
||||||
|
|
||||||
// These are automatically kicked out to the S9xHandlePortCommand function.
|
#define S9xNoMapping 0
|
||||||
// If your port wants to define port-specific commands or whatever, use these values for the s9xcommand_t type field.
|
#define S9xButtonJoypad 1
|
||||||
|
#define S9xButtonMouse 2
|
||||||
|
#define S9xButtonSuperscope 3
|
||||||
|
#define S9xButtonJustifier 4
|
||||||
|
#define S9xButtonCommand 5
|
||||||
|
#define S9xButtonMulti 6
|
||||||
|
#define S9xAxisJoypad 7
|
||||||
|
#define S9xPointer 8
|
||||||
|
|
||||||
#define S9xButtonPort 251
|
#define S9xButtonPseudopointer 254
|
||||||
#define S9xAxisPort 250
|
#define S9xAxisPseudopointer 253
|
||||||
#define S9xPointerPort 249
|
#define S9xAxisPseudobuttons 252
|
||||||
|
|
||||||
#define S9xBadMapping 255
|
// These are automatically kicked out to the S9xHandlePortCommand function. If
|
||||||
#define InvalidControlID ((uint32) -1)
|
// your port wants to define port-specific commands or whatever, use these
|
||||||
|
// values for the s9xcommand_t type field.
|
||||||
|
#define S9xButtonPort 251
|
||||||
|
#define S9xAxisPort 250
|
||||||
|
#define S9xPointerPort 249
|
||||||
|
|
||||||
// S9xButtonPseudopointer and S9xAxisPseudopointer will report pointer motion using IDs PseudoPointerBase through PseudoPointerBase+7.
|
#define S9xBadMapping 255
|
||||||
// S9xAxisPseudopointer command types. S9xAxisPseudobuttons will report buttons with IDs PseudoButtonBase to PseudoButtonBase+255.
|
#define InvalidControlID ((uint32)-1)
|
||||||
|
|
||||||
#define PseudoPointerBase (InvalidControlID - 8)
|
// S9xButtonPseudopointer and S9xAxisPseudopointer will report pointer motion
|
||||||
#define PseudoButtonBase (PseudoPointerBase - 256)
|
// using IDs PseudoPointerBase through PseudoPointerBase+7.
|
||||||
|
// S9xAxisPseudopointer command types. S9xAxisPseudobuttons will report buttons
|
||||||
|
// with IDs PseudoButtonBase to PseudoButtonBase+255.
|
||||||
|
#define PseudoPointerBase (InvalidControlID-8)
|
||||||
|
#define PseudoButtonBase (PseudoPointerBase-256)
|
||||||
|
|
||||||
typedef struct
|
// Yes, this struct looks huge. But gcc makes it 6 bytes (the minimum), so it's
|
||||||
{
|
// not that bad.
|
||||||
uint8 type;
|
typedef struct {
|
||||||
uint8 multi_press:2;
|
uint8 type;
|
||||||
uint8 button_norpt:1;
|
uint8 multi_press:2;
|
||||||
|
uint8 button_norpt:1;
|
||||||
|
|
||||||
union
|
union {
|
||||||
{
|
union {
|
||||||
union
|
struct {
|
||||||
{
|
uint8 idx:3; // Pad number 0-7
|
||||||
struct
|
uint8 toggle:1; // If set, toggle turbo/sticky for the button
|
||||||
{
|
uint8 turbo:1; // If set, be a 'turbo' button
|
||||||
uint8 idx:3; // Pad number 0-7
|
uint8 sticky:1; // If set, toggle button state (on/turbo or off)
|
||||||
uint8 toggle:1; // If set, toggle turbo/sticky for the button
|
// when pressed and do nothing on release
|
||||||
uint8 turbo:1; // If set, be a 'turbo' button
|
uint16 buttons; // Which buttons to actuate.
|
||||||
uint8 sticky:1; // If set, toggle button state (on/turbo or off) when pressed and do nothing on release
|
// Use SNES_*_MASK constants from snes9x.h
|
||||||
uint16 buttons; // Which buttons to actuate. Use SNES_*_MASK constants from snes9x.h
|
} joypad;
|
||||||
} joypad;
|
|
||||||
|
|
||||||
struct
|
struct {
|
||||||
{
|
uint8 idx:1; // Mouse number 0-1
|
||||||
uint8 idx:1; // Mouse number 0-1
|
uint8 left:1; // buttons
|
||||||
uint8 left:1; // buttons
|
uint8 right:1;
|
||||||
uint8 right:1;
|
} mouse;
|
||||||
} mouse;
|
|
||||||
|
|
||||||
struct
|
struct {
|
||||||
{
|
uint8 fire:1;
|
||||||
uint8 fire:1;
|
uint8 cursor:1;
|
||||||
uint8 cursor:1;
|
uint8 turbo:1;
|
||||||
uint8 turbo:1;
|
uint8 pause:1;
|
||||||
uint8 pause:1;
|
uint8 aim_offscreen:1; // Pretend we're pointing the gun
|
||||||
uint8 aim_offscreen:1; // Pretend we're pointing the gun offscreen (ignore the pointer)
|
// offscreen (ignore the pointer)
|
||||||
} scope;
|
} scope;
|
||||||
|
|
||||||
struct
|
struct {
|
||||||
{
|
uint8 idx:3; // Pseudo-pointer number 0-7
|
||||||
uint8 idx:3; // Pseudo-pointer number 0-7
|
uint8 speed_type:2; // 0=variable, 1=slow, 2=med, 3=fast
|
||||||
uint8 speed_type:2; // 0=variable, 1=slow, 2=med, 3=fast
|
int8 UD:2; // -1=up, 1=down, 0=no vertical motion
|
||||||
int8 UD:2; // -1=up, 1=down, 0=no vertical motion
|
int8 LR:2; // -1=left, 1=right, 0=no horizontal motion
|
||||||
int8 LR:2; // -1=left, 1=right, 0=no horizontal motion
|
} pointer;
|
||||||
} pointer;
|
|
||||||
|
|
||||||
struct
|
struct {
|
||||||
{
|
uint8 idx:1; // Justifier number 0-1
|
||||||
uint8 idx:1; // Justifier number 0-1
|
uint8 trigger:1; // buttons
|
||||||
uint8 trigger:1; // buttons
|
uint8 start:1;
|
||||||
uint8 start:1;
|
uint8 aim_offscreen:1; // Pretend we're pointing the gun
|
||||||
uint8 aim_offscreen:1; // Pretend we're pointing the gun offscreen (ignore the pointer)
|
// offscreen (ignore the pointer)
|
||||||
} justifier;
|
} justifier;
|
||||||
|
|
||||||
int32 multi_idx;
|
int32 multi_idx;
|
||||||
uint16 command;
|
uint16 command;
|
||||||
} button;
|
} button;
|
||||||
|
|
||||||
union
|
union {
|
||||||
{
|
struct {
|
||||||
struct
|
uint8 idx:3; // Pad number 0-7
|
||||||
{
|
uint8 invert:1; // 1 = positive is Left/Up/Y/X/L
|
||||||
uint8 idx:3; // Pad number 0-7
|
uint8 axis:3; // 0=Left/Right, 1=Up/Down,
|
||||||
uint8 invert:1; // 1 = positive is Left/Up/Y/X/L
|
// 2=Y/A, 3=X/B, 4=L/R
|
||||||
uint8 axis:3; // 0=Left/Right, 1=Up/Down, 2=Y/A, 3=X/B, 4=L/R
|
uint8 threshold; // (threshold+1)/256% deflection is a
|
||||||
uint8 threshold; // (threshold+1)/256% deflection is a button press
|
// button press
|
||||||
} joypad;
|
} joypad;
|
||||||
|
|
||||||
struct
|
struct {
|
||||||
{
|
uint8 idx:3; // Pseudo-pointer number 0-7
|
||||||
uint8 idx:3; // Pseudo-pointer number 0-7
|
uint8 speed_type:2; // 0=variable, 1=slow, 2=med, 3=fast
|
||||||
uint8 speed_type:2; // 0=variable, 1=slow, 2=med, 3=fast
|
uint8 invert:1; // 1 = invert axis, so positive is up/left
|
||||||
uint8 invert:1; // 1 = invert axis, so positive is up/left
|
uint8 HV:1; // 0=horizontal, 1=vertical
|
||||||
uint8 HV:1; // 0=horizontal, 1=vertical
|
} pointer;
|
||||||
} pointer;
|
|
||||||
|
|
||||||
struct
|
struct {
|
||||||
{
|
uint8 threshold; // (threshold+1)/256% deflection is a
|
||||||
uint8 threshold; // (threshold+1)/256% deflection is a button press
|
// button press
|
||||||
uint8 negbutton; // Button ID for negative deflection
|
uint8 negbutton; // Button ID for negative deflection
|
||||||
uint8 posbutton; // Button ID for positive deflection
|
uint8 posbutton; // Button ID for positive deflection
|
||||||
} button;
|
} button;
|
||||||
} axis;
|
} axis;
|
||||||
|
|
||||||
struct // Which SNES-pointers to control with this pointer
|
struct {
|
||||||
{
|
// Which SNES-pointers to control with this pointer
|
||||||
uint16 aim_mouse0:1;
|
uint16 aim_mouse0:1;
|
||||||
uint16 aim_mouse1:1;
|
uint16 aim_mouse1:1;
|
||||||
uint16 aim_scope:1;
|
uint16 aim_scope:1;
|
||||||
uint16 aim_justifier0:1;
|
uint16 aim_justifier0:1;
|
||||||
uint16 aim_justifier1:1;
|
uint16 aim_justifier1:1;
|
||||||
} pointer;
|
} pointer;
|
||||||
|
|
||||||
uint8 port[4];
|
uint8 port[4];
|
||||||
};
|
};
|
||||||
} s9xcommand_t;
|
} s9xcommand_t;
|
||||||
|
|
||||||
// Starting out...
|
|
||||||
|
|
||||||
void S9xUnmapAllControls (void);
|
/* Starting out... */
|
||||||
|
void S9xUnmapAllControls(void);
|
||||||
|
|
||||||
// Setting which controllers are plugged in.
|
/* Setting which controllers are plugged in */
|
||||||
|
enum controllers {
|
||||||
enum controllers
|
CTL_NONE, /* all ids ignored */
|
||||||
{
|
CTL_JOYPAD, /* use id1 to specify 0-7 */
|
||||||
CTL_NONE, // all ids ignored
|
CTL_MOUSE, /* use id1 to specify 0-1 */
|
||||||
CTL_JOYPAD, // use id1 to specify 0-7
|
CTL_SUPERSCOPE,
|
||||||
CTL_MOUSE, // use id1 to specify 0-1
|
CTL_JUSTIFIER, /* use id1: 0=one justifier, 1=two justifiers */
|
||||||
CTL_SUPERSCOPE,
|
CTL_MP5 /* use id1-id4 to specify pad 0-7 (or -1) */
|
||||||
CTL_JUSTIFIER, // use id1: 0=one justifier, 1=two justifiers
|
|
||||||
CTL_MP5 // use id1-id4 to specify pad 0-7 (or -1)
|
|
||||||
};
|
};
|
||||||
|
void S9xSetController(int port, enum controllers controller, int8 id1, int8 id2, int8 id3, int8 id4); /* port=0-1 */
|
||||||
|
void S9xGetController(int port, enum controllers *controller, int8 *id1, int8 *id2, int8 *id3, int8 *id4);
|
||||||
|
void S9xReportControllers(void);
|
||||||
|
|
||||||
void S9xSetController (int port, enum controllers controller, int8 id1, int8 id2, int8 id3, int8 id4); // port=0-1
|
/* Call this when you're done with S9xSetController, or if you change any of
|
||||||
void S9xGetController (int port, enum controllers *controller, int8 *id1, int8 *id2, int8 *id3, int8 *id4);
|
* the controller Settings.*Master flags. Returns true if something was
|
||||||
void S9xReportControllers (void);
|
* disabled */
|
||||||
|
bool S9xVerifyControllers(void);
|
||||||
|
|
||||||
// Call this when you're done with S9xSetController, or if you change any of the controller Settings.*Master flags.
|
/*
|
||||||
// Returns true if something was disabled.
|
* Functions for translation s9xcommand_t's into strings, and vice versa.
|
||||||
|
* free() the returned string after you're done with it.
|
||||||
|
*/
|
||||||
|
char *S9xGetCommandName(s9xcommand_t command);
|
||||||
|
s9xcommand_t S9xGetCommandT(const char *name);
|
||||||
|
|
||||||
bool S9xVerifyControllers (void);
|
/*
|
||||||
|
* Returns an array of strings naming all the snes9x commands. Note that this
|
||||||
|
* is only the strings for S9xButtonCommand! The idea is that this would be
|
||||||
|
* used for a pull-down list in a config GUI. DO NOT free() the returned value.
|
||||||
|
*/
|
||||||
|
const char **S9xGetAllSnes9xCommands(void);
|
||||||
|
|
||||||
// Functions for translation s9xcommand_t's into strings, and vice versa.
|
/*
|
||||||
// free() the returned string after you're done with it.
|
* Generic mapping functions
|
||||||
|
*/
|
||||||
|
s9xcommand_t S9xGetMapping(uint32 id);
|
||||||
|
void S9xUnmapID(uint32 id);
|
||||||
|
|
||||||
char * S9xGetCommandName (s9xcommand_t command);
|
/*
|
||||||
s9xcommand_t S9xGetCommandT (const char *name);
|
* Button mapping functions. If a button is mapped with poll=TRUE, then
|
||||||
|
* S9xPollButton will be called whenever snes9x feels a need for that mapping.
|
||||||
|
* Otherwise, snes9x will assume you will call S9xReportButton() whenever the
|
||||||
|
* button state changes. S9xMapButton() will fail and return FALSE if
|
||||||
|
* mapping.type isn't a S9xButton* type.
|
||||||
|
*/
|
||||||
|
bool S9xMapButton(uint32 id, s9xcommand_t mapping, bool poll);
|
||||||
|
void S9xReportButton(uint32 id, bool pressed);
|
||||||
|
|
||||||
// Returns an array of strings naming all the snes9x commands.
|
/*
|
||||||
// Note that this is only the strings for S9xButtonCommand!
|
* Pointer mapping functions. If a button is mapped with poll=TRUE, then
|
||||||
// The idea is that this would be used for a pull-down list in a config GUI. DO NOT free() the returned value.
|
* S9xPollPointer will be called whenever snes9x feels a need for that mapping.
|
||||||
|
* Otherwise, snes9x will assume you will call S9xReportPointer() whenever the
|
||||||
|
* pointer position changes. S9xMapPointer() will fail and return FALSE if
|
||||||
|
* mapping.type isn't S9xPointer.
|
||||||
|
*
|
||||||
|
* Note that position [0,0] is considered the upper-left corner of the
|
||||||
|
* 'screen', and either [255,223] or [255,239] is the lower-right. Note that
|
||||||
|
* the SNES mouse doesn't aim at a particular point, so the SNES's idea of
|
||||||
|
* where the mouse pointer is will probably differ from your OS's idea.
|
||||||
|
*/
|
||||||
|
bool S9xMapPointer(uint32 id, s9xcommand_t mapping, bool poll);
|
||||||
|
void S9xReportPointer(uint32 id, int16 x, int16 y);
|
||||||
|
|
||||||
const char ** S9xGetAllSnes9xCommands (void);
|
/*
|
||||||
|
* Axis mapping functions. If a button is mapped with poll=TRUE, then
|
||||||
|
* S9xPollAxis will be called whenever snes9x feels a need for that mapping.
|
||||||
|
* Otherwise, snes9x will assume you will call S9xReportAxis() whenever the
|
||||||
|
* axis deflection changes. S9xMapAxis() will fail and return FALSE if
|
||||||
|
* mapping.type isn't a S9xAxis* type.
|
||||||
|
*
|
||||||
|
* Note that value is linear -32767 through 32767 with 0 being no
|
||||||
|
* deflection. If your axis reports differently you should transform the
|
||||||
|
* value before passing it to S9xReportAxis().
|
||||||
|
*/
|
||||||
|
bool S9xMapAxis(uint32 id, s9xcommand_t mapping, bool poll);
|
||||||
|
void S9xReportAxis(uint32 id, int16 value);
|
||||||
|
|
||||||
// Generic mapping functions
|
/*
|
||||||
|
* Do whatever the s9xcommand_t says to do. If cmd.type is a button type, data1
|
||||||
|
* should be TRUE (non-0) or FALSE (0) to indicate whether the 'button' is
|
||||||
|
* pressed or released. If cmd.type is an axis, data1 holds the deflection
|
||||||
|
* value. If cmd.type is a pointer, data1 and data2 are the positions of the
|
||||||
|
* pointer.
|
||||||
|
*/
|
||||||
|
void S9xApplyCommand(s9xcommand_t cmd, int16 data1, int16 data2);
|
||||||
|
|
||||||
s9xcommand_t S9xGetMapping (uint32 id);
|
/*******
|
||||||
void S9xUnmapID (uint32 id);
|
* These functions are called by snes9x into your port, so each port should
|
||||||
|
* implement them.
|
||||||
|
*/
|
||||||
|
|
||||||
// Button mapping functions.
|
/*
|
||||||
// If a button is mapped with poll=TRUE, then S9xPollButton will be called whenever snes9x feels a need for that mapping.
|
* If something was mapped with poll=TRUE, these functions will be called when
|
||||||
// Otherwise, snes9x will assume you will call S9xReportButton() whenever the button state changes.
|
* snes9x needs the button/axis/pointer state. Fill in the reference options as
|
||||||
// S9xMapButton() will fail and return FALSE if mapping.type isn't an S9xButton* type.
|
* appropriate.
|
||||||
|
*/
|
||||||
|
bool S9xPollButton(uint32 id, bool *pressed);
|
||||||
|
bool S9xPollPointer(uint32 id, int16 *x, int16 *y);
|
||||||
|
bool S9xPollAxis(uint32 id, int16 *value);
|
||||||
|
|
||||||
bool S9xMapButton (uint32 id, s9xcommand_t mapping, bool poll);
|
/*
|
||||||
void S9xReportButton (uint32 id, bool pressed);
|
* These are called when snes9x tries to apply a command with a S9x*Port type.
|
||||||
|
* data1 and data2 are filled in like S9xApplyCommand.
|
||||||
// Pointer mapping functions.
|
*/
|
||||||
// If a pointer is mapped with poll=TRUE, then S9xPollPointer will be called whenever snes9x feels a need for that mapping.
|
void S9xHandlePortCommand(s9xcommand_t cmd, int16 data1, int16 data2);
|
||||||
// Otherwise, snes9x will assume you will call S9xReportPointer() whenever the pointer position changes.
|
|
||||||
// S9xMapPointer() will fail and return FALSE if mapping.type isn't an S9xPointer* type.
|
|
||||||
|
|
||||||
// Note that position [0,0] is considered the upper-left corner of the 'screen',
|
|
||||||
// and either [255,223] or [255,239] is the lower-right.
|
|
||||||
// Note that the SNES mouse doesn't aim at a particular point,
|
|
||||||
// so the SNES's idea of where the mouse pointer is will probably differ from your OS's idea.
|
|
||||||
|
|
||||||
bool S9xMapPointer (uint32 id, s9xcommand_t mapping, bool poll);
|
|
||||||
void S9xReportPointer (uint32 id, int16 x, int16 y);
|
|
||||||
|
|
||||||
// Axis mapping functions.
|
|
||||||
// If an axis is mapped with poll=TRUE, then S9xPollAxis will be called whenever snes9x feels a need for that mapping.
|
|
||||||
// Otherwise, snes9x will assume you will call S9xReportAxis() whenever the axis deflection changes.
|
|
||||||
// S9xMapAxis() will fail and return FALSE if mapping.type isn't an S9xAxis* type.
|
|
||||||
|
|
||||||
// Note that value is linear -32767 through 32767 with 0 being no deflection.
|
|
||||||
// If your axis reports differently you should transform the value before passing it to S9xReportAxis().
|
|
||||||
|
|
||||||
bool S9xMapAxis (uint32 id, s9xcommand_t mapping, bool poll);
|
|
||||||
void S9xReportAxis (uint32 id, int16 value);
|
|
||||||
|
|
||||||
// Do whatever the s9xcommand_t says to do.
|
|
||||||
// If cmd.type is a button type, data1 should be TRUE (non-0) or FALSE (0) to indicate whether the 'button' is pressed or released.
|
|
||||||
// If cmd.type is an axis, data1 holds the deflection value.
|
|
||||||
// If cmd.type is a pointer, data1 and data2 are the positions of the pointer.
|
|
||||||
|
|
||||||
void S9xApplyCommand (s9xcommand_t cmd, int16 data1, int16 data2);
|
|
||||||
|
|
||||||
//////////
|
|
||||||
// These functions are called by snes9x into your port, so each port should implement them.
|
|
||||||
|
|
||||||
// If something was mapped with poll=TRUE, these functions will be called when snes9x needs the button/axis/pointer state.
|
|
||||||
// Fill in the reference options as appropriate.
|
|
||||||
|
|
||||||
bool S9xPollButton (uint32 id, bool *pressed);
|
|
||||||
bool S9xPollPointer (uint32 id, int16 *x, int16 *y);
|
|
||||||
bool S9xPollAxis (uint32 id, int16 *value);
|
|
||||||
|
|
||||||
// These are called when snes9x tries to apply a command with a S9x*Port type.
|
|
||||||
// data1 and data2 are filled in like S9xApplyCommand.
|
|
||||||
|
|
||||||
void S9xHandlePortCommand (s9xcommand_t cmd, int16 data1, int16 data2);
|
|
||||||
|
|
||||||
// Called before already-read SNES joypad data is being used by the game if your port defines SNES_JOY_READ_CALLBACKS.
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called before already-read SNES joypad data is being used by the game
|
||||||
|
* if your port defines SNES_JOY_READ_CALLBACKS
|
||||||
|
*/
|
||||||
#ifdef SNES_JOY_READ_CALLBACKS
|
#ifdef SNES_JOY_READ_CALLBACKS
|
||||||
void S9xOnSNESPadRead (void);
|
void S9xOnSNESPadRead();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// These are for your use.
|
/* These are for your use */
|
||||||
|
s9xcommand_t S9xGetPortCommandT(const char *name);
|
||||||
|
char *S9xGetPortCommandName(s9xcommand_t command);
|
||||||
|
void S9xSetupDefaultKeymap(void);
|
||||||
|
bool8 S9xMapInput(const char *name, s9xcommand_t *cmd);
|
||||||
|
|
||||||
s9xcommand_t S9xGetPortCommandT (const char *name);
|
|
||||||
char * S9xGetPortCommandName (s9xcommand_t command);
|
|
||||||
void S9xSetupDefaultKeymap (void);
|
|
||||||
bool8 S9xMapInput (const char *name, s9xcommand_t *cmd);
|
|
||||||
|
|
||||||
//////////
|
/*******
|
||||||
// These functions are called from snes9x into this subsystem. No need to use them from a port.
|
* These functions are called from snes9x into this subsystem. No need to use
|
||||||
|
* them from a port.
|
||||||
|
*/
|
||||||
|
|
||||||
// Use when resetting snes9x.
|
/* Use when resetting snes9x */
|
||||||
|
void S9xControlsReset(void);
|
||||||
|
void S9xControlsSoftReset(void);
|
||||||
|
|
||||||
void S9xControlsReset (void);
|
/* Use when writing to $4016 */
|
||||||
void S9xControlsSoftReset (void);
|
void S9xSetJoypadLatch(bool latch);
|
||||||
|
|
||||||
// Use when writing to $4016.
|
/* Use when reading $4016/7 (JOYSER0 and JOYSER1) */
|
||||||
|
uint8 S9xReadJOYSERn(int n);
|
||||||
|
|
||||||
void S9xSetJoypadLatch (bool latch);
|
/* End-Of-Frame processing. Sets gun latch variables and tries to draw
|
||||||
|
* crosshairs */
|
||||||
|
void S9xControlEOF(void);
|
||||||
|
|
||||||
// Use when reading $4016/7 (JOYSER0 and JOYSER1).
|
struct SControlSnapshot {
|
||||||
|
uint8 ver;
|
||||||
uint8 S9xReadJOYSERn (int n);
|
uint8 port1_read_idx[2];
|
||||||
|
uint8 dummy1[4]; // for future expansion
|
||||||
// End-Of-Frame processing. Sets gun latch variables and tries to draw crosshairs
|
uint8 port2_read_idx[2];
|
||||||
|
uint8 dummy2[4];
|
||||||
void S9xControlEOF (void);
|
uint8 mouse_speed[2];
|
||||||
|
uint8 justifier_select;
|
||||||
// Functions and a structure for snapshot.
|
uint8 dummy3[8];
|
||||||
|
bool8 pad_read, pad_read_last;
|
||||||
struct SControlSnapshot
|
uint8 internal[60]; // yes, we need to save this!
|
||||||
{
|
|
||||||
uint8 ver;
|
|
||||||
uint8 port1_read_idx[2];
|
|
||||||
uint8 dummy1[4]; // for future expansion
|
|
||||||
uint8 port2_read_idx[2];
|
|
||||||
uint8 dummy2[4];
|
|
||||||
uint8 mouse_speed[2];
|
|
||||||
uint8 justifier_select;
|
|
||||||
uint8 dummy3[8];
|
|
||||||
bool8 pad_read, pad_read_last;
|
|
||||||
uint8 internal[60]; // yes, we need to save this!
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void S9xControlPreSaveState (struct SControlSnapshot *s);
|
void S9xControlPreSave(struct SControlSnapshot *s);
|
||||||
void S9xControlPostLoadState (struct SControlSnapshot *s);
|
void S9xControlPostLoad(struct SControlSnapshot *s);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
233
source/snes9x/copyright.h
Normal file
233
source/snes9x/copyright.h
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
/**********************************************************************************
|
||||||
|
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||||
|
|
||||||
|
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||||
|
Jerremy Koot (jkoot@snes9x.com)
|
||||||
|
|
||||||
|
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||||
|
|
||||||
|
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||||
|
|
||||||
|
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||||
|
|
||||||
|
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||||
|
|
||||||
|
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||||
|
Kris Bleakley (codeviolation@hotmail.com)
|
||||||
|
|
||||||
|
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
|
||||||
|
Nach (n-a-c-h@users.sourceforge.net),
|
||||||
|
zones (kasumitokoduck@yahoo.com)
|
||||||
|
|
||||||
|
(c) Copyright 2006 - 2007 nitsuja
|
||||||
|
|
||||||
|
|
||||||
|
BS-X C emulator code
|
||||||
|
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||||
|
zones
|
||||||
|
|
||||||
|
C4 x86 assembler and some C emulation code
|
||||||
|
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||||
|
Nach,
|
||||||
|
zsKnight (zsknight@zsnes.com)
|
||||||
|
|
||||||
|
C4 C++ code
|
||||||
|
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||||
|
Nach
|
||||||
|
|
||||||
|
DSP-1 emulator code
|
||||||
|
(c) Copyright 1998 - 2006 _Demo_,
|
||||||
|
Andreas Naive (andreasnaive@gmail.com)
|
||||||
|
Gary Henderson,
|
||||||
|
Ivar (ivar@snes9x.com),
|
||||||
|
John Weidman,
|
||||||
|
Kris Bleakley,
|
||||||
|
Matthew Kendora,
|
||||||
|
Nach,
|
||||||
|
neviksti (neviksti@hotmail.com)
|
||||||
|
|
||||||
|
DSP-2 emulator code
|
||||||
|
(c) Copyright 2003 John Weidman,
|
||||||
|
Kris Bleakley,
|
||||||
|
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||||
|
Matthew Kendora,
|
||||||
|
neviksti
|
||||||
|
|
||||||
|
|
||||||
|
DSP-3 emulator code
|
||||||
|
(c) Copyright 2003 - 2006 John Weidman,
|
||||||
|
Kris Bleakley,
|
||||||
|
Lancer,
|
||||||
|
z80 gaiden
|
||||||
|
|
||||||
|
DSP-4 emulator code
|
||||||
|
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||||
|
John Weidman,
|
||||||
|
Kris Bleakley,
|
||||||
|
Nach,
|
||||||
|
z80 gaiden
|
||||||
|
|
||||||
|
OBC1 emulator code
|
||||||
|
(c) Copyright 2001 - 2004 zsKnight,
|
||||||
|
pagefault (pagefault@zsnes.com),
|
||||||
|
Kris Bleakley,
|
||||||
|
Ported from x86 assembler to C by sanmaiwashi
|
||||||
|
|
||||||
|
SPC7110 and RTC C++ emulator code
|
||||||
|
(c) Copyright 2002 Matthew Kendora with research by
|
||||||
|
zsKnight,
|
||||||
|
John Weidman,
|
||||||
|
Dark Force
|
||||||
|
|
||||||
|
S-DD1 C emulator code
|
||||||
|
(c) Copyright 2003 Brad Jorsch with research by
|
||||||
|
Andreas Naive,
|
||||||
|
John Weidman
|
||||||
|
|
||||||
|
S-RTC C emulator code
|
||||||
|
(c) Copyright 2001-2006 byuu,
|
||||||
|
John Weidman
|
||||||
|
|
||||||
|
ST010 C++ emulator code
|
||||||
|
(c) Copyright 2003 Feather,
|
||||||
|
John Weidman,
|
||||||
|
Kris Bleakley,
|
||||||
|
Matthew Kendora
|
||||||
|
|
||||||
|
Super FX x86 assembler emulator code
|
||||||
|
(c) Copyright 1998 - 2003 _Demo_,
|
||||||
|
pagefault,
|
||||||
|
zsKnight,
|
||||||
|
|
||||||
|
Super FX C emulator code
|
||||||
|
(c) Copyright 1997 - 1999 Ivar,
|
||||||
|
Gary Henderson,
|
||||||
|
John Weidman
|
||||||
|
|
||||||
|
Sound DSP emulator code is derived from SNEeSe and OpenSPC:
|
||||||
|
(c) Copyright 1998 - 2003 Brad Martin
|
||||||
|
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||||
|
|
||||||
|
SH assembler code partly based on x86 assembler code
|
||||||
|
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||||
|
|
||||||
|
2xSaI filter
|
||||||
|
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||||
|
|
||||||
|
HQ2x, HQ3x, HQ4x filters
|
||||||
|
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||||
|
|
||||||
|
Win32 GUI code
|
||||||
|
(c) Copyright 2003 - 2006 blip,
|
||||||
|
funkyass,
|
||||||
|
Matthew Kendora,
|
||||||
|
Nach,
|
||||||
|
nitsuja
|
||||||
|
|
||||||
|
Mac OS GUI code
|
||||||
|
(c) Copyright 1998 - 2001 John Stiles
|
||||||
|
(c) Copyright 2001 - 2007 zones
|
||||||
|
|
||||||
|
|
||||||
|
Specific ports contains the works of other authors. See headers in
|
||||||
|
individual files.
|
||||||
|
|
||||||
|
|
||||||
|
Snes9x homepage: http://www.snes9x.com
|
||||||
|
|
||||||
|
Permission to use, copy, modify and/or 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 or it's derivatives.
|
||||||
|
|
||||||
|
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||||
|
seek permission of the copyright holders first. Commercial use includes,
|
||||||
|
but is not limited to, charging money for Snes9x or software derived from
|
||||||
|
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||||
|
using Snes9x as a promotion for your commercial product.
|
||||||
|
|
||||||
|
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.
|
||||||
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||||
|
*
|
||||||
|
* (c) Copyright 1996, 1997, 1998, 1999 Gary Henderson (gary@daniver.demon.co.uk) and
|
||||||
|
* Jerremy Koot (jkoot@snes9x.com)
|
||||||
|
*
|
||||||
|
* Super FX C emulator code (c) Copyright 1997, 1998 Ivar and
|
||||||
|
* Gary Henderson.
|
||||||
|
* Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
@ -159,165 +159,283 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "snes9x.h"
|
#include "snes9x.h"
|
||||||
#include "memmap.h"
|
#include "memmap.h"
|
||||||
|
#include "ppu.h"
|
||||||
|
#include "dsp1.h"
|
||||||
|
#include "cpuexec.h"
|
||||||
|
#include "s9xdebug.h"
|
||||||
|
#include "apu.h"
|
||||||
#include "dma.h"
|
#include "dma.h"
|
||||||
#include "apu/apu.h"
|
#include "sa1.h"
|
||||||
#include "fxemu.h"
|
|
||||||
#include "sdd1.h"
|
|
||||||
#include "srtc.h"
|
|
||||||
#include "snapshot.h"
|
|
||||||
#include "cheats.h"
|
#include "cheats.h"
|
||||||
|
#include "srtc.h"
|
||||||
|
#include "sdd1.h"
|
||||||
|
#include "spc7110.h"
|
||||||
|
#include "obc1.h"
|
||||||
|
#include "bsx.h"
|
||||||
|
#include "snapshot.h"
|
||||||
|
#ifndef NGC
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#ifdef DEBUGGER
|
|
||||||
#include "debug.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void S9xResetCPU (void);
|
|
||||||
static void S9xSoftResetCPU (void);
|
|
||||||
|
|
||||||
|
#ifndef ZSNES_FX
|
||||||
|
#include "fxemu.h"
|
||||||
|
|
||||||
static void S9xResetCPU (void)
|
extern struct FxInit_s SuperFX;
|
||||||
|
|
||||||
|
void S9xResetSuperFX ()
|
||||||
{
|
{
|
||||||
S9xSoftResetCPU();
|
SuperFX.vFlags = 0; //FX_FLAG_ROM_BUFFER;// | FX_FLAG_ADDRESS_CHECKING;
|
||||||
Registers.SL = 0xff;
|
// FIXME: Snes9x can't execute CPU and SuperFX at a time. Don't ask me what is 0.417 :P
|
||||||
Registers.P.W = 0;
|
SuperFX.speedPerLine = (uint32) (0.417 * 10.5e6 * ((1.0 / (float) Memory.ROMFramesPerSecond) / ((float) (Timings.V_Max))));
|
||||||
Registers.A.W = 0;
|
//printf("SFX:%d\n", SuperFX.speedPerLine);
|
||||||
Registers.X.W = 0;
|
SuperFX.oneLineDone = FALSE;
|
||||||
Registers.Y.W = 0;
|
FxReset (&SuperFX);
|
||||||
SetFlags(MemoryFlag | IndexFlag | IRQ | Emulation);
|
|
||||||
ClearFlags(Decimal);
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void S9xSoftResetCPU (void)
|
void S9xSoftResetCPU ()
|
||||||
{
|
{
|
||||||
Registers.PBPC = 0;
|
Registers.PBPC = 0;
|
||||||
Registers.PB = 0;
|
Registers.PB = 0;
|
||||||
Registers.PCw = S9xGetWord(0xfffc);
|
Registers.PCw = S9xGetWord (0xFFFC);
|
||||||
OpenBus = Registers.PCh;
|
OpenBus = Registers.PCh;
|
||||||
Registers.D.W = 0;
|
Registers.D.W = 0;
|
||||||
Registers.DB = 0;
|
Registers.DB = 0;
|
||||||
Registers.SH = 1;
|
Registers.SH = 1;
|
||||||
Registers.SL -= 3;
|
Registers.SL -= 3;
|
||||||
Registers.XH = 0;
|
Registers.XH = 0;
|
||||||
Registers.YH = 0;
|
Registers.YH = 0;
|
||||||
|
|
||||||
ICPU.ShiftedPB = 0;
|
ICPU.ShiftedPB = 0;
|
||||||
ICPU.ShiftedDB = 0;
|
ICPU.ShiftedDB = 0;
|
||||||
SetFlags(MemoryFlag | IndexFlag | IRQ | Emulation);
|
SetFlags (MemoryFlag | IndexFlag | IRQ | Emulation);
|
||||||
ClearFlags(Decimal);
|
ClearFlags (Decimal);
|
||||||
|
|
||||||
CPU.Cycles = 182; // Or 188. This is the cycle count just after the jump to the Reset Vector.
|
CPU.Flags = CPU.Flags & (DEBUG_MODE_FLAG | TRACE_FLAG);
|
||||||
CPU.PrevCycles = -1;
|
CPU.BranchSkip = FALSE;
|
||||||
CPU.V_Counter = 0;
|
CPU.NMIActive = FALSE;
|
||||||
CPU.Flags = CPU.Flags & (DEBUG_MODE_FLAG | TRACE_FLAG);
|
CPU.IRQActive = FALSE;
|
||||||
CPU.PCBase = NULL;
|
CPU.WaitingForInterrupt = FALSE;
|
||||||
CPU.IRQActive = FALSE;
|
|
||||||
CPU.IRQPending = 0;
|
|
||||||
CPU.MemSpeed = SLOW_ONE_CYCLE;
|
|
||||||
CPU.MemSpeedx2 = SLOW_ONE_CYCLE * 2;
|
|
||||||
CPU.FastROMSpeed = SLOW_ONE_CYCLE;
|
|
||||||
CPU.InDMA = FALSE;
|
CPU.InDMA = FALSE;
|
||||||
CPU.InHDMA = FALSE;
|
CPU.InHDMA = FALSE;
|
||||||
CPU.InDMAorHDMA = FALSE;
|
CPU.InDMAorHDMA = FALSE;
|
||||||
CPU.InWRAMDMAorHDMA = FALSE;
|
CPU.InWRAMDMAorHDMA = FALSE;
|
||||||
CPU.HDMARanInDMA = 0;
|
CPU.HDMARanInDMA = 0;
|
||||||
CPU.CurrentDMAorHDMAChannel = -1;
|
CPU.PCBase = NULL;
|
||||||
CPU.WhichEvent = HC_RENDER_EVENT;
|
CPU.PBPCAtOpcodeStart = 0xffffffff;
|
||||||
CPU.NextEvent = Timings.RenderPos;
|
CPU.WaitAddress = 0xffffffff;
|
||||||
CPU.WaitingForInterrupt = FALSE;
|
CPU.WaitCounter = 0;
|
||||||
CPU.WaitAddress = 0xffffffff;
|
CPU.Cycles = 182; // Or 188. This is the cycle count just after the jump to the Reset Vector.
|
||||||
CPU.WaitCounter = 0;
|
CPU.PrevCycles = -1;
|
||||||
CPU.PBPCAtOpcodeStart = 0xffffffff;
|
CPU.V_Counter = 0;
|
||||||
CPU.AutoSaveTimer = 0;
|
CPU.MemSpeed = SLOW_ONE_CYCLE;
|
||||||
CPU.SRAMModified = FALSE;
|
CPU.MemSpeedx2 = SLOW_ONE_CYCLE * 2;
|
||||||
|
CPU.FastROMSpeed = SLOW_ONE_CYCLE;
|
||||||
|
CPU.AutoSaveTimer = 0;
|
||||||
|
CPU.SRAMModified = FALSE;
|
||||||
|
CPU.BRKTriggered = FALSE;
|
||||||
|
CPU.IRQPending = 0;
|
||||||
|
|
||||||
Timings.InterlaceField = FALSE;
|
Timings.InterlaceField = FALSE;
|
||||||
Timings.H_Max = Timings.H_Max_Master;
|
Timings.H_Max = Timings.H_Max_Master;
|
||||||
Timings.V_Max = Timings.V_Max_Master;
|
Timings.V_Max = Timings.V_Max_Master;
|
||||||
Timings.NMITriggerPos = 0xffff;
|
Timings.NMITriggerPos = 0xffff;
|
||||||
if (Model->_5A22 == 2)
|
if (Model->_5A22 == 2)
|
||||||
Timings.WRAMRefreshPos = SNES_WRAM_REFRESH_HC_v2;
|
Timings.WRAMRefreshPos = SNES_WRAM_REFRESH_HC_v2;
|
||||||
else
|
else
|
||||||
Timings.WRAMRefreshPos = SNES_WRAM_REFRESH_HC_v1;
|
Timings.WRAMRefreshPos = SNES_WRAM_REFRESH_HC_v1;
|
||||||
|
|
||||||
S9xSetPCBase(Registers.PBPC);
|
CPU.WhichEvent = HC_RENDER_EVENT;
|
||||||
|
CPU.NextEvent = Timings.RenderPos;
|
||||||
|
|
||||||
ICPU.S9xOpcodes = S9xOpcodesE1;
|
S9xSetPCBase (Registers.PBPC);
|
||||||
ICPU.S9xOpLengths = S9xOpLengthsM1X1;
|
|
||||||
ICPU.CPUExecuting = TRUE;
|
|
||||||
|
|
||||||
S9xUnpackStatus();
|
ICPU.S9xOpcodes = S9xOpcodesE1;
|
||||||
|
ICPU.S9xOpLengths = S9xOpLengthsM1X1;
|
||||||
|
ICPU.CPUExecuting = TRUE;
|
||||||
|
|
||||||
|
S9xUnpackStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void S9xResetCPU ()
|
||||||
|
{
|
||||||
|
S9xSoftResetCPU ();
|
||||||
|
Registers.SL = 0xFF;
|
||||||
|
Registers.P.W = 0;
|
||||||
|
Registers.A.W = 0;
|
||||||
|
Registers.X.W = 0;
|
||||||
|
Registers.Y.W = 0;
|
||||||
|
SetFlags (MemoryFlag | IndexFlag | IRQ | Emulation);
|
||||||
|
ClearFlags (Decimal);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ZSNES_FX
|
||||||
|
START_EXTERN_C
|
||||||
|
void S9xResetSuperFX ();
|
||||||
|
bool8 WinterGold = 0;
|
||||||
|
extern uint8 *C4Ram;
|
||||||
|
END_EXTERN_C
|
||||||
|
#endif
|
||||||
|
|
||||||
void S9xReset (void)
|
void S9xReset (void)
|
||||||
{
|
{
|
||||||
S9xResetSaveTimer(FALSE);
|
#ifndef NGC
|
||||||
S9xResetLogger();
|
ResetLogger();
|
||||||
|
S9xResetSaveTimer (FALSE);
|
||||||
|
#endif
|
||||||
|
|
||||||
memset(Memory.RAM, 0x55, 0x20000);
|
ZeroMemory (Memory.FillRAM, 0x8000);
|
||||||
memset(Memory.VRAM, 0x00, 0x10000);
|
memset (Memory.VRAM, 0x00, 0x10000);
|
||||||
ZeroMemory(Memory.FillRAM, 0x8000);
|
memset (Memory.RAM, 0x55, 0x20000);
|
||||||
|
|
||||||
if (Settings.BS)
|
if (Settings.BS)
|
||||||
S9xResetBSX();
|
S9xResetBSX();
|
||||||
|
if(Settings.SPC7110)
|
||||||
|
S9xSpc7110Reset();
|
||||||
|
S9xResetCPU ();
|
||||||
|
S9xResetPPU ();
|
||||||
|
S9xResetSRTC ();
|
||||||
|
if (Settings.SDD1)
|
||||||
|
S9xResetSDD1 ();
|
||||||
|
|
||||||
S9xResetCPU();
|
S9xResetDMA ();
|
||||||
S9xResetPPU();
|
S9xResetAPU ();
|
||||||
S9xResetDMA();
|
S9xResetDSP1 ();
|
||||||
S9xResetAPU();
|
S9xSA1Init ();
|
||||||
|
if (Settings.C4)
|
||||||
|
S9xInitC4 ();
|
||||||
|
|
||||||
|
S9xInitCheatData ();
|
||||||
|
|
||||||
if (Settings.DSP)
|
|
||||||
S9xResetDSP();
|
|
||||||
if (Settings.SuperFX)
|
|
||||||
S9xResetSuperFX();
|
|
||||||
if (Settings.SA1)
|
|
||||||
S9xSA1Init();
|
|
||||||
if (Settings.SDD1)
|
|
||||||
S9xResetSDD1();
|
|
||||||
if (Settings.SPC7110)
|
|
||||||
S9xResetSPC7110();
|
|
||||||
if (Settings.C4)
|
|
||||||
S9xInitC4();
|
|
||||||
if (Settings.OBC1)
|
if (Settings.OBC1)
|
||||||
S9xResetOBC1();
|
ResetOBC1();
|
||||||
if (Settings.SRTC)
|
if (Settings.SuperFX)
|
||||||
S9xResetSRTC();
|
S9xResetSuperFX ();
|
||||||
|
#ifdef ZSNES_FX
|
||||||
S9xInitCheatData();
|
WinterGold = Settings.WinterGold;
|
||||||
|
#endif
|
||||||
|
// Settings.Paused = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xSoftReset (void)
|
void S9xSoftReset (void)
|
||||||
{
|
{
|
||||||
S9xResetSaveTimer(FALSE);
|
#ifndef NGC
|
||||||
|
S9xResetSaveTimer (FALSE);
|
||||||
memset(Memory.VRAM, 0x00, 0x10000);
|
#endif
|
||||||
ZeroMemory(Memory.FillRAM, 0x8000);
|
|
||||||
|
|
||||||
if (Settings.BS)
|
if (Settings.BS)
|
||||||
S9xResetBSX();
|
S9xResetBSX();
|
||||||
|
if (Settings.SuperFX)
|
||||||
|
S9xResetSuperFX ();
|
||||||
|
#ifdef ZSNES_FX
|
||||||
|
WinterGold = Settings.WinterGold;
|
||||||
|
#endif
|
||||||
|
ZeroMemory (Memory.FillRAM, 0x8000);
|
||||||
|
memset (Memory.VRAM, 0x00, 0x10000);
|
||||||
|
// memset (Memory.RAM, 0x55, 0x20000);
|
||||||
|
|
||||||
S9xSoftResetCPU();
|
if(Settings.SPC7110)
|
||||||
S9xSoftResetPPU();
|
S9xSpc7110Reset();
|
||||||
S9xResetDMA();
|
S9xSoftResetCPU ();
|
||||||
S9xSoftResetAPU();
|
S9xSoftResetPPU ();
|
||||||
|
S9xResetSRTC ();
|
||||||
|
if (Settings.SDD1)
|
||||||
|
S9xResetSDD1 ();
|
||||||
|
|
||||||
if (Settings.DSP)
|
S9xResetDMA ();
|
||||||
S9xResetDSP();
|
S9xResetAPU ();
|
||||||
if (Settings.SuperFX)
|
S9xResetDSP1 ();
|
||||||
S9xResetSuperFX();
|
if(Settings.OBC1)
|
||||||
if (Settings.SA1)
|
ResetOBC1();
|
||||||
S9xSA1Init();
|
S9xSA1Init ();
|
||||||
if (Settings.SDD1)
|
if (Settings.C4)
|
||||||
S9xResetSDD1();
|
S9xInitC4 ();
|
||||||
if (Settings.SPC7110)
|
|
||||||
S9xResetSPC7110();
|
|
||||||
if (Settings.C4)
|
|
||||||
S9xInitC4();
|
|
||||||
if (Settings.OBC1)
|
|
||||||
S9xResetOBC1();
|
|
||||||
if (Settings.SRTC)
|
|
||||||
S9xResetSRTC();
|
|
||||||
|
|
||||||
S9xInitCheatData();
|
S9xInitCheatData ();
|
||||||
|
|
||||||
|
// Settings.Paused = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8 S9xOpLengthsM0X0[256] = {
|
||||||
|
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 0
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 1
|
||||||
|
3, 2, 4, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 2
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 3
|
||||||
|
1, 2, 2, 2, 3, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 4
|
||||||
|
2, 2, 2, 2, 3, 2, 2, 2, 1, 3, 1, 1, 4, 3, 3, 4, // 5
|
||||||
|
1, 2, 3, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 6
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 7
|
||||||
|
2, 2, 3, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 8
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 9
|
||||||
|
3, 2, 3, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // A
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // B
|
||||||
|
3, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // C
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // D
|
||||||
|
3, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // E
|
||||||
|
2, 2, 2, 2, 3, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4 // F
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8 S9xOpLengthsM0X1[256] = {
|
||||||
|
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 0
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 1
|
||||||
|
3, 2, 4, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 2
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 3
|
||||||
|
1, 2, 2, 2, 3, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 4
|
||||||
|
2, 2, 2, 2, 3, 2, 2, 2, 1, 3, 1, 1, 4, 3, 3, 4, // 5
|
||||||
|
1, 2, 3, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 6
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 7
|
||||||
|
2, 2, 3, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 8
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 9
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // A
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // B
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // C
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // D
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // E
|
||||||
|
2, 2, 2, 2, 3, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4 // F
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8 S9xOpLengthsM1X0[256] = {
|
||||||
|
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // 0
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 1
|
||||||
|
3, 2, 4, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // 2
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 3
|
||||||
|
1, 2, 2, 2, 3, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // 4
|
||||||
|
2, 2, 2, 2, 3, 2, 2, 2, 1, 3, 1, 1, 4, 3, 3, 4, // 5
|
||||||
|
1, 2, 3, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // 6
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 7
|
||||||
|
2, 2, 3, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // 8
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 9
|
||||||
|
3, 2, 3, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // A
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // B
|
||||||
|
3, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // C
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // D
|
||||||
|
3, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // E
|
||||||
|
2, 2, 2, 2, 3, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4 // F
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8 S9xOpLengthsM1X1[256] = {
|
||||||
|
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // 0
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 1
|
||||||
|
3, 2, 4, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // 2
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 3
|
||||||
|
1, 2, 2, 2, 3, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // 4
|
||||||
|
2, 2, 2, 2, 3, 2, 2, 2, 1, 3, 1, 1, 4, 3, 3, 4, // 5
|
||||||
|
1, 2, 3, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // 6
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 7
|
||||||
|
2, 2, 3, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // 8
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 9
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // A
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // B
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // C
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // D
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // E
|
||||||
|
2, 2, 2, 2, 3, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4 // F
|
||||||
|
};
|
||||||
|
@ -159,516 +159,395 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _CPUADDR_H_
|
#ifndef _CPUADDR_H_
|
||||||
#define _CPUADDR_H_
|
#define _CPUADDR_H_
|
||||||
|
|
||||||
typedef enum
|
typedef enum {
|
||||||
{
|
NONE = 0,
|
||||||
NONE = 0,
|
READ = 1,
|
||||||
READ = 1,
|
WRITE = 2,
|
||||||
WRITE = 2,
|
MODIFY = 3,
|
||||||
MODIFY = 3,
|
JUMP = 5,
|
||||||
JUMP = 5,
|
JSR = 8
|
||||||
JSR = 8
|
} AccessMode;
|
||||||
} AccessMode;
|
|
||||||
|
|
||||||
static inline uint8 Immediate8Slow (AccessMode a)
|
STATIC inline uint8 Immediate8 (AccessMode a) {
|
||||||
{
|
uint8 val = CPU.PCBase[Registers.PCw];
|
||||||
uint8 val = S9xGetByte(Registers.PBPC);
|
if(a&READ) OpenBus = val;
|
||||||
if (a & READ)
|
AddCycles(CPU.MemSpeed);
|
||||||
OpenBus = val;
|
Registers.PCw++;
|
||||||
Registers.PCw++;
|
return val;
|
||||||
|
|
||||||
return (val);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint8 Immediate8 (AccessMode a)
|
STATIC inline uint8 Immediate8Slow (AccessMode a) {
|
||||||
{
|
uint8 val = S9xGetByte(Registers.PBPC);
|
||||||
uint8 val = CPU.PCBase[Registers.PCw];
|
if(a&READ) OpenBus = val;
|
||||||
if (a & READ)
|
Registers.PCw++;
|
||||||
OpenBus = val;
|
return val;
|
||||||
AddCycles(CPU.MemSpeed);
|
|
||||||
Registers.PCw++;
|
|
||||||
|
|
||||||
return (val);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint16 Immediate16Slow (AccessMode a)
|
STATIC inline uint16 Immediate16 (AccessMode a) {
|
||||||
{
|
uint16 val = READ_WORD(CPU.PCBase+Registers.PCw);
|
||||||
uint16 val = S9xGetWord(Registers.PBPC, WRAP_BANK);
|
if(a&READ) OpenBus = (uint8)(val>>8);
|
||||||
if (a & READ)
|
AddCycles(CPU.MemSpeedx2);
|
||||||
OpenBus = (uint8) (val >> 8);
|
Registers.PCw+=2;
|
||||||
Registers.PCw += 2;
|
return val;
|
||||||
|
|
||||||
return (val);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint16 Immediate16 (AccessMode a)
|
STATIC inline uint16 Immediate16Slow (AccessMode a) {
|
||||||
{
|
uint16 val = S9xGetWord(Registers.PBPC, WRAP_BANK);
|
||||||
uint16 val = READ_WORD(CPU.PCBase + Registers.PCw);
|
if(a&READ) OpenBus = (uint8)(val>>8);
|
||||||
if (a & READ)
|
Registers.PCw+=2;
|
||||||
OpenBus = (uint8) (val >> 8);
|
return val;
|
||||||
AddCycles(CPU.MemSpeedx2);
|
|
||||||
Registers.PCw += 2;
|
|
||||||
|
|
||||||
return (val);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 RelativeSlow (AccessMode a) // branch $xx
|
|
||||||
{
|
|
||||||
int8 offset = Immediate8Slow(a);
|
|
||||||
|
|
||||||
return ((int16) Registers.PCw + offset) & 0xffff;
|
STATIC inline uint32 RelativeSlow (AccessMode a) { // branch $xx
|
||||||
|
int8 offset = Immediate8Slow(a);
|
||||||
|
return ((int16)Registers.PCw + offset) & 0xffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 Relative (AccessMode a) // branch $xx
|
STATIC inline uint32 Relative (AccessMode a) { // branch $xx
|
||||||
{
|
int8 offset = Immediate8(a);
|
||||||
int8 offset = Immediate8(a);
|
return ((int16)Registers.PCw + offset) & 0xffff;
|
||||||
|
|
||||||
return ((int16) Registers.PCw + offset) & 0xffff;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 RelativeLongSlow (AccessMode a) // BRL $xxxx
|
STATIC inline uint32 RelativeLongSlow (AccessMode a) { // BRL $xxxx
|
||||||
{
|
int16 offset = Immediate16Slow(a);
|
||||||
int16 offset = Immediate16Slow(a);
|
return ((int32)Registers.PCw + offset) & 0xffff;
|
||||||
|
|
||||||
return ((int32) Registers.PCw + offset) & 0xffff;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 RelativeLong (AccessMode a) // BRL $xxxx
|
STATIC inline uint32 RelativeLong (AccessMode a) { // BRL $xxxx
|
||||||
{
|
int16 offset = Immediate16(a);
|
||||||
int16 offset = Immediate16(a);
|
return ((int32)Registers.PCw + offset) & 0xffff;
|
||||||
|
|
||||||
return ((int32) Registers.PCw + offset) & 0xffff;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 AbsoluteIndexedIndirectSlow (AccessMode a) // (a,X)
|
STATIC inline uint32 AbsoluteIndexedIndirectSlow (AccessMode a) { // (a,X)
|
||||||
{
|
uint16 addr;
|
||||||
uint16 addr;
|
if(a&JSR){
|
||||||
|
// JSR (a,X) pushes the old address in the middle of loading the new.
|
||||||
|
// OpenBus needs to be set to account for this.
|
||||||
|
addr = Immediate8Slow(READ);
|
||||||
|
if(a==JSR) OpenBus = Registers.PCl;
|
||||||
|
addr |= Immediate8Slow(READ)<<8;
|
||||||
|
} else {
|
||||||
|
addr = Immediate16Slow(READ);
|
||||||
|
}
|
||||||
|
AddCycles(ONE_CYCLE);
|
||||||
|
addr+=Registers.X.W;
|
||||||
|
|
||||||
if (a & JSR)
|
// Address load wraps within the bank
|
||||||
{
|
uint16 addr2 = S9xGetWord(ICPU.ShiftedPB | addr, WRAP_BANK);
|
||||||
// JSR (a,X) pushes the old address in the middle of loading the new.
|
OpenBus = addr2>>8;
|
||||||
// OpenBus needs to be set to account for this.
|
return addr2;
|
||||||
addr = Immediate8Slow(READ);
|
|
||||||
if (a == JSR)
|
|
||||||
OpenBus = Registers.PCl;
|
|
||||||
addr |= Immediate8Slow(READ) << 8;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
addr = Immediate16Slow(READ);
|
|
||||||
|
|
||||||
AddCycles(ONE_CYCLE);
|
|
||||||
addr += Registers.X.W;
|
|
||||||
|
|
||||||
// Address load wraps within the bank
|
|
||||||
uint16 addr2 = S9xGetWord(ICPU.ShiftedPB | addr, WRAP_BANK);
|
|
||||||
OpenBus = addr2 >> 8;
|
|
||||||
|
|
||||||
return (addr2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 AbsoluteIndexedIndirect (AccessMode a) // (a,X)
|
STATIC inline uint32 AbsoluteIndexedIndirect (AccessMode a) { // (a,X)
|
||||||
{
|
uint16 addr = Immediate16Slow(READ);
|
||||||
uint16 addr = Immediate16Slow(READ);
|
addr+=Registers.X.W;
|
||||||
addr += Registers.X.W;
|
|
||||||
|
|
||||||
// Address load wraps within the bank
|
// Address load wraps within the bank
|
||||||
uint16 addr2 = S9xGetWord(ICPU.ShiftedPB | addr, WRAP_BANK);
|
uint16 addr2 = S9xGetWord(ICPU.ShiftedPB | addr, WRAP_BANK);
|
||||||
OpenBus = addr2 >> 8;
|
OpenBus = addr2>>8;
|
||||||
|
return addr2;
|
||||||
return (addr2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 AbsoluteIndirectLongSlow (AccessMode a) // [a]
|
STATIC inline uint32 AbsoluteIndirectLongSlow (AccessMode a) { // [a]
|
||||||
{
|
uint16 addr = Immediate16Slow(READ);
|
||||||
uint16 addr = Immediate16Slow(READ);
|
|
||||||
|
|
||||||
// No info on wrapping, but it doesn't matter anyway due to mirroring
|
// No info on wrapping, but it doesn't matter anyway due to mirroring
|
||||||
uint32 addr2 = S9xGetWord(addr);
|
uint32 addr2 = S9xGetWord(addr);
|
||||||
OpenBus = addr2 >> 8;
|
OpenBus=addr2>>8;
|
||||||
addr2 |= (OpenBus = S9xGetByte(addr + 2)) << 16;
|
addr2 |= (OpenBus = S9xGetByte(addr+2))<<16;
|
||||||
|
return addr2;
|
||||||
return (addr2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 AbsoluteIndirectLong (AccessMode a) // [a]
|
STATIC inline uint32 AbsoluteIndirectLong (AccessMode a) { // [a]
|
||||||
{
|
uint16 addr = Immediate16(READ);
|
||||||
uint16 addr = Immediate16(READ);
|
|
||||||
|
|
||||||
// No info on wrapping, but it doesn't matter anyway due to mirroring
|
// No info on wrapping, but it doesn't matter anyway due to mirroring
|
||||||
uint32 addr2 = S9xGetWord(addr);
|
uint32 addr2 = S9xGetWord(addr);
|
||||||
OpenBus = addr2 >> 8;
|
OpenBus=addr2>>8;
|
||||||
addr2 |= (OpenBus = S9xGetByte(addr + 2)) << 16;
|
addr2 |= (OpenBus = S9xGetByte(addr+2))<<16;
|
||||||
|
return addr2;
|
||||||
return (addr2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 AbsoluteIndirectSlow (AccessMode a) // (a)
|
STATIC inline uint32 AbsoluteIndirectSlow (AccessMode a) { // (a)
|
||||||
{
|
// No info on wrapping, but it doesn't matter anyway due to mirroring
|
||||||
// No info on wrapping, but it doesn't matter anyway due to mirroring
|
uint16 addr2 = S9xGetWord(Immediate16Slow(READ));
|
||||||
uint16 addr2 = S9xGetWord(Immediate16Slow(READ));
|
OpenBus=addr2>>8;
|
||||||
OpenBus = addr2 >> 8;
|
return addr2;
|
||||||
|
|
||||||
return (addr2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 AbsoluteIndirect (AccessMode a) // (a)
|
STATIC inline uint32 AbsoluteIndirect (AccessMode a) { // (a)
|
||||||
{
|
// No info on wrapping, but it doesn't matter anyway due to mirroring
|
||||||
// No info on wrapping, but it doesn't matter anyway due to mirroring
|
uint16 addr2 = S9xGetWord(Immediate16(READ));
|
||||||
uint16 addr2 = S9xGetWord(Immediate16(READ));
|
OpenBus=addr2>>8;
|
||||||
OpenBus = addr2 >> 8;
|
return addr2;
|
||||||
|
|
||||||
return (addr2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 AbsoluteSlow (AccessMode a) // a
|
STATIC inline uint32 AbsoluteSlow (AccessMode a) { // a
|
||||||
{
|
return ICPU.ShiftedDB|Immediate16Slow(a);
|
||||||
return (ICPU.ShiftedDB | Immediate16Slow(a));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 Absolute (AccessMode a) // a
|
STATIC inline uint32 Absolute (AccessMode a) { // a
|
||||||
{
|
return ICPU.ShiftedDB|Immediate16(a);
|
||||||
return (ICPU.ShiftedDB | Immediate16(a));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 AbsoluteLongSlow (AccessMode a) // l
|
STATIC inline uint32 AbsoluteLongSlow (AccessMode a) { // l
|
||||||
{
|
uint32 addr = Immediate16Slow(READ);
|
||||||
uint32 addr = Immediate16Slow(READ);
|
|
||||||
|
|
||||||
// JSR l pushes the old bank in the middle of loading the new.
|
// JSR l pushes the old bank in the middle of loading the new.
|
||||||
// OpenBus needs to be set to account for this.
|
// OpenBus needs to be set to account for this.
|
||||||
if (a == JSR)
|
if(a==JSR) OpenBus = Registers.PB;
|
||||||
OpenBus = Registers.PB;
|
|
||||||
|
|
||||||
addr |= Immediate8Slow(a) << 16;
|
addr |= Immediate8Slow(a)<<16;
|
||||||
|
return addr;
|
||||||
return (addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 AbsoluteLong (AccessMode a) // l
|
STATIC inline uint32 AbsoluteLong (AccessMode a) { // l
|
||||||
{
|
uint32 addr = READ_3WORD(CPU.PCBase+Registers.PCw);
|
||||||
uint32 addr = READ_3WORD(CPU.PCBase + Registers.PCw);
|
AddCycles(CPU.MemSpeedx2+CPU.MemSpeed);
|
||||||
AddCycles(CPU.MemSpeedx2 + CPU.MemSpeed);
|
if(a&READ) OpenBus = addr>>16;
|
||||||
if (a & READ)
|
Registers.PCw+=3;
|
||||||
OpenBus = addr >> 16;
|
return addr;
|
||||||
Registers.PCw += 3;
|
|
||||||
|
|
||||||
return (addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 DirectSlow (AccessMode a) // d
|
STATIC inline uint32 DirectSlow (AccessMode a) { // d
|
||||||
{
|
uint16 addr = Immediate8Slow(a) + Registers.D.W;
|
||||||
uint16 addr = Immediate8Slow(a) + Registers.D.W;
|
if(Registers.DL!=0) AddCycles(ONE_CYCLE);
|
||||||
if (Registers.DL != 0)
|
return addr;
|
||||||
AddCycles(ONE_CYCLE);
|
|
||||||
|
|
||||||
return (addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 Direct (AccessMode a) // d
|
STATIC inline uint32 Direct (AccessMode a) { // d
|
||||||
{
|
uint16 addr = Immediate8(a) + Registers.D.W;
|
||||||
uint16 addr = Immediate8(a) + Registers.D.W;
|
if(Registers.DL!=0) AddCycles(ONE_CYCLE);
|
||||||
if (Registers.DL != 0)
|
return addr;
|
||||||
AddCycles(ONE_CYCLE);
|
|
||||||
|
|
||||||
return (addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 DirectIndirectSlow (AccessMode a) // (d)
|
STATIC inline uint32 DirectIndirectSlow (AccessMode a) { // (d)
|
||||||
{
|
uint32 addr = S9xGetWord(DirectSlow(READ),
|
||||||
uint32 addr = S9xGetWord(DirectSlow(READ), (!CheckEmulation() || Registers.DL) ? WRAP_BANK : WRAP_PAGE);
|
(!CheckEmulation() || Registers.DL)?WRAP_BANK:WRAP_PAGE);
|
||||||
if (a & READ)
|
if(a&READ) OpenBus=(uint8)(addr>>8);
|
||||||
OpenBus = (uint8) (addr >> 8);
|
addr |= ICPU.ShiftedDB;
|
||||||
addr |= ICPU.ShiftedDB;
|
return addr;
|
||||||
|
|
||||||
return (addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 DirectIndirectE0 (AccessMode a) // (d)
|
STATIC inline uint32 DirectIndirectE0 (AccessMode a) { // (d)
|
||||||
{
|
uint32 addr = S9xGetWord(Direct(READ));
|
||||||
uint32 addr = S9xGetWord(Direct(READ));
|
if(a&READ) OpenBus = (uint8)(addr>>8);
|
||||||
if (a & READ)
|
addr |= ICPU.ShiftedDB;
|
||||||
OpenBus = (uint8) (addr >> 8);
|
return addr;
|
||||||
addr |= ICPU.ShiftedDB;
|
|
||||||
|
|
||||||
return (addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 DirectIndirectE1 (AccessMode a) // (d)
|
STATIC inline uint32 DirectIndirectE1 (AccessMode a) { // (d)
|
||||||
{
|
uint32 addr = S9xGetWord(DirectSlow(READ),
|
||||||
uint32 addr = S9xGetWord(DirectSlow(READ), Registers.DL ? WRAP_BANK : WRAP_PAGE);
|
Registers.DL?WRAP_BANK:WRAP_PAGE);
|
||||||
if (a & READ)
|
if(a&READ) OpenBus=(uint8)(addr>>8);
|
||||||
OpenBus = (uint8) (addr >> 8);
|
addr |= ICPU.ShiftedDB;
|
||||||
addr |= ICPU.ShiftedDB;
|
return addr;
|
||||||
|
|
||||||
return (addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 DirectIndirectIndexedSlow (AccessMode a) // (d),Y
|
STATIC inline uint32 DirectIndirectIndexedSlow (AccessMode a) { // (d),Y
|
||||||
{
|
uint32 addr = DirectIndirectSlow(a);
|
||||||
uint32 addr = DirectIndirectSlow(a);
|
if(a&WRITE || !CheckIndex() || (addr&0xff)+Registers.YL>=0x100) AddCycles(ONE_CYCLE);
|
||||||
if (a & WRITE || !CheckIndex() || (addr & 0xff) + Registers.YL >= 0x100)
|
return (addr + Registers.Y.W);
|
||||||
AddCycles(ONE_CYCLE);
|
|
||||||
|
|
||||||
return (addr + Registers.Y.W);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 DirectIndirectIndexedE0X0 (AccessMode a) // (d),Y
|
STATIC inline uint32 DirectIndirectIndexedE0X0 (AccessMode a) { // (d),Y
|
||||||
{
|
uint32 addr = DirectIndirectE0(a);
|
||||||
uint32 addr = DirectIndirectE0(a);
|
AddCycles(ONE_CYCLE);
|
||||||
AddCycles(ONE_CYCLE);
|
return (addr + Registers.Y.W);
|
||||||
|
|
||||||
return (addr + Registers.Y.W);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 DirectIndirectIndexedE0X1 (AccessMode a) // (d),Y
|
STATIC inline uint32 DirectIndirectIndexedE0X1 (AccessMode a) { // (d),Y
|
||||||
{
|
uint32 addr = DirectIndirectE0(a);
|
||||||
uint32 addr = DirectIndirectE0(a);
|
if(a&WRITE || (addr&0xff)+Registers.YL>=0x100) AddCycles(ONE_CYCLE);
|
||||||
if (a & WRITE || (addr & 0xff) + Registers.YL >= 0x100)
|
return (addr + Registers.Y.W);
|
||||||
AddCycles(ONE_CYCLE);
|
|
||||||
|
|
||||||
return (addr + Registers.Y.W);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 DirectIndirectIndexedE1 (AccessMode a) // (d),Y
|
STATIC inline uint32 DirectIndirectIndexedE1 (AccessMode a) { // (d),Y
|
||||||
{
|
uint32 addr = DirectIndirectE1(a);
|
||||||
uint32 addr = DirectIndirectE1(a);
|
if(a&WRITE || (addr&0xff)+Registers.YL>=0x100) AddCycles(ONE_CYCLE);
|
||||||
if (a & WRITE || (addr & 0xff) + Registers.YL >= 0x100)
|
return (addr + Registers.Y.W);
|
||||||
AddCycles(ONE_CYCLE);
|
|
||||||
|
|
||||||
return (addr + Registers.Y.W);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 DirectIndirectLongSlow (AccessMode a) // [d]
|
STATIC inline uint32 DirectIndirectLongSlow (AccessMode a) { // [d]
|
||||||
{
|
uint16 addr = DirectSlow(READ);
|
||||||
uint16 addr = DirectSlow(READ);
|
uint32 addr2 = S9xGetWord(addr);
|
||||||
uint32 addr2 = S9xGetWord(addr);
|
OpenBus=addr2>>8;
|
||||||
OpenBus = addr2 >> 8;
|
addr2 |= (OpenBus = S9xGetByte(addr+2))<<16;
|
||||||
addr2 |= (OpenBus = S9xGetByte(addr + 2)) << 16;
|
return addr2;
|
||||||
|
|
||||||
return (addr2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 DirectIndirectLong (AccessMode a) // [d]
|
STATIC inline uint32 DirectIndirectLong (AccessMode a) { // [d]
|
||||||
{
|
uint16 addr = Direct(READ);
|
||||||
uint16 addr = Direct(READ);
|
uint32 addr2 = S9xGetWord(addr);
|
||||||
uint32 addr2 = S9xGetWord(addr);
|
OpenBus=addr2>>8;
|
||||||
OpenBus = addr2 >> 8;
|
addr2 |= (OpenBus = S9xGetByte(addr+2))<<16;
|
||||||
addr2 |= (OpenBus = S9xGetByte(addr + 2)) << 16;
|
return addr2;
|
||||||
|
|
||||||
return (addr2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 DirectIndirectIndexedLongSlow (AccessMode a) // [d],Y
|
STATIC inline uint32 DirectIndirectIndexedLongSlow (AccessMode a) { // [d],Y
|
||||||
{
|
return DirectIndirectLongSlow(a) + Registers.Y.W;
|
||||||
return (DirectIndirectLongSlow(a) + Registers.Y.W);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 DirectIndirectIndexedLong (AccessMode a) // [d],Y
|
STATIC inline uint32 DirectIndirectIndexedLong (AccessMode a) { // [d],Y
|
||||||
{
|
return DirectIndirectLong(a) + Registers.Y.W;
|
||||||
return (DirectIndirectLong(a) + Registers.Y.W);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 DirectIndexedXSlow (AccessMode a) // d,X
|
STATIC inline uint32 DirectIndexedXSlow (AccessMode a) { // d,X
|
||||||
{
|
pair addr;
|
||||||
pair addr;
|
addr.W = DirectSlow(a);
|
||||||
addr.W = DirectSlow(a);
|
if(!CheckEmulation() || Registers.DL){
|
||||||
if (!CheckEmulation() || Registers.DL)
|
addr.W+=Registers.X.W;
|
||||||
addr.W += Registers.X.W;
|
} else {
|
||||||
else
|
addr.B.l+=Registers.XL;
|
||||||
addr.B.l += Registers.XL;
|
}
|
||||||
|
AddCycles(ONE_CYCLE);
|
||||||
AddCycles(ONE_CYCLE);
|
return addr.W;
|
||||||
|
|
||||||
return (addr.W);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 DirectIndexedXE0 (AccessMode a) // d,X
|
STATIC inline uint32 DirectIndexedXE0 (AccessMode a) { // d,X
|
||||||
{
|
uint16 addr = Direct(a) + Registers.X.W;
|
||||||
uint16 addr = Direct(a) + Registers.X.W;
|
AddCycles(ONE_CYCLE);
|
||||||
AddCycles(ONE_CYCLE);
|
return addr;
|
||||||
|
|
||||||
return (addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 DirectIndexedXE1 (AccessMode a) // d,X
|
STATIC inline uint32 DirectIndexedXE1 (AccessMode a) { // d,X
|
||||||
{
|
if(Registers.DL){
|
||||||
if (Registers.DL)
|
return DirectIndexedXE0(a);
|
||||||
return (DirectIndexedXE0(a));
|
} else {
|
||||||
else
|
pair addr;
|
||||||
{
|
addr.W = Direct(a);
|
||||||
pair addr;
|
addr.B.l+=Registers.XL;
|
||||||
addr.W = Direct(a);
|
AddCycles(ONE_CYCLE);
|
||||||
addr.B.l += Registers.XL;
|
return addr.W;
|
||||||
AddCycles(ONE_CYCLE);
|
}
|
||||||
|
|
||||||
return (addr.W);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 DirectIndexedYSlow (AccessMode a) // d,Y
|
STATIC inline uint32 DirectIndexedYSlow (AccessMode a) { // d,Y
|
||||||
{
|
pair addr;
|
||||||
pair addr;
|
addr.W = DirectSlow(a);
|
||||||
addr.W = DirectSlow(a);
|
if(!CheckEmulation() || Registers.DL){
|
||||||
if (!CheckEmulation() || Registers.DL)
|
addr.W+=Registers.Y.W;
|
||||||
addr.W += Registers.Y.W;
|
} else {
|
||||||
else
|
addr.B.l+=Registers.YL;
|
||||||
addr.B.l += Registers.YL;
|
}
|
||||||
|
AddCycles(ONE_CYCLE);
|
||||||
AddCycles(ONE_CYCLE);
|
return addr.W;
|
||||||
|
|
||||||
return (addr.W);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 DirectIndexedYE0 (AccessMode a) // d,Y
|
STATIC inline uint32 DirectIndexedYE0 (AccessMode a) { // d,Y
|
||||||
{
|
uint16 addr = Direct(a) + Registers.Y.W;
|
||||||
uint16 addr = Direct(a) + Registers.Y.W;
|
AddCycles(ONE_CYCLE);
|
||||||
AddCycles(ONE_CYCLE);
|
return addr;
|
||||||
|
|
||||||
return (addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 DirectIndexedYE1 (AccessMode a) // d,Y
|
STATIC inline uint32 DirectIndexedYE1 (AccessMode a) { // d,Y
|
||||||
{
|
if(Registers.DL){
|
||||||
if (Registers.DL)
|
return DirectIndexedYE0(a);
|
||||||
return (DirectIndexedYE0(a));
|
} else {
|
||||||
else
|
pair addr;
|
||||||
{
|
addr.W = Direct(a);
|
||||||
pair addr;
|
addr.B.l+=Registers.YL;
|
||||||
addr.W = Direct(a);
|
AddCycles(ONE_CYCLE);
|
||||||
addr.B.l += Registers.YL;
|
return addr.W;
|
||||||
AddCycles(ONE_CYCLE);
|
}
|
||||||
|
|
||||||
return (addr.W);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 DirectIndexedIndirectSlow (AccessMode a) // (d,X)
|
STATIC inline uint32 DirectIndexedIndirectSlow (AccessMode a) { // (d,X)
|
||||||
{
|
uint32 addr = S9xGetWord(DirectIndexedXSlow(READ),
|
||||||
uint32 addr = S9xGetWord(DirectIndexedXSlow(READ), (!CheckEmulation() || Registers.DL) ? WRAP_BANK : WRAP_PAGE);
|
(!CheckEmulation() || Registers.DL)?WRAP_BANK:WRAP_PAGE);
|
||||||
if (a & READ)
|
if(a&READ) OpenBus=(uint8)(addr>>8);
|
||||||
OpenBus = (uint8) (addr >> 8);
|
return ICPU.ShiftedDB|addr;
|
||||||
|
|
||||||
return (ICPU.ShiftedDB | addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 DirectIndexedIndirectE0 (AccessMode a) // (d,X)
|
STATIC inline uint32 DirectIndexedIndirectE0 (AccessMode a) { // (d,X)
|
||||||
{
|
uint32 addr = S9xGetWord(DirectIndexedXE0(READ));
|
||||||
uint32 addr = S9xGetWord(DirectIndexedXE0(READ));
|
if(a&READ) OpenBus = (uint8)(addr>>8);
|
||||||
if (a & READ)
|
return ICPU.ShiftedDB|addr;
|
||||||
OpenBus = (uint8) (addr >> 8);
|
|
||||||
|
|
||||||
return (ICPU.ShiftedDB | addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 DirectIndexedIndirectE1 (AccessMode a) // (d,X)
|
STATIC inline uint32 DirectIndexedIndirectE1 (AccessMode a) { // (d,X)
|
||||||
{
|
uint32 addr = S9xGetWord(DirectIndexedXE1(READ),
|
||||||
uint32 addr = S9xGetWord(DirectIndexedXE1(READ), Registers.DL ? WRAP_BANK : WRAP_PAGE);
|
Registers.DL?WRAP_BANK:WRAP_PAGE);
|
||||||
if (a & READ)
|
if(a&READ) OpenBus=(uint8)(addr>>8);
|
||||||
OpenBus = (uint8) (addr >> 8);
|
return ICPU.ShiftedDB|addr;
|
||||||
|
|
||||||
return (ICPU.ShiftedDB | addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 AbsoluteIndexedXSlow (AccessMode a) // a,X
|
STATIC inline uint32 AbsoluteIndexedXSlow (AccessMode a) { // a,X
|
||||||
{
|
uint32 addr = AbsoluteSlow(a);
|
||||||
uint32 addr = AbsoluteSlow(a);
|
if(a&WRITE || !CheckIndex() || (addr&0xff)+Registers.XL>=0x100) AddCycles(ONE_CYCLE);
|
||||||
if (a & WRITE || !CheckIndex() || (addr & 0xff) + Registers.XL >= 0x100)
|
return (addr + Registers.X.W);
|
||||||
AddCycles(ONE_CYCLE);
|
|
||||||
|
|
||||||
return (addr + Registers.X.W);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 AbsoluteIndexedXX0 (AccessMode a) // a,X
|
STATIC inline uint32 AbsoluteIndexedXX0 (AccessMode a) { // a,X
|
||||||
{
|
uint32 addr = Absolute(a);
|
||||||
uint32 addr = Absolute(a);
|
AddCycles(ONE_CYCLE);
|
||||||
AddCycles(ONE_CYCLE);
|
return (addr + Registers.X.W);
|
||||||
|
|
||||||
return (addr + Registers.X.W);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 AbsoluteIndexedXX1 (AccessMode a) // a,X
|
STATIC inline uint32 AbsoluteIndexedXX1 (AccessMode a) { // a,X
|
||||||
{
|
uint32 addr = Absolute(a);
|
||||||
uint32 addr = Absolute(a);
|
if(a&WRITE || (addr&0xff)+Registers.XL>=0x100) AddCycles(ONE_CYCLE);
|
||||||
if (a & WRITE || (addr & 0xff) + Registers.XL >= 0x100)
|
return (addr + Registers.X.W);
|
||||||
AddCycles(ONE_CYCLE);
|
|
||||||
|
|
||||||
return (addr + Registers.X.W);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 AbsoluteIndexedYSlow (AccessMode a) // a,Y
|
STATIC inline uint32 AbsoluteIndexedYSlow (AccessMode a) { // a,Y
|
||||||
{
|
uint32 addr = AbsoluteSlow(a);
|
||||||
uint32 addr = AbsoluteSlow(a);
|
if(a&WRITE || !CheckIndex() || (addr&0xff)+Registers.YL>=0x100) AddCycles(ONE_CYCLE);
|
||||||
if (a & WRITE || !CheckIndex() || (addr & 0xff) + Registers.YL >= 0x100)
|
return (addr + Registers.Y.W);
|
||||||
AddCycles(ONE_CYCLE);
|
|
||||||
|
|
||||||
return (addr + Registers.Y.W);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 AbsoluteIndexedYX0 (AccessMode a) // a,Y
|
STATIC inline uint32 AbsoluteIndexedYX0 (AccessMode a) { // a,Y
|
||||||
{
|
uint32 addr = Absolute(a);
|
||||||
uint32 addr = Absolute(a);
|
AddCycles(ONE_CYCLE);
|
||||||
AddCycles(ONE_CYCLE);
|
return (addr + Registers.Y.W);
|
||||||
|
|
||||||
return (addr + Registers.Y.W);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 AbsoluteIndexedYX1 (AccessMode a) // a,Y
|
STATIC inline uint32 AbsoluteIndexedYX1 (AccessMode a) { // a,Y
|
||||||
{
|
uint32 addr = Absolute(a);
|
||||||
uint32 addr = Absolute(a);
|
if(a&WRITE || (addr&0xff)+Registers.YL>=0x100) AddCycles(ONE_CYCLE);
|
||||||
if (a & WRITE || (addr & 0xff) + Registers.YL >= 0x100)
|
return (addr + Registers.Y.W);
|
||||||
AddCycles(ONE_CYCLE);
|
|
||||||
|
|
||||||
return (addr + Registers.Y.W);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 AbsoluteLongIndexedXSlow (AccessMode a) // l,X
|
STATIC inline uint32 AbsoluteLongIndexedXSlow (AccessMode a) { // l,X
|
||||||
{
|
return (AbsoluteLongSlow(a) + Registers.X.W);
|
||||||
return (AbsoluteLongSlow(a) + Registers.X.W);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 AbsoluteLongIndexedX (AccessMode a) // l,X
|
STATIC inline uint32 AbsoluteLongIndexedX (AccessMode a) { // l,X
|
||||||
{
|
return (AbsoluteLong(a) + Registers.X.W);
|
||||||
return (AbsoluteLong(a) + Registers.X.W);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 StackRelativeSlow (AccessMode a) // d,S
|
STATIC inline uint32 StackRelativeSlow (AccessMode a) { // d,S
|
||||||
{
|
uint16 addr = Immediate8Slow(a) + Registers.S.W;
|
||||||
uint16 addr = Immediate8Slow(a) + Registers.S.W;
|
AddCycles(ONE_CYCLE);
|
||||||
AddCycles(ONE_CYCLE);
|
return addr;
|
||||||
|
|
||||||
return (addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 StackRelative (AccessMode a) // d,S
|
STATIC inline uint32 StackRelative (AccessMode a) { // d,S
|
||||||
{
|
uint16 addr = Immediate8(a) + Registers.S.W;
|
||||||
uint16 addr = Immediate8(a) + Registers.S.W;
|
AddCycles(ONE_CYCLE);
|
||||||
AddCycles(ONE_CYCLE);
|
return addr;
|
||||||
|
|
||||||
return (addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 StackRelativeIndirectIndexedSlow (AccessMode a) // (d,S),Y
|
STATIC inline uint32 StackRelativeIndirectIndexedSlow (AccessMode a) { // (d,S),Y
|
||||||
{
|
uint32 addr=S9xGetWord(StackRelativeSlow(READ));
|
||||||
uint32 addr = S9xGetWord(StackRelativeSlow(READ));
|
if(a&READ) OpenBus = (uint8)(addr>>8);
|
||||||
if (a & READ)
|
addr = (addr+Registers.Y.W+ICPU.ShiftedDB)&0xffffff;
|
||||||
OpenBus = (uint8) (addr >> 8);
|
AddCycles(ONE_CYCLE);
|
||||||
addr = (addr + Registers.Y.W + ICPU.ShiftedDB) & 0xffffff;
|
return addr;
|
||||||
AddCycles(ONE_CYCLE);
|
|
||||||
|
|
||||||
return (addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 StackRelativeIndirectIndexed (AccessMode a) // (d,S),Y
|
STATIC inline uint32 StackRelativeIndirectIndexed (AccessMode a) { // (d,S),Y
|
||||||
{
|
uint32 addr=S9xGetWord(StackRelative(READ));
|
||||||
uint32 addr = S9xGetWord(StackRelative(READ));
|
if(a&READ) OpenBus = (uint8)(addr>>8);
|
||||||
if (a & READ)
|
addr = (addr+Registers.Y.W+ICPU.ShiftedDB)&0xffffff;
|
||||||
OpenBus = (uint8) (addr >> 8);
|
AddCycles(ONE_CYCLE);
|
||||||
addr = (addr + Registers.Y.W + ICPU.ShiftedDB) & 0xffffff;
|
return addr;
|
||||||
AddCycles(ONE_CYCLE);
|
|
||||||
|
|
||||||
return (addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -159,21 +159,38 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "snes9x.h"
|
#include "snes9x.h"
|
||||||
#include "memmap.h"
|
#include "memmap.h"
|
||||||
#include "cpuops.h"
|
#include "cpuops.h"
|
||||||
#include "dma.h"
|
#include "ppu.h"
|
||||||
#include "apu/apu.h"
|
#include "cpuexec.h"
|
||||||
#include "fxemu.h"
|
#include "s9xdebug.h"
|
||||||
#include "snapshot.h"
|
#include "snapshot.h"
|
||||||
#ifdef DEBUGGER
|
#include "gfx.h"
|
||||||
#include "debug.h"
|
|
||||||
#include "missing.h"
|
#include "missing.h"
|
||||||
#endif
|
#include "apu.h"
|
||||||
|
#include "dma.h"
|
||||||
|
#include "sa1.h"
|
||||||
|
#include "spc7110.h"
|
||||||
|
|
||||||
|
#ifndef ZSNES_FX
|
||||||
|
#include "fxemu.h"
|
||||||
|
extern struct FxInit_s SuperFX;
|
||||||
|
#endif
|
||||||
|
|
||||||
void S9xMainLoop (void)
|
void S9xMainLoop (void)
|
||||||
{
|
{
|
||||||
|
if(ICPU.SavedAtOp)
|
||||||
|
{
|
||||||
|
ICPU.SavedAtOp = FALSE;
|
||||||
|
Registers.PCw = CPU.PBPCAtOpcodeStart;
|
||||||
|
if(CPU.PCBase)
|
||||||
|
CPU.Cycles -= CPU.MemSpeed;
|
||||||
|
goto doOp;
|
||||||
|
}
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if (CPU.Flags)
|
if (CPU.Flags)
|
||||||
@ -194,7 +211,7 @@ void S9xMainLoop (void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUGGER
|
#ifdef DEBUGGER
|
||||||
if ((CPU.Flags & BREAK_FLAG) && !(CPU.Flags & SINGLE_STEP_FLAG))
|
if ((CPU.Flags & BREAK_FLAG) && !(CPU.Flags & SINGLE_STEP_FLAG))
|
||||||
{
|
{
|
||||||
for (int Break = 0; Break != 6; Break++)
|
for (int Break = 0; Break != 6; Break++)
|
||||||
@ -210,7 +227,7 @@ void S9xMainLoop (void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CHECK_SOUND();
|
CHECK_SOUND();
|
||||||
|
|
||||||
@ -218,7 +235,7 @@ void S9xMainLoop (void)
|
|||||||
{
|
{
|
||||||
if (CPU.IRQPending)
|
if (CPU.IRQPending)
|
||||||
// FIXME: In case of IRQ during WRAM refresh
|
// FIXME: In case of IRQ during WRAM refresh
|
||||||
CPU.IRQPending--;
|
CPU.IRQPending = 0;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (CPU.WaitingForInterrupt)
|
if (CPU.WaitingForInterrupt)
|
||||||
@ -241,7 +258,7 @@ void S9xMainLoop (void)
|
|||||||
if (CPU.Flags & SCAN_KEYS_FLAG)
|
if (CPU.Flags & SCAN_KEYS_FLAG)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef DEBUGGER
|
#ifdef DEBUGGER
|
||||||
if (CPU.Flags & DEBUG_MODE_FLAG)
|
if (CPU.Flags & DEBUG_MODE_FLAG)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -253,13 +270,13 @@ void S9xMainLoop (void)
|
|||||||
CPU.Flags &= ~SINGLE_STEP_FLAG;
|
CPU.Flags &= ~SINGLE_STEP_FLAG;
|
||||||
CPU.Flags |= DEBUG_MODE_FLAG;
|
CPU.Flags |= DEBUG_MODE_FLAG;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CPU_SHUTDOWN
|
#ifdef CPU_SHUTDOWN
|
||||||
CPU.PBPCAtOpcodeStart = Registers.PBPC;
|
CPU.PBPCAtOpcodeStart = Registers.PBPC;
|
||||||
#endif
|
#endif
|
||||||
|
doOp:
|
||||||
register uint8 Op;
|
register uint8 Op;
|
||||||
register struct SOpcodes *Opcodes;
|
register struct SOpcodes *Opcodes;
|
||||||
|
|
||||||
@ -278,41 +295,50 @@ void S9xMainLoop (void)
|
|||||||
Opcodes = S9xOpcodesSlow;
|
Opcodes = S9xOpcodesSlow;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((Registers.PCw & MEMMAP_MASK) + ICPU.S9xOpLengths[Op] >= MEMMAP_BLOCK_SIZE)
|
if ((Registers.PCw&MEMMAP_MASK) + ICPU.S9xOpLengths[Op] >= MEMMAP_BLOCK_SIZE)
|
||||||
{
|
{
|
||||||
uint8 *oldPCBase = CPU.PCBase;
|
uint8 *oldPCBase = CPU.PCBase;
|
||||||
|
|
||||||
CPU.PCBase = S9xGetBasePointer(ICPU.ShiftedPB + ((uint16) (Registers.PCw + 4)));
|
CPU.PCBase = GetBasePointer(ICPU.ShiftedPB + ((uint16) (Registers.PCw + 4)));
|
||||||
if (oldPCBase != CPU.PCBase || (Registers.PCw & ~MEMMAP_MASK) == (0xffff & ~MEMMAP_MASK))
|
if (oldPCBase!=CPU.PCBase || (Registers.PCw&~MEMMAP_MASK) == (0xffff & ~MEMMAP_MASK))
|
||||||
Opcodes = S9xOpcodesSlow;
|
Opcodes = S9xOpcodesSlow;
|
||||||
}
|
}
|
||||||
|
|
||||||
Registers.PCw++;
|
Registers.PCw++;
|
||||||
(*Opcodes[Op].S9xOpcode)();
|
(*Opcodes[Op].S9xOpcode)();
|
||||||
|
|
||||||
|
if(ICPU.SavedAtOp)
|
||||||
|
{
|
||||||
|
ICPU.SavedAtOp = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
S9xAPUExecute();
|
||||||
|
|
||||||
if (SA1.Executing)
|
if (SA1.Executing)
|
||||||
S9xSA1MainLoop();
|
S9xSA1MainLoop();
|
||||||
|
|
||||||
while (CPU.Cycles >= CPU.NextEvent)
|
while (CPU.Cycles >= CPU.NextEvent)
|
||||||
S9xDoHEventProcessing();
|
S9xDoHEventProcessing();
|
||||||
}
|
}
|
||||||
|
|
||||||
S9xPackStatus();
|
S9xPackStatus();
|
||||||
|
APURegisters.PC = IAPU.PC - IAPU.RAM;
|
||||||
|
S9xAPUPackStatus();
|
||||||
|
|
||||||
if (CPU.Flags & SCAN_KEYS_FLAG)
|
if (CPU.Flags & SCAN_KEYS_FLAG)
|
||||||
{
|
{
|
||||||
#ifdef DEBUGGER
|
#ifdef DEBUGGER
|
||||||
if (!(CPU.Flags & FRAME_ADVANCE_FLAG))
|
if (!(CPU.Flags & FRAME_ADVANCE_FLAG))
|
||||||
#endif
|
#endif
|
||||||
S9xSyncSpeed();
|
S9xSyncSpeed();
|
||||||
CPU.Flags &= ~SCAN_KEYS_FLAG;
|
CPU.Flags &= ~SCAN_KEYS_FLAG;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xSetIRQ (uint32 source)
|
void S9xSetIRQ (uint32 source)
|
||||||
{
|
{
|
||||||
CPU.IRQActive |= source;
|
CPU.IRQActive |= source;
|
||||||
CPU.IRQPending = Timings.IRQPendCount;
|
|
||||||
CPU.Flags |= IRQ_FLAG;
|
CPU.Flags |= IRQ_FLAG;
|
||||||
|
|
||||||
if (CPU.WaitingForInterrupt)
|
if (CPU.WaitingForInterrupt)
|
||||||
@ -322,35 +348,22 @@ void S9xSetIRQ (uint32 source)
|
|||||||
CPU.WaitingForInterrupt = FALSE;
|
CPU.WaitingForInterrupt = FALSE;
|
||||||
Registers.PCw++;
|
Registers.PCw++;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUGGER
|
|
||||||
S9xTraceMessage("--- /IRQ low");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xClearIRQ (uint32 source)
|
void S9xClearIRQ (uint32 source)
|
||||||
{
|
{
|
||||||
CPU.IRQActive &= ~source;
|
CLEAR_IRQ_SOURCE(source);
|
||||||
if (!CPU.IRQActive)
|
|
||||||
CPU.Flags &= ~IRQ_FLAG;
|
|
||||||
|
|
||||||
#ifdef DEBUGGER
|
|
||||||
S9xTraceMessage("--- /IRQ high");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xDoHEventProcessing (void)
|
void S9xDoHEventProcessing (void)
|
||||||
{
|
{
|
||||||
#ifdef DEBUGGER
|
#ifdef DEBUGGER
|
||||||
if (Settings.TraceHCEvent)
|
char mes[256];
|
||||||
S9xTraceFormattedMessage("--- HC event processing (%02d) expected HC:%04d executed HC:%04d",
|
|
||||||
CPU.WhichEvent, CPU.NextEvent, CPU.Cycles);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CPU_SHUTDOWN
|
#ifdef CPU_SHUTDOWN
|
||||||
CPU.WaitCounter++;
|
CPU.WaitCounter++;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch (CPU.WhichEvent)
|
switch (CPU.WhichEvent)
|
||||||
{
|
{
|
||||||
case HC_HBLANK_START_EVENT:
|
case HC_HBLANK_START_EVENT:
|
||||||
@ -362,7 +375,8 @@ void S9xDoHEventProcessing (void)
|
|||||||
if (PPU.HDMA && CPU.V_Counter <= PPU.ScreenHeight)
|
if (PPU.HDMA && CPU.V_Counter <= PPU.ScreenHeight)
|
||||||
{
|
{
|
||||||
#ifdef DEBUGGER
|
#ifdef DEBUGGER
|
||||||
S9xTraceFormattedMessage("*** HDMA HC:%04d, Channel:%02x", CPU.Cycles, PPU.HDMA);
|
sprintf(mes, "*** HDMA HC:%04d, Channel:%02x", CPU.Cycles, PPU.HDMA);
|
||||||
|
S9xTraceMessage(mes);
|
||||||
#endif
|
#endif
|
||||||
PPU.HDMA = S9xDoHDMA(PPU.HDMA);
|
PPU.HDMA = S9xDoHDMA(PPU.HDMA);
|
||||||
}
|
}
|
||||||
@ -383,13 +397,20 @@ void S9xDoHEventProcessing (void)
|
|||||||
S9xSuperFXExec();
|
S9xSuperFXExec();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
S9xAPUEndScanline();
|
#ifndef STORM
|
||||||
|
if (Settings.SoundSync)
|
||||||
|
S9xGenerateSound();
|
||||||
|
#endif
|
||||||
|
|
||||||
CPU.Cycles -= Timings.H_Max;
|
CPU.Cycles -= Timings.H_Max;
|
||||||
S9xAPUSetReferenceTime(CPU.Cycles);
|
APU.NextAPUTimerPos -= (Timings.H_Max << SNES_APU_ACCURACY);
|
||||||
|
APU.Cycles -= (Timings.H_Max << SNES_APU_ACCURACY);
|
||||||
|
|
||||||
if ((Timings.NMITriggerPos != 0xffff) && (Timings.NMITriggerPos >= Timings.H_Max))
|
if ((Timings.NMITriggerPos != 0xffff) && (Timings.NMITriggerPos >= Timings.H_Max))
|
||||||
Timings.NMITriggerPos -= Timings.H_Max;
|
Timings.NMITriggerPos -= Timings.H_Max;
|
||||||
|
|
||||||
|
ICPU.Scanline++;
|
||||||
|
|
||||||
CPU.V_Counter++;
|
CPU.V_Counter++;
|
||||||
if (CPU.V_Counter >= Timings.V_Max) // V ranges from 0 to Timings.V_Max - 1
|
if (CPU.V_Counter >= Timings.V_Max) // V ranges from 0 to Timings.V_Max - 1
|
||||||
{
|
{
|
||||||
@ -466,7 +487,7 @@ void S9xDoHEventProcessing (void)
|
|||||||
|
|
||||||
if (PPU.OAMPriorityRotation)
|
if (PPU.OAMPriorityRotation)
|
||||||
tmp = (PPU.OAMAddr & 0xFE) >> 1;
|
tmp = (PPU.OAMAddr & 0xFE) >> 1;
|
||||||
if ((PPU.OAMFlip & 1) || PPU.FirstSprite != tmp)
|
if ((PPU.OAMFlip & 1) || PPU.FirstSprite!=tmp)
|
||||||
{
|
{
|
||||||
PPU.FirstSprite = tmp;
|
PPU.FirstSprite = tmp;
|
||||||
IPPU.OBJChanged = TRUE;
|
IPPU.OBJChanged = TRUE;
|
||||||
@ -510,7 +531,7 @@ void S9xDoHEventProcessing (void)
|
|||||||
|
|
||||||
case HC_RENDER_EVENT:
|
case HC_RENDER_EVENT:
|
||||||
if (CPU.V_Counter >= FIRST_VISIBLE_LINE && CPU.V_Counter <= PPU.ScreenHeight)
|
if (CPU.V_Counter >= FIRST_VISIBLE_LINE && CPU.V_Counter <= PPU.ScreenHeight)
|
||||||
RenderLine((uint8) (CPU.V_Counter - FIRST_VISIBLE_LINE));
|
RenderLine((uint8)(CPU.V_Counter - FIRST_VISIBLE_LINE));
|
||||||
|
|
||||||
S9xCheckMissingHTimerPosition(Timings.RenderPos);
|
S9xCheckMissingHTimerPosition(Timings.RenderPos);
|
||||||
|
|
||||||
@ -518,10 +539,12 @@ void S9xDoHEventProcessing (void)
|
|||||||
|
|
||||||
case HC_WRAM_REFRESH_EVENT:
|
case HC_WRAM_REFRESH_EVENT:
|
||||||
#ifdef DEBUGGER
|
#ifdef DEBUGGER
|
||||||
S9xTraceFormattedMessage("*** WRAM Refresh HC:%04d", CPU.Cycles);
|
sprintf(mes, "*** WRAM Refresh HC:%04d", CPU.Cycles);
|
||||||
|
S9xTraceMessage(mes);
|
||||||
#endif
|
#endif
|
||||||
S9xCheckMissingHTimerHalt(Timings.WRAMRefreshPos, SNES_WRAM_REFRESH_CYCLES);
|
S9xCheckMissingHTimerHalt(Timings.WRAMRefreshPos, SNES_WRAM_REFRESH_CYCLES);
|
||||||
CPU.Cycles += SNES_WRAM_REFRESH_CYCLES;
|
CPU.Cycles += SNES_WRAM_REFRESH_CYCLES;
|
||||||
|
S9xAPUExecute();
|
||||||
|
|
||||||
S9xCheckMissingHTimerPosition(Timings.WRAMRefreshPos);
|
S9xCheckMissingHTimerPosition(Timings.WRAMRefreshPos);
|
||||||
|
|
||||||
@ -534,18 +557,13 @@ void S9xDoHEventProcessing (void)
|
|||||||
case HC_IRQ_9_A_EVENT:
|
case HC_IRQ_9_A_EVENT:
|
||||||
case HC_IRQ_A_1_EVENT:
|
case HC_IRQ_A_1_EVENT:
|
||||||
if (PPU.HTimerEnabled && (!PPU.VTimerEnabled || (CPU.V_Counter == PPU.VTimerPosition)))
|
if (PPU.HTimerEnabled && (!PPU.VTimerEnabled || (CPU.V_Counter == PPU.VTimerPosition)))
|
||||||
S9xSetIRQ(PPU_IRQ_SOURCE);
|
S9xSetIRQ(PPU_H_BEAM_IRQ_SOURCE);
|
||||||
else
|
else
|
||||||
if (PPU.VTimerEnabled && (CPU.V_Counter == PPU.VTimerPosition))
|
if (PPU.VTimerEnabled && (CPU.V_Counter == PPU.VTimerPosition))
|
||||||
S9xSetIRQ(PPU_IRQ_SOURCE);
|
S9xSetIRQ(PPU_V_BEAM_IRQ_SOURCE);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
S9xReschedule();
|
S9xReschedule();
|
||||||
|
|
||||||
#ifdef DEBUGGER
|
|
||||||
if (Settings.TraceHCEvent)
|
|
||||||
S9xTraceFormattedMessage("--- HC event rescheduled (%02d) expected HC:%04d", CPU.WhichEvent, CPU.NextEvent);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
@ -159,102 +159,126 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _CPUEXEC_H_
|
#ifndef _CPUEXEC_H_
|
||||||
#define _CPUEXEC_H_
|
#define _CPUEXEC_H_
|
||||||
|
|
||||||
#include "ppu.h"
|
#include "snes9x.h"
|
||||||
|
|
||||||
struct SOpcodes
|
struct SOpcodes {
|
||||||
{
|
#ifdef __WIN32__
|
||||||
void (*S9xOpcode) (void);
|
void (__cdecl *S9xOpcode)( void);
|
||||||
|
#else
|
||||||
|
void (*S9xOpcode)( void);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SICPU
|
struct SICPU
|
||||||
{
|
{
|
||||||
struct SOpcodes *S9xOpcodes;
|
uint8 *Speed; // unused
|
||||||
uint8 *S9xOpLengths;
|
struct SOpcodes *S9xOpcodes;
|
||||||
uint8 _Carry;
|
uint8 *S9xOpLengths;
|
||||||
uint8 _Zero;
|
uint8 _Carry;
|
||||||
uint8 _Negative;
|
uint8 _Zero;
|
||||||
uint8 _Overflow;
|
uint8 _Negative;
|
||||||
bool8 CPUExecuting;
|
uint8 _Overflow;
|
||||||
uint32 ShiftedPB;
|
bool8 CPUExecuting;
|
||||||
uint32 ShiftedDB;
|
uint32 ShiftedPB;
|
||||||
uint32 Frame;
|
uint32 ShiftedDB;
|
||||||
uint32 FrameAdvanceCount;
|
uint32 Frame;
|
||||||
|
uint32 Scanline;
|
||||||
|
uint32 FrameAdvanceCount;
|
||||||
|
bool8 SavedAtOp;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct SICPU ICPU;
|
START_EXTERN_C
|
||||||
|
extern struct SICPU ICPU;
|
||||||
|
END_EXTERN_C
|
||||||
|
|
||||||
extern struct SOpcodes S9xOpcodesE1[256];
|
#include "ppu.h"
|
||||||
extern struct SOpcodes S9xOpcodesM1X1[256];
|
#include "memmap.h"
|
||||||
extern struct SOpcodes S9xOpcodesM1X0[256];
|
#include "65c816.h"
|
||||||
extern struct SOpcodes S9xOpcodesM0X1[256];
|
|
||||||
extern struct SOpcodes S9xOpcodesM0X0[256];
|
|
||||||
extern struct SOpcodes S9xOpcodesSlow[256];
|
|
||||||
extern uint8 S9xOpLengthsM1X1[256];
|
|
||||||
extern uint8 S9xOpLengthsM1X0[256];
|
|
||||||
extern uint8 S9xOpLengthsM0X1[256];
|
|
||||||
extern uint8 S9xOpLengthsM0X0[256];
|
|
||||||
|
|
||||||
|
START_EXTERN_C
|
||||||
void S9xMainLoop (void);
|
void S9xMainLoop (void);
|
||||||
void S9xReset (void);
|
void S9xReset (void);
|
||||||
void S9xSoftReset (void);
|
void S9xSoftReset (void);
|
||||||
void S9xDoHEventProcessing (void);
|
void S9xDoHEventProcessing ();
|
||||||
void S9xClearIRQ (uint32);
|
void S9xClearIRQ (uint32);
|
||||||
void S9xSetIRQ (uint32);
|
void S9xSetIRQ (uint32);
|
||||||
|
|
||||||
static inline void S9xUnpackStatus (void)
|
extern struct SOpcodes S9xOpcodesE1 [256];
|
||||||
|
extern struct SOpcodes S9xOpcodesM1X1 [256];
|
||||||
|
extern struct SOpcodes S9xOpcodesM1X0 [256];
|
||||||
|
extern struct SOpcodes S9xOpcodesM0X1 [256];
|
||||||
|
extern struct SOpcodes S9xOpcodesM0X0 [256];
|
||||||
|
extern struct SOpcodes S9xOpcodesSlow [256];
|
||||||
|
extern uint8 S9xOpLengthsM1X1 [256];
|
||||||
|
extern uint8 S9xOpLengthsM1X0 [256];
|
||||||
|
extern uint8 S9xOpLengthsM0X1 [256];
|
||||||
|
extern uint8 S9xOpLengthsM0X0 [256];
|
||||||
|
END_EXTERN_C
|
||||||
|
|
||||||
|
STATIC inline void S9xUnpackStatus()
|
||||||
{
|
{
|
||||||
ICPU._Zero = (Registers.PL & Zero) == 0;
|
ICPU._Zero = (Registers.PL & Zero) == 0;
|
||||||
ICPU._Negative = (Registers.PL & Negative);
|
ICPU._Negative = (Registers.PL & Negative);
|
||||||
ICPU._Carry = (Registers.PL & Carry);
|
ICPU._Carry = (Registers.PL & Carry);
|
||||||
ICPU._Overflow = (Registers.PL & Overflow) >> 6;
|
ICPU._Overflow = (Registers.PL & Overflow) >> 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void S9xPackStatus (void)
|
STATIC inline void S9xPackStatus()
|
||||||
{
|
{
|
||||||
Registers.PL &= ~(Zero | Negative | Carry | Overflow);
|
Registers.PL &= ~(Zero | Negative | Carry | Overflow);
|
||||||
Registers.PL |= ICPU._Carry | ((ICPU._Zero == 0) << 1) | (ICPU._Negative & 0x80) | (ICPU._Overflow << 6);
|
Registers.PL |= ICPU._Carry | ((ICPU._Zero == 0) << 1) |
|
||||||
|
(ICPU._Negative & 0x80) | (ICPU._Overflow << 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void S9xFixCycles (void)
|
STATIC inline void CLEAR_IRQ_SOURCE (uint32 M)
|
||||||
{
|
{
|
||||||
if (CheckEmulation())
|
CPU.IRQActive &= ~M;
|
||||||
|
if (!CPU.IRQActive)
|
||||||
|
CPU.Flags &= ~IRQ_FLAG;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC inline void S9xFixCycles ()
|
||||||
|
{
|
||||||
|
if (CheckEmulation ())
|
||||||
|
{
|
||||||
|
ICPU.S9xOpcodes = S9xOpcodesE1;
|
||||||
|
ICPU.S9xOpLengths = S9xOpLengthsM1X1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (CheckMemory ())
|
||||||
|
{
|
||||||
|
if (CheckIndex ())
|
||||||
{
|
{
|
||||||
ICPU.S9xOpcodes = S9xOpcodesE1;
|
ICPU.S9xOpcodes = S9xOpcodesM1X1;
|
||||||
ICPU.S9xOpLengths = S9xOpLengthsM1X1;
|
ICPU.S9xOpLengths = S9xOpLengthsM1X1;
|
||||||
}
|
|
||||||
else
|
|
||||||
if (CheckMemory())
|
|
||||||
{
|
|
||||||
if (CheckIndex())
|
|
||||||
{
|
|
||||||
ICPU.S9xOpcodes = S9xOpcodesM1X1;
|
|
||||||
ICPU.S9xOpLengths = S9xOpLengthsM1X1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ICPU.S9xOpcodes = S9xOpcodesM1X0;
|
|
||||||
ICPU.S9xOpLengths = S9xOpLengthsM1X0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (CheckIndex())
|
ICPU.S9xOpcodes = S9xOpcodesM1X0;
|
||||||
{
|
ICPU.S9xOpLengths = S9xOpLengthsM1X0;
|
||||||
ICPU.S9xOpcodes = S9xOpcodesM0X1;
|
|
||||||
ICPU.S9xOpLengths = S9xOpLengthsM0X1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ICPU.S9xOpcodes = S9xOpcodesM0X0;
|
|
||||||
ICPU.S9xOpLengths = S9xOpLengthsM0X0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (CheckIndex ())
|
||||||
|
{
|
||||||
|
ICPU.S9xOpcodes = S9xOpcodesM0X1;
|
||||||
|
ICPU.S9xOpLengths = S9xOpLengthsM0X1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ICPU.S9xOpcodes = S9xOpcodesM0X0;
|
||||||
|
ICPU.S9xOpLengths = S9xOpLengthsM0X0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void S9xReschedule (void)
|
STATIC inline void S9xReschedule (void)
|
||||||
{
|
{
|
||||||
uint8 next = 0;
|
uint8 next = 0;
|
||||||
int32 hpos = 0;
|
int32 hpos = 0;
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -159,14 +159,16 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _CPUOPS_H_
|
#ifndef _CPUOPS_H_
|
||||||
#define _CPUOPS_H_
|
#define _CPUOPS_H_
|
||||||
|
void S9xOpcode_NMI ();
|
||||||
void S9xOpcode_NMI (void);
|
void S9xOpcode_IRQ ();
|
||||||
void S9xOpcode_IRQ (void);
|
|
||||||
|
|
||||||
#define CHECK_FOR_IRQ() \
|
#define CHECK_FOR_IRQ() \
|
||||||
if (CPU.IRQActive && !CheckFlag(IRQ) && !Settings.DisableIRQ) \
|
if (CPU.IRQActive && !CheckFlag (IRQ) && !Settings.DisableIRQ) \
|
||||||
S9xOpcode_IRQ()
|
S9xOpcode_IRQ()
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -159,508 +159,487 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#ifdef HAVE_LIBPNG
|
#ifdef HAVE_LIBPNG
|
||||||
#include <png.h>
|
#include <png.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "port.h"
|
#include "port.h"
|
||||||
#include "crosshairs.h"
|
#include "crosshairs.h"
|
||||||
|
|
||||||
static const char *crosshairs[32] =
|
static char *crosshairs[32]={
|
||||||
{
|
"` " /* Crosshair 0 (no image) */
|
||||||
"` " // Crosshair 0 (no image)
|
" "
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
" "
|
" ",
|
||||||
" ",
|
|
||||||
|
|
||||||
"` " // Crosshair 1 (the classic small dot)
|
"` " /* Crosshair 1 (the classic small dot) */
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
" #. "
|
" #. "
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
" ",
|
" ",
|
||||||
|
|
||||||
"` " // Crosshair 2 (a standard cross)
|
"` " /* Crosshair 2 (a standard cross) */
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
" .#. "
|
" .#. "
|
||||||
" .#. "
|
" .#. "
|
||||||
" ...#... "
|
" ...#... "
|
||||||
" ####### "
|
" ####### "
|
||||||
" ...#... "
|
" ...#... "
|
||||||
" .#. "
|
" .#. "
|
||||||
" .#. "
|
" .#. "
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
" ",
|
" ",
|
||||||
|
|
||||||
"` .#. " // Crosshair 3 (a standard cross)
|
"` .#. " /* Crosshair 3 (a standard cross) */
|
||||||
" .#. "
|
" .#. "
|
||||||
" .#. "
|
" .#. "
|
||||||
" .#. "
|
" .#. "
|
||||||
" .#. "
|
" .#. "
|
||||||
" .#. "
|
" .#. "
|
||||||
".......#......."
|
".......#......."
|
||||||
"###############"
|
"###############"
|
||||||
".......#......."
|
".......#......."
|
||||||
" .#. "
|
" .#. "
|
||||||
" .#. "
|
" .#. "
|
||||||
" .#. "
|
" .#. "
|
||||||
" .#. "
|
" .#. "
|
||||||
" .#. "
|
" .#. "
|
||||||
" .#. ",
|
" .#. ",
|
||||||
|
|
||||||
"` " // Crosshair 4 (an X)
|
"` " /* Crosshair 4 (an X) */
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
" . . "
|
" . . "
|
||||||
" .#. .#. "
|
" .#. .#. "
|
||||||
" .#. .#. "
|
" .#. .#. "
|
||||||
" .#.#. "
|
" .#.#. "
|
||||||
" .#. "
|
" .#. "
|
||||||
" .#.#. "
|
" .#.#. "
|
||||||
" .#. .#. "
|
" .#. .#. "
|
||||||
" .#. .#. "
|
" .#. .#. "
|
||||||
" . . "
|
" . . "
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
" ",
|
" ",
|
||||||
|
|
||||||
"`. . " // Crosshair 5 (an X)
|
"`. . " /* Crosshair 5 (an X) */
|
||||||
".#. .#."
|
".#. .#."
|
||||||
" .#. .#. "
|
" .#. .#. "
|
||||||
" .#. .#. "
|
" .#. .#. "
|
||||||
" .#. .#. "
|
" .#. .#. "
|
||||||
" .#. .#. "
|
" .#. .#. "
|
||||||
" .#.#. "
|
" .#.#. "
|
||||||
" .#. "
|
" .#. "
|
||||||
" .#.#. "
|
" .#.#. "
|
||||||
" .#. .#. "
|
" .#. .#. "
|
||||||
" .#. .#. "
|
" .#. .#. "
|
||||||
" .#. .#. "
|
" .#. .#. "
|
||||||
" .#. .#. "
|
" .#. .#. "
|
||||||
".#. .#."
|
".#. .#."
|
||||||
" . . ",
|
" . . ",
|
||||||
|
|
||||||
"` " // Crosshair 6 (a combo)
|
"` " /* Crosshair 6 (a combo) */
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
" # . # "
|
" # . # "
|
||||||
" # . # "
|
" # . # "
|
||||||
" #.# "
|
" #.# "
|
||||||
" ...#... "
|
" ...#... "
|
||||||
" #.# "
|
" #.# "
|
||||||
" # . # "
|
" # . # "
|
||||||
" # . # "
|
" # . # "
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
" ",
|
" ",
|
||||||
|
|
||||||
"` . " // Crosshair 7 (a combo)
|
"` . " /* Crosshair 7 (a combo) */
|
||||||
" # . # "
|
" # . # "
|
||||||
" # . # "
|
" # . # "
|
||||||
" # . # "
|
" # . # "
|
||||||
" # . # "
|
" # . # "
|
||||||
" # . # "
|
" # . # "
|
||||||
" #.# "
|
" #.# "
|
||||||
".......#......."
|
".......#......."
|
||||||
" #.# "
|
" #.# "
|
||||||
" # . # "
|
" # . # "
|
||||||
" # . # "
|
" # . # "
|
||||||
" # . # "
|
" # . # "
|
||||||
" # . # "
|
" # . # "
|
||||||
" # . # "
|
" # . # "
|
||||||
" . ",
|
" . ",
|
||||||
|
|
||||||
"` # " // Crosshair 8 (a diamond cross)
|
"` # " /* Crosshair 8 (a diamond cross) */
|
||||||
" #.# "
|
" #.# "
|
||||||
" # . # "
|
" # . # "
|
||||||
" # . # "
|
" # . # "
|
||||||
" # . # "
|
" # . # "
|
||||||
" # . # "
|
" # . # "
|
||||||
" # . # "
|
" # . # "
|
||||||
"#......#......#"
|
"#......#......#"
|
||||||
" # . # "
|
" # . # "
|
||||||
" # . # "
|
" # . # "
|
||||||
" # . # "
|
" # . # "
|
||||||
" # . # "
|
" # . # "
|
||||||
" # . # "
|
" # . # "
|
||||||
" #.# "
|
" #.# "
|
||||||
" # ",
|
" # ",
|
||||||
|
|
||||||
"` ### " // Crosshair 9 (a circle cross)
|
"` ### " /* Crosshair 9 (a circle cross) */
|
||||||
" ## . ## "
|
" ## . ## "
|
||||||
" # . # "
|
" # . # "
|
||||||
" # . # "
|
" # . # "
|
||||||
" # . # "
|
" # . # "
|
||||||
" # . # "
|
" # . # "
|
||||||
"# . #"
|
"# . #"
|
||||||
"#......#......#"
|
"#......#......#"
|
||||||
"# . #"
|
"# . #"
|
||||||
" # . # "
|
" # . # "
|
||||||
" # . # "
|
" # . # "
|
||||||
" # . # "
|
" # . # "
|
||||||
" # . # "
|
" # . # "
|
||||||
" ## . ## "
|
" ## . ## "
|
||||||
" ### ",
|
" ### ",
|
||||||
|
|
||||||
"` .#. " // Crosshair 10 (a square cross)
|
"` .#. " /* Crosshair 10 (a square cross) */
|
||||||
" .#. "
|
" .#. "
|
||||||
" .#. "
|
" .#. "
|
||||||
" ....#.... "
|
" ....#.... "
|
||||||
" .#######. "
|
" .#######. "
|
||||||
" .# #. "
|
" .# #. "
|
||||||
"....# #...."
|
"....# #...."
|
||||||
"##### #####"
|
"##### #####"
|
||||||
"....# #...."
|
"....# #...."
|
||||||
" .# #. "
|
" .# #. "
|
||||||
" .#######. "
|
" .#######. "
|
||||||
" ....#.... "
|
" ....#.... "
|
||||||
" .#. "
|
" .#. "
|
||||||
" .#. "
|
" .#. "
|
||||||
" .#. ",
|
" .#. ",
|
||||||
|
|
||||||
"` .#. " // Crosshair 11 (an interrupted cross)
|
"` .#. " /* Crosshair 11 (an interrupted cross) */
|
||||||
" .#. "
|
" .#. "
|
||||||
" .#. "
|
" .#. "
|
||||||
" .#. "
|
" .#. "
|
||||||
" .#. "
|
" .#. "
|
||||||
" "
|
" "
|
||||||
"..... ....."
|
"..... ....."
|
||||||
"##### #####"
|
"##### #####"
|
||||||
"..... ....."
|
"..... ....."
|
||||||
" "
|
" "
|
||||||
" .#. "
|
" .#. "
|
||||||
" .#. "
|
" .#. "
|
||||||
" .#. "
|
" .#. "
|
||||||
" .#. "
|
" .#. "
|
||||||
" .#. ",
|
" .#. ",
|
||||||
|
|
||||||
"`. . " // Crosshair 12 (an interrupted X)
|
"`. . " /* Crosshair 12 (an interrupted X) */
|
||||||
".#. .#."
|
".#. .#."
|
||||||
" .#. .#. "
|
" .#. .#. "
|
||||||
" .#. .#. "
|
" .#. .#. "
|
||||||
" .#. .#. "
|
" .#. .#. "
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
" .#. .#. "
|
" .#. .#. "
|
||||||
" .#. .#. "
|
" .#. .#. "
|
||||||
" .#. .#. "
|
" .#. .#. "
|
||||||
".#. .#."
|
".#. .#."
|
||||||
" . . ",
|
" . . ",
|
||||||
|
|
||||||
"` . " // Crosshair 13 (an interrupted combo)
|
"` . " /* Crosshair 13 (an interrupted combo) */
|
||||||
" # . # "
|
" # . # "
|
||||||
" # . # "
|
" # . # "
|
||||||
" # . # "
|
" # . # "
|
||||||
" # . # "
|
" # . # "
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
"..... ....."
|
"..... ....."
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
" # . # "
|
" # . # "
|
||||||
" # . # "
|
" # . # "
|
||||||
" # . # "
|
" # . # "
|
||||||
" # . # "
|
" # . # "
|
||||||
" . ",
|
" . ",
|
||||||
|
|
||||||
"`#### #### " // Crosshair 14
|
"`#### #### " /* Crosshair 14 */
|
||||||
"#.... ....#"
|
"#.... ....#"
|
||||||
"#. .#"
|
"#. .#"
|
||||||
"#. .#"
|
"#. .#"
|
||||||
"#. .#"
|
"#. .#"
|
||||||
" # "
|
" # "
|
||||||
" # "
|
" # "
|
||||||
" ##### "
|
" ##### "
|
||||||
" # "
|
" # "
|
||||||
" # "
|
" # "
|
||||||
"#. .#"
|
"#. .#"
|
||||||
"#. .#"
|
"#. .#"
|
||||||
"#. .#"
|
"#. .#"
|
||||||
"#.... ....#"
|
"#.... ....#"
|
||||||
" #### #### ",
|
" #### #### ",
|
||||||
|
|
||||||
"` .# #. " // Crosshair 15
|
"` .# #. " /* Crosshair 15 */
|
||||||
" .# #. "
|
" .# #. "
|
||||||
" .# #. "
|
" .# #. "
|
||||||
"....# #...."
|
"....# #...."
|
||||||
"##### #####"
|
"##### #####"
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
" "
|
" "
|
||||||
"##### #####"
|
"##### #####"
|
||||||
"....# #...."
|
"....# #...."
|
||||||
" .# #. "
|
" .# #. "
|
||||||
" .# #. "
|
" .# #. "
|
||||||
" .# #. ",
|
" .# #. ",
|
||||||
|
|
||||||
"` # " // Crosshair 16
|
"` # " /* Crosshair 16 */
|
||||||
" # "
|
" # "
|
||||||
" # "
|
" # "
|
||||||
" ....#.... "
|
" ....#.... "
|
||||||
" . # . "
|
" . # . "
|
||||||
" . # . "
|
" . # . "
|
||||||
" . # . "
|
" . # . "
|
||||||
"###############"
|
"###############"
|
||||||
" . # . "
|
" . # . "
|
||||||
" . # . "
|
" . # . "
|
||||||
" . # . "
|
" . # . "
|
||||||
" ....#.... "
|
" ....#.... "
|
||||||
" # "
|
" # "
|
||||||
" # "
|
" # "
|
||||||
" # ",
|
" # ",
|
||||||
|
|
||||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool S9xLoadCrosshairFile(int idx, const char *filename){
|
||||||
|
int i, r;
|
||||||
|
char *s;
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
bool S9xLoadCrosshairFile (int idx, const char *filename)
|
if(idx<1 || idx>31) return false;
|
||||||
{
|
if((s=(char *)calloc(15*15+1, sizeof(char)))==NULL){
|
||||||
if (idx < 1 || idx > 31)
|
fprintf(stderr, "S9xLoadCrosshairFile: malloc error while reading ");
|
||||||
return (false);
|
perror(filename);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
char *s = (char *) calloc(15 * 15 + 1, sizeof(char));
|
if((fp=fopen(filename, "rb"))==NULL){
|
||||||
if (s == NULL)
|
fprintf(stderr, "S9xLoadCrosshairFile: Couldn't open ");
|
||||||
{
|
perror(filename);
|
||||||
fprintf(stderr, "S9xLoadCrosshairFile: malloc error while reading ");
|
free(s);
|
||||||
perror(filename);
|
return false;
|
||||||
return (false);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
FILE *fp = fopen(filename, "rb");
|
|
||||||
if (fp == NULL)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "S9xLoadCrosshairFile: Couldn't open ");
|
|
||||||
perror(filename);
|
|
||||||
free(s);
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t l = fread(s, 1, 8, fp);
|
|
||||||
if (l != 8)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "S9xLoadCrosshairFile: File is too short!\n");
|
|
||||||
free(s);
|
|
||||||
fclose(fp);
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
i=fread(s, 1, 8, fp);
|
||||||
|
if(i!=8){
|
||||||
|
fprintf(stderr, "S9xLoadCrosshairFile: File is too short!\n");
|
||||||
|
free(s);
|
||||||
|
fclose(fp);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
#ifdef HAVE_LIBPNG
|
#ifdef HAVE_LIBPNG
|
||||||
png_structp png_ptr;
|
png_structp png_ptr;
|
||||||
png_infop info_ptr;
|
png_infop info_ptr;
|
||||||
|
|
||||||
if (!png_sig_cmp((png_byte *) s, 0, 8))
|
if(!png_sig_cmp((png_byte *)s, 0, 8)){
|
||||||
{
|
png_ptr=png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||||
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
if (!png_ptr){
|
||||||
if (!png_ptr)
|
free(s);
|
||||||
{
|
fclose(fp);
|
||||||
free(s);
|
return false;
|
||||||
fclose(fp);
|
}
|
||||||
return (false);
|
info_ptr=png_create_info_struct(png_ptr);
|
||||||
}
|
if(!info_ptr){
|
||||||
|
png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
|
||||||
|
free(s);
|
||||||
|
fclose(fp);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
info_ptr = png_create_info_struct(png_ptr);
|
png_init_io(png_ptr, fp);
|
||||||
if (!info_ptr)
|
png_set_sig_bytes(png_ptr, 8);
|
||||||
{
|
png_read_info(png_ptr, info_ptr);
|
||||||
png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL);
|
|
||||||
free(s);
|
|
||||||
fclose(fp);
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
|
|
||||||
png_init_io(png_ptr, fp);
|
png_uint_32 width, height;
|
||||||
png_set_sig_bytes(png_ptr, 8);
|
int bit_depth, color_type;
|
||||||
png_read_info(png_ptr, info_ptr);
|
|
||||||
|
|
||||||
png_uint_32 width, height;
|
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL);
|
||||||
int bit_depth, color_type;
|
if(color_type!=PNG_COLOR_TYPE_PALETTE){
|
||||||
|
fprintf(stderr, "S9xLoadCrosshairFile: Input PNG is not a palettized image!\n");
|
||||||
|
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
|
||||||
|
free(s);
|
||||||
|
fclose(fp);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(bit_depth==16)
|
||||||
|
png_set_strip_16(png_ptr);
|
||||||
|
|
||||||
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL);
|
if(width!=15 || height!=15){
|
||||||
if (color_type != PNG_COLOR_TYPE_PALETTE)
|
fprintf(stderr, "S9xLoadCrosshairFile: Expecting a 15x15 PNG\n");
|
||||||
{
|
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
|
||||||
fprintf(stderr, "S9xLoadCrosshairFile: Input PNG is not a palettized image!\n");
|
free(s);
|
||||||
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
|
fclose(fp);
|
||||||
free(s);
|
return false;
|
||||||
fclose(fp);
|
}
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bit_depth == 16)
|
int num_palette=0, num_trans=0;
|
||||||
png_set_strip_16(png_ptr);
|
int fgcol=-1, bgcol=-1, transcol=-1;
|
||||||
|
png_color *pngpal;
|
||||||
|
png_byte *trans;
|
||||||
|
|
||||||
if (width != 15 || height != 15)
|
png_get_PLTE(png_ptr, info_ptr, &pngpal, &num_palette);
|
||||||
{
|
png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL);
|
||||||
fprintf(stderr, "S9xLoadCrosshairFile: Expecting a 15x15 PNG\n");
|
|
||||||
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
|
|
||||||
free(s);
|
|
||||||
fclose(fp);
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
|
|
||||||
png_color *pngpal;
|
if(num_palette!=3 || num_trans!=1){
|
||||||
png_byte *trans;
|
fprintf(stderr, "S9xLoadCrosshairFile: Expecting a 3-color PNG with 1 trasnparent color\n");
|
||||||
int num_palette = 0, num_trans = 0;
|
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
|
||||||
int transcol = -1, fgcol = -1, bgcol = -1;
|
free(s);
|
||||||
|
fclose(fp);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
png_get_PLTE(png_ptr, info_ptr, &pngpal, &num_palette);
|
for(i=0; i<3; i++){
|
||||||
png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL);
|
if(trans[0]==i){
|
||||||
|
transcol=i;
|
||||||
|
} else if(pngpal[i].red==0 && pngpal[i].green==0 && pngpal[i].blue==0){
|
||||||
|
bgcol=i;
|
||||||
|
} else if(pngpal[i].red==255 && pngpal[i].green==255 && pngpal[i].blue==255){
|
||||||
|
fgcol=i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (num_palette != 3 || num_trans != 1)
|
if(transcol<0 || fgcol<0 || bgcol<0){
|
||||||
{
|
fprintf(stderr, "S9xLoadCrosshairFile: PNG must have 3 colors: white (fg), black (bg), and transparent.\n");
|
||||||
fprintf(stderr, "S9xLoadCrosshairFile: Expecting a 3-color PNG with 1 trasnparent color\n");
|
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
|
||||||
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
|
free(s);
|
||||||
free(s);
|
fclose(fp);
|
||||||
fclose(fp);
|
return false;
|
||||||
return (false);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++)
|
png_set_packing(png_ptr);
|
||||||
{
|
png_read_update_info(png_ptr, info_ptr);
|
||||||
if (trans[0] == i)
|
png_byte *row_pointer = new png_byte [png_get_rowbytes(png_ptr, info_ptr)];
|
||||||
transcol = i;
|
|
||||||
else
|
|
||||||
if (pngpal[i].red == 0 && pngpal[i].green == 0 && pngpal[i].blue == 0)
|
|
||||||
bgcol = i;
|
|
||||||
else
|
|
||||||
if (pngpal[i].red == 255 && pngpal[i].green == 255 && pngpal[i].blue == 255)
|
|
||||||
fgcol = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (transcol < 0 || fgcol < 0 || bgcol < 0)
|
for(r=0; r<15*15; r+=15){
|
||||||
{
|
png_read_row(png_ptr, row_pointer, NULL);
|
||||||
fprintf(stderr, "S9xLoadCrosshairFile: PNG must have 3 colors: white (fg), black (bg), and transparent.\n");
|
for(i=0; i<15; i++){
|
||||||
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
|
if(row_pointer[i]==transcol) s[r+i]=' ';
|
||||||
free(s);
|
else if(row_pointer[i]==fgcol) s[r+i]='#';
|
||||||
fclose(fp);
|
else if(row_pointer[i]==bgcol) s[r+i]='.';
|
||||||
return (false);
|
else {
|
||||||
}
|
fprintf(stderr, "S9xLoadCrosshairFile: WTF? This was supposed to be a 3-color PNG!\n");
|
||||||
|
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
|
||||||
png_set_packing(png_ptr);
|
free(s);
|
||||||
png_read_update_info(png_ptr, info_ptr);
|
fclose(fp);
|
||||||
png_byte *row_pointer = new png_byte[png_get_rowbytes(png_ptr, info_ptr)];
|
return false;
|
||||||
|
}
|
||||||
for (int r = 0; r < 15 * 15; r += 15)
|
}
|
||||||
{
|
}
|
||||||
png_read_row(png_ptr, row_pointer, NULL);
|
s[15*15]=0;
|
||||||
|
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
|
||||||
for (int i = 0; i < 15; i++)
|
} else
|
||||||
{
|
|
||||||
if (row_pointer[i] == transcol)
|
|
||||||
s[r + i] = ' ';
|
|
||||||
else
|
|
||||||
if (row_pointer[i] == fgcol)
|
|
||||||
s[r + i] = '#';
|
|
||||||
else
|
|
||||||
if (row_pointer[i] == bgcol)
|
|
||||||
s[r + i] = '.';
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fprintf(stderr, "S9xLoadCrosshairFile: WTF? This was supposed to be a 3-color PNG!\n");
|
|
||||||
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
|
|
||||||
free(s);
|
|
||||||
fclose(fp);
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
s[15 * 15] = 0;
|
|
||||||
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
l = fread(s + 8, 1, 15 - 8, fp);
|
i=fread(s+8, 1, 15-8, fp);
|
||||||
if (l != 15 - 8)
|
if(i!=15-8){
|
||||||
{
|
fprintf(stderr, "S9xLoadCrosshairFile: File is too short!\n");
|
||||||
fprintf(stderr, "S9xLoadCrosshairFile: File is too short!\n");
|
free(s);
|
||||||
free(s);
|
fclose(fp);
|
||||||
fclose(fp);
|
return false;
|
||||||
return (false);
|
}
|
||||||
}
|
if(getc(fp)!='\n'){
|
||||||
|
fprintf(stderr, "S9xLoadCrosshairFile: Invalid file format!");
|
||||||
|
#ifndef HAVE_LIBPNG
|
||||||
|
fprintf(stderr, " (note: PNG support is not available)");
|
||||||
|
#endif
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
free(s);
|
||||||
|
fclose(fp);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for(r=1; r<15; r++){
|
||||||
|
i=fread(s+r*15, 1, 15, fp);
|
||||||
|
if(i!=15){
|
||||||
|
fprintf(stderr, "S9xLoadCrosshairFile: File is too short!");
|
||||||
|
#ifndef HAVE_LIBPNG
|
||||||
|
fprintf(stderr, " (note: PNG support is not available)");
|
||||||
|
#endif
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
free(s);
|
||||||
|
fclose(fp);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(getc(fp)!='\n'){
|
||||||
|
fprintf(stderr, "S9xLoadCrosshairFile: Invalid file format!");
|
||||||
|
#ifndef HAVE_LIBPNG
|
||||||
|
fprintf(stderr, " (note: PNG support is not available)");
|
||||||
|
#endif
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
free(s);
|
||||||
|
fclose(fp);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(i=0; i<15*15; i++){
|
||||||
|
if(s[i]!=' ' && s[i]!='#' && s[i]!='.'){
|
||||||
|
fprintf(stderr, "S9xLoadCrosshairFile: Invalid file format!");
|
||||||
|
#ifndef HAVE_LIBPNG
|
||||||
|
fprintf(stderr, " (note: PNG support is not available)");
|
||||||
|
#endif
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
free(s);
|
||||||
|
fclose(fp);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
if (getc(fp) != '\n')
|
if(crosshairs[idx]!=NULL && crosshairs[idx][0]!='`') free(crosshairs[idx]);
|
||||||
{
|
crosshairs[idx]=s;
|
||||||
fprintf(stderr, "S9xLoadCrosshairFile: Invalid file format! (note: PNG support is not available)\n");
|
return true;
|
||||||
free(s);
|
|
||||||
fclose(fp);
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int r = 1; r < 15; r++)
|
|
||||||
{
|
|
||||||
l = fread(s + r * 15, 1, 15, fp);
|
|
||||||
if (l != 15)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "S9xLoadCrosshairFile: File is too short! (note: PNG support is not available)\n");
|
|
||||||
free(s);
|
|
||||||
fclose(fp);
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getc(fp) != '\n')
|
|
||||||
{
|
|
||||||
fprintf(stderr, "S9xLoadCrosshairFile: Invalid file format! (note: PNG support is not available)\n");
|
|
||||||
free(s);
|
|
||||||
fclose(fp);
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < 15 * 15; i++)
|
|
||||||
{
|
|
||||||
if (s[i] != ' ' && s[i] != '#' && s[i] != '.')
|
|
||||||
{
|
|
||||||
fprintf(stderr, "S9xLoadCrosshairFile: Invalid file format! (note: PNG support is not available)\n");
|
|
||||||
free(s);
|
|
||||||
fclose(fp);
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
|
|
||||||
if (crosshairs[idx] != NULL && crosshairs[idx][0] != '`')
|
|
||||||
free((void *) crosshairs[idx]);
|
|
||||||
crosshairs[idx] = s;
|
|
||||||
|
|
||||||
return (true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char * S9xGetCrosshair (int idx)
|
const char *S9xGetCrosshair(int idx){
|
||||||
{
|
if(idx<0 || idx>31) return NULL;
|
||||||
if (idx < 0 || idx > 31)
|
return crosshairs[idx];
|
||||||
return (NULL);
|
|
||||||
|
|
||||||
return (crosshairs[idx]);
|
|
||||||
}
|
}
|
||||||
|
@ -159,59 +159,62 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _CROSSHAIRS_H_
|
|
||||||
#define _CROSSHAIRS_H_
|
|
||||||
|
|
||||||
// Read in the specified crosshair file, replacing whatever data might be in that slot.
|
#ifndef CROSSHAIRS_H
|
||||||
// Available slots are 1-31.
|
#define CROSSHAIRS_H
|
||||||
// The input file must be a PNG or a text file.
|
|
||||||
// PNG: 15x15 pixels, palettized, with 3 colors (white, black, and transparent).
|
|
||||||
// text: 15 lines of 16 characters (counting the \n), consisting of ' ', '#', or '.'.
|
|
||||||
|
|
||||||
bool S9xLoadCrosshairFile (int idx, const char *filename);
|
/*
|
||||||
|
* Read in the specified crosshair file, replacing whatever data might be in
|
||||||
|
* that slot. Available slots are 1-31. The input file must be a PNG file,
|
||||||
|
* 15x15 pixels, palettized, with 3 colors: white, black, and transparent. Or a
|
||||||
|
* text file, 15 lines of 16 characters (counting the \n), consisting of ' ',
|
||||||
|
* '#', or '.'.
|
||||||
|
*/
|
||||||
|
bool S9xLoadCrosshairFile(int idx, const char *filename);
|
||||||
|
|
||||||
// Return the specified crosshair. Woo-hoo.
|
/*
|
||||||
// char * to a 225-byte string, with '#' marking foreground, '.' marking background,
|
* Return the specified crosshair. Woo-hoo. char * to a 225-byte string, with
|
||||||
// and anything else transparent.
|
* '#' marking foreground, '.' marking background, and anything else
|
||||||
|
* transparent.
|
||||||
|
*/
|
||||||
|
const char *S9xGetCrosshair(int idx);
|
||||||
|
|
||||||
const char * S9xGetCrosshair (int idx);
|
/*
|
||||||
|
* In controls.cpp. Sets the crosshair for the specified device. Defaults are:
|
||||||
// In controls.cpp. Sets the crosshair for the specified device. Defaults are:
|
* cross fgcolor bgcolor
|
||||||
// cross fgcolor bgcolor
|
* Mouse 1: 1 White Black
|
||||||
// Mouse 1: 1 White Black
|
* Mouse 2: 1 Purple White
|
||||||
// Mouse 2: 1 Purple White
|
* Superscope: 2 White Black
|
||||||
// Superscope: 2 White Black
|
* Justifier 1: 4 Blue Black
|
||||||
// Justifier 1: 4 Blue Black
|
* Justifier 2: 4 MagicPink Black
|
||||||
// Justifier 2: 4 MagicPink Black
|
*
|
||||||
//
|
* Available colors are: Trans, Black, 25Grey, 50Grey, 75Grey, White, Red,
|
||||||
// Available colors are: Trans, Black, 25Grey, 50Grey, 75Grey, White, Red, Orange,
|
* Orange, Yellow, Green, Cyan, Sky, Blue, Violet, MagicPink, and Purple. You
|
||||||
// Yellow, Green, Cyan, Sky, Blue, Violet, MagicPink, and Purple.
|
* may also prefix a 't' (e.g. tBlue) for a 50%-transparent version.
|
||||||
// You may also prefix a 't' (e.g. tBlue) for a 50%-transparent version.
|
*
|
||||||
// Use idx = -1 or fg/bg = NULL to keep the current setting.
|
* Use idx=-1 or fg/bg=NULL to keep the current setting.
|
||||||
|
*/
|
||||||
enum crosscontrols
|
enum crosscontrols {
|
||||||
{
|
X_MOUSE1,
|
||||||
X_MOUSE1,
|
X_MOUSE2,
|
||||||
X_MOUSE2,
|
X_SUPERSCOPE,
|
||||||
X_SUPERSCOPE,
|
X_JUSTIFIER1,
|
||||||
X_JUSTIFIER1,
|
X_JUSTIFIER2
|
||||||
X_JUSTIFIER2
|
|
||||||
};
|
};
|
||||||
|
void S9xSetControllerCrosshair(enum crosscontrols ctl, int8 idx, const char *fg, const char *bg);
|
||||||
|
void S9xGetControllerCrosshair(enum crosscontrols ctl, int8 *idx, const char **fg, const char **bg);
|
||||||
|
|
||||||
void S9xSetControllerCrosshair (enum crosscontrols ctl, int8 idx, const char *fg, const char *bg);
|
/*
|
||||||
void S9xGetControllerCrosshair (enum crosscontrols ctl, int8 *idx, const char **fg, const char **bg);
|
* In gfx.cpp, much like DisplayChar() except it takes the parameters listed
|
||||||
|
* and looks up GFX.Screen. The 'crosshair' arg is a 15x15 image, with '#'
|
||||||
// In gfx.cpp, much like S9xDisplayChar() except it takes the parameters
|
* meaning fgcolor, '.' meaning bgcolor, and anything else meaning transparent.
|
||||||
// listed and looks up GFX.Screen.
|
* Color values should be (RGB):
|
||||||
// The 'crosshair' arg is a 15x15 image, with '#' meaning fgcolor,
|
* 0 = transparent 4=23 23 23 8=31 31 0 12= 0 0 31
|
||||||
// '.' meaning bgcolor, and anything else meaning transparent.
|
* 1 = 0 0 0 5=31 31 31 9= 0 31 0 13=23 0 31
|
||||||
// Color values should be (RGB):
|
* 2 = 8 8 8 6=31 00 00 10= 0 31 31 14=31 0 31
|
||||||
// 0 = transparent 4 = 23 23 23 8 = 31 31 0 12 = 0 0 31
|
* 3 = 16 16 16 7=31 16 00 11= 0 23 31 15=31 0 16
|
||||||
// 1 = 0 0 0 5 = 31 31 31 9 = 0 31 0 13 = 23 0 31
|
* 16-31 are 50% transparent versions of 0-15.
|
||||||
// 2 = 8 8 8 6 = 31 0 0 10 = 0 31 31 14 = 31 0 31
|
*/
|
||||||
// 3 = 16 16 16 7 = 31 16 0 11 = 0 23 31 15 = 31 0 16
|
void S9xDrawCrosshair(const char *crosshair, uint8 fgcolor, uint8 bgcolor, int16 x, int16 y);
|
||||||
// 16-31 are 50% transparent versions of 0-15.
|
|
||||||
|
|
||||||
void S9xDrawCrosshair (const char *crosshair, uint8 fgcolor, uint8 bgcolor, int16 x, int16 y);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
613
source/snes9x/data.cpp
Normal file
613
source/snes9x/data.cpp
Normal file
@ -0,0 +1,613 @@
|
|||||||
|
/**********************************************************************************
|
||||||
|
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||||
|
|
||||||
|
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||||
|
Jerremy Koot (jkoot@snes9x.com)
|
||||||
|
|
||||||
|
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||||
|
|
||||||
|
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||||
|
|
||||||
|
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||||
|
|
||||||
|
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||||
|
|
||||||
|
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||||
|
Kris Bleakley (codeviolation@hotmail.com)
|
||||||
|
|
||||||
|
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
|
||||||
|
Nach (n-a-c-h@users.sourceforge.net),
|
||||||
|
zones (kasumitokoduck@yahoo.com)
|
||||||
|
|
||||||
|
(c) Copyright 2006 - 2007 nitsuja
|
||||||
|
|
||||||
|
|
||||||
|
BS-X C emulator code
|
||||||
|
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||||
|
zones
|
||||||
|
|
||||||
|
C4 x86 assembler and some C emulation code
|
||||||
|
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||||
|
Nach,
|
||||||
|
zsKnight (zsknight@zsnes.com)
|
||||||
|
|
||||||
|
C4 C++ code
|
||||||
|
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||||
|
Nach
|
||||||
|
|
||||||
|
DSP-1 emulator code
|
||||||
|
(c) Copyright 1998 - 2006 _Demo_,
|
||||||
|
Andreas Naive (andreasnaive@gmail.com)
|
||||||
|
Gary Henderson,
|
||||||
|
Ivar (ivar@snes9x.com),
|
||||||
|
John Weidman,
|
||||||
|
Kris Bleakley,
|
||||||
|
Matthew Kendora,
|
||||||
|
Nach,
|
||||||
|
neviksti (neviksti@hotmail.com)
|
||||||
|
|
||||||
|
DSP-2 emulator code
|
||||||
|
(c) Copyright 2003 John Weidman,
|
||||||
|
Kris Bleakley,
|
||||||
|
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||||
|
Matthew Kendora,
|
||||||
|
neviksti
|
||||||
|
|
||||||
|
|
||||||
|
DSP-3 emulator code
|
||||||
|
(c) Copyright 2003 - 2006 John Weidman,
|
||||||
|
Kris Bleakley,
|
||||||
|
Lancer,
|
||||||
|
z80 gaiden
|
||||||
|
|
||||||
|
DSP-4 emulator code
|
||||||
|
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||||
|
John Weidman,
|
||||||
|
Kris Bleakley,
|
||||||
|
Nach,
|
||||||
|
z80 gaiden
|
||||||
|
|
||||||
|
OBC1 emulator code
|
||||||
|
(c) Copyright 2001 - 2004 zsKnight,
|
||||||
|
pagefault (pagefault@zsnes.com),
|
||||||
|
Kris Bleakley,
|
||||||
|
Ported from x86 assembler to C by sanmaiwashi
|
||||||
|
|
||||||
|
SPC7110 and RTC C++ emulator code
|
||||||
|
(c) Copyright 2002 Matthew Kendora with research by
|
||||||
|
zsKnight,
|
||||||
|
John Weidman,
|
||||||
|
Dark Force
|
||||||
|
|
||||||
|
S-DD1 C emulator code
|
||||||
|
(c) Copyright 2003 Brad Jorsch with research by
|
||||||
|
Andreas Naive,
|
||||||
|
John Weidman
|
||||||
|
|
||||||
|
S-RTC C emulator code
|
||||||
|
(c) Copyright 2001-2006 byuu,
|
||||||
|
John Weidman
|
||||||
|
|
||||||
|
ST010 C++ emulator code
|
||||||
|
(c) Copyright 2003 Feather,
|
||||||
|
John Weidman,
|
||||||
|
Kris Bleakley,
|
||||||
|
Matthew Kendora
|
||||||
|
|
||||||
|
Super FX x86 assembler emulator code
|
||||||
|
(c) Copyright 1998 - 2003 _Demo_,
|
||||||
|
pagefault,
|
||||||
|
zsKnight,
|
||||||
|
|
||||||
|
Super FX C emulator code
|
||||||
|
(c) Copyright 1997 - 1999 Ivar,
|
||||||
|
Gary Henderson,
|
||||||
|
John Weidman
|
||||||
|
|
||||||
|
Sound DSP emulator code is derived from SNEeSe and OpenSPC:
|
||||||
|
(c) Copyright 1998 - 2003 Brad Martin
|
||||||
|
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||||
|
|
||||||
|
SH assembler code partly based on x86 assembler code
|
||||||
|
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||||
|
|
||||||
|
2xSaI filter
|
||||||
|
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||||
|
|
||||||
|
HQ2x, HQ3x, HQ4x filters
|
||||||
|
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||||
|
|
||||||
|
Win32 GUI code
|
||||||
|
(c) Copyright 2003 - 2006 blip,
|
||||||
|
funkyass,
|
||||||
|
Matthew Kendora,
|
||||||
|
Nach,
|
||||||
|
nitsuja
|
||||||
|
|
||||||
|
Mac OS GUI code
|
||||||
|
(c) Copyright 1998 - 2001 John Stiles
|
||||||
|
(c) Copyright 2001 - 2007 zones
|
||||||
|
|
||||||
|
|
||||||
|
Specific ports contains the works of other authors. See headers in
|
||||||
|
individual files.
|
||||||
|
|
||||||
|
|
||||||
|
Snes9x homepage: http://www.snes9x.com
|
||||||
|
|
||||||
|
Permission to use, copy, modify and/or 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 or it's derivatives.
|
||||||
|
|
||||||
|
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||||
|
seek permission of the copyright holders first. Commercial use includes,
|
||||||
|
but is not limited to, charging money for Snes9x or software derived from
|
||||||
|
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||||
|
using Snes9x as a promotion for your commercial product.
|
||||||
|
|
||||||
|
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"
|
||||||
|
|
||||||
|
uint8 add32_32 [32][32] = {
|
||||||
|
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
|
||||||
|
0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,
|
||||||
|
0x1e,0x1f},
|
||||||
|
{ 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
|
||||||
|
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,
|
||||||
|
0x1f,0x1f},
|
||||||
|
{ 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,
|
||||||
|
0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
|
||||||
|
0x1f,0x1f},
|
||||||
|
{ 0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,
|
||||||
|
0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,
|
||||||
|
0x1f,0x1f},
|
||||||
|
{ 0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,
|
||||||
|
0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f},
|
||||||
|
{ 0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,
|
||||||
|
0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f},
|
||||||
|
{ 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,
|
||||||
|
0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f},
|
||||||
|
{ 0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,
|
||||||
|
0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f},
|
||||||
|
{ 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,
|
||||||
|
0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f},
|
||||||
|
{ 0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
|
||||||
|
0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f},
|
||||||
|
{ 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,
|
||||||
|
0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f},
|
||||||
|
{ 0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,
|
||||||
|
0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f},
|
||||||
|
{ 0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,
|
||||||
|
0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f},
|
||||||
|
{ 0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,
|
||||||
|
0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f},
|
||||||
|
{ 0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,
|
||||||
|
0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f},
|
||||||
|
{ 0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,
|
||||||
|
0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f},
|
||||||
|
{ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,
|
||||||
|
0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f},
|
||||||
|
{ 0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
|
||||||
|
0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f},
|
||||||
|
{ 0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,
|
||||||
|
0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f},
|
||||||
|
{ 0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f},
|
||||||
|
{ 0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f},
|
||||||
|
{ 0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f},
|
||||||
|
{ 0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f},
|
||||||
|
{ 0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f},
|
||||||
|
{ 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f},
|
||||||
|
{ 0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f},
|
||||||
|
{ 0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f},
|
||||||
|
{ 0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f},
|
||||||
|
{ 0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f},
|
||||||
|
{ 0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f},
|
||||||
|
{ 0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f},
|
||||||
|
{ 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
|
||||||
|
0x1f,0x1f}
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8 add32_32_half [32][32] = {
|
||||||
|
{ 0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,
|
||||||
|
0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,
|
||||||
|
0x0f,0x0f},
|
||||||
|
{ 0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,
|
||||||
|
0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,
|
||||||
|
0x0f,0x10},
|
||||||
|
{ 0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,
|
||||||
|
0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,
|
||||||
|
0x10,0x10},
|
||||||
|
{ 0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,
|
||||||
|
0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,
|
||||||
|
0x10,0x11},
|
||||||
|
{ 0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,
|
||||||
|
0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,
|
||||||
|
0x11,0x11},
|
||||||
|
{ 0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,
|
||||||
|
0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,
|
||||||
|
0x11,0x12},
|
||||||
|
{ 0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,
|
||||||
|
0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,
|
||||||
|
0x12,0x12},
|
||||||
|
{ 0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,
|
||||||
|
0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,
|
||||||
|
0x12,0x13},
|
||||||
|
{ 0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,
|
||||||
|
0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,
|
||||||
|
0x13,0x13},
|
||||||
|
{ 0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,
|
||||||
|
0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,
|
||||||
|
0x13,0x14},
|
||||||
|
{ 0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,
|
||||||
|
0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,
|
||||||
|
0x14,0x14},
|
||||||
|
{ 0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,
|
||||||
|
0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,
|
||||||
|
0x14,0x15},
|
||||||
|
{ 0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,
|
||||||
|
0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,
|
||||||
|
0x15,0x15},
|
||||||
|
{ 0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,
|
||||||
|
0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,
|
||||||
|
0x15,0x16},
|
||||||
|
{ 0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,
|
||||||
|
0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,
|
||||||
|
0x16,0x16},
|
||||||
|
{ 0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,
|
||||||
|
0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16,
|
||||||
|
0x16,0x17},
|
||||||
|
{ 0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,
|
||||||
|
0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16,0x16,
|
||||||
|
0x17,0x17},
|
||||||
|
{ 0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,
|
||||||
|
0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16,0x16,0x17,
|
||||||
|
0x17,0x18},
|
||||||
|
{ 0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,
|
||||||
|
0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16,0x16,0x17,0x17,
|
||||||
|
0x18,0x18},
|
||||||
|
{ 0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,
|
||||||
|
0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16,0x16,0x17,0x17,0x18,
|
||||||
|
0x18,0x19},
|
||||||
|
{ 0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,
|
||||||
|
0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16,0x16,0x17,0x17,0x18,0x18,
|
||||||
|
0x19,0x19},
|
||||||
|
{ 0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,
|
||||||
|
0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16,0x16,0x17,0x17,0x18,0x18,0x19,
|
||||||
|
0x19,0x1a},
|
||||||
|
{ 0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,
|
||||||
|
0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16,0x16,0x17,0x17,0x18,0x18,0x19,0x19,
|
||||||
|
0x1a,0x1a},
|
||||||
|
{ 0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,
|
||||||
|
0x13,0x13,0x14,0x14,0x15,0x15,0x16,0x16,0x17,0x17,0x18,0x18,0x19,0x19,0x1a,
|
||||||
|
0x1a,0x1b},
|
||||||
|
{ 0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,
|
||||||
|
0x13,0x14,0x14,0x15,0x15,0x16,0x16,0x17,0x17,0x18,0x18,0x19,0x19,0x1a,0x1a,
|
||||||
|
0x1b,0x1b},
|
||||||
|
{ 0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,
|
||||||
|
0x14,0x14,0x15,0x15,0x16,0x16,0x17,0x17,0x18,0x18,0x19,0x19,0x1a,0x1a,0x1b,
|
||||||
|
0x1b,0x1c},
|
||||||
|
{ 0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,
|
||||||
|
0x14,0x15,0x15,0x16,0x16,0x17,0x17,0x18,0x18,0x19,0x19,0x1a,0x1a,0x1b,0x1b,
|
||||||
|
0x1c,0x1c},
|
||||||
|
{ 0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,
|
||||||
|
0x15,0x15,0x16,0x16,0x17,0x17,0x18,0x18,0x19,0x19,0x1a,0x1a,0x1b,0x1b,0x1c,
|
||||||
|
0x1c,0x1d},
|
||||||
|
{ 0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,
|
||||||
|
0x15,0x16,0x16,0x17,0x17,0x18,0x18,0x19,0x19,0x1a,0x1a,0x1b,0x1b,0x1c,0x1c,
|
||||||
|
0x1d,0x1d},
|
||||||
|
{ 0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,
|
||||||
|
0x16,0x16,0x17,0x17,0x18,0x18,0x19,0x19,0x1a,0x1a,0x1b,0x1b,0x1c,0x1c,0x1d,
|
||||||
|
0x1d,0x1e},
|
||||||
|
{ 0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16,
|
||||||
|
0x16,0x17,0x17,0x18,0x18,0x19,0x19,0x1a,0x1a,0x1b,0x1b,0x1c,0x1c,0x1d,0x1d,
|
||||||
|
0x1e,0x1e},
|
||||||
|
{ 0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16,0x16,
|
||||||
|
0x17,0x17,0x18,0x18,0x19,0x19,0x1a,0x1a,0x1b,0x1b,0x1c,0x1c,0x1d,0x1d,0x1e,
|
||||||
|
0x1e,0x1f}
|
||||||
|
};
|
||||||
|
uint8 sub32_32 [32][32] = {
|
||||||
|
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
|
||||||
|
0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,
|
||||||
|
0x1e,0x1f},
|
||||||
|
{ 0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,
|
||||||
|
0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,
|
||||||
|
0x1d,0x1e},
|
||||||
|
{ 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
|
||||||
|
0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,
|
||||||
|
0x1c,0x1d},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,
|
||||||
|
0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,
|
||||||
|
0x1b,0x1c},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,
|
||||||
|
0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,
|
||||||
|
0x1a,0x1b},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
|
||||||
|
0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,
|
||||||
|
0x19,0x1a},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
|
||||||
|
0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
|
||||||
|
0x18,0x19},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
|
||||||
|
0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,
|
||||||
|
0x17,0x18},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,
|
||||||
|
0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,
|
||||||
|
0x16,0x17},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,
|
||||||
|
0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,
|
||||||
|
0x15,0x16},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,
|
||||||
|
0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,
|
||||||
|
0x14,0x15},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,
|
||||||
|
0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,
|
||||||
|
0x13,0x14},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,
|
||||||
|
0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,
|
||||||
|
0x12,0x13},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
|
||||||
|
0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,
|
||||||
|
0x11,0x12},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
|
||||||
|
0x10,0x11},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
|
||||||
|
0x0f,0x10},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,
|
||||||
|
0x0e,0x0f},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
|
||||||
|
0x0d,0x0e},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,
|
||||||
|
0x0c,0x0d},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,
|
||||||
|
0x0b,0x0c},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
|
||||||
|
0x0a,0x0b},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
|
||||||
|
0x09,0x0a},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
|
||||||
|
0x08,0x09},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,
|
||||||
|
0x07,0x08},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,
|
||||||
|
0x06,0x07},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,
|
||||||
|
0x05,0x06},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,
|
||||||
|
0x04,0x05},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,
|
||||||
|
0x03,0x04},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
|
||||||
|
0x02,0x03},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x01,0x02},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x01},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00}
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8 sub32_32_half [32][32] = {
|
||||||
|
{ 0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,
|
||||||
|
0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,
|
||||||
|
0x0f,0x0f},
|
||||||
|
{ 0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,
|
||||||
|
0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,
|
||||||
|
0x0e,0x0f},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,
|
||||||
|
0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,
|
||||||
|
0x0e,0x0e},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,
|
||||||
|
0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,
|
||||||
|
0x0d,0x0e},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,
|
||||||
|
0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,
|
||||||
|
0x0d,0x0d},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,
|
||||||
|
0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,
|
||||||
|
0x0c,0x0d},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,
|
||||||
|
0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,
|
||||||
|
0x0c,0x0c},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,
|
||||||
|
0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,
|
||||||
|
0x0b,0x0c},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,
|
||||||
|
0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,
|
||||||
|
0x0b,0x0b},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,
|
||||||
|
0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,
|
||||||
|
0x0a,0x0b},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,
|
||||||
|
0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,
|
||||||
|
0x0a,0x0a},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,
|
||||||
|
0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,
|
||||||
|
0x09,0x0a},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
|
||||||
|
0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,
|
||||||
|
0x09,0x09},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,
|
||||||
|
0x08,0x09},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,
|
||||||
|
0x08,0x08},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,
|
||||||
|
0x07,0x08},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,
|
||||||
|
0x07,0x07},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,
|
||||||
|
0x06,0x07},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,
|
||||||
|
0x06,0x06},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,
|
||||||
|
0x05,0x06},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,
|
||||||
|
0x05,0x05},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,
|
||||||
|
0x04,0x05},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,
|
||||||
|
0x04,0x04},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,
|
||||||
|
0x03,0x04},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,
|
||||||
|
0x03,0x03},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,
|
||||||
|
0x02,0x03},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,
|
||||||
|
0x02,0x02},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
|
||||||
|
0x01,0x02},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x01,0x01},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x01},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
uint8 mul_brightness [16][32] = {
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
|
||||||
|
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
|
||||||
|
0x02,0x02},
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x02,0x02,
|
||||||
|
0x02,0x02,0x02,0x02,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x04,0x04,0x04,
|
||||||
|
0x04,0x04},
|
||||||
|
{ 0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x02,0x02,0x02,0x02,0x03,0x03,
|
||||||
|
0x03,0x03,0x03,0x04,0x04,0x04,0x04,0x04,0x05,0x05,0x05,0x05,0x05,0x06,0x06,
|
||||||
|
0x06,0x06},
|
||||||
|
{ 0x00,0x00,0x01,0x01,0x01,0x01,0x02,0x02,0x02,0x02,0x03,0x03,0x03,0x03,0x04,
|
||||||
|
0x04,0x04,0x05,0x05,0x05,0x05,0x06,0x06,0x06,0x06,0x07,0x07,0x07,0x07,0x08,
|
||||||
|
0x08,0x08},
|
||||||
|
{ 0x00,0x00,0x01,0x01,0x01,0x02,0x02,0x02,0x03,0x03,0x03,0x04,0x04,0x04,0x05,
|
||||||
|
0x05,0x05,0x06,0x06,0x06,0x07,0x07,0x07,0x08,0x08,0x08,0x09,0x09,0x09,0x0a,
|
||||||
|
0x0a,0x0a},
|
||||||
|
{ 0x00,0x00,0x01,0x01,0x02,0x02,0x02,0x03,0x03,0x04,0x04,0x04,0x05,0x05,0x06,
|
||||||
|
0x06,0x06,0x07,0x07,0x08,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0a,0x0b,0x0b,0x0c,
|
||||||
|
0x0c,0x0c},
|
||||||
|
{ 0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,
|
||||||
|
0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,
|
||||||
|
0x0e,0x0e},
|
||||||
|
{ 0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,
|
||||||
|
0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,
|
||||||
|
0x10,0x11},
|
||||||
|
{ 0x00,0x01,0x01,0x02,0x02,0x03,0x04,0x04,0x05,0x05,0x06,0x07,0x07,0x08,0x08,
|
||||||
|
0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x10,0x10,0x11,0x11,
|
||||||
|
0x12,0x13},
|
||||||
|
{ 0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x05,0x05,0x06,0x07,0x07,0x08,0x09,0x09,
|
||||||
|
0x0a,0x0b,0x0b,0x0c,0x0d,0x0d,0x0e,0x0f,0x0f,0x10,0x11,0x11,0x12,0x13,0x13,
|
||||||
|
0x14,0x15},
|
||||||
|
{ 0x00,0x01,0x01,0x02,0x03,0x04,0x04,0x05,0x06,0x07,0x07,0x08,0x09,0x0a,0x0a,
|
||||||
|
0x0b,0x0c,0x0c,0x0d,0x0e,0x0f,0x0f,0x10,0x11,0x12,0x12,0x13,0x14,0x15,0x15,
|
||||||
|
0x16,0x17},
|
||||||
|
{ 0x00,0x01,0x02,0x02,0x03,0x04,0x05,0x06,0x06,0x07,0x08,0x09,0x0a,0x0a,0x0b,
|
||||||
|
0x0c,0x0d,0x0e,0x0e,0x0f,0x10,0x11,0x12,0x12,0x13,0x14,0x15,0x16,0x16,0x17,
|
||||||
|
0x18,0x19},
|
||||||
|
{ 0x00,0x01,0x02,0x03,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0a,0x0b,0x0c,
|
||||||
|
0x0d,0x0e,0x0f,0x10,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x17,0x18,0x19,
|
||||||
|
0x1a,0x1b},
|
||||||
|
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,
|
||||||
|
0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,
|
||||||
|
0x1c,0x1d},
|
||||||
|
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
|
||||||
|
0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,
|
||||||
|
0x1e,0x1f}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
@ -159,63 +159,65 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _DISPLAY_H_
|
#ifndef _DISPLAY_H_
|
||||||
#define _DISPLAY_H_
|
#define _DISPLAY_H_
|
||||||
|
|
||||||
enum s9x_getdirtype
|
START_EXTERN_C
|
||||||
{
|
// Routines the port specific code has to implement
|
||||||
DEFAULT_DIR = 0,
|
void S9xSetPalette ();
|
||||||
HOME_DIR,
|
void S9xTextMode ();
|
||||||
ROMFILENAME_DIR,
|
void S9xGraphicsMode ();
|
||||||
ROM_DIR,
|
void S9xParseArg (char **argv, int &index, int argc);
|
||||||
SRAM_DIR,
|
void S9xExtraUsage ();
|
||||||
SNAPSHOT_DIR,
|
|
||||||
SCREENSHOT_DIR,
|
void S9xLoadConfigFiles(char **argv, int argc);
|
||||||
SPC_DIR,
|
char *S9xParseArgs (char **argv, int argc);
|
||||||
|
void S9xUsage ();
|
||||||
|
void S9xInitDisplay (int argc, char **argv);
|
||||||
|
void S9xDeinitDisplay ();
|
||||||
|
void S9xInitInputDevices ();
|
||||||
|
void S9xSetTitle (const char *title);
|
||||||
|
void S9xProcessEvents (bool8 block);
|
||||||
|
void S9xPutImage (int width, int height);
|
||||||
|
void S9xParseDisplayArg (char **argv, int &index, int argc);
|
||||||
|
void S9xExtraDisplayUsage ();
|
||||||
|
void S9xToggleSoundChannel (int channel);
|
||||||
|
void S9xSetInfoString (const char *string);
|
||||||
|
int S9xMinCommandLineArgs ();
|
||||||
|
void S9xNextController ();
|
||||||
|
bool8 S9xLoadROMImage (const char *string);
|
||||||
|
const char *S9xSelectFilename (const char *def, const char *dir,
|
||||||
|
const char *ext, const char *title);
|
||||||
|
const char *S9xStringInput(const char *message);
|
||||||
|
const char *S9xChooseFilename (bool8 read_only);
|
||||||
|
bool8 S9xOpenSnapshotFile (const char *base, bool8 read_only, STREAM *file);
|
||||||
|
void S9xCloseSnapshotFile (STREAM file);
|
||||||
|
|
||||||
|
const char *S9xBasename (const char *filename);
|
||||||
|
|
||||||
|
int S9xFStrcmp (FILE *, const char *);
|
||||||
|
|
||||||
|
enum s9x_getdirtype {
|
||||||
|
DEFAULT_DIR,
|
||||||
|
HOME_DIR,
|
||||||
|
ROM_DIR,
|
||||||
|
ROMFILENAME_DIR,
|
||||||
|
SNAPSHOT_DIR,
|
||||||
|
SRAM_DIR,
|
||||||
|
SCREENSHOT_DIR,
|
||||||
|
SPC_DIR,
|
||||||
|
PATCH_DIR,
|
||||||
CHEAT_DIR,
|
CHEAT_DIR,
|
||||||
IPS_DIR,
|
PACK_DIR,
|
||||||
BIOS_DIR,
|
BIOS_DIR,
|
||||||
LOG_DIR,
|
LOG_DIR
|
||||||
LAST_DIR
|
|
||||||
};
|
};
|
||||||
|
const char *S9xGetDirectory (enum s9x_getdirtype dirtype);
|
||||||
void S9xUsage (void);
|
const char *S9xGetFilename (const char *extension, enum s9x_getdirtype dirtype);
|
||||||
char * S9xParseArgs (char **, int);
|
const char *S9xGetFilenameInc (const char *, enum s9x_getdirtype);
|
||||||
void S9xLoadConfigFiles (char **, int);
|
END_EXTERN_C
|
||||||
void S9xSetInfoString (const char *);
|
|
||||||
|
|
||||||
// Routines the port has to implement even if it doesn't use them
|
|
||||||
|
|
||||||
void S9xTextMode (void);
|
|
||||||
void S9xGraphicsMode (void);
|
|
||||||
void S9xSetPalette (void);
|
|
||||||
void S9xToggleSoundChannel (int);
|
|
||||||
bool8 S9xOpenSnapshotFile (const char *, bool8, STREAM *);
|
|
||||||
void S9xCloseSnapshotFile (STREAM);
|
|
||||||
const char * S9xStringInput (const char *);
|
|
||||||
const char * S9xGetDirectory (enum s9x_getdirtype);
|
|
||||||
const char * S9xGetFilename (const char *, enum s9x_getdirtype);
|
|
||||||
const char * S9xGetFilenameInc (const char *, enum s9x_getdirtype);
|
|
||||||
const char * S9xChooseFilename (bool8);
|
|
||||||
const char * S9xBasename (const char *);
|
|
||||||
|
|
||||||
// Routines the port has to implement if it uses command-line
|
|
||||||
|
|
||||||
void S9xExtraUsage (void);
|
|
||||||
void S9xParseArg (char **, int &, int);
|
|
||||||
|
|
||||||
// Routines the port may implement as needed
|
|
||||||
|
|
||||||
void S9xExtraDisplayUsage (void);
|
|
||||||
void S9xParseDisplayArg (char **, int &, int);
|
|
||||||
int S9xMinCommandLineArgs (void);
|
|
||||||
void S9xSetTitle (const char *);
|
|
||||||
void S9xInitDisplay (int, char **);
|
|
||||||
void S9xDeinitDisplay (void);
|
|
||||||
void S9xPutImage (int, int);
|
|
||||||
void S9xInitInputDevices (void);
|
|
||||||
void S9xProcessEvents (bool8);
|
|
||||||
bool8 S9xLoadROMImage (const char *);
|
|
||||||
const char * S9xSelectFilename (const char *, const char *, const char *, const char *);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -159,37 +159,17 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _DMA_H_
|
#ifndef _DMA_H_
|
||||||
#define _DMA_H_
|
#define _DMA_H_
|
||||||
|
|
||||||
struct SDMA
|
START_EXTERN_C
|
||||||
{
|
void S9xResetDMA ();
|
||||||
bool8 ReverseTransfer;
|
|
||||||
bool8 HDMAIndirectAddressing;
|
|
||||||
bool8 UnusedBit43x0;
|
|
||||||
bool8 AAddressFixed;
|
|
||||||
bool8 AAddressDecrement;
|
|
||||||
uint8 TransferMode;
|
|
||||||
uint8 BAddress;
|
|
||||||
uint16 AAddress;
|
|
||||||
uint8 ABank;
|
|
||||||
uint16 DMACount_Or_HDMAIndirectAddress;
|
|
||||||
uint8 IndirectBank;
|
|
||||||
uint16 Address;
|
|
||||||
uint8 Repeat;
|
|
||||||
uint8 LineCount;
|
|
||||||
uint8 UnknownByte;
|
|
||||||
uint8 DoTransfer;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define TransferBytes DMACount_Or_HDMAIndirectAddress
|
|
||||||
#define IndirectAddress DMACount_Or_HDMAIndirectAddress
|
|
||||||
|
|
||||||
extern struct SDMA DMA[8];
|
|
||||||
|
|
||||||
bool8 S9xDoDMA (uint8);
|
|
||||||
void S9xStartHDMA (void);
|
|
||||||
uint8 S9xDoHDMA (uint8);
|
uint8 S9xDoHDMA (uint8);
|
||||||
void S9xResetDMA (void);
|
void S9xStartHDMA ();
|
||||||
|
bool8 S9xDoDMA (uint8);
|
||||||
|
END_EXTERN_C
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1,602 +0,0 @@
|
|||||||
/**********************************************************************************
|
|
||||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
|
||||||
|
|
||||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
|
||||||
Jerremy Koot (jkoot@snes9x.com)
|
|
||||||
|
|
||||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
|
||||||
|
|
||||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
|
||||||
|
|
||||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
|
||||||
|
|
||||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
|
||||||
|
|
||||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
|
||||||
Kris Bleakley (codeviolation@hotmail.com)
|
|
||||||
|
|
||||||
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
|
|
||||||
Nach (n-a-c-h@users.sourceforge.net),
|
|
||||||
zones (kasumitokoduck@yahoo.com)
|
|
||||||
|
|
||||||
(c) Copyright 2006 - 2007 nitsuja
|
|
||||||
|
|
||||||
|
|
||||||
BS-X C emulator code
|
|
||||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
|
||||||
zones
|
|
||||||
|
|
||||||
C4 x86 assembler and some C emulation code
|
|
||||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
|
||||||
Nach,
|
|
||||||
zsKnight (zsknight@zsnes.com)
|
|
||||||
|
|
||||||
C4 C++ code
|
|
||||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
|
||||||
Nach
|
|
||||||
|
|
||||||
DSP-1 emulator code
|
|
||||||
(c) Copyright 1998 - 2006 _Demo_,
|
|
||||||
Andreas Naive (andreasnaive@gmail.com)
|
|
||||||
Gary Henderson,
|
|
||||||
Ivar (ivar@snes9x.com),
|
|
||||||
John Weidman,
|
|
||||||
Kris Bleakley,
|
|
||||||
Matthew Kendora,
|
|
||||||
Nach,
|
|
||||||
neviksti (neviksti@hotmail.com)
|
|
||||||
|
|
||||||
DSP-2 emulator code
|
|
||||||
(c) Copyright 2003 John Weidman,
|
|
||||||
Kris Bleakley,
|
|
||||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
|
||||||
Matthew Kendora,
|
|
||||||
neviksti
|
|
||||||
|
|
||||||
|
|
||||||
DSP-3 emulator code
|
|
||||||
(c) Copyright 2003 - 2006 John Weidman,
|
|
||||||
Kris Bleakley,
|
|
||||||
Lancer,
|
|
||||||
z80 gaiden
|
|
||||||
|
|
||||||
DSP-4 emulator code
|
|
||||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
|
||||||
John Weidman,
|
|
||||||
Kris Bleakley,
|
|
||||||
Nach,
|
|
||||||
z80 gaiden
|
|
||||||
|
|
||||||
OBC1 emulator code
|
|
||||||
(c) Copyright 2001 - 2004 zsKnight,
|
|
||||||
pagefault (pagefault@zsnes.com),
|
|
||||||
Kris Bleakley,
|
|
||||||
Ported from x86 assembler to C by sanmaiwashi
|
|
||||||
|
|
||||||
SPC7110 and RTC C++ emulator code
|
|
||||||
(c) Copyright 2002 Matthew Kendora with research by
|
|
||||||
zsKnight,
|
|
||||||
John Weidman,
|
|
||||||
Dark Force
|
|
||||||
|
|
||||||
S-DD1 C emulator code
|
|
||||||
(c) Copyright 2003 Brad Jorsch with research by
|
|
||||||
Andreas Naive,
|
|
||||||
John Weidman
|
|
||||||
|
|
||||||
S-RTC C emulator code
|
|
||||||
(c) Copyright 2001-2006 byuu,
|
|
||||||
John Weidman
|
|
||||||
|
|
||||||
ST010 C++ emulator code
|
|
||||||
(c) Copyright 2003 Feather,
|
|
||||||
John Weidman,
|
|
||||||
Kris Bleakley,
|
|
||||||
Matthew Kendora
|
|
||||||
|
|
||||||
Super FX x86 assembler emulator code
|
|
||||||
(c) Copyright 1998 - 2003 _Demo_,
|
|
||||||
pagefault,
|
|
||||||
zsKnight,
|
|
||||||
|
|
||||||
Super FX C emulator code
|
|
||||||
(c) Copyright 1997 - 1999 Ivar,
|
|
||||||
Gary Henderson,
|
|
||||||
John Weidman
|
|
||||||
|
|
||||||
Sound DSP emulator code is derived from SNEeSe and OpenSPC:
|
|
||||||
(c) Copyright 1998 - 2003 Brad Martin
|
|
||||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
|
||||||
|
|
||||||
SH assembler code partly based on x86 assembler code
|
|
||||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
|
||||||
|
|
||||||
2xSaI filter
|
|
||||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
|
||||||
|
|
||||||
HQ2x, HQ3x, HQ4x filters
|
|
||||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
|
||||||
|
|
||||||
Win32 GUI code
|
|
||||||
(c) Copyright 2003 - 2006 blip,
|
|
||||||
funkyass,
|
|
||||||
Matthew Kendora,
|
|
||||||
Nach,
|
|
||||||
nitsuja
|
|
||||||
|
|
||||||
Mac OS GUI code
|
|
||||||
(c) Copyright 1998 - 2001 John Stiles
|
|
||||||
(c) Copyright 2001 - 2007 zones
|
|
||||||
|
|
||||||
|
|
||||||
Specific ports contains the works of other authors. See headers in
|
|
||||||
individual files.
|
|
||||||
|
|
||||||
|
|
||||||
Snes9x homepage: http://www.snes9x.com
|
|
||||||
|
|
||||||
Permission to use, copy, modify and/or 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 or it's derivatives.
|
|
||||||
|
|
||||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
|
||||||
seek permission of the copyright holders first. Commercial use includes,
|
|
||||||
but is not limited to, charging money for Snes9x or software derived from
|
|
||||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
|
||||||
using Snes9x as a promotion for your commercial product.
|
|
||||||
|
|
||||||
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 _DSP1_H_
|
|
||||||
#define _DSP1_H_
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
M_DSP1_LOROM_S,
|
|
||||||
M_DSP1_LOROM_L,
|
|
||||||
M_DSP1_HIROM,
|
|
||||||
M_DSP2_LOROM,
|
|
||||||
M_DSP3_LOROM,
|
|
||||||
M_DSP4_LOROM
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SDSP0
|
|
||||||
{
|
|
||||||
uint32 maptype;
|
|
||||||
uint32 boundary;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SDSP1
|
|
||||||
{
|
|
||||||
bool8 waiting4command;
|
|
||||||
bool8 first_parameter;
|
|
||||||
uint8 command;
|
|
||||||
uint32 in_count;
|
|
||||||
uint32 in_index;
|
|
||||||
uint32 out_count;
|
|
||||||
uint32 out_index;
|
|
||||||
uint8 parameters[512];
|
|
||||||
uint8 output[512];
|
|
||||||
|
|
||||||
int16 CentreX;
|
|
||||||
int16 CentreY;
|
|
||||||
int16 VOffset;
|
|
||||||
|
|
||||||
int16 VPlane_C;
|
|
||||||
int16 VPlane_E;
|
|
||||||
|
|
||||||
// Azimuth and Zenith angles
|
|
||||||
int16 SinAas;
|
|
||||||
int16 CosAas;
|
|
||||||
int16 SinAzs;
|
|
||||||
int16 CosAzs;
|
|
||||||
|
|
||||||
// Clipped Zenith angle
|
|
||||||
int16 SinAZS;
|
|
||||||
int16 CosAZS;
|
|
||||||
int16 SecAZS_C1;
|
|
||||||
int16 SecAZS_E1;
|
|
||||||
int16 SecAZS_C2;
|
|
||||||
int16 SecAZS_E2;
|
|
||||||
|
|
||||||
int16 Nx;
|
|
||||||
int16 Ny;
|
|
||||||
int16 Nz;
|
|
||||||
int16 Gx;
|
|
||||||
int16 Gy;
|
|
||||||
int16 Gz;
|
|
||||||
int16 C_Les;
|
|
||||||
int16 E_Les;
|
|
||||||
int16 G_Les;
|
|
||||||
|
|
||||||
int16 matrixA[3][3];
|
|
||||||
int16 matrixB[3][3];
|
|
||||||
int16 matrixC[3][3];
|
|
||||||
|
|
||||||
int16 Op00Multiplicand;
|
|
||||||
int16 Op00Multiplier;
|
|
||||||
int16 Op00Result;
|
|
||||||
|
|
||||||
int16 Op20Multiplicand;
|
|
||||||
int16 Op20Multiplier;
|
|
||||||
int16 Op20Result;
|
|
||||||
|
|
||||||
int16 Op10Coefficient;
|
|
||||||
int16 Op10Exponent;
|
|
||||||
int16 Op10CoefficientR;
|
|
||||||
int16 Op10ExponentR;
|
|
||||||
|
|
||||||
int16 Op04Angle;
|
|
||||||
int16 Op04Radius;
|
|
||||||
int16 Op04Sin;
|
|
||||||
int16 Op04Cos;
|
|
||||||
|
|
||||||
int16 Op0CA;
|
|
||||||
int16 Op0CX1;
|
|
||||||
int16 Op0CY1;
|
|
||||||
int16 Op0CX2;
|
|
||||||
int16 Op0CY2;
|
|
||||||
|
|
||||||
int16 Op02FX;
|
|
||||||
int16 Op02FY;
|
|
||||||
int16 Op02FZ;
|
|
||||||
int16 Op02LFE;
|
|
||||||
int16 Op02LES;
|
|
||||||
int16 Op02AAS;
|
|
||||||
int16 Op02AZS;
|
|
||||||
int16 Op02VOF;
|
|
||||||
int16 Op02VVA;
|
|
||||||
int16 Op02CX;
|
|
||||||
int16 Op02CY;
|
|
||||||
|
|
||||||
int16 Op0AVS;
|
|
||||||
int16 Op0AA;
|
|
||||||
int16 Op0AB;
|
|
||||||
int16 Op0AC;
|
|
||||||
int16 Op0AD;
|
|
||||||
|
|
||||||
int16 Op06X;
|
|
||||||
int16 Op06Y;
|
|
||||||
int16 Op06Z;
|
|
||||||
int16 Op06H;
|
|
||||||
int16 Op06V;
|
|
||||||
int16 Op06M;
|
|
||||||
|
|
||||||
int16 Op01m;
|
|
||||||
int16 Op01Zr;
|
|
||||||
int16 Op01Xr;
|
|
||||||
int16 Op01Yr;
|
|
||||||
|
|
||||||
int16 Op11m;
|
|
||||||
int16 Op11Zr;
|
|
||||||
int16 Op11Xr;
|
|
||||||
int16 Op11Yr;
|
|
||||||
|
|
||||||
int16 Op21m;
|
|
||||||
int16 Op21Zr;
|
|
||||||
int16 Op21Xr;
|
|
||||||
int16 Op21Yr;
|
|
||||||
|
|
||||||
int16 Op0DX;
|
|
||||||
int16 Op0DY;
|
|
||||||
int16 Op0DZ;
|
|
||||||
int16 Op0DF;
|
|
||||||
int16 Op0DL;
|
|
||||||
int16 Op0DU;
|
|
||||||
|
|
||||||
int16 Op1DX;
|
|
||||||
int16 Op1DY;
|
|
||||||
int16 Op1DZ;
|
|
||||||
int16 Op1DF;
|
|
||||||
int16 Op1DL;
|
|
||||||
int16 Op1DU;
|
|
||||||
|
|
||||||
int16 Op2DX;
|
|
||||||
int16 Op2DY;
|
|
||||||
int16 Op2DZ;
|
|
||||||
int16 Op2DF;
|
|
||||||
int16 Op2DL;
|
|
||||||
int16 Op2DU;
|
|
||||||
|
|
||||||
int16 Op03F;
|
|
||||||
int16 Op03L;
|
|
||||||
int16 Op03U;
|
|
||||||
int16 Op03X;
|
|
||||||
int16 Op03Y;
|
|
||||||
int16 Op03Z;
|
|
||||||
|
|
||||||
int16 Op13F;
|
|
||||||
int16 Op13L;
|
|
||||||
int16 Op13U;
|
|
||||||
int16 Op13X;
|
|
||||||
int16 Op13Y;
|
|
||||||
int16 Op13Z;
|
|
||||||
|
|
||||||
int16 Op23F;
|
|
||||||
int16 Op23L;
|
|
||||||
int16 Op23U;
|
|
||||||
int16 Op23X;
|
|
||||||
int16 Op23Y;
|
|
||||||
int16 Op23Z;
|
|
||||||
|
|
||||||
int16 Op14Zr;
|
|
||||||
int16 Op14Xr;
|
|
||||||
int16 Op14Yr;
|
|
||||||
int16 Op14U;
|
|
||||||
int16 Op14F;
|
|
||||||
int16 Op14L;
|
|
||||||
int16 Op14Zrr;
|
|
||||||
int16 Op14Xrr;
|
|
||||||
int16 Op14Yrr;
|
|
||||||
|
|
||||||
int16 Op0EH;
|
|
||||||
int16 Op0EV;
|
|
||||||
int16 Op0EX;
|
|
||||||
int16 Op0EY;
|
|
||||||
|
|
||||||
int16 Op0BX;
|
|
||||||
int16 Op0BY;
|
|
||||||
int16 Op0BZ;
|
|
||||||
int16 Op0BS;
|
|
||||||
|
|
||||||
int16 Op1BX;
|
|
||||||
int16 Op1BY;
|
|
||||||
int16 Op1BZ;
|
|
||||||
int16 Op1BS;
|
|
||||||
|
|
||||||
int16 Op2BX;
|
|
||||||
int16 Op2BY;
|
|
||||||
int16 Op2BZ;
|
|
||||||
int16 Op2BS;
|
|
||||||
|
|
||||||
int16 Op28X;
|
|
||||||
int16 Op28Y;
|
|
||||||
int16 Op28Z;
|
|
||||||
int16 Op28R;
|
|
||||||
|
|
||||||
int16 Op1CX;
|
|
||||||
int16 Op1CY;
|
|
||||||
int16 Op1CZ;
|
|
||||||
int16 Op1CXBR;
|
|
||||||
int16 Op1CYBR;
|
|
||||||
int16 Op1CZBR;
|
|
||||||
int16 Op1CXAR;
|
|
||||||
int16 Op1CYAR;
|
|
||||||
int16 Op1CZAR;
|
|
||||||
int16 Op1CX1;
|
|
||||||
int16 Op1CY1;
|
|
||||||
int16 Op1CZ1;
|
|
||||||
int16 Op1CX2;
|
|
||||||
int16 Op1CY2;
|
|
||||||
int16 Op1CZ2;
|
|
||||||
|
|
||||||
uint16 Op0FRamsize;
|
|
||||||
uint16 Op0FPass;
|
|
||||||
|
|
||||||
int16 Op2FUnknown;
|
|
||||||
int16 Op2FSize;
|
|
||||||
|
|
||||||
int16 Op08X;
|
|
||||||
int16 Op08Y;
|
|
||||||
int16 Op08Z;
|
|
||||||
int16 Op08Ll;
|
|
||||||
int16 Op08Lh;
|
|
||||||
|
|
||||||
int16 Op18X;
|
|
||||||
int16 Op18Y;
|
|
||||||
int16 Op18Z;
|
|
||||||
int16 Op18R;
|
|
||||||
int16 Op18D;
|
|
||||||
|
|
||||||
int16 Op38X;
|
|
||||||
int16 Op38Y;
|
|
||||||
int16 Op38Z;
|
|
||||||
int16 Op38R;
|
|
||||||
int16 Op38D;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SDSP2
|
|
||||||
{
|
|
||||||
bool8 waiting4command;
|
|
||||||
uint8 command;
|
|
||||||
uint32 in_count;
|
|
||||||
uint32 in_index;
|
|
||||||
uint32 out_count;
|
|
||||||
uint32 out_index;
|
|
||||||
uint8 parameters[512];
|
|
||||||
uint8 output[512];
|
|
||||||
|
|
||||||
bool8 Op05HasLen;
|
|
||||||
int32 Op05Len;
|
|
||||||
uint8 Op05Transparent;
|
|
||||||
|
|
||||||
bool8 Op06HasLen;
|
|
||||||
int32 Op06Len;
|
|
||||||
|
|
||||||
uint16 Op09Word1;
|
|
||||||
uint16 Op09Word2;
|
|
||||||
|
|
||||||
bool8 Op0DHasLen;
|
|
||||||
int32 Op0DOutLen;
|
|
||||||
int32 Op0DInLen;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SDSP3
|
|
||||||
{
|
|
||||||
uint16 DR;
|
|
||||||
uint16 SR;
|
|
||||||
uint16 MemoryIndex;
|
|
||||||
|
|
||||||
int16 WinLo;
|
|
||||||
int16 WinHi;
|
|
||||||
int16 AddLo;
|
|
||||||
int16 AddHi;
|
|
||||||
|
|
||||||
uint16 Codewords;
|
|
||||||
uint16 Outwords;
|
|
||||||
uint16 Symbol;
|
|
||||||
uint16 BitCount;
|
|
||||||
uint16 Index;
|
|
||||||
uint16 Codes[512];
|
|
||||||
uint16 BitsLeft;
|
|
||||||
uint16 ReqBits;
|
|
||||||
uint16 ReqData;
|
|
||||||
uint16 BitCommand;
|
|
||||||
uint8 BaseLength;
|
|
||||||
uint16 BaseCodes;
|
|
||||||
uint16 BaseCode;
|
|
||||||
uint8 CodeLengths[8];
|
|
||||||
uint16 CodeOffsets[8];
|
|
||||||
uint16 LZCode;
|
|
||||||
uint8 LZLength;
|
|
||||||
|
|
||||||
uint16 X;
|
|
||||||
uint16 Y;
|
|
||||||
|
|
||||||
uint8 Bitmap[8];
|
|
||||||
uint8 Bitplane[8];
|
|
||||||
uint16 BMIndex;
|
|
||||||
uint16 BPIndex;
|
|
||||||
uint16 Count;
|
|
||||||
|
|
||||||
int16 op3e_x;
|
|
||||||
int16 op3e_y;
|
|
||||||
|
|
||||||
int16 op1e_terrain[0x2000];
|
|
||||||
int16 op1e_cost[0x2000];
|
|
||||||
int16 op1e_weight[0x2000];
|
|
||||||
|
|
||||||
int16 op1e_cell;
|
|
||||||
int16 op1e_turn;
|
|
||||||
int16 op1e_search;
|
|
||||||
|
|
||||||
int16 op1e_x;
|
|
||||||
int16 op1e_y;
|
|
||||||
|
|
||||||
int16 op1e_min_radius;
|
|
||||||
int16 op1e_max_radius;
|
|
||||||
|
|
||||||
int16 op1e_max_search_radius;
|
|
||||||
int16 op1e_max_path_radius;
|
|
||||||
|
|
||||||
int16 op1e_lcv_radius;
|
|
||||||
int16 op1e_lcv_steps;
|
|
||||||
int16 op1e_lcv_turns;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SDSP4
|
|
||||||
{
|
|
||||||
bool8 waiting4command;
|
|
||||||
bool8 half_command;
|
|
||||||
uint16 command;
|
|
||||||
uint32 in_count;
|
|
||||||
uint32 in_index;
|
|
||||||
uint32 out_count;
|
|
||||||
uint32 out_index;
|
|
||||||
uint8 parameters[512];
|
|
||||||
uint8 output[512];
|
|
||||||
uint8 byte;
|
|
||||||
uint16 address;
|
|
||||||
|
|
||||||
// op control
|
|
||||||
int8 Logic; // controls op flow
|
|
||||||
|
|
||||||
// projection format
|
|
||||||
int16 lcv; // loop-control variable
|
|
||||||
int16 distance; // z-position into virtual world
|
|
||||||
int16 raster; // current raster line
|
|
||||||
int16 segments; // number of raster lines drawn
|
|
||||||
|
|
||||||
// 1.15.16 or 1.15.0 [sign, integer, fraction]
|
|
||||||
int32 world_x; // line of x-projection in world
|
|
||||||
int32 world_y; // line of y-projection in world
|
|
||||||
int32 world_dx; // projection line x-delta
|
|
||||||
int32 world_dy; // projection line y-delta
|
|
||||||
int16 world_ddx; // x-delta increment
|
|
||||||
int16 world_ddy; // y-delta increment
|
|
||||||
int32 world_xenv; // world x-shaping factor
|
|
||||||
int16 world_yofs; // world y-vertical scroll
|
|
||||||
int16 view_x1; // current viewer-x
|
|
||||||
int16 view_y1; // current viewer-y
|
|
||||||
int16 view_x2; // future viewer-x
|
|
||||||
int16 view_y2; // future viewer-y
|
|
||||||
int16 view_dx; // view x-delta factor
|
|
||||||
int16 view_dy; // view y-delta factor
|
|
||||||
int16 view_xofs1; // current viewer x-vertical scroll
|
|
||||||
int16 view_yofs1; // current viewer y-vertical scroll
|
|
||||||
int16 view_xofs2; // future viewer x-vertical scroll
|
|
||||||
int16 view_yofs2; // future viewer y-vertical scroll
|
|
||||||
int16 view_yofsenv; // y-scroll shaping factor
|
|
||||||
int16 view_turnoff_x; // road turnoff data
|
|
||||||
int16 view_turnoff_dx; // road turnoff delta factor
|
|
||||||
|
|
||||||
// drawing area
|
|
||||||
int16 viewport_cx; // x-center of viewport window
|
|
||||||
int16 viewport_cy; // y-center of render window
|
|
||||||
int16 viewport_left; // x-left of viewport
|
|
||||||
int16 viewport_right; // x-right of viewport
|
|
||||||
int16 viewport_top; // y-top of viewport
|
|
||||||
int16 viewport_bottom; // y-bottom of viewport
|
|
||||||
|
|
||||||
// sprite structure
|
|
||||||
int16 sprite_x; // projected x-pos of sprite
|
|
||||||
int16 sprite_y; // projected y-pos of sprite
|
|
||||||
int16 sprite_attr; // obj attributes
|
|
||||||
bool8 sprite_size; // sprite size: 8x8 or 16x16
|
|
||||||
int16 sprite_clipy; // visible line to clip pixels off
|
|
||||||
int16 sprite_count;
|
|
||||||
|
|
||||||
// generic projection variables designed for two solid polygons + two polygon sides
|
|
||||||
int16 poly_clipLf[2][2]; // left clip boundary
|
|
||||||
int16 poly_clipRt[2][2]; // right clip boundary
|
|
||||||
int16 poly_ptr[2][2]; // HDMA structure pointers
|
|
||||||
int16 poly_raster[2][2]; // current raster line below horizon
|
|
||||||
int16 poly_top[2][2]; // top clip boundary
|
|
||||||
int16 poly_bottom[2][2]; // bottom clip boundary
|
|
||||||
int16 poly_cx[2][2]; // center for left/right points
|
|
||||||
int16 poly_start[2]; // current projection points
|
|
||||||
int16 poly_plane[2]; // previous z-plane distance
|
|
||||||
|
|
||||||
// OAM
|
|
||||||
int16 OAM_attr[16]; // OAM (size, MSB) data
|
|
||||||
int16 OAM_index; // index into OAM table
|
|
||||||
int16 OAM_bits; // offset into OAM table
|
|
||||||
int16 OAM_RowMax; // maximum number of tiles per 8 aligned pixels (row)
|
|
||||||
int16 OAM_Row[32]; // current number of tiles per row
|
|
||||||
};
|
|
||||||
|
|
||||||
extern struct SDSP0 DSP0;
|
|
||||||
extern struct SDSP1 DSP1;
|
|
||||||
extern struct SDSP2 DSP2;
|
|
||||||
extern struct SDSP3 DSP3;
|
|
||||||
extern struct SDSP4 DSP4;
|
|
||||||
|
|
||||||
uint8 S9xGetDSP (uint16);
|
|
||||||
void S9xSetDSP (uint8, uint16);
|
|
||||||
void S9xResetDSP (void);
|
|
||||||
uint8 DSP1GetByte (uint16);
|
|
||||||
void DSP1SetByte (uint8, uint16);
|
|
||||||
uint8 DSP2GetByte (uint16);
|
|
||||||
void DSP2SetByte (uint8, uint16);
|
|
||||||
uint8 DSP3GetByte (uint16);
|
|
||||||
void DSP3SetByte (uint8, uint16);
|
|
||||||
uint8 DSP4GetByte (uint16);
|
|
||||||
void DSP4SetByte (uint8, uint16);
|
|
||||||
void DSP3_Reset (void);
|
|
||||||
|
|
||||||
extern uint8 (*GetDSP) (uint16);
|
|
||||||
extern void (*SetDSP) (uint8, uint16);
|
|
||||||
|
|
||||||
#endif
|
|
File diff suppressed because it is too large
Load Diff
@ -159,54 +159,64 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _READER_H_
|
|
||||||
#define _READER_H_
|
|
||||||
|
|
||||||
class Reader
|
|
||||||
|
#ifndef _DSP1_H_
|
||||||
|
#define _DSP1_H_
|
||||||
|
|
||||||
|
extern void (*SetDSP)(uint8, uint16);
|
||||||
|
extern uint8 (*GetDSP)(uint16);
|
||||||
|
|
||||||
|
void DSP1SetByte(uint8 byte, uint16 address);
|
||||||
|
uint8 DSP1GetByte(uint16 address);
|
||||||
|
|
||||||
|
void DSP2SetByte(uint8 byte, uint16 address);
|
||||||
|
uint8 DSP2GetByte(uint16 address);
|
||||||
|
|
||||||
|
void DSP3SetByte(uint8 byte, uint16 address);
|
||||||
|
uint8 DSP3GetByte(uint16 address);
|
||||||
|
void DSP3_Reset();
|
||||||
|
|
||||||
|
void DSP4SetByte(uint8 byte, uint16 address);
|
||||||
|
uint8 DSP4GetByte(uint16 address);
|
||||||
|
|
||||||
|
enum
|
||||||
{
|
{
|
||||||
public:
|
M_DSP1_LOROM_S,
|
||||||
Reader (void);
|
M_DSP1_LOROM_L,
|
||||||
virtual ~Reader (void);
|
M_DSP1_HIROM,
|
||||||
virtual int get_char (void) = 0;
|
M_DSP2_LOROM,
|
||||||
virtual char * gets (char *, size_t) = 0;
|
M_DSP3_LOROM,
|
||||||
virtual char * getline (void); // free() when done
|
M_DSP4_LOROM
|
||||||
virtual std::string getline (bool &);
|
|
||||||
virtual size_t read (char *, size_t) = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class fReader : public Reader
|
struct SDSP1 {
|
||||||
{
|
uint8 version;
|
||||||
public:
|
bool8 waiting4command;
|
||||||
fReader (STREAM);
|
bool8 first_parameter;
|
||||||
virtual ~fReader (void);
|
uint8 command;
|
||||||
virtual int get_char (void);
|
uint32 in_count;
|
||||||
virtual char * gets (char *, size_t);
|
uint32 in_index;
|
||||||
virtual size_t read (char *, size_t);
|
uint32 out_count;
|
||||||
|
uint32 out_index;
|
||||||
|
uint8 parameters [512];
|
||||||
|
uint8 output [512];
|
||||||
|
|
||||||
private:
|
uint8 temp_save_data [406];
|
||||||
STREAM fp;
|
uint32 maptype;
|
||||||
|
uint32 boundary;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef UNZIP_SUPPORT
|
START_EXTERN_C
|
||||||
|
void S9xResetDSP1 ();
|
||||||
|
uint8 S9xGetDSP (uint16 Address);
|
||||||
|
void S9xSetDSP (uint8 Byte, uint16 Address);
|
||||||
|
void S9xPreSaveDSP1();
|
||||||
|
void S9xPostLoadDSP1();
|
||||||
|
|
||||||
#define unz_BUFFSIZ 1024
|
extern struct SDSP1 DSP1;
|
||||||
|
|
||||||
class unzReader : public Reader
|
END_EXTERN_C
|
||||||
{
|
|
||||||
public:
|
|
||||||
unzReader (unzFile &);
|
|
||||||
virtual ~unzReader (void);
|
|
||||||
virtual int get_char (void);
|
|
||||||
virtual char * gets (char *, size_t);
|
|
||||||
virtual size_t read (char *, size_t);
|
|
||||||
|
|
||||||
private:
|
|
||||||
unzFile file;
|
|
||||||
char buffer[unz_BUFFSIZ];
|
|
||||||
char *head;
|
|
||||||
size_t numbytes;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
1394
source/snes9x/dsp1emu.c.inc
Normal file
1394
source/snes9x/dsp1emu.c.inc
Normal file
File diff suppressed because it is too large
Load Diff
@ -159,84 +159,20 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#include "snes9x.h"
|
|
||||||
#include "memmap.h"
|
|
||||||
|
|
||||||
static void DSP2_Op01 (void);
|
|
||||||
static void DSP2_Op03 (void);
|
|
||||||
static void DSP2_Op05 (void);
|
|
||||||
static void DSP2_Op06 (void);
|
|
||||||
static void DSP2_Op09 (void);
|
|
||||||
static void DSP2_Op0D (void);
|
|
||||||
|
|
||||||
|
|
||||||
// convert bitmap to bitplane tile
|
|
||||||
static void DSP2_Op01 (void)
|
uint16 DSP2Op09Word1=0;
|
||||||
{
|
uint16 DSP2Op09Word2=0;
|
||||||
// Op01 size is always 32 bytes input and output
|
bool DSP2Op05HasLen=false;
|
||||||
// The hardware does strange things if you vary the size
|
int DSP2Op05Len=0;
|
||||||
|
bool DSP2Op06HasLen=false;
|
||||||
uint8 c0, c1, c2, c3;
|
int DSP2Op06Len=0;
|
||||||
uint8 *p1 = DSP2.parameters;
|
uint8 DSP2Op05Transparent=0;
|
||||||
uint8 *p2a = DSP2.output;
|
|
||||||
uint8 *p2b = DSP2.output + 16; // halfway
|
void DSP2_Op05 ()
|
||||||
|
|
||||||
// Process 8 blocks of 4 bytes each
|
|
||||||
|
|
||||||
for (int j = 0; j < 8; j++)
|
|
||||||
{
|
|
||||||
c0 = *p1++;
|
|
||||||
c1 = *p1++;
|
|
||||||
c2 = *p1++;
|
|
||||||
c3 = *p1++;
|
|
||||||
|
|
||||||
*p2a++ = (c0 & 0x10) << 3 |
|
|
||||||
(c0 & 0x01) << 6 |
|
|
||||||
(c1 & 0x10) << 1 |
|
|
||||||
(c1 & 0x01) << 4 |
|
|
||||||
(c2 & 0x10) >> 1 |
|
|
||||||
(c2 & 0x01) << 2 |
|
|
||||||
(c3 & 0x10) >> 3 |
|
|
||||||
(c3 & 0x01);
|
|
||||||
|
|
||||||
*p2a++ = (c0 & 0x20) << 2 |
|
|
||||||
(c0 & 0x02) << 5 |
|
|
||||||
(c1 & 0x20) |
|
|
||||||
(c1 & 0x02) << 3 |
|
|
||||||
(c2 & 0x20) >> 2 |
|
|
||||||
(c2 & 0x02) << 1 |
|
|
||||||
(c3 & 0x20) >> 4 |
|
|
||||||
(c3 & 0x02) >> 1;
|
|
||||||
|
|
||||||
*p2b++ = (c0 & 0x40) << 1 |
|
|
||||||
(c0 & 0x04) << 4 |
|
|
||||||
(c1 & 0x40) >> 1 |
|
|
||||||
(c1 & 0x04) << 2 |
|
|
||||||
(c2 & 0x40) >> 3 |
|
|
||||||
(c2 & 0x04) |
|
|
||||||
(c3 & 0x40) >> 5 |
|
|
||||||
(c3 & 0x04) >> 2;
|
|
||||||
|
|
||||||
*p2b++ = (c0 & 0x80) |
|
|
||||||
(c0 & 0x08) << 3 |
|
|
||||||
(c1 & 0x80) >> 2 |
|
|
||||||
(c1 & 0x08) << 1 |
|
|
||||||
(c2 & 0x80) >> 4 |
|
|
||||||
(c2 & 0x08) >> 1 |
|
|
||||||
(c3 & 0x80) >> 6 |
|
|
||||||
(c3 & 0x08) >> 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// set transparent color
|
|
||||||
static void DSP2_Op03 (void)
|
|
||||||
{
|
|
||||||
DSP2.Op05Transparent = DSP2.parameters[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
// replace bitmap using transparent color
|
|
||||||
static void DSP2_Op05 (void)
|
|
||||||
{
|
{
|
||||||
|
uint8 color;
|
||||||
// Overlay bitmap with transparency.
|
// Overlay bitmap with transparency.
|
||||||
// Input:
|
// Input:
|
||||||
//
|
//
|
||||||
@ -262,52 +198,136 @@ static void DSP2_Op05 (void)
|
|||||||
// size = 0. I don't think it's worth implementing this quirk unless it's
|
// size = 0. I don't think it's worth implementing this quirk unless it's
|
||||||
// proven necessary.
|
// proven necessary.
|
||||||
|
|
||||||
uint8 color;
|
int n;
|
||||||
uint8 c1, c2;
|
unsigned char c1;
|
||||||
uint8 *p1 = DSP2.parameters;
|
unsigned char c2;
|
||||||
uint8 *p2 = DSP2.parameters + DSP2.Op05Len;
|
unsigned char *p1 = DSP1.parameters;
|
||||||
uint8 *p3 = DSP2.output;
|
unsigned char *p2 = &DSP1.parameters[DSP2Op05Len];
|
||||||
|
unsigned char *p3 = DSP1.output;
|
||||||
|
|
||||||
color = DSP2.Op05Transparent & 0x0f;
|
color = DSP2Op05Transparent&0x0f;
|
||||||
|
|
||||||
for (int32 n = 0; n < DSP2.Op05Len; n++)
|
for( n = 0; n < DSP2Op05Len; n++ )
|
||||||
{
|
{
|
||||||
c1 = *p1++;
|
c1 = *p1++;
|
||||||
c2 = *p2++;
|
c2 = *p2++;
|
||||||
*p3++ = (((c2 >> 4) == color) ? c1 & 0xf0: c2 & 0xf0) | (((c2 & 0x0f) == color) ? c1 & 0x0f: c2 & 0x0f);
|
*p3++ = ( ((c2 >> 4) == color ) ? c1 & 0xf0: c2 & 0xf0 ) |
|
||||||
|
( ((c2 & 0x0f)==color) ? c1 & 0x0f: c2 & 0x0f );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// reverse bitmap
|
void DSP2_Op01 ()
|
||||||
static void DSP2_Op06 (void)
|
{
|
||||||
|
// Op01 size is always 32 bytes input and output.
|
||||||
|
// The hardware does strange things if you vary the size.
|
||||||
|
|
||||||
|
int j;
|
||||||
|
unsigned char c0, c1, c2, c3;
|
||||||
|
unsigned char *p1 = DSP1.parameters;
|
||||||
|
unsigned char *p2a = DSP1.output;
|
||||||
|
unsigned char *p2b = &DSP1.output[16]; // halfway
|
||||||
|
|
||||||
|
// Process 8 blocks of 4 bytes each
|
||||||
|
|
||||||
|
for ( j = 0; j < 8; j++ )
|
||||||
|
{
|
||||||
|
c0 = *p1++;
|
||||||
|
c1 = *p1++;
|
||||||
|
c2 = *p1++;
|
||||||
|
c3 = *p1++;
|
||||||
|
|
||||||
|
*p2a++ = (c0 & 0x10) << 3 |
|
||||||
|
(c0 & 0x01) << 6 |
|
||||||
|
(c1 & 0x10) << 1 |
|
||||||
|
(c1 & 0x01) << 4 |
|
||||||
|
(c2 & 0x10) >> 1 |
|
||||||
|
(c2 & 0x01) << 2 |
|
||||||
|
(c3 & 0x10) >> 3 |
|
||||||
|
(c3 & 0x01);
|
||||||
|
|
||||||
|
*p2a++ = (c0 & 0x20) << 2 |
|
||||||
|
(c0 & 0x02) << 5 |
|
||||||
|
(c1 & 0x20) |
|
||||||
|
(c1 & 0x02) << 3 |
|
||||||
|
(c2 & 0x20) >> 2 |
|
||||||
|
(c2 & 0x02) << 1 |
|
||||||
|
(c3 & 0x20) >> 4 |
|
||||||
|
(c3 & 0x02) >> 1;
|
||||||
|
|
||||||
|
*p2b++ = (c0 & 0x40) << 1 |
|
||||||
|
(c0 & 0x04) << 4 |
|
||||||
|
(c1 & 0x40) >> 1 |
|
||||||
|
(c1 & 0x04) << 2 |
|
||||||
|
(c2 & 0x40) >> 3 |
|
||||||
|
(c2 & 0x04) |
|
||||||
|
(c3 & 0x40) >> 5 |
|
||||||
|
(c3 & 0x04) >> 2;
|
||||||
|
|
||||||
|
|
||||||
|
*p2b++ = (c0 & 0x80) |
|
||||||
|
(c0 & 0x08) << 3 |
|
||||||
|
(c1 & 0x80) >> 2 |
|
||||||
|
(c1 & 0x08) << 1 |
|
||||||
|
(c2 & 0x80) >> 4 |
|
||||||
|
(c2 & 0x08) >> 1 |
|
||||||
|
(c3 & 0x80) >> 6 |
|
||||||
|
(c3 & 0x08) >> 3;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DSP2_Op06 ()
|
||||||
{
|
{
|
||||||
// Input:
|
// Input:
|
||||||
// size
|
// size
|
||||||
// bitmap
|
// bitmap
|
||||||
|
|
||||||
for (int32 i = 0, j = DSP2.Op06Len - 1; i < DSP2.Op06Len; i++, j--)
|
int i, j;
|
||||||
DSP2.output[j] = (DSP2.parameters[i] << 4) | (DSP2.parameters[i] >> 4);
|
|
||||||
|
for ( i = 0, j = DSP2Op06Len - 1; i < DSP2Op06Len; i++, j-- )
|
||||||
|
{
|
||||||
|
DSP1.output[j] = (DSP1.parameters[i] << 4) | (DSP1.parameters[i] >> 4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// multiply
|
bool DSP2Op0DHasLen=false;
|
||||||
static void DSP2_Op09 (void)
|
int DSP2Op0DOutLen=0;
|
||||||
|
int DSP2Op0DInLen=0;
|
||||||
|
|
||||||
|
#ifndef DSP2_BIT_ACCURRATE_CODE
|
||||||
|
|
||||||
|
// Scale bitmap based on input length out output length
|
||||||
|
|
||||||
|
void DSP2_Op0D()
|
||||||
{
|
{
|
||||||
DSP2.Op09Word1 = DSP2.parameters[0] | (DSP2.parameters[1] << 8);
|
// Overload's algorithm - use this unless doing hardware testing
|
||||||
DSP2.Op09Word2 = DSP2.parameters[2] | (DSP2.parameters[3] << 8);
|
|
||||||
|
|
||||||
#ifdef FAST_LSB_WORD_ACCESS
|
// One note: the HW can do odd byte scaling but since we divide
|
||||||
*(uint32 *) DSP2.output = DSP2.Op09Word1 * DSP2.Op09Word2;
|
// by two to get the count of bytes this won't work well for
|
||||||
#else
|
// odd byte scaling (in any of the current algorithm implementations).
|
||||||
uint32 temp = DSP2.Op09Word1 * DSP2.Op09Word2;
|
// So far I haven't seen Dungeon Master use it.
|
||||||
DSP2.output[0] = temp & 0xFF;
|
// If it does we can adjust the parameters and code to work with it
|
||||||
DSP2.output[1] = (temp >> 8) & 0xFF;
|
|
||||||
DSP2.output[2] = (temp >> 16) & 0xFF;
|
int i;
|
||||||
DSP2.output[3] = (temp >> 24) & 0xFF;
|
int pixel_offset;
|
||||||
#endif
|
uint8 pixelarray[512];
|
||||||
|
|
||||||
|
for(i=0; i<DSP2Op0DOutLen*2; i++)
|
||||||
|
{
|
||||||
|
pixel_offset = (i * DSP2Op0DInLen) / DSP2Op0DOutLen;
|
||||||
|
if ( (pixel_offset&1) == 0 )
|
||||||
|
pixelarray[i] = DSP1.parameters[pixel_offset>>1] >> 4;
|
||||||
|
else
|
||||||
|
pixelarray[i] = DSP1.parameters[pixel_offset>>1] & 0x0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( i=0; i < DSP2Op0DOutLen; i++ )
|
||||||
|
DSP1.output[i] = ( pixelarray[i<<1] << 4 ) | pixelarray[(i<<1)+1];
|
||||||
}
|
}
|
||||||
|
|
||||||
// scale bitmap
|
#else
|
||||||
static void DSP2_Op0D (void)
|
|
||||||
|
void DSP2_Op0D()
|
||||||
{
|
{
|
||||||
// Bit accurate hardware algorithm - uses fixed point math
|
// Bit accurate hardware algorithm - uses fixed point math
|
||||||
// This should match the DSP2 Op0D output exactly
|
// This should match the DSP2 Op0D output exactly
|
||||||
@ -323,198 +343,74 @@ static void DSP2_Op0D (void)
|
|||||||
// So far I haven't seen Dungeon Master use it.
|
// So far I haven't seen Dungeon Master use it.
|
||||||
// If it does we can adjust the parameters and code to work with it
|
// If it does we can adjust the parameters and code to work with it
|
||||||
|
|
||||||
uint32 multiplier; // Any size int >= 32-bits
|
|
||||||
uint32 pixloc; // match size of multiplier
|
|
||||||
uint8 pixelarray[512];
|
|
||||||
|
|
||||||
if (DSP2.Op0DInLen <= DSP2.Op0DOutLen)
|
uint32 multiplier; // Any size int >= 32-bits
|
||||||
multiplier = 0x10000; // In our self defined fixed point 0x10000 == 1
|
uint32 pixloc; // match size of multiplier
|
||||||
|
int i, j;
|
||||||
|
uint8 pixelarray[512];
|
||||||
|
|
||||||
|
if (DSP2Op0DInLen <= DSP2Op0DOutLen)
|
||||||
|
multiplier = 0x10000; // In our self defined fixed point 0x10000 == 1
|
||||||
else
|
else
|
||||||
multiplier = (DSP2.Op0DInLen << 17) / ((DSP2.Op0DOutLen << 1) + 1);
|
multiplier = (DSP2Op0DInLen << 17) / ((DSP2Op0DOutLen<<1) + 1);
|
||||||
|
|
||||||
pixloc = 0;
|
pixloc = 0;
|
||||||
|
for ( i=0; i < DSP2Op0DOutLen * 2; i++ )
|
||||||
for (int32 i = 0; i < DSP2.Op0DOutLen * 2; i++)
|
|
||||||
{
|
{
|
||||||
int32 j = pixloc >> 16;
|
j = pixloc >> 16;
|
||||||
|
|
||||||
if (j & 1)
|
if ( j & 1 )
|
||||||
pixelarray[i] = DSP2.parameters[j >> 1] & 0x0f;
|
pixelarray[i] = DSP1.parameters[j>>1] & 0x0f;
|
||||||
else
|
else
|
||||||
pixelarray[i] = (DSP2.parameters[j >> 1] & 0xf0) >> 4;
|
pixelarray[i] = (DSP1.parameters[j>>1] & 0xf0) >> 4;
|
||||||
|
|
||||||
pixloc += multiplier;
|
pixloc += multiplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int32 i = 0; i < DSP2.Op0DOutLen; i++)
|
for ( i=0; i < DSP2Op0DOutLen; i++ )
|
||||||
DSP2.output[i] = (pixelarray[i << 1] << 4) | pixelarray[(i << 1) + 1];
|
DSP1.output[i] = ( pixelarray[i<<1] << 4 ) | pixelarray[(i<<1)+1];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
#endif
|
||||||
static void DSP2_Op0D (void)
|
|
||||||
|
#if 0 // Probably no reason to use this code - it's not quite bit accurate and it doesn't look as good as Overload's algorithm
|
||||||
|
|
||||||
|
void DSP2_Op0D()
|
||||||
{
|
{
|
||||||
// Overload's algorithm - use this unless doing hardware testing
|
// Float implementation of Neviksti's algorithm
|
||||||
|
// This is the right algorithm to match the DSP2 bits but the precision
|
||||||
|
// of the PC float does not match the precision of the fixed point math
|
||||||
|
// on the DSP2 causing occasional one off data mismatches (which should
|
||||||
|
// be no problem because its just a one pixel difference in a scaled image
|
||||||
|
// to be displayed).
|
||||||
|
|
||||||
// One note: the HW can do odd byte scaling but since we divide
|
float multiplier;
|
||||||
// by two to get the count of bytes this won't work well for
|
float pixloc;
|
||||||
// odd byte scaling (in any of the current algorithm implementations).
|
int i, j;
|
||||||
// So far I haven't seen Dungeon Master use it.
|
uint8 pixelarray[512];
|
||||||
// If it does we can adjust the parameters and code to work with it
|
|
||||||
|
|
||||||
int32 pixel_offset;
|
if (DSP2Op0DInLen <= DSP2Op0DOutLen)
|
||||||
uint8 pixelarray[512];
|
multiplier = (float) 1.0;
|
||||||
|
|
||||||
for (int32 i = 0; i < DSP2.Op0DOutLen * 2; i++)
|
|
||||||
{
|
|
||||||
pixel_offset = (i * DSP2.Op0DInLen) / DSP2.Op0DOutLen;
|
|
||||||
|
|
||||||
if ((pixel_offset & 1) == 0)
|
|
||||||
pixelarray[i] = DSP2.parameters[pixel_offset >> 1] >> 4;
|
|
||||||
else
|
|
||||||
pixelarray[i] = DSP2.parameters[pixel_offset >> 1] & 0x0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int32 i = 0; i < DSP2.Op0DOutLen; i++)
|
|
||||||
DSP2.output[i] = (pixelarray[i << 1] << 4) | pixelarray[(i << 1) + 1];
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
void DSP2SetByte (uint8 byte, uint16 address)
|
|
||||||
{
|
|
||||||
if ((address & 0xf000) == 0x6000 || (address >= 0x8000 && address < 0xc000))
|
|
||||||
{
|
|
||||||
if (DSP2.waiting4command)
|
|
||||||
{
|
|
||||||
DSP2.command = byte;
|
|
||||||
DSP2.in_index = 0;
|
|
||||||
DSP2.waiting4command = FALSE;
|
|
||||||
|
|
||||||
switch (byte)
|
|
||||||
{
|
|
||||||
case 0x01: DSP2.in_count = 32; break;
|
|
||||||
case 0x03: DSP2.in_count = 1; break;
|
|
||||||
case 0x05: DSP2.in_count = 1; break;
|
|
||||||
case 0x06: DSP2.in_count = 1; break;
|
|
||||||
case 0x09: DSP2.in_count = 4; break;
|
|
||||||
case 0x0D: DSP2.in_count = 2; break;
|
|
||||||
default:
|
|
||||||
#ifdef DEBUGGER
|
|
||||||
//printf("Op%02X\n", byte);
|
|
||||||
#endif
|
|
||||||
case 0x0f: DSP2.in_count = 0; break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DSP2.parameters[DSP2.in_index] = byte;
|
|
||||||
DSP2.in_index++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DSP2.in_count == DSP2.in_index)
|
|
||||||
{
|
|
||||||
DSP2.waiting4command = TRUE;
|
|
||||||
DSP2.out_index = 0;
|
|
||||||
|
|
||||||
switch (DSP2.command)
|
|
||||||
{
|
|
||||||
case 0x01:
|
|
||||||
DSP2.out_count = 32;
|
|
||||||
DSP2_Op01();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x03:
|
|
||||||
DSP2_Op03();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x05:
|
|
||||||
if (DSP2.Op05HasLen)
|
|
||||||
{
|
|
||||||
DSP2.Op05HasLen = FALSE;
|
|
||||||
DSP2.out_count = DSP2.Op05Len;
|
|
||||||
DSP2_Op05();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DSP2.Op05Len = DSP2.parameters[0];
|
|
||||||
DSP2.in_index = 0;
|
|
||||||
DSP2.in_count = 2 * DSP2.Op05Len;
|
|
||||||
DSP2.Op05HasLen = TRUE;
|
|
||||||
if (byte)
|
|
||||||
DSP2.waiting4command = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x06:
|
|
||||||
if (DSP2.Op06HasLen)
|
|
||||||
{
|
|
||||||
DSP2.Op06HasLen = FALSE;
|
|
||||||
DSP2.out_count = DSP2.Op06Len;
|
|
||||||
DSP2_Op06();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DSP2.Op06Len = DSP2.parameters[0];
|
|
||||||
DSP2.in_index = 0;
|
|
||||||
DSP2.in_count = DSP2.Op06Len;
|
|
||||||
DSP2.Op06HasLen = TRUE;
|
|
||||||
if (byte)
|
|
||||||
DSP2.waiting4command = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x09:
|
|
||||||
DSP2.out_count = 4;
|
|
||||||
DSP2_Op09();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x0D:
|
|
||||||
if (DSP2.Op0DHasLen)
|
|
||||||
{
|
|
||||||
DSP2.Op0DHasLen = FALSE;
|
|
||||||
DSP2.out_count = DSP2.Op0DOutLen;
|
|
||||||
DSP2_Op0D();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DSP2.Op0DInLen = DSP2.parameters[0];
|
|
||||||
DSP2.Op0DOutLen = DSP2.parameters[1];
|
|
||||||
DSP2.in_index = 0;
|
|
||||||
DSP2.in_count = (DSP2.Op0DInLen + 1) >> 1;
|
|
||||||
DSP2.Op0DHasLen = TRUE;
|
|
||||||
if (byte)
|
|
||||||
DSP2.waiting4command = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x0f:
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8 DSP2GetByte (uint16 address)
|
|
||||||
{
|
|
||||||
uint8 t;
|
|
||||||
|
|
||||||
if ((address & 0xf000) == 0x6000 || (address >= 0x8000 && address < 0xc000))
|
|
||||||
{
|
|
||||||
if (DSP2.out_count)
|
|
||||||
{
|
|
||||||
t = (uint8) DSP2.output[DSP2.out_index];
|
|
||||||
DSP2.out_index++;
|
|
||||||
if (DSP2.out_count == DSP2.out_index)
|
|
||||||
DSP2.out_count = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
t = 0xff;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
t = 0x80;
|
multiplier = (float) ((DSP2Op0DInLen * 2.0) / (DSP2Op0DOutLen * 2.0 + 1.0));
|
||||||
|
|
||||||
return (t);
|
pixloc = 0.0;
|
||||||
|
for ( i=0; i < DSP2Op0DOutLen * 2; i++ )
|
||||||
|
{
|
||||||
|
// j = (int)(i * multiplier);
|
||||||
|
j = (int) pixloc;
|
||||||
|
|
||||||
|
if ( j & 1 )
|
||||||
|
pixelarray[i] = DSP1.parameters[j>>1] & 0x0f;
|
||||||
|
else
|
||||||
|
pixelarray[i] = (DSP1.parameters[j>>1] & 0xf0) >> 4;
|
||||||
|
|
||||||
|
pixloc += multiplier; // use an add in the loop instead of multiply to increase loop speed
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( i=0; i < DSP2Op0DOutLen; i++ )
|
||||||
|
DSP1.output[i] = ( pixelarray[i<<1] << 4 ) | pixelarray[(i<<1)+1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
2396
source/snes9x/dsp4emu.c.inc
Normal file
2396
source/snes9x/dsp4emu.c.inc
Normal file
File diff suppressed because it is too large
Load Diff
@ -159,151 +159,142 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _FONT_H_
|
|
||||||
#define _FONT_H_
|
|
||||||
|
|
||||||
static const char *font[] =
|
static char *font[] = {
|
||||||
{
|
" . . . . .. . . ",
|
||||||
//2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678
|
" .#. .#.#. . . ... .#. . . .##. .#. .#. . . . . ",
|
||||||
" . . . . .. . . ",
|
" .#. .#.#. .#.#. .###. .#..#. .#. .#. .#. .#. .#.#. .#. .#. ",
|
||||||
" .#. .#.#. . . ... .#. . . .##. .#. .#. . . . . ",
|
" .#. .#.#. .#####. .#.#. ..#. .#.#. .#. .#. .#. .#. ..#.. .... .#. ",
|
||||||
" .#. .#.#. .#.#. .###. .#..#. .#. .#. .#. .#. .#.#. .#. .#. ",
|
" .#. . . .#.#. .###. .#.. .#. . .#. .#. .###. .#####. .. .####. .. .#. ",
|
||||||
" .#. .#.#. .#####. .#.#. ..#. .#.#. .#. .#. .#. .#. ..#.. .... .#. ",
|
" . .#####. .#.#. .#..#. .#.#. .#. .#. .#. ..#.. .##. .... .##. .#. ",
|
||||||
" .#. . . .#.#. .###. .#.. .#. . .#. .#. .###. .#####. .. .####. .. .#. ",
|
" .#. .#.#. .###. . .#. .#.#. .#. .#. .#.#. .#. .#. .##. . ",
|
||||||
" . .#####. .#.#. .#..#. .#.#. .#. .#. .#. ..#.. .##. .... .##. .#. ",
|
" . . . ... . . . . . . . . .#. .. ",
|
||||||
" .#. .#.#. .###. . .#. .#.#. .#. .#. .#.#. .#. .#. .##. . ",
|
" . ",
|
||||||
" . . . ... . . . . . . . . .#. .. ",
|
" . . .. .... . .... .. .... .. .. . ",
|
||||||
" . ",
|
" .#. .#. .##. .####. .#. .####. .##. .####. .##. .##. .. .. . . .#. ",
|
||||||
//2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678
|
".#.#. .##. .#..#. ...#. .##. .#... .#.. ...#. .#..#. .#..#. .##. .##. .#. .... .#. .#.#. ",
|
||||||
" . . .. .... . .... .. .... .. .. . ",
|
".#.#. .#. . .#. .##. .#.#. .###. .###. .#. .##. .#..#. .##. .##. .#. .####. .#. ..#. ",
|
||||||
" .#. .#. .##. .####. .#. .####. .##. .####. .##. .##. .. .. . . .#. ",
|
".#.#. .#. .#. ...#. .####. ...#. .#..#. .#. .#..#. .###. .. .. .#. .... .#. .#. ",
|
||||||
".#.#. .##. .#..#. ...#. .##. .#... .#.. ...#. .#..#. .#..#. .##. .##. .#. .... .#. .#.#. ",
|
".#.#. .#. .#.. .#..#. ..#. .#..#. .#..#. .#. .#..#. ..#. .##. .##. .#. .####. .#. . ",
|
||||||
".#.#. .#. . .#. .##. .#.#. .###. .###. .#. .##. .#..#. .##. .##. .#. .####. .#. ..#. ",
|
" .#. .###. .####. .##. .#. .##. .##. .#. .##. .##. .##. .#. .#. .... .#. .#. ",
|
||||||
".#.#. .#. .#. ...#. .####. ...#. .#..#. .#. .#..#. .###. .. .. .#. .... .#. .#. ",
|
" . ... .... .. . .. .. . .. .. .. .#. . . . ",
|
||||||
".#.#. .#. .#.. .#..#. ..#. .#..#. .#..#. .#. .#..#. ..#. .##. .##. .#. .####. .#. . ",
|
" . ",
|
||||||
" .#. .###. .####. .##. .#. .##. .##. .#. .##. .##. .##. .#. .#. .... .#. .#. ",
|
" .. .. ... .. ... .... .... .. . . ... . . . . . . . . .. ",
|
||||||
" . ... .... .. . .. .. . .. .. .. .#. . . . ",
|
" .##. .##. .###. .##. .###. .####. .####. .##. .#..#. .###. .#. .#..#. .#. .#. .#. .#. .#. .##. ",
|
||||||
" . ",
|
".#..#. .#..#. .#..#. .#..#. .#..#. .#... .#... .#..#. .#..#. .#. .#. .#.#. .#. .##.##. .##..#. .#..#. ",
|
||||||
//2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678
|
".#.##. .#..#. .###. .#. . .#..#. .###. .###. .#... .####. .#. .#. .##. .#. .#.#.#. .#.#.#. .#..#. ",
|
||||||
" .. .. ... .. ... .... .... .. . . ... . . . . . . . . .. ",
|
".#.##. .####. .#..#. .#. . .#..#. .#.. .#.. .#.##. .#..#. .#. . .#. .##. .#. .#...#. .#.#.#. .#..#. ",
|
||||||
" .##. .##. .###. .##. .###. .####. .####. .##. .#..#. .###. .#. .#..#. .#. .#. .#. .#. .#. .##. ",
|
".#... .#..#. .#..#. .#..#. .#..#. .#... .#. .#..#. .#..#. .#. .#..#. .#.#. .#... .#. .#. .#..##. .#..#. ",
|
||||||
".#..#. .#..#. .#..#. .#..#. .#..#. .#... .#... .#..#. .#..#. .#. .#. .#.#. .#. .##.##. .##..#. .#..#. ",
|
" .##. .#..#. .###. .##. .###. .####. .#. .###. .#..#. .###. .##. .#..#. .####. .#. .#. .#. .#. .##. ",
|
||||||
".#.##. .#..#. .###. .#. . .#..#. .###. .###. .#... .####. .#. .#. .##. .#. .#.#.#. .#.#.#. .#..#. ",
|
" .. . . ... .. ... .... . ... . . ... .. . . .... . . . . .. ",
|
||||||
".#.##. .####. .#..#. .#. . .#..#. .#.. .#.. .#.##. .#..#. .#. . .#. .##. .#. .#...#. .#.#.#. .#..#. ",
|
" ",
|
||||||
".#... .#..#. .#..#. .#..#. .#..#. .#... .#. .#..#. .#..#. .#. .#..#. .#.#. .#... .#. .#. .#..##. .#..#. ",
|
" ... .. ... .. ... . . . . . . . . . . .... ... ... . ",
|
||||||
" .##. .#..#. .###. .##. .###. .####. .#. .###. .#..#. .###. .##. .#..#. .####. .#. .#. .#. .#. .##. ",
|
".###. .##. .###. .##. .###. .#. .#. .#. .#. .#. .#. .#..#. .#.#. .####. .###. . .###. .#. ",
|
||||||
" .. . . ... .. ... .... . ... . . ... .. . . .... . . . . .. ",
|
".#..#. .#..#. .#..#. .#..#. .#. .#. .#. .#. .#. .#...#. .#..#. .#.#. ...#. .#.. .#. ..#. .#.#. ",
|
||||||
" ",
|
".#..#. .#..#. .#..#. .#.. .#. .#. .#. .#. .#. .#.#.#. .##. .#.#. .#. .#. .#. .#. . . ",
|
||||||
//2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678
|
".###. .#..#. .###. ..#. .#. .#. .#. .#. .#. .#.#.#. .#..#. .#. .#. .#. .#. .#. ",
|
||||||
" ... .. ... .. ... . . . . . . . . . . .... ... ... . ",
|
".#.. .##.#. .#.#. .#..#. .#. .#...#. .#.#. .##.##. .#..#. .#. .#... .#.. .#. ..#. .... ",
|
||||||
".###. .##. .###. .##. .###. .#. .#. .#. .#. .#. .#. .#..#. .#.#. .####. .###. . .###. .#. ",
|
".#. .##. .#..#. .##. .#. .###. .#. .#. .#. .#..#. .#. .####. .###. . .###. .####. ",
|
||||||
".#..#. .#..#. .#..#. .#..#. .#. .#. .#. .#. .#. .#...#. .#..#. .#.#. ...#. .#.. .#. ..#. .#.#. ",
|
" . ..#. . . .. . ... . . . . . . .... ... ... .... ",
|
||||||
".#..#. .#..#. .#..#. .#.. .#. .#. .#. .#. .#. .#.#.#. .##. .#.#. .#. .#. .#. .#. . . ",
|
" . ",
|
||||||
".###. .#..#. .###. ..#. .#. .#. .#. .#. .#. .#.#.#. .#..#. .#. .#. .#. .#. .#. ",
|
" .. . . . . . . . .. ",
|
||||||
".#.. .##.#. .#.#. .#..#. .#. .#...#. .#.#. .##.##. .#..#. .#. .#... .#.. .#. ..#. .... ",
|
".##. .#. .#. .#. .#. .#. .#. .#. .##. ",
|
||||||
".#. .##. .#..#. .##. .#. .###. .#. .#. .#. .#..#. .#. .####. .###. . .###. .####. ",
|
" .#. ... .#.. .. ..#. .. .#.#. ... .#.. .. . .#.. .#. .. .. ... .. ",
|
||||||
" . ..#. . . .. . ... . . . . . . .... ... ... .... ",
|
" .#. .###. .###. .##. .###. .##. .#.. .###. .###. .##. .#. .#.#. .#. .##.##. .###. .##. ",
|
||||||
" . ",
|
" . .#..#. .#..#. .#.. .#..#. .#.##. .###. .#..#. .#..#. .#. .#. .##. .#. .#.#.#. .#..#. .#..#. ",
|
||||||
//2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678
|
" .#.##. .#..#. .#.. .#..#. .##.. .#. .##. .#..#. .#. ..#. .#.#. .#. .#...#. .#..#. .#..#. ",
|
||||||
" .. . . . . . . . .. ",
|
" .#.#. .###. .##. .###. .##. .#. .#... .#..#. .###. .#.#. .#..#. .###. .#. .#. .#..#. .##. ",
|
||||||
".##. .#. .#. .#. .#. .#. .#. .#. .##. ",
|
" . . ... .. ... .. . .###. . . ... .#. . . ... . . . . .. ",
|
||||||
" .#. ... .#.. .. ..#. .. .#.#. ... .#.. .. . .#.. .#. .. .. ... .. ",
|
" ... . ",
|
||||||
" .#. .###. .###. .##. .###. .##. .#.. .###. .###. .##. .#. .#.#. .#. .##.##. .###. .##. ",
|
" . . . . . . ",
|
||||||
" . .#..#. .#..#. .#.. .#..#. .#.##. .###. .#..#. .#..#. .#. .#. .##. .#. .#.#.#. .#..#. .#..#. ",
|
" .#. .#. .#. .#. .#.#. ",
|
||||||
" .#.##. .#..#. .#.. .#..#. .##.. .#. .##. .#..#. .#. ..#. .#.#. .#. .#...#. .#..#. .#..#. ",
|
" ... ... ... ... .#. . . . . . . . . . . .... .#. .#. .#. .#.#. ",
|
||||||
" .#.#. .###. .##. .###. .##. .#. .#... .#..#. .###. .#.#. .#..#. .###. .#. .#. .#..#. .##. ",
|
".###. .###. .###. .###. .###. .#..#. .#.#. .#...#. .#..#. .#..#. .####. .##. .#. .##. . . ",
|
||||||
" . . ... .. ... .. . .###. . . ... .#. . . ... . . . . .. ",
|
".#..#. .#..#. .#..#. .##.. .#. .#..#. .#.#. .#.#.#. .##. .#..#. ..#. .#. .#. .#. ",
|
||||||
" ... . ",
|
".#..#. .#..#. .#. . ..##. .#.. .#..#. .#.#. .#.#.#. .##. .#.#. .#.. .#. .#. .#. ",
|
||||||
//2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678
|
".###. .###. .#. .###. .##. .###. .#. .#.#. .#..#. .#. .####. .#. .#. .#. ",
|
||||||
" . . . . . . ",
|
".#.. ..#. . ... .. ... . . . . . .#. .... . . . ",
|
||||||
" .#. .#. .#. .#. .#.#. ",
|
" . . . ",
|
||||||
" ... ... ... ... .#. . . . . . . . . . . .... .#. .#. .#. .#.#. ",
|
|
||||||
".###. .###. .###. .###. .###. .#..#. .#.#. .#...#. .#..#. .#..#. .####. .##. .#. .##. . . ",
|
" ",
|
||||||
".#..#. .#..#. .#..#. .##.. .#. .#..#. .#.#. .#.#.#. .##. .#..#. ..#. .#. .#. .#. ",
|
" ",
|
||||||
".#..#. .#..#. .#. . ..##. .#.. .#..#. .#.#. .#.#.#. .##. .#.#. .#.. .#. .#. .#. ",
|
" ",
|
||||||
".###. .###. .#. .###. .##. .###. .#. .#.#. .#..#. .#. .####. .#. .#. .#. ",
|
" ",
|
||||||
".#.. ..#. . ... .. ... . . . . . .#. .... . . . ",
|
" ",
|
||||||
" . . . ",
|
" ",
|
||||||
//2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678
|
" ",
|
||||||
" ",
|
" ",
|
||||||
" ",
|
" ",
|
||||||
" ",
|
|
||||||
" ",
|
" ",
|
||||||
" ",
|
" ",
|
||||||
" ",
|
" ",
|
||||||
" ",
|
" ",
|
||||||
" ",
|
" ",
|
||||||
" ",
|
" ",
|
||||||
//2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678
|
" ",
|
||||||
" ",
|
" ",
|
||||||
" ",
|
" ",
|
||||||
" ",
|
|
||||||
" ",
|
//2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678
|
||||||
" ",
|
" .. ..... ",
|
||||||
" ",
|
" .##. .#####. ... . . . . .. ",
|
||||||
" ",
|
" .#. . .. ....#. .###. .#. .#. .#. .#.. .##. . . . ",
|
||||||
" ",
|
" .#. .#. .##. .#####. .#. .#. .###. ... .###. .###. .. .#. .#.#.#. ",
|
||||||
" ",
|
" . .#. .#. . .##. ....#. .#. .##. .#.#. .###. .#. .##.#. .##. .##. .#.#.#. ",
|
||||||
//2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678
|
" .#. . .#. .#. .. ...#. .#. .#. ..#. .#. .##. .#.. ..#. .#. ...#. ",
|
||||||
" .. ..... ",
|
" .#.#. .##. .#. .###. .#. .#. .#. .###. .#. .#. .####. .##. .##. ",
|
||||||
" .##. .#####. ... . . . . .. ",
|
" .#. .. .#. ... . . . ... . . .... .. .. ",
|
||||||
" .#. . .. ....#. .###. .#. .#. .#. .#.. .##. . . . ",
|
" . . ",
|
||||||
" .#. .#. .##. .#####. .#. .#. .###. ... .###. .###. .. .#. .#.#.#. ",
|
//2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678
|
||||||
" . .#. .#. . .##. ....#. .#. .##. .#.#. .###. .#. .##.#. .##. .##. .#.#.#. ",
|
" .... . . ... . . . .... . . . .. . ..... . . . ",
|
||||||
" .#. . .#. .#. .. ...#. .#. .#. ..#. .#. .##. .#.. ..#. .#. ...#. ",
|
" .####. .#. ..#.. .###. ...#. ..#.. ..#.. .####. .#... .... .#.#. .##..#. .#####. .#... .#. .#. ",
|
||||||
" .#.#. .##. .#. .###. .#. .#. .#. .###. .#. .#. .####. .##. .##. ",
|
" .... ...#. .#. .#####. .#. .#####. .#####. .#####. .#..#. .####. .####. .#####. .. .#. ....#. .#####. .#. .#. ",
|
||||||
" .#. .. .#. ... . . . ... . . .... .. .. ",
|
".####. .##. .## .#...#. .#. ...#. ..#.#. ..#.. .# .#. .#..#. ...#. .#.#. .##..#. .#. .#..#. .#..#. ",
|
||||||
" . . ",
|
" .... .#. .#.# . .#. .#. .##. .#..#. .#####. .#. .#. . .#. .#. ..#. .. .#. .#. .#.#. . .#. ",
|
||||||
//2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678
|
" .#. .#. ..#. ..#.. .#.#. .#..#. ..#.. . .#. .#. ...#. .#. ...#. .#.#. .#... ...#. ",
|
||||||
" .... . . ... . . . .... . . . .. . ..... . . . ",
|
" .#. .#. .##. .#####. .#..#. .#..#. .#. .#. .#. .####. .#. .###. .#. .#. .###. .###. ",
|
||||||
" .####. .#. ..#.. .###. ...#. ..#.. ..#.. .####. .#... .... .#.#. .##..#. .#####. .#... .#. .#. ",
|
" . . .. ..... . . . . . . . .... . ... . . ... ... ",
|
||||||
" .... ...#. .#. .#####. .#. .#####. .#####. .#####. .#..#. .####. .####. .#####. .. .#. ....#. .#####. .#. .#. ",
|
" ",
|
||||||
".####. .##. .## .#...#. .#. ...#. ..#.#. ..#.. .# .#. .#..#. ...#. .#.#. .##..#. .#. .#..#. .#..#. ",
|
//2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678
|
||||||
" .... .#. .#.# . .#. .#. .##. .#..#. .#####. .#. .#. . .#. .#. ..#. .. .#. .#. .#.#. . .#. ",
|
" .... .. . . . ... . . ... .... . . . ..... . . ",
|
||||||
" .#. .#. ..#. ..#.. .#.#. .#..#. ..#.. . .#. .#. ...#. .#. ...#. .#.#. .#... ...#. ",
|
" .####. ..##. .#.#.#. .###. .#. ..#.. .###. .####. ..#.. .#. . . .#. .. .#####. .#. ..#.. ..... ",
|
||||||
" .#. .#. .##. .#####. .#..#. .#..#. .#. .#. .#. .####. .#. .###. .#. .#. .###. .###. ",
|
" .#..#. .###. .#.#.#. ..... .#. .#####. ... ...#. .#####. .#. .#.#. .#..##. ....#. .#.#. .#####. .#####. ",
|
||||||
" . . .. ..... . . . . . . . .... . ... . . ... ... ",
|
" .####. ..#. .#.#.#. .#####. .##. ..#.. .#.#. ....#. .#. .#.#. .###.. .#. .#..#. ..#.. .#. ",
|
||||||
" ",
|
".#...#. .####. . ..#. ..#.. .#.#. .#. .#. .###. .#. .#. .#. .#.. .#. . .#. .#.#.#. .#.#. ",
|
||||||
//2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678
|
" . .#. ..#. ...#. .#. .#.. ..#. ..... .#.#. .#.#.#. .#. .#. .#. .#.... ..#. .#. .#.#.#. .#. ",
|
||||||
" .... .. . . . ... . . ... .... . . . ..... . . ",
|
" .#. .##. .###. .#. .#. .##. .#####. .#. .#. ..#.. .#. .#. .#. .####. .##. .#. ..#.. .#. ",
|
||||||
" .####. ..##. .#.#.#. .###. .#. ..#.. .###. .####. ..#.. .#. . . .#. .. .#####. .#. ..#.. ..... ",
|
" . .. ... . . .. ..... . . . . . . .... .. . . . ",
|
||||||
" .#..#. .###. .#.#.#. ..... .#. .#####. ... ...#. .#####. .#. .#.#. .#..##. ....#. .#.#. .#####. .#####. ",
|
" ",
|
||||||
" .####. ..#. .#.#.#. .#####. .##. ..#.. .#.#. ....#. .#. .#.#. .###.. .#. .#..#. ..#.. .#. ",
|
//2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678
|
||||||
".#...#. .####. . ..#. ..#.. .#.#. .#. .#. .###. .#. .#. .#. .#.. .#. . .#. .#.#.#. .#.#. ",
|
" .. . . ... . .... .... . . . . . ..... . . . . ",
|
||||||
" . .#. ..#. ...#. .#. .#.. ..#. ..... .#.#. .#.#.#. .#. .#. .#. .#.... ..#. .#. .#.#.#. .#. ",
|
" .##. .#. .#. .###. .#... ... .####. .####. .#..#. .#.#. .#. ..... .#####. ....#. .#.#. .#. ",
|
||||||
" .#. .##. .###. .#. .#. .##. .#####. .#. .#. ..#.. .#. .#. .#. .####. .##. .#. ..#.. .#. ",
|
" ..#. .#. . .#. .#. .#.##. .###. ...#. ..... .#..#. .#.#. .#. .#####. .#...#. .###.#. .#.#. .#.#. ",
|
||||||
" . .. ... . . .. ..... . . . . . . .... .. . . . ",
|
" .##. .#. . .#.#. .#####. .##.#. .#. .###. .#####. .#..#. .#.#. .#. . .#...#. . .#. ....#. . . .#. ",
|
||||||
" ",
|
" ..#. .#..#. .##. ..#.. .#.#. ..#. ..#. ....#. . .#. .#.#. .#..#. .#...#. .#. .#. . ",
|
||||||
//2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678
|
" .##. .####. ..#.#. .#.. .#. ...#. ...#. ..#. ..#. .#.#. .#.#. .#####. ..#. ...#. ",
|
||||||
" .. . . ... . .... .... . . . . . ..... . . . . ",
|
" ..#. ...#. .##. . .###. .#. .#####. .####. .##. .##. .#..##. .##. .#...#. .##. .###. ",
|
||||||
" .##. .#. .#. .###. .#... ... .####. .####. .#..#. .#.#. .#. ..... .#####. ....#. .#.#. .#. ",
|
" . . .. ... . ..... .... .. ... . .. .. . . .. ... ",
|
||||||
" ..#. .#. . .#. .#. .#.##. .###. ...#. ..... .#..#. .#.#. .#. .#####. .#...#. .###.#. .#.#. .#.#. ",
|
" ",
|
||||||
" .##. .#. . .#.#. .#####. .##.#. .#. .###. .#####. .#..#. .#.#. .#. . .#...#. . .#. ....#. . . .#. ",
|
|
||||||
" ..#. .#..#. .##. ..#.. .#.#. ..#. ..#. ....#. . .#. .#.#. .#..#. .#...#. .#. .#. . ",
|
" ",
|
||||||
" .##. .####. ..#.#. .#.. .#. ...#. ...#. ..#. ..#. .#.#. .#.#. .#####. ..#. ...#. ",
|
" ",
|
||||||
" ..#. ...#. .##. . .###. .#. .#####. .####. .##. .##. .#..##. .##. .#...#. .##. .###. ",
|
" ",
|
||||||
" . . .. ... . ..... .... .. ... . .. .. . . .. ... ",
|
" ",
|
||||||
" ",
|
" ",
|
||||||
//2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678
|
" ",
|
||||||
" ",
|
" ",
|
||||||
" ",
|
" ",
|
||||||
" ",
|
" ",
|
||||||
" ",
|
|
||||||
" ",
|
" ",
|
||||||
" ",
|
" ",
|
||||||
" ",
|
" ",
|
||||||
" ",
|
" ",
|
||||||
" ",
|
" ",
|
||||||
//2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678
|
" ",
|
||||||
" ",
|
" ",
|
||||||
" ",
|
" ",
|
||||||
" ",
|
" "
|
||||||
" ",
|
|
||||||
" ",
|
|
||||||
" ",
|
|
||||||
" ",
|
|
||||||
" ",
|
|
||||||
" "
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -159,62 +159,76 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _FXEMU_H_
|
#ifndef _FXEMU_H_
|
||||||
#define _FXEMU_H_
|
#define _FXEMU_H_ 1
|
||||||
|
|
||||||
#ifndef ZSNES_FX
|
#include "port.h"
|
||||||
|
|
||||||
// The FxInfo_s structure, the link between the FxEmulator and the Snes Emulator
|
/* The FxInfo_s structure, the link between the FxEmulator and the Snes Emulator */
|
||||||
struct FxInfo_s
|
struct FxInit_s
|
||||||
{
|
{
|
||||||
uint32 vFlags;
|
uint32 vFlags;
|
||||||
uint8 *pvRegisters; // 768 bytes located in the memory at address 0x3000
|
uint8 * pvRegisters; /* 768 bytes located in the memory at address 0x3000 */
|
||||||
uint32 nRamBanks; // Number of 64kb-banks in GSU-RAM/BackupRAM (banks 0x70-0x73)
|
uint32 nRamBanks; /* Number of 64kb-banks in GSU-RAM/BackupRAM (banks 0x70-0x73) */
|
||||||
uint8 *pvRam; // Pointer to GSU-RAM
|
uint8 * pvRam; /* Pointer to GSU-RAM */
|
||||||
uint32 nRomBanks; // Number of 32kb-banks in Cart-ROM
|
uint32 nRomBanks; /* Number of 32kb-banks in Cart-ROM */
|
||||||
uint8 *pvRom; // Pointer to Cart-ROM
|
uint8 * pvRom; /* Pointer to Cart-ROM */
|
||||||
uint32 speedPerLine;
|
uint32 speedPerLine;
|
||||||
bool8 oneLineDone;
|
bool8 oneLineDone;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct FxInfo_s SuperFX;
|
/* Reset the FxChip */
|
||||||
|
extern void FxReset(struct FxInit_s *psFxInfo);
|
||||||
|
|
||||||
void S9xInitSuperFX (void);
|
/* Execute until the next stop instruction */
|
||||||
void S9xSetSuperFX (uint8, uint16);
|
extern int FxEmulate(uint32 nInstructions);
|
||||||
uint8 S9xGetSuperFX (uint16);
|
|
||||||
void fx_flushCache (void);
|
|
||||||
void fx_computeScreenPointers (void);
|
|
||||||
uint32 fx_run (uint32);
|
|
||||||
|
|
||||||
#define FX_BREAKPOINT (-1)
|
/* Write access to the cache */
|
||||||
#define FX_ERROR_ILLEGAL_ADDRESS (-2)
|
extern void FxCacheWriteAccess(uint16 vAddress);
|
||||||
|
extern void FxFlushCache(); /* Callled when the G flag in SFR is set to zero */
|
||||||
|
|
||||||
#else
|
/* Breakpoint */
|
||||||
|
extern void FxBreakPointSet(uint32 vAddress);
|
||||||
|
extern void FxBreakPointClear();
|
||||||
|
|
||||||
extern uint8 *SFXPlotTable;
|
/* Step by step execution */
|
||||||
|
extern int FxStepOver(uint32 nInstructions);
|
||||||
|
|
||||||
#define S9xSetSuperFX S9xSuperFXWriteReg
|
/* Errors */
|
||||||
#define S9xGetSuperFX S9xSuperFXReadReg
|
extern int FxGetErrorCode();
|
||||||
|
extern int FxGetIllegalAddress();
|
||||||
|
|
||||||
START_EXTERN_C
|
/* Access to internal registers */
|
||||||
void S9xSuperFXWriteReg (uint8, uint32);
|
extern uint32 FxGetColorRegister();
|
||||||
uint8 S9xSuperFXReadReg (uint32);
|
extern uint32 FxGetPlotOptionRegister();
|
||||||
void S9xSuperFXPreSaveState (void);
|
extern uint32 FxGetSourceRegisterIndex();
|
||||||
void S9xSuperFXPostSaveState (void);
|
extern uint32 FxGetDestinationRegisterIndex();
|
||||||
void S9xSuperFXPostLoadState (void);
|
|
||||||
END_EXTERN_C
|
/* Get string for opcode currently in the pipe */
|
||||||
|
extern void FxPipeString(char * pvString);
|
||||||
|
|
||||||
|
/* Get the byte currently in the pipe */
|
||||||
|
extern uint8 FxPipe();
|
||||||
|
|
||||||
|
/* SCBR write seen. We need to update our cached screen pointers */
|
||||||
|
extern void fx_dirtySCBR (void);
|
||||||
|
|
||||||
|
/* Update RamBankReg and RAM Bank pointer */
|
||||||
|
extern void fx_updateRamBank(uint8 Byte);
|
||||||
|
|
||||||
|
/* Option flags */
|
||||||
|
#define FX_FLAG_ADDRESS_CHECKING 0x01
|
||||||
|
#define FX_FLAG_ROM_BUFFER 0x02
|
||||||
|
|
||||||
|
/* Return codes from FxEmulate(), FxStepInto() or FxStepOver() */
|
||||||
|
#define FX_BREAKPOINT -1
|
||||||
|
#define FX_ERROR_ILLEGAL_ADDRESS -2
|
||||||
|
|
||||||
|
/* Return the number of bytes in an opcode */
|
||||||
|
#define OPCODE_BYTES(op) ((((op)>=0x05&&(op)<=0xf)||((op)>=0xa0&&(op)<=0xaf))?2:(((op)>=0xf0)?3:1))
|
||||||
|
|
||||||
|
extern void fx_computeScreenPointers ();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ZSNES_FX
|
|
||||||
START_EXTERN_C
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void S9xResetSuperFX (void);
|
|
||||||
void S9xSuperFXExec (void);
|
|
||||||
|
|
||||||
#ifdef ZSNES_FX
|
|
||||||
END_EXTERN_C
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -159,74 +159,73 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _FXINST_H_
|
|
||||||
#define _FXINST_H_
|
|
||||||
|
|
||||||
#ifndef ZSNES_FX
|
#ifndef _FXINST_H_
|
||||||
|
#define _FXINST_H_ 1
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FxChip(GSU) register space specification
|
* FxChip(GSU) register space specification
|
||||||
* (Register address space 3000-32ff)
|
* (Register address space 3000->32ff)
|
||||||
*
|
*
|
||||||
* The 16 generic 16 bit registers:
|
* The 16 generic 16 bit registers:
|
||||||
* (Some have a special function in special circumstances)
|
* (Some have a special function in special circumstances)
|
||||||
* 3000 - R0 default source/destination register
|
* 3000 - R0 default source/destination register
|
||||||
* 3002 - R1 pixel plot X position register
|
* 3002 - R1 pixel plot X position register
|
||||||
* 3004 - R2 pixel plot Y position register
|
* 3004 - R2 pixel plot Y position register
|
||||||
* 3006 - R3
|
* 3006 - R3
|
||||||
* 3008 - R4 lower 16 bit result of lmult
|
* 3008 - R4 lower 16 bit result of lmult
|
||||||
* 300a - R5
|
* 300a - R5
|
||||||
* 300c - R6 multiplier for fmult and lmult
|
* 300c - R6 multiplier for fmult and lmult
|
||||||
* 300e - R7 fixed point texel X position for merge
|
* 300e - R7 fixed point texel X position for merge
|
||||||
* 3010 - R8 fixed point texel Y position for merge
|
* 3010 - R8 fixed point texel Y position for merge
|
||||||
* 3012 - R9
|
* 3012 - R9
|
||||||
* 3014 - R10
|
* 3014 - R10
|
||||||
* 3016 - R11 return address set by link
|
* 3016 - R11 return address set by link
|
||||||
* 3018 - R12 loop counter
|
* 3018 - R12 loop counter
|
||||||
* 301a - R13 loop point address
|
* 301a - R13 loop point address
|
||||||
* 301c - R14 rom address for getb, getbh, getbl, getbs
|
* 301c - R14 rom address for getb, getbh, getbl, getbs
|
||||||
* 301e - R15 program counter
|
* 301e - R15 program counter
|
||||||
*
|
*
|
||||||
* 3020-302f - unused
|
* 3020-302f - unused
|
||||||
*
|
*
|
||||||
* Other internal registers
|
* Other internal registers
|
||||||
* 3030 - SFR status flag register (16bit)
|
* 3030 - SFR status flag register (16bit)
|
||||||
* 3032 - unused
|
* 3032 - unused
|
||||||
* 3033 - BRAMR Backup RAM register (8bit)
|
* 3033 - BRAMR Backup RAM register (8bit)
|
||||||
* 3034 - PBR program bank register (8bit)
|
* 3034 - PBR program bank register (8bit)
|
||||||
* 3035 - unused
|
* 3035 - unused
|
||||||
* 3036 - ROMBR rom bank register (8bit)
|
* 3036 - ROMBR rom bank register (8bit)
|
||||||
* 3037 - CFGR control flags register (8bit)
|
* 3037 - CFGR control flags register (8bit)
|
||||||
* 3038 - SCBR screen base register (8bit)
|
* 3038 - SCBR screen base register (8bit)
|
||||||
* 3039 - CLSR clock speed register (8bit)
|
* 3039 - CLSR clock speed register (8bit)
|
||||||
* 303a - SCMR screen mode register (8bit)
|
* 303a - SCMR screen mode register (8bit)
|
||||||
* 303b - VCR version code register (8bit) (read only)
|
* 303b - VCR version code register (8bit) (read only)
|
||||||
* 303c - RAMBR ram bank register (8bit)
|
* 303c - RAMBR ram bank register (8bit)
|
||||||
* 303d - unused
|
* 303d - unused
|
||||||
* 303e - CBR cache base register (16bit)
|
* 303e - CBR cache base register (16bit)
|
||||||
*
|
*
|
||||||
* 3040-30ff - unused
|
* 3040-30ff - unused
|
||||||
*
|
*
|
||||||
* 3100-32ff - CACHERAM 512 bytes of GSU cache memory
|
* 3100-32ff - CACHERAM 512 bytes of GSU cache memory
|
||||||
*
|
*
|
||||||
* SFR status flag register bits:
|
* SFR status flag register bits:
|
||||||
* 0 -
|
* 0 -
|
||||||
* 1 Z Zero flag
|
* 1 Z Zero flag
|
||||||
* 2 CY Carry flag
|
* 2 CY Carry flag
|
||||||
* 3 S Sign flag
|
* 3 S Sign flag
|
||||||
* 4 OV Overflow flag
|
* 4 OV Overflow flag
|
||||||
* 5 G Go flag (set to 1 when the GSU is running)
|
* 5 G Go flag (set to 1 when the GSU is running)
|
||||||
* 6 R Set to 1 when reading ROM using R14 address
|
* 6 R Set to 1 when reading ROM using R14 address
|
||||||
* 7 -
|
* 7 -
|
||||||
* 8 ALT1 Mode set-up flag for the next instruction
|
* 8 ALT1 Mode set-up flag for the next instruction
|
||||||
* 9 ALT2 Mode set-up flag for the next instruction
|
* 9 ALT2 Mode set-up flag for the next instruction
|
||||||
* 10 IL Immediate lower 8-bit flag
|
* 10 IL Immediate lower 8-bit flag
|
||||||
* 11 IH Immediate higher 8-bit flag
|
* 11 IH Immediate higher 8-bit flag
|
||||||
* 12 B Set to 1 when the WITH instruction is executed
|
* 12 B Set to 1 when the WITH instruction is executed
|
||||||
* 13 -
|
* 13 -
|
||||||
* 14 -
|
* 14 -
|
||||||
* 15 IRQ Set to 1 when GSU caused an interrupt
|
* 15 IRQ Set to 1 when GSU caused an interrupt
|
||||||
* Set to 0 when read by 658c16
|
* Set to 0 when read by 658c16
|
||||||
*
|
*
|
||||||
* BRAMR = 0, BackupRAM is disabled
|
* BRAMR = 0, BackupRAM is disabled
|
||||||
* BRAMR = 1, BackupRAM is enabled
|
* BRAMR = 1, BackupRAM is enabled
|
||||||
@ -237,44 +236,44 @@
|
|||||||
* 2 -
|
* 2 -
|
||||||
* 3 -
|
* 3 -
|
||||||
* 4 -
|
* 4 -
|
||||||
* 5 MS0 Multiplier speed, 0=standard, 1=high speed
|
* 5 MS0 Multiplier speed, 0=standard, 1=high speed
|
||||||
* 6 -
|
* 6 -
|
||||||
* 7 IRQ Set to 1 when GSU interrupt request is masked
|
* 7 IRQ Set to 1 when GSU interrupt request is masked
|
||||||
*
|
*
|
||||||
* CLSR clock speed register bits:
|
* CLSR clock speed register bits:
|
||||||
* 0 CLSR clock speed, 0 = 10.7Mhz, 1 = 21.4Mhz
|
* 0 CLSR clock speed, 0 = 10.7Mhz, 1 = 21.4Mhz
|
||||||
*
|
*
|
||||||
* SCMR screen mode register bits:
|
* SCMR screen mode register bits:
|
||||||
* 0 MD0 color depth mode bit 0
|
* 0 MD0 color depth mode bit 0
|
||||||
* 1 MD1 color depth mode bit 1
|
* 1 MD1 color depth mode bit 1
|
||||||
* 2 HT0 screen height bit 1
|
* 2 HT0 screen height bit 1
|
||||||
* 3 RAN RAM access control
|
* 3 RAN RAM access control
|
||||||
* 4 RON ROM access control
|
* 4 RON ROM access control
|
||||||
* 5 HT1 screen height bit 2
|
* 5 HT1 screen height bit 2
|
||||||
* 6 -
|
* 6 -
|
||||||
* 7 -
|
* 7 -
|
||||||
*
|
*
|
||||||
* RON = 0 SNES CPU has ROM access
|
* RON = 0 SNES CPU has ROM access
|
||||||
* RON = 1 GSU has ROM access
|
* RON = 1 GSU has ROM access
|
||||||
*
|
*
|
||||||
* RAN = 0 SNES has game pak RAM access
|
* RAN = 0 SNES has game pak RAM access
|
||||||
* RAN = 1 GSU has game pak RAM access
|
* RAN = 1 GSU has game pak RAM access
|
||||||
*
|
*
|
||||||
* HT1 HT0 Screen height mode
|
* HT1 HT0 Screen height mode
|
||||||
* 0 0 128 pixels high
|
* 0 0 128 pixels high
|
||||||
* 0 1 160 pixels high
|
* 0 1 160 pixels high
|
||||||
* 1 0 192 pixels high
|
* 1 0 192 pixels high
|
||||||
* 1 1 OBJ mode
|
* 1 1 OBJ mode
|
||||||
*
|
*
|
||||||
* MD1 MD0 Color depth mode
|
* MD1 MD0 Color depth mode
|
||||||
* 0 0 4 color mode
|
* 0 0 4 color mode
|
||||||
* 0 1 16 color mode
|
* 0 1 16 color mode
|
||||||
* 1 0 not used
|
* 1 0 not used
|
||||||
* 1 1 256 color mode
|
* 1 1 256 color mode
|
||||||
*
|
*
|
||||||
* CBR cache base register bits:
|
* CBR cache base register bits:
|
||||||
* 15-4 Specify base address for data to cache from ROM or RAM
|
* 15-4 Specify base address for data to cache from ROM or RAM
|
||||||
* 3-0 Are 0 when address is read
|
* 3-0 Are 0 when address is read
|
||||||
*
|
*
|
||||||
* Write access to the program counter (301e) from
|
* Write access to the program counter (301e) from
|
||||||
* the SNES-CPU will start the GSU, and it will not
|
* the SNES-CPU will start the GSU, and it will not
|
||||||
@ -282,247 +281,270 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Number of banks in GSU RAM
|
/* Number of banks in GSU RAM */
|
||||||
#define FX_RAM_BANKS 4
|
#define FX_RAM_BANKS 4
|
||||||
|
|
||||||
// Emulate proper R14 ROM access (slower, but safer)
|
/* Emulate proper R14 ROM access (slower, but safer) */
|
||||||
#define FX_DO_ROMBUFFER
|
/* #define FX_DO_ROMBUFFER */
|
||||||
|
|
||||||
// Address checking (definately slow)
|
/* Address checking (definately slow) */
|
||||||
//#define FX_ADDRESS_CHECK
|
/* #define FX_ADDRESS_CHECK */
|
||||||
|
|
||||||
struct FxRegs_s
|
struct FxRegs_s
|
||||||
{
|
{
|
||||||
// FxChip registers
|
/* FxChip registers */
|
||||||
uint32 avReg[16]; // 16 Generic registers
|
uint32 avReg[16]; /* 16 Generic registers */
|
||||||
uint32 vColorReg; // Internal color register
|
uint32 vColorReg; /* Internal color register */
|
||||||
uint32 vPlotOptionReg; // Plot option register
|
uint32 vPlotOptionReg; /* Plot option register */
|
||||||
uint32 vStatusReg; // Status register
|
uint32 vStatusReg; /* Status register */
|
||||||
uint32 vPrgBankReg; // Program bank index register
|
uint32 vPrgBankReg; /* Program bank index register */
|
||||||
uint32 vRomBankReg; // Rom bank index register
|
uint32 vRomBankReg; /* Rom bank index register */
|
||||||
uint32 vRamBankReg; // Ram bank index register
|
uint32 vRamBankReg; /* Ram bank index register */
|
||||||
uint32 vCacheBaseReg; // Cache base address register
|
uint32 vCacheBaseReg; /* Cache base address register */
|
||||||
uint32 vCacheFlags; // Saying what parts of the cache was written to
|
uint32 vCacheFlags; /* Saying what parts of the cache was written to */
|
||||||
uint32 vLastRamAdr; // Last RAM address accessed
|
uint32 vLastRamAdr; /* Last RAM address accessed */
|
||||||
uint32 *pvDreg; // Pointer to current destination register
|
uint32 * pvDreg; /* Pointer to current destination register */
|
||||||
uint32 *pvSreg; // Pointer to current source register
|
uint32 * pvSreg; /* Pointer to current source register */
|
||||||
uint8 vRomBuffer; // Current byte read by R14
|
uint8 vRomBuffer; /* Current byte read by R14 */
|
||||||
uint8 vPipe; // Instructionset pipe
|
uint8 vPipe; /* Instructionset pipe */
|
||||||
uint32 vPipeAdr; // The address of where the pipe was read from
|
uint32 vPipeAdr; /* The address of where the pipe was read from */
|
||||||
|
|
||||||
// Status register optimization stuff
|
/* status register optimization stuff */
|
||||||
uint32 vSign; // v & 0x8000
|
uint32 vSign; /* v & 0x8000 */
|
||||||
uint32 vZero; // v == 0
|
uint32 vZero; /* v == 0 */
|
||||||
uint32 vCarry; // a value of 1 or 0
|
uint32 vCarry; /* a value of 1 or 0 */
|
||||||
int32 vOverflow; // (v >= 0x8000 || v < -0x8000)
|
int32 vOverflow; /* (v >= 0x8000 || v < -0x8000) */
|
||||||
|
|
||||||
// Other emulator variables
|
/* Other emulator variables */
|
||||||
int32 vErrorCode;
|
|
||||||
uint32 vIllegalAddress;
|
|
||||||
|
|
||||||
uint8 bBreakPoint;
|
int32 vErrorCode;
|
||||||
uint32 vBreakPoint;
|
uint32 vIllegalAddress;
|
||||||
uint32 vStepPoint;
|
|
||||||
|
|
||||||
uint8 *pvRegisters; // 768 bytes located in the memory at address 0x3000
|
uint8 bBreakPoint;
|
||||||
uint32 nRamBanks; // Number of 64kb-banks in FxRam (Don't confuse it with SNES-Ram!!!)
|
uint32 vBreakPoint;
|
||||||
uint8 *pvRam; // Pointer to FxRam
|
uint32 vStepPoint;
|
||||||
uint32 nRomBanks; // Number of 32kb-banks in Cart-ROM
|
|
||||||
uint8 *pvRom; // Pointer to Cart-ROM
|
|
||||||
|
|
||||||
uint32 vMode; // Color depth/mode
|
uint8 * pvRegisters; /* 768 bytes located in the memory at address 0x3000 */
|
||||||
uint32 vPrevMode; // Previous depth
|
uint32 nRamBanks; /* Number of 64kb-banks in FxRam (Don't confuse it with SNES-Ram!!!) */
|
||||||
uint8 *pvScreenBase;
|
uint8 * pvRam; /* Pointer to FxRam */
|
||||||
uint8 *apvScreen[32]; // Pointer to each of the 32 screen colums
|
uint32 nRomBanks; /* Number of 32kb-banks in Cart-ROM */
|
||||||
int32 x[32];
|
uint8 * pvRom; /* Pointer to Cart-ROM */
|
||||||
uint32 vScreenHeight; // 128, 160, 192 or 256 (could be overriden by cmode)
|
|
||||||
uint32 vScreenRealHeight; // 128, 160, 192 or 256
|
|
||||||
uint32 vPrevScreenHeight;
|
|
||||||
uint32 vScreenSize;
|
|
||||||
void (*pfPlot) (void);
|
|
||||||
void (*pfRpix) (void);
|
|
||||||
|
|
||||||
uint8 *pvRamBank; // Pointer to current RAM-bank
|
uint32 vMode; /* Color depth/mode */
|
||||||
uint8 *pvRomBank; // Pointer to current ROM-bank
|
uint32 vPrevMode; /* Previous depth */
|
||||||
uint8 *pvPrgBank; // Pointer to current program ROM-bank
|
uint8 * pvScreenBase;
|
||||||
|
uint8 * apvScreen[32]; /* Pointer to each of the 32 screen colums */
|
||||||
|
int32 x[32];
|
||||||
|
uint32 vScreenHeight; /* 128, 160, 192 or 256 (could be overriden by cmode) */
|
||||||
|
uint32 vScreenRealHeight; /* 128, 160, 192 or 256 */
|
||||||
|
uint32 vPrevScreenHeight;
|
||||||
|
uint32 vScreenSize;
|
||||||
|
void (*pfPlot)();
|
||||||
|
void (*pfRpix)();
|
||||||
|
|
||||||
uint8 *apvRamBank[FX_RAM_BANKS]; // Ram bank table (max 256kb)
|
uint8 * pvRamBank; /* Pointer to current RAM-bank */
|
||||||
uint8 *apvRomBank[256]; // Rom bank table
|
uint8 * pvRomBank; /* Pointer to current ROM-bank */
|
||||||
|
uint8 * pvPrgBank; /* Pointer to current program ROM-bank */
|
||||||
|
|
||||||
uint8 bCacheActive;
|
uint8 * apvRamBank[FX_RAM_BANKS];/* Ram bank table (max 256kb) */
|
||||||
uint8 *pvCache; // Pointer to the GSU cache
|
uint8 * apvRomBank[256]; /* Rom bank table */
|
||||||
uint8 avCacheBackup[512]; // Backup of ROM when the cache has replaced it
|
|
||||||
uint32 vCounter;
|
uint8 bCacheActive;
|
||||||
uint32 vInstCount;
|
uint8 * pvCache; /* Pointer to the GSU cache */
|
||||||
uint32 vSCBRDirty; // If SCBR is written, our cached screen pointers need updating
|
uint8 avCacheBackup[512]; /* Backup of ROM when the cache has replaced it */
|
||||||
|
uint32 vCounter;
|
||||||
|
uint32 vInstCount;
|
||||||
|
uint32 vSCBRDirty; /* if SCBR is written, our cached screen pointers need updating */
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct FxRegs_s GSU;
|
#define FxRegs_s_null { \
|
||||||
|
{0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
|
||||||
|
NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, \
|
||||||
|
0, 0, 0, 0, NULL, 0, NULL, 0, NULL, 0, \
|
||||||
|
0, NULL, {NULL}, {0}, 0, 0, 0, 0, NULL, NULL, \
|
||||||
|
NULL, NULL, NULL, {NULL}, {NULL}, 0, NULL, {0}, 0, 0, \
|
||||||
|
0, \
|
||||||
|
}
|
||||||
|
|
||||||
// GSU registers
|
/* GSU registers */
|
||||||
#define GSU_R0 0x000
|
#define GSU_R0 0x000
|
||||||
#define GSU_R1 0x002
|
#define GSU_R1 0x002
|
||||||
#define GSU_R2 0x004
|
#define GSU_R2 0x004
|
||||||
#define GSU_R3 0x006
|
#define GSU_R3 0x006
|
||||||
#define GSU_R4 0x008
|
#define GSU_R4 0x008
|
||||||
#define GSU_R5 0x00a
|
#define GSU_R5 0x00a
|
||||||
#define GSU_R6 0x00c
|
#define GSU_R6 0x00c
|
||||||
#define GSU_R7 0x00e
|
#define GSU_R7 0x00e
|
||||||
#define GSU_R8 0x010
|
#define GSU_R8 0x010
|
||||||
#define GSU_R9 0x012
|
#define GSU_R9 0x012
|
||||||
#define GSU_R10 0x014
|
#define GSU_R10 0x014
|
||||||
#define GSU_R11 0x016
|
#define GSU_R11 0x016
|
||||||
#define GSU_R12 0x018
|
#define GSU_R12 0x018
|
||||||
#define GSU_R13 0x01a
|
#define GSU_R13 0x01a
|
||||||
#define GSU_R14 0x01c
|
#define GSU_R14 0x01c
|
||||||
#define GSU_R15 0x01e
|
#define GSU_R15 0x01e
|
||||||
#define GSU_SFR 0x030
|
#define GSU_SFR 0x030
|
||||||
#define GSU_BRAMR 0x033
|
#define GSU_BRAMR 0x033
|
||||||
#define GSU_PBR 0x034
|
#define GSU_PBR 0x034
|
||||||
#define GSU_ROMBR 0x036
|
#define GSU_ROMBR 0x036
|
||||||
#define GSU_CFGR 0x037
|
#define GSU_CFGR 0x037
|
||||||
#define GSU_SCBR 0x038
|
#define GSU_SCBR 0x038
|
||||||
#define GSU_CLSR 0x039
|
#define GSU_CLSR 0x039
|
||||||
#define GSU_SCMR 0x03a
|
#define GSU_SCMR 0x03a
|
||||||
#define GSU_VCR 0x03b
|
#define GSU_VCR 0x03b
|
||||||
#define GSU_RAMBR 0x03c
|
#define GSU_RAMBR 0x03c
|
||||||
#define GSU_CBR 0x03e
|
#define GSU_CBR 0x03e
|
||||||
#define GSU_CACHERAM 0x100
|
#define GSU_CACHERAM 0x100
|
||||||
|
|
||||||
// SFR flags
|
/* SFR flags */
|
||||||
#define FLG_Z (1 << 1)
|
#define FLG_Z (1<<1)
|
||||||
#define FLG_CY (1 << 2)
|
#define FLG_CY (1<<2)
|
||||||
#define FLG_S (1 << 3)
|
#define FLG_S (1<<3)
|
||||||
#define FLG_OV (1 << 4)
|
#define FLG_OV (1<<4)
|
||||||
#define FLG_G (1 << 5)
|
#define FLG_G (1<<5)
|
||||||
#define FLG_R (1 << 6)
|
#define FLG_R (1<<6)
|
||||||
#define FLG_ALT1 (1 << 8)
|
#define FLG_ALT1 (1<<8)
|
||||||
#define FLG_ALT2 (1 << 9)
|
#define FLG_ALT2 (1<<9)
|
||||||
#define FLG_IL (1 << 10)
|
#define FLG_IL (1<<10)
|
||||||
#define FLG_IH (1 << 11)
|
#define FLG_IH (1<<11)
|
||||||
#define FLG_B (1 << 12)
|
#define FLG_B (1<<12)
|
||||||
#define FLG_IRQ (1 << 15)
|
#define FLG_IRQ (1<<15)
|
||||||
|
|
||||||
// Test flag
|
/* Test flag */
|
||||||
#define TF(a) (GSU.vStatusReg & FLG_##a)
|
#define TF(a) (GSU.vStatusReg & FLG_##a )
|
||||||
#define CF(a) (GSU.vStatusReg &= ~FLG_##a)
|
#define CF(a) (GSU.vStatusReg &= ~FLG_##a )
|
||||||
#define SF(a) (GSU.vStatusReg |= FLG_##a)
|
#define SF(a) (GSU.vStatusReg |= FLG_##a )
|
||||||
|
|
||||||
// Test and set flag if condition, clear if not
|
/* Test and set flag if condition, clear if not */
|
||||||
#define TS(a, b) GSU.vStatusReg = ((GSU.vStatusReg & (~FLG_##a)) | ((!!(##b)) * FLG_##a))
|
#define TS(a,b) GSU.vStatusReg = ( (GSU.vStatusReg & (~FLG_##a)) | ( (!!(##b)) * FLG_##a ) )
|
||||||
|
|
||||||
// Testing ALT1 & ALT2 bits
|
/* Testing ALT1 & ALT2 bits */
|
||||||
#define ALT0 (!TF(ALT1) && !TF(ALT2))
|
#define ALT0 (!TF(ALT1)&&!TF(ALT2))
|
||||||
#define ALT1 ( TF(ALT1) && !TF(ALT2))
|
#define ALT1 (TF(ALT1)&&!TF(ALT2))
|
||||||
#define ALT2 (!TF(ALT1) && TF(ALT2))
|
#define ALT2 (!TF(ALT1)&&TF(ALT2))
|
||||||
#define ALT3 ( TF(ALT1) && TF(ALT2))
|
#define ALT3 (TF(ALT1)&&TF(ALT2))
|
||||||
|
|
||||||
// Sign extend from 8/16 bit to 32 bit
|
/* Sign extend from 8/16 bit to 32 bit */
|
||||||
#define SEX8(a) ((int32) ((int8) (a)))
|
#define SEX16(a) ((int32)((int16)(a)))
|
||||||
#define SEX16(a) ((int32) ((int16) (a)))
|
#define SEX8(a) ((int32)((int8)(a)))
|
||||||
|
|
||||||
// Unsign extend from 8/16 bit to 32 bit
|
/* Unsign extend from 8/16 bit to 32 bit */
|
||||||
#define USEX8(a) ((uint32) ((uint8) (a)))
|
#define USEX16(a) ((uint32)((uint16)(a)))
|
||||||
#define USEX16(a) ((uint32) ((uint16) (a)))
|
#define USEX8(a) ((uint32)((uint8)(a)))
|
||||||
#define SUSEX16(a) ((int32) ((uint16) (a)))
|
|
||||||
|
|
||||||
// Set/Clr Sign and Zero flag
|
#define SUSEX16(a) ((int32)((uint16)(a)))
|
||||||
#define TSZ(num) TS(S, ((num) & 0x8000)); TS(Z, (!USEX16(num)))
|
|
||||||
|
|
||||||
// Clear flags
|
/* Set/Clr Sign and Zero flag */
|
||||||
#define CLRFLAGS GSU.vStatusReg &= ~(FLG_ALT1 | FLG_ALT2 | FLG_B); GSU.pvDreg = GSU.pvSreg = &R0
|
#define TSZ(num) TS(S, (num & 0x8000)); TS(Z, (!USEX16(num)) )
|
||||||
|
|
||||||
// Read current RAM-Bank
|
/* Clear flags */
|
||||||
#define RAM(adr) GSU.pvRamBank[USEX16(adr)]
|
#define CLRFLAGS GSU.vStatusReg &= ~(FLG_ALT1|FLG_ALT2|FLG_B); GSU.pvDreg = GSU.pvSreg = &R0;
|
||||||
|
|
||||||
// Read current ROM-Bank
|
/* Read current RAM-Bank */
|
||||||
#define ROM(idx) GSU.pvRomBank[USEX16(idx)]
|
#define RAM(adr) GSU.pvRamBank[USEX16(adr)]
|
||||||
|
|
||||||
// Access the current value in the pipe
|
/* Read current ROM-Bank */
|
||||||
#define PIPE GSU.vPipe
|
#define ROM(idx) (GSU.pvRomBank[USEX16(idx)])
|
||||||
|
|
||||||
// Access data in the current program bank
|
/* Access the current value in the pipe */
|
||||||
#define PRGBANK(idx) GSU.pvPrgBank[USEX16(idx)]
|
#define PIPE GSU.vPipe
|
||||||
|
|
||||||
// Update pipe from ROM
|
/* Access data in the current program bank */
|
||||||
|
#define PRGBANK(idx) GSU.pvPrgBank[USEX16(idx)]
|
||||||
|
|
||||||
|
/* Update pipe from ROM */
|
||||||
#if 0
|
#if 0
|
||||||
#define FETCHPIPE { PIPE = PRGBANK(R15); GSU.vPipeAdr = (GSU.vPrgBankReg << 16) + R15; }
|
#define FETCHPIPE { PIPE = PRGBANK(R15); GSU.vPipeAdr = (GSU.vPrgBankReg<<16) + R15; }
|
||||||
#else
|
#else
|
||||||
#define FETCHPIPE { PIPE = PRGBANK(R15); }
|
#define FETCHPIPE { PIPE = PRGBANK(R15); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ABS
|
/* ABS */
|
||||||
#define ABS(x) ((x) < 0 ? -(x) : (x))
|
#define ABS(x) ((x)<0?-(x):(x))
|
||||||
|
|
||||||
// Access source register
|
/* Access source register */
|
||||||
#define SREG (*GSU.pvSreg)
|
#define SREG (*GSU.pvSreg)
|
||||||
|
|
||||||
// Access destination register
|
/* Access destination register */
|
||||||
#define DREG (*GSU.pvDreg)
|
#define DREG (*GSU.pvDreg)
|
||||||
|
|
||||||
#ifndef FX_DO_ROMBUFFER
|
#ifndef FX_DO_ROMBUFFER
|
||||||
|
|
||||||
// Don't read R14
|
/* Don't read R14 */
|
||||||
#define READR14
|
#define READR14
|
||||||
|
|
||||||
// Don't test and/or read R14
|
/* Don't test and/or read R14 */
|
||||||
#define TESTR14
|
#define TESTR14
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
// Read R14
|
/* Read R14 */
|
||||||
#define READR14 GSU.vRomBuffer = ROM(R14)
|
#define READR14 GSU.vRomBuffer = ROM(R14)
|
||||||
|
|
||||||
// Test and/or read R14
|
/* Test and/or read R14 */
|
||||||
#define TESTR14 if (GSU.pvDreg == &R14) READR14
|
#define TESTR14 if(GSU.pvDreg == &R14) READR14
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Access to registers
|
/* Access to registers */
|
||||||
#define R0 GSU.avReg[0]
|
#define R0 GSU.avReg[0]
|
||||||
#define R1 GSU.avReg[1]
|
#define R1 GSU.avReg[1]
|
||||||
#define R2 GSU.avReg[2]
|
#define R2 GSU.avReg[2]
|
||||||
#define R3 GSU.avReg[3]
|
#define R3 GSU.avReg[3]
|
||||||
#define R4 GSU.avReg[4]
|
#define R4 GSU.avReg[4]
|
||||||
#define R5 GSU.avReg[5]
|
#define R5 GSU.avReg[5]
|
||||||
#define R6 GSU.avReg[6]
|
#define R6 GSU.avReg[6]
|
||||||
#define R7 GSU.avReg[7]
|
#define R7 GSU.avReg[7]
|
||||||
#define R8 GSU.avReg[8]
|
#define R8 GSU.avReg[8]
|
||||||
#define R9 GSU.avReg[9]
|
#define R9 GSU.avReg[9]
|
||||||
#define R10 GSU.avReg[10]
|
#define R10 GSU.avReg[10]
|
||||||
#define R11 GSU.avReg[11]
|
#define R11 GSU.avReg[11]
|
||||||
#define R12 GSU.avReg[12]
|
#define R12 GSU.avReg[12]
|
||||||
#define R13 GSU.avReg[13]
|
#define R13 GSU.avReg[13]
|
||||||
#define R14 GSU.avReg[14]
|
#define R14 GSU.avReg[14]
|
||||||
#define R15 GSU.avReg[15]
|
#define R15 GSU.avReg[15]
|
||||||
#define SFR GSU.vStatusReg
|
#define SFR GSU.vStatusReg
|
||||||
#define PBR GSU.vPrgBankReg
|
#define PBR GSU.vPrgBankReg
|
||||||
#define ROMBR GSU.vRomBankReg
|
#define ROMBR GSU.vRomBankReg
|
||||||
#define RAMBR GSU.vRamBankReg
|
#define RAMBR GSU.vRamBankReg
|
||||||
#define CBR GSU.vCacheBaseReg
|
#define CBR GSU.vCacheBaseReg
|
||||||
#define SCBR USEX8(GSU.pvRegisters[GSU_SCBR])
|
#define SCBR USEX8(GSU.pvRegisters[GSU_SCBR])
|
||||||
#define SCMR USEX8(GSU.pvRegisters[GSU_SCMR])
|
#define SCMR USEX8(GSU.pvRegisters[GSU_SCMR])
|
||||||
#define COLR GSU.vColorReg
|
#define COLR GSU.vColorReg
|
||||||
#define POR GSU.vPlotOptionReg
|
#define POR GSU.vPlotOptionReg
|
||||||
#define BRAMR USEX8(GSU.pvRegisters[GSU_BRAMR])
|
#define BRAMR USEX8(GSU.pvRegisters[GSU_BRAMR])
|
||||||
#define VCR USEX8(GSU.pvRegisters[GSU_VCR])
|
#define VCR USEX8(GSU.pvRegisters[GSU_VCR])
|
||||||
#define CFGR USEX8(GSU.pvRegisters[GSU_CFGR])
|
#define CFGR USEX8(GSU.pvRegisters[GSU_CFGR])
|
||||||
#define CLSR USEX8(GSU.pvRegisters[GSU_CLSR])
|
#define CLSR USEX8(GSU.pvRegisters[GSU_CLSR])
|
||||||
|
|
||||||
// Execute instruction from the pipe, and fetch next byte to the pipe
|
/* Execute instruction from the pipe, and fetch next byte to the pipe */
|
||||||
#define FX_STEP \
|
#define FX_STEP { uint32 vOpcode = (uint32)PIPE; FETCHPIPE; \
|
||||||
{ \
|
(*fx_ppfOpcodeTable[ (GSU.vStatusReg & 0x300) | vOpcode ])(); } \
|
||||||
uint32 vOpcode = (uint32) PIPE; \
|
|
||||||
FETCHPIPE; \
|
|
||||||
(*fx_OpcodeTable[(GSU.vStatusReg & 0x300) | vOpcode])(); \
|
|
||||||
}
|
|
||||||
|
|
||||||
extern void (*fx_PlotTable[]) (void);
|
#define FX_FUNCTION_RUN 0
|
||||||
extern void (*fx_OpcodeTable[]) (void);
|
#define FX_FUNCTION_RUN_TO_BREAKPOINT 1
|
||||||
|
#define FX_FUNCTION_STEP_OVER 2
|
||||||
|
|
||||||
// Set this define if branches are relative to the instruction in the delay slot (I think they are)
|
extern uint32 (**fx_ppfFunctionTable)(uint32);
|
||||||
|
extern void (**fx_ppfPlotTable)();
|
||||||
|
extern void (**fx_ppfOpcodeTable)();
|
||||||
|
|
||||||
|
extern uint32 (*fx_apfFunctionTable[])(uint32);
|
||||||
|
extern void (*fx_apfOpcodeTable[])();
|
||||||
|
extern void (*fx_apfPlotTable[])();
|
||||||
|
extern uint32 (*fx_a_apfFunctionTable[])(uint32);
|
||||||
|
extern void (*fx_a_apfOpcodeTable[])();
|
||||||
|
extern void (*fx_a_apfPlotTable[])();
|
||||||
|
extern uint32 (*fx_r_apfFunctionTable[])(uint32);
|
||||||
|
extern void (*fx_r_apfOpcodeTable[])();
|
||||||
|
extern void (*fx_r_apfPlotTable[])();
|
||||||
|
extern uint32 (*fx_ar_apfFunctionTable[])(uint32);
|
||||||
|
extern void (*fx_ar_apfOpcodeTable[])();
|
||||||
|
extern void (*fx_ar_apfPlotTable[])();
|
||||||
|
|
||||||
|
/* Set this define if branches are relative to the instruction in the delay slot */
|
||||||
|
/* (I think they are) */
|
||||||
#define BRANCH_DELAY_RELATIVE
|
#define BRANCH_DELAY_RELATIVE
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -159,150 +159,177 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _GFX_H_
|
#ifndef _GFX_H_
|
||||||
#define _GFX_H_
|
#define _GFX_H_
|
||||||
|
|
||||||
struct SGFX
|
#include "port.h"
|
||||||
{
|
#include "snes9x.h"
|
||||||
uint16 *Screen;
|
|
||||||
uint16 *SubScreen;
|
|
||||||
uint8 *ZBuffer;
|
|
||||||
uint8 *SubZBuffer;
|
|
||||||
uint32 Pitch;
|
|
||||||
uint32 ScreenSize;
|
|
||||||
uint16 *S;
|
|
||||||
uint8 *DB;
|
|
||||||
uint16 *X2;
|
|
||||||
uint16 *ZERO;
|
|
||||||
uint32 RealPPL; // true PPL of Screen buffer
|
|
||||||
uint32 PPL; // number of pixels on each of Screen buffer
|
|
||||||
uint32 LinesPerTile; // number of lines in 1 tile (4 or 8 due to interlace)
|
|
||||||
uint16 *ScreenColors; // screen colors for rendering main
|
|
||||||
uint16 *RealScreenColors; // screen colors, ignoring color window clipping
|
|
||||||
uint8 Z1; // depth for comparison
|
|
||||||
uint8 Z2; // depth to save
|
|
||||||
uint32 FixedColour;
|
|
||||||
uint8 DoInterlace;
|
|
||||||
uint8 InterlaceFrame;
|
|
||||||
uint32 StartY;
|
|
||||||
uint32 EndY;
|
|
||||||
bool8 ClipColors;
|
|
||||||
uint8 OBJWidths[128];
|
|
||||||
uint8 OBJVisibleTiles[128];
|
|
||||||
|
|
||||||
struct ClipData *Clip;
|
struct SGFX{
|
||||||
|
// Initialize these variables
|
||||||
|
uint16 *Screen;
|
||||||
|
uint16 *SubScreen;
|
||||||
|
uint8 *ZBuffer;
|
||||||
|
uint8 *SubZBuffer;
|
||||||
|
uint32 Pitch;
|
||||||
|
uint32 ScreenSize;
|
||||||
|
|
||||||
struct
|
uint16 *S;
|
||||||
{
|
uint8 *DB;
|
||||||
uint8 RTOFlags;
|
|
||||||
int16 Tiles;
|
|
||||||
|
|
||||||
struct
|
// Setup in call to S9xGraphicsInit()
|
||||||
{
|
uint16 *X2;
|
||||||
int8 Sprite;
|
uint16 *ZERO_OR_X2;
|
||||||
uint8 Line;
|
uint16 *ZERO;
|
||||||
} OBJ[32];
|
|
||||||
} OBJLines[SNES_HEIGHT_EXTENDED];
|
uint32 RealPPL; // True PPL of Screen buffer.
|
||||||
|
uint32 PPL; // Number of pixels on each of Screen buffer
|
||||||
|
uint32 LinesPerTile; // number of lines in 1 tile (4 or 8 due to interlace)
|
||||||
|
uint16 *ScreenColors; // Screen colors for rendering main
|
||||||
|
uint16 *RealScreenColors; // Screen colors, ignoring color window clipping
|
||||||
|
uint8 Z1; // Depth for comparison
|
||||||
|
uint8 Z2; // Depth to save
|
||||||
|
uint32 FixedColour;
|
||||||
|
const char *InfoString;
|
||||||
|
uint32 InfoStringTimeout;
|
||||||
|
char FrameDisplayString[256];
|
||||||
|
bool8 FrameDisplay;
|
||||||
|
bool8 Repainting; // True if the frame is being re-drawn
|
||||||
|
uint8 DoInterlace;
|
||||||
|
uint8 InterlaceFrame;
|
||||||
|
uint32 StartY;
|
||||||
|
uint32 EndY;
|
||||||
|
struct ClipData *Clip;
|
||||||
|
bool8 ClipColors;
|
||||||
|
uint8 OBJWidths[128];
|
||||||
|
uint8 OBJVisibleTiles[128];
|
||||||
|
struct {
|
||||||
|
uint8 RTOFlags;
|
||||||
|
int16 Tiles;
|
||||||
|
struct {
|
||||||
|
int8 Sprite;
|
||||||
|
uint8 Line;
|
||||||
|
} OBJ[32];
|
||||||
|
} OBJLines [SNES_HEIGHT_EXTENDED];
|
||||||
|
|
||||||
#ifdef GFX_MULTI_FORMAT
|
#ifdef GFX_MULTI_FORMAT
|
||||||
uint32 PixelFormat;
|
uint32 PixelFormat;
|
||||||
uint32 (*BuildPixel) (uint32, uint32, uint32);
|
uint32 (*BuildPixel) (uint32 R, uint32 G, uint32 B);
|
||||||
uint32 (*BuildPixel2) (uint32, uint32, uint32);
|
uint32 (*BuildPixel2) (uint32 R, uint32 G, uint32 B);
|
||||||
void (*DecomposePixel) (uint32, uint32 &, uint32 &, uint32 &);
|
void (*DecomposePixel) (uint32 Pixel, uint32 &R, uint32 &G, uint32 &B);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void (*DrawBackdropMath) (uint32, uint32, uint32);
|
void (*DrawBackdropMath)(uint32,uint32,uint32);
|
||||||
void (*DrawBackdropNomath) (uint32, uint32, uint32);
|
void (*DrawBackdropNomath)(uint32,uint32,uint32);
|
||||||
void (*DrawTileMath) (uint32, uint32, uint32, uint32);
|
void (*DrawTileMath)(uint32,uint32,uint32,uint32);
|
||||||
void (*DrawTileNomath) (uint32, uint32, uint32, uint32);
|
void (*DrawTileNomath)(uint32,uint32,uint32,uint32);
|
||||||
void (*DrawClippedTileMath) (uint32, uint32, uint32, uint32, uint32, uint32);
|
void (*DrawClippedTileMath)(uint32,uint32,uint32,uint32,uint32,uint32);
|
||||||
void (*DrawClippedTileNomath) (uint32, uint32, uint32, uint32, uint32, uint32);
|
void (*DrawClippedTileNomath)(uint32,uint32,uint32,uint32,uint32,uint32);
|
||||||
void (*DrawMosaicPixelMath) (uint32, uint32, uint32, uint32, uint32, uint32);
|
void (*DrawMosaicPixelMath)(uint32,uint32,uint32,uint32,uint32,uint32);
|
||||||
void (*DrawMosaicPixelNomath) (uint32, uint32, uint32, uint32, uint32, uint32);
|
void (*DrawMosaicPixelNomath)(uint32,uint32,uint32,uint32,uint32,uint32);
|
||||||
void (*DrawMode7BG1Math) (uint32, uint32, int);
|
void (*DrawMode7BG1Math)(uint32,uint32,int);
|
||||||
void (*DrawMode7BG1Nomath) (uint32, uint32, int);
|
void (*DrawMode7BG1Nomath)(uint32,uint32,int);
|
||||||
void (*DrawMode7BG2Math) (uint32, uint32, int);
|
void (*DrawMode7BG2Math)(uint32,uint32,int);
|
||||||
void (*DrawMode7BG2Nomath) (uint32, uint32, int);
|
void (*DrawMode7BG2Nomath)(uint32,uint32,int);
|
||||||
|
|
||||||
const char *InfoString;
|
|
||||||
uint32 InfoStringTimeout;
|
|
||||||
char FrameDisplayString[256];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SBG
|
struct SLineData {
|
||||||
{
|
struct {
|
||||||
uint8 (*ConvertTile) (uint8 *, uint32, uint32);
|
uint16 VOffset;
|
||||||
uint8 (*ConvertTileFlip) (uint8 *, uint32, uint32);
|
uint16 HOffset;
|
||||||
|
} BG [4];
|
||||||
uint32 TileSizeH;
|
|
||||||
uint32 TileSizeV;
|
|
||||||
uint32 OffsetSizeH;
|
|
||||||
uint32 OffsetSizeV;
|
|
||||||
uint32 TileShift;
|
|
||||||
uint32 TileAddress;
|
|
||||||
uint32 NameSelect;
|
|
||||||
uint32 SCBase;
|
|
||||||
|
|
||||||
uint32 StartPalette;
|
|
||||||
uint32 PaletteShift;
|
|
||||||
uint32 PaletteMask;
|
|
||||||
uint8 EnableMath;
|
|
||||||
uint8 InterlaceLine;
|
|
||||||
|
|
||||||
uint8 *Buffer;
|
|
||||||
uint8 *BufferFlip;
|
|
||||||
uint8 *Buffered;
|
|
||||||
uint8 *BufferedFlip;
|
|
||||||
bool8 DirectColourMode;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SLineData
|
#define H_FLIP 0x4000
|
||||||
{
|
#define V_FLIP 0x8000
|
||||||
struct
|
#define BLANK_TILE 2
|
||||||
{
|
|
||||||
uint16 VOffset;
|
struct SBG {
|
||||||
uint16 HOffset;
|
uint8 (*ConvertTile)(uint8 *,uint32,uint32);
|
||||||
} BG[4];
|
uint8 (*ConvertTileFlip)(uint8 *,uint32,uint32);
|
||||||
|
|
||||||
|
uint32 TileSizeH;
|
||||||
|
uint32 TileSizeV;
|
||||||
|
uint32 OffsetSizeH;
|
||||||
|
uint32 OffsetSizeV;
|
||||||
|
uint32 TileShift;
|
||||||
|
uint32 TileAddress;
|
||||||
|
uint32 NameSelect;
|
||||||
|
uint32 SCBase;
|
||||||
|
|
||||||
|
uint32 StartPalette;
|
||||||
|
uint32 PaletteShift;
|
||||||
|
uint32 PaletteMask;
|
||||||
|
uint8 EnableMath;
|
||||||
|
uint8 InterlaceLine;
|
||||||
|
|
||||||
|
uint8 *Buffer, *BufferFlip;
|
||||||
|
uint8 *Buffered, *BufferedFlip;
|
||||||
|
bool8 DirectColourMode;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SLineMatrixData
|
struct SLineMatrixData
|
||||||
{
|
{
|
||||||
short MatrixA;
|
short MatrixA;
|
||||||
short MatrixB;
|
short MatrixB;
|
||||||
short MatrixC;
|
short MatrixC;
|
||||||
short MatrixD;
|
short MatrixD;
|
||||||
short CentreX;
|
short CentreX;
|
||||||
short CentreY;
|
short CentreY;
|
||||||
short M7HOFS;
|
short M7HOFS;
|
||||||
short M7VOFS;
|
short M7VOFS;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern uint16 BlackColourMap[256];
|
extern SBG BG;
|
||||||
extern uint16 DirectColourMaps[8][256];
|
extern uint16 BlackColourMap [256];
|
||||||
extern uint8 mul_brightness[16][32];
|
extern uint16 DirectColourMaps [8][256];
|
||||||
extern struct SBG BG;
|
|
||||||
extern struct SGFX GFX;
|
|
||||||
|
|
||||||
#define H_FLIP 0x4000
|
extern uint8 add32_32 [32][32];
|
||||||
#define V_FLIP 0x8000
|
extern uint8 add32_32_half [32][32];
|
||||||
#define BLANK_TILE 2
|
extern uint8 sub32_32 [32][32];
|
||||||
|
extern uint8 sub32_32_half [32][32];
|
||||||
|
extern uint8 mul_brightness [16][32];
|
||||||
|
|
||||||
|
// Could use BSWAP instruction on Intel port...
|
||||||
|
#define SWAP_DWORD(dw) dw = ((dw & 0xff) << 24) | ((dw & 0xff00) << 8) | \
|
||||||
|
((dw & 0xff0000) >> 8) | ((dw & 0xff000000) >> 24)
|
||||||
|
|
||||||
|
#define SUB_SCREEN_DEPTH 0
|
||||||
|
#define MAIN_SCREEN_DEPTH 32
|
||||||
|
|
||||||
|
#if defined(OLD_COLOUR_BLENDING)
|
||||||
|
#define COLOR_ADD(C1, C2) \
|
||||||
|
GFX.X2 [((((C1) & RGB_REMOVE_LOW_BITS_MASK) + \
|
||||||
|
((C2) & RGB_REMOVE_LOW_BITS_MASK)) >> 1) + \
|
||||||
|
((C1) & (C2) & RGB_LOW_BITS_MASK)]
|
||||||
|
#else
|
||||||
|
#define COLOR_ADD(C1, C2) \
|
||||||
|
(GFX.X2 [((((C1) & RGB_REMOVE_LOW_BITS_MASK) + \
|
||||||
|
((C2) & RGB_REMOVE_LOW_BITS_MASK)) >> 1) + \
|
||||||
|
((C1) & (C2) & RGB_LOW_BITS_MASK)] | \
|
||||||
|
(((C1) ^ (C2)) & RGB_LOW_BITS_MASK))
|
||||||
|
#endif
|
||||||
|
|
||||||
#define COLOR_ADD1_2(C1, C2) \
|
#define COLOR_ADD1_2(C1, C2) \
|
||||||
((((((C1) & RGB_REMOVE_LOW_BITS_MASK) + \
|
(((((C1) & RGB_REMOVE_LOW_BITS_MASK) + \
|
||||||
((C2) & RGB_REMOVE_LOW_BITS_MASK)) >> 1) + \
|
((C2) & RGB_REMOVE_LOW_BITS_MASK)) >> 1) + \
|
||||||
((C1) & (C2) & RGB_LOW_BITS_MASK)) | ALPHA_BITS_MASK)
|
((C1) & (C2) & RGB_LOW_BITS_MASK) | ALPHA_BITS_MASK)
|
||||||
|
|
||||||
#define COLOR_ADD(C1, C2) \
|
#if defined(OLD_COLOUR_BLENDING)
|
||||||
(GFX.X2[((((C1) & RGB_REMOVE_LOW_BITS_MASK) + \
|
#define COLOR_SUB(C1, C2) \
|
||||||
((C2) & RGB_REMOVE_LOW_BITS_MASK)) >> 1) + \
|
GFX.ZERO_OR_X2 [(((C1) | RGB_HI_BITS_MASKx2) - \
|
||||||
((C1) & (C2) & RGB_LOW_BITS_MASK)] | \
|
((C2) & RGB_REMOVE_LOW_BITS_MASK)) >> 1]
|
||||||
(((C1) ^ (C2)) & RGB_LOW_BITS_MASK))
|
#elif !defined(NEW_COLOUR_BLENDING)
|
||||||
|
#define COLOR_SUB(C1, C2) \
|
||||||
|
(GFX.ZERO_OR_X2 [(((C1) | RGB_HI_BITS_MASKx2) - \
|
||||||
|
((C2) & RGB_REMOVE_LOW_BITS_MASK)) >> 1] + \
|
||||||
|
((C1) & RGB_LOW_BITS_MASK) - ((C2) & RGB_LOW_BITS_MASK))
|
||||||
|
#else
|
||||||
|
inline uint16 COLOR_SUB(uint16, uint16);
|
||||||
|
|
||||||
#define COLOR_SUB1_2(C1, C2) \
|
inline uint16 COLOR_SUB(uint16 C1, uint16 C2)
|
||||||
GFX.ZERO[(((C1) | RGB_HI_BITS_MASKx2) - \
|
|
||||||
((C2) & RGB_REMOVE_LOW_BITS_MASK)) >> 1]
|
|
||||||
|
|
||||||
inline uint16 COLOR_SUB (uint16 C1, uint16 C2)
|
|
||||||
{
|
{
|
||||||
uint16 mC1, mC2, v = ALPHA_BITS_MASK;
|
uint16 mC1, mC2, v = ALPHA_BITS_MASK;
|
||||||
|
|
||||||
@ -318,33 +345,44 @@ inline uint16 COLOR_SUB (uint16 C1, uint16 C2)
|
|||||||
mC2 = C2 & THIRD_COLOR_MASK;
|
mC2 = C2 & THIRD_COLOR_MASK;
|
||||||
if (mC1 > mC2) v += (mC1 - mC2);
|
if (mC1 > mC2) v += (mC1 - mC2);
|
||||||
|
|
||||||
return (v);
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xStartScreenRefresh (void);
|
|
||||||
void S9xEndScreenRefresh (void);
|
|
||||||
void S9xUpdateScreen (void);
|
|
||||||
void S9xBuildDirectColourMaps (void);
|
|
||||||
void RenderLine (uint8);
|
|
||||||
void S9xComputeClipWindows (void);
|
|
||||||
void S9xDisplayChar (uint16 *, uint8);
|
|
||||||
// called automatically unless Settings.AutoDisplayMessages is false
|
|
||||||
void S9xDisplayMessages (uint16 *, int, int, int, int);
|
|
||||||
#ifdef GFX_MULTI_FORMAT
|
|
||||||
bool8 S9xSetRenderPixelFormat (int);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// external port interface which must be implemented or initialised for each port
|
#define COLOR_SUB1_2(C1, C2) \
|
||||||
bool8 S9xGraphicsInit (void);
|
GFX.ZERO [(((C1) | RGB_HI_BITS_MASKx2) - \
|
||||||
void S9xGraphicsDeinit (void);
|
((C2) & RGB_REMOVE_LOW_BITS_MASK)) >> 1]
|
||||||
|
|
||||||
|
START_EXTERN_C
|
||||||
|
void S9xStartScreenRefresh ();
|
||||||
|
void S9xDrawScanLine (uint8 Line);
|
||||||
|
void S9xEndScreenRefresh ();
|
||||||
|
void S9xSetupOBJ ();
|
||||||
|
void S9xUpdateScreen ();
|
||||||
|
void RenderLine (uint8 line);
|
||||||
|
void S9xBuildDirectColourMaps ();
|
||||||
|
|
||||||
|
void S9xDisplayMessages (uint16 *screen, int ppl, int width, int height, int scale); // called automatically unless Settings.AutoDisplayMessages is false
|
||||||
|
|
||||||
|
extern struct SGFX GFX;
|
||||||
|
|
||||||
|
// External port interface which must be implemented or initialised for each
|
||||||
|
// port.
|
||||||
|
bool8 S9xGraphicsInit ();
|
||||||
|
void S9xGraphicsDeinit();
|
||||||
bool8 S9xInitUpdate (void);
|
bool8 S9xInitUpdate (void);
|
||||||
bool8 S9xDeinitUpdate (int, int);
|
bool8 S9xDeinitUpdate (int Width, int Height);
|
||||||
bool8 S9xContinueUpdate (int, int);
|
bool8 S9xContinueUpdate (int Width, int Height);
|
||||||
void S9xReRefresh (void);
|
void S9xSetPalette ();
|
||||||
void S9xSetPalette (void);
|
void S9xSyncSpeed ();
|
||||||
void S9xSyncSpeed (void);
|
|
||||||
|
|
||||||
// called instead of S9xDisplayString if set to non-NULL
|
extern void (*S9xCustomDisplayString) (const char *string, int linesFromBottom, int pixelsFromLeft, bool allowWrap); // called instead of S9xDisplayString if set to non-NULL
|
||||||
extern void (*S9xCustomDisplayString) (const char *, int, int, bool);
|
|
||||||
|
#ifdef GFX_MULTI_FORMAT
|
||||||
|
bool8 S9xSetRenderPixelFormat (int format);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
END_EXTERN_C
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -159,236 +159,235 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "snes9x.h"
|
#include "snes9x.h"
|
||||||
#include "memmap.h"
|
#include "memmap.h"
|
||||||
|
#include "ppu.h"
|
||||||
|
#include "dsp1.h"
|
||||||
|
#include "missing.h"
|
||||||
|
#include "cpuexec.h"
|
||||||
|
#include "s9xdebug.h"
|
||||||
|
#include "apu.h"
|
||||||
#include "dma.h"
|
#include "dma.h"
|
||||||
#include "apu/apu.h"
|
|
||||||
#include "fxinst.h"
|
|
||||||
#include "fxemu.h"
|
#include "fxemu.h"
|
||||||
#include "srtc.h"
|
#include "gfx.h"
|
||||||
|
#include "soundux.h"
|
||||||
#include "cheats.h"
|
#include "cheats.h"
|
||||||
|
#include "sa1.h"
|
||||||
|
#include "bsx.h"
|
||||||
|
#include "spc7110.h"
|
||||||
#ifdef NETPLAY_SUPPORT
|
#ifdef NETPLAY_SUPPORT
|
||||||
#include "netplay.h"
|
#include "netplay.h"
|
||||||
#endif
|
#endif
|
||||||
#ifdef DEBUGGER
|
|
||||||
#include "debug.h"
|
|
||||||
#include "missing.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct SCPUState CPU;
|
START_EXTERN_C
|
||||||
struct SICPU ICPU;
|
char String[513];
|
||||||
struct SRegisters Registers;
|
|
||||||
struct SPPU PPU;
|
|
||||||
struct InternalPPU IPPU;
|
|
||||||
struct SDMA DMA[8];
|
|
||||||
struct STimings Timings;
|
|
||||||
struct SGFX GFX;
|
|
||||||
struct SBG BG;
|
|
||||||
struct SLineData LineData[240];
|
|
||||||
struct SLineMatrixData LineMatrixData[240];
|
|
||||||
struct SDSP0 DSP0;
|
|
||||||
struct SDSP1 DSP1;
|
|
||||||
struct SDSP2 DSP2;
|
|
||||||
struct SDSP3 DSP3;
|
|
||||||
struct SDSP4 DSP4;
|
|
||||||
struct SSA1 SA1;
|
|
||||||
struct SSA1Registers SA1Registers;
|
|
||||||
struct SST010 ST010;
|
|
||||||
struct SST011 ST011;
|
|
||||||
struct SST018 ST018;
|
|
||||||
struct SOBC1 OBC1;
|
|
||||||
struct SSPC7110Snapshot s7snap;
|
|
||||||
struct SSRTCSnapshot srtcsnap;
|
|
||||||
struct SRTCData RTCData;
|
|
||||||
struct SBSX BSX;
|
|
||||||
struct SMulti Multi;
|
|
||||||
struct SSettings Settings;
|
|
||||||
struct SSNESGameFixes SNESGameFixes;
|
|
||||||
#ifdef NETPLAY_SUPPORT
|
|
||||||
struct SNetPlay NetPlay;
|
|
||||||
#endif
|
|
||||||
#ifdef DEBUGGER
|
|
||||||
struct Missing missing;
|
|
||||||
#endif
|
|
||||||
struct SCheatData Cheat;
|
|
||||||
struct Watch watches[16];
|
|
||||||
#ifndef ZSNES_FX
|
|
||||||
struct FxRegs_s GSU;
|
|
||||||
struct FxInfo_s SuperFX;
|
|
||||||
#endif
|
|
||||||
CMemory Memory;
|
|
||||||
|
|
||||||
char String[513];
|
struct Missing missing;
|
||||||
uint8 OpenBus = 0;
|
|
||||||
uint8 *HDMAMemPointers[8];
|
|
||||||
uint16 BlackColourMap[256];
|
|
||||||
uint16 DirectColourMaps[8][256];
|
|
||||||
|
|
||||||
SnesModel M1SNES = { 1, 3, 2 };
|
struct SICPU ICPU;
|
||||||
SnesModel M2SNES = { 2, 4, 3 };
|
|
||||||
SnesModel *Model = &M1SNES;
|
struct SCPUState CPU;
|
||||||
|
|
||||||
|
struct STimings Timings;
|
||||||
|
|
||||||
|
struct SRegisters Registers;
|
||||||
|
|
||||||
|
struct SAPU APU;
|
||||||
|
|
||||||
|
struct SIAPU IAPU;
|
||||||
|
|
||||||
|
struct SAPURegisters APURegisters;
|
||||||
|
|
||||||
|
struct SSettings Settings;
|
||||||
|
|
||||||
|
struct SSA1Registers SA1Registers;
|
||||||
|
|
||||||
|
struct SSA1 SA1;
|
||||||
|
|
||||||
|
struct SBSX BSX;
|
||||||
|
|
||||||
|
struct SMulti Multi;
|
||||||
|
|
||||||
|
SSoundData SoundData;
|
||||||
|
|
||||||
#if defined(ZSNES_FX) || defined(ZSNES_C4)
|
#if defined(ZSNES_FX) || defined(ZSNES_C4)
|
||||||
uint8 *ROM = NULL;
|
uint8 *ROM = NULL;
|
||||||
uint8 *SRAM = NULL;
|
uint8 *SRAM = NULL;
|
||||||
uint8 *RegRAM = NULL;
|
uint8 *RegRAM = NULL;
|
||||||
#endif
|
#endif
|
||||||
#ifdef ZSNES_FX
|
|
||||||
uint8 *SFXPlotTable = NULL;
|
CMemory Memory;
|
||||||
|
|
||||||
|
struct SSNESGameFixes SNESGameFixes;
|
||||||
|
|
||||||
|
unsigned char OpenBus = 0;
|
||||||
|
|
||||||
|
|
||||||
|
END_EXTERN_C
|
||||||
|
|
||||||
|
struct SDSP1 DSP1;
|
||||||
|
|
||||||
|
SnesModel M1SNES={1,3,2};
|
||||||
|
SnesModel M2SNES={2,4,3};
|
||||||
|
SnesModel* Model=&M1SNES;
|
||||||
|
|
||||||
|
#ifndef ZSNES_FX
|
||||||
|
struct FxInit_s SuperFX;
|
||||||
|
#else
|
||||||
|
START_EXTERN_C
|
||||||
|
uint8 *SFXPlotTable = NULL;
|
||||||
|
END_EXTERN_C
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct SPPU PPU;
|
||||||
|
struct InternalPPU IPPU;
|
||||||
|
|
||||||
|
struct SDMA DMA[8];
|
||||||
|
|
||||||
|
uint8 *HDMAMemPointers [8];
|
||||||
|
uint8 *HDMABasePointers [8];
|
||||||
|
|
||||||
|
struct SBG BG;
|
||||||
|
|
||||||
|
struct SGFX GFX;
|
||||||
|
struct SLineData LineData[240];
|
||||||
|
struct SLineMatrixData LineMatrixData [240];
|
||||||
|
|
||||||
#ifdef GFX_MULTI_FORMAT
|
#ifdef GFX_MULTI_FORMAT
|
||||||
uint32 RED_LOW_BIT_MASK = RED_LOW_BIT_MASK_RGB565;
|
|
||||||
uint32 GREEN_LOW_BIT_MASK = GREEN_LOW_BIT_MASK_RGB565;
|
uint32 RED_LOW_BIT_MASK = RED_LOW_BIT_MASK_RGB565;
|
||||||
uint32 BLUE_LOW_BIT_MASK = BLUE_LOW_BIT_MASK_RGB565;
|
uint32 GREEN_LOW_BIT_MASK = GREEN_LOW_BIT_MASK_RGB565;
|
||||||
uint32 RED_HI_BIT_MASK = RED_HI_BIT_MASK_RGB565;
|
uint32 BLUE_LOW_BIT_MASK = BLUE_LOW_BIT_MASK_RGB565;
|
||||||
uint32 GREEN_HI_BIT_MASK = GREEN_HI_BIT_MASK_RGB565;
|
uint32 RED_HI_BIT_MASK = RED_HI_BIT_MASK_RGB565;
|
||||||
uint32 BLUE_HI_BIT_MASK = BLUE_HI_BIT_MASK_RGB565;
|
uint32 GREEN_HI_BIT_MASK = GREEN_HI_BIT_MASK_RGB565;
|
||||||
uint32 MAX_RED = MAX_RED_RGB565;
|
uint32 BLUE_HI_BIT_MASK = BLUE_HI_BIT_MASK_RGB565;
|
||||||
uint32 MAX_GREEN = MAX_GREEN_RGB565;
|
uint32 MAX_RED = MAX_RED_RGB565;
|
||||||
uint32 MAX_BLUE = MAX_BLUE_RGB565;
|
uint32 MAX_GREEN = MAX_GREEN_RGB565;
|
||||||
uint32 SPARE_RGB_BIT_MASK = SPARE_RGB_BIT_MASK_RGB565;
|
uint32 MAX_BLUE = MAX_BLUE_RGB565;
|
||||||
uint32 GREEN_HI_BIT = (MAX_GREEN_RGB565 + 1) >> 1;
|
uint32 SPARE_RGB_BIT_MASK = SPARE_RGB_BIT_MASK_RGB565;
|
||||||
uint32 RGB_LOW_BITS_MASK = (RED_LOW_BIT_MASK_RGB565 | GREEN_LOW_BIT_MASK_RGB565 | BLUE_LOW_BIT_MASK_RGB565);
|
uint32 GREEN_HI_BIT = (MAX_GREEN_RGB565 + 1) >> 1;
|
||||||
uint32 RGB_HI_BITS_MASK = (RED_HI_BIT_MASK_RGB565 | GREEN_HI_BIT_MASK_RGB565 | BLUE_HI_BIT_MASK_RGB565);
|
uint32 RGB_LOW_BITS_MASK = (RED_LOW_BIT_MASK_RGB565 |
|
||||||
uint32 RGB_HI_BITS_MASKx2 = (RED_HI_BIT_MASK_RGB565 | GREEN_HI_BIT_MASK_RGB565 | BLUE_HI_BIT_MASK_RGB565) << 1;
|
GREEN_LOW_BIT_MASK_RGB565 |
|
||||||
uint32 RGB_REMOVE_LOW_BITS_MASK = ~RGB_LOW_BITS_MASK;
|
BLUE_LOW_BIT_MASK_RGB565);
|
||||||
uint32 FIRST_COLOR_MASK = FIRST_COLOR_MASK_RGB565;
|
uint32 RGB_HI_BITS_MASK = (RED_HI_BIT_MASK_RGB565 |
|
||||||
uint32 SECOND_COLOR_MASK = SECOND_COLOR_MASK_RGB565;
|
GREEN_HI_BIT_MASK_RGB565 |
|
||||||
uint32 THIRD_COLOR_MASK = THIRD_COLOR_MASK_RGB565;
|
BLUE_HI_BIT_MASK_RGB565);
|
||||||
uint32 ALPHA_BITS_MASK = ALPHA_BITS_MASK_RGB565;
|
uint32 RGB_HI_BITS_MASKx2 = (RED_HI_BIT_MASK_RGB565 |
|
||||||
uint32 FIRST_THIRD_COLOR_MASK = 0;
|
GREEN_HI_BIT_MASK_RGB565 |
|
||||||
uint32 TWO_LOW_BITS_MASK = 0;
|
BLUE_HI_BIT_MASK_RGB565) << 1;
|
||||||
uint32 HIGH_BITS_SHIFTED_TWO_MASK = 0;
|
uint32 RGB_REMOVE_LOW_BITS_MASK = ~RGB_LOW_BITS_MASK;
|
||||||
|
uint32 FIRST_COLOR_MASK = FIRST_COLOR_MASK_RGB565;
|
||||||
|
uint32 SECOND_COLOR_MASK = SECOND_COLOR_MASK_RGB565;
|
||||||
|
uint32 THIRD_COLOR_MASK = THIRD_COLOR_MASK_RGB565;
|
||||||
|
uint32 ALPHA_BITS_MASK = ALPHA_BITS_MASK_RGB565;
|
||||||
|
uint32 FIRST_THIRD_COLOR_MASK = 0;
|
||||||
|
uint32 TWO_LOW_BITS_MASK = 0;
|
||||||
|
uint32 HIGH_BITS_SHIFTED_TWO_MASK = 0;
|
||||||
|
|
||||||
|
uint32 current_graphic_format = RGB565;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint16 SignExtend[2] =
|
uint8 GetBank = 0;
|
||||||
{
|
struct SCheatData Cheat;
|
||||||
0x0000,
|
|
||||||
0xff00
|
volatile SoundStatus so;
|
||||||
|
|
||||||
|
int32 Loop[16];
|
||||||
|
int32 Echo[24000];
|
||||||
|
int32 FilterTaps[8];
|
||||||
|
int32 MixBuffer[SOUND_BUFFER_SIZE];
|
||||||
|
int32 EchoBuffer[SOUND_BUFFER_SIZE];
|
||||||
|
int32 DummyEchoBuffer[SOUND_BUFFER_SIZE];
|
||||||
|
uint32 FIRIndex = 0;
|
||||||
|
|
||||||
|
uint16 SignExtend [2] = {
|
||||||
|
0x00, 0xff00
|
||||||
};
|
};
|
||||||
|
|
||||||
int HDMA_ModeByteCounts[8] =
|
//modified per anomie Mode 5 findings
|
||||||
{
|
int HDMA_ModeByteCounts [8] = {
|
||||||
1, 2, 2, 4, 4, 4, 2, 4
|
1, 2, 2, 4, 4, 4, 2, 4
|
||||||
};
|
};
|
||||||
|
|
||||||
uint8 mul_brightness[16][32] =
|
uint16 BlackColourMap [256];
|
||||||
{
|
uint16 DirectColourMaps [8][256];
|
||||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
uint32 HeadMask [4] = {
|
||||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
#ifdef LSB_FIRST
|
||||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 },
|
0xffffffff, 0xffffff00, 0xffff0000, 0xff000000
|
||||||
{ 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
|
#else
|
||||||
0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04 },
|
0xffffffff, 0x00ffffff, 0x0000ffff, 0x000000ff
|
||||||
{ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03,
|
#endif
|
||||||
0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06 },
|
|
||||||
{ 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04,
|
|
||||||
0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08 },
|
|
||||||
{ 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05,
|
|
||||||
0x05, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a },
|
|
||||||
{ 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06,
|
|
||||||
0x06, 0x07, 0x07, 0x08, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0c, 0x0c },
|
|
||||||
{ 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, 0x07,
|
|
||||||
0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0e },
|
|
||||||
{ 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, 0x07, 0x08,
|
|
||||||
0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, 0x10, 0x11 },
|
|
||||||
{ 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09,
|
|
||||||
0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x10, 0x10, 0x11, 0x11, 0x12, 0x13 },
|
|
||||||
{ 0x00, 0x01, 0x01, 0x02, 0x03, 0x03, 0x04, 0x05, 0x05, 0x06, 0x07, 0x07, 0x08, 0x09, 0x09, 0x0a,
|
|
||||||
0x0b, 0x0b, 0x0c, 0x0d, 0x0d, 0x0e, 0x0f, 0x0f, 0x10, 0x11, 0x11, 0x12, 0x13, 0x13, 0x14, 0x15 },
|
|
||||||
{ 0x00, 0x01, 0x01, 0x02, 0x03, 0x04, 0x04, 0x05, 0x06, 0x07, 0x07, 0x08, 0x09, 0x0a, 0x0a, 0x0b,
|
|
||||||
0x0c, 0x0c, 0x0d, 0x0e, 0x0f, 0x0f, 0x10, 0x11, 0x12, 0x12, 0x13, 0x14, 0x15, 0x15, 0x16, 0x17 },
|
|
||||||
{ 0x00, 0x01, 0x02, 0x02, 0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0a, 0x0b, 0x0c,
|
|
||||||
0x0d, 0x0e, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x12, 0x13, 0x14, 0x15, 0x16, 0x16, 0x17, 0x18, 0x19 },
|
|
||||||
{ 0x00, 0x01, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0a, 0x0b, 0x0c, 0x0d,
|
|
||||||
0x0e, 0x0f, 0x10, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x17, 0x18, 0x19, 0x1a, 0x1b },
|
|
||||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
|
|
||||||
0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d },
|
|
||||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
|
||||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
uint8 S9xOpLengthsM0X0[256] =
|
uint32 TailMask [5] = {
|
||||||
{
|
#ifdef LSB_FIRST
|
||||||
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
0x00000000, 0x000000ff, 0x0000ffff, 0x00ffffff, 0xffffffff
|
||||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 0
|
#else
|
||||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 1
|
0x00000000, 0xff000000, 0xffff0000, 0xffffff00, 0xffffffff
|
||||||
3, 2, 4, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 2
|
#endif
|
||||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 3
|
|
||||||
1, 2, 2, 2, 3, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 4
|
|
||||||
2, 2, 2, 2, 3, 2, 2, 2, 1, 3, 1, 1, 4, 3, 3, 4, // 5
|
|
||||||
1, 2, 3, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 6
|
|
||||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 7
|
|
||||||
2, 2, 3, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 8
|
|
||||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 9
|
|
||||||
3, 2, 3, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // A
|
|
||||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // B
|
|
||||||
3, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // C
|
|
||||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // D
|
|
||||||
3, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // E
|
|
||||||
2, 2, 2, 2, 3, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4 // F
|
|
||||||
};
|
};
|
||||||
|
|
||||||
uint8 S9xOpLengthsM0X1[256] =
|
START_EXTERN_C
|
||||||
|
uint8 APUROM [64] =
|
||||||
{
|
{
|
||||||
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
0xCD,0xEF,0xBD,0xE8,0x00,0xC6,0x1D,0xD0,0xFC,0x8F,0xAA,0xF4,0x8F,
|
||||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 0
|
0xBB,0xF5,0x78,0xCC,0xF4,0xD0,0xFB,0x2F,0x19,0xEB,0xF4,0xD0,0xFC,
|
||||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 1
|
0x7E,0xF4,0xD0,0x0B,0xE4,0xF5,0xCB,0xF4,0xD7,0x00,0xFC,0xD0,0xF3,
|
||||||
3, 2, 4, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 2
|
0xAB,0x01,0x10,0xEF,0x7E,0xF4,0x10,0xEB,0xBA,0xF6,0xDA,0x00,0xBA,
|
||||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 3
|
0xF4,0xC4,0xF4,0xDD,0x5D,0xD0,0xDB,0x1F,0x00,0x00,0xC0,0xFF
|
||||||
1, 2, 2, 2, 3, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 4
|
|
||||||
2, 2, 2, 2, 3, 2, 2, 2, 1, 3, 1, 1, 4, 3, 3, 4, // 5
|
|
||||||
1, 2, 3, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 6
|
|
||||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 7
|
|
||||||
2, 2, 3, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 8
|
|
||||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 9
|
|
||||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // A
|
|
||||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // B
|
|
||||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // C
|
|
||||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // D
|
|
||||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // E
|
|
||||||
2, 2, 2, 2, 3, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4 // F
|
|
||||||
};
|
};
|
||||||
|
|
||||||
uint8 S9xOpLengthsM1X0[256] =
|
#ifdef NETPLAY_SUPPORT
|
||||||
|
struct SNetPlay NetPlay;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Raw SPC700 instruction cycle lengths
|
||||||
|
int32 S9xAPUCycleLengths [256] =
|
||||||
{
|
{
|
||||||
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
|
||||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // 0
|
/* 00 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 6, 8,
|
||||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 1
|
/* 10 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 4, 6,
|
||||||
3, 2, 4, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // 2
|
/* 20 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 5, 4,
|
||||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 3
|
/* 30 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 3, 8,
|
||||||
1, 2, 2, 2, 3, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // 4
|
/* 40 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 6, 6,
|
||||||
2, 2, 2, 2, 3, 2, 2, 2, 1, 3, 1, 1, 4, 3, 3, 4, // 5
|
/* 50 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 4, 5, 2, 2, 4, 3,
|
||||||
1, 2, 3, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // 6
|
/* 60 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 5, 5,
|
||||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 7
|
/* 70 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 6,
|
||||||
2, 2, 3, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // 8
|
/* 80 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 2, 4, 5,
|
||||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 9
|
/* 90 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2,12, 5,
|
||||||
3, 2, 3, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // A
|
/* A0 */ 3, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 2, 4, 4,
|
||||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // B
|
/* B0 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 4,
|
||||||
3, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // C
|
/* C0 */ 3, 8, 4, 5, 4, 5, 4, 7, 2, 5, 6, 4, 5, 2, 4, 9,
|
||||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // D
|
/* D0 */ 2, 8, 4, 5, 5, 6, 6, 7, 4, 5, 5, 5, 2, 2, 6, 3,
|
||||||
3, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // E
|
/* E0 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 4, 5, 3, 4, 3, 4, 3,
|
||||||
2, 2, 2, 2, 3, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4 // F
|
/* F0 */ 2, 8, 4, 5, 4, 5, 5, 6, 3, 4, 5, 4, 2, 2, 4, 3
|
||||||
};
|
};
|
||||||
|
|
||||||
uint8 S9xOpLengthsM1X1[256] =
|
// Actual data used by CPU emulation, will be scaled by APUReset routine
|
||||||
|
// to be relative to the 65c816 instruction lengths.
|
||||||
|
int32 S9xAPUCycles [256] =
|
||||||
{
|
{
|
||||||
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
|
||||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // 0
|
/* 00 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 6, 8,
|
||||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 1
|
/* 10 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 4, 6,
|
||||||
3, 2, 4, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // 2
|
/* 20 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 5, 4,
|
||||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 3
|
/* 30 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 3, 8,
|
||||||
1, 2, 2, 2, 3, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // 4
|
/* 40 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 6, 6,
|
||||||
2, 2, 2, 2, 3, 2, 2, 2, 1, 3, 1, 1, 4, 3, 3, 4, // 5
|
/* 50 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 4, 5, 2, 2, 4, 3,
|
||||||
1, 2, 3, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // 6
|
/* 60 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 5, 5,
|
||||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 7
|
/* 70 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 6,
|
||||||
2, 2, 3, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // 8
|
/* 80 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 2, 4, 5,
|
||||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 9
|
/* 90 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2,12, 5,
|
||||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // A
|
/* A0 */ 3, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 2, 4, 4,
|
||||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // B
|
/* B0 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 4,
|
||||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // C
|
/* C0 */ 3, 8, 4, 5, 4, 5, 4, 7, 2, 5, 6, 4, 5, 2, 4, 9,
|
||||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // D
|
/* D0 */ 2, 8, 4, 5, 5, 6, 6, 7, 4, 5, 5, 5, 2, 2, 6, 3,
|
||||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // E
|
/* E0 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 4, 5, 3, 4, 3, 4, 3,
|
||||||
2, 2, 2, 2, 3, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4 // F
|
/* F0 */ 2, 8, 4, 5, 4, 5, 5, 6, 3, 4, 5, 4, 2, 2, 4, 3
|
||||||
};
|
};
|
||||||
|
|
||||||
|
END_EXTERN_C
|
||||||
|
|
||||||
|
@ -159,28 +159,30 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _LANGUAGE_H_
|
|
||||||
#define _LANGUAGE_H_
|
|
||||||
|
|
||||||
// Movie Messages
|
|
||||||
#define MOVIE_ERR_SNAPSHOT_WRONG_MOVIE "Snapshot not from this movie"
|
|
||||||
#define MOVIE_ERR_SNAPSHOT_NOT_MOVIE "Not a movie snapshot"
|
|
||||||
#define MOVIE_INFO_REPLAY "Movie replay"
|
|
||||||
#define MOVIE_INFO_RECORD "Movie record"
|
|
||||||
#define MOVIE_INFO_RERECORD "Movie re-record"
|
|
||||||
#define MOVIE_INFO_REWIND "Movie rewind"
|
|
||||||
#define MOVIE_INFO_STOP "Movie stop"
|
|
||||||
#define MOVIE_INFO_END "Movie end"
|
|
||||||
#define MOVIE_INFO_SNAPSHOT "Movie snapshot"
|
|
||||||
#define MOVIE_ERR_SNAPSHOT_INCONSISTENT "Snapshot inconsistent with movie"
|
|
||||||
|
|
||||||
// Snapshot Messages
|
/* This file is for core emulator messages. Use a port-specific file for *
|
||||||
#define SAVE_INFO_SNAPSHOT "Saved"
|
* GUI strings and the like. Thank you. */
|
||||||
#define SAVE_INFO_LOAD "Loaded"
|
|
||||||
#define SAVE_INFO_OOPS "Auto-saving 'oops' snapshot"
|
/* Movie Messages */
|
||||||
#define SAVE_ERR_WRONG_FORMAT "File not in Snes9x snapshot format"
|
|
||||||
#define SAVE_ERR_WRONG_VERSION "Incompatable snapshot version"
|
#define MOVIE_ERR_SNAPSHOT_WRONG_MOVIE "Snapshot not from this movie"
|
||||||
#define SAVE_ERR_ROM_NOT_FOUND "ROM image \"%s\" for snapshot not found"
|
#define MOVIE_ERR_SNAPSHOT_NOT_MOVIE "Not a movie snapshot"
|
||||||
#define SAVE_ERR_SAVE_NOT_FOUND "Snapshot %s does not exist"
|
#define MOVIE_INFO_REPLAY "Movie replay"
|
||||||
|
#define MOVIE_INFO_RECORD "Movie record"
|
||||||
|
#define MOVIE_INFO_RERECORD "Movie re-record"
|
||||||
|
#define MOVIE_INFO_REWIND "Movie rewind"
|
||||||
|
#define MOVIE_INFO_STOP "Movie stop"
|
||||||
|
#define MOVIE_INFO_END "Movie end"
|
||||||
|
#define MOVIE_INFO_SNAPSHOT "Movie snapshot"
|
||||||
|
#define MOVIE_ERR_SNAPSHOT_INCONSISTENT "Snapshot inconsistent with movie"
|
||||||
|
|
||||||
|
/* Snapshot Messages */
|
||||||
|
|
||||||
|
#define SAVE_INFO_SNAPSHOT "Saved"
|
||||||
|
#define SAVE_INFO_LOAD "Loaded"
|
||||||
|
#define SAVE_ERR_WRONG_FORMAT "File not in Snes9x freeze format"
|
||||||
|
#define SAVE_ERR_WRONG_VERSION "Incompatable Snes9x freeze file format version"
|
||||||
|
#define SAVE_ERR_ROM_NOT_FOUND "ROM image \"%s\" for freeze file not found"
|
||||||
|
#define SAVE_ERR_SAVE_NOT_FOUND "Save file %s does not exist."
|
||||||
|
|
||||||
#endif
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -159,19 +159,26 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _MEMMAP_H_
|
|
||||||
#define _MEMMAP_H_
|
|
||||||
|
|
||||||
#define MEMMAP_BLOCK_SIZE (0x1000)
|
#ifndef _memmap_h_
|
||||||
#define MEMMAP_NUM_BLOCKS (0x1000000 / MEMMAP_BLOCK_SIZE)
|
#define _memmap_h_
|
||||||
#define MEMMAP_SHIFT (12)
|
|
||||||
#define MEMMAP_MASK (MEMMAP_BLOCK_SIZE - 1)
|
#include "snes9x.h"
|
||||||
|
|
||||||
|
#define MEMMAP_BLOCK_SIZE (0x1000)
|
||||||
|
#define MEMMAP_NUM_BLOCKS (0x1000000 / MEMMAP_BLOCK_SIZE)
|
||||||
|
#define MEMMAP_SHIFT (12)
|
||||||
|
#define MEMMAP_MASK (MEMMAP_BLOCK_SIZE - 1)
|
||||||
|
#define MEMMAP_MAX_SDD1_LOGGED_ENTRIES (0x10000 / 8)
|
||||||
|
|
||||||
struct CMemory
|
struct CMemory
|
||||||
{
|
{
|
||||||
enum
|
enum
|
||||||
{ MAX_ROM_SIZE = 0x800000 };
|
#ifdef HW_RVL
|
||||||
|
{ MAX_ROM_SIZE = 0x800000 }; // Wii - lots of memory
|
||||||
|
#else
|
||||||
|
{ MAX_ROM_SIZE = 0x500000 }; // GameCube - less memory to play with
|
||||||
|
#endif
|
||||||
enum file_formats
|
enum file_formats
|
||||||
{ FILE_ZIP, FILE_JMA, FILE_DEFAULT };
|
{ FILE_ZIP, FILE_JMA, FILE_DEFAULT };
|
||||||
|
|
||||||
@ -183,25 +190,26 @@ struct CMemory
|
|||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
MAP_CPU,
|
|
||||||
MAP_PPU,
|
MAP_PPU,
|
||||||
|
MAP_CPU,
|
||||||
MAP_LOROM_SRAM,
|
MAP_LOROM_SRAM,
|
||||||
MAP_LOROM_SRAM_B,
|
MAP_LOROM_SRAM_B,
|
||||||
MAP_HIROM_SRAM,
|
MAP_HIROM_SRAM,
|
||||||
MAP_DSP,
|
MAP_DSP,
|
||||||
MAP_SA1RAM,
|
MAP_C4,
|
||||||
MAP_BWRAM,
|
MAP_BWRAM,
|
||||||
MAP_BWRAM_BITMAP,
|
MAP_BWRAM_BITMAP,
|
||||||
MAP_BWRAM_BITMAP2,
|
MAP_BWRAM_BITMAP2,
|
||||||
|
MAP_SA1RAM,
|
||||||
MAP_SPC7110_ROM,
|
MAP_SPC7110_ROM,
|
||||||
MAP_SPC7110_DRAM,
|
MAP_SPC7110_DRAM,
|
||||||
MAP_RONLY_SRAM,
|
MAP_RONLY_SRAM,
|
||||||
MAP_C4,
|
|
||||||
MAP_OBC_RAM,
|
MAP_OBC_RAM,
|
||||||
MAP_SETA_DSP,
|
MAP_SETA_DSP,
|
||||||
MAP_SETA_RISC,
|
MAP_SETA_RISC,
|
||||||
MAP_BSX,
|
MAP_BSX,
|
||||||
MAP_NONE,
|
MAP_NONE,
|
||||||
|
MAP_DEBUG,
|
||||||
MAP_LAST
|
MAP_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -215,7 +223,6 @@ struct CMemory
|
|||||||
uint8 *FillRAM;
|
uint8 *FillRAM;
|
||||||
uint8 *BWRAM;
|
uint8 *BWRAM;
|
||||||
uint8 *C4RAM;
|
uint8 *C4RAM;
|
||||||
uint8 *OBC1RAM;
|
|
||||||
uint8 *BSRAM;
|
uint8 *BSRAM;
|
||||||
uint8 *BIOSROM;
|
uint8 *BIOSROM;
|
||||||
|
|
||||||
@ -226,11 +233,11 @@ struct CMemory
|
|||||||
uint8 MemorySpeed[MEMMAP_NUM_BLOCKS];
|
uint8 MemorySpeed[MEMMAP_NUM_BLOCKS];
|
||||||
uint8 ExtendedFormat;
|
uint8 ExtendedFormat;
|
||||||
|
|
||||||
char ROMFilename[PATH_MAX + 1];
|
char ROMFilename[_MAX_PATH + 1];
|
||||||
char ROMName[ROM_NAME_LEN];
|
char ROMName[ROM_NAME_LEN];
|
||||||
char RawROMName[ROM_NAME_LEN];
|
char RawROMName[ROM_NAME_LEN];
|
||||||
char ROMId[5];
|
char ROMId[5];
|
||||||
int32 CompanyId;
|
char CompanyId[3];
|
||||||
uint8 ROMRegion;
|
uint8 ROMRegion;
|
||||||
uint8 ROMSpeed;
|
uint8 ROMSpeed;
|
||||||
uint8 ROMType;
|
uint8 ROMType;
|
||||||
@ -247,11 +254,19 @@ struct CMemory
|
|||||||
uint32 CalculatedSize;
|
uint32 CalculatedSize;
|
||||||
uint32 CalculatedChecksum;
|
uint32 CalculatedChecksum;
|
||||||
|
|
||||||
|
uint8 *SDD1Index;
|
||||||
|
uint8 *SDD1Data;
|
||||||
|
uint32 SDD1Entries;
|
||||||
|
uint32 SDD1LoggedDataCountPrev;
|
||||||
|
uint32 SDD1LoggedDataCount;
|
||||||
|
uint8 SDD1LoggedData[MEMMAP_MAX_SDD1_LOGGED_ENTRIES];
|
||||||
|
|
||||||
// ports can assign this to perform some custom action upon loading a ROM (such as adjusting controls)
|
// ports can assign this to perform some custom action upon loading a ROM (such as adjusting controls)
|
||||||
void (*PostRomInitFunc) (void);
|
void (*PostRomInitFunc) ();
|
||||||
|
|
||||||
bool8 Init (void);
|
bool8 Init (void);
|
||||||
void Deinit (void);
|
void Deinit (void);
|
||||||
|
void FreeSDD1Data (void);
|
||||||
|
|
||||||
int ScoreHiROM (bool8, int32 romoff = 0);
|
int ScoreHiROM (bool8, int32 romoff = 0);
|
||||||
int ScoreLoROM (bool8, int32 romoff = 0);
|
int ScoreLoROM (bool8, int32 romoff = 0);
|
||||||
@ -261,11 +276,10 @@ struct CMemory
|
|||||||
bool8 LoadMultiCart (const char *, const char *);
|
bool8 LoadMultiCart (const char *, const char *);
|
||||||
bool8 LoadSufamiTurbo (const char *, const char *);
|
bool8 LoadSufamiTurbo (const char *, const char *);
|
||||||
bool8 LoadSameGame (const char *, const char *);
|
bool8 LoadSameGame (const char *, const char *);
|
||||||
|
bool8 LoadLastROM (void);
|
||||||
bool8 LoadSRAM (const char *);
|
bool8 LoadSRAM (const char *);
|
||||||
bool8 SaveSRAM (const char *);
|
bool8 SaveSRAM (const char *);
|
||||||
void ClearSRAM (bool8 onlyNonSavedSRAM = 0);
|
void ClearSRAM (bool8 onlyNonSavedSRAM = 0);
|
||||||
bool8 LoadSRTC (void);
|
|
||||||
bool8 SaveSRTC (void);
|
|
||||||
|
|
||||||
char * Safe (const char *);
|
char * Safe (const char *);
|
||||||
char * SafeANK (const char *);
|
char * SafeANK (const char *);
|
||||||
@ -319,15 +333,13 @@ struct CMemory
|
|||||||
void ApplyROMFixes (void);
|
void ApplyROMFixes (void);
|
||||||
void CheckForIPSPatch (const char *, bool8, int32 &);
|
void CheckForIPSPatch (const char *, bool8, int32 &);
|
||||||
|
|
||||||
void MakeRomInfoText (char *);
|
const char * TVStandard (void);
|
||||||
|
|
||||||
const char * MapType (void);
|
const char * MapType (void);
|
||||||
|
const char * MapMode (void);
|
||||||
const char * StaticRAMSize (void);
|
const char * StaticRAMSize (void);
|
||||||
const char * Size (void);
|
const char * Size (void);
|
||||||
const char * Revision (void);
|
const char * Revision (void);
|
||||||
const char * KartContents (void);
|
const char * KartContents (void);
|
||||||
const char * Country (void);
|
|
||||||
const char * PublishingCompany (void);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SMulti
|
struct SMulti
|
||||||
@ -338,20 +350,21 @@ struct SMulti
|
|||||||
uint32 sramMaskA, sramMaskB;
|
uint32 sramMaskA, sramMaskB;
|
||||||
uint32 cartOffsetA, cartOffsetB;
|
uint32 cartOffsetA, cartOffsetB;
|
||||||
uint8 *sramA, *sramB;
|
uint8 *sramA, *sramB;
|
||||||
char fileNameA[PATH_MAX + 1], fileNameB[PATH_MAX + 1];
|
char fileNameA[_MAX_PATH + 1], fileNameB[_MAX_PATH + 1];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
START_EXTERN_C
|
||||||
extern CMemory Memory;
|
extern CMemory Memory;
|
||||||
extern SMulti Multi;
|
extern SMulti Multi;
|
||||||
|
|
||||||
#if defined(ZSNES_FX) || defined(ZSNES_C4)
|
#if defined(ZSNES_FX) || defined(ZSNES_C4)
|
||||||
extern uint8 *ROM;
|
extern uint8 *ROM;
|
||||||
extern uint8 *SRAM;
|
extern uint8 *SRAM;
|
||||||
extern uint8 *RegRAM;
|
extern uint8 *RegRAM;
|
||||||
#endif
|
#endif
|
||||||
|
bool8 LoadZip(const char *, int32 *, int32 *, uint8 *);
|
||||||
|
END_EXTERN_C
|
||||||
|
|
||||||
void S9xAutoSaveSRAM (void);
|
void S9xAutoSaveSRAM (void);
|
||||||
bool8 LoadZip(const char *, int32 *, int32 *, uint8 *);
|
|
||||||
|
|
||||||
enum s9xwrap_t
|
enum s9xwrap_t
|
||||||
{
|
{
|
||||||
@ -366,6 +379,25 @@ enum s9xwriteorder_t
|
|||||||
WRITE_10
|
WRITE_10
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef NO_INLINE_SET_GET
|
||||||
|
|
||||||
|
uint8 S9xGetByte (uint32);
|
||||||
|
uint16 S9xGetWord (uint32, enum s9xwrap_t w = WRAP_NONE);
|
||||||
|
void S9xSetByte (uint8, uint32);
|
||||||
|
void S9xSetWord (uint16, uint32, enum s9xwrap_t w = WRAP_NONE, enum s9xwriteorder_t o = WRITE_01);
|
||||||
|
void S9xSetPCBase (uint32);
|
||||||
|
uint8 * S9xGetMemPointer (uint32);
|
||||||
|
uint8 * GetBasePointer (uint32);
|
||||||
|
|
||||||
|
START_EXTERN_C
|
||||||
|
extern uint8 OpenBus;
|
||||||
|
END_EXTERN_C
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define INLINE inline
|
||||||
#include "getset.h"
|
#include "getset.h"
|
||||||
|
|
||||||
#endif
|
#endif // NO_INLINE_SET_GET
|
||||||
|
|
||||||
|
#endif // _memmap_h_
|
||||||
|
@ -159,49 +159,49 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _MESSAGES_H_
|
|
||||||
#define _MESSAGES_H_
|
|
||||||
|
|
||||||
// Types of message sent to S9xMessage()
|
|
||||||
enum
|
#ifndef _messages_h_
|
||||||
{
|
#define _messages_h_
|
||||||
S9X_TRACE,
|
|
||||||
S9X_DEBUG,
|
/* Types of message sent to S9xMessage routine */
|
||||||
S9X_WARNING,
|
enum {
|
||||||
S9X_INFO,
|
S9X_TRACE,
|
||||||
S9X_ERROR,
|
S9X_DEBUG,
|
||||||
S9X_FATAL_ERROR
|
S9X_WARNING,
|
||||||
|
S9X_INFO,
|
||||||
|
S9X_ERROR,
|
||||||
|
S9X_FATAL_ERROR
|
||||||
};
|
};
|
||||||
|
|
||||||
// Individual message numbers
|
/* Individual message numbers */
|
||||||
enum
|
enum {
|
||||||
{
|
S9X_ROM_INFO,
|
||||||
S9X_ROM_INFO,
|
S9X_HEADERS_INFO,
|
||||||
S9X_HEADERS_INFO,
|
S9X_CONFIG_INFO,
|
||||||
S9X_CONFIG_INFO,
|
S9X_ROM_CONFUSING_FORMAT_INFO,
|
||||||
S9X_ROM_CONFUSING_FORMAT_INFO,
|
S9X_ROM_INTERLEAVED_INFO,
|
||||||
S9X_ROM_INTERLEAVED_INFO,
|
S9X_SOUND_DEVICE_OPEN_FAILED,
|
||||||
S9X_SOUND_DEVICE_OPEN_FAILED,
|
S9X_APU_STOPPED,
|
||||||
S9X_APU_STOPPED,
|
S9X_USAGE,
|
||||||
S9X_USAGE,
|
S9X_GAME_GENIE_CODE_ERROR,
|
||||||
S9X_GAME_GENIE_CODE_ERROR,
|
S9X_ACTION_REPLY_CODE_ERROR,
|
||||||
S9X_ACTION_REPLY_CODE_ERROR,
|
S9X_GOLD_FINGER_CODE_ERROR,
|
||||||
S9X_GOLD_FINGER_CODE_ERROR,
|
S9X_DEBUG_OUTPUT,
|
||||||
S9X_DEBUG_OUTPUT,
|
S9X_DMA_TRACE,
|
||||||
S9X_DMA_TRACE,
|
S9X_HDMA_TRACE,
|
||||||
S9X_HDMA_TRACE,
|
S9X_WRONG_FORMAT,
|
||||||
S9X_WRONG_FORMAT,
|
S9X_WRONG_VERSION,
|
||||||
S9X_WRONG_VERSION,
|
S9X_ROM_NOT_FOUND,
|
||||||
S9X_ROM_NOT_FOUND,
|
S9X_FREEZE_FILE_NOT_FOUND,
|
||||||
S9X_FREEZE_FILE_NOT_FOUND,
|
S9X_PPU_TRACE,
|
||||||
S9X_PPU_TRACE,
|
S9X_TRACE_DSP1,
|
||||||
S9X_TRACE_DSP1,
|
S9X_FREEZE_ROM_NAME,
|
||||||
S9X_FREEZE_ROM_NAME,
|
S9X_HEADER_WARNING,
|
||||||
S9X_HEADER_WARNING,
|
S9X_NETPLAY_NOT_SERVER,
|
||||||
S9X_NETPLAY_NOT_SERVER,
|
S9X_FREEZE_FILE_INFO,
|
||||||
S9X_FREEZE_FILE_INFO,
|
S9X_TURBO_MODE,
|
||||||
S9X_TURBO_MODE,
|
S9X_SOUND_NOT_BUILT,
|
||||||
S9X_SOUND_NOT_BUILT,
|
|
||||||
S9X_MOVIE_INFO,
|
S9X_MOVIE_INFO,
|
||||||
S9X_WRONG_MOVIE_SNAPSHOT,
|
S9X_WRONG_MOVIE_SNAPSHOT,
|
||||||
S9X_NOT_A_MOVIE_SNAPSHOT,
|
S9X_NOT_A_MOVIE_SNAPSHOT,
|
||||||
@ -210,3 +210,4 @@ enum
|
|||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -159,82 +159,80 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUGGER
|
|
||||||
|
|
||||||
#ifndef _MISSING_H_
|
#ifndef _MISSING_H_
|
||||||
#define _MISSING_H_
|
#define _MISSING_H_
|
||||||
|
|
||||||
struct MissingHDMA
|
struct HDMA
|
||||||
{
|
{
|
||||||
uint8 used;
|
uint8 used;
|
||||||
uint8 bbus_address;
|
uint8 bbus_address;
|
||||||
uint8 abus_bank;
|
uint8 abus_bank;
|
||||||
uint16 abus_address;
|
uint16 abus_address;
|
||||||
uint8 indirect_address;
|
uint8 indirect_address;
|
||||||
uint8 force_table_address_write;
|
uint8 force_table_address_write;
|
||||||
uint8 force_table_address_read;
|
uint8 force_table_address_read;
|
||||||
uint8 line_count_write;
|
uint8 line_count_write;
|
||||||
uint8 line_count_read;
|
uint8 line_count_read;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Missing
|
struct Missing
|
||||||
{
|
{
|
||||||
struct MissingHDMA hdma[8];
|
uint8 emulate6502;
|
||||||
uint8 emulate6502;
|
uint8 decimal_mode;
|
||||||
uint8 decimal_mode;
|
uint8 mv_8bit_index;
|
||||||
uint8 mv_8bit_index;
|
uint8 mv_8bit_acc;
|
||||||
uint8 mv_8bit_acc;
|
uint8 interlace;
|
||||||
uint8 interlace;
|
uint8 lines_239;
|
||||||
uint8 lines_239;
|
uint8 pseudo_512;
|
||||||
uint8 pseudo_512;
|
struct HDMA hdma [8];
|
||||||
uint8 modes[8];
|
uint8 modes [8];
|
||||||
uint8 mode7_fx;
|
uint8 mode7_fx;
|
||||||
uint8 mode7_flip;
|
uint8 mode7_flip;
|
||||||
uint8 mode7_bgmode;
|
uint8 mode7_bgmode;
|
||||||
uint8 direct;
|
uint8 direct;
|
||||||
uint8 matrix_multiply;
|
uint8 matrix_multiply;
|
||||||
uint8 oam_read;
|
uint8 oam_read;
|
||||||
uint8 vram_read;
|
uint8 vram_read;
|
||||||
uint8 cgram_read;
|
uint8 cgram_read;
|
||||||
uint8 wram_read;
|
uint8 wram_read;
|
||||||
uint8 dma_read;
|
uint8 dma_read;
|
||||||
uint8 vram_inc;
|
uint8 vram_inc;
|
||||||
uint8 vram_full_graphic_inc;
|
uint8 vram_full_graphic_inc;
|
||||||
uint8 virq;
|
uint8 virq;
|
||||||
uint8 hirq;
|
uint8 hirq;
|
||||||
uint16 virq_pos;
|
uint16 virq_pos;
|
||||||
uint16 hirq_pos;
|
uint16 hirq_pos;
|
||||||
uint8 h_v_latch;
|
uint8 h_v_latch;
|
||||||
uint8 h_counter_read;
|
uint8 h_counter_read;
|
||||||
uint8 v_counter_read;
|
uint8 v_counter_read;
|
||||||
uint8 fast_rom;
|
uint8 fast_rom;
|
||||||
uint8 window1[6];
|
uint8 window1 [6];
|
||||||
uint8 window2[6];
|
uint8 window2 [6];
|
||||||
uint8 sprite_priority_rotation;
|
uint8 sprite_priority_rotation;
|
||||||
uint8 subscreen;
|
uint8 subscreen;
|
||||||
uint8 subscreen_add;
|
uint8 subscreen_add;
|
||||||
uint8 subscreen_sub;
|
uint8 subscreen_sub;
|
||||||
uint8 fixed_colour_add;
|
uint8 fixed_colour_add;
|
||||||
uint8 fixed_colour_sub;
|
uint8 fixed_colour_sub;
|
||||||
uint8 mosaic;
|
uint8 mosaic;
|
||||||
uint8 sprite_double_height;
|
uint8 sprite_double_height;
|
||||||
uint8 dma_channels;
|
uint8 dma_channels;
|
||||||
uint8 dma_this_frame;
|
uint8 dma_this_frame;
|
||||||
uint8 oam_address_read;
|
uint8 oam_address_read;
|
||||||
uint8 bg_offset_read;
|
uint8 bg_offset_read;
|
||||||
uint8 matrix_read;
|
uint8 matrix_read;
|
||||||
uint8 hdma_channels;
|
uint8 hdma_channels;
|
||||||
uint8 hdma_this_frame;
|
uint8 hdma_this_frame;
|
||||||
uint16 unknownppu_read;
|
uint16 unknownppu_read;
|
||||||
uint16 unknownppu_write;
|
uint16 unknownppu_write;
|
||||||
uint16 unknowncpu_read;
|
uint16 unknowncpu_read;
|
||||||
uint16 unknowncpu_write;
|
uint16 unknowncpu_write;
|
||||||
uint16 unknowndsp_read;
|
uint16 unknowndsp_read;
|
||||||
uint16 unknowndsp_write;
|
uint16 unknowndsp_write;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct Missing missing;
|
EXTERN_C struct Missing missing;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,241 +0,0 @@
|
|||||||
/**********************************************************************************
|
|
||||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
|
||||||
|
|
||||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
|
||||||
Jerremy Koot (jkoot@snes9x.com)
|
|
||||||
|
|
||||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
|
||||||
|
|
||||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
|
||||||
|
|
||||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
|
||||||
|
|
||||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
|
||||||
|
|
||||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
|
||||||
Kris Bleakley (codeviolation@hotmail.com)
|
|
||||||
|
|
||||||
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
|
|
||||||
Nach (n-a-c-h@users.sourceforge.net),
|
|
||||||
zones (kasumitokoduck@yahoo.com)
|
|
||||||
|
|
||||||
(c) Copyright 2006 - 2007 nitsuja
|
|
||||||
|
|
||||||
|
|
||||||
BS-X C emulator code
|
|
||||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
|
||||||
zones
|
|
||||||
|
|
||||||
C4 x86 assembler and some C emulation code
|
|
||||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
|
||||||
Nach,
|
|
||||||
zsKnight (zsknight@zsnes.com)
|
|
||||||
|
|
||||||
C4 C++ code
|
|
||||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
|
||||||
Nach
|
|
||||||
|
|
||||||
DSP-1 emulator code
|
|
||||||
(c) Copyright 1998 - 2006 _Demo_,
|
|
||||||
Andreas Naive (andreasnaive@gmail.com)
|
|
||||||
Gary Henderson,
|
|
||||||
Ivar (ivar@snes9x.com),
|
|
||||||
John Weidman,
|
|
||||||
Kris Bleakley,
|
|
||||||
Matthew Kendora,
|
|
||||||
Nach,
|
|
||||||
neviksti (neviksti@hotmail.com)
|
|
||||||
|
|
||||||
DSP-2 emulator code
|
|
||||||
(c) Copyright 2003 John Weidman,
|
|
||||||
Kris Bleakley,
|
|
||||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
|
||||||
Matthew Kendora,
|
|
||||||
neviksti
|
|
||||||
|
|
||||||
|
|
||||||
DSP-3 emulator code
|
|
||||||
(c) Copyright 2003 - 2006 John Weidman,
|
|
||||||
Kris Bleakley,
|
|
||||||
Lancer,
|
|
||||||
z80 gaiden
|
|
||||||
|
|
||||||
DSP-4 emulator code
|
|
||||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
|
||||||
John Weidman,
|
|
||||||
Kris Bleakley,
|
|
||||||
Nach,
|
|
||||||
z80 gaiden
|
|
||||||
|
|
||||||
OBC1 emulator code
|
|
||||||
(c) Copyright 2001 - 2004 zsKnight,
|
|
||||||
pagefault (pagefault@zsnes.com),
|
|
||||||
Kris Bleakley,
|
|
||||||
Ported from x86 assembler to C by sanmaiwashi
|
|
||||||
|
|
||||||
SPC7110 and RTC C++ emulator code
|
|
||||||
(c) Copyright 2002 Matthew Kendora with research by
|
|
||||||
zsKnight,
|
|
||||||
John Weidman,
|
|
||||||
Dark Force
|
|
||||||
|
|
||||||
S-DD1 C emulator code
|
|
||||||
(c) Copyright 2003 Brad Jorsch with research by
|
|
||||||
Andreas Naive,
|
|
||||||
John Weidman
|
|
||||||
|
|
||||||
S-RTC C emulator code
|
|
||||||
(c) Copyright 2001-2006 byuu,
|
|
||||||
John Weidman
|
|
||||||
|
|
||||||
ST010 C++ emulator code
|
|
||||||
(c) Copyright 2003 Feather,
|
|
||||||
John Weidman,
|
|
||||||
Kris Bleakley,
|
|
||||||
Matthew Kendora
|
|
||||||
|
|
||||||
Super FX x86 assembler emulator code
|
|
||||||
(c) Copyright 1998 - 2003 _Demo_,
|
|
||||||
pagefault,
|
|
||||||
zsKnight,
|
|
||||||
|
|
||||||
Super FX C emulator code
|
|
||||||
(c) Copyright 1997 - 1999 Ivar,
|
|
||||||
Gary Henderson,
|
|
||||||
John Weidman
|
|
||||||
|
|
||||||
Sound DSP emulator code is derived from SNEeSe and OpenSPC:
|
|
||||||
(c) Copyright 1998 - 2003 Brad Martin
|
|
||||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
|
||||||
|
|
||||||
SH assembler code partly based on x86 assembler code
|
|
||||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
|
||||||
|
|
||||||
2xSaI filter
|
|
||||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
|
||||||
|
|
||||||
HQ2x, HQ3x, HQ4x filters
|
|
||||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
|
||||||
|
|
||||||
Win32 GUI code
|
|
||||||
(c) Copyright 2003 - 2006 blip,
|
|
||||||
funkyass,
|
|
||||||
Matthew Kendora,
|
|
||||||
Nach,
|
|
||||||
nitsuja
|
|
||||||
|
|
||||||
Mac OS GUI code
|
|
||||||
(c) Copyright 1998 - 2001 John Stiles
|
|
||||||
(c) Copyright 2001 - 2007 zones
|
|
||||||
|
|
||||||
|
|
||||||
Specific ports contains the works of other authors. See headers in
|
|
||||||
individual files.
|
|
||||||
|
|
||||||
|
|
||||||
Snes9x homepage: http://www.snes9x.com
|
|
||||||
|
|
||||||
Permission to use, copy, modify and/or 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 or it's derivatives.
|
|
||||||
|
|
||||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
|
||||||
seek permission of the copyright holders first. Commercial use includes,
|
|
||||||
but is not limited to, charging money for Snes9x or software derived from
|
|
||||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
|
||||||
using Snes9x as a promotion for your commercial product.
|
|
||||||
|
|
||||||
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.
|
|
||||||
**********************************************************************************/
|
|
||||||
|
|
||||||
// Input recording/playback code
|
|
||||||
// (c) Copyright 2004 blip
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _MOVIE_H_
|
|
||||||
#define _MOVIE_H_
|
|
||||||
|
|
||||||
#define MOVIE_OPT_FROM_SNAPSHOT 0
|
|
||||||
#define MOVIE_OPT_FROM_RESET (1 << 0)
|
|
||||||
#define MOVIE_OPT_PAL (1 << 1)
|
|
||||||
#define MOVIE_OPT_NOSAVEDATA (1 << 2)
|
|
||||||
#define MOVIE_SYNC_DATA_EXISTS 0x01
|
|
||||||
#define MOVIE_SYNC_OBSOLETE 0x02
|
|
||||||
#define MOVIE_SYNC_LEFTRIGHT 0x04
|
|
||||||
#define MOVIE_SYNC_VOLUMEENVX 0x08
|
|
||||||
#define MOVIE_SYNC_FAKEMUTE 0x10
|
|
||||||
#define MOVIE_SYNC_SYNCSOUND 0x20
|
|
||||||
#define MOVIE_SYNC_HASROMINFO 0x40
|
|
||||||
#define MOVIE_SYNC_NOCPUSHUTDOWN 0x80
|
|
||||||
#define MOVIE_MAX_METADATA 512
|
|
||||||
|
|
||||||
#define CONTROLLER_DATA_SIZE 2
|
|
||||||
#define MOUSE_DATA_SIZE 5
|
|
||||||
#define SCOPE_DATA_SIZE 6
|
|
||||||
#define JUSTIFIER_DATA_SIZE 11
|
|
||||||
|
|
||||||
struct MovieInfo
|
|
||||||
{
|
|
||||||
time_t TimeCreated;
|
|
||||||
uint32 Version;
|
|
||||||
uint32 LengthFrames;
|
|
||||||
uint32 LengthSamples;
|
|
||||||
uint32 RerecordCount;
|
|
||||||
uint8 Opts;
|
|
||||||
uint8 ControllersMask;
|
|
||||||
uint8 SyncFlags;
|
|
||||||
bool8 ReadOnly;
|
|
||||||
uint8 PortType[2];
|
|
||||||
wchar_t Metadata[MOVIE_MAX_METADATA];
|
|
||||||
uint32 ROMCRC32;
|
|
||||||
char ROMName[23];
|
|
||||||
};
|
|
||||||
|
|
||||||
// methods used by the user-interface code
|
|
||||||
int S9xMovieOpen (const char *, bool8);
|
|
||||||
int S9xMovieCreate (const char *, uint8, uint8, const wchar_t *, int);
|
|
||||||
int S9xMovieGetInfo (const char *, struct MovieInfo *);
|
|
||||||
void S9xMovieStop (bool8);
|
|
||||||
void S9xMovieToggleRecState (void);
|
|
||||||
void S9xMovieToggleFrameDisplay (void);
|
|
||||||
const char * S9xChooseMovieFilename (bool8);
|
|
||||||
|
|
||||||
// methods used by the emulation
|
|
||||||
void S9xMovieInit (void);
|
|
||||||
void S9xMovieShutdown (void);
|
|
||||||
void S9xMovieUpdate (bool a = true);
|
|
||||||
void S9xMovieUpdateOnReset (void);
|
|
||||||
void S9xUpdateFrameCounter (int o = 0);
|
|
||||||
void S9xMovieFreeze (uint8 **, uint32 *);
|
|
||||||
int S9xMovieUnfreeze (uint8 *, uint32);
|
|
||||||
|
|
||||||
// accessor functions
|
|
||||||
bool8 S9xMovieActive (void);
|
|
||||||
bool8 S9xMoviePlaying (void);
|
|
||||||
bool8 S9xMovieRecording (void);
|
|
||||||
bool8 S9xMovieReadOnly (void);
|
|
||||||
uint8 S9xMovieControllers (void);
|
|
||||||
uint32 S9xMovieGetId (void);
|
|
||||||
uint32 S9xMovieGetLength (void);
|
|
||||||
uint32 S9xMovieGetFrameCounter (void);
|
|
||||||
|
|
||||||
uint16 MovieGetJoypad (int);
|
|
||||||
void MovieSetJoypad (int, uint16);
|
|
||||||
bool MovieGetMouse (int, uint8 d[MOUSE_DATA_SIZE]);
|
|
||||||
void MovieSetMouse (int, uint8 d[MOUSE_DATA_SIZE], bool);
|
|
||||||
bool MovieGetScope (int, uint8 d[SCOPE_DATA_SIZE]);
|
|
||||||
void MovieSetScope (int, uint8 d[SCOPE_DATA_SIZE]);
|
|
||||||
bool MovieGetJustifier (int, uint8 d[JUSTIFIER_DATA_SIZE]);
|
|
||||||
void MovieSetJustifier (int, uint8 d[JUSTIFIER_DATA_SIZE]);
|
|
||||||
|
|
||||||
#endif
|
|
@ -159,102 +159,124 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#include "snes9x.h"
|
|
||||||
|
#include <string.h>
|
||||||
#include "memmap.h"
|
#include "memmap.h"
|
||||||
|
#include "obc1.h"
|
||||||
|
|
||||||
|
static uint8 *OBC1_RAM = NULL;
|
||||||
|
|
||||||
uint8 S9xGetOBC1 (uint16 Address)
|
int OBC1_Address;
|
||||||
|
int OBC1_BasePtr;
|
||||||
|
int OBC1_Shift;
|
||||||
|
|
||||||
|
extern "C"
|
||||||
{
|
{
|
||||||
switch (Address)
|
uint8 GetOBC1 (uint16 Address)
|
||||||
{
|
{
|
||||||
|
switch(Address) {
|
||||||
case 0x7ff0:
|
case 0x7ff0:
|
||||||
return (Memory.OBC1RAM[OBC1.basePtr + (OBC1.address << 2)]);
|
return OBC1_RAM[OBC1_BasePtr + (OBC1_Address << 2)];
|
||||||
|
|
||||||
case 0x7ff1:
|
case 0x7ff1:
|
||||||
return (Memory.OBC1RAM[OBC1.basePtr + (OBC1.address << 2) + 1]);
|
return OBC1_RAM[OBC1_BasePtr + (OBC1_Address << 2) + 1];
|
||||||
|
|
||||||
case 0x7ff2:
|
case 0x7ff2:
|
||||||
return (Memory.OBC1RAM[OBC1.basePtr + (OBC1.address << 2) + 2]);
|
return OBC1_RAM[OBC1_BasePtr + (OBC1_Address << 2) + 2];
|
||||||
|
|
||||||
case 0x7ff3:
|
case 0x7ff3:
|
||||||
return (Memory.OBC1RAM[OBC1.basePtr + (OBC1.address << 2) + 3]);
|
return OBC1_RAM[OBC1_BasePtr + (OBC1_Address << 2) + 3];
|
||||||
|
|
||||||
case 0x7ff4:
|
case 0x7ff4:
|
||||||
return (Memory.OBC1RAM[OBC1.basePtr + (OBC1.address >> 2) + 0x200]);
|
return OBC1_RAM[OBC1_BasePtr + (OBC1_Address >> 2) + 0x200];
|
||||||
}
|
}
|
||||||
|
|
||||||
return (Memory.OBC1RAM[Address - 0x6000]);
|
return OBC1_RAM[Address & 0x1fff];
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xSetOBC1 (uint8 Byte, uint16 Address)
|
void SetOBC1 (uint8 Byte, uint16 Address)
|
||||||
{
|
{
|
||||||
switch (Address)
|
switch(Address) {
|
||||||
{
|
|
||||||
case 0x7ff0:
|
case 0x7ff0:
|
||||||
Memory.OBC1RAM[OBC1.basePtr + (OBC1.address << 2)] = Byte;
|
{
|
||||||
|
OBC1_RAM[OBC1_BasePtr + (OBC1_Address << 2)] = Byte;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 0x7ff1:
|
case 0x7ff1:
|
||||||
Memory.OBC1RAM[OBC1.basePtr + (OBC1.address << 2) + 1] = Byte;
|
{
|
||||||
|
OBC1_RAM[OBC1_BasePtr + (OBC1_Address << 2) + 1] = Byte;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 0x7ff2:
|
case 0x7ff2:
|
||||||
Memory.OBC1RAM[OBC1.basePtr + (OBC1.address << 2) + 2] = Byte;
|
{
|
||||||
|
OBC1_RAM[OBC1_BasePtr + (OBC1_Address << 2) + 2] = Byte;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 0x7ff3:
|
case 0x7ff3:
|
||||||
Memory.OBC1RAM[OBC1.basePtr + (OBC1.address << 2) + 3] = Byte;
|
{
|
||||||
|
OBC1_RAM[OBC1_BasePtr + (OBC1_Address << 2) + 3] = Byte;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 0x7ff4:
|
case 0x7ff4:
|
||||||
{
|
{
|
||||||
uint8 Temp;
|
unsigned char Temp;
|
||||||
Temp = Memory.OBC1RAM[OBC1.basePtr + (OBC1.address >> 2) + 0x200];
|
|
||||||
Temp = (Temp & ~(3 << OBC1.shift)) | ((Byte & 3) << OBC1.shift);
|
Temp = OBC1_RAM[OBC1_BasePtr + (OBC1_Address >> 2) + 0x200];
|
||||||
Memory.OBC1RAM[OBC1.basePtr + (OBC1.address >> 2) + 0x200] = Temp;
|
Temp = (Temp & ~(3 << OBC1_Shift)) | ((Byte & 3) << OBC1_Shift);
|
||||||
|
OBC1_RAM[OBC1_BasePtr + (OBC1_Address >> 2) + 0x200] = Temp;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x7ff5:
|
case 0x7ff5:
|
||||||
|
{
|
||||||
if (Byte & 1)
|
if (Byte & 1)
|
||||||
OBC1.basePtr = 0x1800;
|
OBC1_BasePtr = 0x1800;
|
||||||
else
|
else
|
||||||
OBC1.basePtr = 0x1c00;
|
OBC1_BasePtr = 0x1c00;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 0x7ff6:
|
case 0x7ff6:
|
||||||
OBC1.address = Byte & 0x7f;
|
{
|
||||||
OBC1.shift = (Byte & 3) << 1;
|
OBC1_Address = Byte & 0x7f;
|
||||||
|
OBC1_Shift = (Byte & 3) << 1;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Memory.OBC1RAM[Address - 0x6000] = Byte;
|
OBC1_RAM[Address & 0x1fff] = Byte;
|
||||||
}
|
|
||||||
|
|
||||||
void S9xResetOBC1 (void)
|
|
||||||
{
|
|
||||||
for (int i = 0; i <= 0x1fff; i++)
|
|
||||||
Memory.OBC1RAM[i] = 0xff;
|
|
||||||
|
|
||||||
if (Memory.OBC1RAM[0x1ff5] & 1)
|
|
||||||
OBC1.basePtr = 0x1800;
|
|
||||||
else
|
|
||||||
OBC1.basePtr = 0x1c00;
|
|
||||||
|
|
||||||
OBC1.address = Memory.OBC1RAM[0x1ff6] & 0x7f;
|
|
||||||
OBC1.shift = (Memory.OBC1RAM[0x1ff6] & 3) << 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 * S9xGetBasePointerOBC1 (uint16 Address)
|
uint8 * S9xGetBasePointerOBC1 (uint16 Address)
|
||||||
{
|
{
|
||||||
if (Address >= 0x7ff0 && Address <= 0x7ff6)
|
if (Address >= 0x7ff0 && Address <= 0x7ff6)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
return (Memory.OBC1RAM - 0x6000);
|
return (OBC1_RAM - 0x6000);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 * S9xGetMemPointerOBC1 (uint16 Address)
|
uint8 * S9xGetMemPointerOBC1 (uint16 Address)
|
||||||
{
|
{
|
||||||
if (Address >= 0x7ff0 && Address <= 0x7ff6)
|
if (Address >= 0x7ff0 && Address <= 0x7ff6)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
return (Memory.OBC1RAM + Address - 0x6000);
|
return (OBC1_RAM - 0x6000 + (Address & 0xffff));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResetOBC1()
|
||||||
|
{
|
||||||
|
OBC1_RAM = &Memory.FillRAM[0x6000];
|
||||||
|
|
||||||
|
if (OBC1_RAM[0x1ff5] & 1)
|
||||||
|
OBC1_BasePtr = 0x1800;
|
||||||
|
else
|
||||||
|
OBC1_BasePtr = 0x1c00;
|
||||||
|
|
||||||
|
OBC1_Address = OBC1_RAM[0x1ff6] & 0x7f;
|
||||||
|
OBC1_Shift = (OBC1_RAM[0x1ff6] & 3) << 1;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -159,22 +159,18 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _OBC1_H_
|
#ifndef _OBC1_H_
|
||||||
#define _OBC1_H_
|
#define _OBC1_H_
|
||||||
|
|
||||||
struct SOBC1
|
START_EXTERN_C
|
||||||
{
|
uint8 GetOBC1 (uint16 Address);
|
||||||
uint16 address;
|
void SetOBC1 (uint8 Byte, uint16 Address);
|
||||||
uint16 basePtr;
|
|
||||||
uint16 shift;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern struct SOBC1 OBC1;
|
|
||||||
|
|
||||||
void S9xSetOBC1 (uint8, uint16);
|
|
||||||
uint8 S9xGetOBC1 (uint16);
|
|
||||||
void S9xResetOBC1 (void);
|
|
||||||
uint8 * S9xGetBasePointerOBC1 (uint16);
|
uint8 * S9xGetBasePointerOBC1 (uint16);
|
||||||
uint8 * S9xGetMemPointerOBC1 (uint16);
|
uint8 * S9xGetMemPointerOBC1 (uint16);
|
||||||
|
void ResetOBC1();//bool8 full);
|
||||||
|
END_EXTERN_C
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -159,6 +159,8 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _PIXFORM_H_
|
#ifndef _PIXFORM_H_
|
||||||
#define _PIXFORM_H_
|
#define _PIXFORM_H_
|
||||||
|
|
||||||
@ -166,226 +168,229 @@
|
|||||||
|
|
||||||
enum { RGB565, RGB555, BGR565, BGR555, GBR565, GBR555, RGB5551 };
|
enum { RGB565, RGB555, BGR565, BGR555, GBR565, GBR555, RGB5551 };
|
||||||
|
|
||||||
#define BUILD_PIXEL(R, G, B) ((*GFX.BuildPixel) (R, G, B))
|
#define BUILD_PIXEL(R,G,B) ((*GFX.BuildPixel) (R, G, B))
|
||||||
#define BUILD_PIXEL2(R, G, B) ((*GFX.BuildPixel2) (R, G, B))
|
#define BUILD_PIXEL2(R,G,B) ((*GFX.BuildPixel2) (R, G, B))
|
||||||
#define DECOMPOSE_PIXEL(PIX, R, G, B) ((*GFX.DecomposePixel) (PIX, R, G, B))
|
#define DECOMPOSE_PIXEL(Pixel,R,G,B) ((*GFX.DecomposePixel) (Pixel, R,G,B))
|
||||||
|
|
||||||
extern uint32 MAX_RED;
|
extern uint32 RED_LOW_BIT_MASK;
|
||||||
extern uint32 MAX_GREEN;
|
extern uint32 GREEN_LOW_BIT_MASK;
|
||||||
extern uint32 MAX_BLUE;
|
extern uint32 BLUE_LOW_BIT_MASK;
|
||||||
extern uint32 RED_LOW_BIT_MASK;
|
extern uint32 RED_HI_BIT_MASK;
|
||||||
extern uint32 GREEN_LOW_BIT_MASK;
|
extern uint32 GREEN_HI_BIT_MASK;
|
||||||
extern uint32 BLUE_LOW_BIT_MASK;
|
extern uint32 BLUE_HI_BIT_MASK;
|
||||||
extern uint32 RED_HI_BIT_MASK;
|
extern uint32 MAX_RED;
|
||||||
extern uint32 GREEN_HI_BIT_MASK;
|
extern uint32 MAX_GREEN;
|
||||||
extern uint32 BLUE_HI_BIT_MASK;
|
extern uint32 MAX_BLUE;
|
||||||
extern uint32 FIRST_COLOR_MASK;
|
extern uint32 SPARE_RGB_BIT_MASK;
|
||||||
extern uint32 SECOND_COLOR_MASK;
|
extern uint32 GREEN_HI_BIT;
|
||||||
extern uint32 THIRD_COLOR_MASK;
|
extern uint32 RGB_LOW_BITS_MASK;
|
||||||
extern uint32 ALPHA_BITS_MASK;
|
extern uint32 RGB_HI_BITS_MASK;
|
||||||
extern uint32 GREEN_HI_BIT;
|
extern uint32 RGB_HI_BITS_MASKx2;
|
||||||
extern uint32 RGB_LOW_BITS_MASK;
|
extern uint32 RGB_REMOVE_LOW_BITS_MASK;
|
||||||
extern uint32 RGB_HI_BITS_MASK;
|
extern uint32 FIRST_COLOR_MASK;
|
||||||
extern uint32 RGB_HI_BITS_MASKx2;
|
extern uint32 SECOND_COLOR_MASK;
|
||||||
extern uint32 RGB_REMOVE_LOW_BITS_MASK;
|
extern uint32 THIRD_COLOR_MASK;
|
||||||
extern uint32 FIRST_THIRD_COLOR_MASK;
|
extern uint32 ALPHA_BITS_MASK;
|
||||||
extern uint32 TWO_LOW_BITS_MASK;
|
extern uint32 FIRST_THIRD_COLOR_MASK;
|
||||||
extern uint32 HIGH_BITS_SHIFTED_TWO_MASK;
|
extern uint32 TWO_LOW_BITS_MASK;
|
||||||
extern uint32 SPARE_RGB_BIT_MASK;
|
extern uint32 HIGH_BITS_SHIFTED_TWO_MASK;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* RGB565 format */
|
/* RGB565 format */
|
||||||
#define BUILD_PIXEL_RGB565(R, G, B) (((int) (R) << 11) | ((int) (G) << 6) | (int) (B))
|
#define BUILD_PIXEL_RGB565(R,G,B) (((int) (R) << 11) | ((int) (G) << 6) | (int) (B))
|
||||||
#define BUILD_PIXEL2_RGB565(R, G, B) (((int) (R) << 11) | ((int) (G) << 5) | (int) (B))
|
#define BUILD_PIXEL2_RGB565(R,G,B) (((int) (R) << 11) | ((int) (G) << 5) | (int) (B))
|
||||||
#define DECOMPOSE_PIXEL_RGB565(PIX, R, G, B) { (R) = (PIX) >> 11; (G) = ((PIX) >> 6) & 0x1f; (B) = (PIX) & 0x1f; }
|
#define DECOMPOSE_PIXEL_RGB565(PIX,R,G,B) {(R) = (PIX) >> 11; (G) = ((PIX) >> 6) & 0x1f; (B) = (PIX) & 0x1f; }
|
||||||
#define SPARE_RGB_BIT_MASK_RGB565 (1 << 5)
|
#define SPARE_RGB_BIT_MASK_RGB565 (1 << 5)
|
||||||
|
|
||||||
#define MAX_RED_RGB565 31
|
#define MAX_RED_RGB565 31
|
||||||
#define MAX_GREEN_RGB565 63
|
#define MAX_GREEN_RGB565 63
|
||||||
#define MAX_BLUE_RGB565 31
|
#define MAX_BLUE_RGB565 31
|
||||||
#define RED_LOW_BIT_MASK_RGB565 0x0800
|
#define RED_LOW_BIT_MASK_RGB565 0x0800
|
||||||
#define GREEN_LOW_BIT_MASK_RGB565 0x0020
|
#define GREEN_LOW_BIT_MASK_RGB565 0x0020
|
||||||
#define BLUE_LOW_BIT_MASK_RGB565 0x0001
|
#define BLUE_LOW_BIT_MASK_RGB565 0x0001
|
||||||
#define RED_HI_BIT_MASK_RGB565 0x8000
|
#define RED_HI_BIT_MASK_RGB565 0x8000
|
||||||
#define GREEN_HI_BIT_MASK_RGB565 0x0400
|
#define GREEN_HI_BIT_MASK_RGB565 0x0400
|
||||||
#define BLUE_HI_BIT_MASK_RGB565 0x0010
|
#define BLUE_HI_BIT_MASK_RGB565 0x0010
|
||||||
#define FIRST_COLOR_MASK_RGB565 0xF800
|
#define FIRST_COLOR_MASK_RGB565 0xF800
|
||||||
#define SECOND_COLOR_MASK_RGB565 0x07E0
|
#define SECOND_COLOR_MASK_RGB565 0x07E0
|
||||||
#define THIRD_COLOR_MASK_RGB565 0x001F
|
#define THIRD_COLOR_MASK_RGB565 0x001F
|
||||||
#define ALPHA_BITS_MASK_RGB565 0x0000
|
#define ALPHA_BITS_MASK_RGB565 0x0000
|
||||||
|
|
||||||
/* RGB555 format */
|
/* RGB555 format */
|
||||||
#define BUILD_PIXEL_RGB555(R, G, B) (((int) (R) << 10) | ((int) (G) << 5) | (int) (B))
|
#define BUILD_PIXEL_RGB555(R,G,B) (((int) (R) << 10) | ((int) (G) << 5) | (int) (B))
|
||||||
#define BUILD_PIXEL2_RGB555(R, G, B) (((int) (R) << 10) | ((int) (G) << 5) | (int) (B))
|
#define BUILD_PIXEL2_RGB555(R,G,B) (((int) (R) << 10) | ((int) (G) << 5) | (int) (B))
|
||||||
#define DECOMPOSE_PIXEL_RGB555(PIX, R, G, B) { (R) = (PIX) >> 10; (G) = ((PIX) >> 5) & 0x1f; (B) = (PIX) & 0x1f; }
|
#define DECOMPOSE_PIXEL_RGB555(PIX,R,G,B) {(R) = (PIX) >> 10; (G) = ((PIX) >> 5) & 0x1f; (B) = (PIX) & 0x1f; }
|
||||||
#define SPARE_RGB_BIT_MASK_RGB555 (1 << 15)
|
#define SPARE_RGB_BIT_MASK_RGB555 (1 << 15)
|
||||||
|
|
||||||
#define MAX_RED_RGB555 31
|
#define MAX_RED_RGB555 31
|
||||||
#define MAX_GREEN_RGB555 31
|
#define MAX_GREEN_RGB555 31
|
||||||
#define MAX_BLUE_RGB555 31
|
#define MAX_BLUE_RGB555 31
|
||||||
#define RED_LOW_BIT_MASK_RGB555 0x0400
|
#define RED_LOW_BIT_MASK_RGB555 0x0400
|
||||||
#define GREEN_LOW_BIT_MASK_RGB555 0x0020
|
#define GREEN_LOW_BIT_MASK_RGB555 0x0020
|
||||||
#define BLUE_LOW_BIT_MASK_RGB555 0x0001
|
#define BLUE_LOW_BIT_MASK_RGB555 0x0001
|
||||||
#define RED_HI_BIT_MASK_RGB555 0x4000
|
#define RED_HI_BIT_MASK_RGB555 0x4000
|
||||||
#define GREEN_HI_BIT_MASK_RGB555 0x0200
|
#define GREEN_HI_BIT_MASK_RGB555 0x0200
|
||||||
#define BLUE_HI_BIT_MASK_RGB555 0x0010
|
#define BLUE_HI_BIT_MASK_RGB555 0x0010
|
||||||
#define FIRST_COLOR_MASK_RGB555 0x7C00
|
#define FIRST_COLOR_MASK_RGB555 0x7C00
|
||||||
#define SECOND_COLOR_MASK_RGB555 0x03E0
|
#define SECOND_COLOR_MASK_RGB555 0x03E0
|
||||||
#define THIRD_COLOR_MASK_RGB555 0x001F
|
#define THIRD_COLOR_MASK_RGB555 0x001F
|
||||||
#define ALPHA_BITS_MASK_RGB555 0x0000
|
#define ALPHA_BITS_MASK_RGB555 0x0000
|
||||||
|
|
||||||
/* BGR565 format */
|
/* BGR565 format */
|
||||||
#define BUILD_PIXEL_BGR565(R, G, B) (((int) (B) << 11) | ((int) (G) << 6) | (int) (R))
|
#define BUILD_PIXEL_BGR565(R,G,B) (((int) (B) << 11) | ((int) (G) << 6) | (int) (R))
|
||||||
#define BUILD_PIXEL2_BGR565(R, G, B) (((int) (B) << 11) | ((int) (G) << 5) | (int) (R))
|
#define BUILD_PIXEL2_BGR565(R,G,B) (((int) (B) << 11) | ((int) (G) << 5) | (int) (R))
|
||||||
#define DECOMPOSE_PIXEL_BGR565(PIX, R, G, B) { (B) = (PIX) >> 11; (G) = ((PIX) >> 6) & 0x1f; (R) = (PIX) & 0x1f; }
|
#define DECOMPOSE_PIXEL_BGR565(PIX,R,G,B) {(B) = (PIX) >> 11; (G) = ((PIX) >> 6) & 0x1f; (R) = (PIX) & 0x1f; }
|
||||||
#define SPARE_RGB_BIT_MASK_BGR565 (1 << 5)
|
#define SPARE_RGB_BIT_MASK_BGR565 (1 << 5)
|
||||||
|
|
||||||
#define MAX_RED_BGR565 31
|
#define MAX_RED_BGR565 31
|
||||||
#define MAX_GREEN_BGR565 63
|
#define MAX_GREEN_BGR565 63
|
||||||
#define MAX_BLUE_BGR565 31
|
#define MAX_BLUE_BGR565 31
|
||||||
#define RED_LOW_BIT_MASK_BGR565 0x0001
|
#define RED_LOW_BIT_MASK_BGR565 0x0001
|
||||||
#define GREEN_LOW_BIT_MASK_BGR565 0x0040
|
#define GREEN_LOW_BIT_MASK_BGR565 0x0040
|
||||||
#define BLUE_LOW_BIT_MASK_BGR565 0x0800
|
#define BLUE_LOW_BIT_MASK_BGR565 0x0800
|
||||||
#define RED_HI_BIT_MASK_BGR565 0x0010
|
#define RED_HI_BIT_MASK_BGR565 0x0010
|
||||||
#define GREEN_HI_BIT_MASK_BGR565 0x0400
|
#define GREEN_HI_BIT_MASK_BGR565 0x0400
|
||||||
#define BLUE_HI_BIT_MASK_BGR565 0x8000
|
#define BLUE_HI_BIT_MASK_BGR565 0x8000
|
||||||
#define FIRST_COLOR_MASK_BGR565 0xF800
|
#define FIRST_COLOR_MASK_BGR565 0xF800
|
||||||
#define SECOND_COLOR_MASK_BGR565 0x07E0
|
#define SECOND_COLOR_MASK_BGR565 0x07E0
|
||||||
#define THIRD_COLOR_MASK_BGR565 0x001F
|
#define THIRD_COLOR_MASK_BGR565 0x001F
|
||||||
#define ALPHA_BITS_MASK_BGR565 0x0000
|
#define ALPHA_BITS_MASK_BGR565 0x0000
|
||||||
|
|
||||||
/* BGR555 format */
|
/* BGR555 format */
|
||||||
#define BUILD_PIXEL_BGR555(R, G, B) (((int) (B) << 10) | ((int) (G) << 5) | (int) (R))
|
#define BUILD_PIXEL_BGR555(R,G,B) (((int) (B) << 10) | ((int) (G) << 5) | (int) (R))
|
||||||
#define BUILD_PIXEL2_BGR555(R, G, B) (((int) (B) << 10) | ((int) (G) << 5) | (int) (R))
|
#define BUILD_PIXEL2_BGR555(R,G,B) (((int) (B) << 10) | ((int) (G) << 5) | (int) (R))
|
||||||
#define DECOMPOSE_PIXEL_BGR555(PIX, R, G, B) { (B) = (PIX) >> 10; (G) = ((PIX) >> 5) & 0x1f; (R) = (PIX) & 0x1f; }
|
#define DECOMPOSE_PIXEL_BGR555(PIX,R,G,B) {(B) = (PIX) >> 10; (G) = ((PIX) >> 5) & 0x1f; (R) = (PIX) & 0x1f; }
|
||||||
#define SPARE_RGB_BIT_MASK_BGR555 (1 << 15)
|
#define SPARE_RGB_BIT_MASK_BGR555 (1 << 15)
|
||||||
|
|
||||||
#define MAX_RED_BGR555 31
|
#define MAX_RED_BGR555 31
|
||||||
#define MAX_GREEN_BGR555 31
|
#define MAX_GREEN_BGR555 31
|
||||||
#define MAX_BLUE_BGR555 31
|
#define MAX_BLUE_BGR555 31
|
||||||
#define RED_LOW_BIT_MASK_BGR555 0x0001
|
#define RED_LOW_BIT_MASK_BGR555 0x0001
|
||||||
#define GREEN_LOW_BIT_MASK_BGR555 0x0020
|
#define GREEN_LOW_BIT_MASK_BGR555 0x0020
|
||||||
#define BLUE_LOW_BIT_MASK_BGR555 0x0400
|
#define BLUE_LOW_BIT_MASK_BGR555 0x0400
|
||||||
#define RED_HI_BIT_MASK_BGR555 0x0010
|
#define RED_HI_BIT_MASK_BGR555 0x0010
|
||||||
#define GREEN_HI_BIT_MASK_BGR555 0x0200
|
#define GREEN_HI_BIT_MASK_BGR555 0x0200
|
||||||
#define BLUE_HI_BIT_MASK_BGR555 0x4000
|
#define BLUE_HI_BIT_MASK_BGR555 0x4000
|
||||||
#define FIRST_COLOR_MASK_BGR555 0x7C00
|
#define FIRST_COLOR_MASK_BGR555 0x7C00
|
||||||
#define SECOND_COLOR_MASK_BGR555 0x03E0
|
#define SECOND_COLOR_MASK_BGR555 0x03E0
|
||||||
#define THIRD_COLOR_MASK_BGR555 0x001F
|
#define THIRD_COLOR_MASK_BGR555 0x001F
|
||||||
#define ALPHA_BITS_MASK_BGR555 0x0000
|
#define ALPHA_BITS_MASK_BGR555 0x0000
|
||||||
|
|
||||||
/* GBR565 format */
|
/* GBR565 format */
|
||||||
#define BUILD_PIXEL_GBR565(R, G, B) (((int) (G) << 11) | ((int) (B) << 6) | (int) (R))
|
#define BUILD_PIXEL_GBR565(R,G,B) (((int) (G) << 11) | ((int) (B) << 6) | (int) (R))
|
||||||
#define BUILD_PIXEL2_GBR565(R, G, B) (((int) (G) << 11) | ((int) (B) << 5) | (int) (R))
|
#define BUILD_PIXEL2_GBR565(R,G,B) (((int) (G) << 11) | ((int) (B) << 5) | (int) (R))
|
||||||
#define DECOMPOSE_PIXEL_GBR565(PIX, R, G, B) { (G) = (PIX) >> 11; (B) = ((PIX) >> 6) & 0x1f; (R) = (PIX) & 0x1f; }
|
#define DECOMPOSE_PIXEL_GBR565(PIX,R,G,B) {(G) = (PIX) >> 11; (B) = ((PIX) >> 6) & 0x1f; (R) = (PIX) & 0x1f; }
|
||||||
#define SPARE_RGB_BIT_MASK_GBR565 (1 << 5)
|
#define SPARE_RGB_BIT_MASK_GBR565 (1 << 5)
|
||||||
|
|
||||||
#define MAX_RED_GBR565 31
|
#define MAX_RED_GBR565 31
|
||||||
#define MAX_GREEN_GBR565 31
|
#define MAX_BLUE_GBR565 63
|
||||||
#define MAX_BLUE_GBR565 63
|
#define MAX_GREEN_GBR565 31
|
||||||
#define RED_LOW_BIT_MASK_GBR565 0x0001
|
#define RED_LOW_BIT_MASK_GBR565 0x0001
|
||||||
#define GREEN_LOW_BIT_MASK_GBR565 0x0800
|
#define BLUE_LOW_BIT_MASK_GBR565 0x0040
|
||||||
#define BLUE_LOW_BIT_MASK_GBR565 0x0040
|
#define GREEN_LOW_BIT_MASK_GBR565 0x0800
|
||||||
#define RED_HI_BIT_MASK_GBR565 0x0010
|
#define RED_HI_BIT_MASK_GBR565 0x0010
|
||||||
#define GREEN_HI_BIT_MASK_GBR565 0x8000
|
#define BLUE_HI_BIT_MASK_GBR565 0x0400
|
||||||
#define BLUE_HI_BIT_MASK_GBR565 0x0400
|
#define GREEN_HI_BIT_MASK_GBR565 0x8000
|
||||||
#define FIRST_COLOR_MASK_GBR565 0xF800
|
#define FIRST_COLOR_MASK_GBR565 0xF800
|
||||||
#define SECOND_COLOR_MASK_GBR565 0x07E0
|
#define SECOND_COLOR_MASK_GBR565 0x07E0
|
||||||
#define THIRD_COLOR_MASK_GBR565 0x001F
|
#define THIRD_COLOR_MASK_GBR565 0x001F
|
||||||
#define ALPHA_BITS_MASK_GBR565 0x0000
|
#define ALPHA_BITS_MASK_GBR565 0x0000
|
||||||
|
|
||||||
/* GBR555 format */
|
/* GBR555 format */
|
||||||
#define BUILD_PIXEL_GBR555(R, G, B) (((int) (G) << 10) | ((int) (B) << 5) | (int) (R))
|
#define BUILD_PIXEL_GBR555(R,G,B) (((int) (G) << 10) | ((int) (B) << 5) | (int) (R))
|
||||||
#define BUILD_PIXEL2_GBR555(R, G, B) (((int) (G) << 10) | ((int) (B) << 5) | (int) (R))
|
#define BUILD_PIXEL2_GBR555(R,G,B) (((int) (G) << 10) | ((int) (B) << 5) | (int) (R))
|
||||||
#define DECOMPOSE_PIXEL_GBR555(PIX, R, G, B) { (G) = (PIX) >> 10; (B) = ((PIX) >> 5) & 0x1f; (R) = (PIX) & 0x1f; }
|
#define DECOMPOSE_PIXEL_GBR555(PIX,R,G,B) {(G) = (PIX) >> 10; (B) = ((PIX) >> 5) & 0x1f; (R) = (PIX) & 0x1f; }
|
||||||
#define SPARE_RGB_BIT_MASK_GBR555 (1 << 15)
|
#define SPARE_RGB_BIT_MASK_GBR555 (1 << 15)
|
||||||
|
|
||||||
#define MAX_RED_GBR555 31
|
#define MAX_RED_GBR555 31
|
||||||
#define MAX_GREEN_GBR555 31
|
#define MAX_BLUE_GBR555 31
|
||||||
#define MAX_BLUE_GBR555 31
|
#define MAX_GREEN_GBR555 31
|
||||||
#define RED_LOW_BIT_MASK_GBR555 0x0001
|
#define RED_LOW_BIT_MASK_GBR555 0x0001
|
||||||
#define GREEN_LOW_BIT_MASK_GBR555 0x0400
|
#define BLUE_LOW_BIT_MASK_GBR555 0x0020
|
||||||
#define BLUE_LOW_BIT_MASK_GBR555 0x0020
|
#define GREEN_LOW_BIT_MASK_GBR555 0x0400
|
||||||
#define RED_HI_BIT_MASK_GBR555 0x0010
|
#define RED_HI_BIT_MASK_GBR555 0x0010
|
||||||
#define GREEN_HI_BIT_MASK_GBR555 0x4000
|
#define BLUE_HI_BIT_MASK_GBR555 0x0200
|
||||||
#define BLUE_HI_BIT_MASK_GBR555 0x0200
|
#define GREEN_HI_BIT_MASK_GBR555 0x4000
|
||||||
#define FIRST_COLOR_MASK_GBR555 0x7C00
|
#define FIRST_COLOR_MASK_GBR555 0x7C00
|
||||||
#define SECOND_COLOR_MASK_GBR555 0x03E0
|
#define SECOND_COLOR_MASK_GBR555 0x03E0
|
||||||
#define THIRD_COLOR_MASK_GBR555 0x001F
|
#define THIRD_COLOR_MASK_GBR555 0x001F
|
||||||
#define ALPHA_BITS_MASK_GBR555 0x0000
|
#define ALPHA_BITS_MASK_GBR555 0x0000
|
||||||
|
|
||||||
/* RGB5551 format */
|
/* RGB5551 format */
|
||||||
#define BUILD_PIXEL_RGB5551(R, G, B) (((int) (R) << 11) | ((int) (G) << 6) | (int) ((B) << 1) | 1)
|
#define BUILD_PIXEL_RGB5551(R,G,B) (((int) (R) << 11) | ((int) (G) << 6) | (int) ((B) << 1) | 1)
|
||||||
#define BUILD_PIXEL2_RGB5551(R, G, B) (((int) (R) << 11) | ((int) (G) << 6) | (int) ((B) << 1) | 1)
|
#define BUILD_PIXEL2_RGB5551(R,G,B) (((int) (R) << 11) | ((int) (G) << 6) | (int) ((B) << 1) | 1)
|
||||||
#define DECOMPOSE_PIXEL_RGB5551(PIX, R, G, B) { (R) = (PIX) >> 11; (G) = ((PIX) >> 6) & 0x1f; (B) = ((PIX) >> 1) & 0x1f; }
|
#define DECOMPOSE_PIXEL_RGB5551(PIX,R,G,B) {(R) = (PIX) >> 11; (G) = ((PIX) >> 6) & 0x1f; (B) = ((PIX) >> 1) & 0x1f; }
|
||||||
#define SPARE_RGB_BIT_MASK_RGB5551 (1)
|
#define SPARE_RGB_BIT_MASK_RGB5551 (1)
|
||||||
|
|
||||||
#define MAX_RED_RGB5551 31
|
#define MAX_RED_RGB5551 31
|
||||||
#define MAX_GREEN_RGB5551 31
|
#define MAX_GREEN_RGB5551 31
|
||||||
#define MAX_BLUE_RGB5551 31
|
#define MAX_BLUE_RGB5551 31
|
||||||
#define RED_LOW_BIT_MASK_RGB5551 0x0800
|
#define RED_LOW_BIT_MASK_RGB5551 0x0800
|
||||||
#define GREEN_LOW_BIT_MASK_RGB5551 0x0040
|
#define GREEN_LOW_BIT_MASK_RGB5551 0x0040
|
||||||
#define BLUE_LOW_BIT_MASK_RGB5551 0x0002
|
#define BLUE_LOW_BIT_MASK_RGB5551 0x0002
|
||||||
#define RED_HI_BIT_MASK_RGB5551 0x8000
|
#define RED_HI_BIT_MASK_RGB5551 0x8000
|
||||||
#define GREEN_HI_BIT_MASK_RGB5551 0x0400
|
#define GREEN_HI_BIT_MASK_RGB5551 0x0400
|
||||||
#define BLUE_HI_BIT_MASK_RGB5551 0x0020
|
#define BLUE_HI_BIT_MASK_RGB5551 0x0020
|
||||||
#define FIRST_COLOR_MASK_RGB5551 0xf800
|
#define FIRST_COLOR_MASK_RGB5551 0xf800
|
||||||
#define SECOND_COLOR_MASK_RGB5551 0x07c0
|
#define SECOND_COLOR_MASK_RGB5551 0x07c0
|
||||||
#define THIRD_COLOR_MASK_RGB5551 0x003e
|
#define THIRD_COLOR_MASK_RGB5551 0x003e
|
||||||
#define ALPHA_BITS_MASK_RGB5551 0x0001
|
#define ALPHA_BITS_MASK_RGB5551 0x0001
|
||||||
|
|
||||||
#ifndef GFX_MULTI_FORMAT
|
#ifndef GFX_MULTI_FORMAT
|
||||||
|
#define CONCAT(X,Y) X##Y
|
||||||
|
|
||||||
#define CONCAT(X, Y) X##Y
|
/* C pre-processor needs a two stage macro define to enable it to concat
|
||||||
|
* to macro names together to form the name of another macro. */
|
||||||
|
#define BUILD_PIXEL_D(F,R,G,B) CONCAT(BUILD_PIXEL_,F) (R,G,B)
|
||||||
|
#define BUILD_PIXEL2_D(F,R,G,B) CONCAT(BUILD_PIXEL2_,F) (R,G,B)
|
||||||
|
#define DECOMPOSE_PIXEL_D(F,PIX,R,G,B) CONCAT(DECOMPOSE_PIXEL_,F) (PIX,R,G,B)
|
||||||
|
|
||||||
// C pre-processor needs a two stage macro define to enable it to concat
|
#define BUILD_PIXEL(R,G,B) BUILD_PIXEL_D(PIXEL_FORMAT,R,G,B)
|
||||||
// to macro names together to form the name of another macro.
|
#define BUILD_PIXEL2(R,G,B) BUILD_PIXEL2_D(PIXEL_FORMAT,R,G,B)
|
||||||
#define BUILD_PIXEL_D(F, R, G, B) CONCAT(BUILD_PIXEL_,F) (R, G, B)
|
#define DECOMPOSE_PIXEL(PIX,R,G,B) DECOMPOSE_PIXEL_D(PIXEL_FORMAT,PIX,R,G,B)
|
||||||
#define BUILD_PIXEL2_D(F, R, G, B) CONCAT(BUILD_PIXEL2_,F) (R, G, B)
|
|
||||||
#define DECOMPOSE_PIXEL_D(F, PIX, R, G, B) CONCAT(DECOMPOSE_PIXEL_,F) (PIX, R, G, B)
|
|
||||||
|
|
||||||
#define BUILD_PIXEL(R, G, B) BUILD_PIXEL_D(PIXEL_FORMAT, R, G, B)
|
#define MAX_RED_D(F) CONCAT(MAX_RED_,F)
|
||||||
#define BUILD_PIXEL2(R, G, B) BUILD_PIXEL2_D(PIXEL_FORMAT, R, G, B)
|
#define MAX_BLUE_D(F) CONCAT(MAX_BLUE_,F)
|
||||||
#define DECOMPOSE_PIXEL(PIX, R, G, B) DECOMPOSE_PIXEL_D(PIXEL_FORMAT, PIX, R, G, B)
|
#define MAX_GREEN_D(F) CONCAT(MAX_GREEN_,F)
|
||||||
|
#define RED_LOW_BIT_MASK_D(F) CONCAT(RED_LOW_BIT_MASK_,F)
|
||||||
|
#define BLUE_LOW_BIT_MASK_D(F) CONCAT(BLUE_LOW_BIT_MASK_,F)
|
||||||
|
#define GREEN_LOW_BIT_MASK_D(F) CONCAT(GREEN_LOW_BIT_MASK_,F)
|
||||||
|
#define RED_HI_BIT_MASK_D(F) CONCAT(RED_HI_BIT_MASK_,F)
|
||||||
|
#define BLUE_HI_BIT_MASK_D(F) CONCAT(BLUE_HI_BIT_MASK_,F)
|
||||||
|
#define GREEN_HI_BIT_MASK_D(F) CONCAT(GREEN_HI_BIT_MASK_,F)
|
||||||
|
#define FIRST_COLOR_MASK_D(F) CONCAT(FIRST_COLOR_MASK_,F)
|
||||||
|
#define SECOND_COLOR_MASK_D(F) CONCAT(SECOND_COLOR_MASK_,F)
|
||||||
|
#define THIRD_COLOR_MASK_D(F) CONCAT(THIRD_COLOR_MASK_,F)
|
||||||
|
#define ALPHA_BITS_MASK_D(F) CONCAT(ALPHA_BITS_MASK_,F)
|
||||||
|
|
||||||
#define MAX_RED_D(F) CONCAT(MAX_RED_, F)
|
#define MAX_RED MAX_RED_D(PIXEL_FORMAT)
|
||||||
#define MAX_GREEN_D(F) CONCAT(MAX_GREEN_, F)
|
#define MAX_BLUE MAX_BLUE_D(PIXEL_FORMAT)
|
||||||
#define MAX_BLUE_D(F) CONCAT(MAX_BLUE_, F)
|
#define MAX_GREEN MAX_GREEN_D(PIXEL_FORMAT)
|
||||||
#define RED_LOW_BIT_MASK_D(F) CONCAT(RED_LOW_BIT_MASK_, F)
|
#define RED_LOW_BIT_MASK RED_LOW_BIT_MASK_D(PIXEL_FORMAT)
|
||||||
#define GREEN_LOW_BIT_MASK_D(F) CONCAT(GREEN_LOW_BIT_MASK_, F)
|
#define BLUE_LOW_BIT_MASK BLUE_LOW_BIT_MASK_D(PIXEL_FORMAT)
|
||||||
#define BLUE_LOW_BIT_MASK_D(F) CONCAT(BLUE_LOW_BIT_MASK_, F)
|
#define GREEN_LOW_BIT_MASK GREEN_LOW_BIT_MASK_D(PIXEL_FORMAT)
|
||||||
#define RED_HI_BIT_MASK_D(F) CONCAT(RED_HI_BIT_MASK_, F)
|
#define RED_HI_BIT_MASK RED_HI_BIT_MASK_D(PIXEL_FORMAT)
|
||||||
#define GREEN_HI_BIT_MASK_D(F) CONCAT(GREEN_HI_BIT_MASK_, F)
|
#define BLUE_HI_BIT_MASK BLUE_HI_BIT_MASK_D(PIXEL_FORMAT)
|
||||||
#define BLUE_HI_BIT_MASK_D(F) CONCAT(BLUE_HI_BIT_MASK_, F)
|
#define GREEN_HI_BIT_MASK GREEN_HI_BIT_MASK_D(PIXEL_FORMAT)
|
||||||
#define FIRST_COLOR_MASK_D(F) CONCAT(FIRST_COLOR_MASK_, F)
|
#define FIRST_COLOR_MASK FIRST_COLOR_MASK_D(PIXEL_FORMAT)
|
||||||
#define SECOND_COLOR_MASK_D(F) CONCAT(SECOND_COLOR_MASK_, F)
|
#define SECOND_COLOR_MASK SECOND_COLOR_MASK_D(PIXEL_FORMAT)
|
||||||
#define THIRD_COLOR_MASK_D(F) CONCAT(THIRD_COLOR_MASK_, F)
|
#define THIRD_COLOR_MASK THIRD_COLOR_MASK_D(PIXEL_FORMAT)
|
||||||
#define ALPHA_BITS_MASK_D(F) CONCAT(ALPHA_BITS_MASK_, F)
|
#define ALPHA_BITS_MASK ALPHA_BITS_MASK_D(PIXEL_FORMAT)
|
||||||
|
|
||||||
#define MAX_RED MAX_RED_D(PIXEL_FORMAT)
|
|
||||||
#define MAX_GREEN MAX_GREEN_D(PIXEL_FORMAT)
|
|
||||||
#define MAX_BLUE MAX_BLUE_D(PIXEL_FORMAT)
|
|
||||||
#define RED_LOW_BIT_MASK RED_LOW_BIT_MASK_D(PIXEL_FORMAT)
|
|
||||||
#define GREEN_LOW_BIT_MASK GREEN_LOW_BIT_MASK_D(PIXEL_FORMAT)
|
|
||||||
#define BLUE_LOW_BIT_MASK BLUE_LOW_BIT_MASK_D(PIXEL_FORMAT)
|
|
||||||
#define RED_HI_BIT_MASK RED_HI_BIT_MASK_D(PIXEL_FORMAT)
|
|
||||||
#define GREEN_HI_BIT_MASK GREEN_HI_BIT_MASK_D(PIXEL_FORMAT)
|
|
||||||
#define BLUE_HI_BIT_MASK BLUE_HI_BIT_MASK_D(PIXEL_FORMAT)
|
|
||||||
#define FIRST_COLOR_MASK FIRST_COLOR_MASK_D(PIXEL_FORMAT)
|
|
||||||
#define SECOND_COLOR_MASK SECOND_COLOR_MASK_D(PIXEL_FORMAT)
|
|
||||||
#define THIRD_COLOR_MASK THIRD_COLOR_MASK_D(PIXEL_FORMAT)
|
|
||||||
#define ALPHA_BITS_MASK ALPHA_BITS_MASK_D(PIXEL_FORMAT)
|
|
||||||
|
|
||||||
#define GREEN_HI_BIT ((MAX_GREEN + 1) >> 1)
|
|
||||||
#define RGB_LOW_BITS_MASK (RED_LOW_BIT_MASK | GREEN_LOW_BIT_MASK | BLUE_LOW_BIT_MASK)
|
|
||||||
#define RGB_HI_BITS_MASK (RED_HI_BIT_MASK | GREEN_HI_BIT_MASK | BLUE_HI_BIT_MASK)
|
|
||||||
#define RGB_HI_BITS_MASKx2 ((RED_HI_BIT_MASK | GREEN_HI_BIT_MASK | BLUE_HI_BIT_MASK) << 1)
|
|
||||||
#define RGB_REMOVE_LOW_BITS_MASK (~RGB_LOW_BITS_MASK)
|
|
||||||
#define FIRST_THIRD_COLOR_MASK (FIRST_COLOR_MASK | THIRD_COLOR_MASK)
|
|
||||||
#define TWO_LOW_BITS_MASK (RGB_LOW_BITS_MASK | (RGB_LOW_BITS_MASK << 1))
|
|
||||||
#define HIGH_BITS_SHIFTED_TWO_MASK (((FIRST_COLOR_MASK | SECOND_COLOR_MASK | THIRD_COLOR_MASK) & ~TWO_LOW_BITS_MASK ) >> 2)
|
|
||||||
|
|
||||||
|
#define GREEN_HI_BIT ((MAX_GREEN + 1) >> 1)
|
||||||
|
#define RGB_LOW_BITS_MASK (RED_LOW_BIT_MASK | GREEN_LOW_BIT_MASK | \
|
||||||
|
BLUE_LOW_BIT_MASK)
|
||||||
|
#define RGB_HI_BITS_MASK (RED_HI_BIT_MASK | GREEN_HI_BIT_MASK | \
|
||||||
|
BLUE_HI_BIT_MASK)
|
||||||
|
#define RGB_HI_BITS_MASKx2 ((RED_HI_BIT_MASK | GREEN_HI_BIT_MASK | \
|
||||||
|
BLUE_HI_BIT_MASK) << 1)
|
||||||
|
#define RGB_REMOVE_LOW_BITS_MASK (~RGB_LOW_BITS_MASK)
|
||||||
|
#define FIRST_THIRD_COLOR_MASK (FIRST_COLOR_MASK | THIRD_COLOR_MASK)
|
||||||
|
#define TWO_LOW_BITS_MASK (RGB_LOW_BITS_MASK | (RGB_LOW_BITS_MASK << 1))
|
||||||
|
#define HIGH_BITS_SHIFTED_TWO_MASK (( (FIRST_COLOR_MASK | SECOND_COLOR_MASK | THIRD_COLOR_MASK) & \
|
||||||
|
~TWO_LOW_BITS_MASK ) >> 2)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -159,142 +159,243 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _PORT_H_
|
#ifndef _PORT_H_
|
||||||
#define _PORT_H_
|
#define _PORT_H_
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#ifndef GEKKO
|
|
||||||
#include <memory.h>
|
#ifndef STORM
|
||||||
#endif
|
//#include <memory.h>
|
||||||
#include <time.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#ifdef HAVE_STRINGS_H
|
#else
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
|
#include <clib/powerpc_protos.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef ACCEPT_SIZE_T
|
||||||
|
#ifdef __WIN32__
|
||||||
|
#define ACCEPT_SIZE_T int
|
||||||
|
#else
|
||||||
|
#define ACCEPT_SIZE_T unsigned int
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#ifdef __WIN32__
|
/* #define PIXEL_FORMAT RGB565 */
|
||||||
#include <windows.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define CHECK_SOUND()
|
|
||||||
#define GFX_MULTI_FORMAT
|
#define GFX_MULTI_FORMAT
|
||||||
|
|
||||||
#ifdef __WIN32__
|
#ifndef NOASM
|
||||||
#define RIGHTSHIFT_IS_SAR
|
//#define USE_X86_ASM
|
||||||
#define SNES_JOY_READ_CALLBACKS
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __MACOSX__
|
#ifdef __MACOSX__
|
||||||
#undef GFX_MULTI_FORMAT
|
|
||||||
#define PIXEL_FORMAT RGB555
|
#ifdef _C
|
||||||
#endif
|
#undef _C
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _D
|
||||||
|
#undef _D
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CHECK_SOUND()
|
||||||
|
#define PIXEL_FORMAT RGB555
|
||||||
|
#undef GFX_MULTI_FORMAT
|
||||||
|
#undef USE_X86_ASM
|
||||||
|
#undef _MAX_PATH
|
||||||
|
|
||||||
|
#define SET_UI_COLOR(r,g,b) SetInfoDlgColor(r,g,b)
|
||||||
|
void SetInfoDlgColor(unsigned char, unsigned char, unsigned char);
|
||||||
|
|
||||||
|
#endif /* __MACOSX__ */
|
||||||
|
|
||||||
#ifndef snes9x_types_defined
|
#ifndef snes9x_types_defined
|
||||||
#define snes9x_types_defined
|
#define snes9x_types_defined
|
||||||
typedef unsigned char bool8;
|
|
||||||
|
typedef unsigned char bool8;
|
||||||
|
|
||||||
#ifdef HAVE_STDINT_H
|
#ifdef HAVE_STDINT_H
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
typedef intptr_t pint;
|
|
||||||
typedef int8_t int8;
|
typedef int8_t int8;
|
||||||
typedef uint8_t uint8;
|
typedef uint8_t uint8;
|
||||||
typedef int16_t int16;
|
typedef int16_t int16;
|
||||||
typedef uint16_t uint16;
|
typedef uint16_t uint16;
|
||||||
typedef int32_t int32;
|
typedef int32_t int32;
|
||||||
typedef uint32_t uint32;
|
typedef uint32_t uint32;
|
||||||
typedef int64_t int64;
|
typedef int64_t int64;
|
||||||
typedef uint64_t uint64;
|
typedef uint64_t uint64;
|
||||||
#else // HAVE_STDINT_H
|
typedef intptr_t pint;
|
||||||
|
|
||||||
|
#else /* Don't have stdint.h */
|
||||||
|
|
||||||
#ifdef PTR_NOT_INT
|
#ifdef PTR_NOT_INT
|
||||||
typedef long pint;
|
typedef long pint;
|
||||||
#else
|
#else /* pointer is int */
|
||||||
typedef int pint;
|
typedef int pint;
|
||||||
#endif
|
#endif /* PTR_NOT_INT */
|
||||||
#ifdef __WIN32__
|
|
||||||
#ifdef __BORLANDC__
|
/* FIXME: Refactor this by moving out the BORLAND part and unifying typedefs */
|
||||||
#include <systypes.h>
|
#ifndef __WIN32__
|
||||||
#else
|
typedef unsigned char uint8;
|
||||||
typedef signed char int8;
|
typedef unsigned short uint16;
|
||||||
typedef unsigned char uint8;
|
typedef signed char int8;
|
||||||
typedef signed short int16;
|
typedef short int16;
|
||||||
typedef unsigned short uint16;
|
typedef int int32;
|
||||||
#ifndef WSAAP
|
typedef unsigned int uint32;
|
||||||
// winsock2.h typedefs int32 as well
|
# ifdef __GNUC__ /* long long is not part of ISO C++ */
|
||||||
typedef signed int int32;
|
|
||||||
#endif
|
|
||||||
typedef unsigned int uint32;
|
|
||||||
#endif
|
|
||||||
typedef signed __int64 int64;
|
|
||||||
typedef unsigned __int64 uint64;
|
|
||||||
#else // __WIN32__
|
|
||||||
typedef signed char int8;
|
|
||||||
typedef unsigned char uint8;
|
|
||||||
typedef signed short int16;
|
|
||||||
typedef unsigned short uint16;
|
|
||||||
typedef signed int int32;
|
|
||||||
typedef unsigned int uint32;
|
|
||||||
#ifdef __GNUC__
|
|
||||||
// long long is not part of ISO C++
|
|
||||||
__extension__
|
__extension__
|
||||||
|
# endif
|
||||||
|
typedef long long int64;
|
||||||
|
typedef unsigned long long uint64;
|
||||||
|
#else /* __WIN32__ */
|
||||||
|
|
||||||
|
#ifndef PATH_MAX
|
||||||
|
#define PATH_MAX _MAX_PATH
|
||||||
#endif
|
#endif
|
||||||
typedef long long int64;
|
|
||||||
typedef unsigned long long uint64;
|
# ifdef __BORLANDC__
|
||||||
#endif // __WIN32__
|
# include <systypes.h>
|
||||||
#endif // HAVE_STDINT_H
|
# else
|
||||||
#endif // snes9x_types_defined
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
# define PLAT_SOUND_BUFFER SoundBuffer
|
||||||
|
# define RIGHTSHIFT_IS_SAR
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if defined(_MSC_VER) && (_MSC_VER == 1400) /* VC8.0 */
|
||||||
|
/* temporary solution for fatal error C1063 (cl.exe 14.00.50727.762) */
|
||||||
|
# ifdef RIGHTSHIFT_IS_SAR
|
||||||
|
# undef RIGHTSHIFT_IS_SAR
|
||||||
|
# endif /* RIGHTSHIFT_IS_SAR */
|
||||||
|
# define RIGHTSHIFT_INT8_IS_SAR
|
||||||
|
# define RIGHTSHIFT_INT16_IS_SAR
|
||||||
|
# define RIGHTSHIFT_INT32_IS_SAR
|
||||||
|
# endif /* VC8.0 */
|
||||||
|
|
||||||
|
typedef unsigned int uint32;
|
||||||
|
|
||||||
|
# endif /* __BORLANDC__ */
|
||||||
|
|
||||||
|
typedef __int64 int64;
|
||||||
|
typedef unsigned __int64 uint64;
|
||||||
|
|
||||||
|
#endif /* __WIN32__ */
|
||||||
|
#endif /* HAVE_STDINT_H */
|
||||||
|
#endif /* snes9x_types_defined */
|
||||||
|
|
||||||
|
|
||||||
|
#include "pixform.h"
|
||||||
|
|
||||||
#ifndef TRUE
|
#ifndef TRUE
|
||||||
#define TRUE 1
|
#define TRUE 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef FALSE
|
#ifndef FALSE
|
||||||
#define FALSE 0
|
#define FALSE 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define START_EXTERN_C extern "C" {
|
#ifdef STORM
|
||||||
#define END_EXTERN_C }
|
#define EXTERN_C
|
||||||
|
#define START_EXTERN_C
|
||||||
#ifndef __WIN32__
|
#define END_EXTERN_C
|
||||||
#ifndef PATH_MAX
|
|
||||||
#define PATH_MAX 1024
|
|
||||||
#endif
|
|
||||||
#define _MAX_DRIVE 1
|
|
||||||
#define _MAX_DIR PATH_MAX
|
|
||||||
#define _MAX_FNAME PATH_MAX
|
|
||||||
#define _MAX_EXT PATH_MAX
|
|
||||||
#define _MAX_PATH PATH_MAX
|
|
||||||
#else
|
#else
|
||||||
#ifndef PATH_MAX
|
#if defined(__cplusplus) || defined(c_plusplus)
|
||||||
#define PATH_MAX _MAX_PATH
|
#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
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef __WIN32__
|
#ifndef __WIN32__
|
||||||
#define ZeroMemory(a, b) memset((a), 0, (b))
|
|
||||||
void _splitpath (const char *, char *, char *, char *, char *);
|
#ifndef PATH_MAX
|
||||||
void _makepath (char *, const char *, const char *, const char *, const char *);
|
#define PATH_MAX 1024
|
||||||
#define S9xDisplayString DisplayStringFromBottom
|
#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))
|
||||||
|
|
||||||
|
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);
|
||||||
|
#else /* __WIN32__ */
|
||||||
|
#define strcasecmp stricmp
|
||||||
|
#define strncasecmp strnicmp
|
||||||
|
|
||||||
|
#define SNES_JOY_READ_CALLBACKS
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
EXTERN_C void S9xGenerateSound ();
|
||||||
|
#ifdef __WIN32__
|
||||||
|
EXTERN_C void S9xGenerateFrameSound ();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#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
|
#else
|
||||||
#define strcasecmp stricmp
|
#define CHECK_SOUND()
|
||||||
#define strncasecmp strnicmp
|
|
||||||
#define S9xDisplayString S9xCustomDisplayString
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __DJGPP
|
#ifdef __DJGPP
|
||||||
#define SLASH_STR "\\"
|
#define SLASH_STR "\\"
|
||||||
#define SLASH_CHAR '\\'
|
#define SLASH_CHAR '\\'
|
||||||
#else
|
#else
|
||||||
#define SLASH_STR "/"
|
#define SLASH_STR "/"
|
||||||
#define SLASH_CHAR '/'
|
#define SLASH_CHAR '/'
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Taken care of in signal.h on Linux.
|
||||||
|
* #ifdef __linux
|
||||||
|
* typedef void (*SignalHandler)(int);
|
||||||
|
* #define SIG_PF SignalHandler
|
||||||
|
* #endif
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* If including signal.h, do it before snes9.h and port.h to avoid clashes. */
|
||||||
#ifndef SIG_PF
|
#ifndef SIG_PF
|
||||||
#define SIG_PF void (*) (int)
|
#define SIG_PF void(*)(int)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__i386__) || defined(__i486__) || defined(__i586__) || \
|
||||||
|
defined(__x86_64__) || defined(__WIN32__) || defined(__alpha__)
|
||||||
|
#define LSB_FIRST
|
||||||
|
#define FAST_LSB_WORD_ACCESS
|
||||||
|
#else
|
||||||
|
#define MSB_FIRST
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __sun
|
||||||
|
#define TITLE "Snes9X: Solaris"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __linux
|
#ifdef __linux
|
||||||
#define TITLE "Snes9x: Linux"
|
#define TITLE "Snes9X: Linux"
|
||||||
#define SYS_CONFIG_FILE "/etc/snes9x/snes9x.conf"
|
#define SYS_CONFIG_FILE "/etc/snes9x/snes9x.conf"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -302,32 +403,41 @@ void _makepath (char *, const char *, const char *, const char *, const char *);
|
|||||||
#define TITLE "Snes9x"
|
#define TITLE "Snes9x"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) || defined(__x86_64__) || defined(__alpha__) || defined(__MIPSEL__)
|
#ifdef STORM
|
||||||
#define LSB_FIRST
|
#define STATIC
|
||||||
#define FAST_LSB_WORD_ACCESS
|
#define strncasecmp strnicmp
|
||||||
#else
|
#else
|
||||||
#define MSB_FIRST
|
#define STATIC static
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef FAST_LSB_WORD_ACCESS
|
#ifdef FAST_LSB_WORD_ACCESS
|
||||||
#define READ_WORD(s) (*(uint16 *) (s))
|
#define READ_WORD(s) (*(uint16 *) (s))
|
||||||
#define READ_3WORD(s) (*(uint32 *) (s) & 0x00ffffff)
|
#define READ_3WORD(s) (0x00ffffff & *(uint32 *) (s))
|
||||||
#define READ_DWORD(s) (*(uint32 *) (s))
|
#define READ_DWORD(s) (*(uint32 *) (s))
|
||||||
#define WRITE_WORD(s, d) *(uint16 *) (s) = (d)
|
#define WRITE_WORD(s, d) (*(uint16 *) (s)) = (d)
|
||||||
#define WRITE_3WORD(s, d) *(uint16 *) (s) = (uint16) (d), *((uint8 *) (s) + 2) = (uint8) ((d) >> 16)
|
#define WRITE_3WORD(s, d) *(uint16 *) (s) = (uint16)(d),\
|
||||||
#define WRITE_DWORD(s, d) *(uint32 *) (s) = (d)
|
*((uint8 *) (s) + 2) = (uint8) ((d) >> 16)
|
||||||
|
#define WRITE_DWORD(s, d) (*(uint32 *) (s)) = (d)
|
||||||
#else
|
#else
|
||||||
#define READ_WORD(s) (*(uint8 *) (s) | (*((uint8 *) (s) + 1) << 8))
|
#define READ_WORD(s) ( *(uint8 *) (s) |\
|
||||||
#define READ_3WORD(s) (*(uint8 *) (s) | (*((uint8 *) (s) + 1) << 8) | (*((uint8 *) (s) + 2) << 16))
|
(*((uint8 *) (s) + 1) << 8))
|
||||||
#define READ_DWORD(s) (*(uint8 *) (s) | (*((uint8 *) (s) + 1) << 8) | (*((uint8 *) (s) + 2) << 16) | (*((uint8 *) (s) + 3) << 24))
|
#define READ_3WORD(s) ( *(uint8 *) (s) |\
|
||||||
#define WRITE_WORD(s, d) *(uint8 *) (s) = (uint8) (d), *((uint8 *) (s) + 1) = (uint8) ((d) >> 8)
|
(*((uint8 *) (s) + 1) << 8) |\
|
||||||
#define WRITE_3WORD(s, d) *(uint8 *) (s) = (uint8) (d), *((uint8 *) (s) + 1) = (uint8) ((d) >> 8), *((uint8 *) (s) + 2) = (uint8) ((d) >> 16)
|
(*((uint8 *) (s) + 2) << 16))
|
||||||
#define WRITE_DWORD(s, d) *(uint8 *) (s) = (uint8) (d), *((uint8 *) (s) + 1) = (uint8) ((d) >> 8), *((uint8 *) (s) + 2) = (uint8) ((d) >> 16), *((uint8 *) (s) + 3) = (uint8) ((d) >> 24)
|
#define READ_DWORD(s) ( *(uint8 *) (s) |\
|
||||||
|
(*((uint8 *) (s) + 1) << 8) |\
|
||||||
|
(*((uint8 *) (s) + 2) << 16) |\
|
||||||
|
(*((uint8 *) (s) + 3) << 24))
|
||||||
|
#define WRITE_WORD(s, d) *(uint8 *) (s) = (d), \
|
||||||
|
*((uint8 *) (s) + 1) = (d) >> 8
|
||||||
|
#define WRITE_3WORD(s, d) *(uint8 *) (s) = (uint8) (d), \
|
||||||
|
*((uint8 *) (s) + 1) = (uint8) ((d) >> 8),\
|
||||||
|
*((uint8 *) (s) + 2) = (uint8) ((d) >> 16)
|
||||||
|
#define WRITE_DWORD(s, d) *(uint8 *) (s) = (uint8) (d), \
|
||||||
|
*((uint8 *) (s) + 1) = (uint8) ((d) >> 8),\
|
||||||
|
*((uint8 *) (s) + 2) = (uint8) ((d) >> 16),\
|
||||||
|
*((uint8 *) (s) + 3) = (uint8) ((d) >> 24)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SWAP_WORD(s) (s) = (((s) & 0xff) << 8) | (((s) & 0xff00) >> 8)
|
|
||||||
#define SWAP_DWORD(s) (s) = (((s) & 0xff) << 24) | (((s) & 0xff00) << 8) | (((s) & 0xff0000) >> 8) | (((s) & 0xff000000) >> 24)
|
|
||||||
|
|
||||||
#include "pixform.h"
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
1064
source/snes9x/ppu.h
1064
source/snes9x/ppu.h
File diff suppressed because it is too large
Load Diff
2307
source/snes9x/s9xdebug.cpp
Normal file
2307
source/snes9x/s9xdebug.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -159,12 +159,29 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _LOGGER_H_
|
|
||||||
#define _LOGGER_H_
|
|
||||||
|
|
||||||
void S9xResetLogger(void);
|
|
||||||
void S9xCloseLogger(void);
|
|
||||||
void S9xVideoLogger(void *, int, int, int, int);
|
|
||||||
void S9xAudioLogger(void *, int);
|
|
||||||
|
|
||||||
|
#ifndef _DEBUG_H_
|
||||||
|
#define _DEBUG_H_
|
||||||
|
|
||||||
|
START_EXTERN_C
|
||||||
|
void S9xDoDebug ();
|
||||||
|
void S9xTrace ();
|
||||||
|
void S9xSA1Trace ();
|
||||||
|
void S9xTraceMessage (const char *);
|
||||||
|
|
||||||
|
// Structures
|
||||||
|
struct SBreakPoint{
|
||||||
|
bool8 Enabled;
|
||||||
|
uint8 Bank;
|
||||||
|
uint16 Address;
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8 S9xOPrint( char *Line, uint8 Bank, uint16 Address);
|
||||||
|
uint8 S9xSA1OPrint( char *Line, uint8 Bank, uint16 Address);
|
||||||
|
|
||||||
|
extern struct SBreakPoint S9xBreakpoint[ 6];
|
||||||
|
extern char *S9xMnemonics[256];
|
||||||
|
END_EXTERN_C
|
||||||
#endif
|
#endif
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
@ -159,149 +159,150 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _SA1_H_
|
|
||||||
#define _SA1_H_
|
|
||||||
|
|
||||||
struct SSA1Registers
|
|
||||||
{
|
#ifndef _sa1_h_
|
||||||
uint8 DB;
|
#define _sa1_h_
|
||||||
pair P;
|
|
||||||
pair A;
|
#include "memmap.h"
|
||||||
pair D;
|
|
||||||
pair S;
|
struct SSA1Registers {
|
||||||
pair X;
|
uint8 DB;
|
||||||
pair Y;
|
pair P;
|
||||||
PC_t PC;
|
pair A;
|
||||||
|
pair D;
|
||||||
|
pair S;
|
||||||
|
pair X;
|
||||||
|
pair Y;
|
||||||
|
PC_t PC;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SSA1
|
struct SSA1 {
|
||||||
{
|
struct SOpcodes *S9xOpcodes;
|
||||||
struct SOpcodes *S9xOpcodes;
|
uint8 *S9xOpLengths;
|
||||||
uint8 *S9xOpLengths;
|
uint8 _Carry;
|
||||||
uint8 _Carry;
|
uint8 _Zero;
|
||||||
uint8 _Zero;
|
uint8 _Negative;
|
||||||
uint8 _Negative;
|
uint8 _Overflow;
|
||||||
uint8 _Overflow;
|
bool8 CPUExecuting;
|
||||||
bool8 CPUExecuting;
|
uint32 ShiftedPB;
|
||||||
uint32 ShiftedPB;
|
uint32 ShiftedDB;
|
||||||
uint32 ShiftedDB;
|
uint32 Flags;
|
||||||
|
bool8 Executing;
|
||||||
uint32 Flags;
|
bool8 NMIActive;
|
||||||
uint8 *PCBase;
|
bool8 IRQActive;
|
||||||
bool8 IRQActive;
|
bool8 WaitingForInterrupt;
|
||||||
bool8 Waiting;
|
bool8 Waiting;
|
||||||
bool8 WaitingForInterrupt;
|
// uint8 WhichEvent;
|
||||||
uint32 WaitAddress;
|
uint8 *PCBase;
|
||||||
uint32 WaitCounter;
|
uint8 *BWRAM;
|
||||||
uint32 PBPCAtOpcodeStart;
|
uint32 PBPCAtOpcodeStart;
|
||||||
uint8 *WaitByteAddress1;
|
uint32 WaitAddress;
|
||||||
uint8 *WaitByteAddress2;
|
uint32 WaitCounter;
|
||||||
|
uint8 *WaitByteAddress1;
|
||||||
uint8 *Map[MEMMAP_NUM_BLOCKS];
|
uint8 *WaitByteAddress2;
|
||||||
uint8 *WriteMap[MEMMAP_NUM_BLOCKS];
|
// int32 Cycles;
|
||||||
uint8 *BWRAM;
|
// int32 NextEvent;
|
||||||
|
// int32 V_Counter;
|
||||||
bool8 Executing;
|
uint8 *Map [MEMMAP_NUM_BLOCKS];
|
||||||
bool8 overflow;
|
uint8 *WriteMap [MEMMAP_NUM_BLOCKS];
|
||||||
bool8 in_char_dma;
|
int16 op1;
|
||||||
int16 op1;
|
int16 op2;
|
||||||
int16 op2;
|
int32 arithmetic_op;
|
||||||
int32 arithmetic_op;
|
int64 sum;
|
||||||
int64 sum;
|
bool8 overflow;
|
||||||
uint8 VirtualBitmapFormat;
|
uint8 VirtualBitmapFormat;
|
||||||
uint8 variable_bit_pos;
|
bool8 in_char_dma;
|
||||||
|
uint8 variable_bit_pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SA1CheckCarry() (SA1._Carry)
|
#define SA1CheckZero() (SA1._Zero == 0)
|
||||||
#define SA1CheckZero() (SA1._Zero == 0)
|
#define SA1CheckCarry() (SA1._Carry)
|
||||||
#define SA1CheckIRQ() (SA1Registers.PL & IRQ)
|
#define SA1CheckIRQ() (SA1Registers.PL & IRQ)
|
||||||
#define SA1CheckDecimal() (SA1Registers.PL & Decimal)
|
#define SA1CheckDecimal() (SA1Registers.PL & Decimal)
|
||||||
#define SA1CheckIndex() (SA1Registers.PL & IndexFlag)
|
#define SA1CheckIndex() (SA1Registers.PL & IndexFlag)
|
||||||
#define SA1CheckMemory() (SA1Registers.PL & MemoryFlag)
|
#define SA1CheckMemory() (SA1Registers.PL & MemoryFlag)
|
||||||
#define SA1CheckOverflow() (SA1._Overflow)
|
#define SA1CheckOverflow() (SA1._Overflow)
|
||||||
#define SA1CheckNegative() (SA1._Negative & 0x80)
|
#define SA1CheckNegative() (SA1._Negative & 0x80)
|
||||||
#define SA1CheckEmulation() (SA1Registers.P.W & Emulation)
|
#define SA1CheckEmulation() (SA1Registers.P.W & Emulation)
|
||||||
|
|
||||||
#define SA1SetFlags(f) (SA1Registers.P.W |= (f))
|
#define SA1ClearFlags(f) (SA1Registers.P.W &= ~(f))
|
||||||
#define SA1ClearFlags(f) (SA1Registers.P.W &= ~(f))
|
#define SA1SetFlags(f) (SA1Registers.P.W |= (f))
|
||||||
#define SA1CheckFlag(f) (SA1Registers.PL & (f))
|
#define SA1CheckFlag(f) (SA1Registers.PL & (f))
|
||||||
|
|
||||||
extern struct SSA1Registers SA1Registers;
|
|
||||||
extern struct SSA1 SA1;
|
|
||||||
extern uint8 SA1OpenBus;
|
|
||||||
extern struct SOpcodes S9xSA1OpcodesM1X1[256];
|
|
||||||
extern struct SOpcodes S9xSA1OpcodesM1X0[256];
|
|
||||||
extern struct SOpcodes S9xSA1OpcodesM0X1[256];
|
|
||||||
extern struct SOpcodes S9xSA1OpcodesM0X0[256];
|
|
||||||
extern uint8 S9xOpLengthsM1X1[256];
|
|
||||||
extern uint8 S9xOpLengthsM1X0[256];
|
|
||||||
extern uint8 S9xOpLengthsM0X1[256];
|
|
||||||
extern uint8 S9xOpLengthsM0X0[256];
|
|
||||||
|
|
||||||
|
START_EXTERN_C
|
||||||
uint8 S9xSA1GetByte (uint32);
|
uint8 S9xSA1GetByte (uint32);
|
||||||
|
uint16 S9xSA1GetWord (uint32, enum s9xwrap_t w=WRAP_NONE);
|
||||||
void S9xSA1SetByte (uint8, uint32);
|
void S9xSA1SetByte (uint8, uint32);
|
||||||
uint16 S9xSA1GetWord (uint32, enum s9xwrap_t w = WRAP_NONE);
|
void S9xSA1SetWord (uint16, uint32, enum s9xwrap_t w=WRAP_NONE, enum s9xwriteorder_t o=WRITE_01);
|
||||||
void S9xSA1SetWord (uint16, uint32, enum s9xwrap_t w = WRAP_NONE, enum s9xwriteorder_t o = WRITE_01);
|
|
||||||
void S9xSA1SetPCBase (uint32);
|
void S9xSA1SetPCBase (uint32);
|
||||||
uint8 S9xGetSA1 (uint32);
|
uint8 S9xGetSA1 (uint32);
|
||||||
void S9xSetSA1 (uint8, uint32);
|
void S9xSetSA1 (uint8, uint32);
|
||||||
void S9xSA1Init (void);
|
|
||||||
void S9xSA1MainLoop (void);
|
|
||||||
void S9xSA1ExecuteDuringSleep (void);
|
|
||||||
void S9xSA1PostLoadState (void);
|
|
||||||
|
|
||||||
#define SNES_IRQ_SOURCE (1 << 7)
|
extern struct SOpcodes S9xSA1OpcodesM1X1 [256];
|
||||||
#define TIMER_IRQ_SOURCE (1 << 6)
|
extern struct SOpcodes S9xSA1OpcodesM1X0 [256];
|
||||||
#define DMA_IRQ_SOURCE (1 << 5)
|
extern struct SOpcodes S9xSA1OpcodesM0X1 [256];
|
||||||
|
extern struct SOpcodes S9xSA1OpcodesM0X0 [256];
|
||||||
|
extern uint8 S9xOpLengthsM1X1 [256];
|
||||||
|
extern uint8 S9xOpLengthsM1X0 [256];
|
||||||
|
extern uint8 S9xOpLengthsM0X1 [256];
|
||||||
|
extern uint8 S9xOpLengthsM0X0 [256];
|
||||||
|
extern struct SSA1Registers SA1Registers;
|
||||||
|
extern struct SSA1 SA1;
|
||||||
|
extern uint8 SA1OpenBus;
|
||||||
|
|
||||||
static inline void S9xSA1UnpackStatus (void)
|
void S9xSA1MainLoop ();
|
||||||
|
void S9xSA1Init ();
|
||||||
|
void S9xFixSA1AfterSnapshotLoad ();
|
||||||
|
void S9xSA1ExecuteDuringSleep ();
|
||||||
|
END_EXTERN_C
|
||||||
|
|
||||||
|
#define SNES_IRQ_SOURCE (1 << 7)
|
||||||
|
#define TIMER_IRQ_SOURCE (1 << 6)
|
||||||
|
#define DMA_IRQ_SOURCE (1 << 5)
|
||||||
|
|
||||||
|
STATIC inline void S9xSA1UnpackStatus()
|
||||||
{
|
{
|
||||||
SA1._Zero = (SA1Registers.PL & Zero) == 0;
|
SA1._Zero = (SA1Registers.PL & Zero) == 0;
|
||||||
SA1._Negative = (SA1Registers.PL & Negative);
|
SA1._Negative = (SA1Registers.PL & Negative);
|
||||||
SA1._Carry = (SA1Registers.PL & Carry);
|
SA1._Carry = (SA1Registers.PL & Carry);
|
||||||
SA1._Overflow = (SA1Registers.PL & Overflow) >> 6;
|
SA1._Overflow = (SA1Registers.PL & Overflow) >> 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void S9xSA1PackStatus (void)
|
STATIC inline void S9xSA1PackStatus()
|
||||||
{
|
{
|
||||||
SA1Registers.PL &= ~(Zero | Negative | Carry | Overflow);
|
SA1Registers.PL &= ~(Zero | Negative | Carry | Overflow);
|
||||||
SA1Registers.PL |= SA1._Carry | ((SA1._Zero == 0) << 1) | (SA1._Negative & 0x80) | (SA1._Overflow << 6);
|
SA1Registers.PL |= SA1._Carry | ((SA1._Zero == 0) << 1) |
|
||||||
|
(SA1._Negative & 0x80) | (SA1._Overflow << 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void S9xSA1FixCycles (void)
|
STATIC inline void S9xSA1FixCycles ()
|
||||||
{
|
{
|
||||||
if (SA1CheckEmulation())
|
if (SA1CheckEmulation ()) {
|
||||||
{
|
SA1.S9xOpcodes = S9xSA1OpcodesM1X1;
|
||||||
SA1.S9xOpcodes = S9xSA1OpcodesM1X1;
|
SA1.S9xOpLengths = S9xOpLengthsM1X1;
|
||||||
SA1.S9xOpLengths = S9xOpLengthsM1X1;
|
} else
|
||||||
}
|
if (SA1CheckMemory ())
|
||||||
else
|
{
|
||||||
if (SA1CheckMemory())
|
if (SA1CheckIndex ()){
|
||||||
{
|
SA1.S9xOpcodes = S9xSA1OpcodesM1X1;
|
||||||
if (SA1CheckIndex())
|
SA1.S9xOpLengths = S9xOpLengthsM1X1;
|
||||||
{
|
} else {
|
||||||
SA1.S9xOpcodes = S9xSA1OpcodesM1X1;
|
SA1.S9xOpcodes = S9xSA1OpcodesM1X0;
|
||||||
SA1.S9xOpLengths = S9xOpLengthsM1X1;
|
SA1.S9xOpLengths = S9xOpLengthsM1X0;
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
{
|
else
|
||||||
SA1.S9xOpcodes = S9xSA1OpcodesM1X0;
|
{
|
||||||
SA1.S9xOpLengths = S9xOpLengthsM1X0;
|
if (SA1CheckIndex ()){
|
||||||
}
|
SA1.S9xOpcodes = S9xSA1OpcodesM0X1;
|
||||||
}
|
SA1.S9xOpLengths = S9xOpLengthsM0X1;
|
||||||
else
|
} else {
|
||||||
{
|
SA1.S9xOpcodes = S9xSA1OpcodesM0X0;
|
||||||
if (SA1CheckIndex())
|
SA1.S9xOpLengths = S9xOpLengthsM0X0;
|
||||||
{
|
}
|
||||||
SA1.S9xOpcodes = S9xSA1OpcodesM0X1;
|
}
|
||||||
SA1.S9xOpLengths = S9xOpLengthsM0X1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SA1.S9xOpcodes = S9xSA1OpcodesM0X0;
|
|
||||||
SA1.S9xOpLengths = S9xOpLengthsM0X0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -159,125 +159,120 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "snes9x.h"
|
#include "snes9x.h"
|
||||||
#include "memmap.h"
|
#include "memmap.h"
|
||||||
|
#include "ppu.h"
|
||||||
|
#include "cpuexec.h"
|
||||||
|
|
||||||
#define CPU SA1
|
#include "sa1.h"
|
||||||
#define ICPU SA1
|
|
||||||
#define Registers SA1Registers
|
#define CPU SA1
|
||||||
#define OpenBus SA1OpenBus
|
#define ICPU SA1
|
||||||
#define S9xGetByte S9xSA1GetByte
|
#define Registers SA1Registers
|
||||||
#define S9xGetWord S9xSA1GetWord
|
#define OpenBus SA1OpenBus
|
||||||
#define S9xSetByte S9xSA1SetByte
|
#define S9xGetByte S9xSA1GetByte
|
||||||
#define S9xSetWord S9xSA1SetWord
|
#define S9xGetWord S9xSA1GetWord
|
||||||
#define S9xSetPCBase S9xSA1SetPCBase
|
#define S9xSetByte S9xSA1SetByte
|
||||||
#define S9xOpcodesM1X1 S9xSA1OpcodesM1X1
|
#define S9xSetWord S9xSA1SetWord
|
||||||
#define S9xOpcodesM1X0 S9xSA1OpcodesM1X0
|
#define S9xSetPCBase S9xSA1SetPCBase
|
||||||
#define S9xOpcodesM0X1 S9xSA1OpcodesM0X1
|
#define S9xOpcodesM1X1 S9xSA1OpcodesM1X1
|
||||||
#define S9xOpcodesM0X0 S9xSA1OpcodesM0X0
|
#define S9xOpcodesM1X0 S9xSA1OpcodesM1X0
|
||||||
#define S9xOpcodesE1 S9xSA1OpcodesE1
|
#define S9xOpcodesM0X1 S9xSA1OpcodesM0X1
|
||||||
#define S9xOpcodesSlow S9xSA1OpcodesSlow
|
#define S9xOpcodesM0X0 S9xSA1OpcodesM0X0
|
||||||
#define S9xOpcode_IRQ S9xSA1Opcode_IRQ
|
#define S9xOpcodesE1 S9xSA1OpcodesE1
|
||||||
#define S9xOpcode_NMI S9xSA1Opcode_NMI
|
#define S9xOpcodesSlow S9xSA1OpcodesSlow
|
||||||
#define S9xUnpackStatus S9xSA1UnpackStatus
|
#define S9xOpcode_IRQ S9xSA1Opcode_IRQ
|
||||||
#define S9xPackStatus S9xSA1PackStatus
|
#define S9xOpcode_NMI S9xSA1Opcode_NMI
|
||||||
#define S9xFixCycles S9xSA1FixCycles
|
#define S9xUnpackStatus S9xSA1UnpackStatus
|
||||||
#define Immediate8 SA1Immediate8
|
#define S9xPackStatus S9xSA1PackStatus
|
||||||
#define Immediate16 SA1Immediate16
|
#define S9xFixCycles S9xSA1FixCycles
|
||||||
#define Relative SA1Relative
|
#define Immediate8 SA1Immediate8
|
||||||
#define RelativeLong SA1RelativeLong
|
#define Immediate16 SA1Immediate16
|
||||||
#define Absolute SA1Absolute
|
#define Relative SA1Relative
|
||||||
#define AbsoluteLong SA1AbsoluteLong
|
#define RelativeLong SA1RelativeLong
|
||||||
#define AbsoluteIndirect SA1AbsoluteIndirect
|
#define AbsoluteIndexedIndirect SA1AbsoluteIndexedIndirect
|
||||||
#define AbsoluteIndirectLong SA1AbsoluteIndirectLong
|
#define AbsoluteIndirectLong SA1AbsoluteIndirectLong
|
||||||
#define AbsoluteIndexedIndirect SA1AbsoluteIndexedIndirect
|
#define AbsoluteIndirect SA1AbsoluteIndirect
|
||||||
#define Direct SA1Direct
|
#define Absolute SA1Absolute
|
||||||
#define DirectIndirectIndexed SA1DirectIndirectIndexed
|
#define AbsoluteLong SA1AbsoluteLong
|
||||||
#define DirectIndirectIndexedLong SA1DirectIndirectIndexedLong
|
#define Direct SA1Direct
|
||||||
#define DirectIndexedIndirect SA1DirectIndexedIndirect
|
#define DirectIndirectIndexed SA1DirectIndirectIndexed
|
||||||
#define DirectIndexedX SA1DirectIndexedX
|
#define DirectIndirectIndexedLong SA1DirectIndirectIndexedLong
|
||||||
#define DirectIndexedY SA1DirectIndexedY
|
#define DirectIndexedIndirect SA1DirectIndexedIndirect
|
||||||
#define AbsoluteIndexedX SA1AbsoluteIndexedX
|
#define DirectIndexedX SA1DirectIndexedX
|
||||||
#define AbsoluteIndexedY SA1AbsoluteIndexedY
|
#define DirectIndexedY SA1DirectIndexedY
|
||||||
#define AbsoluteLongIndexedX SA1AbsoluteLongIndexedX
|
#define AbsoluteIndexedX SA1AbsoluteIndexedX
|
||||||
#define DirectIndirect SA1DirectIndirect
|
#define AbsoluteIndexedY SA1AbsoluteIndexedY
|
||||||
#define DirectIndirectLong SA1DirectIndirectLong
|
#define AbsoluteLongIndexedX SA1AbsoluteLongIndexedX
|
||||||
#define StackRelative SA1StackRelative
|
#define DirectIndirect SA1DirectIndirect
|
||||||
#define StackRelativeIndirectIndexed SA1StackRelativeIndirectIndexed
|
#define DirectIndirectLong SA1DirectIndirectLong
|
||||||
|
#define StackRelative SA1StackRelative
|
||||||
|
#define StackRelativeIndirectIndexed SA1StackRelativeIndirectIndexed
|
||||||
|
|
||||||
//#undef CPU_SHUTDOWN
|
//#undef CPU_SHUTDOWN
|
||||||
#define SA1_OPCODES
|
#define SA1_OPCODES
|
||||||
|
|
||||||
#include "cpuops.cpp"
|
#include "cpuops.cpp"
|
||||||
|
|
||||||
|
void S9xSA1MainLoop ()
|
||||||
void S9xSA1MainLoop (void)
|
|
||||||
{
|
{
|
||||||
#if 0
|
int i;
|
||||||
if (SA1.Flags & NMI_FLAG)
|
|
||||||
{
|
|
||||||
SA1.Flags &= ~NMI_FLAG;
|
|
||||||
if (SA1.WaitingForInterrupt)
|
|
||||||
{
|
|
||||||
SA1.WaitingForInterrupt = FALSE;
|
|
||||||
SA1Registers.PCw++;
|
|
||||||
}
|
|
||||||
|
|
||||||
S9xSA1Opcode_NMI();
|
#if 0
|
||||||
|
if (SA1.Flags & NMI_FLAG)
|
||||||
|
{
|
||||||
|
SA1.Flags &= ~NMI_FLAG;
|
||||||
|
if (SA1.WaitingForInterrupt)
|
||||||
|
{
|
||||||
|
SA1.WaitingForInterrupt = FALSE;
|
||||||
|
SA1Registers.PCw++;
|
||||||
}
|
}
|
||||||
|
S9xSA1Opcode_NMI ();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (SA1.Flags & IRQ_FLAG)
|
||||||
|
{
|
||||||
|
if (SA1.IRQActive)
|
||||||
|
{
|
||||||
|
if (SA1.WaitingForInterrupt)
|
||||||
|
{
|
||||||
|
SA1.WaitingForInterrupt = FALSE;
|
||||||
|
SA1Registers.PCw++;
|
||||||
|
}
|
||||||
|
if (!SA1CheckFlag (IRQ))
|
||||||
|
S9xSA1Opcode_IRQ ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
SA1.Flags &= ~IRQ_FLAG;
|
||||||
|
}
|
||||||
|
for (i = 0; i < 3 && SA1.Executing; i++)
|
||||||
|
{
|
||||||
|
#ifdef DEBUGGER
|
||||||
|
if (SA1.Flags & TRACE_FLAG){ S9xSA1Trace(); }
|
||||||
|
#endif
|
||||||
|
#ifdef CPU_SHUTDOWN
|
||||||
|
SA1.PBPCAtOpcodeStart = SA1Registers.PBPC;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (SA1.Flags & IRQ_FLAG)
|
register uint8 Op;
|
||||||
{
|
register struct SOpcodes *Opcodes;
|
||||||
if (SA1.IRQActive)
|
if(SA1.PCBase){
|
||||||
{
|
SA1OpenBus = Op = SA1.PCBase[Registers.PCw];
|
||||||
if (SA1.WaitingForInterrupt)
|
Opcodes = SA1.S9xOpcodes;
|
||||||
{
|
} else {
|
||||||
SA1.WaitingForInterrupt = FALSE;
|
Op = S9xSA1GetByte(Registers.PBPC);
|
||||||
SA1Registers.PCw++;
|
Opcodes = S9xOpcodesSlow;
|
||||||
}
|
}
|
||||||
|
if((SA1Registers.PCw&MEMMAP_MASK)+SA1.S9xOpLengths[Op]>=MEMMAP_BLOCK_SIZE){
|
||||||
if (!SA1CheckFlag(IRQ))
|
uint32 oldPC = SA1Registers.PBPC;
|
||||||
S9xSA1Opcode_IRQ();
|
S9xSA1SetPCBase(SA1Registers.PBPC);
|
||||||
}
|
SA1Registers.PBPC = oldPC;
|
||||||
else
|
Opcodes = S9xSA1OpcodesSlow;
|
||||||
SA1.Flags &= ~IRQ_FLAG;
|
}
|
||||||
}
|
Registers.PCw++;
|
||||||
|
(*Opcodes[Op].S9xOpcode) ();
|
||||||
for (int i = 0; i < 3 && SA1.Executing; i++)
|
}
|
||||||
{
|
|
||||||
#ifdef DEBUGGER
|
|
||||||
if (SA1.Flags & TRACE_FLAG)
|
|
||||||
S9xSA1Trace();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CPU_SHUTDOWN
|
|
||||||
SA1.PBPCAtOpcodeStart = SA1Registers.PBPC;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
register uint8 Op;
|
|
||||||
register struct SOpcodes *Opcodes;
|
|
||||||
|
|
||||||
if (SA1.PCBase)
|
|
||||||
{
|
|
||||||
SA1OpenBus = Op = SA1.PCBase[Registers.PCw];
|
|
||||||
Opcodes = SA1.S9xOpcodes;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Op = S9xSA1GetByte(Registers.PBPC);
|
|
||||||
Opcodes = S9xOpcodesSlow;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((SA1Registers.PCw & MEMMAP_MASK) + SA1.S9xOpLengths[Op] >= MEMMAP_BLOCK_SIZE)
|
|
||||||
{
|
|
||||||
uint32 oldPC = SA1Registers.PBPC;
|
|
||||||
S9xSA1SetPCBase(SA1Registers.PBPC);
|
|
||||||
SA1Registers.PBPC = oldPC;
|
|
||||||
Opcodes = S9xSA1OpcodesSlow;
|
|
||||||
}
|
|
||||||
|
|
||||||
Registers.PCw++;
|
|
||||||
(*Opcodes[Op].S9xOpcode)();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,49 +159,54 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _SAR_H_
|
#ifndef _SAR_H_
|
||||||
#define _SAR_H_
|
#define _SAR_H_
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "port.h"
|
||||||
|
|
||||||
|
#ifndef snes9x_types_defined
|
||||||
|
#include "9xtypes.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef RIGHTSHIFT_IS_SAR
|
#ifdef RIGHTSHIFT_IS_SAR
|
||||||
#define SAR(b, n) ((b) >> (n))
|
#define SAR(b, n) ((b)>>(n))
|
||||||
#else
|
#else
|
||||||
|
|
||||||
static inline int8 SAR (const int8 b, const int n)
|
static inline int8 SAR(const int8 b, const int n){
|
||||||
{
|
|
||||||
#ifndef RIGHTSHIFT_int8_IS_SAR
|
#ifndef RIGHTSHIFT_int8_IS_SAR
|
||||||
if (b < 0)
|
if(b<0) return (b>>n)|(-1<<(8-n));
|
||||||
return ((b >> n) | (-1 << (8 - n)));
|
|
||||||
#endif
|
#endif
|
||||||
return (b >> n);
|
return b>>n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int16 SAR (const int16 b, const int n)
|
static inline int16 SAR(const int16 b, const int n){
|
||||||
{
|
|
||||||
#ifndef RIGHTSHIFT_int16_IS_SAR
|
#ifndef RIGHTSHIFT_int16_IS_SAR
|
||||||
if (b < 0)
|
if(b<0) return (b>>n)|(-1<<(16-n));
|
||||||
return ((b >> n) | (-1 << (16 - n)));
|
|
||||||
#endif
|
#endif
|
||||||
return (b >> n);
|
return b>>n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int32 SAR (const int32 b, const int n)
|
static inline int32 SAR(const int32 b, const int n){
|
||||||
{
|
|
||||||
#ifndef RIGHTSHIFT_int32_IS_SAR
|
#ifndef RIGHTSHIFT_int32_IS_SAR
|
||||||
if (b < 0)
|
if(b<0) return (b>>n)|(-1<<(32-n));
|
||||||
return ((b >> n) | (-1 << (32 - n)));
|
|
||||||
#endif
|
#endif
|
||||||
return (b >> n);
|
return b>>n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int64 SAR (const int64 b, const int n)
|
static inline int64 SAR(const int64 b, const int n){
|
||||||
{
|
|
||||||
#ifndef RIGHTSHIFT_int64_IS_SAR
|
#ifndef RIGHTSHIFT_int64_IS_SAR
|
||||||
if (b < 0)
|
if(b<0) return (b>>n)|(-1<<(64-n));
|
||||||
return ((b >> n) | (-1 << (64 - n)));
|
|
||||||
#endif
|
#endif
|
||||||
return (b >> n);
|
return b>>n;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1,299 +0,0 @@
|
|||||||
/**********************************************************************************
|
|
||||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
|
||||||
|
|
||||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
|
||||||
Jerremy Koot (jkoot@snes9x.com)
|
|
||||||
|
|
||||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
|
||||||
|
|
||||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
|
||||||
|
|
||||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
|
||||||
|
|
||||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
|
||||||
|
|
||||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
|
||||||
Kris Bleakley (codeviolation@hotmail.com)
|
|
||||||
|
|
||||||
(c) Copyright 2002 - 2007 Brad Jorsch (anomie@users.sourceforge.net),
|
|
||||||
Nach (n-a-c-h@users.sourceforge.net),
|
|
||||||
zones (kasumitokoduck@yahoo.com)
|
|
||||||
|
|
||||||
(c) Copyright 2006 - 2007 nitsuja
|
|
||||||
|
|
||||||
|
|
||||||
BS-X C emulator code
|
|
||||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
|
||||||
zones
|
|
||||||
|
|
||||||
C4 x86 assembler and some C emulation code
|
|
||||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
|
||||||
Nach,
|
|
||||||
zsKnight (zsknight@zsnes.com)
|
|
||||||
|
|
||||||
C4 C++ code
|
|
||||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
|
||||||
Nach
|
|
||||||
|
|
||||||
DSP-1 emulator code
|
|
||||||
(c) Copyright 1998 - 2006 _Demo_,
|
|
||||||
Andreas Naive (andreasnaive@gmail.com)
|
|
||||||
Gary Henderson,
|
|
||||||
Ivar (ivar@snes9x.com),
|
|
||||||
John Weidman,
|
|
||||||
Kris Bleakley,
|
|
||||||
Matthew Kendora,
|
|
||||||
Nach,
|
|
||||||
neviksti (neviksti@hotmail.com)
|
|
||||||
|
|
||||||
DSP-2 emulator code
|
|
||||||
(c) Copyright 2003 John Weidman,
|
|
||||||
Kris Bleakley,
|
|
||||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
|
||||||
Matthew Kendora,
|
|
||||||
neviksti
|
|
||||||
|
|
||||||
|
|
||||||
DSP-3 emulator code
|
|
||||||
(c) Copyright 2003 - 2006 John Weidman,
|
|
||||||
Kris Bleakley,
|
|
||||||
Lancer,
|
|
||||||
z80 gaiden
|
|
||||||
|
|
||||||
DSP-4 emulator code
|
|
||||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
|
||||||
John Weidman,
|
|
||||||
Kris Bleakley,
|
|
||||||
Nach,
|
|
||||||
z80 gaiden
|
|
||||||
|
|
||||||
OBC1 emulator code
|
|
||||||
(c) Copyright 2001 - 2004 zsKnight,
|
|
||||||
pagefault (pagefault@zsnes.com),
|
|
||||||
Kris Bleakley,
|
|
||||||
Ported from x86 assembler to C by sanmaiwashi
|
|
||||||
|
|
||||||
SPC7110 and RTC C++ emulator code
|
|
||||||
(c) Copyright 2002 Matthew Kendora with research by
|
|
||||||
zsKnight,
|
|
||||||
John Weidman,
|
|
||||||
Dark Force
|
|
||||||
|
|
||||||
S-DD1 C emulator code
|
|
||||||
(c) Copyright 2003 Brad Jorsch with research by
|
|
||||||
Andreas Naive,
|
|
||||||
John Weidman
|
|
||||||
|
|
||||||
S-RTC C emulator code
|
|
||||||
(c) Copyright 2001-2006 byuu,
|
|
||||||
John Weidman
|
|
||||||
|
|
||||||
ST010 C++ emulator code
|
|
||||||
(c) Copyright 2003 Feather,
|
|
||||||
John Weidman,
|
|
||||||
Kris Bleakley,
|
|
||||||
Matthew Kendora
|
|
||||||
|
|
||||||
Super FX x86 assembler emulator code
|
|
||||||
(c) Copyright 1998 - 2003 _Demo_,
|
|
||||||
pagefault,
|
|
||||||
zsKnight,
|
|
||||||
|
|
||||||
Super FX C emulator code
|
|
||||||
(c) Copyright 1997 - 1999 Ivar,
|
|
||||||
Gary Henderson,
|
|
||||||
John Weidman
|
|
||||||
|
|
||||||
Sound DSP emulator code is derived from SNEeSe and OpenSPC:
|
|
||||||
(c) Copyright 1998 - 2003 Brad Martin
|
|
||||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
|
||||||
|
|
||||||
SH assembler code partly based on x86 assembler code
|
|
||||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
|
||||||
|
|
||||||
2xSaI filter
|
|
||||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
|
||||||
|
|
||||||
HQ2x, HQ3x, HQ4x filters
|
|
||||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
|
||||||
|
|
||||||
Win32 GUI code
|
|
||||||
(c) Copyright 2003 - 2006 blip,
|
|
||||||
funkyass,
|
|
||||||
Matthew Kendora,
|
|
||||||
Nach,
|
|
||||||
nitsuja
|
|
||||||
|
|
||||||
Mac OS GUI code
|
|
||||||
(c) Copyright 1998 - 2001 John Stiles
|
|
||||||
(c) Copyright 2001 - 2007 zones
|
|
||||||
|
|
||||||
|
|
||||||
Specific ports contains the works of other authors. See headers in
|
|
||||||
individual files.
|
|
||||||
|
|
||||||
|
|
||||||
Snes9x homepage: http://www.snes9x.com
|
|
||||||
|
|
||||||
Permission to use, copy, modify and/or 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 or it's derivatives.
|
|
||||||
|
|
||||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
|
||||||
seek permission of the copyright holders first. Commercial use includes,
|
|
||||||
but is not limited to, charging money for Snes9x or software derived from
|
|
||||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
|
||||||
using Snes9x as a promotion for your commercial product.
|
|
||||||
|
|
||||||
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.
|
|
||||||
**********************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_LIBPNG
|
|
||||||
#include <png.h>
|
|
||||||
#endif
|
|
||||||
#include "snes9x.h"
|
|
||||||
#include "memmap.h"
|
|
||||||
#include "display.h"
|
|
||||||
#include "screenshot.h"
|
|
||||||
|
|
||||||
|
|
||||||
bool8 S9xDoScreenshot (int width, int height)
|
|
||||||
{
|
|
||||||
Settings.TakeScreenshot = FALSE;
|
|
||||||
|
|
||||||
#ifdef HAVE_LIBPNG
|
|
||||||
FILE *fp;
|
|
||||||
png_structp png_ptr;
|
|
||||||
png_infop info_ptr;
|
|
||||||
png_color_8 sig_bit;
|
|
||||||
int imgwidth, imgheight;
|
|
||||||
const char *fname;
|
|
||||||
|
|
||||||
fname = S9xGetFilenameInc(".png", SCREENSHOT_DIR);
|
|
||||||
|
|
||||||
fp = fopen(fname, "wb");
|
|
||||||
if (!fp)
|
|
||||||
{
|
|
||||||
S9xMessage(S9X_ERROR, 0, "Failed to take screenshot.");
|
|
||||||
return (FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
|
||||||
if (!png_ptr)
|
|
||||||
{
|
|
||||||
fclose(fp);
|
|
||||||
unlink(fname);
|
|
||||||
S9xMessage(S9X_ERROR, 0, "Failed to take screenshot.");
|
|
||||||
return (FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
info_ptr = png_create_info_struct(png_ptr);
|
|
||||||
if (!info_ptr)
|
|
||||||
{
|
|
||||||
png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
|
|
||||||
fclose(fp);
|
|
||||||
unlink(fname);
|
|
||||||
S9xMessage(S9X_ERROR, 0, "Failed to take screenshot.");
|
|
||||||
return (FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (setjmp(png_jmpbuf(png_ptr)))
|
|
||||||
{
|
|
||||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
|
||||||
fclose(fp);
|
|
||||||
unlink(fname);
|
|
||||||
S9xMessage(S9X_ERROR, 0, "Failed to take screenshot.");
|
|
||||||
return (FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
imgwidth = width;
|
|
||||||
imgheight = height;
|
|
||||||
|
|
||||||
if (Settings.StretchScreenshots == 1)
|
|
||||||
{
|
|
||||||
if (width > SNES_WIDTH && height <= SNES_HEIGHT_EXTENDED)
|
|
||||||
imgheight = height << 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (Settings.StretchScreenshots == 2)
|
|
||||||
{
|
|
||||||
if (width <= SNES_WIDTH)
|
|
||||||
imgwidth = width << 1;
|
|
||||||
if (height <= SNES_HEIGHT_EXTENDED)
|
|
||||||
imgheight = height << 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
png_init_io(png_ptr, fp);
|
|
||||||
|
|
||||||
png_set_IHDR(png_ptr, info_ptr, imgwidth, imgheight, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
|
|
||||||
|
|
||||||
sig_bit.red = 5;
|
|
||||||
sig_bit.green = 5;
|
|
||||||
sig_bit.blue = 5;
|
|
||||||
png_set_sBIT(png_ptr, info_ptr, &sig_bit);
|
|
||||||
png_set_shift(png_ptr, &sig_bit);
|
|
||||||
|
|
||||||
png_write_info(png_ptr, info_ptr);
|
|
||||||
|
|
||||||
png_set_packing(png_ptr);
|
|
||||||
|
|
||||||
png_byte *row_pointer = new png_byte[png_get_rowbytes(png_ptr, info_ptr)];
|
|
||||||
uint16 *screen = GFX.Screen;
|
|
||||||
|
|
||||||
for (int y = 0; y < height; y++, screen += GFX.RealPPL)
|
|
||||||
{
|
|
||||||
png_byte *rowpix = row_pointer;
|
|
||||||
|
|
||||||
for (int x = 0; x < width; x++)
|
|
||||||
{
|
|
||||||
uint32 r, g, b;
|
|
||||||
|
|
||||||
DECOMPOSE_PIXEL(screen[x], r, g, b);
|
|
||||||
|
|
||||||
*(rowpix++) = r;
|
|
||||||
*(rowpix++) = g;
|
|
||||||
*(rowpix++) = b;
|
|
||||||
|
|
||||||
if (imgwidth != width)
|
|
||||||
{
|
|
||||||
*(rowpix++) = r;
|
|
||||||
*(rowpix++) = g;
|
|
||||||
*(rowpix++) = b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
png_write_row(png_ptr, row_pointer);
|
|
||||||
if (imgheight != height)
|
|
||||||
png_write_row(png_ptr, row_pointer);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete [] row_pointer;
|
|
||||||
|
|
||||||
png_write_end(png_ptr, info_ptr);
|
|
||||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
|
|
||||||
fprintf(stderr, "%s saved.\n", fname);
|
|
||||||
|
|
||||||
const char *base = S9xBasename(fname);
|
|
||||||
sprintf(String, "Saved screenshot %s", base);
|
|
||||||
S9xMessage(S9X_INFO, 0, String);
|
|
||||||
|
|
||||||
return (TRUE);
|
|
||||||
#else
|
|
||||||
fprintf(stderr, "Screenshot support not available (libpng was not found at build time).\n");
|
|
||||||
return (FALSE);
|
|
||||||
#endif
|
|
||||||
}
|
|
@ -159,9 +159,12 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _SCREENSHOT_H_
|
|
||||||
#define _SCREENSHOT_H_
|
|
||||||
|
|
||||||
bool8 S9xDoScreenshot (int, int);
|
|
||||||
|
#ifndef SCREENSHOT_H
|
||||||
|
#define SCREENSHOT_H
|
||||||
|
|
||||||
|
bool8 S9xDoScreenshot(int width, int height);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -159,37 +159,97 @@
|
|||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "snes9x.h"
|
#include "snes9x.h"
|
||||||
#include "memmap.h"
|
#include "memmap.h"
|
||||||
|
#include "ppu.h"
|
||||||
#include "sdd1.h"
|
#include "sdd1.h"
|
||||||
#include "display.h"
|
#include "display.h"
|
||||||
|
|
||||||
|
#ifdef __linux
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
void S9xSetSDD1MemoryMap (uint32 bank, uint32 value)
|
void S9xSetSDD1MemoryMap (uint32 bank, uint32 value)
|
||||||
{
|
{
|
||||||
bank = 0xc00 + bank * 0x100;
|
bank = 0xc00 + bank * 0x100;
|
||||||
value = value * 1024 * 1024;
|
value = value * 1024 * 1024;
|
||||||
|
|
||||||
for (int c = 0; c < 0x100; c += 16)
|
int c;
|
||||||
{
|
|
||||||
uint8 *block = &Memory.ROM[value + (c << 12)];
|
for (c = 0; c < 0x100; c += 16)
|
||||||
for (int i = c; i < c + 16; i++)
|
{
|
||||||
Memory.Map[i + bank] = block;
|
uint8 *block = &Memory.ROM [value + (c << 12)];
|
||||||
}
|
int i;
|
||||||
|
|
||||||
|
for (i = c; i < c + 16; i++)
|
||||||
|
Memory.Map [i + bank] = block;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xResetSDD1 (void)
|
void S9xResetSDD1 ()
|
||||||
{
|
{
|
||||||
memset(&Memory.FillRAM[0x4800], 0, 4);
|
memset (&Memory.FillRAM [0x4800], 0, 4);
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
Memory.FillRAM[0x4804 + i] = i;
|
Memory.FillRAM [0x4804 + i] = i;
|
||||||
S9xSetSDD1MemoryMap(i, i);
|
S9xSetSDD1MemoryMap (i, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xSDD1PostLoadState (void)
|
void S9xSDD1PostLoadState ()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
S9xSetSDD1MemoryMap(i, Memory.FillRAM[0x4804 + i]);
|
S9xSetSDD1MemoryMap (i, Memory.FillRAM [0x4804 + i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int S9xCompareSDD1LoggedDataEntries (const void *p1, const void *p2)
|
||||||
|
{
|
||||||
|
uint8 *b1 = (uint8 *) p1;
|
||||||
|
uint8 *b2 = (uint8 *) p2;
|
||||||
|
uint32 a1 = (*b1 << 16) + (*(b1 + 1) << 8) + *(b1 + 2);
|
||||||
|
uint32 a2 = (*b2 << 16) + (*(b2 + 1) << 8) + *(b2 + 2);
|
||||||
|
|
||||||
|
return (a1 - a2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void S9xSDD1SaveLoggedData ()
|
||||||
|
{
|
||||||
|
if (Memory.SDD1LoggedDataCount != Memory.SDD1LoggedDataCountPrev)
|
||||||
|
{
|
||||||
|
qsort (Memory.SDD1LoggedData, Memory.SDD1LoggedDataCount, 8,
|
||||||
|
S9xCompareSDD1LoggedDataEntries);
|
||||||
|
|
||||||
|
FILE *fs = fopen (S9xGetFilename (".dat", PATCH_DIR), "wb");
|
||||||
|
|
||||||
|
if (fs)
|
||||||
|
{
|
||||||
|
fwrite (Memory.SDD1LoggedData, 8,
|
||||||
|
Memory.SDD1LoggedDataCount, fs);
|
||||||
|
fclose (fs);
|
||||||
|
#if defined(__linux)
|
||||||
|
chown (S9xGetFilename (".dat", PATCH_DIR), getuid (), getgid ());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
Memory.SDD1LoggedDataCountPrev = Memory.SDD1LoggedDataCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void S9xSDD1LoadLoggedData ()
|
||||||
|
{
|
||||||
|
FILE *fs = fopen (S9xGetFilename (".dat", PATCH_DIR), "rb");
|
||||||
|
|
||||||
|
Memory.SDD1LoggedDataCount = Memory.SDD1LoggedDataCountPrev = 0;
|
||||||
|
|
||||||
|
if (fs)
|
||||||
|
{
|
||||||
|
int c = fread (Memory.SDD1LoggedData, 8,
|
||||||
|
MEMMAP_MAX_SDD1_LOGGED_ENTRIES, fs);
|
||||||
|
|
||||||
|
if (c != EOF)
|
||||||
|
Memory.SDD1LoggedDataCount = Memory.SDD1LoggedDataCountPrev = c;
|
||||||
|
fclose (fs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user