mirror of
https://github.com/dborth/fceugx.git
synced 2024-12-04 14:24:16 +01:00
-Too many to write
This commit is contained in:
parent
2037f6cfa1
commit
aa7cf18989
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
/build_wii
|
||||
/build_gc
|
||||
/executables
|
21
Makefile.gc
21
Makefile.gc
@ -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 $<)
|
||||
@ -150,6 +151,10 @@ $(OUTPUT).elf: $(OFILES)
|
||||
@echo $(notdir $<)
|
||||
$(bin2o)
|
||||
|
||||
%.ogg.o : %.ogg
|
||||
@echo $(notdir $<)
|
||||
$(bin2o)
|
||||
|
||||
%.pcm.o : %.pcm
|
||||
@echo $(notdir $<)
|
||||
$(bin2o)
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
41
readme.txt
41
readme.txt
@ -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)
|
||||
|
@ -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,6 +437,64 @@ int main(int argc, char *argv[])
|
||||
FCEUI_SetSoundQuality(1); // 0 - low, 1 - high, 2 - high (alt.)
|
||||
int currentTiming = 0;
|
||||
|
||||
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
|
||||
@ -406,11 +503,21 @@ int main(int argc, char *argv[])
|
||||
|
||||
SwitchAudioMode(1);
|
||||
|
||||
if(!autoboot)
|
||||
{
|
||||
if(!romLoaded)
|
||||
MainMenu(MENU_GAMESELECTION);
|
||||
else
|
||||
MainMenu(MENU_GAME);
|
||||
|
||||
ConfigRequested = 0;
|
||||
ScreenshotRequested = 0;
|
||||
}
|
||||
else if(romLoaded && autoboot)
|
||||
autoboot = false;
|
||||
else
|
||||
ExitApp();
|
||||
|
||||
if(currentTiming != GCSettings.timing)
|
||||
{
|
||||
GameInfo->vidsys=(EGIV)GCSettings.timing;
|
||||
|
@ -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,7 +77,8 @@ enum {
|
||||
LANG_LENGTH
|
||||
};
|
||||
|
||||
struct SGCSettings{
|
||||
struct SGCSettings
|
||||
{
|
||||
int AutoLoad;
|
||||
int AutoSave;
|
||||
int LoadMethod; // For ROMS: Auto, SD, DVD, USB, Network (SMB)
|
||||
@ -85,6 +89,10 @@ struct SGCSettings{
|
||||
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();
|
||||
|
42
source/fceultra/SConscript
Normal file
42
source/fceultra/SConscript
Normal 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')
|
@ -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; \
|
||||
}
|
||||
|
||||
|
||||
//odd, 1-byte opcodes
|
||||
#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 0x08: strcpy(str,"PHP"); break;
|
||||
case 0x0A: strcpy(str,"ASL"); break;
|
||||
case 0x18: strcpy(str,"CLC"); break;
|
||||
|
45
source/fceultra/auxlib.lua
Normal file
45
source/fceultra/auxlib.lua
Normal 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);
|
@ -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);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -18,42 +18,44 @@
|
||||
* 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")
|
||||
* 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);
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -48,6 +48,7 @@ static void Sync(void)
|
||||
|
||||
static DECLFW(M176Write_5001)
|
||||
{
|
||||
printf("%04X = $%02X\n",A,V);
|
||||
if(sbw)
|
||||
{
|
||||
prg[0] = V*4;
|
||||
@ -60,12 +61,14 @@ 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)
|
||||
{
|
||||
@ -79,6 +82,7 @@ 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;
|
||||
@ -89,6 +93,7 @@ static DECLFW(M176Write_5FF1)
|
||||
|
||||
static DECLFW(M176Write_5FF2)
|
||||
{
|
||||
printf("%04X = $%02X\n",A,V);
|
||||
chr = V;
|
||||
Sync();
|
||||
}
|
||||
@ -115,6 +120,7 @@ static void M176Power(void)
|
||||
SetWriteHandler(0x5011,0x5011,M176Write_5011);
|
||||
SetWriteHandler(0x5ff1,0x5ff1,M176Write_5FF1);
|
||||
SetWriteHandler(0x5ff2,0x5ff2,M176Write_5FF2);
|
||||
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
|
||||
|
||||
we_sram = 0;
|
||||
sbw = 0;
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ static void Sync(void) {
|
||||
} else
|
||||
setprg32(0x8000, prg >> 1);
|
||||
setchr8(chr);
|
||||
setmirror(mirr);
|
||||
setmirror(mirr ^ 1);
|
||||
}
|
||||
|
||||
static DECLFW(M225Write) {
|
||||
|
@ -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)
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
@ -90,11 +90,13 @@ static DECLFW(M253Write) {
|
||||
}
|
||||
|
||||
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) {
|
||||
|
@ -129,7 +129,6 @@ static DECLFW(WriteEXP)
|
||||
{
|
||||
uint32 addr = A;
|
||||
uint8 value = V;
|
||||
if (addr >= 05000)
|
||||
reg = value & 0x81;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,16 +31,20 @@ static SFORMAT StateRegs[] =
|
||||
{ &IRQCount, 4, "IRQC" },
|
||||
{ &IRQa, 4, "IRQA" },
|
||||
{ ®, 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);
|
||||
}
|
||||
|
||||
@ -48,13 +53,14 @@ static DECLFW(M43Write) {
|
||||
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 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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
@ -89,8 +90,8 @@ static DECLFW(M69Write1) {
|
||||
case 0xB: preg[2] = V; 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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -16,29 +16,40 @@
|
||||
* 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
|
||||
if ((cmdreg & 0x100) && (PRGsize[0] < (1024 * 1024))) {
|
||||
A = (A & 0xFFF0) + reset;
|
||||
}
|
||||
return CartBR(A);
|
||||
}
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
|
6
source/fceultra/boards/SConscript
Normal file
6
source/fceultra/boards/SConscript
Normal 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')
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
||||
@ -45,18 +40,129 @@ static SFORMAT StateRegs[] =
|
||||
{ 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 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;
|
||||
}
|
||||
}
|
||||
|
||||
static void BandaiSync(void) {
|
||||
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;
|
||||
|
||||
|
108
source/fceultra/boards/coolboy.cpp
Normal file
108
source/fceultra/boards/coolboy.cpp
Normal 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");
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
@ -100,6 +101,8 @@ static void NROMPower(void) {
|
||||
SetWriteHandler(0x6000, 0x7FFF, CartBW);
|
||||
SetReadHandler(0x8000, 0xFFFF, CartBR);
|
||||
|
||||
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);
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
@ -435,6 +451,9 @@ void Mapper240_Init(CartInfo *info) {
|
||||
static void M241Sync(void) {
|
||||
setchr8(0);
|
||||
setprg8r(0x10, 0x6000, 0);
|
||||
if (latche & 0x80)
|
||||
setprg32(0x8000, latche | 8); // no 241 actually, but why not afterall?
|
||||
else
|
||||
setprg32(0x8000, latche);
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
62
source/fceultra/boards/inlnsf.cpp
Normal file
62
source/fceultra/boards/inlnsf.cpp
Normal 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);
|
||||
}
|
85
source/fceultra/boards/ks7010.cpp
Normal file
85
source/fceultra/boards/ks7010.cpp
Normal 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);
|
||||
}
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
68
source/fceultra/boards/mihunche.cpp
Normal file
68
source/fceultra/boards/mihunche.cpp
Normal 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);
|
||||
}
|
@ -248,7 +248,7 @@ static void GenMMC1Power(void) {
|
||||
if (mmc1opts & 4)
|
||||
FCEU_dwmemset(WRAM, 0, 8192)
|
||||
else if (!(mmc1opts & 2))
|
||||
FCEU_dwmemset(WRAM, 0, 8192);
|
||||
FCEU_dwmemset(WRAM, 0, 8192); // wtf?
|
||||
}
|
||||
SetWriteHandler(0x8000, 0xFFFF, MMC1_write);
|
||||
SetReadHandler(0x8000, 0xFFFF, CartBR);
|
||||
|
@ -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);
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "mmc3.h"
|
||||
|
||||
uint8 MMC3_cmd;
|
||||
uint8 kt_extra;
|
||||
uint8 *WRAM;
|
||||
uint32 WRAMSIZE;
|
||||
uint8 *CHRRAM;
|
||||
@ -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) {
|
||||
@ -220,7 +232,10 @@ static void GENCWRAP(uint32 A, uint8 V) {
|
||||
}
|
||||
|
||||
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,6 +318,8 @@ 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;
|
||||
@ -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");
|
||||
}
|
||||
|
||||
@ -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 ------------------------------
|
||||
@ -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) {
|
||||
@ -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) {
|
||||
|
@ -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,30 +150,34 @@ 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]))
|
||||
@ -176,20 +185,11 @@ int DetectMMC5WRAMSize(uint32 crc32) {
|
||||
int x;
|
||||
for (x = 0; x < MMC5_NOCARTS; x++) {
|
||||
if (crc32 == MMC5CartList[x].crc32) {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -201,13 +201,7 @@ static void BuildWRAMSizeTable(void) {
|
||||
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 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;
|
||||
switch (A) {
|
||||
case 0x5100:
|
||||
mmc5psize = V;
|
||||
MMC5PRG();
|
||||
break;
|
||||
case 0x5101:
|
||||
mmc5vsize = V;
|
||||
if (!mmc5ABMode) {
|
||||
MMC5CHRB();
|
||||
MMC5CHRA();
|
||||
} else switch (A) {
|
||||
} 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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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]
|
||||
#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;
|
||||
|
@ -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);
|
||||
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 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 UNLPEC586Power(void) {
|
||||
if(PRGsize[0] == 512 * 1024)
|
||||
reg[0] = 0x00;
|
||||
else
|
||||
reg[0] = 0x0E;
|
||||
Sync();
|
||||
setchr8(0);
|
||||
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);
|
||||
}
|
||||
|
||||
static void UNLPEC586IRQ(void) {
|
||||
// if(reg[0]&0x80)
|
||||
{
|
||||
if (scanline == 128) {
|
||||
setchr4(0x0000, 1);
|
||||
setchr4(0x1000, 0);
|
||||
} else {
|
||||
setchr4(0x0000, 0);
|
||||
setchr4(0x1000, 1);
|
||||
}
|
||||
}
|
||||
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;
|
||||
|
195
source/fceultra/boards/sb-2000.cpp
Normal file
195
source/fceultra/boards/sb-2000.cpp
Normal 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);
|
||||
}
|
@ -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) {
|
||||
if(IRQCount > 0)
|
||||
IRQCount--;
|
||||
if (IRQCount == 0) {
|
||||
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) {
|
||||
|
@ -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) {
|
||||
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) {
|
||||
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
|
||||
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);
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
269
source/fceultra/boards/unrom512.cpp
Normal file
269
source/fceultra/boards/unrom512.cpp
Normal 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");
|
||||
}
|
@ -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) {
|
||||
|
@ -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)
|
||||
|
@ -184,6 +184,7 @@ static void M190Power(void) {
|
||||
SetWriteHandler(0x8000, 0xFFFF, M190Write);
|
||||
SetReadHandler(0xDC00, 0xDC00, M190Read);
|
||||
SetReadHandler(0xDD00, 0xDD00, M190Read);
|
||||
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
|
||||
Sync();
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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" },
|
||||
{ (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)
|
||||
|
@ -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) {
|
||||
|
@ -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. */
|
||||
|
@ -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);
|
||||
|
@ -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.");
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
@ -403,6 +422,7 @@ void LogCDData(uint8 *opcode, uint16 A, int size) {
|
||||
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 & 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)
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
@ -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;
|
||||
|
@ -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
91
source/fceultra/fceulua.h
Normal 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
|
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user