add mednafen's pce fast core

~1.6x the speed of the mednafen pce core, or something
Supports all of the same features except ADPCM ram view
TODO: romloader hookups
This commit is contained in:
nattthebear 2020-06-01 11:12:40 -04:00
parent 571a5be992
commit 474d41bd8a
10 changed files with 348 additions and 16 deletions

BIN
output/dll/pce-fast.wbx.gz Normal file

Binary file not shown.

View File

@ -171,7 +171,12 @@ namespace BizHawk.Client.Common
private bool HandleArchiveBinding(HawkFile file)
{
var romExtensions = new[] { "SMS", "SMC", "SFC", "PCE", "SGX", "GG", "SG", "BIN", "GEN", "MD", "SMD", "GB", "NES", "FDS", "ROM", "INT", "GBC", "UNF", "A78", "CRT", "COL", "XML", "Z64", "V64", "N64", "WS", "WSC", "GBA", "32X", "VEC", "O2" };
var romExtensions = new[]
{
"SMS", "SMC", "SFC", "PCE", "SGX", "GG", "SG", "BIN", "GEN", "MD", "SMD", "GB",
"NES", "FDS", "ROM", "INT", "GBC", "UNF", "A78", "CRT", "COL", "XML", "Z64",
"V64", "N64", "WS", "WSC", "GBA", "32X", "VEC", "O2"
};
// try binding normal rom extensions first
if (!file.IsBound)
@ -530,6 +535,9 @@ namespace BizHawk.Client.Common
nextEmulator = new TerboGrafix(game, new[] { disc }, nextComm,
(Emulation.Cores.Waterbox.NymaCore.NymaSettings)GetCoreSettings<TerboGrafix>(),
(Emulation.Cores.Waterbox.NymaCore.NymaSyncSettings)GetCoreSyncSettings<TerboGrafix>(), Deterministic);
// nextEmulator = new TerboGrafixSanic(game, new[] { disc }, nextComm,
// (Emulation.Cores.Waterbox.NymaCore.NymaSettings)GetCoreSettings<TerboGrafixSanic>(),
// (Emulation.Cores.Waterbox.NymaCore.NymaSyncSettings)GetCoreSyncSettings<TerboGrafixSanic>(), Deterministic);
}
break;

View File

@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using BizHawk.BizInvoke;
using BizHawk.Common;
using BizHawk.Emulation.Common;
using BizHawk.Emulation.Cores.PCEngine;
using BizHawk.Emulation.Cores.Waterbox;
using BizHawk.Emulation.DiscSystem;
namespace BizHawk.Emulation.Cores.Consoles.NEC.PCE
{
[Core(CoreNames.TurboTurboNyma, "Mednafen Team", true, true, "1.24.3", "https://mednafen.github.io/releases/", false)]
public class TerboGrafixSanic : NymaCore, IRegionable, IPceGpuView
{
private readonly LibTerboGrafixSanic _terboGrafix;
[CoreConstructor(new[] { "PCE", "SGX" })]
public TerboGrafixSanic(GameInfo game, byte[] rom, CoreComm comm, string extension,
NymaSettings settings, NymaSyncSettings syncSettings, bool deterministic)
: base(comm, "PCE", "PC Engine Controller", settings, syncSettings)
{
if (game["BRAM"])
SettingsOverrides["pce.disable_bram_hucard"] = "0";
_terboGrafix = DoInit<LibTerboGrafixSanic>(game, rom, null, "pce-fast.wbx", extension, deterministic);
}
public TerboGrafixSanic(GameInfo game, Disc[] discs, CoreComm comm,
NymaSettings settings, NymaSyncSettings syncSettings, bool deterministic)
: base(comm, "PCE", "PC Engine Controller", settings, syncSettings)
{
var firmwares = new Dictionary<string, byte[]>
{
{ "FIRMWARE:syscard3.pce", comm.CoreFileProvider.GetFirmware("PCECD", "Bios", true) },
};
_terboGrafix = DoInit<LibTerboGrafixSanic>(game, null, discs, "pce-fast.wbx", null, deterministic, firmwares);
}
public override string SystemId => IsSgx ? "SGX" : "PCE";
protected override IDictionary<string, string> SettingsOverrides { get; } = new Dictionary<string, string>
{
{ "pce_fast.correct_aspect", null },
{ "pce_fast.mouse_sensitivity", null },
{ "pce_fast.disable_softreset", null },
{ "pce_fast.cdbios", null },
{ "nyma.rtcinitialtime", null },
{ "nyma.rtcrealtime", null },
};
protected override IDictionary<string, string> ButtonNameOverrides { get; } = new Dictionary<string, string>
{
{ "RIGHT →", "Right up my arse" },
};
// pce always has two layers, sgx always has 4, and mednafen knows this
public bool IsSgx => SettingsInfo.LayerNames.Count == 4;
public unsafe void GetGpuData(int vdc, Action<PceGpuData> callback)
{
using(_exe.EnterExit())
{
var palScratch = new int[512];
var v = new PceGpuData();
_terboGrafix.GetVramInfo(v, vdc);
fixed(int* p = palScratch)
{
for (var i = 0; i < 512; i++)
p[i] = v.PaletteCache[i] | unchecked((int)0xff000000);
v.PaletteCache = p;
callback(v);
}
}
}
}
public abstract class LibTerboGrafixSanic : LibNymaCore
{
[BizImport(CallingConvention.Cdecl, Compatibility = true)]
public abstract void GetVramInfo([Out]PceGpuData v, int vdcIndex);
}
}

View File

@ -23,5 +23,6 @@ namespace BizHawk.Emulation.Cores
public const string Gpgx = "Genplus-gx";
public const string PceHawk = "PCEHawk";
public const string TurboNyma = "TurboNyma";
public const string TurboTurboNyma = "TurboTurboNyma";
}
}

View File

@ -99,8 +99,11 @@ namespace Mednafen
va_start(argp, format);
vfprintf(t == MDFN_NOTICE_ERROR ? stderr : stdout, format, argp);
}
void MDFN_MidSync(EmulateSpecStruct *espec, const unsigned flags)
{}
void MDFN_MidLineUpdate(EmulateSpecStruct *espec, int y)
{}
bool MDFNSS_StateAction(StateMem *sm, const unsigned load, const bool data_only, const SFORMAT *sf, const char *sname, const bool optional) noexcept
{

View File

@ -50,3 +50,15 @@ SRCS := \
$(call cppdir,video) \
$(filter-out %generate.cpp,$(call cppdir,sound)) \
Interfaces.cpp NymaCore.cpp
# Common sources cores with cdroms need for cdrom support
CD_SRCS := \
mednafen/src/cdrom/CDInterface.cpp \
mednafen/src/cdrom/scsicd.cpp \
mednafen/src/cdrom/CDUtility.cpp \
mednafen/src/cdrom/lec.cpp \
mednafen/src/cdrom/recover-raw.cpp \
mednafen/src/cdrom/l-ec.cpp \
mednafen/src/cdrom/crc32.cpp \
mednafen/src/cdrom/galois.cpp \
cdrom.cpp

@ -1 +1 @@
Subproject commit 3a6060d1006a16c913a57495971e2dfe9e6b976d
Subproject commit 10cc0a77301a11b740f6210626b00418bd83e1ee

227
waterbox/nyma/pce-fast.cpp Normal file
View File

@ -0,0 +1,227 @@
#include "mednafen/src/types.h"
#include "nyma.h"
#include <emulibc.h>
#include "mednafen/src/pce_fast/pce.h"
#include <waterboxcore.h>
#include "mednafen/src/pce_fast/pcecd.h"
#include "mednafen/src/pce_fast/huc.h"
#include "mednafen/src/pce_fast/vdc.h"
#include "mednafen/src/hw_misc/arcade_card/arcade_card.h"
#include "mednafen/src/pce_fast/huc6280.h"
using namespace PCE_Fast;
extern Mednafen::MDFNGI EmulatedPCE_Fast;
void SetupMDFNGameInfo()
{
Mednafen::MDFNGameInfo = &EmulatedPCE_Fast;
}
#define MemoryDomainFunctions(N,R,W)\
static void Access##N(uint8_t* buffer, int64_t address, int64_t count, bool write)\
{\
if (write)\
{\
while (count--)\
W(address++, *buffer++);\
}\
else\
{\
while (count--)\
*buffer++ = R(address++);\
}\
}
#define MemoryDomainBulkFunctions(N,R,W)\
static void Access##N(uint8_t* buffer, int64_t address, int64_t count, bool write)\
{\
if (write)\
{\
W(address, count, buffer);\
}\
else\
{\
R(address, count, buffer);\
}\
}
namespace PCE_Fast
{
extern ArcadeCard* arcade_card;
// extern VCE* vce;
uint8 ZZINPUT_Read(unsigned int A);
uint8 INPUT_Read(unsigned int A)
{
LagFlag = false;
if (InputCallback)
InputCallback();
return ZZINPUT_Read(A);
}
}
uint8 HucReadVirtual(unsigned int A)
{
uint8 wmpr = HuCPU.MPR[A >> 13];
return HuCPU.PCERead[wmpr]((wmpr << 13) | (A & 0x1FFF));
}
void HucWriteVirtual(unsigned int A, uint8 V)
{
uint8 wmpr = HuCPU.MPR[A >> 13];
HuCPU.PCEWrite[wmpr]((wmpr << 13) | (A & 0x1FFF), V);
}
uint8 HucReadActual(unsigned int A)
{
uint8 wmpr = A >> 13;
return HuCPU.PCERead[wmpr](A);
}
void HucWriteActual(unsigned int A, uint8 V)
{
uint8 wmpr = A >> 13;
HuCPU.PCEWrite[wmpr](A, V);
}
MemoryDomainFunctions(ShortBus, HucReadVirtual, HucWriteVirtual);
MemoryDomainFunctions(LongBus, HucReadActual, HucWriteActual);
ECL_EXPORT void GetMemoryAreas(MemoryArea* m)
{
CheatArea* c;
int i = 0;
m[i].Data = (void*)(MemoryFunctionHook)AccessLongBus;
m[i].Name = "System Bus (21 bit)";
m[i].Size = 1 << 21;
m[i].Flags = MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_WORDSIZE1 | MEMORYAREA_FLAGS_FUNCTIONHOOK;
i++;
m[i].Data = (void*)(MemoryFunctionHook)AccessShortBus;
m[i].Name = "System Bus";
m[i].Size = 1 << 16;
m[i].Flags = MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_WORDSIZE1 | MEMORYAREA_FLAGS_FUNCTIONHOOK;
i++;
c = FindCheatArea(0xf8 * 8192);
m[i].Data = c->data;
m[i].Name = "Main Memory";
m[i].Size = c->size;
m[i].Flags = MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_WORDSIZE1 | MEMORYAREA_FLAGS_PRIMARY;
i++;
// TODO: "ROM"
// not that important because we have ROM file domain in the frontend
c = FindCheatArea(0xf7 * 8192);
if (c)
{
m[i].Data = c->data;
m[i].Name = "Battery RAM";
m[i].Size = c->size;
m[i].Flags = MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_WORDSIZE1 | MEMORYAREA_FLAGS_ONEFILLED | MEMORYAREA_FLAGS_SAVERAMMABLE;
i++;
}
if (PCE_IsCD)
{
// pce-fast always adds the full 256kiB of turbocd + super system card as a single block
c = FindCheatArea(0x68 * 8192);
m[i].Data = c->data + 0x18 * 8192;
m[i].Name = "TurboCD RAM";
m[i].Size = 8 * 8192;
m[i].Flags = MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_WORDSIZE1;
i++;
// m[i].Data = (void*)(MemoryFunctionHook)AccessADPCM;
// m[i].Name = "ADPCM RAM";
// m[i].Size = 1 << 16;
// m[i].Flags = MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_WORDSIZE1 | MEMORYAREA_FLAGS_FUNCTIONHOOK;
// i++;
c = FindCheatArea(0x68 * 8192);
m[i].Data = c->data;
m[i].Name = "Super System Card RAM";
m[i].Size = 0x18 * 8192;
m[i].Flags = MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_WORDSIZE1;
i++;
if (arcade_card)
{
m[i].Data = arcade_card->ACRAM;
m[i].Name = "Arcade Card RAM";
m[i].Size = sizeof(arcade_card->ACRAM);
m[i].Flags = MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_WORDSIZE1;
i++;
}
}
c = FindCheatArea(0x40 * 8192);
if (c)
{
// populous
m[i].Data = c->data;
m[i].Name = "Cart Battery RAM";
m[i].Size = c->size;
m[i].Flags = MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_WORDSIZE1;
i++;
}
}
struct VramInfo
{
int32_t BatWidth;
int32_t BatHeight;
const uint32_t* PaletteCache;
const uint8_t* BackgroundCache;
const uint8_t* SpriteCache;
const uint16_t* Vram;
};
static uint8_t* SpriteCache;
static const int bat_width_tab[4] = { 32, 64, 128, 128 };
static const int bat_height_tab[2] = { 32, 64 };
ECL_EXPORT void GetVramInfo(VramInfo& v, int vdcIndex)
{
// pce-fast does have a spr_tile_cache,
// but it's only updated when a particular vram area is actually rendered as a sprite
if (!SpriteCache)
SpriteCache = (uint8_t*)alloc_invisible(0x20000);
auto& vdc = vdc_chips[vdcIndex];
v.BatWidth = bat_width_tab[(vdc.MWR >> 4) & 3];
v.BatHeight = bat_height_tab[(vdc.MWR >> 6) & 1];
v.PaletteCache = vce.color_table_cache;
v.BackgroundCache = (uint8_t*)vdc.bg_tile_cache;
v.SpriteCache = SpriteCache;
v.Vram = vdc.VRAM;
uint16_t* ssrc = vdc.VRAM;
uint8_t* sdst = SpriteCache;
for (int spriteNum = 0; spriteNum < 512; spriteNum++)
{
auto lsrc = ssrc;
auto ldst = sdst;
for (int line = 0; line < 16; line++)
{
auto a = lsrc[0], b = lsrc[16], c = lsrc[32], d = lsrc[48];
*ldst++ = a >> 15 & 1 | b >> 14 & 2 | c >> 13 & 4 | d >> 12 & 8;
*ldst++ = a >> 14 & 1 | b >> 13 & 2 | c >> 12 & 4 | d >> 11 & 8;
*ldst++ = a >> 13 & 1 | b >> 12 & 2 | c >> 11 & 4 | d >> 10 & 8;
*ldst++ = a >> 12 & 1 | b >> 11 & 2 | c >> 10 & 4 | d >> 9 & 8;
*ldst++ = a >> 11 & 1 | b >> 10 & 2 | c >> 9 & 4 | d >> 8 & 8;
*ldst++ = a >> 10 & 1 | b >> 9 & 2 | c >> 8 & 4 | d >> 7 & 8;
*ldst++ = a >> 9 & 1 | b >> 8 & 2 | c >> 7 & 4 | d >> 6 & 8;
*ldst++ = a >> 8 & 1 | b >> 7 & 2 | c >> 6 & 4 | d >> 5 & 8;
*ldst++ = a >> 7 & 1 | b >> 6 & 2 | c >> 5 & 4 | d >> 4 & 8;
*ldst++ = a >> 6 & 1 | b >> 5 & 2 | c >> 4 & 4 | d >> 3 & 8;
*ldst++ = a >> 5 & 1 | b >> 4 & 2 | c >> 3 & 4 | d >> 2 & 8;
*ldst++ = a >> 4 & 1 | b >> 3 & 2 | c >> 2 & 4 | d >> 1 & 8;
*ldst++ = a >> 3 & 1 | b >> 2 & 2 | c >> 1 & 4 | d >> 0 & 8;
*ldst++ = a >> 2 & 1 | b >> 1 & 2 | c >> 0 & 4 | d << 1 & 8;
*ldst++ = a >> 1 & 1 | b >> 0 & 2 | c << 1 & 4 | d << 2 & 8;
*ldst++ = a >> 0 & 1 | b << 1 & 2 | c << 2 & 4 | d << 3 & 8;
lsrc += 1;
}
ssrc += 64;
sdst += 256;
}
}

View File

@ -0,0 +1,11 @@
include common.mak
SRCS += \
$(call cppdir,pce_fast) \
$(call cppdir,hw_misc/arcade_card) \
$(CD_SRCS) \
pce-fast.cpp
PER_FILE_FLAGS_mednafen/src/pce_fast/input.cpp := -DINPUT_Read=ZZINPUT_Read
include ../common.mak

View File

@ -1,24 +1,11 @@
include common.mak
# $(filter-out %CDAFReader_SF.cpp,$(call cppdir,cdrom))
# $(call cdir,tremor)
# $(call cdir,mpcdec)
# mednafen/src/mthreading/MThreading_POSIX.cpp
SRCS += \
$(filter-out %debug.cpp,$(call cppdir,pce)) \
$(call cppdir,hw_sound/pce_psg) \
$(call cppdir,hw_misc/arcade_card) \
$(call cppdir,hw_video/huc6270) \
mednafen/src/cdrom/CDInterface.cpp \
mednafen/src/cdrom/scsicd.cpp \
mednafen/src/cdrom/CDUtility.cpp \
mednafen/src/cdrom/lec.cpp \
mednafen/src/cdrom/recover-raw.cpp \
mednafen/src/cdrom/l-ec.cpp \
mednafen/src/cdrom/crc32.cpp \
mednafen/src/cdrom/galois.cpp \
cdrom.cpp \
$(CD_SRCS) \
pce.cpp
PER_FILE_FLAGS_mednafen/src/pce/input.cpp := -DINPUT_Read=ZZINPUT_Read