2008-08-06 03:09:59 +02:00
|
|
|
/**********************************************************************************
|
|
|
|
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
|
|
|
|
2008-10-16 03:49:58 +02:00
|
|
|
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
|
2008-08-06 03:09:59 +02:00
|
|
|
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)
|
|
|
|
|
2008-10-16 03:49:58 +02:00
|
|
|
(c) Copyright 2002 - 2006 Brad Jorsch (anomie@users.sourceforge.net),
|
|
|
|
funkyass (funkyass@spam.shaw.ca),
|
|
|
|
Kris Bleakley (codeviolation@hotmail.com),
|
|
|
|
Nach (n-a-c-h@users.sourceforge.net), and
|
2008-08-06 03:09:59 +02:00
|
|
|
zones (kasumitokoduck@yahoo.com)
|
|
|
|
|
|
|
|
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
|
|
|
|
|
2008-10-16 03:49:58 +02:00
|
|
|
HQ2x filter
|
2008-08-06 03:09:59 +02:00
|
|
|
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
|
|
|
|
|
|
|
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
|
2008-10-16 03:49:58 +02:00
|
|
|
and source form, for non-commercial purposes, is hereby granted without
|
|
|
|
fee, providing that this license information and copyright notice appear
|
2008-08-06 03:09:59 +02:00
|
|
|
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.
|
|
|
|
**********************************************************************************/
|
|
|
|
|
2008-10-16 03:49:58 +02:00
|
|
|
#define _GLOBALS_CPP
|
2008-08-06 03:09:59 +02:00
|
|
|
|
|
|
|
#include "snes9x.h"
|
|
|
|
#include "memmap.h"
|
|
|
|
#include "ppu.h"
|
|
|
|
#include "dsp1.h"
|
|
|
|
#include "missing.h"
|
|
|
|
#include "cpuexec.h"
|
|
|
|
#include "debug.h"
|
|
|
|
#include "apu.h"
|
|
|
|
#include "dma.h"
|
|
|
|
#include "fxemu.h"
|
|
|
|
#include "gfx.h"
|
|
|
|
#include "soundux.h"
|
|
|
|
|
2008-10-16 03:49:58 +02:00
|
|
|
#ifndef NGC
|
2008-08-06 03:09:59 +02:00
|
|
|
#include "cheats.h"
|
2008-10-16 03:49:58 +02:00
|
|
|
#endif
|
2008-08-06 03:09:59 +02:00
|
|
|
|
|
|
|
#include "sa1.h"
|
|
|
|
#include "bsx.h"
|
2008-10-16 03:49:58 +02:00
|
|
|
|
2008-08-06 03:09:59 +02:00
|
|
|
#ifdef NETPLAY_SUPPORT
|
|
|
|
#include "netplay.h"
|
|
|
|
#endif
|
|
|
|
|
2008-10-16 03:49:58 +02:00
|
|
|
#include "spc7110.h"
|
|
|
|
|
|
|
|
//START_EXTERN_C
|
2008-08-06 03:09:59 +02:00
|
|
|
char String[513];
|
|
|
|
|
|
|
|
struct Missing missing;
|
|
|
|
|
|
|
|
struct SICPU ICPU;
|
|
|
|
|
|
|
|
struct SCPUState CPU;
|
|
|
|
|
|
|
|
struct STimings Timings;
|
|
|
|
|
|
|
|
struct SRegisters Registers;
|
|
|
|
|
|
|
|
struct SAPU APU;
|
|
|
|
|
|
|
|
struct SIAPU IAPU;
|
|
|
|
|
|
|
|
struct SAPURegisters APURegisters;
|
|
|
|
|
|
|
|
struct SSettings Settings;
|
|
|
|
|
|
|
|
struct SDSP1 DSP1;
|
|
|
|
|
|
|
|
struct SSA1Registers SA1Registers;
|
|
|
|
|
|
|
|
struct SSA1 SA1;
|
|
|
|
|
|
|
|
struct SBSX BSX;
|
|
|
|
|
|
|
|
SSoundData SoundData;
|
|
|
|
|
|
|
|
SnesModel M1SNES={1,3,2};
|
|
|
|
SnesModel M2SNES={2,4,3};
|
|
|
|
SnesModel* Model=&M1SNES;
|
|
|
|
|
2008-10-16 03:49:58 +02:00
|
|
|
|
2008-09-10 07:57:37 +02:00
|
|
|
uint8 *SRAM = NULL;
|
2008-10-16 03:49:58 +02:00
|
|
|
uint8 *ROM = NULL;
|
2008-08-06 03:09:59 +02:00
|
|
|
uint8 *RegRAM = NULL;
|
|
|
|
|
|
|
|
CMemory Memory;
|
|
|
|
|
2008-10-16 03:49:58 +02:00
|
|
|
SSNESGameFixes SNESGameFixes;
|
2008-08-06 03:09:59 +02:00
|
|
|
|
|
|
|
unsigned char OpenBus = 0;
|
|
|
|
|
|
|
|
|
2008-10-16 03:49:58 +02:00
|
|
|
//END_EXTERN_C
|
2008-08-06 03:09:59 +02:00
|
|
|
|
|
|
|
#ifndef ZSNES_FX
|
|
|
|
struct FxInit_s SuperFX;
|
|
|
|
#else
|
|
|
|
START_EXTERN_C
|
|
|
|
uint8 *SFXPlotTable = NULL;
|
|
|
|
END_EXTERN_C
|
|
|
|
#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
|
|
|
|
|
|
|
|
uint32 RED_LOW_BIT_MASK = RED_LOW_BIT_MASK_RGB565;
|
|
|
|
uint32 GREEN_LOW_BIT_MASK = GREEN_LOW_BIT_MASK_RGB565;
|
|
|
|
uint32 BLUE_LOW_BIT_MASK = BLUE_LOW_BIT_MASK_RGB565;
|
|
|
|
uint32 RED_HI_BIT_MASK = RED_HI_BIT_MASK_RGB565;
|
|
|
|
uint32 GREEN_HI_BIT_MASK = GREEN_HI_BIT_MASK_RGB565;
|
|
|
|
uint32 BLUE_HI_BIT_MASK = BLUE_HI_BIT_MASK_RGB565;
|
|
|
|
uint32 MAX_RED = MAX_RED_RGB565;
|
|
|
|
uint32 MAX_GREEN = MAX_GREEN_RGB565;
|
|
|
|
uint32 MAX_BLUE = MAX_BLUE_RGB565;
|
|
|
|
uint32 SPARE_RGB_BIT_MASK = SPARE_RGB_BIT_MASK_RGB565;
|
|
|
|
uint32 GREEN_HI_BIT = (MAX_GREEN_RGB565 + 1) >> 1;
|
2008-10-16 03:49:58 +02:00
|
|
|
uint32 RGB_LOW_BITS_MASK = (RED_LOW_BIT_MASK_RGB565 |
|
2008-08-06 03:09:59 +02:00
|
|
|
GREEN_LOW_BIT_MASK_RGB565 |
|
|
|
|
BLUE_LOW_BIT_MASK_RGB565);
|
|
|
|
uint32 RGB_HI_BITS_MASK = (RED_HI_BIT_MASK_RGB565 |
|
|
|
|
GREEN_HI_BIT_MASK_RGB565 |
|
|
|
|
BLUE_HI_BIT_MASK_RGB565);
|
|
|
|
uint32 RGB_HI_BITS_MASKx2 = (RED_HI_BIT_MASK_RGB565 |
|
|
|
|
GREEN_HI_BIT_MASK_RGB565 |
|
|
|
|
BLUE_HI_BIT_MASK_RGB565) << 1;
|
|
|
|
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
|
|
|
|
|
|
|
|
uint8 GetBank = 0;
|
|
|
|
|
2008-10-16 03:49:58 +02:00
|
|
|
#ifndef NGC
|
2008-08-06 03:09:59 +02:00
|
|
|
struct SCheatData Cheat;
|
2008-10-16 03:49:58 +02:00
|
|
|
#endif
|
2008-08-06 03:09:59 +02:00
|
|
|
|
|
|
|
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
|
|
|
|
};
|
|
|
|
|
|
|
|
//modified per anomie Mode 5 findings
|
|
|
|
int HDMA_ModeByteCounts [8] = {
|
|
|
|
1, 2, 2, 4, 4, 4, 2, 4
|
|
|
|
};
|
|
|
|
|
|
|
|
uint16 BlackColourMap [256];
|
|
|
|
uint16 DirectColourMaps [8][256];
|
|
|
|
|
|
|
|
uint32 HeadMask [4] = {
|
|
|
|
#ifdef LSB_FIRST
|
|
|
|
0xffffffff, 0xffffff00, 0xffff0000, 0xff000000
|
|
|
|
#else
|
|
|
|
0xffffffff, 0x00ffffff, 0x0000ffff, 0x000000ff
|
|
|
|
#endif
|
|
|
|
};
|
|
|
|
|
|
|
|
uint32 TailMask [5] = {
|
|
|
|
#ifdef LSB_FIRST
|
|
|
|
0x00000000, 0x000000ff, 0x0000ffff, 0x00ffffff, 0xffffffff
|
|
|
|
#else
|
|
|
|
0x00000000, 0xff000000, 0xffff0000, 0xffffff00, 0xffffffff
|
|
|
|
#endif
|
|
|
|
};
|
|
|
|
|
|
|
|
START_EXTERN_C
|
|
|
|
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
|
|
|
|
};
|
|
|
|
|
|
|
|
#ifdef NETPLAY_SUPPORT
|
|
|
|
struct SNetPlay NetPlay;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Raw SPC700 instruction cycle lengths
|
2008-10-16 03:49:58 +02:00
|
|
|
int32 S9xAPUCycleLengths [256] =
|
2008-08-06 03:09:59 +02:00
|
|
|
{
|
|
|
|
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
|
|
|
|
/* 00 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 6, 8,
|
|
|
|
/* 10 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 4, 6,
|
|
|
|
/* 20 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 5, 4,
|
|
|
|
/* 30 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 3, 8,
|
|
|
|
/* 40 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 6, 6,
|
|
|
|
/* 50 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 4, 5, 2, 2, 4, 3,
|
|
|
|
/* 60 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 5, 5,
|
|
|
|
/* 70 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 6,
|
|
|
|
/* 80 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 2, 4, 5,
|
|
|
|
/* 90 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2,12, 5,
|
|
|
|
/* A0 */ 3, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 2, 4, 4,
|
|
|
|
/* B0 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 4,
|
|
|
|
/* C0 */ 3, 8, 4, 5, 4, 5, 4, 7, 2, 5, 6, 4, 5, 2, 4, 9,
|
|
|
|
/* D0 */ 2, 8, 4, 5, 5, 6, 6, 7, 4, 5, 5, 5, 2, 2, 6, 3,
|
|
|
|
/* E0 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 4, 5, 3, 4, 3, 4, 3,
|
|
|
|
/* F0 */ 2, 8, 4, 5, 4, 5, 5, 6, 3, 4, 5, 4, 2, 2, 4, 3
|
|
|
|
};
|
|
|
|
|
|
|
|
// 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 */
|
|
|
|
/* 00 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 6, 8,
|
|
|
|
/* 10 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 4, 6,
|
|
|
|
/* 20 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 5, 4,
|
|
|
|
/* 30 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 3, 8,
|
|
|
|
/* 40 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 6, 6,
|
|
|
|
/* 50 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 4, 5, 2, 2, 4, 3,
|
|
|
|
/* 60 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 5, 5,
|
|
|
|
/* 70 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 6,
|
|
|
|
/* 80 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 2, 4, 5,
|
|
|
|
/* 90 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2,12, 5,
|
|
|
|
/* A0 */ 3, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 2, 4, 4,
|
|
|
|
/* B0 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 4,
|
|
|
|
/* C0 */ 3, 8, 4, 5, 4, 5, 4, 7, 2, 5, 6, 4, 5, 2, 4, 9,
|
|
|
|
/* D0 */ 2, 8, 4, 5, 5, 6, 6, 7, 4, 5, 5, 5, 2, 2, 6, 3,
|
|
|
|
/* E0 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 4, 5, 3, 4, 3, 4, 3,
|
|
|
|
/* F0 */ 2, 8, 4, 5, 4, 5, 5, 6, 3, 4, 5, 4, 2, 2, 4, 3
|
|
|
|
};
|
|
|
|
|
|
|
|
END_EXTERN_C
|
|
|
|
|