-Too many to write

This commit is contained in:
Askot 2016-09-17 20:43:24 -07:00
parent 2037f6cfa1
commit aa7cf18989
247 changed files with 36425 additions and 5953 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
/build_wii
/build_gc
/executables

View File

@ -19,26 +19,26 @@ TARGET := fceugx-gc
TARGETDIR := executables
BUILD := build_gc
SOURCES := source source/images source/sounds source/fonts source/lang \
source/gui source/utils source/utils/sz \
source/gui source/utils source/utils/unzip source/utils/sz \
source/fceultra source/fceultra/boards source/fceultra/input \
source/fceultra/utils source/fceultra/mbshare
source/fceultra/utils source/fceultra/mbshare source/utils/vm
INCLUDES := source
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
CFLAGS = -g -O3 -Wall $(MACHDEP) $(INCLUDE) -DNO_SOUND \
CFLAGS = -g -O3 -LTO -Wall $(MACHDEP) $(INCLUDE) \
-DFRAMESKIP -DPSS_STYLE=1 -DPATH_MAX=1024 -DHAVE_ASPRINTF \
-D_SZ_ONE_DIRECTORY -D_LZMA_IN_CB -D_LZMA_OUT_READ \
-D_SZ_ONE_DIRECTORY -D_LZMA_IN_CB -D_LZMA_OUT_READ -DUSE_VM \
-fomit-frame-pointer \
-Wno-unused-parameter -Wno-strict-aliasing -Wno-write-strings
CXXFLAGS = $(CFLAGS)
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map
LDFLAGS = -g $(MACHDEP) -LTO -Wl,-Map,$(notdir $@).map
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project
#---------------------------------------------------------------------------------
LIBS := -lpng -lmxml -ltinysmb -lbba -lfat -liso9660 -lz -logc -lfreetype
LIBS := -lpng -lmxml -ltinysmb -lbba -lfat -liso9660 -lvorbisidec -lasnd -lz -logc -lfreetype
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
@ -70,6 +70,7 @@ SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S)))
TTFFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.ttf)))
LANGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.lang)))
PNGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.png)))
OGGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.ogg)))
PCMFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.pcm)))
#---------------------------------------------------------------------------------
@ -85,7 +86,7 @@ export OFILES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \
$(sFILES:.s=.o) $(SFILES:.S=.o) \
$(TTFFILES:.ttf=.ttf.o) $(LANGFILES:.lang=.lang.o) \
$(PNGFILES:.png=.png.o) \
$(PCMFILES:.pcm=.pcm.o)
$(OGGFILES:.ogg=.ogg.o) $(PCMFILES:.pcm=.pcm.o)
#---------------------------------------------------------------------------------
# build a list of include paths
@ -136,7 +137,7 @@ $(OUTPUT).dol: $(OUTPUT).elf
$(OUTPUT).elf: $(OFILES)
#---------------------------------------------------------------------------------
# This rule links in binary data with these extensions: ttf lang png pcm
# This rule links in binary data with these extensions: ttf lang png ogg pcm
#---------------------------------------------------------------------------------
%.ttf.o : %.ttf
@echo $(notdir $<)
@ -149,7 +150,11 @@ $(OUTPUT).elf: $(OFILES)
%.png.o : %.png
@echo $(notdir $<)
$(bin2o)
%.ogg.o : %.ogg
@echo $(notdir $<)
$(bin2o)
%.pcm.o : %.pcm
@echo $(notdir $<)
$(bin2o)

View File

@ -16,8 +16,8 @@ include $(DEVKITPPC)/wii_rules
# INCLUDES is a list of directories containing extra header files
#---------------------------------------------------------------------------------
TARGET := fceugx-wii
TARGETDIR := executables
BUILD := build_wii
TARGETDIR := executables
BUILD := build_wii
SOURCES := source source/images source/sounds source/fonts source/lang \
source/gui source/utils source/utils/sz source/utils/unzip \
source/fceultra source/fceultra/boards source/fceultra/input \
@ -27,19 +27,19 @@ INCLUDES := source
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
CFLAGS = -g -O3 -Wall $(MACHDEP) $(INCLUDE) \
CFLAGS = -g -O3 -Wall $(MACHDEP) $(INCLUDE) -DNO_SOUND \
-DFRAMESKIP -DPSS_STYLE=1 -DPATH_MAX=1024 -DHAVE_ASPRINTF \
-D_SZ_ONE_DIRECTORY -D_LZMA_IN_CB -D_LZMA_OUT_READ \
-fomit-frame-pointer \
-Wno-unused-parameter -Wno-strict-aliasing -Wno-write-strings
CXXFLAGS = $(CFLAGS)
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map,-wrap,wiiuse_register
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project
#---------------------------------------------------------------------------------
LIBS := -ldi -liso9660 -lpng -lmxml \
-lfat -lwiiuse -lz -lbte -lasnd -logc -lvorbisidec -lfreetype -ltinysmb
-lfat -lwiiuse -lwupc -lz -lbte -lasnd -logc -lvorbisidec -lfreetype -ltinysmb
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<app version="1">
<name>FCE Ultra GX</name>
<coder>Tantric</coder>
<version>3.3.4</version>
<coder>Tantric & Zopenko</coder>
<version>3.3.7</version>
<release_date>20130112</release_date>
<short_description>Nintendo Emulator</short_description>
<long_description>A port of FCE Ultra to the Wii.</long_description>

View File

@ -12,7 +12,7 @@ Wii/GameCube.
-=[ Features ]=-
* Wiimote, Nunchuk, Classic, and Gamecube controller support
* Wiimote, Nunchuk, Classic, Wii U Pro and Gamecube controller support
* iNES, FDS, VS, UNIF, and NSF ROM support
* 1-4 Player Support
* Zapper support
@ -26,13 +26,50 @@ Wii/GameCube.
* Cheat support (.CHT files and Game Genie)
* Famicom 3D System support
* IPS/UPS automatic patching support
* NES Compatibility Based on FCEUX 2.2.0+ (r2818)
* NES Compatibility Based on FCEUX 2.2.0+ (r2951)
* Open Source!
×—–­—–­—–­—–­ –­—–­—–­—–­—–­—–­—–­—–­—–­—–­— ­—–­—–­—–­—–­—–­—–­—–­—-­—–­-–•¬
|0O×øo· UPDATE HISTORY ·oø×O0|
`¨•¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨'
[3.3.7 - Apr 18, 2016]
* Added both Firebrandx NES color palettes (thanks to SuperrSonic and Asho).
* Added Nestopia's RGB palette (thanks to SuperrSonic and ShadowOne333).
* Added a new window when selecting a color palette (in order to avoid cycling the color palettes one by one).
* Reverted FDS file in order to fix Disk System support (thanks to Burnt Lasagna) (Support was broken on ver 3.3.5 MOD).
* Added option to disable / enable the Virtual Memory messages on the settings menu.
* Removed the "Reset" and "Power On" messages when loading and reseting a game (Messages were added on ver 3.3.5 MOD).
[3.3.6 - Apr 12, 2015]
* Merged Emu_kidid's 3.3.5 mod version with Zopenko's 3.3.4 mod version.
* Added SuperrSonic's 3DS Virtual Console palette.
* Changed the savestate cursor box color (in order to match the emu's color design).
[3.3.5 MOD - Apr 22, 2015]
* Merged in changes from FCEUX (up to r2951)
* Added tueidj's TLB VM (w/ ARAM storage) for ROM and other data storage
* Enabled menu audio
* Less out of memory crashes
* Free memory displayed on in game menu
[3.3.4 MOD - Apr 12, 2015]
* Added Cebolleto's preview image support.
* Added FIX94's WiiUPro controller support.
* Added SuperrSonic's Wii Virtual Console Palette.
* Increase preview image size and reduce game list width.
* Added a background to the preview image.
* Added a Screenshot button (under the game settings options, the video scaling option must be set to default otherwise screenshot looks smaller and with black borders around it, also screenshot folder must already exist otherwise a folder error will popup).
* Added a "WiiuPro" button on the button mapping menu, the options is just for completeness, since the controller mappings are shared between the wiiupro and the classic controller.
* Fixed the inverted color button selection that was in some option Windows.
* On the cheat menu, increased the cheat name display size and added scrolling if the name is too long to display at once.
* Fixed cover image dimensions, now it displays screenshot and cover within the background border.
* Fixed screenshot option, it no longer creates an additional "dummy" file.
[3.3.4 - January 12, 2013]
* Updated core to latest FCEUX (r2818)

View File

@ -17,6 +17,7 @@
#include <ogc/system.h>
#include <fat.h>
#include <wiiuse/wpad.h>
#include <wupc/wupc.h>
#include <malloc.h>
#include <sys/iosupport.h>
@ -40,6 +41,9 @@
#include "filelist.h"
#include "gui/gui.h"
#include "utils/FreeTypeGX.h"
#ifdef USE_VM
#include "vmalloc.h"
#endif
#include "fceultra/types.h"
@ -49,6 +53,9 @@ void FCEUD_UpdateLeft(uint8 *XBuf, int32 *Buffer, int Count);
void FCEUD_UpdateRight(uint8 *XBuf, int32 *Buffer, int Count);
extern "C" {
#ifdef USE_VM
#include "utils/vm/vm.h"
#endif
extern void __exception_setreload(int t);
}
@ -91,6 +98,26 @@ static void ExitCleanup()
void (*PSOReload) () = (void (*)()) 0x80001800;
#endif
void ExitToWiiflow()
{
ShutoffRumble();
SavePrefs(SILENT);
if (romLoaded && !ConfigRequested && GCSettings.AutoSave == 1)
SaveRAMAuto(SILENT);
ExitCleanup();
if( !!*(u32*)0x80001800 )
{
// Were we launched via HBC? (or via wiiflows stub replacement? :P)
exit(1);
}
else
{
// Wii channel support
SYS_ResetSystem( SYS_RETURNTOMENU, 0, 0 );
}
}
void ExitApp()
{
#ifdef HW_RVL
@ -326,6 +353,10 @@ extern "C" {
int main(int argc, char *argv[])
{
#ifdef USE_VM
VM_Init(ARAM_SIZE, MRAM_BACKING); // Setup Virtual Memory with the entire ARAM
#endif
#ifdef HW_RVL
L2Enhance();
@ -357,6 +388,7 @@ int main(int argc, char *argv[])
SYS_SetPowerCallback(ShutdownCB);
SYS_SetResetCallback(ResetCB);
WUPC_Init();
WPAD_Init();
WPAD_SetPowerButtonCallback((WPADShutdownCallback)ShutdownCB);
DI_Init();
@ -379,13 +411,20 @@ int main(int argc, char *argv[])
DefaultSettings(); // Set defaults
InitialiseAudio();
InitFreeType((u8*)font_ttf, font_ttf_size); // Initialize font system
#ifdef USE_VM
gameScreenPng = (u8 *)vm_malloc(512*1024);
#else
gameScreenPng = (u8 *)malloc(512*1024);
#endif
browserList = (BROWSERENTRY *)malloc(sizeof(BROWSERENTRY)*MAX_BROWSER_SIZE);
InitGUIThreads();
// allocate memory to store rom
#ifdef USE_VM
nesrom = (unsigned char *)vm_malloc(1024*1024*4); // 4 MB should be plenty
#else
nesrom = (unsigned char *)memalign(32,1024*1024*4); // 4 MB should be plenty
#endif
/*** Minimal Emulation Loop ***/
if (!FCEUI_Initialize())
ExitApp();
@ -398,18 +437,86 @@ int main(int argc, char *argv[])
FCEUI_SetSoundQuality(1); // 0 - low, 1 - high, 2 - high (alt.)
int currentTiming = 0;
while (1) // main loop
{
// go back to checking if devices were inserted/removed
bool autoboot = false;
if(argc > 3 && argv[1] != NULL && argv[2] != NULL && argv[3] != NULL)
{
autoboot = true;
ResetBrowser();
LoadPrefs();
if(strcasestr(argv[1], "sd:/") != NULL)
{
GCSettings.SaveMethod = DEVICE_SD;
GCSettings.LoadMethod = DEVICE_SD;
}
else
{
GCSettings.SaveMethod = DEVICE_USB;
GCSettings.LoadMethod = DEVICE_USB;
}
SavePrefs(SILENT);
selectLoadedFile = 1;
std::string dir(argv[1]);
dir.assign(&dir[dir.find_last_of(":") + 2]);
char arg_filename[1024];
strncpy(arg_filename, argv[2], sizeof(arg_filename));
strncpy(GCSettings.LoadFolder, dir.c_str(), sizeof(GCSettings.LoadFolder));
OpenGameList();
strncpy(GCSettings.Exit_Dol_File, argv[3], sizeof(GCSettings.Exit_Dol_File));
if(argc > 5 && argv[4] != NULL && argv[5] != NULL)
{
sscanf(argv[4], "%08x", &GCSettings.Exit_Channel[0]);
sscanf(argv[5], "%08x", &GCSettings.Exit_Channel[1]);
}
else
{
GCSettings.Exit_Channel[0] = 0x00010008;
GCSettings.Exit_Channel[1] = 0x57494948;
}
if(argc > 6 && argv[6] != NULL)
strncpy(GCSettings.LoaderName, argv[6], sizeof(GCSettings.LoaderName));
else
snprintf(GCSettings.LoaderName, sizeof(GCSettings.LoaderName), "WiiFlow");
for(int i = 0; i < browser.numEntries; i++)
{
// Skip it
if (strcmp(browserList[i].filename, ".") == 0 || strcmp(browserList[i].filename, "..") == 0)
continue;
if(strcasestr(browserList[i].filename, arg_filename) != NULL)
{
browser.selIndex = i;
if(IsSz())
{
BrowserLoadSz();
browser.selIndex = 1;
}
break;
}
}
BrowserLoadFile();
}
while (1) // main loop
{
// go back to checking if devices were inserted/removed
// since we're entering the menu
ResumeDeviceThread();
ResumeDeviceThread();
SwitchAudioMode(1);
if(!romLoaded)
MainMenu(MENU_GAMESELECTION);
if(!autoboot)
{
if(!romLoaded)
MainMenu(MENU_GAMESELECTION);
else
MainMenu(MENU_GAME);
ConfigRequested = 0;
ScreenshotRequested = 0;
}
else if(romLoaded && autoboot)
autoboot = false;
else
MainMenu(MENU_GAME);
ExitApp();
if(currentTiming != GCSettings.timing)
{

View File

@ -17,7 +17,7 @@
#include "fceultra/driver.h"
#define APPNAME "FCE Ultra GX"
#define APPVERSION "3.3.4"
#define APPVERSION "3.3.8.x"
#define APPFOLDER "fceugx"
#define PREF_FILE_NAME "settings.xml"
@ -27,7 +27,8 @@
const char pathPrefix[9][8] =
{ "", "sd:/", "usb:/", "dvd:/", "smb:/", "carda:/", "cardb:/" };
enum {
enum
{
DEVICE_AUTO,
DEVICE_SD,
DEVICE_USB,
@ -37,7 +38,8 @@ enum {
DEVICE_SD_SLOTB
};
enum {
enum
{
FILE_RAM,
FILE_STATE,
FILE_ROM,
@ -56,7 +58,8 @@ enum
const char ctrlName[6][20] =
{ "NES Controller", "NES Zapper", "NES Controllers (2)", "NES Controllers (4)" };
enum {
enum
{
LANG_JAPANESE = 0,
LANG_ENGLISH,
LANG_GERMAN,
@ -74,17 +77,22 @@ enum {
LANG_LENGTH
};
struct SGCSettings{
struct SGCSettings
{
int AutoLoad;
int AutoSave;
int LoadMethod; // For ROMS: Auto, SD, DVD, USB, Network (SMB)
int AutoSave;
int LoadMethod; // For ROMS: Auto, SD, DVD, USB, Network (SMB)
int SaveMethod; // For SRAM, Freeze, Prefs: Auto, SD, USB, SMB
char LoadFolder[MAXPATHLEN]; // Path to game files
char LastFileLoaded[MAXPATHLEN]; //Last file loaded filename
char SaveFolder[MAXPATHLEN]; // Path to save files
char CheatFolder[MAXPATHLEN]; // Path to cheat files
char ScreenshotsFolder[MAXPATHLEN]; //Path to screenshots files
char Exit_Dol_File[MAXPATHLEN]; // Exit Path
char LoaderName[20]; // Menu Loader Name
u32 Exit_Channel[2]; // Exit Channel
char smbip[80];
char smbuser[20];
char smbpwd[20];
@ -110,6 +118,7 @@ struct SGCSettings{
int SFXVolume;
int Rumble;
int language;
int DisplayVM;
};
void ExitApp();
@ -128,4 +137,4 @@ extern int fskipc;
extern int turbomode;
extern bool romLoaded;
#endif
#endif

View File

@ -0,0 +1,42 @@
import glob
file_list = glob.glob('*.cpp')
file_list.remove('lua-engine.cpp') # use logic below for this
subdirs = Split("""
boards
drivers/common
fir
input
utils
""")
#palettes
Import('env')
Export('env')
if env['LUA']:
file_list.append('lua-engine.cpp')
if env['SYSTEM_LUA'] == 0:
subdirs.append('lua')
if env['CREATE_AVI']:
subdirs.append('drivers/videolog')
for dir in subdirs:
subdir_files = SConscript('%s/SConscript' % dir)
file_list.append(subdir_files)
if env['PLATFORM'] == 'win32':
platform_files = SConscript('drivers/win/SConscript')
else:
platform_files = SConscript('drivers/sdl/SConscript')
file_list.append(platform_files)
print env['LINKFLAGS']
if env['PLATFORM'] == 'win32':
fceux = env.Program('fceux.exe', file_list)
else:
fceux = env.Program('fceux', file_list)
Return('fceux')

View File

@ -1,15 +1,15 @@
/// \file
/// \brief 6502 assembler and disassembler
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "types.h"
#include "utils/xstring.h"
#include "debug.h"
#include "asm.h"
#include "x6502.h"
#include <cstring>
#include <cstdlib>
#include <cstdio>
///assembles the string to an instruction located at addr, storing opcodes in output buffer
int Assemble(unsigned char *output, int addr, char *str) {
//unsigned char opcode[3] = { 0,0,0 };
@ -276,16 +276,23 @@ char *Disassemble(int addr, uint8 *opcode) {
}
#define indirectX(a) { \
(a) = (opcode[1]+RX)&0xFF; \
(a) = GetMem((a)) | (GetMem((a)+1))<<8; \
(a) = GetMem((a)) | (GetMem(((a)+1)&0xff))<<8; \
}
#define indirectY(a) { \
(a) = GetMem(opcode[1]) | (GetMem(opcode[1]+1))<<8; \
(a) = GetMem(opcode[1]) | (GetMem((opcode[1]+1)&0xff))<<8; \
(a) += RY; \
}
#ifdef BRK_3BYTE_HACK
case 0x00:
sprintf(str,"BRK %02X %02X", opcode[1], opcode[2]);
break;
#else
case 0x00: strcpy(str,"BRK"); break;
#endif
//odd, 1-byte opcodes
case 0x00: strcpy(str,"BRK"); break;
case 0x08: strcpy(str,"PHP"); break;
case 0x0A: strcpy(str,"ASL"); break;
case 0x18: strcpy(str,"CLC"); break;

View File

@ -0,0 +1,45 @@
-- this includes the iup system
--local iuplua_open = package.loadlib("iuplua51.dll", "iuplua_open");
--if(iuplua_open == nil) then require("libiuplua51"); end
--iuplua_open();
-- this includes the "special controls" of iup (dont change the order though)
--local iupcontrolslua_open = package.loadlib("iupluacontrols51.dll", "iupcontrolslua_open");
--if(iupcontrolslua_open == nil) then require("libiupluacontrols51"); end
--iupcontrolslua_open();
require("iuplua");
--TODO!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
--LUACALL_BEFOREEXIT use that instead of emu.OnClose below
-- callback function to clean up our mess
-- this is called when the script exits (forced or natural)
-- you need to close all the open dialogs here or FCEUX crashes
--function emu.OnClose.iuplua()
-- gui.popup("OnClose!");
--if(emu and emu.OnCloseIup ~= nil) then
-- emu.OnCloseIup();
--end
--iup.Close();
--end
-- this system allows you to open a number of dialogs without
-- having to bother about cleanup when the script exits
handles = {}; -- this table should hold the handle to all dialogs created in lua
dialogs = 0; -- should be incremented PRIOR to creating a new dialog
-- called by the onclose event (above)
function OnCloseIup()
if (handles) then -- just in case the user was "smart" enough to clear this
local i = 1;
while (handles[i] ~= nil) do -- cycle through all handles, false handles are skipped, nil denotes the end
if (handles[i] and handles[i].destroy) then -- check for the existence of what we need
handles[i]:destroy(); -- close this dialog (:close() just hides it)
handles[i] = nil;
end;
i = i + 1;
end;
end;
end;
emu.registerexit(OnCloseIup);

View File

@ -19,11 +19,13 @@
*
* FDS Conversions
*
* Super Mario Bros 2 J alt version is a BAD incomplete dump, should be mapper 43
* Super Mario Bros 2j (Alt Full) is a BAD incomplete dump, should be mapper 43
*
* Both Voleyball and Zanac by Whirlind Manu shares the same PCB, but with
* some differences: Voleyball has 8K CHR ROM and 8K ROM at 6000K, Zanac
* have 8K CHR RAM and banked 16K ROM mapper at 6000 as two 8K banks.
*
* Super Mario Bros 2j (Alt Small) uses additionally IRQ timer to drive framerate
*
* PCB for this mapper is "09-034A"
*/
@ -31,9 +33,12 @@
#include "mapinc.h"
static uint8 prg;
static uint32 IRQCount, IRQa;
static SFORMAT StateRegs[] =
{
{ &IRQCount, 4, "IRQC" },
{ &IRQa, 4, "IRQA" },
{ &prg, 1, "PRG" },
{ 0 }
};
@ -44,16 +49,40 @@ static void Sync(void) {
setchr8(0);
}
static DECLFW(UNLSMB2JWrite) {
static DECLFW(UNLSMB2JWrite1) {
prg = V & 1;
Sync();
}
static DECLFW(UNLSMB2JWrite2) {
IRQa = V & 1;
IRQCount = 0;
X6502_IRQEnd(FCEU_IQEXT);
}
static DECLFR(UNLSMB2JRead) {
return 0xFF;
}
static void UNLSMB2JPower(void) {
prg = 0;
Sync();
SetReadHandler(0x6000, 0xFFFF, CartBR);
SetWriteHandler(0x4027, 0x4027, UNLSMB2JWrite);
SetReadHandler(0x4042, 0x4055, UNLSMB2JRead);
SetWriteHandler(0x4068, 0x4068, UNLSMB2JWrite2);
SetWriteHandler(0x4027, 0x4027, UNLSMB2JWrite1);
}
static void UNLSMB2JIRQHook(int a) {
if (IRQa)
{
if (IRQCount < 5750) // completely by guess
IRQCount += a;
else {
IRQa = 0;
X6502_IRQBegin(FCEU_IQEXT);
}
}
}
static void StateRestore(int version) {
@ -62,6 +91,7 @@ static void StateRestore(int version) {
void UNLSMB2J_Init(CartInfo *info) {
info->Power = UNLSMB2JPower;
MapIRQHook = UNLSMB2JIRQHook;
GameStateRestore = StateRestore;
AddExState(&StateRegs, ~0, 0, 0);
}

View File

@ -72,6 +72,7 @@ static void M112Power(void) {
SetWriteHandler(0x4020, 0x5FFF, M112Write);
SetReadHandler(0x6000, 0x7FFF, CartBR);
SetWriteHandler(0x6000, 0x7FFF, CartBW);
FCEU_CheatAddRAM(8, 0x6000, WRAM);
}
static void StateRestore(int version) {

View File

@ -17,43 +17,45 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* 7-in-1 Darkwing Duck, Snake, MagicBlock (PCB marked as "12 in 1")
* 7-in-1 Darkwing Duck, Snake, MagicBlock (PCB marked as "12 in 1")
* 12-in-1 1991 New Star Co. Ltd.
*
*/
#include "mapinc.h"
static uint8 reg[4];
static uint8 prgchr[2], ctrl;
static SFORMAT StateRegs[] =
{
{ reg, 4, "REGS" },
{ prgchr, 2, "REGS" },
{ &ctrl, 1, "CTRL" },
{ 0 }
};
static void Sync(void) {
uint8 bank = (reg[3] & 3) << 3;
setchr4(0x0000, (reg[1] >> 3) | (bank << 2));
setchr4(0x1000, (reg[2] >> 3) | (bank << 2));
if (reg[3] & 8) {
setprg32(0x8000, ((reg[2] & 7) >> 1) | bank);
uint8 bank = (ctrl & 3) << 3;
setchr4(0x0000, (prgchr[0] >> 3) | (bank << 2));
setchr4(0x1000, (prgchr[1] >> 3) | (bank << 2));
if (ctrl & 8) {
setprg16(0x8000, bank | (prgchr[0] & 6) | 0); // actually, both 0 and 1 registers used, but they will switch each PA12 transition
setprg16(0xc000, bank | (prgchr[0] & 6) | 1); // if bits are different for both registers, so they must be programmed strongly the same!
} else {
setprg16(0x8000, (reg[1] & 7) | bank);
setprg16(0xc000, 7 | bank);
setprg16(0x8000, bank | (prgchr[0] & 7));
setprg16(0xc000, bank | 7 );
}
setmirror(((reg[3] & 4) >> 2) ^ 1);
setmirror(((ctrl & 4) >> 2) ^ 1);
}
static DECLFW(BMC12IN1Write) {
switch (A) {
case 0xafff: reg[0] = V; break;
case 0xbfff: reg[1] = V; break;
case 0xdfff: reg[2] = V; break;
case 0xefff: reg[3] = V; break;
switch (A & 0xE000) {
case 0xA000: prgchr[0] = V; Sync(); break;
case 0xC000: prgchr[1] = V; Sync(); break;
case 0xE000: ctrl = V & 0x0F; Sync(); break;
}
Sync();
}
static void BMC12IN1Power(void) {
reg[0] = reg[1] = reg[2] = reg[3] = 0;
prgchr[0] = prgchr[1] = ctrl = 0;
Sync();
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x8000, 0xFFFF, BMC12IN1Write);
@ -68,3 +70,4 @@ void BMC12IN1_Init(CartInfo *info) {
GameStateRestore = StateRestore;
AddExState(&StateRegs, ~0, 0, 0);
}

View File

@ -76,6 +76,7 @@ static void M15Power(void) {
SetWriteHandler(0x6000, 0x7FFF, CartBW);
SetWriteHandler(0x8000, 0xFFFF, M15Write);
SetReadHandler(0x8000, 0xFFFF, CartBR);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
Sync();
}

View File

@ -86,6 +86,7 @@ static void M156Power(void) {
SetReadHandler(0x6000, 0xFFFF, CartBR);
SetWriteHandler(0x6000, 0x7FFF, CartBW);
SetWriteHandler(0xC000, 0xCFFF, M156Write);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
}
static void M156Close(void) {

View File

@ -102,6 +102,7 @@ static void Power(void) {
SetWriteHandler(0x5000, 0x5FFF, Write);
SetReadHandler(0x6000, 0xFFFF, CartBR);
SetWriteHandler(0x6000, 0x7FFF, CartBW);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
WSync();
}
@ -155,6 +156,7 @@ static void Power2(void) {
SetWriteHandler(0x5000, 0x5FFF, Write2);
SetReadHandler(0x6000, 0xFFFF, CartBR);
SetWriteHandler(0x6000, 0x7FFF, CartBW);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
WSync();
}
@ -206,6 +208,7 @@ static void Power3(void) {
SetWriteHandler(0x5000, 0x5FFF, Write3);
SetReadHandler(0x6000, 0xFFFF, CartBR);
SetWriteHandler(0x6000, 0x7FFF, CartBW);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
WSync();
}

View File

@ -47,7 +47,8 @@ static void Sync(void)
}
static DECLFW(M176Write_5001)
{
{
printf("%04X = $%02X\n",A,V);
if(sbw)
{
prg[0] = V*4;
@ -59,13 +60,15 @@ static DECLFW(M176Write_5001)
}
static DECLFW(M176Write_5010)
{
{
printf("%04X = $%02X\n",A,V);
if(V == 0x24) sbw = 1;
Sync();
}
static DECLFW(M176Write_5011)
{
{
printf("%04X = $%02X\n",A,V);
V >>= 1;
if(sbw)
{
@ -78,7 +81,8 @@ static DECLFW(M176Write_5011)
}
static DECLFW(M176Write_5FF1)
{
{
printf("%04X = $%02X\n",A,V);
V >>= 1;
prg[0] = V*4;
prg[1] = V*4+1;
@ -88,7 +92,8 @@ static DECLFW(M176Write_5FF1)
}
static DECLFW(M176Write_5FF2)
{
{
printf("%04X = $%02X\n",A,V);
chr = V;
Sync();
}
@ -106,15 +111,16 @@ static DECLFW(M176Write_WriteSRAM)
static void M176Power(void)
{
SetReadHandler(0x6000,0x7fff,CartBR);
SetWriteHandler(0x6000,0x7fff,M176Write_WriteSRAM);
SetReadHandler(0x8000,0xFFFF,CartBR);
SetReadHandler(0x6000,0x7fff,CartBR);
SetWriteHandler(0x6000,0x7fff,M176Write_WriteSRAM);
SetReadHandler(0x8000,0xFFFF,CartBR);
SetWriteHandler(0xA001,0xA001,M176Write_A001);
SetWriteHandler(0x5001,0x5001,M176Write_5001);
SetWriteHandler(0x5010,0x5010,M176Write_5010);
SetWriteHandler(0x5011,0x5011,M176Write_5011);
SetWriteHandler(0x5ff1,0x5ff1,M176Write_5FF1);
SetWriteHandler(0x5ff2,0x5ff2,M176Write_5FF2);
SetWriteHandler(0x5ff1,0x5ff1,M176Write_5FF1);
SetWriteHandler(0x5ff2,0x5ff2,M176Write_5FF2);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
we_sram = 0;
sbw = 0;

View File

@ -50,6 +50,7 @@ static void M177Power(void) {
SetWriteHandler(0x6000, 0x7fff, CartBW);
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x8000, 0xFFFF, M177Write);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
}
static void M177Close(void) {

View File

@ -1,7 +1,7 @@
/* FCE Ultra - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 2007 CaH4e3
* Copyright (C) 2013 CaH4e3
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -16,49 +16,134 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* DSOUNDV1/FL-TR8MA boards (32K WRAM, 8/16M), 178 mapper boards (8K WRAM, 4/8M)
* Various Education Cartridges
*
*/
#include "mapinc.h"
static uint8 reg[4];
static uint8 *WRAM = NULL;
static uint32 WRAMSIZE;
// SND Registers
static uint8 pcm_enable = 0;
static int16 pcm_latch = 0x3F6, pcm_clock = 0x3F6;
static writefunc pcmwrite;
static SFORMAT StateRegs[] =
{
{ reg, 4, "REGS" },
{ 0 }
};
static void Sync(void) {
uint8 bank = (reg[2] & 3) << 3;
setmirror((reg[0] & 1) ^ 1);
setprg8r(0x10, 0x6000, 0);
setchr8(0);
if (reg[0] & 2) {
setprg16(0x8000, (reg[1] & 7) | bank);
setprg16(0xC000, ((~0) & 7) | bank);
} else {
setprg16(0x8000, (reg[1] & 6) | bank);
setprg16(0xC000, (reg[1] & 6) | bank | 1);
static int16 step_size[49] = {
16, 17, 19, 21, 23, 25, 28, 31, 34, 37,
41, 45, 50, 55, 60, 66, 73, 80, 88, 97,
107, 118, 130, 143, 157, 173, 190, 209, 230, 253,
279, 307, 337, 371, 408, 449, 494, 544, 598, 658,
724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552
}; //49 items
static int32 step_adj[16] = { -1, -1, -1, -1, 2, 5, 7, 9, -1, -1, -1, -1, 2, 5, 7, 9 };
//decode stuff
static int32 jedi_table[16 * 49];
static int32 acc = 0; //ADPCM accumulator, initial condition must be 0
static int32 decstep = 0; //ADPCM decoding step, initial condition must be 0
static void jedi_table_init() {
int step, nib;
for (step = 0; step < 49; step++) {
for (nib = 0; nib < 16; nib++) {
int value = (2 * (nib & 0x07) + 1) * step_size[step] / 8;
jedi_table[step * 16 + nib] = ((nib & 0x08) != 0) ? -value : value;
}
}
}
static uint8 decode(uint8 code) {
acc += jedi_table[decstep + code];
if ((acc & ~0x7ff) != 0) // acc is > 2047
acc |= ~0xfff;
else acc &= 0xfff;
decstep += step_adj[code & 7] * 16;
if (decstep < 0) decstep = 0;
if (decstep > 48 * 16) decstep = 48 * 16;
return (acc >> 8) & 0xff;
}
static void Sync(void) {
uint32 sbank = reg[1] & 0x7;
uint32 bbank = reg[2];
setchr8(0);
setprg8r(0x10, 0x6000, reg[3] & 3);
if (reg[0] & 2) { // UNROM mode
setprg16(0x8000, (bbank << 3) | sbank);
if (reg[0] & 4)
setprg16(0xC000, (bbank << 3) | 6 | (reg[1] & 1));
else
setprg16(0xC000, (bbank << 3) | 7);
} else { // NROM mode
uint32 bank = (bbank << 3) | sbank;
if (reg[0] & 4) {
setprg16(0x8000, bank);
setprg16(0xC000, bank);
} else
setprg32(0x8000, bank >> 1);
}
setmirror((reg[0] & 1) ^ 1);
}
static DECLFW(M178Write) {
reg[A & 3] = V;
// FCEU_printf("cmd %04x:%02x\n", A, V);
Sync();
}
static DECLFW(M178WriteSnd) {
if (A == 0x5800) {
if (V & 0xF0) {
pcm_enable = 1;
// pcmwrite(0x4011, (V & 0xF) << 3);
pcmwrite(0x4011, decode(V & 0xf));
} else
pcm_enable = 0;
} else
FCEU_printf("misc %04x:%02x\n", A, V);
}
static DECLFR(M178ReadSnd) {
if (A == 0x5800)
return (X.DB & 0xBF) | ((pcm_enable ^ 1) << 6);
else
return X.DB;
}
static void M178Power(void) {
reg[0] = 1;
reg[1] = 0;
reg[2] = 0;
reg[3] = 0;
reg[0] = reg[1] = reg[2] = reg[3] = 0;
Sync();
SetReadHandler(0x6000, 0x7FFF, CartBR);
SetWriteHandler(0x6000, 0x7FFF, CartBW);
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x4800, 0x4803, M178Write);
pcmwrite = GetWriteHandler(0x4011);
SetWriteHandler(0x4800, 0x4fff, M178Write);
SetWriteHandler(0x5800, 0x5fff, M178WriteSnd);
SetReadHandler(0x5800, 0x5fff, M178ReadSnd);
SetReadHandler(0x6000, 0x7fff, CartBR);
SetWriteHandler(0x6000, 0x7fff, CartBW);
SetReadHandler(0x8000, 0xffff, CartBR);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
}
static void M178SndClk(int a) {
if (pcm_enable) {
pcm_latch -= a;
if (pcm_latch <= 0) {
pcm_latch += pcm_clock;
pcm_enable = 0;
}
}
}
static void M178Close(void) {
@ -67,7 +152,6 @@ static void M178Close(void) {
WRAM = NULL;
}
static void StateRestore(int version) {
Sync();
}
@ -76,8 +160,11 @@ void Mapper178_Init(CartInfo *info) {
info->Power = M178Power;
info->Close = M178Close;
GameStateRestore = StateRestore;
MapIRQHook = M178SndClk;
WRAMSIZE = 8192;
jedi_table_init();
WRAMSIZE = 32768;
WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE);
SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1);
if (info->battery) {

View File

@ -89,6 +89,7 @@ static void M18Power(void) {
SetWriteHandler(0x8000, 0x9FFF, M18WritePrg);
SetWriteHandler(0xA000, 0xDFFF, M18WriteChr);
SetWriteHandler(0xE000, 0xFFFF, M18WriteIRQ);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
}
static void M18IRQHook(int a) {

View File

@ -22,8 +22,7 @@
#include "mapinc.h"
static uint8 prg[4];
static uint8 chr[8];
static uint8 prg[4], chr[8], mirr;
static uint8 IRQCount;
static uint8 IRQPre;
static uint8 IRQa;
@ -32,6 +31,7 @@ static SFORMAT StateRegs[] =
{
{ prg, 4, "PRG" },
{ chr, 8, "CHR" },
{ &mirr, 1, "MIRR" },
{ &IRQCount, 1, "IRQC" },
{ &IRQPre, 1, "IRQP" },
{ &IRQa, 1, "IRQA" },
@ -39,13 +39,22 @@ static SFORMAT StateRegs[] =
};
static void SyncPrg(void) {
setprg8(0x6000, 0);
setprg8(0x6000, prg[3]);
setprg8(0x8000, prg[0]);
setprg8(0xA000, prg[1]);
setprg8(0xC000, prg[2]);
setprg8(0xE000, ~0);
}
static void SyncMirr(void) {
switch (mirr) {
case 0: setmirror(MI_V); break;
case 1: setmirror(MI_H); break;
case 2: setmirror(MI_0); break;
case 3: setmirror(MI_1); break;
}
}
static void SyncChr(void) {
int i;
for (i = 0; i < 8; i++)
@ -55,10 +64,14 @@ static void SyncChr(void) {
static void StateRestore(int version) {
SyncPrg();
SyncChr();
SyncMirr();
}
static DECLFW(M183Write) {
if (((A & 0xF80C) >= 0xB000) && ((A & 0xF80C) <= 0xE00C)) {
if ((A & 0xF800) == 0x6800) {
prg[3] = A & 0x3F;
SyncPrg();
} else if (((A & 0xF80C) >= 0xB000) && ((A & 0xF80C) <= 0xE00C)) {
int index = (((A >> 11) - 6) | (A >> 3)) & 7;
chr[index] = (chr[index] & (0xF0 >> (A & 4))) | ((V & 0x0F) << (A & 4));
SyncChr();
@ -66,14 +79,7 @@ static DECLFW(M183Write) {
case 0x8800: prg[0] = V; SyncPrg(); break;
case 0xA800: prg[1] = V; SyncPrg(); break;
case 0xA000: prg[2] = V; SyncPrg(); break;
case 0x9800:
switch (V & 3) {
case 0: setmirror(MI_V); break;
case 1: setmirror(MI_H); break;
case 2: setmirror(MI_0); break;
case 3: setmirror(MI_1); break;
}
break;
case 0x9800: mirr = V & 3; SyncMirr(); break;
case 0xF000: IRQCount = ((IRQCount & 0xF0) | (V & 0xF)); break;
case 0xF004: IRQCount = ((IRQCount & 0x0F) | ((V & 0xF) << 4)); break;
case 0xF008: IRQa = V; if (!V) IRQPre = 0; X6502_IRQEnd(FCEU_IQEXT); break;
@ -91,9 +97,8 @@ static void M183IRQCounter(void) {
static void M183Power(void) {
IRQPre = IRQCount = IRQa = 0;
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x8000, 0xFFFF, M183Write);
SetReadHandler(0x6000, 0x7FFF, CartBR);
SetReadHandler(0x6000, 0xFFFF, CartBR);
SetWriteHandler(0x6000, 0xFFFF, M183Write);
SyncPrg();
SyncChr();
}

View File

@ -22,14 +22,14 @@
#include "mapinc.h"
static uint8 SWRAM[2816];
static uint8 SWRAM[3072];
static uint8 *WRAM = NULL;
static uint8 regs[4];
static SFORMAT StateRegs[] =
{
{ regs, 4, "DREG" },
{ SWRAM, 2816, "SWRM" },
{ SWRAM, 3072, "SWRM" },
{ 0 }
};
@ -67,8 +67,9 @@ static void M186Power(void) {
SetWriteHandler(0x6000, 0xFFFF, CartBW);
SetReadHandler(0x4200, 0x43FF, M186Read);
SetWriteHandler(0x4200, 0x43FF, M186Write);
SetReadHandler(0x4400, 0x4EFF, ASWRAM);
SetWriteHandler(0x4400, 0x4EFF, BSWRAM);
SetReadHandler(0x4400, 0x4FFF, ASWRAM);
SetWriteHandler(0x4400, 0x4FFF, BSWRAM);
FCEU_CheatAddRAM(32, 0x6000, WRAM);
regs[0] = regs[1] = regs[2] = regs[3];
Sync();
}

View File

@ -38,6 +38,8 @@ static void Sync(void) {
setchr1(0x1000 + (x << 10), DRegs[2 + x]);
setprg8(0x8000, DRegs[6]);
setprg8(0xa000, DRegs[7]);
setprg8(0xc000, ~1);
setprg8(0xe000, ~0);
}
static void StateRestore(int version) {
@ -60,10 +62,9 @@ static DECLFW(M206Write) {
}
static void M206Power(void) {
setprg8(0xc000, 0xE);
setprg8(0xe000, 0xF);
cmd = 0;
memset(DRegs, 0, 8);
DRegs[6] = 0;
DRegs[7] = 1;
Sync();
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x8000, 0xFFFF, M206Write);

View File

@ -63,9 +63,10 @@ static DECLFR(M208ProtRead) {
static void M208Power(void) {
EXPREGS[5] = 3;
GenMMC3Power();
SetWriteHandler(0x4800, 0x4FFF, M208Write);
SetWriteHandler(0x4800, 0x4fff, M208Write);
SetWriteHandler(0x6800, 0x6fff, M208Write);
SetWriteHandler(0x5000, 0x5fff, M208ProtWrite);
SetReadHandler(0x5800, 0x5FFF, M208ProtRead);
SetReadHandler(0x5800, 0x5fff, M208ProtRead);
SetReadHandler(0x8000, 0xffff, CartBR);
}

View File

@ -39,7 +39,7 @@ static void Sync(void) {
} else
setprg32(0x8000, prg >> 1);
setchr8(chr);
setmirror(mirr);
setmirror(mirr ^ 1);
}
static DECLFW(M225Write) {

View File

@ -30,7 +30,7 @@ static SFORMAT StateRegs[] =
static void Sync(void) {
// uint32 bbank = (bank & 0x18) >> 1;
uint32 bbank = ((bank & 0x10) >> 2) | (bank & 8); // some dumps have bbanks swapped, if swap commands,
uint32 bbank = ((bank & 0x10) >> 2) | (bank & 8); // some dumps have bbanks swapped, if swap commands,
// then all roms can be played, but with some swapped
// games in menu. if not, some dumps are unplayable
// make hard dump for both cart types to check

View File

@ -54,6 +54,7 @@ static void M246Power(void) {
SetReadHandler(0x6800, 0x6FFF, CartBR);
SetWriteHandler(0x6800, 0x6FFF, CartBW);
SetReadHandler(0x8000, 0xFFFF, CartBR);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
}
static void M246Close(void)

View File

@ -80,6 +80,7 @@ static void M252Power(void) {
SetWriteHandler(0x6000, 0x7FFF, CartBW);
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x8000, 0xFFFF, M252Write);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
}
static void M252IRQ(int a) {

View File

@ -50,13 +50,6 @@ static void Sync(void) {
setprg8(0xe000, ~0);
for (i = 0; i < 8; i++) {
uint32 chr = chrlo[i] | (chrhi[i] << 8);
if (chrlo[i] == 0xc8) {
vlock = 0;
continue;
} else if (chrlo[i] == 0x88) {
vlock = 1;
continue;
}
if (((chrlo[i] == 4) || (chrlo[i] == 5)) && !vlock)
setchr1r(0x10, i << 10, chr & 1);
else
@ -74,8 +67,15 @@ static DECLFW(M253Write) {
if ((A >= 0xB000) && (A <= 0xE00C)) {
uint8 ind = ((((A & 8) | (A >> 8)) >> 3) + 2) & 7;
uint8 sar = A & 4;
chrlo[ind] = (chrlo[ind] & (0xF0 >> sar)) | ((V & 0x0F) << sar);
if (A & 4)
uint8 clo = (chrlo[ind] & (0xF0 >> sar)) | ((V & 0x0F) << sar);
chrlo[ind] = clo;
if (ind == 0) {
if (clo == 0xc8)
vlock = 0;
else if (clo == 0x88)
vlock = 1;
}
if (sar)
chrhi[ind] = V >> 4;
Sync();
} else
@ -85,16 +85,18 @@ static DECLFW(M253Write) {
case 0x9400: mirr = V & 3; Sync(); break;
case 0xF000: X6502_IRQEnd(FCEU_IQEXT); IRQLatch &= 0xF0; IRQLatch |= V & 0xF; break;
case 0xF004: X6502_IRQEnd(FCEU_IQEXT); IRQLatch &= 0x0F; IRQLatch |= V << 4; break;
case 0xF008: X6502_IRQEnd(FCEU_IQEXT); IRQClock = 0; IRQCount = IRQLatch; IRQa = V & 2;break;
case 0xF008: X6502_IRQEnd(FCEU_IQEXT); IRQClock = 0; IRQCount = IRQLatch; IRQa = V & 2; break;
}
}
static void M253Power(void) {
vlock = 0;
Sync();
SetReadHandler(0x6000, 0x7FFF, CartBR);
SetWriteHandler(0x6000, 0x7FFF, CartBW);
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x8000, 0xFFFF, M253Write);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
}
static void M253Close(void) {

View File

@ -129,8 +129,7 @@ static DECLFW(WriteEXP)
{
uint32 addr = A;
uint8 value = V;
if (addr >= 05000)
reg = value & 0x81;
reg = value & 0x81;
}
static DECLFW(WritePRG)
@ -175,7 +174,7 @@ static void M28Power(void)
prg_mask_16k = PRGsize[0] - 1;
//EXP
SetWriteHandler(0x4020,0x5FFF,WriteEXP);
SetWriteHandler(0x5000,0x5FFF,WriteEXP);
//PRG
SetWriteHandler(0x8000,0xFFFF,WritePRG);

View File

@ -75,6 +75,7 @@ static void M32Power(void) {
SetWriteHandler(0x9000, 0x9FFF, M32Write1);
SetWriteHandler(0xA000, 0xAFFF, M32Write2);
SetWriteHandler(0xB000, 0xBFFF, M32Write3);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
}
static void M32Close(void)

View File

@ -66,6 +66,7 @@ static void M34Power(void) {
SetWriteHandler(0x6000, 0x7ffc, CartBW);
SetReadHandler(0x8000, 0xffff, CartBR);
SetWriteHandler(0x7ffd, 0xffff, M34Write);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
}
static void M34Close(void) {

View File

@ -2,6 +2,7 @@
*
* Copyright notice for this file:
* Copyright (C) 2012 CaH4e3
* Copyright (C) 2002 Xodnizel
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -2,6 +2,7 @@
*
* Copyright notice for this file:
* Copyright (C) 2012 CaH4e3
* Copyright (C) 2002 Xodnizel
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -16,13 +16,14 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* FDS Conversion
*
*/
//ccording to nestopia, BTL_SMB2_C, otherwise known as UNL-SMB2J
#include "mapinc.h"
static uint8 reg;
static uint8 reg, swap;
static uint32 IRQCount, IRQa;
static SFORMAT StateRegs[] =
@ -30,31 +31,36 @@ static SFORMAT StateRegs[] =
{ &IRQCount, 4, "IRQC" },
{ &IRQa, 4, "IRQA" },
{ &reg, 1, "REG" },
{ &swap, 1, "SWAP" },
{ 0 }
};
static void Sync(void) {
setprg4(0x5000, 16); // Only YS-612 advdnced version
setprg8(0x6000, 2);
setprg4(0x5000, 8 << 1); // Only YS-612 advanced version
setprg8(0x6000, swap?0:2);
setprg8(0x8000, 1);
setprg8(0xa000, 0);
setprg8(0xc000, reg);
setprg8(0xe000, 9);
setprg8(0xe000, swap?8:9); // hard dump for mr.Mary is 128K,
// bank 9 is the last 2K ok bank 8 repeated 4 times, then till the end of 128K
// instead used bank A, containing some CHR data, ines rom have unused banks removed,
// and bank A moved to the bank 9 place for compatibility with other crappy dumps
setchr8(0);
}
static DECLFW(M43Write) {
// int transo[8]={4,3,4,4,4,7,5,6};
int transo[8] = { 4, 3, 5, 3, 6, 3, 7, 3 }; // According to hardware tests
int transo[8] = { 4, 3, 5, 3, 6, 3, 7, 3 }; // According to hardware tests
switch (A & 0xf1ff) {
case 0x4022: reg = transo[V & 7]; Sync(); break;
case 0x8122: // hacked version
case 0x4122: IRQa = V & 1; X6502_IRQEnd(FCEU_IQEXT); IRQCount = 0; break; // original version
case 0x4120: swap = V & 1; Sync(); break;
case 0x8122: // hacked version
case 0x4122: IRQa = V & 1; X6502_IRQEnd(FCEU_IQEXT); IRQCount = 0; break; // original version
}
}
static void M43Power(void) {
reg = 0;
reg = swap = 0;
Sync();
SetReadHandler(0x5000, 0xffff, CartBR);
SetWriteHandler(0x4020, 0xffff, M43Write);

View File

@ -2,6 +2,7 @@
*
* Copyright notice for this file:
* Copyright (C) 2012 CaH4e3
* Copyright (C) 2002 Xodnizel
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -2,6 +2,7 @@
*
* Copyright notice for this file:
* Copyright (C) 2012 CaH4e3
* Copyright (C) 2002 Xodnizel
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -2,6 +2,7 @@
*
* Copyright notice for this file:
* Copyright (C) 2012 CaH4e3
* Copyright (C) 2002 Xodnizel
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -134,6 +134,7 @@ static void M68Power(void) {
SetWriteHandler(0xF000, 0xFFFF, M68WriteROM);
SetWriteHandler(0x6000, 0x6000, M68WriteLo);
SetWriteHandler(0x6001, 0x7FFF, CartBW);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
}
static void M68Close(void) {

View File

@ -2,6 +2,7 @@
*
* Copyright notice for this file:
* Copyright (C) 2012 CaH4e3
* Copyright (C) 2002 Xodnizel
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -74,7 +75,7 @@ static DECLFW(M69Write0) {
}
static DECLFW(M69Write1) {
switch(cmdreg) {
switch (cmdreg) {
case 0x0: creg[0] = V; Sync(); break;
case 0x1: creg[1] = V; Sync(); break;
case 0x2: creg[2] = V; Sync(); break;
@ -87,10 +88,10 @@ static DECLFW(M69Write1) {
case 0x9: preg[0] = V; Sync(); break;
case 0xA: preg[1] = V; Sync(); break;
case 0xB: preg[2] = V; Sync(); break;
case 0xC: mirr = V & 3; Sync(); break;
case 0xC: mirr = V & 3; Sync();break;
case 0xD: IRQa = V; X6502_IRQEnd(FCEU_IQEXT); break;
case 0xE: IRQCount &= 0xFF00; IRQCount |= V; X6502_IRQEnd(FCEU_IQEXT); break;
case 0xF: IRQCount &= 0x00FF; IRQCount |= V << 8; X6502_IRQEnd(FCEU_IQEXT); break;
case 0xE: IRQCount &= 0xFF00; IRQCount |= V; break;
case 0xF: IRQCount &= 0x00FF; IRQCount |= V << 8; break;
}
}
@ -153,7 +154,7 @@ static void DoAYSQ(int x) {
if (end <= start) return;
CAYBC[x] = end;
if (amp)
if (amp && !(sreg[0x7] & (1 << x)))
for (V = start; V < end; V++) {
if (dcount[x])
Wave[V >> 4] += amp;
@ -231,10 +232,10 @@ static void M69Power(void) {
SetWriteHandler(0xA000, 0xBFFF, M69Write1);
SetWriteHandler(0xC000, 0xDFFF, M69SWrite0);
SetWriteHandler(0xE000, 0xFFFF, M69SWrite1);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
}
static void M69Close(void)
{
static void M69Close(void) {
if (WRAM)
FCEU_gfree(WRAM);
WRAM = NULL;

View File

@ -2,6 +2,7 @@
*
* Copyright notice for this file:
* Copyright (C) 2012 CaH4e3
* Copyright (C) 2002 Xodnizel
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -2,6 +2,7 @@
*
* Copyright notice for this file:
* Copyright (C) 2012 CaH4e3
* Copyright (C) 2002 Xodnizel
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -16,30 +16,41 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* GG1 boards, similar to T-262, with no Data latch
*
*/
#include "mapinc.h"
static uint16 cmdreg;
static uint8 invalid_data;
static uint8 reset;
static SFORMAT StateRegs[] =
{
{ &invalid_data, 1, "INVD" },
{ &reset, 1, "REST" },
{ &cmdreg, 2, "CREG" },
{ 0 }
};
static void Sync(void) {
setprg16r((cmdreg & 0x060) >> 5, 0x8000, (cmdreg & 0x01C) >> 2);
setprg16r((cmdreg & 0x060) >> 5, 0xC000, (cmdreg & 0x200) ? (~0) : 0);
uint32 base = ((cmdreg & 0x060) | ((cmdreg & 0x100) >> 1)) >> 2;
uint32 bank = (cmdreg & 0x01C) >> 2;
uint32 lbank = (cmdreg & 0x200) ? 7 : ((cmdreg & 0x80) ? bank : 0);
if (PRGptr[1]) {
setprg16r(base >> 3, 0x8000, bank); // for versions with split ROMs
setprg16r(base >> 3, 0xC000, lbank);
} else {
setprg16(0x8000, base | bank);
setprg16(0xC000, base | lbank);
}
setmirror(((cmdreg & 2) >> 1) ^ 1);
}
static DECLFR(UNL8157Read) {
if (invalid_data && cmdreg & 0x100)
return 0xFF;
else
return CartBR(A);
if ((cmdreg & 0x100) && (PRGsize[0] < (1024 * 1024))) {
A = (A & 0xFFF0) + reset;
}
return CartBR(A);
}
static DECLFW(UNL8157Write) {
@ -51,14 +62,14 @@ static void UNL8157Power(void) {
setchr8(0);
SetWriteHandler(0x8000, 0xFFFF, UNL8157Write);
SetReadHandler(0x8000, 0xFFFF, UNL8157Read);
cmdreg = 0x200;
invalid_data = 1;
cmdreg = reset = 0;
Sync();
}
static void UNL8157Reset(void) {
cmdreg = 0;
invalid_data ^= 1;
cmdreg = reset = 0;
reset++;
reset &= 0x1F;
Sync();
}

View File

@ -68,6 +68,7 @@ static void M82Power(void) {
SetReadHandler(0x6000, 0xffff, CartBR);
SetWriteHandler(0x6000, 0x7fff, CartBW);
SetWriteHandler(0x7ef0, 0x7efc, M82Write); // external WRAM might end at $73FF
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
}
static void M82Close(void) {

View File

@ -56,6 +56,9 @@ static DECLFW(M88Write) {
}
static void M88Power(void) {
reg[0] = reg[1] = reg[2] = reg[3] = reg[4] = reg[5] = reg[6] = reg[7] = 0;
Sync();
MSync();
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x8000, 0xFFFF, M88Write);
}

View File

@ -51,6 +51,7 @@ static void M99Power(void) {
SetWriteHandler(0x4016, 0x4016, M99Write);
SetReadHandler(0x6000, 0xFFFF, CartBR);
SetWriteHandler(0x6000, 0x7FFF, CartBW);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
}
static void M99Close(void)

View File

@ -0,0 +1,6 @@
import glob
source_list = glob.glob('*.cpp')+glob.glob('*.c')
for x in range(len(source_list)):
source_list[x] = 'boards/' + source_list[x]
Return('source_list')

View File

@ -1,7 +1,7 @@
/* FCE Ultra - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 2012 CaH4e3
* Copyright (C) 2013 CaH4e3
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -44,6 +44,7 @@ static void LatchPower(void) {
if (WRAM) {
SetReadHandler(0x6000, 0xFFFF, CartBR);
SetWriteHandler(0x6000, 0x7FFF, CartBW);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
} else
SetReadHandler(0x6000, 0xFFFF, defread);
SetWriteHandler(addrreg0, addrreg1, LatchWrite);
@ -85,18 +86,6 @@ static void Latch_Init(CartInfo *info, void (*proc)(void), readfunc func, uint16
AddExState(&latche, 2, 0, "LATC");
}
//------------------ UNLCC21 ---------------------------
static void UNLCC21Sync(void) {
setprg32(0x8000, 0);
setchr8(latche & 1);
setmirror(MI_0 + ((latche & 2) >> 1));
}
void UNLCC21_Init(CartInfo *info) {
Latch_Init(info, UNLCC21Sync, NULL, 0x0000, 0x8000, 0xFFFF, 0);
}
//------------------ BMCD1038 ---------------------------
static void BMCD1038Sync(void) {
@ -248,7 +237,7 @@ void Mapper200_Init(CartInfo *info) {
//------------------ Map 201 ---------------------------
static void M201Sync(void) {
if(latche & 8) {
if (latche & 8) {
setprg32(0x8000, latche & 3);
setchr8(latche & 3);
} else {
@ -303,14 +292,14 @@ static DECLFR(M212Read) {
}
static void M212Sync(void) {
if(latche & 0x4000) {
if (latche & 0x4000) {
setprg32(0x8000, (latche >> 1) & 3);
} else {
setprg16(0x8000, latche & 7);
setprg16(0xC000, latche & 7);
}
setchr8(latche & 7);
setmirror(((latche >> 3) & 1)^1);
setmirror(((latche >> 3) & 1) ^ 1);
}
void Mapper212_Init(CartInfo *info) {
@ -385,7 +374,7 @@ static void M227Sync(void) {
}
}
setmirror(((latche >> 1) & 1)^1);
setmirror(((latche >> 1) & 1) ^ 1);
setchr8(0);
setprg8r(0x10, 0x6000, 0);
}
@ -398,13 +387,13 @@ void Mapper227_Init(CartInfo *info) {
static void M229Sync(void) {
setchr8(latche);
if(!(latche & 0x1e))
if (!(latche & 0x1e))
setprg32(0x8000, 0);
else {
setprg16(0x8000, latche & 0x1F);
setprg16(0xC000, latche & 0x1F);
}
setmirror(((latche >> 5) & 1)^1);
setmirror(((latche >> 5) & 1) ^ 1);
}
void Mapper229_Init(CartInfo *info) {
@ -415,13 +404,13 @@ void Mapper229_Init(CartInfo *info) {
static void M231Sync(void) {
setchr8(0);
if(latche & 0x20)
if (latche & 0x20)
setprg32(0x8000, (latche >> 1) & 0x0F);
else {
setprg16(0x8000, latche & 0x1E);
setprg16(0xC000, latche & 0x1E);
}
setmirror(((latche >> 7) & 1)^1);
setmirror(((latche >> 7) & 1) ^ 1);
}
void Mapper231_Init(CartInfo *info) {
@ -460,7 +449,7 @@ static void BMC810544CA1Sync(void) {
uint32 bank = latche >> 7;
if (latche & 0x40)
setprg32(0x8000, bank);
else{
else {
setprg16(0x8000, (bank << 1) | ((latche >> 5) & 1));
setprg16(0xC000, (bank << 1) | ((latche >> 5) & 1));
}
@ -498,11 +487,11 @@ void BMCNTD03_Init(CartInfo *info) {
static void BMCG146Sync(void) {
setchr8(0);
if (latche & 0x800) { // UNROM mode
if (latche & 0x800) { // UNROM mode
setprg16(0x8000, (latche & 0x1F) | (latche & ((latche & 0x40) >> 6)));
setprg16(0xC000, (latche & 0x18) | 7);
} else {
if (latche & 0x40) { // 16K mode
if (latche & 0x40) { // 16K mode
setprg16(0x8000, latche & 0x1F);
setprg16(0xC000, latche & 0x1F);
} else {

View File

@ -22,14 +22,9 @@
*
*/
//Famicom Jump 2 should get transformed to m153
//All other games are not supporting EEPROM saving right now.
//We may need to distinguish between 16 and 159 in order to know the EEPROM configuration.
//Until then, we just return 0x00 from the EEPROM read
#include "mapinc.h"
static uint8 reg[16], is153;
static uint8 reg[16], is153, x24c02;
static uint8 IRQa;
static int16 IRQCount, IRQLatch;
@ -41,22 +36,133 @@ static SFORMAT StateRegs[] =
{ reg, 16, "REGS" },
{ &IRQa, 1, "IRQA" },
{ &IRQCount, 2, "IRQC" },
{ &IRQLatch, 2, "IRQL" }, // need for Famicom Jump II - Saikyou no 7 Nin (J) [!]
{ &IRQLatch, 2, "IRQL" }, // need for Famicom Jump II - Saikyou no 7 Nin (J) [!]
{ 0 }
};
static void BandaiIRQHook(int a) {
if (IRQa) {
IRQCount -= a;
if (IRQCount < 0) {
X6502_IRQBegin(FCEU_IQEXT);
IRQa = 0;
IRQCount = -1;
}
}
// x24C0x interface
#define X24C0X_STANDBY 0
#define X24C0X_ADDRESS 1
#define X24C0X_WORD 2
#define X24C0X_READ 3
#define X24C0X_WRITE 4
static uint8 x24c0x_data[256], x24c0x_state;
static uint8 x24c0x_addr, x24c0x_word, x24c0x_latch, x24c0x_bitcount;
static uint8 x24c0x_sda, x24c0x_scl, x24c0x_out, x24c0x_oe;
static SFORMAT x24c0xStateRegs[] =
{
{ &x24c0x_addr, 1, "ADDR" },
{ &x24c0x_word, 1, "WORD" },
{ &x24c0x_latch, 1, "LATC" },
{ &x24c0x_bitcount, 1, "BITC" },
{ &x24c0x_sda, 1, "SDA" },
{ &x24c0x_scl, 1, "SCL" },
{ &x24c0x_out, 1, "OUT" },
{ &x24c0x_oe, 1, "OE" },
{ &x24c0x_state, 1, "STAT" },
{ 0 }
};
static void x24c0x_init() {
x24c0x_addr = x24c0x_word = x24c0x_latch = x24c0x_bitcount = x24c0x_sda = x24c0x_scl = x24c0x_oe = 0;
x24c0x_state = X24C0X_STANDBY;
}
static void BandaiSync(void) {
static void x24c0x_write(uint8 data) {
uint8 sda = (data >> 6) & 1;
uint8 scl = (data >> 5) & 1;
x24c0x_oe = (data >> 7);
if(x24c0x_scl && scl) {
if(x24c0x_sda && !sda) { // START
x24c0x_state = X24C0X_ADDRESS;
x24c0x_bitcount = 0;
x24c0x_addr = 0;
} else if(!x24c0x_sda && sda) { //STOP
x24c0x_state = X24C0X_STANDBY;
}
} else if(!x24c0x_scl && scl) { // RISING EDGE
switch(x24c0x_state) {
case X24C0X_ADDRESS:
if(x24c0x_bitcount < 7) {
x24c0x_addr <<= 1;
x24c0x_addr |= sda;
} else {
if(!x24c02) // X24C01 mode
x24c0x_word = x24c0x_addr;
if(sda) { // READ COMMAND
x24c0x_state = X24C0X_READ;
} else { // WRITE COMMAND
if(x24c02) // X24C02 mode
x24c0x_state = X24C0X_WORD;
else
x24c0x_state = X24C0X_WRITE;
}
}
x24c0x_bitcount++;
break;
case X24C0X_WORD:
if(x24c0x_bitcount == 8) { // ACK
x24c0x_word = 0;
x24c0x_out = 0;
} else { // WORD ADDRESS INPUT
x24c0x_word <<= 1;
x24c0x_word |= sda;
if(x24c0x_bitcount == 16) { // END OF ADDRESS INPUT
x24c0x_bitcount = 7;
x24c0x_state = X24C0X_WRITE;
}
}
x24c0x_bitcount++;
break;
case X24C0X_READ:
if (x24c0x_bitcount == 8) { // ACK
x24c0x_out = 0;
x24c0x_latch = x24c0x_data[x24c0x_word];
x24c0x_bitcount = 0;
} else { // REAL OUTPUT
x24c0x_out = x24c0x_latch >> 7;
x24c0x_latch <<= 1;
x24c0x_bitcount++;
if(x24c0x_bitcount == 8) {
x24c0x_word++;
x24c0x_word &= 0xff;
}
}
break;
case X24C0X_WRITE:
if (x24c0x_bitcount == 8) { // ACK
x24c0x_out = 0;
x24c0x_latch = 0;
x24c0x_bitcount = 0;
} else { // REAL INPUT
x24c0x_latch <<= 1;
x24c0x_latch |= sda;
x24c0x_bitcount++;
if(x24c0x_bitcount == 8) {
x24c0x_data[x24c0x_word] = x24c0x_latch;
x24c0x_word++;
x24c0x_word &= 0xff;
}
}
break;
}
}
x24c0x_sda = sda;
x24c0x_scl = scl;
}
static uint8 x24c0x_read() {
return x24c0x_out << 4;
}
//
static void Sync(void) {
if (is153) {
int base = (reg[0] & 1) << 4;
setchr8(0);
@ -80,41 +186,91 @@ static DECLFW(BandaiWrite) {
A &= 0x0F;
if (A < 0x0A) {
reg[A & 0x0F] = V;
BandaiSync();
Sync();
} else
switch (A) {
case 0x0A: X6502_IRQEnd(FCEU_IQEXT); IRQa = V & 1; IRQCount = IRQLatch; break;
case 0x0B: IRQLatch &= 0xFF00; IRQLatch |= V; break;
case 0x0C: IRQLatch &= 0xFF; IRQLatch |= V << 8; break;
case 0x0D: break; // Serial EEPROM control port
case 0x0D: x24c0x_write(V); break;
}
}
static DECLFR(BandaiRead) {
return (X.DB & 0xEF) | x24c0x_read();
}
static void BandaiIRQHook(int a) {
if (IRQa) {
IRQCount -= a;
if (IRQCount < 0) {
X6502_IRQBegin(FCEU_IQEXT);
IRQa = 0;
IRQCount = -1;
}
}
}
static void BandaiPower(void) {
BandaiSync();
IRQa = 0;
x24c0x_init();
Sync();
SetReadHandler(0x6000, 0x7FFF, BandaiRead);
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x6000, 0xFFFF, BandaiWrite);
}
static void StateRestore(int version) {
BandaiSync();
Sync();
}
void Mapper16_Init(CartInfo *info) {
x24c02 = 1;
is153 = 0;
info->Power = BandaiPower;
MapIRQHook = BandaiIRQHook;
info->battery = 1;
info->SaveGame[0] = x24c0x_data;
info->SaveGameLen[0] = 256;
AddExState(x24c0x_data, 256, 0, "DATA");
GameStateRestore = StateRestore;
AddExState(&x24c0xStateRegs, ~0, 0, 0);
AddExState(&StateRegs, ~0, 0, 0);
}
void Mapper159_Init(CartInfo *info) {
x24c02 = 0;
is153 = 0;
info->Power = BandaiPower;
MapIRQHook = BandaiIRQHook;
info->battery = 1;
info->SaveGame[0] = x24c0x_data;
info->SaveGameLen[0] = 128;
AddExState(x24c0x_data, 128, 0, "DATA");
GameStateRestore = StateRestore;
AddExState(&x24c0xStateRegs, ~0, 0, 0);
AddExState(&StateRegs, ~0, 0, 0);
}
// Famicom jump 2:
// 0-7: Lower bit of data selects which 256KB PRG block is in use.
// This seems to be a hack on the developers' part, so I'll make emulation
// of it a hack(I think the current PRG block would depend on whatever the
// lowest bit of the CHR bank switching register that corresponds to the
// last CHR address read).
static void M153Power(void) {
BandaiSync();
Sync();
setprg8r(0x10, 0x6000, 0);
SetReadHandler(0x6000, 0x7FFF, CartBR);
SetWriteHandler(0x6000, 0x7FFF, CartBW);
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x8000, 0xFFFF, BandaiWrite);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
}
@ -284,12 +440,13 @@ static DECLFR(BarcodeRead) {
}
static void M157Power(void) {
IRQa = 0;
BarcodeData[0] = 0xFF;
BarcodeReadPos = 0;
BarcodeOut = 0;
BarcodeCycleCount = 0;
BandaiSync();
Sync();
SetWriteHandler(0x6000, 0xFFFF, BandaiWrite);
SetReadHandler(0x6000, 0x7FFF, BarcodeRead);
@ -297,7 +454,7 @@ static void M157Power(void) {
}
void Mapper157_Init(CartInfo *info) {
is153 = 0;
is153 = 1;
info->Power = M157Power;
MapIRQHook = BarcodeIRQHook;

View File

@ -0,0 +1,108 @@
/* FCE Ultra - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 2015 CaH4e3
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* CoolBoy 400-in-1 FK23C-mimic mapper 16Mb/32Mb PROM + 128K/256K CHR RAM, optional SRAM, optional NTRAM
* only MMC3 mode
*
* 6000 (õõ76x210) | 0õÑ0
* 6001 (õõõ354õõ)
* 6002 = 0
* 6003 = 0
*
*/
#include "mapinc.h"
#include "mmc3.h"
static void COOLBOYCW(uint32 A, uint8 V) {
if(EXPREGS[3] & 0x10)
setchr8(EXPREGS[2] & 0xF);
else {
uint32 mask = 0xFF;
switch(EXPREGS[0] & 0xC0) {
case 0xC0:
mask = 0x7F;
break;
}
setchr1(A, V & mask);
}
}
static void COOLBOYPW(uint32 A, uint8 V) {
uint32 mask, shift;
uint32 base = ((EXPREGS[0] & 0x07) >> 0) | ((EXPREGS[1] & 0x10) >> 1) | ((EXPREGS[1] & 0x0C) << 2) | ((EXPREGS[0] & 0x30) << 2);
switch(EXPREGS[0] & 0xC0) {
case 0x00:
mask = 0x3F;
break;
case 0x80:
mask = 0x1F;
break;
case 0xC0:
if(EXPREGS[3] & 0x10) {
mask = 0x01 | (EXPREGS[1] & 2);
} else {
mask = 0x0F;
}
break;
}
if(EXPREGS[3] & 0x10)
setprg8(A, (base << 4) | (V & mask) | ((EXPREGS[3] & (0x0E ^ (EXPREGS[1] & 2))) ));
else
setprg8(A, (base << 4) | (V & mask));
}
static DECLFW(COOLBOYWrite) {
if(A001B & 0x80)
CartBW(A,V);
else
if((EXPREGS[3] & 0x80) == 0) {
EXPREGS[A & 3] = V;
FixMMC3PRG(MMC3_cmd);
FixMMC3CHR(MMC3_cmd);
uint32 base = ((EXPREGS[0] & 0x07) >> 0) | ((EXPREGS[1] & 0x10) >> 1) | ((EXPREGS[1] & 0x0C) << 2) | ((EXPREGS[0] & 0x30) << 2);
FCEU_printf("exp %02x %02x (base %03d)\n",A,V,base);
}
}
static void COOLBOYReset(void) {
MMC3RegReset();
EXPREGS[0] = EXPREGS[1] = EXPREGS[2] = EXPREGS[3] = 0;
FixMMC3PRG(MMC3_cmd);
FixMMC3CHR(MMC3_cmd);
}
static void COOLBOYPower(void) {
GenMMC3Power();
EXPREGS[0] = EXPREGS[1] = EXPREGS[2] = EXPREGS[3] = 0;
FixMMC3PRG(MMC3_cmd);
FixMMC3CHR(MMC3_cmd);
SetWriteHandler(0x5000, 0x5fff, CartBW); // some games access random unmapped areas and crashes because of KT-008 PCB hack in MMC3 source lol
SetWriteHandler(0x6000, 0x6fff, COOLBOYWrite);
}
void COOLBOY_Init(CartInfo *info) {
GenMMC3_Init(info, 512, 128, 8, 0);
pwrap = COOLBOYPW;
cwrap = COOLBOYCW;
info->Power = COOLBOYPower;
info->Reset = COOLBOYReset;
AddExState(EXPREGS, 4, 0, "EXPR");
}

View File

@ -16,30 +16,29 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Dance 2000 12-in-1
*
*/
#include "mapinc.h"
static uint8 prg, mirr, prgmode;
static uint8 prg, mode;
static uint8 *WRAM = NULL;
static uint32 WRAMSIZE;
static uint32 lastnt = 0;
static SFORMAT StateRegs[] =
{
{ &prg, 1, "REGS" },
{ &mirr, 1, "MIRR" },
{ &prgmode, 1, "MIRR" },
{ &mode, 1, "MODE" },
{ &lastnt, 4, "LSNT" },
{ 0 }
};
static void Sync(void) {
setmirror(mirr);
setmirror((mode ^ 1) & 1);
setprg8r(0x10, 0x6000, 0);
setchr8(0);
if (prgmode)
setchr4(0x0000, lastnt);
setchr4(0x1000, 1);
if (mode & 4)
setprg32(0x8000, prg & 7);
else {
setprg16(0x8000, prg & 0x0f);
@ -48,11 +47,9 @@ static void Sync(void) {
}
static DECLFW(UNLD2000Write) {
// FCEU_printf("write %04x:%04x\n",A,V);
switch (A) {
case 0x5000: prg = V; Sync(); break;
case 0x5200: mirr = (V & 1) ^ 1; prgmode = V & 4; Sync(); break;
// default: FCEU_printf("write %04x:%04x\n",A,V);
case 0x5200: mode = V; if (mode & 4) Sync(); break;
}
}
@ -64,17 +61,28 @@ static DECLFR(UNLD2000Read) {
}
static void UNLD2000Power(void) {
prg = prgmode = 0;
prg = mode = 0;
Sync();
SetReadHandler(0x6000, 0x7FFF, CartBR);
SetWriteHandler(0x6000, 0x7FFF, CartBW);
SetReadHandler(0x8000, 0xFFFF, UNLD2000Read);
SetWriteHandler(0x4020, 0x5FFF, UNLD2000Write);
SetWriteHandler(0x5000, 0x5FFF, UNLD2000Write);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
}
static void UNLAX5705IRQ(void) {
if (scanline > 174) setchr4(0x0000, 1);
else setchr4(0x0000, 0);
static void UNL2000Hook(uint32 A) {
if (mode & 2) {
if ((A & 0x3000) == 0x2000) {
uint32 curnt = A & 0x800;
if (curnt != lastnt) {
setchr4(0x0000, curnt >> 11);
lastnt = curnt;
}
}
} else {
lastnt = 0;
setchr4(0x0000, 0);
}
}
static void UNLD2000Close(void) {
@ -83,7 +91,6 @@ static void UNLD2000Close(void) {
WRAM = NULL;
}
static void StateRestore(int version) {
Sync();
}
@ -91,7 +98,7 @@ static void StateRestore(int version) {
void UNLD2000_Init(CartInfo *info) {
info->Power = UNLD2000Power;
info->Close = UNLD2000Close;
GameHBIRQHook = UNLAX5705IRQ;
PPU_hook = UNL2000Hook;
GameStateRestore = StateRestore;
WRAMSIZE = 8192;

View File

@ -30,7 +30,7 @@ static void (*WSync)(void);
static DECLFW(LatchWrite) {
// FCEU_printf("bs %04x %02x\n",A,V);
if (bus_conflict)
latche = V & CartBR(A);
latche = (V == CartBR(A)) ? V : 0;
else
latche = V;
WSync();
@ -42,6 +42,7 @@ static void LatchPower(void) {
if (WRAM) {
SetReadHandler(0x6000, 0xFFFF, CartBR);
SetWriteHandler(0x6000, 0x7FFF, CartBW);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
} else {
SetReadHandler(0x8000, 0xFFFF, CartBR);
}
@ -91,7 +92,7 @@ static DECLFW(NROMWrite) {
#endif
static void NROMPower(void) {
setprg8r(0x10, 0x6000, 0); // Famili BASIC (v3.0) need it (uses only 4KB), FP-BASIC uses 8KB
setprg8r(0x10, 0x6000, 0); // Famili BASIC (v3.0) need it (uses only 4KB), FP-BASIC uses 8KB
setprg16(0x8000, 0);
setprg16(0xC000, ~0);
setchr8(0);
@ -100,7 +101,9 @@ static void NROMPower(void) {
SetWriteHandler(0x6000, 0x7FFF, CartBW);
SetReadHandler(0x8000, 0xFFFF, CartBR);
#ifdef DEBUG_MAPPER
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
#ifdef DEBUG_MAPPER
SetWriteHandler(0x4020, 0xFFFF, NROMWrite);
#endif
}
@ -122,14 +125,14 @@ void NROM_Init(CartInfo *info) {
//------------------ Map 2 ---------------------------
static void UNROMSync(void) {
static uint32 mirror_in_use = 0;
if (PRGsize[0] <= 128 * 1024) {
setprg16(0x8000, latche & 0x7);
if (latche & 8) mirror_in_use = 1;
if (mirror_in_use)
setmirror(((latche >> 3) & 1) ^ 1); // Higway Star Hacked mapper
} else
setprg16(0x8000, latche & 0xf);
// static uint32 mirror_in_use = 0;
// if (PRGsize[0] <= 128 * 1024) {
// setprg16(0x8000, latche & 0x7);
// if (latche & 8) mirror_in_use = 1;
// if (mirror_in_use)
// setmirror(((latche >> 3) & 1) ^ 1); // Higway Star Hacked mapper, disabled till new mapper defined
// } else
setprg16(0x8000, latche);
setprg16(0xc000, ~0);
setchr8(0);
}
@ -143,7 +146,7 @@ void UNROM_Init(CartInfo *info) {
static void CNROMSync(void) {
setchr8(latche);
setprg32(0x8000, 0);
setprg8r(0x10, 0x6000, 0); // Hayauchy IGO uses 2Kb or RAM
setprg8r(0x10, 0x6000, 0); // Hayauchy IGO uses 2Kb or RAM
}
void CNROM_Init(CartInfo *info) {
@ -159,7 +162,7 @@ static void ANROMSync() {
}
void ANROM_Init(CartInfo *info) {
Latch_Init(info, ANROMSync, 0, 0x8000, 0xFFFF, 0, 0);
Latch_Init(info, ANROMSync, 0, 0x4020, 0xFFFF, 0, 0);
}
//------------------ Map 8 ---------------------------
@ -201,6 +204,20 @@ void CPROM_Init(CartInfo *info) {
Latch_Init(info, CPROMSync, 0, 0x8000, 0xFFFF, 0, 0);
}
//------------------ Map 29 --------------------------- //Used by Glider, http://www.retrousb.com/product_info.php?cPath=30&products_id=58
static void M29Sync() {
setprg16(0x8000, (latche & 0x1C) >> 2);
setprg16(0xc000, ~0);
setchr8r(0, latche & 3);
setprg8r(0x10, 0x6000, 0);
}
void Mapper29_Init(CartInfo *info) {
Latch_Init(info, M29Sync, 0, 0x8000, 0xFFFF, 1, 0);
}
//------------------ Map 38 ---------------------------
static void M38Sync(void) {
@ -215,7 +232,6 @@ void Mapper38_Init(CartInfo *info) {
//------------------ Map 66 ---------------------------
static void MHROMSync(void) {
setprg32(0x8000, latche >> 4);
setchr8(latche & 0xF);
}
@ -373,7 +389,7 @@ static void M152Sync() {
setprg16(0x8000, (latche >> 4) & 7);
setprg16(0xc000, ~0);
setchr8(latche & 0xf);
setmirror(MI_0 + ((latche >> 7) & 1)); /* Saint Seiya...hmm. */
setmirror(MI_0 + ((latche >> 7) & 1)); /* Saint Seiya...hmm. */
}
void Mapper152_Init(CartInfo *info) {
@ -435,7 +451,10 @@ void Mapper240_Init(CartInfo *info) {
static void M241Sync(void) {
setchr8(0);
setprg8r(0x10, 0x6000, 0);
setprg32(0x8000, latche);
if (latche & 0x80)
setprg32(0x8000, latche | 8); // no 241 actually, but why not afterall?
else
setprg32(0x8000, latche);
}
void Mapper241_Init(CartInfo *info) {
@ -452,7 +471,7 @@ void Mapper241_Init(CartInfo *info) {
static void BMCA65ASSync(void) {
if (latche & 0x40)
setprg32(0x8000, (latche >> 1) & 0x0F);
else{
else {
setprg16(0x8000, ((latche & 0x30) >> 1) | (latche & 7));
setprg16(0xC000, ((latche & 0x30) >> 1) | 7);
}

View File

@ -48,6 +48,7 @@ static void UNLEDU2000Power(void) {
SetReadHandler(0x6000, 0xFFFF, CartBR);
SetWriteHandler(0x6000, 0xFFFF, CartBW);
SetWriteHandler(0x8000, 0xFFFF, UNLEDU2000HiWrite);
FCEU_CheatAddRAM(32, 0x6000, WRAM);
reg = 0;
Sync();
}

View File

@ -335,7 +335,7 @@ static void makeDphaseARTable(void) {
dphaseARTable[AR][Rks] = 0; /*EG_DP_WIDTH;*/
break;
default:
dphaseARTable[AR][Rks] = rate_adjust((3 * (RL + 4) << (RM + 1)));
dphaseARTable[AR][Rks] = rate_adjust(3 * (RL + 4) << (RM + 1));
break;
}
}

View File

@ -79,6 +79,7 @@ static void SSSNROMPower(void) {
SetReadHandler(0x6000, 0x7FFF, CartBR);
SetWriteHandler(0x6000, 0x7FFF, CartBW);
SetReadHandler(0x8000, 0xFFFF, CartBR);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
}
static void SSSNROMReset(void) {
@ -109,7 +110,6 @@ void SSSNROM_Init(CartInfo *info) {
WRAMSIZE = 16384;
WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE);
SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1);
AddExState(WRAM, WRAMSIZE, 0, "WRAM");
AddExState(&StateRegs, ~0, 0, 0);
}

View File

@ -102,6 +102,7 @@ static void FFEPower(void) {
SetWriteHandler(0x6000, 0x7FFF, CartBW);
SetReadHandler(0x6000, 0x7FFF, CartBR);
SetWriteHandler(0x8000, 0xFFFF, FFEWriteLatch);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
}
static void FFEIRQHook(int a) {

View File

@ -0,0 +1,62 @@
/* FCE Ultra - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 2002 Xodnizel
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "mapinc.h"
static uint8 regs[8];
static SFORMAT StateRegs[] =
{
{ regs, 8, "REGS" },
{ 0 }
};
static void Sync(void) {
for (int i=0; i < 8; ++i)
{
setprg4(0x8000 + (0x1000 * i), regs[i]);
}
}
static DECLFW(M31Write) {
if (A >= 0x5000 && A <= 0x5FFF)
{
regs[A&7] = V;
Sync();
}
}
static void M31Power(void) {
setchr8(0);
regs[7] = 0xFF;
Sync();
SetReadHandler(0x8000, 0xffff, CartBR);
SetWriteHandler(0x5000, 0x5fff, M31Write);
}
static void StateRestore(int version) {
Sync();
}
void Mapper31_Init(CartInfo *info) {
info->Power = M31Power;
GameStateRestore = StateRestore;
AddExState(&StateRegs, ~0, 0, 0);
}

View File

@ -0,0 +1,85 @@
/* FCE Ultra - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 2007 CaH4e3
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "mapinc.h"
static uint8 preg[4], creg, mirr;
static SFORMAT StateRegs[] =
{
{ preg, 4, "PREG" },
{ &creg, 1, "CREG" },
{ &mirr, 1, "MIRR" },
{ 0 }
};
static void Sync(void) {
setprg8(0x6000, preg[0]);
setprg8(0x8000, 0xa);
setprg8(0xa000, 0xb);
setprg8(0xc000, 0x6);
setprg8(0xe000, 0x7);
setchr8(0x0c);
setmirror(mirr);
}
static DECLFW(UNLKS7010Write) {
switch (A) {
case 0x4025: mirr = (((V >> 3) & 1) ^ 1); Sync(); break;
default:
FCEU_printf("bs %04x %02x\n",A,V);
break;
}
}
static void UNLKS7010Reset(void) {
preg[0]++;
if(preg[0] == 0x10) {
preg[0] = 0;
preg[1]++;
if(preg[1] == 0x10) {
preg[1] = 0;
preg[2]++;
}
}
FCEU_printf("preg %02x %02x %02x\n",preg[0], preg[1], preg[2]);
Sync();
}
static void UNLKS7010Power(void) {
preg[0] = preg[1] = preg[2] = 0;
Sync();
SetReadHandler(0x6000, 0x7fff, CartBR);
SetWriteHandler(0x6000, 0x7fff, CartBW);
SetReadHandler(0x8000, 0xffff, CartBR);
SetWriteHandler(0x4020, 0xffff, UNLKS7010Write);
}
static void StateRestore(int version) {
Sync();
}
void UNLKS7010_Init(CartInfo *info) {
info->Power = UNLKS7010Power;
info->Reset = UNLKS7010Reset;
GameStateRestore = StateRestore;
AddExState(&StateRegs, ~0, 0, 0);
}

View File

@ -51,6 +51,7 @@ static void UNLKS7012Power(void) {
SetWriteHandler(0x6000, 0x7FFF, CartBW);
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x8000, 0xFFFF, UNLKS7012Write);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
}
static void UNLKS7012Reset(void) {

View File

@ -87,6 +87,7 @@ static void UNLKS7017Power(void) {
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetReadHandler(0x4030, 0x4030, FDSRead4030);
SetWriteHandler(0x4020, 0x5FFF, UNLKS7017Write);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
}
static void UNLKS7017Close(void) {

View File

@ -82,6 +82,7 @@ static void LH10Power(void) {
SetWriteHandler(0x8000, 0xBFFF, UNLKS7037Write);
SetWriteHandler(0xC000, 0xDFFF, CartBW);
SetWriteHandler(0xE000, 0xFFFF, UNLKS7037Write);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
}
static void Close(void) {

View File

@ -52,6 +52,7 @@ static void LH32Power(void) {
SetReadHandler(0x6000, 0xFFFF, CartBR);
SetWriteHandler(0xC000, 0xDFFF, CartBW);
SetWriteHandler(0x6000, 0x6000, LH32Write);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
}
static void LH32Close(void) {

View File

@ -80,6 +80,7 @@ static void LH53Power(void) {
SetWriteHandler(0xB800, 0xD7FF, LH53RamWrite);
SetWriteHandler(0xE000, 0xEFFF, LH53IRQaWrite);
SetWriteHandler(0xF000, 0xFFFF, LH53Write);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
}
static void LH53Close(void) {

View File

@ -0,0 +1,68 @@
/* FCE Ultra - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 2013 CaH4e3
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "mapinc.h"
static uint16 latche;
static SFORMAT StateRegs[] =
{
{ &latche, 2, "LATC" },
{ 0 }
};
static void Sync(void) {
setprg32(0x8000, 0);
if(CHRsize[0] == 8192) {
setchr4(0x0000, latche & 1);
setchr4(0x1000, latche & 1);
} else {
setchr8(latche & 1); // actually, my bad, overdumped roms, the real CHR size if 8K
}
setmirror(MI_0 + (latche & 1));
}
static DECLFW(UNLCC21Write1) {
latche = A;
Sync();
}
static DECLFW(UNLCC21Write2) {
latche = V;
Sync();
}
static void UNLCC21Power(void) {
latche = 0;
Sync();
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x8001, 0xFFFF, UNLCC21Write1);
SetWriteHandler(0x8000, 0x8000, UNLCC21Write2); // another one many-in-1 mapper, there is a lot of similar carts with little different wirings
}
static void StateRestore(int version) {
Sync();
}
void UNLCC21_Init(CartInfo *info) {
info->Power = UNLCC21Power;
GameStateRestore = StateRestore;
AddExState(&StateRegs, ~0, 0, 0);
}

View File

@ -247,8 +247,8 @@ static void GenMMC1Power(void) {
FCEU_CheatAddRAM(8, 0x6000, WRAM);
if (mmc1opts & 4)
FCEU_dwmemset(WRAM, 0, 8192)
else if (!(mmc1opts & 2))
FCEU_dwmemset(WRAM, 0, 8192);
else if (!(mmc1opts & 2))
FCEU_dwmemset(WRAM, 0, 8192); // wtf?
}
SetWriteHandler(0x8000, 0xFFFF, MMC1_write);
SetReadHandler(0x8000, 0xFFFF, CartBR);

View File

@ -2,6 +2,7 @@
*
* Copyright notice for this file:
* Copyright (C) 2012 CaH4e3
* Copyright (C) 2002 Xodnizel
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -94,6 +95,7 @@ static void MMC2and4Power(void) {
if (is10) {
SetReadHandler(0x6000, 0x7FFF, CartBR);
SetWriteHandler(0x6000, 0x7FFF, CartBW);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
}
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0xA000, 0xFFFF, MMC2and4Write);

View File

@ -28,12 +28,13 @@
#include "mmc3.h"
uint8 MMC3_cmd;
uint8 kt_extra;
uint8 *WRAM;
uint32 WRAMSIZE;
uint8 *CHRRAM;
uint32 CHRRAMSIZE;
uint8 DRegBuf[8];
uint8 EXPREGS[8]; /* For bootleg games, mostly. */
uint8 EXPREGS[8]; /* For bootleg games, mostly. */
uint8 A000B, A001B;
uint8 mmc3opts = 0;
@ -79,7 +80,7 @@ void FixMMC3PRG(int V) {
} else {
pwrap(0x8000, DRegBuf[6]);
pwrap(0xC000, ~1);
}
}
pwrap(0xA000, DRegBuf[7]);
pwrap(0xE000, ~0);
}
@ -182,6 +183,17 @@ DECLFW(MMC3_IRQWrite) {
}
}
// KT-008 boards hack 2-in-1, TODO assign to new ines mapper, most dump of KT-boards on the net are mapper 4, so need database or goodnes fix support
DECLFW(KT008HackWrite) {
// FCEU_printf("%04x:%04x\n",A,V);
switch (A & 3) {
case 0: kt_extra = V; FixMMC3PRG(MMC3_cmd); break;
case 1: break; // unk
case 2: break; // unk
case 3: break; // unk
}
}
static void ClockMMC3Counter(void) {
int count = IRQCount;
if (!count || IRQReload) {
@ -216,11 +228,14 @@ void GenMMC3Restore(int version) {
}
static void GENCWRAP(uint32 A, uint8 V) {
setchr1(A, V); // Business Wars NEEDS THIS for 8K CHR-RAM
setchr1(A, V); // Business Wars NEEDS THIS for 8K CHR-RAM
}
static void GENPWRAP(uint32 A, uint8 V) {
setprg8(A, V & 0x7F); // [NJ102] Mo Dao Jie (C) has 1024Mb MMC3 BOARD, maybe something other will be broken
// [NJ102] Mo Dao Jie (C) has 1024Mb MMC3 BOARD, maybe something other will be broken
// also HengGe BBC-2x boards enables this mode as default board mode at boot up
setprg8(A, (V & 0x7F) | ((kt_extra & 4) << 4));
// KT-008 boards hack 2-in-1, TODO assign to new ines mapper, most dump of KT-boards on the net are mapper 4, so need database or goodnes fix support
}
static void GENMWRAP(uint8 V) {
@ -246,6 +261,10 @@ void GenMMC3Power(void) {
SetWriteHandler(0x8000, 0xBFFF, MMC3_CMDWrite);
SetWriteHandler(0xC000, 0xFFFF, MMC3_IRQWrite);
SetReadHandler(0x8000, 0xFFFF, CartBR);
// KT-008 boards hack 2-in-1, TODO assign to new ines mapper, most dump of KT-boards on the net are mapper 4, so need database or goodnes fix support
SetWriteHandler(0x5000,0x5FFF, KT008HackWrite);
A001B = A000B = 0;
setmirror(1);
if (mmc3opts & 1) {
@ -254,7 +273,7 @@ void GenMMC3Power(void) {
SetReadHandler(0x7000, 0x7FFF, MAWRAMMMC6);
SetWriteHandler(0x7000, 0x7FFF, MBWRAMMMC6);
} else {
FCEU_CheatAddRAM((WRAMSIZE & 0x1fff) >> 10, 0x6000, WRAM);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
SetWriteHandler(0x6000, 0x6000 + ((WRAMSIZE - 1) & 0x1fff), CartBW);
SetReadHandler(0x6000, 0x6000 + ((WRAMSIZE - 1) & 0x1fff), CartBR);
setprg8r(0x10, 0x6000, 0);
@ -299,17 +318,19 @@ void GenMMC3_Init(CartInfo *info, int prg, int chr, int wram, int battery) {
info->SaveGameLen[0] = WRAMSIZE;
}
// KT-008 boards hack 2-in-1, TODO assign to new ines mapper, most dump of KT-boards on the net are mapper 4, so need database or goodnes fix support
AddExState(&kt_extra, 1, 0, "KTEX");
AddExState(MMC3_StateRegs, ~0, 0, 0);
info->Power = GenMMC3Power;
info->Reset = MMC3RegReset;
info->Close = GenMMC3Close;
if (info->CRC32 == 0x5104833e) // Kick Master
if (info->CRC32 == 0x5104833e) // Kick Master
GameHBIRQHook = MMC3_hb_KickMasterHack;
else if (info->CRC32 == 0x5a6860f1 || info->CRC32 == 0xae280e20) // Shougi Meikan '92/'93
else if (info->CRC32 == 0x5a6860f1 || info->CRC32 == 0xae280e20)// Shougi Meikan '92/'93
GameHBIRQHook = MMC3_hb_KickMasterHack;
else if (info->CRC32 == 0xfcd772eb) // PAL Star Wars, similar problem as Kick Master.
else if (info->CRC32 == 0xfcd772eb) // PAL Star Wars, similar problem as Kick Master.
GameHBIRQHook = MMC3_hb_PALStarWarsHack;
else
GameHBIRQHook = MMC3_hb;
@ -322,7 +343,7 @@ void GenMMC3_Init(CartInfo *info, int prg, int chr, int wram, int battery) {
// ---------------------------- Mapper 4 --------------------------------
static int hackm4 = 0; /* For Karnov, maybe others. BLAH. Stupid iNES format.*/
static int hackm4 = 0; /* For Karnov, maybe others. BLAH. Stupid iNES format.*/
static void M4Power(void) {
GenMMC3Power();
@ -353,10 +374,22 @@ static DECLFW(M12Write) {
EXPREGS[1] = (V & 0x10) >> 4;
}
static DECLFR(M12Read) {
return EXPREGS[2];
}
static void M12Power(void) {
EXPREGS[0] = EXPREGS[1] = 0;
EXPREGS[2] = 1; // chinese is default
GenMMC3Power();
SetWriteHandler(0x4100, 0x5FFF, M12Write);
SetReadHandler(0x4100, 0x5FFF, M12Read);
}
static void M12Reset(void) {
EXPREGS[0] = EXPREGS[1] = 0;
EXPREGS[2] ^= 1;
MMC3RegReset();
}
void Mapper12_Init(CartInfo *info) {
@ -365,6 +398,7 @@ void Mapper12_Init(CartInfo *info) {
isRevB = 0;
info->Power = M12Power;
info->Reset = M12Reset;
AddExState(EXPREGS, 2, 0, "EXPR");
}
@ -461,7 +495,7 @@ static void M45CW(uint32 A, uint8 V) {
NV &= (1 << ((EXPREGS[2] & 7) + 1)) - 1;
else
if (EXPREGS[2])
NV &= 0; // hack ;( don't know exactly how it should be
NV &= 0; // hack ;( don't know exactly how it should be
NV |= EXPREGS[0] | ((EXPREGS[2] & 0xF0) << 4);
setchr1(A, NV);
}
@ -609,7 +643,7 @@ static void M52PW(uint32 A, uint8 V) {
static void M52CW(uint32 A, uint8 V) {
uint32 mask = 0xFF ^ ((EXPREGS[0] & 0x40) << 1);
// uint32 bank = (((EXPREGS[0]>>3)&4)|((EXPREGS[0]>>1)&2)|((EXPREGS[0]>>6)&(EXPREGS[0]>>4)&1))<<7;
uint32 bank = (((EXPREGS[0] >> 4) & 2) | (EXPREGS[0] & 4) | ((EXPREGS[0] >> 6) & (EXPREGS[0] >> 4) & 1)) << 7; // actually 256K CHR banks index bits is inverted!
uint32 bank = (((EXPREGS[0] >> 4) & 2) | (EXPREGS[0] & 4) | ((EXPREGS[0] >> 6) & (EXPREGS[0] >> 4) & 1)) << 7; // actually 256K CHR banks index bits is inverted!
setchr1(A, bank | (V & mask));
}
@ -659,7 +693,7 @@ void Mapper76_Init(CartInfo *info) {
// ---------------------------- Mapper 74 -------------------------------
static void M74CW(uint32 A, uint8 V) {
if ((V == 8) || (V == 9)) //Di 4 Ci - Ji Qi Ren Dai Zhan (As).nes, Ji Jia Zhan Shi (As).nes
if ((V == 8) || (V == 9)) //Di 4 Ci - Ji Qi Ren Dai Zhan (As).nes, Ji Jia Zhan Shi (As).nes
setchr1r(0x10, A, V);
else
setchr1r(0, A, V);
@ -735,7 +769,7 @@ void Mapper114_Init(CartInfo *info) {
static void M115PW(uint32 A, uint8 V) {
if (EXPREGS[0] & 0x80) {
if (EXPREGS[0] & 0x20)
setprg32(0x8000, (EXPREGS[0] & 0x0F) >> 1); // real hardware tests, info 100% now lol
setprg32(0x8000, (EXPREGS[0] & 0x0F) >> 1); // real hardware tests, info 100% now lol
else {
setprg16(0x8000, (EXPREGS[0] & 0x0F));
setprg16(0xC000, (EXPREGS[0] & 0x0F));
@ -749,8 +783,9 @@ static void M115CW(uint32 A, uint8 V) {
}
static DECLFW(M115Write) {
if (A == 0x5080) EXPREGS[2] = V;
if (A == 0x6000)
if (A == 0x5080)
EXPREGS[2] = V; // Extra prot hardware 2-in-1 mode
else if (A == 0x6000)
EXPREGS[0] = V;
else if (A == 0x6001)
EXPREGS[1] = V;
@ -772,7 +807,7 @@ void Mapper115_Init(CartInfo *info) {
cwrap = M115CW;
pwrap = M115PW;
info->Power = M115Power;
AddExState(EXPREGS, 2, 0, "EXPR");
AddExState(EXPREGS, 3, 0, "EXPR");
}
// ---------------------------- Mapper 118 ------------------------------
@ -806,6 +841,7 @@ void Mapper119_Init(CartInfo *info) {
CHRRAMSIZE = 8192;
CHRRAM = (uint8*)FCEU_gmalloc(CHRRAMSIZE);
SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSIZE, 1);
AddExState(CHRRAM, CHRRAMSIZE, 0, "CHRR");
}
// ---------------------------- Mapper 134 ------------------------------
@ -939,7 +975,7 @@ void Mapper192_Init(CartInfo *info) {
// ---------------------------- Mapper 194 -------------------------------
static void M194CW(uint32 A, uint8 V) {
if (V <= 1) //Dai-2-Ji - Super Robot Taisen (As).nes
if (V <= 1) //Dai-2-Ji - Super Robot Taisen (As).nes
setchr1r(0x10, A, V);
else
setchr1r(0, A, V);
@ -956,7 +992,7 @@ void Mapper194_Init(CartInfo *info) {
// ---------------------------- Mapper 195 -------------------------------
static void M195CW(uint32 A, uint8 V) {
if (V <= 3) // Crystalis (c).nes, Captain Tsubasa Vol 2 - Super Striker (C)
if (V <= 3) // Crystalis (c).nes, Captain Tsubasa Vol 2 - Super Striker (C)
setchr1r(0x10, A, V);
else
setchr1r(0, A, V);
@ -986,25 +1022,18 @@ void Mapper195_Init(CartInfo *info) {
// game
static void M196PW(uint32 A, uint8 V) {
if (EXPREGS[0]) // Tenchi o Kurau II - Shokatsu Koumei Den (J) (C).nes
if (EXPREGS[0])
setprg32(0x8000, EXPREGS[1]);
else
setprg8(A, V);
// setprg8(A,(V&3)|((V&8)>>1)|((V&4)<<1)); // Mali Splash Bomb
}
//static void M196CW(uint32 A, uint8 V)
//{
// setchr1(A,(V&0xDD)|((V&0x20)>>4)|((V&2)<<4));
//}
static DECLFW(Mapper196Write) {
if (A >= 0xC000) {
A = (A & 0xFFFE) | ((A >> 2) & 1) | ((A >> 3) & 1);
MMC3_IRQWrite(A, V);
} else {
A = (A & 0xFFFE) | ((A >> 2) & 1) | ((A >> 3) & 1) | ((A >> 1) & 1);
// A=(A&0xFFFE)|((A>>3)&1); // Mali Splash Bomb
MMC3_CMDWrite(A, V);
}
}
@ -1025,10 +1054,44 @@ static void Mapper196Power(void) {
void Mapper196_Init(CartInfo *info) {
GenMMC3_Init(info, 128, 128, 0, 0);
pwrap = M196PW;
// cwrap=M196CW; // Mali Splash Bomb
info->Power = Mapper196Power;
}
// ---------------------------- Mali Splash Bomb----------------------------
// The same board as for 196 mapper games, but with additional data bit swap
// Also, it is impossible to work on the combined 196 mapper source with
// all data bits merged, because it's using one of them as 8000 reg...
static void UNLMaliSBPW(uint32 A, uint8 V) {
setprg8(A, (V & 3) | ((V & 8) >> 1) | ((V & 4) << 1));
}
static void UNLMaliSBCW(uint32 A, uint8 V) {
setchr1(A, (V & 0xDD) | ((V & 0x20) >> 4) | ((V & 2) << 4));
}
static DECLFW(UNLMaliSBWrite) {
if (A >= 0xC000) {
A = (A & 0xFFFE) | ((A >> 2) & 1) | ((A >> 3) & 1);
MMC3_IRQWrite(A, V);
} else {
A = (A & 0xFFFE) | ((A >> 3) & 1);
MMC3_CMDWrite(A, V);
}
}
static void UNLMaliSBPower(void) {
GenMMC3Power();
SetWriteHandler(0x8000, 0xFFFF, UNLMaliSBWrite);
}
void UNLMaliSB_Init(CartInfo *info) {
GenMMC3_Init(info, 128, 128, 0, 0);
pwrap = UNLMaliSBPW;
cwrap = UNLMaliSBCW;
info->Power = UNLMaliSBPower;
}
// ---------------------------- Mapper 197 -------------------------------
static void M197CW(uint32 A, uint8 V) {
@ -1048,7 +1111,7 @@ void Mapper197_Init(CartInfo *info) {
// ---------------------------- Mapper 198 -------------------------------
static void M198PW(uint32 A, uint8 V) {
if (V >= 0x50) // Tenchi o Kurau II - Shokatsu Koumei Den (J) (C).nes
if (V >= 0x50) // Tenchi o Kurau II - Shokatsu Koumei Den (J) (C).nes
setprg8(A, V & 0x4F);
else
setprg8(A, V);
@ -1100,7 +1163,7 @@ static void M205Reset(void) {
static void M205Power(void) {
GenMMC3Power();
SetWriteHandler(0x6000, 0x6fff, M205Write0);
SetWriteHandler(0x7000, 0x7fff, M205Write1); // OK-411 boards, the same logic, but data latched, 2-in-1 frankenstein
SetWriteHandler(0x7000, 0x7fff, M205Write1); // OK-411 boards, the same logic, but data latched, 2-in-1 frankenstein
}
void Mapper205_Init(CartInfo *info) {
@ -1115,7 +1178,7 @@ void Mapper205_Init(CartInfo *info) {
// ---------------------------- Mapper 245 ------------------------------
static void M245CW(uint32 A, uint8 V) {
if (!UNIFchrrama) // Yong Zhe Dou E Long - Dragon Quest VI (As).nes NEEDS THIS for RAM cart
if (!UNIFchrrama) // Yong Zhe Dou E Long - Dragon Quest VI (As).nes NEEDS THIS for RAM cart
setchr1(A, V & 7);
EXPREGS[0] = V;
FixMMC3PRG(MMC3_cmd);
@ -1144,7 +1207,7 @@ static void M249PW(uint32 A, uint8 V) {
if (EXPREGS[0] & 0x2) {
if (V < 0x20)
V = (V & 1) | ((V >> 3) & 2) | ((V >> 1) & 4) | ((V << 2) & 8) | ((V << 2) & 0x10);
else{
else {
V -= 0x20;
V = (V & 3) | ((V >> 1) & 4) | ((V >> 4) & 8) | ((V >> 2) & 0x10) | ((V << 3) & 0x20) | ((V << 2) & 0xC0);
}
@ -1280,6 +1343,7 @@ void TQROM_Init(CartInfo *info) {
CHRRAMSIZE = 8192;
CHRRAM = (uint8*)FCEU_gmalloc(CHRRAMSIZE);
SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSIZE, 1);
AddExState(CHRRAM, CHRRAMSIZE, 0, "CHRR");
}
void HKROM_Init(CartInfo *info) {

View File

@ -88,12 +88,13 @@ static uint8 MMC5LineCounter;
static uint8 mmc5psize, mmc5vsize;
static uint8 mul[2];
static uint32 WRAMSIZE = 0;
static uint8 *WRAM = NULL;
static uint8 *MMC5fill = NULL;
static uint8 *ExRAM = NULL;
static uint8 MMC5WRAMsize;
static uint8 MMC5WRAMIndex[8];
static uint8 MMC5WRAMsize; //configuration, not state
static uint8 MMC5WRAMIndex[8]; //configuration, not state
static uint8 MMC5ROMWrProtect[4];
static uint8 MMC5MemIn[5];
@ -137,7 +138,11 @@ static void mmc5_PPUWrite(uint32 A, uint8 V) {
uint8 FASTCALL mmc5_PPURead(uint32 A) {
if (A < 0x2000) {
if (ppuphase == PPUPHASE_BG)
if (ppuphase == PPUPHASE_BG
//zero 03-aug-2014 - added this to fix Uchuu Keibitai SDF. The game reads NT entries from CHR rom while PPU is disabled.
//obviously we have enormous numbers of bugs springing from our terrible emulation of ppu-disabled states, but this does the job for fixing this one
&& (PPU[1] & 0x10)
)
return *MMC5BGVRAMADR(A);
else return MMC5SPRVPage[(A) >> 10][(A)];
} else {
@ -145,51 +150,46 @@ uint8 FASTCALL mmc5_PPURead(uint32 A) {
}
}
// ELROM seems to have 8KB of RAM
// ETROM seems to have 16KB of WRAM
// EWROM seems to have 32KB of WRAM
cartdata MMC5CartList[] =
{
{ 0x9c18762b, 2 }, /* L'Empereur */
{ 0x26533405, 2 },
{ 0x6396b988, 2 },
{ 0xaca15643, 2 }, /* Uncharted Waters */
{ 0xfe3488d1, 2 }, /* Dai Koukai Jidai */
{ 0x15fe6d0f, 2 }, /* BKAC */
{ 0x39f2ce4b, 2 }, /* Suikoden */
{ 0x8ce478db, 2 }, /* Nobunaga's Ambition 2 */
{ 0xeee9a682, 2 },
{ 0xf9b4240f, 2 },
{ 0x6f4e4312, 4 }, /* Aoki Ookami to Shiroki Mejika - Genchou Hishi */
{ 0x15fe6d0f, 2 }, /* Bandit Kings of Ancient China */
{ 0x671f23a8, 0 }, /* Castlevania III - Dracula's Curse (E) */
{ 0xcd4e7430, 0 }, /* Castlevania III - Dracula's Curse (KC) */
{ 0xed2465be, 0 }, /* Castlevania III - Dracula's Curse (U) */
{ 0xfe3488d1, 2 }, /* Daikoukai Jidai */
{ 0x0ec6c023, 1 }, /* Gemfire */
{ 0x0afb395e, 0 }, /* Gun Sight */
{ 0x1ced086f, 2 }, /* Ishin no Arashi */
{ 0xf540677b, 4 }, /* Nobunaga...Bushou Fuuun Roku */
{ 0x6f4e4312, 4 }, /* Aoki Ookami..Genchou */
{ 0xf011e490, 4 }, /* Romance of the 3 Kingdoms 2 */
{ 0x184c2124, 4 }, /* Sangokushi 2 */
{ 0xee8e6553, 4 },
{ 0x9cbadc25, 1 }, /* Just Breed */
{ 0x6396b988, 2 }, /* L'Empereur (J) */
{ 0x9c18762b, 2 }, /* L'Empereur (U) */
{ 0xb0480ae9, 0 }, /* Laser Invasion */
{ 0xb4735fac, 0 }, /* Metal Slader Glory */
{ 0xf540677b, 4 }, /* Nobunaga no Yabou - Bushou Fuuun Roku */
{ 0xeee9a682, 2 }, /* Nobunaga no Yabou - Sengoku Gunyuu Den (J) (PRG0) */
{ 0xf9b4240f, 2 }, /* Nobunaga no Yabou - Sengoku Gunyuu Den (J) (PRG1) */
{ 0x8ce478db, 2 }, /* Nobunaga's Ambition 2 */
{ 0xf011e490, 4 }, /* Romance of The Three Kingdoms II */
{ 0xbc80fb52, 1 }, /* Royal Blood */
{ 0x184c2124, 4 }, /* Sangokushi II (J) (PRG0) */
{ 0xee8e6553, 4 }, /* Sangokushi II (J) (PRG1) */
{ 0xd532e98f, 1 }, /* Shin 4 Nin Uchi Mahjong - Yakuman Tengoku */
{ 0x39f2ce4b, 2 }, /* Suikoden - Tenmei no Chikai */
{ 0xbb7f829a, 0 }, /* Uchuu Keibitai SDF */
{ 0xaca15643, 2 }, /* Uncharted Waters */
};
#define MMC5_NOCARTS (sizeof(MMC5CartList) / sizeof(MMC5CartList[0]))
#define MMC5_NOCARTS (sizeof(MMC5CartList) / sizeof(MMC5CartList[0]))
int DetectMMC5WRAMSize(uint32 crc32) {
int x;
for (x = 0; x < MMC5_NOCARTS; x++) {
if (crc32 == MMC5CartList[x].crc32) {
FCEU_printf(" >8KB external WRAM present. Use UNIF if you hack the ROM image.\n");
if(MMC5CartList[x].size > 1)
FCEU_printf(" >8KB external WRAM present. Use UNIF if you hack the ROM image.\n");
return(MMC5CartList[x].size * 8);
}
}
//mbg 04-aug-08 - previously, this was returning 8KB
//but I changed it to return 64 because unlisted carts are probably homebrews, and they should probably use 64 (why not use it all?)
//ch4 10-dec-08 - then f***ng for what all this shit above? let's give em all this 64k shit! Damn
// homebrew must use it's own emulators or standart features.
//adelikat 20-dec-08 - reverting back to return 64, sounds like it was changed back to 8 simply on principle. FCEUX is all encompassing, and that include
//rom-hacking. We want it to be the best emulator for such purposes. So unless return 64 harms compatibility with anything else, I see now reason not to have it
//mbg 29-mar-09 - I should note that mmc5 is in principle capable of 64KB, even if no real carts ever supported it.
//This does not in principle break any games which share this mapper, and it should be OK for homebrew.
//if there are games which need 8KB instead of 64KB default then lets add them to the list
return 64;
}
@ -197,17 +197,11 @@ static void BuildWRAMSizeTable(void) {
int x;
for (x = 0; x < 8; x++) {
switch (MMC5WRAMsize) {
case 0: MMC5WRAMIndex[x] = 255; break; //X,X,X,X,X,X,X,X
case 1: MMC5WRAMIndex[x] = (x > 3) ? 255 : 0; break; //0,0,0,0,X,X,X,X
case 2: MMC5WRAMIndex[x] = (x & 4) >> 2; break; //0,0,0,0,1,1,1,1
case 4: MMC5WRAMIndex[x] = (x > 3) ? 255 : (x & 3); break; //0,1,2,3,X,X,X,X
case 8: MMC5WRAMIndex[x] = x; break; //0,1,2,3,4,5,6,7,8
//mbg 8/6/08 - i added this to support 64KB of wram
//now, I have at least one example (laser invasion) which actually uses size 1 but isnt in the crc list
//so, whereas before my change on 8/4/08 we would have selected size 1, now we select size 8
//this means that we could have just introduced an emulation bug, in case those games happened to
//address, say, page 3. with size 1 that would resolve to [0] but in size 8 it resolves to [3].
//so, you know what to do if there are problems.
case 0: MMC5WRAMIndex[x] = 255; break; //X,X,X,X,X,X,X,X
case 1: MMC5WRAMIndex[x] = (x > 3) ? 255 : 0; break; //0,0,0,0,X,X,X,X
case 2: MMC5WRAMIndex[x] = (x & 4) >> 2; break; //0,0,0,0,1,1,1,1
case 4: MMC5WRAMIndex[x] = (x > 3) ? 255 : (x & 3); break; //0,1,2,3,X,X,X,X
case 8: MMC5WRAMIndex[x] = x; break; //0,1,2,3,4,5,6,7
}
}
}
@ -277,10 +271,10 @@ static void MMC5CHRB(void) {
}
static void MMC5WRAM(uint32 A, uint32 V) {
//printf("%02x\n",V);
V = MMC5WRAMIndex[V & 7];
if (V != 255) {
setprg8r(0x10, A, V);
FCEU_CheatAddRAM(8, 0x6000, (WRAM + ((V * 8192) & (WRAMSIZE - 1))));
MMC5MemIn[(A - 0x6000) >> 13] = 1;
} else
MMC5MemIn[(A - 0x6000) >> 13] = 0;
@ -349,12 +343,31 @@ static void MMC5PRG(void) {
}
static DECLFW(Mapper5_write) {
if (A >= 0x5120 && A <= 0x5127) {
mmc5ABMode = 0;
CHRBanksA[A & 7] = V | ((MMC50x5130 & 0x3) << 8); //if we had a test case for this then we could test this, but it hasnt been verified
//CHRBanksA[A&7]=V;
MMC5CHRA();
} else switch (A) {
switch (A) {
case 0x5100:
mmc5psize = V;
MMC5PRG();
break;
case 0x5101:
mmc5vsize = V;
if (!mmc5ABMode) {
MMC5CHRB();
MMC5CHRA();
} else {
MMC5CHRA();
MMC5CHRB();
}
break;
case 0x5102:
WRAMMaskEnable[0] = V;
break;
case 0x5103:
WRAMMaskEnable[1] = V;
break;
case 0x5104:
CHRMode = V;
MMC5HackCHRMode = V & 3;
break;
case 0x5105:
{
int x;
@ -369,53 +382,50 @@ static DECLFW(Mapper5_write) {
NTAMirroring = V;
break;
}
case 0x5113: WRAMPage = V; MMC5WRAM(0x6000, V & 7); break;
case 0x5100: mmc5psize = V; MMC5PRG(); break;
case 0x5101:
mmc5vsize = V;
if (!mmc5ABMode) {
MMC5CHRB();
MMC5CHRA();
} else {
MMC5CHRA();
MMC5CHRB();
case 0x5106:
if (V != NTFill)
FCEU_dwmemset(MMC5fill, (V | (V << 8) | (V << 16) | (V << 24)), 0x3c0);
NTFill = V;
break;
case 0x5107:
if (V != ATFill) {
unsigned char moop = V | (V << 2) | (V << 4) | (V << 6);
FCEU_dwmemset(MMC5fill + 0x3c0, moop | (moop << 8) | (moop << 16) | (moop << 24), 0x40);
}
ATFill = V;
break;
case 0x5113:
WRAMPage = V;
MMC5WRAM(0x6000, V & 7);
break;
case 0x5114:
case 0x5115:
case 0x5116:
case 0x5117: PRGBanks[A & 3] = V; MMC5PRG(); break;
case 0x5117:
PRGBanks[A & 3] = V;
MMC5PRG();
break;
case 0x5120:
case 0x5121:
case 0x5122:
case 0x5123:
case 0x5124:
case 0x5125:
case 0x5126:
case 0x5127:
mmc5ABMode = 0;
CHRBanksA[A & 7] = V | ((MMC50x5130 & 0x3) << 8);
MMC5CHRA();
break;
case 0x5128:
case 0x5129:
case 0x512a:
case 0x512b:
mmc5ABMode = 1;
CHRBanksB[A & 3] = V;
CHRBanksB[A & 3] = V | ((MMC50x5130 & 0x3) << 8);
MMC5CHRB();
break;
case 0x5102: WRAMMaskEnable[0] = V; break;
case 0x5103: WRAMMaskEnable[1] = V; break;
case 0x5104: CHRMode = V; MMC5HackCHRMode = V & 3; break;
case 0x5106:
if (V != NTFill) {
uint32 t;
t = V | (V << 8) | (V << 16) | (V << 24);
FCEU_dwmemset(MMC5fill, t, 0x3c0);
}
NTFill = V;
break;
case 0x5107:
if (V != ATFill) {
unsigned char moop;
uint32 t;
moop = V | (V << 2) | (V << 4) | (V << 6);
t = moop | (moop << 8) | (moop << 16) | (moop << 24);
FCEU_dwmemset(MMC5fill + 0x3c0, t, 0x40);
}
ATFill = V;
break;
case 0x5130: MMC50x5130 = V; break;
case 0x5200: MMC5HackSPMode = V; break;
case 0x5201: MMC5HackSPScroll = (V >> 3) & 0x1F; break;
case 0x5202: MMC5HackSPPage = V & 0x3F; break;
@ -434,10 +444,11 @@ static DECLFR(MMC5_ReadROMRAM) {
}
static DECLFW(MMC5_WriteROMRAM) {
if (A >= 0x8000)
if (MMC5ROMWrProtect[(A - 0x8000) >> 13]) return;
if ((A >= 0x8000) && (MMC5ROMWrProtect[(A - 0x8000) >> 13]))
return;
if (MMC5MemIn[(A - 0x6000) >> 13])
if (((WRAMMaskEnable[0] & 3) | ((WRAMMaskEnable[1] & 3) << 2)) == 6) Page[A >> 11][A] = V;
if (((WRAMMaskEnable[0] & 3) | ((WRAMMaskEnable[1] & 3) << 2)) == 6)
Page[A >> 11][A] = V;
}
static DECLFW(MMC5_ExRAMWr) {
@ -446,17 +457,12 @@ static DECLFW(MMC5_ExRAMWr) {
}
static DECLFR(MMC5_ExRAMRd) {
// Not sure if this is correct, so I'll comment it out for now.
// if(MMC5HackCHRMode>=2)
return ExRAM[A & 0x3ff];
// else
// return(X.DB);
return ExRAM[A & 0x3ff];
}
static DECLFR(MMC5_read) {
switch (A) {
case 0x5204:
{
case 0x5204: {
uint8 x;
X6502_IRQEnd(FCEU_IQEXT);
x = MMC5IRQR;
@ -466,8 +472,10 @@ static DECLFR(MMC5_read) {
MMC5IRQR &= 0x40;
return x;
}
case 0x5205: return(mul[0] * mul[1]);
case 0x5206: return((mul[0] * mul[1]) >> 8);
case 0x5205:
return(mul[0] * mul[1]);
case 0x5206:
return((mul[0] * mul[1]) >> 8);
}
return(X.DB);
}
@ -492,38 +500,56 @@ void MMC5Synco(void) {
MMC5CHRA();
MMC5CHRB();
}
//in case the fill register changed, we need to overwrite the fill buffer
FCEU_dwmemset(MMC5fill, NTFill | (NTFill << 8) | (NTFill << 16) | (NTFill << 24), 0x3c0);
{
uint32 t;
t = NTFill | (NTFill << 8) | (NTFill << 16) | (NTFill << 24);
FCEU_dwmemset(MMC5fill, t, 0x3c0);
unsigned char moop = ATFill | (ATFill << 2) | (ATFill << 4) | (ATFill << 6);
FCEU_dwmemset(MMC5fill + 0x3c0, moop | (moop << 8) | (moop << 16) | (moop << 24), 0x40);
}
{
unsigned char moop;
uint32 t;
moop = ATFill | (ATFill << 2) | (ATFill << 4) | (ATFill << 6);
t = moop | (moop << 8) | (moop << 16) | (moop << 24);
FCEU_dwmemset(MMC5fill + 0x3c0, t, 0x40);
}
X6502_IRQEnd(FCEU_IQEXT);
MMC5HackCHRMode = CHRMode & 3;
//zero 17-apr-2013 - why the heck should this happen here? anything in a `synco` should be depending on the state.
//im going to leave it commented out to see what happens
//X6502_IRQEnd(FCEU_IQEXT);
}
void MMC5_hb(int scanline) {
if (scanline == 240) {
//zero 24-jul-2014 - revised for newer understanding, to fix metal slader glory credits. see r7371 in bizhawk
int sl = scanline + 1;
int ppuon = (PPU[1] & 0x18);
if (!ppuon || sl >= 241)
{
// whenever rendering is off for any reason (vblank or forced disable
// the irq counter resets, as well as the inframe flag (easily verifiable from software)
MMC5IRQR &= ~0x40;
MMC5IRQR &= ~0x80;
MMC5LineCounter = 0;
MMC5IRQR = 0x40;
X6502_IRQEnd(FCEU_IQEXT);
return;
}
if (MMC5LineCounter < 240) {
if (MMC5LineCounter == IRQScanline) {
if (!(MMC5IRQR&0x40))
{
MMC5IRQR |= 0x40;
MMC5IRQR &= ~0x80;
MMC5LineCounter = 0;
X6502_IRQEnd(FCEU_IQEXT);
}
else
{
MMC5LineCounter++;
if (MMC5LineCounter == IRQScanline)
{
MMC5IRQR |= 0x80;
if (IRQEnable & 0x80)
X6502_IRQBegin(FCEU_IQEXT);
}
MMC5LineCounter++;
}
if (MMC5LineCounter == 240)
MMC5IRQR = 0;
}
void MMC5_StateRestore(int version) {
@ -560,7 +586,7 @@ static void Do5PCM() {
}
static void Do5PCMHQ() {
uint32 V; //mbg merge 7/17/06 made uint32
uint32 V;
if (!(MMC5Sound.rawcontrol & 0x40) && MMC5Sound.raw)
for (V = MMC5Sound.BC[2]; V < SOUNDTS; V++)
WaveHi[V] += MMC5Sound.raw << 5;
@ -643,7 +669,7 @@ static void Do5SQ(int P) {
static void Do5SQHQ(int P) {
static int tal[4] = { 1, 2, 4, 6 };
uint32 V; //mbg merge 7/17/06 made uint32
uint32 V;
int32 amp, rthresh, wl;
wl = MMC5Sound.wl[P] + 1;
@ -726,8 +752,11 @@ void NSFMMC5_Init(void) {
}
void NSFMMC5_Close(void) {
if (WRAM)
FCEU_gfree(WRAM);
WRAM = NULL;
FCEU_gfree(ExRAM);
ExRAM = 0;
ExRAM = NULL;
}
static void GenMMC5Reset(void) {
@ -759,7 +788,7 @@ static void GenMMC5Reset(void) {
SetReadHandler(0x5205, 0x5206, MMC5_read);
// GameHBIRQHook=MMC5_hb;
FCEU_CheatAddRAM(8, 0x6000, WRAM);
// FCEU_CheatAddRAM(8, 0x6000, WRAM);
FCEU_CheatAddRAM(1, 0x5c00, ExRAM);
}
@ -777,6 +806,15 @@ static SFORMAT MMC5_StateRegs[] = {
{ &NTFill, 1, "NTFL" },
{ &ATFill, 1, "ATFL" },
//zero 17-apr-2013 - added
{ &MMC5IRQR, 1, "IRQR" },
{ &MMC5LineCounter, 1, "LCTR" },
{ &mmc5psize, 1, "PSIZ" },
{ &mmc5vsize, 1, "VSIZ" },
{ mul, 2, "MUL2" },
{ MMC5ROMWrProtect, 4, "WRPR" },
{ MMC5MemIn, 5, "MEMI" },
{ &MMC5Sound.wl[0], 2 | FCEUSTATE_RLSB, "SDW0" },
{ &MMC5Sound.wl[1], 2 | FCEUSTATE_RLSB, "SDW1" },
{ MMC5Sound.env, 2, "SDEV" },
@ -784,6 +822,15 @@ static SFORMAT MMC5_StateRegs[] = {
{ &MMC5Sound.running, 1, "SDRU" },
{ &MMC5Sound.raw, 1, "SDRW" },
{ &MMC5Sound.rawcontrol, 1, "SDRC" },
//zero 17-apr-2013 - added
{ &MMC5Sound.dcount[0], 4 | FCEUSTATE_RLSB, "DCT0" },
{ &MMC5Sound.dcount[1], 4 | FCEUSTATE_RLSB, "DCT1" },
{ &MMC5Sound.BC[0], 4 | FCEUSTATE_RLSB, "BC00" },
{ &MMC5Sound.BC[1], 4 | FCEUSTATE_RLSB, "BC01" },
{ &MMC5Sound.BC[2], 4 | FCEUSTATE_RLSB, "BC02" },
{ &MMC5Sound.vcount[0], 4 | FCEUSTATE_RLSB, "VCT0" },
{ &MMC5Sound.vcount[1], 4 | FCEUSTATE_RLSB, "VCT1" },
{ 0 }
};
@ -797,13 +844,12 @@ static void GenMMC5_Init(CartInfo *info, int wsize, int battery) {
MMC5fill = (uint8*)FCEU_gmalloc(1024);
ExRAM = (uint8*)FCEU_gmalloc(1024);
AddExState(MMC5_StateRegs, ~0, 0, 0);
AddExState(WRAM, wsize * 1024, 0, "WRAM");
AddExState(ExRAM, 1024, 0, "ERAM");
AddExState(&MMC5HackSPMode, 1, 0, "SPLM");
AddExState(&MMC5HackSPScroll, 1, 0, "SPLS");
AddExState(&MMC5HackSPPage, 1, 0, "SPLP");
AddExState(&MMC50x5130, 1, 0, "5130");
AddExState(MMC5_StateRegs, ~0, 0, 0);
MMC5WRAMsize = wsize / 8;
BuildWRAMSizeTable();
@ -831,28 +877,27 @@ static void GenMMC5_Init(CartInfo *info, int wsize, int battery) {
}
void Mapper5_Init(CartInfo *info) {
GenMMC5_Init(info, DetectMMC5WRAMSize(info->CRC32), info->battery);
WRAMSIZE = DetectMMC5WRAMSize(info->CRC32);
GenMMC5_Init(info, WRAMSIZE, info->battery);
}
// ELROM seems to have 0KB of WRAM
// EKROM seems to have 8KB of WRAM
// ETROM seems to have 16KB of WRAM
// EWROM seems to have 32KB of WRAM
// ETROM and EWROM are battery-backed, EKROM isn't.
void ETROM_Init(CartInfo *info) {
GenMMC5_Init(info, 16, info->battery);
}
// EKROM seems to have 8KB of WRAM, battery-backed
// ETROM seems to have 16KB of WRAM, battery-backed
// EWROM seems to have 32KB of WRAM, battery-backed
void ELROM_Init(CartInfo *info) {
GenMMC5_Init(info, 0, 0);
}
void EWROM_Init(CartInfo *info) {
GenMMC5_Init(info, 32, info->battery);
}
void EKROM_Init(CartInfo *info) {
GenMMC5_Init(info, 8, info->battery);
}
void ETROM_Init(CartInfo *info) {
GenMMC5_Init(info, 16, info->battery);
}
void EWROM_Init(CartInfo *info) {
GenMMC5_Init(info, 32, info->battery);
}

View File

@ -264,7 +264,7 @@ static void DoNamcoSoundHQ(void) {
lengo = LengthCache[P];
duff2 = FetchDuff(P, envelope);
for (V = CVBC << 1; V < SOUNDTS << 1; V++) {
for (V = CVBC << 1; V < (int)SOUNDTS << 1; V++) {
WaveHi[V >> 1] += duff2;
if (!vco) {
PlayIndex[P] += freq;

View File

@ -32,17 +32,17 @@ static uint8 cpu410x[16], ppu201x[16], apu40xx[64];
// IRQ Registers
static uint8 IRQCount, IRQa, IRQReload;
#define IRQLatch cpu410x[0x1]
#define IRQLatch cpu410x[0x1] // accc cccc, a = 0, AD12 switching, a = 1, HSYNC switching
// MMC3 Registers
static uint8 inv_hack = 0; // some OneBus Systems have swapped PRG reg commans in MMC3 inplementation,
// trying to autodetect unusual behavior, due not to add a new mapper.
#define mmc3cmd cpu410x[0x5]
#define mirror cpu410x[0x6]
static uint8 inv_hack = 0; // some OneBus Systems have swapped PRG reg commans in MMC3 inplementation,
// trying to autodetect unusual behavior, due not to add a new mapper.
#define mmc3cmd cpu410x[0x5] // pcv- ----, p - program swap, c - video swap, v - internal VRAM enable
#define mirror cpu410x[0x6] // ---- ---m, m = 0 - H, m = 1 - V
// APU Registers
static uint8 pcm_enable = 0, pcm_irq = 0;
static int16 pcm_addr, pcm_size, pcm_latch, pcm_clock = 0xF6;
static int16 pcm_addr, pcm_size, pcm_latch, pcm_clock = 0xE1;
static writefunc defapuwrite[64];
static readfunc defapuread[64];
@ -113,7 +113,7 @@ static void CSync(void) {
setchr1(0x1800 ^ cswap, block | (bank6 & mask));
setchr1(0x1c00 ^ cswap, block | (bank7 & mask));
setmirror((mirror & 1) ^ 1);
setmirror(mirror & 1);
}
static void Sync(void) {
@ -124,7 +124,7 @@ static void Sync(void) {
static DECLFW(UNLOneBusWriteCPU410X) {
// FCEU_printf("CPU %04x:%04x\n",A,V);
switch (A & 0xf) {
case 0x1: IRQLatch = V & 0xfe; break;
case 0x1: IRQLatch = V & 0xfe; break; // íå ïî äàòàøèòó
case 0x2: IRQReload = 1; break;
case 0x3: X6502_IRQEnd(FCEU_IQEXT); IRQa = 0; break;
case 0x4: IRQa = 1; break;
@ -158,7 +158,7 @@ static DECLFW(UNLOneBusWriteMMC3) {
}
break;
}
case 0xa000: mirror = V; CSync(); break;
case 0xa000: mirror = V ^ 1; CSync(); break;
case 0xc000: IRQLatch = V & 0xfe; break;
case 0xc001: IRQReload = 1; break;
case 0xe000: X6502_IRQEnd(FCEU_IQEXT); IRQa = 0; break;
@ -180,17 +180,19 @@ static void UNLOneBusIRQHook(void) {
}
static DECLFW(UNLOneBusWriteAPU40XX) {
// FCEU_printf("APU %04x:%04x\n",A,V);
// if(((A & 0x3f)!=0x16) && ((apu40xx[0x30] & 0x10) || ((A & 0x3f)>0x17)))FCEU_printf("APU %04x:%04x\n",A,V);
apu40xx[A & 0x3f] = V;
switch (A & 0x3f) {
case 0x12:
if (apu40xx[0x30] & 0x10) {
pcm_addr = V << 6;
}
break;
case 0x13:
if (apu40xx[0x30] & 0x10) {
pcm_size = (V << 4) + 1;
}
break;
case 0x15:
if (apu40xx[0x30] & 0x10) {
pcm_enable = V & 0x10;
@ -202,6 +204,7 @@ static DECLFW(UNLOneBusWriteAPU40XX) {
pcm_latch = pcm_clock;
V &= 0xef;
}
break;
}
defapuwrite[A & 0x3f](A, V);
}
@ -214,6 +217,7 @@ static DECLFR(UNLOneBusReadAPU40XX) {
if (apu40xx[0x30] & 0x10) {
result = (result & 0x7f) | pcm_irq;
}
break;
}
return result;
}
@ -229,7 +233,8 @@ static void UNLOneBusCpuHook(int a) {
pcm_enable = 0;
X6502_IRQBegin(FCEU_IQEXT);
} else {
uint8 raw_pcm = ARead[pcm_addr](pcm_addr) >> 1;
uint16 addr = pcm_addr | ((apu40xx[0x30]^3) << 14);
uint8 raw_pcm = ARead[addr](addr) >> 1;
defapuwrite[0x11](0x4011, raw_pcm);
pcm_addr++;
pcm_addr &= 0x7FFF;
@ -281,7 +286,7 @@ void UNLOneBus_Init(CartInfo *info) {
info->Power = UNLOneBusPower;
info->Reset = UNLOneBusReset;
if (((*(uint32*)&(info->MD5)) == 0x305fcdc3) || // PowerJoy Supermax Carts
if (((*(uint32*)&(info->MD5)) == 0x305fcdc3) || // PowerJoy Supermax Carts
((*(uint32*)&(info->MD5)) == 0x6abfce8e))
inv_hack = 0xf;

View File

@ -20,25 +20,27 @@
#include "mapinc.h"
static uint8 reg[7];
static uint8 reg[8];
static uint32 lastnt = 0;
static uint8 *WRAM = NULL;
static uint32 WRAMSIZE;
static SFORMAT StateRegs[] =
{
{ reg, 2, "REG" },
{ &lastnt, 4, "LNT" },
{ 0 }
};
static uint8 bs_tbl[128] = {
0x03, 0x13, 0x23, 0x33, 0x03, 0x13, 0x23, 0x33, 0x03, 0x13, 0x23, 0x33, 0x03, 0x13, 0x23, 0x33,
0x45, 0x67, 0x45, 0x67, 0x45, 0x67, 0x45, 0x67, 0x45, 0x67, 0x45, 0x67, 0x45, 0x67, 0x45, 0x67,
0x03, 0x13, 0x23, 0x33, 0x03, 0x13, 0x23, 0x33, 0x03, 0x13, 0x23, 0x33, 0x03, 0x13, 0x23, 0x33,
0x47, 0x67, 0x47, 0x67, 0x47, 0x67, 0x47, 0x67, 0x47, 0x67, 0x47, 0x67, 0x47, 0x67, 0x47, 0x67,
0x02, 0x12, 0x22, 0x32, 0x02, 0x12, 0x22, 0x32, 0x02, 0x12, 0x22, 0x32, 0x02, 0x12, 0x22, 0x32,
0x45, 0x67, 0x45, 0x67, 0x45, 0x67, 0x45, 0x67, 0x45, 0x67, 0x45, 0x67, 0x45, 0x67, 0x45, 0x67,
0x02, 0x12, 0x22, 0x32, 0x02, 0x12, 0x22, 0x32, 0x02, 0x12, 0x22, 0x32, 0x00, 0x10, 0x20, 0x30,
0x47, 0x67, 0x47, 0x67, 0x47, 0x67, 0x47, 0x67, 0x47, 0x67, 0x47, 0x67, 0x47, 0x67, 0x47, 0x67,
0x03, 0x13, 0x23, 0x33, 0x03, 0x13, 0x23, 0x33, 0x03, 0x13, 0x23, 0x33, 0x03, 0x13, 0x23, 0x33, // 00
0x45, 0x67, 0x45, 0x67, 0x45, 0x67, 0x45, 0x67, 0x45, 0x67, 0x45, 0x67, 0x45, 0x67, 0x45, 0x67, // 10
0x03, 0x13, 0x23, 0x33, 0x03, 0x13, 0x23, 0x33, 0x03, 0x13, 0x23, 0x33, 0x03, 0x13, 0x23, 0x33, // 20
0x47, 0x67, 0x47, 0x67, 0x47, 0x67, 0x47, 0x67, 0x47, 0x67, 0x47, 0x67, 0x47, 0x67, 0x47, 0x67, // 30
0x02, 0x12, 0x22, 0x32, 0x02, 0x12, 0x22, 0x32, 0x02, 0x12, 0x22, 0x32, 0x02, 0x12, 0x22, 0x32, // 40
0x45, 0x67, 0x45, 0x67, 0x45, 0x67, 0x45, 0x67, 0x45, 0x67, 0x45, 0x67, 0x45, 0x67, 0x45, 0x67, // 50
0x02, 0x12, 0x22, 0x32, 0x02, 0x12, 0x22, 0x32, 0x02, 0x12, 0x22, 0x32, 0x00, 0x10, 0x20, 0x30, // 60
0x47, 0x67, 0x47, 0x67, 0x47, 0x67, 0x47, 0x67, 0x47, 0x67, 0x47, 0x67, 0x47, 0x67, 0x47, 0x67, // 70
};
static uint8 br_tbl[16] = {
@ -46,48 +48,60 @@ static uint8 br_tbl[16] = {
};
static void Sync(void) {
// setchr4(0x0000,(reg[0]&0x80) >> 7);
// setchr4(0x1000,(reg[0]&0x80) >> 7);
setchr8(0);
setprg8r(0x10, 0x6000, 0);
setprg16(0x8000, bs_tbl[reg[0] & 0x7f] >> 4);
setprg16(0xc000, bs_tbl[reg[0] & 0x7f] & 0xf);
setmirror(MI_V);
if(PRGsize[0] == 512 * 1024) {
if(reg[0] & 0x010) {
setprg32(0x8000, reg[0] & 7);
} else {
if(reg[0] & 0x40)
setprg8(0x8000, (reg[0] & 0x0F) | 0x20 | ((reg[0] & 0x20) >> 1));
}
if((reg[0] & 0x18) == 0x18)
setmirror(MI_H);
else
setmirror(MI_V);
} else {
setprg16(0x8000, bs_tbl[reg[0] & 0x7f] >> 4);
setprg16(0xc000, bs_tbl[reg[0] & 0x7f] & 0xf);
setmirror(MI_V);
}
}
static DECLFW(UNLPEC586Write) {
reg[(A & 0x700) >> 8] = V;
FCEU_printf("bs %04x %02x\n", A, V);
PEC586Hack = (reg[0] & 0x80) >> 7;
// FCEU_printf("bs %04x %02x\n", A, V);
Sync();
}
static DECLFR(UNLPEC586Read) {
FCEU_printf("read %04x\n", A);
// FCEU_printf("read %04x\n", A);
return (X.DB & 0xD8) | br_tbl[reg[4] >> 4];
}
static void UNLPEC586Power(void) {
reg[0] = 0x0E;
Sync();
setchr8(0);
SetReadHandler(0x6000, 0x7FFF, CartBR);
SetWriteHandler(0x6000, 0x7FFF, CartBW);
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x5000, 0x5fff, UNLPEC586Write);
SetReadHandler(0x5000, 0x5fff, UNLPEC586Read);
static DECLFR(UNLPEC586ReadHi) {
if((reg[0] & 0x10) || ((reg[0] & 0x40) && (A < 0xA000)))
return CartBR(A);
else
return PRGptr[0][((0x0107 | ((A >> 7) & 0x0F8)) << 10) | (A & 0x3FF)];
}
static void UNLPEC586IRQ(void) {
// if(reg[0]&0x80)
{
if (scanline == 128) {
setchr4(0x0000, 1);
setchr4(0x1000, 0);
} else {
setchr4(0x0000, 0);
setchr4(0x1000, 1);
}
}
static void UNLPEC586Power(void) {
if(PRGsize[0] == 512 * 1024)
reg[0] = 0x00;
else
reg[0] = 0x0E;
Sync();
SetReadHandler(0x6000, 0x7FFF, CartBR);
SetWriteHandler(0x6000, 0x7FFF, CartBW);
if(PRGsize[0] == 512 * 1024)
SetReadHandler(0x8000, 0xFFFF, UNLPEC586ReadHi);
else
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x5000, 0x5fff, UNLPEC586Write);
SetReadHandler(0x5000, 0x5fff, UNLPEC586Read);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
}
static void UNLPEC586Close(void) {
@ -103,7 +117,6 @@ static void StateRestore(int version) {
void UNLPEC586Init(CartInfo *info) {
info->Power = UNLPEC586Power;
info->Close = UNLPEC586Close;
GameHBIRQHook = UNLPEC586IRQ;
GameStateRestore = StateRestore;
WRAMSIZE = 8192;

View File

@ -0,0 +1,195 @@
/* FCE Ultra - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 2014 CaH4e3
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "mapinc.h"
static uint8 preg[8];
static uint8 IRQa;
static int16 IRQCount, IRQLatch;
static uint8 *WRAM = NULL;
static uint32 WRAMSIZE;
/*
static uint8 *CHRRAM = NULL;
static uint32 CHRRAMSIZE;
*/
static SFORMAT StateRegs[] =
{
{ preg, 8, "PREG" },
{ &IRQa, 1, "IRQA" },
{ &IRQCount, 2, "IRQC" },
{ &IRQLatch, 2, "IRQL" },
{ 0 }
};
static void Sync(void) {
setchr8(0);
setprg8r(0x10, 0x6000, 0);
if(preg[0] & 0x80)
setprg4r(0x10,0x8000,preg[0] & 0x7f);
else
setprg4(0x8000,preg[0] & 0x7f);
if(preg[1] & 0x80)
setprg4r(0x10,0x9000,preg[1] & 0x7f);
else
setprg4(0x9000,preg[1] & 0x7f);
if(preg[2] & 0x80)
setprg4r(0x10,0xa000,preg[2] & 0x7f);
else
setprg4(0xa000,preg[2] & 0x7f);
if(preg[3] & 0x80)
setprg4r(0x10,0xb000,preg[3] & 0x7f);
else
setprg4(0xb000,preg[3] & 0x7f);
/*
if(preg[4] & 0x80)
setprg4r(0x10,0xc000,preg[4] & 0x7f);
else
setprg4(0xc000,preg[4] & 0x7f);
if(preg[5] & 0x80)
setprg4r(0x10,0xd000,preg[5] & 0x7f);
else
setprg4(0xd000,preg[5] & 0x7f);
if(preg[6] & 0x80)
setprg4r(0x10,0xe000,preg[6] & 0x7f);
else
setprg4(0xe000,preg[6] & 0x7f);
if(preg[7] & 0x80)
setprg4r(0x10,0xf000,preg[7] & 0x7f);
else
setprg4(0xf000,preg[7] & 0x7f);
*/
setprg16(0xC000,1);
}
static DECLFR(UNLSB2000Read) {
switch(A) {
case 0x4033: // IRQ flags
X6502_IRQEnd(FCEU_IQFCOUNT);
return 0xff;
// case 0x4204: // unk
// return 0xff;
// case 0x4205: // unk
// return 0xff;
default:
FCEU_printf("unk read: %04x\n",A);
// break;
return 0xff; // needed to prevent C4715 warning?
}
}
static DECLFW(UNLSB2000Write) {
switch(A) {
case 0x4027: // PCM output
BWrite[0x4015](0x4015, 0x10);
BWrite[0x4011](0x4011, V >> 1);
break;
case 0x4032: // IRQ mask
IRQa &= ~V;
// X6502_IRQEnd(FCEU_IQEXT);
break;
case 0x4040:
case 0x4041:
case 0x4042:
case 0x4043:
case 0x4044:
case 0x4045:
case 0x4046:
case 0x4047:
// FCEU_printf("bank write: %04x:%02x\n",A,V);
preg[A&7] = V;
Sync();
break;
default:
// FCEU_printf("unk write: %04x:%02x\n",A,V);
break;
}
}
static void UNLSB2000Reset(void) {
preg[0] = 0;
preg[1] = 1;
preg[2] = 2;
preg[3] = 3;
preg[4] = 4;
preg[5] = 5;
preg[6] = 6;
preg[7] = 7;
IRQa = 0;
// BWrite[0x4017](0x4017,0xC0);
// BWrite[0x4015](0x4015,0x1F);
}
static void UNLSB2000Power(void) {
UNLSB2000Reset();
Sync();
SetReadHandler(0x6000, 0x7fff, CartBR);
SetWriteHandler(0x6000, 0x7fff, CartBW);
SetReadHandler(0x8000, 0xffff, CartBR);
SetWriteHandler(0x8000, 0xbfff, CartBW);
SetWriteHandler(0x4020, 0x5fff, UNLSB2000Write);
SetReadHandler(0x4020, 0x5fff, UNLSB2000Read);
}
static void UNLSB2000Close(void)
{
if (WRAM)
FCEU_gfree(WRAM);
/*
if (CHRRAM)
FCEU_gfree(CHRRAM);
*/
WRAM = /*CHRRAM = */NULL;
}
/*
static void UNLSB2000IRQHook() {
X6502_IRQBegin(FCEU_IQEXT);
}
*/
static void StateRestore(int version) {
Sync();
}
void UNLSB2000_Init(CartInfo *info) {
info->Reset = UNLSB2000Reset;
info->Power = UNLSB2000Power;
info->Close = UNLSB2000Close;
// GameHBIRQHook = UNLSB2000IRQHook;
GameStateRestore = StateRestore;
/*
CHRRAMSIZE = 8192;
CHRRAM = (uint8*)FCEU_gmalloc(CHRRAMSIZE);
SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSIZE, 1);
AddExState(CHRRAM, CHRRAMSIZE, 0, "CRAM");
*/
// SetupCartCHRMapping(0, PRGptr[0], PRGsize[0], 0);
WRAMSIZE = 512 * 1024;
WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE);
SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1);
AddExState(WRAM, WRAMSIZE, 0, "WRAM");
if (info->battery) {
info->SaveGame[0] = WRAM;
info->SaveGameLen[0] = WRAMSIZE;
}
AddExState(&StateRegs, ~0, 0, 0);
}

View File

@ -31,16 +31,18 @@ static SFORMAT StateRegs[] =
{
{ reg, 8, "REGS" },
{ chr, 8, "CHRS" },
{ &IRQCount, 16, "IRQc" },
{ &IRQa, 16, "IRQa" },
{ &IRQCount, 2, "IRQc" },
{ &IRQa, 2, "IRQa" },
{ 0 }
};
static void Sync(void) {
int i;
setprg8r(0x10, 0x6000, 0);
setprg8(0x8000, reg[0]);
setprg8(0xA000, reg[1]);
setprg8(0xC000, reg[2]);
setprg8(0xE000, ~0);
for (i = 0; i < 8; i++)
setchr1(i << 10, chr[i]);
setmirror(reg[3] ^ 1);
@ -67,20 +69,26 @@ static DECLFW(UNLSC127Write) {
Sync();
}
static DECLFR(UNLSC127ProtRead) {
return 0x20;
}
static void UNLSC127Power(void) {
IRQCount = IRQa = 0;
Sync();
setprg8r(0x10, 0x6000, 0);
setprg8(0xE000, ~0);
SetReadHandler(0x5800, 0x5800, UNLSC127ProtRead);
SetReadHandler(0x6000, 0x7fff, CartBR);
SetWriteHandler(0x6000, 0x7fff, CartBW);
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x8000, 0xFFFF, UNLSC127Write);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
}
static void UNLSC127IRQ(void) {
if (IRQa) {
IRQCount--;
if (IRQCount == 0) {
if(IRQCount > 0)
IRQCount--;
if (!IRQCount) {
X6502_IRQBegin(FCEU_IQEXT);
IRQa = 0;
}
@ -88,6 +96,7 @@ static void UNLSC127IRQ(void) {
}
static void UNLSC127Reset(void) {
IRQCount = IRQa = 0;
}
static void UNLSC127Close(void) {

View File

@ -21,45 +21,67 @@
#include "mapinc.h"
static uint8 cmd0, cmd1;
static SFORMAT StateRegs[] =
{
{ &cmd0, 1, "L1" },
{ &cmd1, 1, "L2" },
{ 0 }
};
static void DoSuper(void) {
setprg8r((cmd0 & 0xC) >> 2, 0x6000, ((cmd0 & 0x3) << 4) | 0xF);
static void Sync(void) {
setchr8(0);
if (PRGptr[1])
setprg8r((cmd0 & 0xC) >> 2, 0x6000, ((cmd0 & 0x3) << 4) | 0xF);
else
setprg8(0x6000, (((cmd0 & 0xF) << 4) | 0xF) + 4);
if (cmd0 & 0x10) {
setprg16r((cmd0 & 0xC) >> 2, 0x8000, ((cmd0 & 0x3) << 3) | (cmd1 & 7));
setprg16r((cmd0 & 0xC) >> 2, 0xc000, ((cmd0 & 0x3) << 3) | 7);
if (PRGptr[1]) {
setprg16r((cmd0 & 0xC) >> 2, 0x8000, ((cmd0 & 0x3) << 3) | (cmd1 & 7));
setprg16r((cmd0 & 0xC) >> 2, 0xc000, ((cmd0 & 0x3) << 3) | 7);
} else {
setprg16(0x8000, (((cmd0 & 0xF) << 3) | (cmd1 & 7)) + 2);
setprg16(0xc000, (((cmd0 & 0xF) << 3) | 7) + 2);
}
} else
setprg32r(4, 0x8000, 0);
if (PRGptr[4])
setprg32r(4, 0x8000, 0);
else
setprg32(0x8000, 0);
setmirror(((cmd0 & 0x20) >> 5) ^ 1);
}
static DECLFW(SuperWrite) {
static DECLFW(SuperWriteLo) {
if (!(cmd0 & 0x10)) {
cmd0 = V;
DoSuper();
Sync();
}
}
static DECLFW(SuperHi) {
static DECLFW(SuperWriteHi) {
cmd1 = V;
DoSuper();
Sync();
}
static void SuperPower(void) {
SetWriteHandler(0x6000, 0x7FFF, SuperWriteLo);
SetWriteHandler(0x8000, 0xFFFF, SuperWriteHi);
SetReadHandler(0x6000, 0xFFFF, CartBR);
cmd0 = cmd1 = 0;
Sync();
}
static void SuperReset(void) {
SetWriteHandler(0x6000, 0x7FFF, SuperWrite);
SetWriteHandler(0x8000, 0xFFFF, SuperHi);
SetReadHandler(0x6000, 0xFFFF, CartBR);
cmd0 = cmd1 = 0;
setprg32r(4, 0x8000, 0);
setchr8(0);
Sync();
}
static void SuperRestore(int version) {
DoSuper();
Sync();
}
void Supervision16_Init(CartInfo *info) {
AddExState(&cmd0, 1, 0, "L1");
AddExState(&cmd1, 1, 0, "L2");
info->Power = SuperReset;
info->Power = SuperPower;
info->Reset = SuperReset;
GameStateRestore = SuperRestore;
AddExState(&StateRegs, ~0, 0, 0);
}

View File

@ -20,26 +20,28 @@
#include "mapinc.h"
static uint8 bank, base, lock, mirr;
static uint8 bank, base, lock, mirr, mode;
static SFORMAT StateRegs[] =
{
{ &bank, 1, "BANK" },
{ &base, 1, "BASE" },
{ &lock, 1, "LOCK" },
{ &mirr, 1, "MIRR" },
{ &mode, 1, "MODE" },
{ 0 }
};
static void Sync(void) {
setchr8(0);
setprg16(0x8000, base | bank);
setprg16(0xC000, base | 7);
setprg16(0xC000, base | (mode ? bank : 7));
setmirror(mirr);
}
static DECLFW(BMCT262Write) {
if (!lock) {
base = ((A & 0x60) >> 2) | ((A & 0x100) >> 3);
mode = A & 0x80;
mirr = ((A & 2) >> 1) ^ 1;
lock = (A & 0x2000) >> 13;
}
@ -48,14 +50,14 @@ static DECLFW(BMCT262Write) {
}
static void BMCT262Power(void) {
lock = bank = base = 0;
lock = bank = base = mode = 0;
Sync();
SetWriteHandler(0x8000, 0xFFFF, BMCT262Write);
SetReadHandler(0x8000, 0xFFFF, CartBR);
}
static void BMCT262Reset(void) {
lock = bank = base = 0;
lock = bank = base = mode = 0;
Sync();
}

View File

@ -71,6 +71,7 @@ static void TransformerPower(void) {
SetReadHandler(0x6000, 0x7FFF, CartBR);
SetWriteHandler(0x6000, 0x7FFF, CartBW);
SetReadHandler(0x8000, 0xFFFF, CartBR);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
MapIRQHook = TransformerIRQHook;
}

View File

@ -0,0 +1,269 @@
/* FCE Ultra - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 2014 CaitSith2
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* Roms still using NES 1.0 format should be loaded as 32K CHR RAM.
* Roms defined under NES 2.0 should use the VRAM size field, defining 7, 8 or 9, based on how much VRAM should be present.
* UNIF doesn't have this problem, because unique board names can define this information.
* The UNIF names are UNROM-512-8K, UNROM-512-16K and UNROM-512-32K
*
* The battery flag in the NES header enables flash, Mirrror mode 2 Enables MI_0 and MI_1 mode.
* Known games to use this board are:
* Battle Kid 2: Mountain of Torment (512K PRG, 8K CHR RAM, Horizontal Mirroring, Flash disabled)
* Study Hall (128K PRG (in 512K flash chip), 8K CHR RAM, Horizontal Mirroring, Flash enabled)
* Although Xmas 2013 uses a different board, where LEDs can be controlled (with writes to the $8000-BFFF space),
* it otherwise functions identically.
*/
#include "mapinc.h"
#include "../ines.h"
static uint8 latche, latcheinit, bus_conflict, chrram_mask, software_id=false;
static uint16 latcha;
static uint8 *flashdata;
static uint32 *flash_write_count;
static uint8 *FlashPage[32];
static uint32 *FlashWriteCountPage[32];
static uint8 flashloaded = false;
static uint8 flash_save=0, flash_state=0, flash_mode=0, flash_bank;
static void (*WLSync)(void);
static void (*WHSync)(void);
static INLINE void setfpageptr(int s, uint32 A, uint8 *p) {
uint32 AB = A >> 11;
int x;
if (p)
for (x = (s >> 1) - 1; x >= 0; x--) {
FlashPage[AB + x] = p - A;
}
else
for (x = (s >> 1) - 1; x >= 0; x--) {
FlashPage[AB + x] = 0;
}
}
void setfprg16(uint32 A, uint32 V) {
if (PRGsize[0] >= 16384) {
V &= PRGmask16[0];
setfpageptr(16, A, flashdata ? (&flashdata[V << 14]) : 0);
} else {
uint32 VA = V << 3;
int x;
for (x = 0; x < 8; x++)
setfpageptr(2, A + (x << 11), flashdata ? (&flashdata[((VA + x) & PRGmask2[0]) << 11]) : 0);
}
}
void inc_flash_write_count(uint8 bank, uint32 A)
{
flash_write_count[(bank*4) + ((A&0x3000)>>12)]++;
if(!flash_write_count[(bank*4) + ((A&0x3000)>>12)])
flash_write_count[(bank*4) + ((A&0x3000)>>12)]++;
}
uint32 GetFlashWriteCount(uint8 bank, uint32 A)
{
return flash_write_count[(bank*4) + ((A&0x3000)>>12)];
}
static void StateRestore(int version) {
WHSync();
}
static DECLFW(UNROM512LLatchWrite)
{
latche = V;
latcha = A;
WLSync();
}
static DECLFW(UNROM512HLatchWrite)
{
if (bus_conflict)
latche = (V == CartBR(A)) ? V : 0;
else
latche = V;
latcha = A;
WHSync();
}
static DECLFR(UNROM512LatchRead)
{
uint8 flash_id[3]={0xB5,0xB6,0xB7};
if(software_id)
{
if(A&1)
return flash_id[ROM_size>>4];
else
return 0xBF;
}
if(flash_save)
{
if(A < 0xC000)
{
if(GetFlashWriteCount(flash_bank,A))
return FlashPage[A >> 11][A];
}
else
{
if(GetFlashWriteCount(ROM_size-1,A))
return FlashPage[A >> 11][A];
}
}
return Page[A >> 11][A];
}
static void UNROM512LatchPower(void) {
latche = latcheinit;
WHSync();
SetReadHandler(0x8000, 0xFFFF, UNROM512LatchRead);
if(!flash_save)
SetWriteHandler(0x8000, 0xFFFF, UNROM512HLatchWrite);
else
{
SetWriteHandler(0x8000,0xBFFF,UNROM512LLatchWrite);
SetWriteHandler(0xC000,0xFFFF,UNROM512HLatchWrite);
}
}
static void UNROM512LatchClose(void) {
if(flash_write_count)
FCEU_gfree(flash_write_count);
if(flashdata)
FCEU_gfree(flashdata);
flash_write_count = NULL;
flashdata = NULL;
}
static void UNROM512LSync() {
int erase_a[5]={0x9555,0xAAAA,0x9555,0x9555,0xAAAA};
int erase_d[5]={0xAA,0x55,0x80,0xAA,0x55};
int erase_b[5]={1,0,1,1,0};
if(flash_mode==0)
{
if((latcha == erase_a[flash_state]) && (latche == erase_d[flash_state]) && (flash_bank == erase_b[flash_state]))
{
flash_state++;
if(flash_state == 5)
{
flash_mode=1;
}
}
else if ((flash_state==2)&&(latcha==0x9555)&&(latche==0xA0)&&(flash_bank==1))
{
flash_state++;
flash_mode=2;
}
else if ((flash_state==2)&&(latcha==0x9555)&&(latche==0x90)&&(flash_bank==1))
{
flash_state=0;
software_id=true;
}
else
{
if(latche==0xF0)
software_id=false;
flash_state=0;
}
}
else if(flash_mode==1) //Chip Erase or Sector Erase
{
if(latche==0x30)
{
inc_flash_write_count(flash_bank,latcha);
memset(&FlashPage[(latcha & 0xF000) >> 11][latcha & 0xF000],0xFF,0x1000);
}
else if (latche==0x10)
{
for(int i=0;i<(ROM_size*4);i++)
inc_flash_write_count(i>>2,i<<12);
memset(flashdata,0xFF,ROM_size*0x4000); //Erasing the rom chip as instructed. Crash rate calulated to be 99.9% :)
}
flash_state=0;
flash_mode=0;
}
else if(flash_mode==2) //Byte Program
{
if(!GetFlashWriteCount(flash_bank,latcha))
{
inc_flash_write_count(flash_bank,latcha);
memcpy(&FlashPage[(latcha & 0xF000) >> 11][latcha & 0xF000],&Page[(latcha & 0xF000)>>11][latcha & 0xF000],0x1000);
}
FlashPage[latcha>>11][latcha]&=latche;
flash_state=0;
flash_mode=0;
}
}
static void UNROM512HSync()
{
flash_bank=latche&(ROM_size-1);
setprg16(0x8000, flash_bank);
setprg16(0xc000, ~0);
setfprg16(0x8000, flash_bank);
setfprg16(0xC000, ~0);
setchr8r(0, (latche & chrram_mask) >> 5);
setmirror(MI_0+(latche>>7));
}
void UNROM512_Init(CartInfo *info) {
flash_state=0;
flash_bank=0;
flash_save=info->battery;
if(info->vram_size == 8192)
chrram_mask = 0;
else if (info->vram_size == 16384)
chrram_mask = 0x20;
else
chrram_mask = 0x60;
SetupCartMirroring(info->mirror,(info->mirror>=MI_0)?0:1,0);
bus_conflict = !info->battery;
latcheinit = 0;
WLSync = UNROM512LSync;
WHSync = UNROM512HSync;
info->Power = UNROM512LatchPower;
info->Close = UNROM512LatchClose;
GameStateRestore = StateRestore;
if(flash_save)
{
flashdata = (uint8*)FCEU_gmalloc(ROM_size*0x4000);
flash_write_count = (uint32*)FCEU_gmalloc(ROM_size*4*sizeof(uint32));
info->SaveGame[0] = (uint8*)flash_write_count;
info->SaveGame[1] = flashdata;
info->SaveGameLen[0] = ROM_size*4*sizeof(uint32);
info->SaveGameLen[1] = ROM_size*0x4000;
AddExState(flash_write_count,ROM_size*4*sizeof(uint32),0,"FLASH_WRITE_COUNT");
AddExState(flashdata,ROM_size*0x4000,0,"FLASH_DATA");
AddExState(&flash_state,1,0,"FLASH_STATE");
AddExState(&flash_mode,1,0,"FLASH_MODE");
AddExState(&flash_bank,1,0,"FLASH_BANK");
AddExState(&latcha,2,0,"LATA");
}
AddExState(&latche, 1, 0, "LATC");
AddExState(&bus_conflict, 1, 0, "BUSC");
}

View File

@ -169,6 +169,7 @@ static void M23Power(void) {
SetWriteHandler(0x6000, 0x7FFF, CartBW);
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x8000, 0xFFFF, M23Write);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
}
static void M25Power(void) {
@ -179,6 +180,7 @@ static void M25Power(void) {
SetWriteHandler(0x6000, 0x7FFF, CartBW);
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x8000, 0xFFFF, M22Write);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
}
void VRC24IRQHook(int a) {

View File

@ -106,6 +106,7 @@ static void M73Power(void) {
SetReadHandler(0x6000, 0xFFFF, CartBR);
SetWriteHandler(0x6000, 0x7FFF, CartBW);
SetWriteHandler(0x8000, 0xFFFF, M73Write);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
}
static void M73Close(void)

View File

@ -1,225 +1,226 @@
/* FCE Ultra - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 2005 CaH4e3
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* VRC-5 (CAI Shogakko no Sansu)
*
*/
#include "mapinc.h"
static uint8 QTAINTRAM[2048];
static writefunc old2007wrap;
static uint16 CHRSIZE = 8192;
static uint16 WRAMSIZE = 8192 + 4096;
static uint8 *CHRRAM = NULL;
static uint8 *WRAM = NULL;
static uint8 IRQa, K4IRQ;
static uint32 IRQLatch, IRQCount;
static uint8 regs[16];
//static uint8 test[8];
static SFORMAT StateRegs[] =
{
{ &IRQCount, 1, "IRQC" },
{ &IRQLatch, 1, "IRQL" },
{ &IRQa, 1, "IRQA" },
{ &K4IRQ, 1, "KIRQ" },
{ regs, 16, "REGS" },
{ 0 }
};
static void chrSync(void) {
setchr4r(0x10, 0x0000, regs[5] & 1);
setchr4r(0x10, 0x1000, 0);
}
static void Sync(void) {
chrSync();
// if(regs[0xA]&0x10)
// {
/* setchr1r(0x10,0x0000,(((regs[5]&1))<<2)+0);
setchr1r(0x10,0x0400,(((regs[5]&1))<<2)+1);
setchr1r(0x10,0x0800,(((regs[5]&1))<<2)+2);
setchr1r(0x10,0x0c00,(((regs[5]&1))<<2)+3);
setchr1r(0x10,0x1000,0);
setchr1r(0x10,0x1400,1);
setchr1r(0x10,0x1800,2);
setchr1r(0x10,0x1c00,3);*/
/* setchr1r(0x10,0x0000,(((regs[5]&1))<<2)+0);
setchr1r(0x10,0x0400,(((regs[5]&1))<<2)+1);
setchr1r(0x10,0x0800,(((regs[5]&1))<<2)+2);
setchr1r(0x10,0x0c00,(((regs[5]&1))<<2)+3);
setchr1r(0x10,0x1000,(((regs[5]&1)^1)<<2)+4);
setchr1r(0x10,0x1400,(((regs[5]&1)^1)<<2)+5);
setchr1r(0x10,0x1800,(((regs[5]&1)^1)<<2)+6);
setchr1r(0x10,0x1c00,(((regs[5]&1)^1)<<2)+7);
*/
// }
// else
// {
/*
setchr1r(0x10,0x0000,(((regs[5]&1)^1)<<2)+0);
setchr1r(0x10,0x0400,(((regs[5]&1)^1)<<2)+1);
setchr1r(0x10,0x0800,(((regs[5]&1)^1)<<2)+2);
setchr1r(0x10,0x0c00,(((regs[5]&1)^1)<<2)+3);
setchr1r(0x10,0x1000,(((regs[5]&1))<<2)+4);
setchr1r(0x10,0x1400,(((regs[5]&1))<<2)+5);
setchr1r(0x10,0x1800,(((regs[5]&1))<<2)+6);
setchr1r(0x10,0x1c00,(((regs[5]&1))<<2)+7);
// }
//*/
/* setchr1r(1,0x0000,test[0]);
setchr1r(1,0x0400,test[1]);
setchr1r(1,0x0800,test[2]);
setchr1r(1,0x0c00,test[3]);
setchr1r(1,0x1000,test[4]);
setchr1r(1,0x1400,test[5]);
setchr1r(1,0x1800,test[6]);
setchr1r(1,0x1c00,test[7]);
*/
setprg4r(0x10, 0x6000, regs[0] & 1);
if (regs[2] >= 0x40)
setprg8r(1, 0x8000, (regs[2] - 0x40));
else
setprg8r(0, 0x8000, (regs[2] & 0x3F));
if (regs[3] >= 0x40)
setprg8r(1, 0xA000, (regs[3] - 0x40));
else
setprg8r(0, 0xA000, (regs[3] & 0x3F));
if (regs[4] >= 0x40)
setprg8r(1, 0xC000, (regs[4] - 0x40));
else
setprg8r(0, 0xC000, (regs[4] & 0x3F));
setprg8r(1, 0xE000, ~0);
setmirror(MI_V);
}
/*static DECLFW(TestWrite)
{
test[A&7] = V;
Sync();
}*/
static DECLFW(M190Write) {
// FCEU_printf("write %04x:%04x %d, %d\n",A,V,scanline,timestamp);
regs[(A & 0x0F00) >> 8] = V;
switch (A) {
case 0xd600: IRQLatch &= 0xFF00; IRQLatch |= V; break;
case 0xd700: IRQLatch &= 0x00FF; IRQLatch |= V << 8; break;
case 0xd900: IRQCount = IRQLatch; IRQa = V & 2; K4IRQ = V & 1; X6502_IRQEnd(FCEU_IQEXT); break;
case 0xd800: IRQa = K4IRQ; X6502_IRQEnd(FCEU_IQEXT); break;
}
Sync();
}
static DECLFR(M190Read) {
// FCEU_printf("read %04x:%04x %d, %d\n",A,regs[(A&0x0F00)>>8],scanline,timestamp);
return regs[(A & 0x0F00) >> 8] + regs[0x0B];
}
static void VRC5IRQ(int a) {
if (IRQa) {
IRQCount += a;
if (IRQCount & 0x10000) {
X6502_IRQBegin(FCEU_IQEXT);
IRQCount = IRQLatch;
}
}
}
//static void Mapper190_PPU(uint32 A)
//{
// if(A<0x2000)
// setchr4r(0x10,0x1000,QTAINTRAM[A&0x1FFF]&1);
// else
// chrSync();
//}
static DECLFW(M1902007Wrap) {
if (A >= 0x2000) {
if (regs[0xA] & 1)
QTAINTRAM[A & 0x1FFF] = V;
else
old2007wrap(A, V);
}
}
static void M190Power(void) {
/* test[0]=0;
test[1]=1;
test[2]=2;
test[3]=3;
test[4]=4;
test[5]=5;
test[6]=6;
test[7]=7;
*/
setprg4r(0x10, 0x7000, 2);
old2007wrap = GetWriteHandler(0x2007);
SetWriteHandler(0x2007, 0x2007, M1902007Wrap);
SetReadHandler(0x6000, 0xFFFF, CartBR);
// SetWriteHandler(0x5000,0x5007,TestWrite);
SetWriteHandler(0x6000, 0x7FFF, CartBW);
SetWriteHandler(0x8000, 0xFFFF, M190Write);
SetReadHandler(0xDC00, 0xDC00, M190Read);
SetReadHandler(0xDD00, 0xDD00, M190Read);
Sync();
}
static void M190Close(void) {
if (CHRRAM)
FCEU_gfree(CHRRAM);
CHRRAM = NULL;
if (WRAM)
FCEU_gfree(WRAM);
WRAM = NULL;
}
static void StateRestore(int version) {
Sync();
}
void Mapper190_Init(CartInfo *info) {
info->Power = M190Power;
info->Close = M190Close;
GameStateRestore = StateRestore;
MapIRQHook = VRC5IRQ;
// PPU_hook=Mapper190_PPU;
CHRRAM = (uint8*)FCEU_gmalloc(CHRSIZE);
SetupCartCHRMapping(0x10, CHRRAM, CHRSIZE, 1);
AddExState(CHRRAM, CHRSIZE, 0, "CRAM");
WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE);
SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1);
AddExState(WRAM, WRAMSIZE, 0, "WRAM");
if (info->battery) {
info->SaveGame[0] = WRAM;
info->SaveGameLen[0] = WRAMSIZE - 4096;
}
AddExState(&StateRegs, ~0, 0, 0);
}
/* FCE Ultra - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 2005 CaH4e3
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* VRC-5 (CAI Shogakko no Sansu)
*
*/
#include "mapinc.h"
static uint8 QTAINTRAM[2048];
static writefunc old2007wrap;
static uint16 CHRSIZE = 8192;
static uint16 WRAMSIZE = 8192 + 4096;
static uint8 *CHRRAM = NULL;
static uint8 *WRAM = NULL;
static uint8 IRQa, K4IRQ;
static uint32 IRQLatch, IRQCount;
static uint8 regs[16];
//static uint8 test[8];
static SFORMAT StateRegs[] =
{
{ &IRQCount, 1, "IRQC" },
{ &IRQLatch, 1, "IRQL" },
{ &IRQa, 1, "IRQA" },
{ &K4IRQ, 1, "KIRQ" },
{ regs, 16, "REGS" },
{ 0 }
};
static void chrSync(void) {
setchr4r(0x10, 0x0000, regs[5] & 1);
setchr4r(0x10, 0x1000, 0);
}
static void Sync(void) {
chrSync();
// if(regs[0xA]&0x10)
// {
/* setchr1r(0x10,0x0000,(((regs[5]&1))<<2)+0);
setchr1r(0x10,0x0400,(((regs[5]&1))<<2)+1);
setchr1r(0x10,0x0800,(((regs[5]&1))<<2)+2);
setchr1r(0x10,0x0c00,(((regs[5]&1))<<2)+3);
setchr1r(0x10,0x1000,0);
setchr1r(0x10,0x1400,1);
setchr1r(0x10,0x1800,2);
setchr1r(0x10,0x1c00,3);*/
/* setchr1r(0x10,0x0000,(((regs[5]&1))<<2)+0);
setchr1r(0x10,0x0400,(((regs[5]&1))<<2)+1);
setchr1r(0x10,0x0800,(((regs[5]&1))<<2)+2);
setchr1r(0x10,0x0c00,(((regs[5]&1))<<2)+3);
setchr1r(0x10,0x1000,(((regs[5]&1)^1)<<2)+4);
setchr1r(0x10,0x1400,(((regs[5]&1)^1)<<2)+5);
setchr1r(0x10,0x1800,(((regs[5]&1)^1)<<2)+6);
setchr1r(0x10,0x1c00,(((regs[5]&1)^1)<<2)+7);
*/
// }
// else
// {
/*
setchr1r(0x10,0x0000,(((regs[5]&1)^1)<<2)+0);
setchr1r(0x10,0x0400,(((regs[5]&1)^1)<<2)+1);
setchr1r(0x10,0x0800,(((regs[5]&1)^1)<<2)+2);
setchr1r(0x10,0x0c00,(((regs[5]&1)^1)<<2)+3);
setchr1r(0x10,0x1000,(((regs[5]&1))<<2)+4);
setchr1r(0x10,0x1400,(((regs[5]&1))<<2)+5);
setchr1r(0x10,0x1800,(((regs[5]&1))<<2)+6);
setchr1r(0x10,0x1c00,(((regs[5]&1))<<2)+7);
// }
//*/
/* setchr1r(1,0x0000,test[0]);
setchr1r(1,0x0400,test[1]);
setchr1r(1,0x0800,test[2]);
setchr1r(1,0x0c00,test[3]);
setchr1r(1,0x1000,test[4]);
setchr1r(1,0x1400,test[5]);
setchr1r(1,0x1800,test[6]);
setchr1r(1,0x1c00,test[7]);
*/
setprg4r(0x10, 0x6000, regs[0] & 1);
if (regs[2] >= 0x40)
setprg8r(1, 0x8000, (regs[2] - 0x40));
else
setprg8r(0, 0x8000, (regs[2] & 0x3F));
if (regs[3] >= 0x40)
setprg8r(1, 0xA000, (regs[3] - 0x40));
else
setprg8r(0, 0xA000, (regs[3] & 0x3F));
if (regs[4] >= 0x40)
setprg8r(1, 0xC000, (regs[4] - 0x40));
else
setprg8r(0, 0xC000, (regs[4] & 0x3F));
setprg8r(1, 0xE000, ~0);
setmirror(MI_V);
}
/*static DECLFW(TestWrite)
{
test[A&7] = V;
Sync();
}*/
static DECLFW(M190Write) {
// FCEU_printf("write %04x:%04x %d, %d\n",A,V,scanline,timestamp);
regs[(A & 0x0F00) >> 8] = V;
switch (A) {
case 0xd600: IRQLatch &= 0xFF00; IRQLatch |= V; break;
case 0xd700: IRQLatch &= 0x00FF; IRQLatch |= V << 8; break;
case 0xd900: IRQCount = IRQLatch; IRQa = V & 2; K4IRQ = V & 1; X6502_IRQEnd(FCEU_IQEXT); break;
case 0xd800: IRQa = K4IRQ; X6502_IRQEnd(FCEU_IQEXT); break;
}
Sync();
}
static DECLFR(M190Read) {
// FCEU_printf("read %04x:%04x %d, %d\n",A,regs[(A&0x0F00)>>8],scanline,timestamp);
return regs[(A & 0x0F00) >> 8] + regs[0x0B];
}
static void VRC5IRQ(int a) {
if (IRQa) {
IRQCount += a;
if (IRQCount & 0x10000) {
X6502_IRQBegin(FCEU_IQEXT);
IRQCount = IRQLatch;
}
}
}
//static void Mapper190_PPU(uint32 A)
//{
// if(A<0x2000)
// setchr4r(0x10,0x1000,QTAINTRAM[A&0x1FFF]&1);
// else
// chrSync();
//}
static DECLFW(M1902007Wrap) {
if (A >= 0x2000) {
if (regs[0xA] & 1)
QTAINTRAM[A & 0x1FFF] = V;
else
old2007wrap(A, V);
}
}
static void M190Power(void) {
/* test[0]=0;
test[1]=1;
test[2]=2;
test[3]=3;
test[4]=4;
test[5]=5;
test[6]=6;
test[7]=7;
*/
setprg4r(0x10, 0x7000, 2);
old2007wrap = GetWriteHandler(0x2007);
SetWriteHandler(0x2007, 0x2007, M1902007Wrap);
SetReadHandler(0x6000, 0xFFFF, CartBR);
// SetWriteHandler(0x5000,0x5007,TestWrite);
SetWriteHandler(0x6000, 0x7FFF, CartBW);
SetWriteHandler(0x8000, 0xFFFF, M190Write);
SetReadHandler(0xDC00, 0xDC00, M190Read);
SetReadHandler(0xDD00, 0xDD00, M190Read);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
Sync();
}
static void M190Close(void) {
if (CHRRAM)
FCEU_gfree(CHRRAM);
CHRRAM = NULL;
if (WRAM)
FCEU_gfree(WRAM);
WRAM = NULL;
}
static void StateRestore(int version) {
Sync();
}
void Mapper190_Init(CartInfo *info) {
info->Power = M190Power;
info->Close = M190Close;
GameStateRestore = StateRestore;
MapIRQHook = VRC5IRQ;
// PPU_hook=Mapper190_PPU;
CHRRAM = (uint8*)FCEU_gmalloc(CHRSIZE);
SetupCartCHRMapping(0x10, CHRRAM, CHRSIZE, 1);
AddExState(CHRRAM, CHRSIZE, 0, "CRAM");
WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE);
SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1);
AddExState(WRAM, WRAMSIZE, 0, "WRAM");
if (info->battery) {
info->SaveGame[0] = WRAM;
info->SaveGameLen[0] = WRAMSIZE - 4096;
}
AddExState(&StateRegs, ~0, 0, 0);
}

View File

@ -127,6 +127,7 @@ static void VRC6Power(void) {
SetReadHandler(0x6000, 0xFFFF, CartBR);
SetWriteHandler(0x6000, 0x7FFF, CartBW);
SetWriteHandler(0x8000, 0xFFFF, VRC6Write);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
}
static void VRC6IRQHook(int a) {
@ -245,11 +246,11 @@ static INLINE void DoSQVHQ(int x) {
if (vpsg1[(x << 2) | 0x2] & 0x80) {
if (vpsg1[x << 2] & 0x80) {
for (V = cvbc[x]; V < SOUNDTS; V++)
for (V = cvbc[x]; V < (int)SOUNDTS; V++)
WaveHi[V] += amp;
} else {
int32 thresh = (vpsg1[x << 2] >> 4) & 7;
for (V = cvbc[x]; V < SOUNDTS; V++) {
for (V = cvbc[x]; V < (int)SOUNDTS; V++) {
if (dcount[x] > thresh)
WaveHi[V] += amp;
vcount[x]--;
@ -277,7 +278,7 @@ static void DoSawVHQ(void) {
int32 V;
if (vpsg2[2] & 0x80) {
for (V = cvbc[2]; V < SOUNDTS; V++) {
for (V = cvbc[2]; V < (int)SOUNDTS; V++) {
WaveHi[V] += (((phaseacc >> 3) & 0x1f) << 8) * 6 / 8;
vcount[2]--;
if (vcount[2] <= 0) {

View File

@ -26,6 +26,12 @@ static int32 IRQCount, CycleCount;
static uint8 *WRAM = NULL;
static uint32 WRAMSIZE;
#include "emu2413.h"
static int32 dwave = 0;
static OPLL *VRC7Sound = NULL;
static OPLL **VRC7Sound_saveptr = &VRC7Sound;
static SFORMAT StateRegs[] =
{
{ &vrc7idx, 1, "VRCI" },
@ -37,16 +43,12 @@ static SFORMAT StateRegs[] =
{ &IRQLatch, 1, "IRQL" },
{ &IRQCount, 4, "IRQC" },
{ &CycleCount, 4, "CYCC" },
{ 0 }
{ (void**)VRC7Sound_saveptr, sizeof(*VRC7Sound) | FCEUSTATE_INDIRECT, "VRC7" },
{0}
};
// VRC7 Sound
#include "emu2413.h"
static int32 dwave = 0;
static OPLL *VRC7Sound = NULL;
void DoVRC7Sound(void) {
int32 z, a;
if (FSettings.soundq >= 1)
@ -151,6 +153,7 @@ static void VRC7Power(void) {
SetWriteHandler(0x6000, 0x7FFF, CartBW);
SetReadHandler(0x6000, 0xFFFF, CartBR);
SetWriteHandler(0x8000, 0xFFFF, VRC7Write);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
}
static void VRC7Close(void)

View File

@ -174,6 +174,7 @@ static void M83Power(void) {
SetWriteHandler(0x6000, 0x7fff, CartBW); // Pirate Dragon Ball Z Party [p1] used if for saves instead of seraial EEPROM
SetReadHandler(0x8000, 0xffff, CartBR);
SetWriteHandler(0x8000, 0xffff, M83Write);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
}
static void UNLYOKOReset(void) {

View File

@ -21,10 +21,6 @@
/// \file
/// \brief This file contains all code for coordinating the mapping in of the address space external to the NES.
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include "types.h"
#include "fceu.h"
#include "ppu.h"
@ -37,6 +33,11 @@
#include "utils/memory.h"
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <climits>
uint8 *Page[32], *VPage[8];
uint8 **VPageR = VPage;
uint8 *VPageG[8];
@ -46,8 +47,8 @@ uint8 *MMC5BGVPage[8];
static uint8 PRGIsRAM[32]; /* This page is/is not PRG RAM. */
/* 16 are (sort of) reserved for UNIF/iNES and 16 to map other stuff. */
static int CHRram[32];
static int PRGram[32];
uint8 CHRram[32];
uint8 PRGram[32];
uint8 *PRGptr[32];
uint8 *CHRptr[32];
@ -343,40 +344,48 @@ static uint8 *GENIEROM=0;
void FixGenieMap(void);
// Called when a game(file) is opened successfully.
void FCEU_OpenGenie(void) {
// Called when a game(file) is opened successfully. Returns TRUE on error.
bool FCEU_OpenGenie(void)
{
FILE *fp;
int x;
if (!GENIEROM) {
if (!GENIEROM)
{
char *fn;
if (!(GENIEROM = (uint8*)FCEU_malloc(4096 + 1024))) return;
if (!(GENIEROM = (uint8*)FCEU_malloc(4096 + 1024)))
return true;
fn = strdup(FCEU_MakeFName(FCEUMKF_GGROM, 0, 0).c_str());
fp = FCEUD_UTF8fopen(fn, "rb");
if (!fp) {
FCEU_PrintError("Error opening Game Genie ROM image!");
if (!fp)
{
FCEU_PrintError("Error opening Game Genie ROM image!\nIt should be named \"gg.rom\"!");
free(GENIEROM);
GENIEROM = 0;
return;
return true;
}
if (fread(GENIEROM, 1, 16, fp) != 16) {
if (fread(GENIEROM, 1, 16, fp) != 16)
{
grerr:
FCEU_PrintError("Error reading from Game Genie ROM image!");
free(GENIEROM);
GENIEROM = 0;
fclose(fp);
return;
return true;
}
if (GENIEROM[0] == 0x4E) { /* iNES ROM image */
if (GENIEROM[0] == 0x4E)
{
/* iNES ROM image */
if (fread(GENIEROM, 1, 4096, fp) != 4096)
goto grerr;
if (fseek(fp, 16384 - 4096, SEEK_CUR))
goto grerr;
if (fread(GENIEROM + 4096, 1, 256, fp) != 256)
goto grerr;
} else {
} else
{
if (fread(GENIEROM + 16, 1, 4352 - 16, fp) != (4352 - 16))
goto grerr;
}
@ -384,10 +393,13 @@ void FCEU_OpenGenie(void) {
/* Workaround for the FCE Ultra CHR page size only being 1KB */
for (x = 0; x < 4; x++)
{
memcpy(GENIEROM + 4096 + (x << 8), GENIEROM + 4096, 256);
}
}
geniestage = 1;
return false;
}
/* Called when a game is closed. */

View File

@ -13,6 +13,12 @@ typedef struct {
// that are not really MMC3 but are
// set to mapper 4.
int battery; // Presence of an actual battery.
int ines2;
int submapper; // Submappers as defined by NES 2.0
int wram_size;
int battery_wram_size;
int vram_size;
int battery_vram_size;
uint8 MD5[16];
uint32 CRC32; // Should be set by the iNES/UNIF loading
// code, used by mapper/board code, maybe
@ -34,6 +40,9 @@ DECLFR(CartBROB);
DECLFR(CartBR);
DECLFW(CartBW);
extern uint8 PRGram[32];
extern uint8 CHRram[32];
extern uint8 *PRGptr[32];
extern uint8 *CHRptr[32];
@ -86,6 +95,6 @@ extern int geniestage;
void FCEU_GeniePower(void);
void FCEU_OpenGenie(void);
bool FCEU_OpenGenie(void);
void FCEU_CloseGenie(void);
void FCEU_KillGenie(void);

View File

@ -18,11 +18,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <string>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include "types.h"
#include "x6502.h"
@ -33,6 +28,12 @@
#include "driver.h"
#include "utils/memory.h"
#include <string>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cctype>
using namespace std;
static uint8 *CheatRPtrs[64];
@ -152,6 +153,8 @@ void FCEU_PowerCheats()
numsubcheats=0; /* Quick hack to prevent setting of ancient read addresses. */
RebuildSubCheats();
}
int AddCheatEntry(char *name, uint32 addr, uint8 val, int compare, int status, int type);
static void CheatMemErr(void)
{
FCEUD_PrintError("Error allocating memory for cheat data.");

View File

@ -37,18 +37,21 @@
* Register -> 'A' | 'X' | 'Y' | 'P'
* Flag -> 'N' | 'C' | 'Z' | 'I' | 'B' | 'V'
* PC Bank -> 'K'
* Data Bank -> 'T'
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <ctype.h>
#include "conddebug.h"
#include "types.h"
#include "conddebug.h"
#include "utils/memory.h"
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <cctype>
// hack: this address is used by 'T' condition
uint16 addressOfTheLastAccessedData = 0;
// Next non-whitespace character in string
char next;
@ -137,12 +140,18 @@ int isRegister(char c)
return c == 'A' || c == 'X' || c == 'Y' || c == 'P';
}
// Determines if a character is for bank
int isBank(char c)
// Determines if a character is for PC bank
int isPCBank(char c)
{
return c == 'K';
}
// Determines if a character is for Data bank
int isDataBank(char c)
{
return c == 'T';
}
// Reads a hexadecimal number from str
int getNumber(unsigned int* number, const char** str)
{
@ -229,16 +238,33 @@ Condition* Primitive(const char** str, Condition* c)
return c;
}
else if (isBank(next)) /* PC Bank */
else if (isPCBank(next)) /* PC Bank */
{
if (c->type1 == TYPE_NO)
{
c->type1 = TYPE_BANK;
c->type1 = TYPE_PC_BANK;
c->value1 = next;
}
else
{
c->type2 = TYPE_BANK;
c->type2 = TYPE_PC_BANK;
c->value2 = next;
}
scan(str);
return c;
}
else if (isDataBank(next)) /* Data Bank */
{
if (c->type1 == TYPE_NO)
{
c->type1 = TYPE_DATA_BANK;
c->value1 = next;
}
else
{
c->type2 = TYPE_DATA_BANK;
c->value2 = next;
}

View File

@ -26,7 +26,8 @@
#define TYPE_FLAG 2
#define TYPE_NUM 3
#define TYPE_ADDR 4
#define TYPE_BANK 5
#define TYPE_PC_BANK 5
#define TYPE_DATA_BANK 6
#define OP_NO 0
#define OP_EQ 1
@ -42,6 +43,7 @@
#define OP_OR 11
#define OP_AND 12
extern uint16 addressOfTheLastAccessedData;
//mbg merge 7/18/06 turned into sane c++
struct Condition
{

View File

@ -1,48 +1,47 @@
/// \file
/// \brief Contains methods related to the build configuration
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "types.h"
#include "version.h"
#include "fceu.h"
#include "driver.h"
#include "utils/memory.h"
#include <cstring>
#include <cstdio>
#include <cstdlib>
static char *aboutString = 0;
///returns a string suitable for use in an aboutbox
// returns a string suitable for use in an aboutbox
char *FCEUI_GetAboutString() {
const char *aboutTemplate =
FCEU_NAME_AND_VERSION "\n\n\
Administrators:\n\
zeromus, adelikat, AnS\n\n\
Current Contributors:\n\
punkrockguy318 (Lukas Sabota)\n\
Plombo (Bryan Cain)\n\
qeed, QFox, Shinydoofy, ugetab\n\
CaH4e3, gocha, Acmlm, DWEdit\n\
\n\
FCEUX 2.0:\n\
mz, nitsujrehtona, Lukas Sabota,\n\
SP, Ugly Joe\n\
\n\
Previous versions:\n\
FCE - Bero\n\
FCEU - Xodnizel\n\
FCEU XD - Bbitmaster & Parasyte\n\
FCEU XD SP - Sebastian Porst\n\
FCEU MM - CaH4e3\n\
FCEU TAS - blip & nitsuja\n\
FCEU TAS+ - Luke Gustafson\n\
\n\
FCEUX is dedicated to the fallen heroes\n\
of NES emulation. In Memoriam --\n\
ugetab\n\
\n\
"__TIME__" "__DATE__"\n";
FCEU_NAME_AND_VERSION "\n\n"
"Administrators:\n"
"zeromus, adelikat, AnS\n\n"
"Current Contributors:\n"
"punkrockguy318 (Lukas Sabota)\n"
"CaH4e3, gocha, xhainingx, feos\n"
"\n"
"FCEUX 2.0:\n"
"mz, nitsujrehtona, SP, Ugly Joe,\n"
"Plombo, qeed, QFox, Shinydoofy\n"
"ugetab, Acmlm, DWEdit\n"
"\n"
"Previous versions:\n"
"FCE - Bero\n"
"FCEU - Xodnizel\n"
"FCEU XD - Bbitmaster & Parasyte\n"
"FCEU XD SP - Sebastian Porst\n"
"FCEU MM - CaH4e3\n"
"FCEU TAS - blip & nitsuja\n"
"FCEU TAS+ - Luke Gustafson\n"
"\n"
"FCEUX is dedicated to the fallen heroes\n"
"of NES emulation. In Memoriam --\n"
"ugetab\n"
"\n"
__TIME__ " " __DATE__ "\n";
if(aboutString) return aboutString;

View File

@ -1,9 +1,5 @@
/// \file
/// \brief Implements core debugging facilities
#include <stdlib.h>
#include <string.h>
#include "types.h"
#include "x6502.h"
#include "fceu.h"
@ -15,6 +11,10 @@
#include "x6502abbrev.h"
#include <cstdlib>
#include <cstring>
unsigned int debuggerPageSize = 14;
int vblankScanLines = 0; //Used to calculate scanlines 240-261 (vblank)
int vblankPixel = 0; //Used to calculate the pixels in vblank
@ -232,12 +232,12 @@ int getBank(int offs)
if (GameInfo && GameInfo->type==GIT_NSF)
return addr != -1 ? addr / 0x1000 : -1;
return addr != -1 ? addr / 0x4000 : -1;
return addr != -1 ? addr / (1<<debuggerPageSize) : -1; //formerly, dividing by 0x4000
}
int GetNesFileAddress(int A){
int result;
if((A < 0x8000) || (A > 0xFFFF))return -1;
if((A < 0x6000) || (A > 0xFFFF))return -1;
result = &Page[A>>11][A]-PRGptr[0];
if((result > (int)(PRGsize[0])) || (result < 0))return -1;
else return result+16; //16 bytes for the header remember
@ -263,7 +263,7 @@ uint8 *GetNesCHRPointer(int A){
}
uint8 GetMem(uint16 A) {
if ((A >= 0x2000) && (A < 0x4000)) {
if ((A >= 0x2000) && (A < 0x4000)) // PPU regs and their mirrors
switch (A&7) {
case 0: return PPU[0];
case 1: return PPU[1];
@ -271,16 +271,32 @@ uint8 GetMem(uint16 A) {
case 3: return PPU[3];
case 4: return SPRAM[PPU[3]];
case 5: return XOffset;
case 6: return RefreshAddr&0xFF;
case 6: return FCEUPPU_PeekAddress() & 0xFF;
case 7: return VRAMBuffer;
}
} else if ((A >= 0x4000) && (A < 0x5000)) return 0xFF; // AnS: changed the range, so MMC5 ExRAM can be watched in the Hexeditor
if (GameInfo) return ARead[A](A); //adelikat: 11/17/09: Prevent crash if this is called with no game loaded.
// feos: added more registers
else if ((A >= 0x4000) && (A < 0x4010))
return PSG[A&15];
else if ((A >= 0x4010) && (A < 0x4018))
switch(A&7) {
case 0: return DMCFormat;
case 1: return RawDALatch;
case 2: return DMCAddressLatch;
case 3: return DMCSizeLatch;
case 4: return SpriteDMA;
case 5: return EnabledChannels;
case 6: return RawReg4016;
case 7: return IRQFrameMode;
}
else if ((A >= 0x4018) && (A < 0x5000)) // AnS: changed the range, so MMC5 ExRAM can be watched in the Hexeditor
return 0xFF;
if (GameInfo) //adelikat: 11/17/09: Prevent crash if this is called with no game loaded.
return ARead[A](A);
else return 0;
}
uint8 GetPPUMem(uint8 A) {
uint16 tmp=RefreshAddr&0x3FFF;
uint16 tmp = FCEUPPU_PeekAddress() & 0x3FFF;
if (tmp<0x2000) return VPage[tmp>>10][tmp];
if (tmp>=0x3F00) return PALRAM[tmp&0x1F];
@ -313,7 +329,8 @@ int evaluate(Condition* c)
switch(c->type1)
{
case TYPE_ADDR: value1 = GetMem(value1); break;
case TYPE_BANK: value1 = getBank(_PC); break;
case TYPE_PC_BANK: value1 = getBank(_PC); break;
case TYPE_DATA_BANK: value1 = getBank(addressOfTheLastAccessedData); break;
}
f = value1;
@ -337,7 +354,8 @@ int evaluate(Condition* c)
switch(c->type2)
{
case TYPE_ADDR: value2 = GetMem(value2); break;
case TYPE_BANK: value2 = getBank(_PC); break;
case TYPE_PC_BANK: value2 = getBank(_PC); break;
case TYPE_DATA_BANK: value2 = getBank(addressOfTheLastAccessedData); break;
}
switch (c->op)
@ -370,6 +388,7 @@ int condition(watchpointinfo* wp)
volatile int codecount, datacount, undefinedcount;
unsigned char *cdloggerdata;
unsigned int cdloggerdataSize = 0;
static int indirectnext;
int debug_loggingCD;
@ -402,7 +421,8 @@ void LogCDData(uint8 *opcode, uint16 A, int size) {
for (i = 0; i < size; i++) {
if(cdloggerdata[j+i] & 1)continue; //this has been logged so skip
cdloggerdata[j+i] |= 1;
cdloggerdata[j+i] |=((_PC+i)>>11)&0x0c;
cdloggerdata[j+i] |= ((_PC + i) >> 11) & 0x0c;
cdloggerdata[j+i] |= ((_PC & 0x8000) >> 8) ^ 0x80; // 19/07/14 used last reserved bit, if bit 7 is 1, then code is running from lowe area (6000)
if(indirectnext)cdloggerdata[j+i] |= 0x10;
codecount++;
if(!(cdloggerdata[j+i] & 2))undefinedcount--;
@ -439,15 +459,16 @@ int u; //deleteme
int skipdebug; //deleteme
int numWPs;
bool break_asap = false;
// for CPU cycles and Instructions counters
unsigned long int total_cycles_base = 0;
unsigned long int delta_cycles_base = 0;
uint64 total_cycles_base = 0;
uint64 delta_cycles_base = 0;
bool break_on_cycles = false;
unsigned long int break_cycles_limit = 0;
unsigned long int total_instructions = 0;
unsigned long int delta_instructions = 0;
uint64 break_cycles_limit = 0;
uint64 total_instructions = 0;
uint64 delta_instructions = 0;
bool break_on_instructions = false;
unsigned long int break_instructions_limit = 0;
uint64 break_instructions_limit = 0;
static DebuggerState dbgstate;
@ -455,12 +476,20 @@ DebuggerState &FCEUI_Debugger() { return dbgstate; }
void ResetDebugStatisticsCounters()
{
total_cycles_base = delta_cycles_base = timestampbase + timestamp;
ResetCyclesCounter();
ResetInstructionsCounter();
}
void ResetCyclesCounter()
{
total_cycles_base = delta_cycles_base = timestampbase + (uint64)timestamp;
}
void ResetInstructionsCounter()
{
total_instructions = delta_instructions = 0;
}
void ResetDebugStatisticsDeltaCounters()
{
delta_cycles_base = timestampbase + timestamp;
delta_cycles_base = timestampbase + (uint64)timestamp;
delta_instructions = 0;
}
void IncrementInstructionsCounters()
@ -469,12 +498,13 @@ void IncrementInstructionsCounters()
delta_instructions++;
}
void BreakHit(int bp_num, bool force = false)
void BreakHit(int bp_num, bool force)
{
if(!force) {
if(!force)
{
//check to see whether we fall in any forbid zone
for (int i = 0; i < numWPs; i++) {
for (int i = 0; i < numWPs; i++)
{
watchpointinfo& wp = watchpoint[i];
if(!(wp.flags & WP_F) || !(wp.flags & WP_E))
continue;
@ -509,7 +539,13 @@ static void breakpoint(uint8 *opcode, uint16 A, int size) {
uint8 stackop=0;
uint8 stackopstartaddr,stackopendaddr;
if (break_on_cycles && (timestampbase + timestamp - total_cycles_base > break_cycles_limit))
if (break_asap)
{
break_asap = false;
BreakHit(BREAK_TYPE_LUA, true);
}
if (break_on_cycles && ((timestampbase + (uint64)timestamp - total_cycles_base) > break_cycles_limit))
BreakHit(BREAK_TYPE_CYCLES_EXCEED, true);
if (break_on_instructions && (total_instructions > break_instructions_limit))
BreakHit(BREAK_TYPE_INSTRUCTIONS_EXCEED, true);
@ -588,13 +624,14 @@ static void breakpoint(uint8 *opcode, uint16 A, int size) {
// PPU Mem breaks
if ((watchpoint[i].flags & brk_type) && ((A >= 0x2000) && (A < 0x4000)) && ((A&7) == 7))
{
const uint32 PPUAddr = FCEUPPU_PeekAddress();
if (watchpoint[i].endaddress)
{
if ((watchpoint[i].address <= RefreshAddr) && (watchpoint[i].endaddress >= RefreshAddr))
if ((watchpoint[i].address <= PPUAddr) && (watchpoint[i].endaddress >= PPUAddr))
BreakHit(i);
} else
{
if (watchpoint[i].address == RefreshAddr)
if (watchpoint[i].address == PPUAddr)
BreakHit(i);
}
}
@ -715,19 +752,12 @@ static void breakpoint(uint8 *opcode, uint16 A, int size) {
}
//bbit edited: this is the end of the inserted code
int debug_tracing;
void DebugCycle()
{
uint8 opcode[3] = {0};
uint16 A = 0;
uint16 A = 0, tmp;
int size;
#ifdef WIN32
// since this function is called once for every instruction, we can use it for keeping statistics
IncrementInstructionsCounters();
#endif
if (scanline == 240)
{
vblankScanLines = (PAL?int((double)timestamp / ((double)341 / (double)3.2)):timestamp / 114); //114 approximates the number of timestamps per scanline during vblank. Approx 2508. NTSC: (341 / 3.0) PAL: (341 / 3.2). Uses (3.? * cpu_cycles) / 341.0, and assumes 1 cpu cycle.
@ -760,19 +790,22 @@ void DebugCycle()
{
case 0: break;
case 1:
A = (opcode[1] + _X) & 0xFF;
A = GetMem(A) | (GetMem(A + 1) << 8);
tmp = (opcode[1] + _X) & 0xFF;
A = GetMem(tmp);
tmp = (opcode[1] + _X + 1) & 0xFF;
A |= (GetMem(tmp) << 8);
break;
case 2: A = opcode[1]; break;
case 3: A = opcode[1] | (opcode[2] << 8); break;
case 4: A = (GetMem(opcode[1]) | (GetMem(opcode[1]+1) << 8)) + _Y; break;
case 4: A = (GetMem(opcode[1]) | (GetMem((opcode[1] + 1) & 0xFF) << 8)) + _Y; break;
case 5: A = opcode[1] + _X; break;
case 6: A = (opcode[1] | (opcode[2] << 8)) + _Y; break;
case 7: A = (opcode[1] | (opcode[2] << 8)) + _X; break;
case 8: A = opcode[1] + _Y; break;
}
addressOfTheLastAccessedData = A;
if (numWPs || dbgstate.step || dbgstate.runline || dbgstate.stepout || watchpoint[64].flags || dbgstate.badopbreak || break_on_cycles || break_on_instructions)
if (numWPs || dbgstate.step || dbgstate.runline || dbgstate.stepout || watchpoint[64].flags || dbgstate.badopbreak || break_on_cycles || break_on_instructions || break_asap)
breakpoint(opcode, A, size);
if(debug_loggingCD)

View File

@ -20,6 +20,7 @@
#define BREAK_TYPE_BADOP -2
#define BREAK_TYPE_CYCLES_EXCEED -3
#define BREAK_TYPE_INSTRUCTIONS_EXCEED -4
#define BREAK_TYPE_LUA -5
//opbrktype is used to grab the breakpoint type that each instruction will cause.
//WP_X is not used because ALL opcodes will have the execute bit set.
@ -76,6 +77,7 @@ void LogCDVectors(int which);
void LogCDData(uint8 *opcode, uint16 A, int size);
extern volatile int codecount, datacount, undefinedcount;
extern unsigned char *cdloggerdata;
extern unsigned int cdloggerdataSize;
extern int debug_loggingCD;
static INLINE void FCEUI_SetLoggingCD(int val) { debug_loggingCD = val; }
@ -93,12 +95,28 @@ static INLINE int FCEUI_GetLoggingCD() { return debug_loggingCD; }
extern int iaPC;
extern uint32 iapoffset; //mbg merge 7/18/06 changed from int
void DebugCycle();
void BreakHit(int bp_num, bool force = false);
extern bool break_asap;
extern uint64 total_cycles_base;
extern uint64 delta_cycles_base;
extern bool break_on_cycles;
extern uint64 break_cycles_limit;
extern uint64 total_instructions;
extern uint64 delta_instructions;
extern bool break_on_instructions;
extern uint64 break_instructions_limit;
extern void ResetDebugStatisticsCounters();
extern void ResetCyclesCounter();
extern void ResetInstructionsCounter();
extern void ResetDebugStatisticsDeltaCounters();
extern void IncrementInstructionsCounters();
//-------------
//internal variables that debuggers will want access to
extern uint8 *vnapage[4],*VPage[8];
extern uint8 PPU[4],PALRAM[0x20],SPRAM[0x100],VRAMBuffer,PPUGenLatch,XOffset;
extern uint32 RefreshAddr;
extern uint32 FCEUPPU_PeekAddress();
extern int debug_loggingCD;
extern int numWPs;
@ -130,6 +148,16 @@ public:
extern NSF_HEADER NSFHeader;
extern uint8 PSG[0x10];
extern uint8 DMCFormat;
extern uint8 RawDALatch;
extern uint8 DMCAddressLatch;
extern uint8 DMCSizeLatch;
extern uint8 EnabledChannels;
extern uint8 SpriteDMA;
extern uint8 RawReg4016;
extern uint8 IRQFrameMode;
///retrieves the core's DebuggerState
DebuggerState &FCEUI_Debugger();

View File

@ -7,7 +7,7 @@
static uint8 Font6x7[792] =
{
6, 0, 0, 0, 0, 0, 0, 0,
6, 0, 0, 0, 0, 0, 0, 0, // 0x20 - Spacebar
3, 64, 64, 64, 64, 64, 0, 64,
5, 80, 80, 80, 0, 0, 0, 0,
6, 80, 80,248, 80,248, 80, 80,
@ -23,7 +23,7 @@ static uint8 Font6x7[792] =
5, 0, 0, 0,240, 0, 0, 0,
3, 0, 0, 0, 0, 0, 0, 64,
5, 16, 16, 32, 32, 32, 64, 64,
6,112,136,136,136,136,136,112, //0
6,112,136,136,136,136,136,112, // 0x30 - 0
6, 32, 96, 32, 32, 32, 32, 32,
6,112,136, 8, 48, 64,128,248,
6,112,136, 8, 48, 8,136,112,
@ -38,9 +38,9 @@ static uint8 Font6x7[792] =
4, 0, 32, 64,128, 64, 32, 0,
5, 0, 0,240, 0,240, 0, 0,
4, 0,128, 64, 32, 64,128, 0,
5,112,136, 8, 16, 32, 0, 32,
6,112,136,136,184,176,128,112,
6,112,136,136,248,136,136,136, //A
6,112,136, 8, 16, 32, 0, 32, // 0x3F - ?
6,112,136,136,184,176,128,112, // 0x40 - @
6,112,136,136,248,136,136,136, // 0x41 - A
6,240,136,136,240,136,136,240,
6,112,136,128,128,128,136,112,
6,224,144,136,136,136,144,224,
@ -72,7 +72,7 @@ static uint8 Font6x7[792] =
4, 64,160, 0, 0, 0, 0, 0,
6, 0, 0, 0, 0, 0, 0,248,
3,128, 64, 0, 0, 0, 0, 0,
5, 0, 0, 96, 16,112,144,112, //a
5, 0, 0, 96, 16,112,144,112, // 0x61 - a
5,128,128,224,144,144,144,224,
5, 0, 0,112,128,128,128,112,
5, 16, 16,112,144,144,144,112,
@ -402,10 +402,10 @@ static int JoedCharWidth(uint8 ch)
char target[64][256];
void DrawTextTransWH(uint8 *dest, uint32 width, uint8 *textmsg, uint8 fgcolor, int max_w, int max_h, int border)
void DrawTextTransWH(uint8 *dest, int width, uint8 *textmsg, uint8 fgcolor, int max_w, int max_h, int border)
{
unsigned int beginx=2, x=beginx;
unsigned int y=2;
int beginx=2, x=beginx;
int y=2;
memset(target, 0, 64 * 256);

View File

@ -1,8 +1,6 @@
#include <assert.h>
void DrawTextLineBG(uint8 *dest);
void DrawMessage(bool beforeMovie);
void FCEU_DrawRecordingStatus(uint8* XBuf);
void FCEU_DrawNumberRow(uint8 *XBuf, int *nstatus, int cur);
void DrawTextTrans(uint8 *dest, uint32 width, uint8 *textmsg, uint8 fgcolor);
void DrawTextTransWH(uint8 *dest, uint32 width, uint8 *textmsg, uint8 fgcolor, int max_w, int max_h, int border);
void DrawTextTransWH(uint8 *dest, int width, uint8 *textmsg, uint8 fgcolor, int max_w, int max_h, int border);

View File

@ -1,14 +1,14 @@
#ifndef __DRIVER_H_
#define __DRIVER_H_
#include <stdio.h>
#include <string>
#include <iosfwd>
#include "types.h"
#include "git.h"
#include "file.h"
#include <cstdio>
#include <cstring>
#include <iosfwd>
FILE *FCEUD_UTF8fopen(const char *fn, const char *mode);
inline FILE *FCEUD_UTF8fopen(const std::string &n, const char *mode) { return FCEUD_UTF8fopen(n.c_str(),mode); }
EMUFILE_FILE* FCEUD_UTF8_fstream(const char *n, const char *m);
@ -120,6 +120,10 @@ void FCEUI_SetGameGenie(bool a);
//Set video system a=0 NTSC, a=1 PAL
void FCEUI_SetVidSystem(int a);
//Set variables for NTSC(0) / PAL(1) / Dendy(2)
//Dendy has PAL framerate and resolution, but ~NTSC timings, and has 50 dummy scanlines to force 50 fps
void FCEUI_SetRegion(int region);
//Convenience function; returns currently emulated video system(0=NTSC, 1=PAL).
int FCEUI_GetCurrentVidSystem(int *slstart, int *slend);
@ -161,8 +165,8 @@ int FCEUI_SelectState(int, int);
extern void FCEUI_SelectStateNext(int);
//"fname" overrides the default save state filename code if non-NULL.
void FCEUI_SaveState(const char *fname);
void FCEUI_LoadState(const char *fname);
void FCEUI_SaveState(const char *fname, bool display_message=true);
void FCEUI_LoadState(const char *fname, bool display_message=true);
void FCEUD_SaveStateAs(void);
void FCEUD_LoadStateFrom(void);
@ -229,7 +233,6 @@ void FCEUI_GetIVectors(uint16 *reset, uint16 *irq, uint16 *nmi);
uint32 FCEUI_CRC32(uint32 crc, uint8 *buf, uint32 len);
void FCEUI_ToggleTileView(void);
void FCEUI_SetLowPass(int q);
void FCEUI_NSFSetVis(int mode);
@ -336,7 +339,7 @@ enum EFCEUI
FCEUI_STOPMOVIE, FCEUI_RECORDMOVIE, FCEUI_PLAYMOVIE,
FCEUI_OPENGAME, FCEUI_CLOSEGAME,
FCEUI_TASEDITOR,
FCEUI_RESET, FCEUI_POWER, FCEUI_PLAYFROMBEGINNING, FCEUI_EJECT_DISK, FCEUI_SWITCH_DISK
FCEUI_RESET, FCEUI_POWER, FCEUI_PLAYFROMBEGINNING, FCEUI_EJECT_DISK, FCEUI_SWITCH_DISK, FCEUI_INSERT_COIN
};
//checks whether an EFCEUI is valid right now

View File

@ -21,6 +21,7 @@ THE SOFTWARE.
*/
#include "emufile.h"
#include "utils/xstring.h"
#include <vector>
@ -59,6 +60,24 @@ size_t EMUFILE_MEMORY::_fread(const void *ptr, size_t bytes){
return todo;
}
void EMUFILE_FILE::open(const char* fname, const char* mode)
{
fp = fopen(fname,mode);
if(!fp)
{
#ifdef _MSC_VER
std::wstring wfname = mbstowcs((std::string)fname);
std::wstring wfmode = mbstowcs((std::string)mode);
fp = _wfopen(wfname.c_str(),wfmode.c_str());
#endif
if(!fp)
failbit = true;
}
this->fname = fname;
strcpy(this->mode,mode);
}
void EMUFILE_FILE::truncate(s32 length)
{
::fflush(fp);
@ -229,7 +248,7 @@ size_t EMUFILE::read8le(u8* val)
u8 EMUFILE::read8le()
{
u8 temp;
u8 temp = 0;
fread(&temp,1);
return temp;
}
@ -256,4 +275,4 @@ size_t EMUFILE::readdouble(double* val)
size_t ret = read64le(&temp);
*val = u64_to_double(temp);
return ret;
}
}

View File

@ -25,23 +25,23 @@ THE SOFTWARE.
#ifndef EMUFILE_H
#define EMUFILE_H
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <vector>
#include <algorithm>
#include <string>
#include <stdarg.h>
#ifdef GEKKO
#include <malloc.h>
#endif
#include "emufile_types.h"
#ifdef _MSC_VER
#include <io.h>
#endif
#include <cassert>
#include <cstdio>
#include <cstring>
#include <cstdarg>
#include <vector>
#include <algorithm>
#include <string>
class EMUFILE {
protected:
bool failbit;

View File

@ -18,12 +18,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <string>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <time.h>
#include "types.h"
#include "x6502.h"
#include "fceu.h"
@ -49,14 +43,15 @@
#include "file.h"
#include "vsuni.h"
#include "ines.h"
#ifdef WIN32
#include "drivers/win/pref.h"
#include "utils/xstring.h"
extern void CDLoggerROMClosed();
extern void CDLoggerROMChanged();
extern void ResetDebugStatisticsCounters();
extern void SetMainWindowText();
extern bool TaseditorIsRecording();
extern bool isTaseditorRecording();
extern int32 fps_scale;
extern int32 fps_scale_unpaused;
@ -64,9 +59,6 @@ extern int32 fps_scale_frameadvance;
extern void RefreshThrottleFPS();
#endif
#include <fstream>
#include <sstream>
#ifdef _S9XLUA_H
#include "fceulua.h"
#endif
@ -74,6 +66,7 @@ extern void RefreshThrottleFPS();
//TODO - we really need some kind of global platform-specific options api
#ifdef WIN32
#include "drivers/win/main.h"
#include "drivers/win/memview.h"
#include "drivers/win/cheat.h"
#include "drivers/win/texthook.h"
#include "drivers/win/ram_search.h"
@ -88,6 +81,16 @@ extern void RefreshThrottleFPS();
#endif
#endif
#include <fstream>
#include <sstream>
#include <string>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cstdarg>
#include <ctime>
using namespace std;
int AFon = 1, AFoff = 1, AutoFireOffset = 0; //For keeping track of autofire settings
@ -97,17 +100,24 @@ bool AutoSS = false; //Flagged true when the first auto-savestate is made
bool movieSubtitles = true; //Toggle for displaying movie subtitles
bool DebuggerWasUpdated = false; //To prevent the debugger from updating things without being updated.
bool AutoResumePlay = false;
char rom_name_when_closing_emulator[129] = {0};
char romNameWhenClosingEmulator[2048] = {0};
int dendy = 0;
FCEUGI::FCEUGI()
: filename(0)
, archiveFilename(0) {
: filename(0),
archiveFilename(0) {
//printf("%08x",opsize); // WTF?!
}
FCEUGI::~FCEUGI() {
if (filename) delete filename;
if (archiveFilename) delete archiveFilename;
if (filename) {
free(filename);
filename = NULL;
}
if (archiveFilename) {
delete archiveFilename;
archiveFilename = NULL;
}
}
bool CheckFileExists(const char* filename) {
@ -143,18 +153,17 @@ static void FCEU_CloseGame(void)
{
if (GameInfo)
{
if (AutoResumePlay && (GameInfo->type != GIT_NSF))
if (AutoResumePlay)
{
// save "-resume" savestate
FCEUSS_Save(FCEU_MakeFName(FCEUMKF_RESUMESTATE, 0, 0).c_str());
FCEUSS_Save(FCEU_MakeFName(FCEUMKF_RESUMESTATE, 0, 0).c_str(), false);
}
#ifdef WIN32
extern char LoadedRomFName[2048];
if (storePreferences(LoadedRomFName))
{
if (storePreferences(mass_replace(LoadedRomFName, "|", ".").c_str()))
FCEUD_PrintError("Couldn't store debugging data");
}
CDLoggerROMClosed();
#endif
if (FCEUnetplay) {
@ -163,7 +172,7 @@ static void FCEU_CloseGame(void)
if (GameInfo->name) {
free(GameInfo->name);
GameInfo->name = 0;
GameInfo->name = NULL;
}
if (GameInfo->type != GIT_NSF) {
@ -264,8 +273,8 @@ void FlushGenieRW(void) {
}
free(AReadG);
free(BWriteG);
AReadG = 0;
BWriteG = 0;
AReadG = NULL;
BWriteG = NULL;
RWWrap = 0;
}
}
@ -276,8 +285,10 @@ readfunc GetReadHandler(int32 a) {
else
return ARead[a];
}
void SetReadHandler(int32 start, int32 end, readfunc func) {
int32 x;
if (!func)
func = ANull;
@ -329,6 +340,7 @@ static void AllocBuffers() {
static void FreeBuffers() {
FCEU_free(RAM);
RAM = NULL;
}
//------
@ -361,15 +373,16 @@ void ResetGameLoaded(void) {
if (GameInfo) FCEU_CloseGame();
EmulationPaused = 0; //mbg 5/8/08 - loading games while paused was bad news. maybe this fixes it
GameStateRestore = 0;
PPU_hook = 0;
GameHBIRQHook = 0;
FFCEUX_PPURead = 0;
FFCEUX_PPUWrite = 0;
PPU_hook = NULL;
GameHBIRQHook = NULL;
FFCEUX_PPURead = NULL;
FFCEUX_PPUWrite = NULL;
if (GameExpSound.Kill)
GameExpSound.Kill();
memset(&GameExpSound, 0, sizeof(GameExpSound));
MapIRQHook = 0;
MapIRQHook = NULL;
MMC5Hack = 0;
PEC586Hack = 0;
PAL &= 1;
pale = 0;
}
@ -387,8 +400,7 @@ FCEUGI *FCEUI_LoadGameVirtual(const char *name, int OverwriteVidMode, bool silen
//----------
//attempt to open the files
FCEUFILE *fp;
FCEU_printf("Loading %s...\n\n", name);
char fullname[2048]; // this name contains both archive name and ROM file name
const char* romextensions[] = { "nes", "fds", 0 };
fp = FCEU_fopen(name, 0, "rb", 0, -1, romextensions);
@ -398,16 +410,21 @@ FCEUGI *FCEUI_LoadGameVirtual(const char *name, int OverwriteVidMode, bool silen
if (!silent)
FCEU_PrintError("Error opening \"%s\"!", name);
return 0;
} else if (fp->archiveFilename != "")
{
strcpy(fullname, fp->archiveFilename.c_str());
strcat(fullname, "|");
strcat(fullname, fp->filename.c_str());
} else
{
strcpy(fullname, name);
}
GetFileBase(fp->filename.c_str());
//---------
//file opened ok. start loading.
FCEU_printf("Loading %s...\n\n", fullname);
GetFileBase(fp->filename.c_str());
ResetGameLoaded();
//reset parameters so theyre cleared just in case a format's loader doesnt know to do the clearing
//reset parameters so they're cleared just in case a format's loader doesn't know to do the clearing
MasterRomInfoParams = TMasterRomInfoParams();
if (!AutosaveStatus)
@ -420,7 +437,8 @@ FCEUGI *FCEUI_LoadGameVirtual(const char *name, int OverwriteVidMode, bool silen
memset(GameInfo, 0, sizeof(FCEUGI));
GameInfo->filename = strdup(fp->filename.c_str());
if (fp->archiveFilename != "") GameInfo->archiveFilename = strdup(fp->archiveFilename.c_str());
if (fp->archiveFilename != "")
GameInfo->archiveFilename = strdup(fp->archiveFilename.c_str());
GameInfo->archiveCount = fp->archiveCount;
GameInfo->soundchan = 0;
@ -436,13 +454,13 @@ FCEUGI *FCEUI_LoadGameVirtual(const char *name, int OverwriteVidMode, bool silen
bool FCEUXLoad(const char *name, FCEUFILE * fp);
/*if(FCEUXLoad(name,fp))
goto endlseq;*/
if (iNESLoad(name, fp, OverwriteVidMode))
if (iNESLoad(fullname, fp, OverwriteVidMode))
goto endlseq;
if (NSFLoad(name, fp))
if (NSFLoad(fullname, fp))
goto endlseq;
if (UNIFLoad(name, fp))
if (UNIFLoad(fullname, fp))
goto endlseq;
if (FDSLoad(name, fp))
if (FDSLoad(fullname, fp))
goto endlseq;
if (!silent)
@ -463,7 +481,7 @@ FCEUGI *FCEUI_LoadGameVirtual(const char *name, int OverwriteVidMode, bool silen
extern char LoadedRomFName[2048];
extern int loadDebugDataFailed;
if ((loadDebugDataFailed = loadPreferences(LoadedRomFName)))
if ((loadDebugDataFailed = loadPreferences(mass_replace(LoadedRomFName, "|", ".").c_str())))
if (!silent)
FCEU_printf("Couldn't load debugging data.\n");
@ -473,8 +491,18 @@ FCEUGI *FCEUI_LoadGameVirtual(const char *name, int OverwriteVidMode, bool silen
FCEU_ResetVidSys();
if (GameInfo->type != GIT_NSF)
{
if (FSettings.GameGenie)
FCEU_OpenGenie();
{
if (FCEU_OpenGenie())
{
FCEUI_SetGameGenie(false);
#ifdef WIN32
genie = 0;
#endif
}
}
}
PowerNES();
if (GameInfo->type != GIT_NSF)
@ -486,21 +514,24 @@ FCEUGI *FCEUI_LoadGameVirtual(const char *name, int OverwriteVidMode, bool silen
if (GameInfo->type != GIT_NSF)
FCEU_LoadGameCheats(0);
#if defined (WIN32) || defined (WIN64)
DoDebuggerDataReload(); // Reloads data without reopening window
#endif
if (AutoResumePlay && (GameInfo->type != GIT_NSF))
if (AutoResumePlay)
{
// load "-resume" savestate
if (FCEUSS_Load(FCEU_MakeFName(FCEUMKF_RESUMESTATE, 0, 0).c_str()))
if (FCEUSS_Load(FCEU_MakeFName(FCEUMKF_RESUMESTATE, 0, 0).c_str(), false))
FCEU_DispMessage("Old play session resumed.", 0);
else
FCEU_DispMessage("", 0);
}
ResetScreenshotsCounter();
#if defined (WIN32) || defined (WIN64)
DoDebuggerDataReload(); // Reloads data without reopening window
CDLoggerROMChanged();
if (hMemView) UpdateColorTable();
if (hCheat) UpdateCheatsAdded();
if (FrozenAddressCount)
FCEU_DispMessage("%d cheats active", 0, FrozenAddressCount);
#endif
return GameInfo;
}
@ -735,7 +766,7 @@ void ResetNES(void) {
extern uint8 *XBackBuf;
memset(XBackBuf, 0, 256 * 256);
FCEU_DispMessage("Reset", 0);
//FCEU_DispMessage("Reset", 0);
}
void FCEU_MemoryRand(uint8 *ptr, uint32 size) {
@ -782,8 +813,8 @@ void PowerNES(void) {
SetReadHandler(0, 0x7FF, ARAML);
SetWriteHandler(0, 0x7FF, BRAML);
SetReadHandler(0x800, 0x1FFF, ARAMH); // Part of a little
SetWriteHandler(0x800, 0x1FFF, BRAMH); //hack for a small speed boost.
SetReadHandler(0x800, 0x1FFF, ARAMH); // Part of a little
SetWriteHandler(0x800, 0x1FFF, BRAMH); //hack for a small speed boost.
InitializeInput();
FCEUSND_Power();
@ -806,7 +837,7 @@ void PowerNES(void) {
#endif
FCEU_PowerCheats();
LagCounterReset();
// clear back baffer
// clear back buffer
extern uint8 *XBackBuf;
memset(XBackBuf, 0, 256 * 256);
@ -814,7 +845,7 @@ void PowerNES(void) {
Update_RAM_Search(); // Update_RAM_Watch() is also called.
#endif
FCEU_DispMessage("Power on", 0);
//FCEU_DispMessage("Power on", 0);
}
void FCEU_ResetVidSys(void) {
@ -822,13 +853,15 @@ void FCEU_ResetVidSys(void) {
if (GameInfo->vidsys == GIV_NTSC)
w = 0;
else if (GameInfo->vidsys == GIV_PAL)
else if (GameInfo->vidsys == GIV_PAL) {
w = 1;
else
dendy = 0;
} else
w = FSettings.PAL;
PAL = w ? 1 : 0;
FCEUPPU_SetVideoSystem(w);
FCEUPPU_SetVideoSystem(w || dendy);
SetSoundVariables();
}
@ -867,7 +900,7 @@ void FCEUI_SetRenderedLines(int ntscf, int ntscl, int palf, int pall) {
FSettings.UsrLastSLine[0] = ntscl;
FSettings.UsrFirstSLine[1] = palf;
FSettings.UsrLastSLine[1] = pall;
if (PAL) {
if (PAL || dendy) {
FSettings.FirstSLine = FSettings.UsrFirstSLine[1];
FSettings.LastSLine = FSettings.UsrLastSLine[1];
} else {
@ -892,6 +925,30 @@ int FCEUI_GetCurrentVidSystem(int *slstart, int *slend) {
*slend = FSettings.LastSLine;
return(PAL);
}
/*
// TODO: make use on SDL
void FCEUI_SetRegion(int region) {
switch (region) {
case 0: // NTSC
pal_emulation = 0;
dendy = 0;
break;
case 1: // PAL
pal_emulation = 1;
dendy = 0;
break;
case 2: // Dendy
pal_emulation = 0;
dendy = 1;
break;
}
FCEUI_SetVidSystem(pal_emulation);
RefreshThrottleFPS();
#ifdef WIN32
UpdateCheckedMenuItems();
PushCurrentVideoSettings();
#endif
}*/
//Enable or disable Game Genie option.
void FCEUI_SetGameGenie(bool a) {
@ -905,7 +962,7 @@ void FCEUI_SetGameGenie(bool a) {
//}
int32 FCEUI_GetDesiredFPS(void) {
if (PAL)
if (PAL || dendy)
return(838977920); // ~50.007
else
return(1008307711); // ~60.1
@ -958,14 +1015,15 @@ void UpdateAutosave(void) {
AutosaveCounter = 0;
AutosaveIndex = (AutosaveIndex + 1) % AutosaveQty;
f = strdup(FCEU_MakeFName(FCEUMKF_AUTOSTATE, AutosaveIndex, 0).c_str());
FCEUSS_Save(f);
FCEUSS_Save(f, false);
AutoSS = true; //Flag that an auto-savestate was made
free(f);
f = NULL;
AutosaveStatus[AutosaveIndex] = 1;
}
}
void FCEUI_Autosave(void) {
void FCEUI_RewindToLastAutosave(void) {
if (!EnableAutosave || !AutoSS)
return;
@ -974,6 +1032,7 @@ void FCEUI_Autosave(void) {
f = strdup(FCEU_MakeFName(FCEUMKF_AUTOSTATE, AutosaveIndex, 0).c_str());
FCEUSS_Load(f);
free(f);
f = NULL;
//Set pointer to previous available slot
if (AutosaveStatus[(AutosaveIndex + AutosaveQty - 1) % AutosaveQty] == 1) {
@ -1031,10 +1090,11 @@ bool FCEU_IsValidUI(EFCEUI ui) {
case FCEUI_POWER:
case FCEUI_EJECT_DISK:
case FCEUI_SWITCH_DISK:
case FCEUI_INSERT_COIN:
if (!GameInfo) return false;
if (FCEUMOV_Mode(MOVIEMODE_RECORD)) return true;
#ifdef WIN32
if (FCEUMOV_Mode(MOVIEMODE_TASEDITOR) && TaseditorIsRecording()) return true;
if (FCEUMOV_Mode(MOVIEMODE_TASEDITOR) && isTaseditorRecording()) return true;
#endif
if (!FCEUMOV_Mode(MOVIEMODE_INACTIVE)) return false;
break;

View File

@ -1,12 +1,14 @@
#ifndef _FCEUH
#define _FCEUH
#include "types.h"
extern int fceuindbg;
extern int newppu;
void ResetGameLoaded(void);
extern bool AutoResumePlay;
extern char rom_name_when_closing_emulator[];
extern char romNameWhenClosingEmulator[];
#define DECLFR(x) uint8 x (uint32 A)
#define DECLFW(x) void x (uint32 A, uint8 V)
@ -29,7 +31,7 @@ void PowerNES(void);
void SetAutoFireOffset(int offset);
void SetAutoFirePattern(int onframes, int offframes);
void AutoFire(void);
void FCEUI_Autosave(void);
void FCEUI_RewindToLastAutosave(void);
//mbg 7/23/06
char *FCEUI_GetAboutString();
@ -37,7 +39,7 @@ char *FCEUI_GetAboutString();
extern uint64 timestampbase;
extern uint32 MMC5HackVROMMask;
extern uint8 *MMC5HackExNTARAMPtr;
extern int MMC5Hack;
extern int MMC5Hack, PEC586Hack;
extern uint8 *MMC5HackVROMPTR;
extern uint8 MMC5HackCHRMode;
extern uint8 MMC5HackSPMode;
@ -72,6 +74,7 @@ extern FCEUGI *GameInfo;
extern int GameAttributes;
extern uint8 PAL;
extern int dendy;
//#include "driver.h"
@ -125,6 +128,11 @@ void FCEU_PutImage(void);
void FCEU_PutImageDummy(void);
#endif
#ifdef WIN32
extern void UpdateCheckedMenuItems();
extern void PushCurrentVideoSettings();
#endif
extern uint8 Exit;
extern uint8 pale;
extern uint8 vsdip;

91
source/fceultra/fceulua.h Normal file
View File

@ -0,0 +1,91 @@
#ifdef _S9XLUA_H
#ifndef _FCEULUA_H
#define _FCEULUA_H
enum LuaCallID
{
LUACALL_BEFOREEMULATION,
LUACALL_AFTEREMULATION,
LUACALL_BEFOREEXIT,
LUACALL_BEFORESAVE,
LUACALL_AFTERLOAD,
LUACALL_TASEDITOR_AUTO,
LUACALL_TASEDITOR_MANUAL,
LUACALL_COUNT
};
extern void CallRegisteredLuaFunctions(LuaCallID calltype);
enum LuaMemHookType
{
LUAMEMHOOK_WRITE,
LUAMEMHOOK_READ,
LUAMEMHOOK_EXEC,
LUAMEMHOOK_WRITE_SUB,
LUAMEMHOOK_READ_SUB,
LUAMEMHOOK_EXEC_SUB,
LUAMEMHOOK_COUNT
};
void CallRegisteredLuaMemHook(unsigned int address, int size, unsigned int value, LuaMemHookType hookType);
struct LuaSaveData
{
LuaSaveData() { recordList = 0; }
~LuaSaveData() { ClearRecords(); }
struct Record
{
unsigned int key; // crc32
unsigned int size; // size of data
unsigned char* data;
Record* next;
};
Record* recordList;
void SaveRecord(struct lua_State* L, unsigned int key); // saves Lua stack into a record and pops it
void LoadRecord(struct lua_State* L, unsigned int key, unsigned int itemsToLoad) const; // pushes a record's data onto the Lua stack
void SaveRecordPartial(struct lua_State* L, unsigned int key, int idx); // saves part of the Lua stack (at the given index) into a record and does NOT pop anything
void ExportRecords(void* file) const; // writes all records to an already-open file
void ImportRecords(void* file); // reads records from an already-open file
void ClearRecords(); // deletes all record data
private:
// disallowed, it's dangerous to call this
// (because the memory the destructor deletes isn't refcounted and shouldn't need to be copied)
// so pass LuaSaveDatas by reference and this should never get called
LuaSaveData(const LuaSaveData& copy) {}
};
#define LUA_DATARECORDKEY 42
void CallRegisteredLuaSaveFunctions(int savestateNumber, LuaSaveData& saveData);
void CallRegisteredLuaLoadFunctions(int savestateNumber, const LuaSaveData& saveData);
// Just forward function declarations
void FCEU_LuaFrameBoundary();
int FCEU_LoadLuaCode(const char *filename, const char *arg=NULL);
void FCEU_ReloadLuaCode();
void FCEU_LuaStop();
int FCEU_LuaRunning();
uint8 FCEU_LuaReadJoypad(int,uint8); // HACK - Function needs controller input
int FCEU_LuaSpeed();
int FCEU_LuaFrameskip();
int FCEU_LuaRerecordCountSkip();
void FCEU_LuaGui(uint8 *XBuf);
void FCEU_LuaUpdatePalette();
struct lua_State* FCEU_GetLuaState();
char* FCEU_GetLuaScriptName();
// And some interesting REVERSE declarations!
char *FCEU_GetFreezeFilename(int slot);
#endif
#endif

Some files were not shown because too many files have changed in this diff Show More