mirror of https://github.com/bsnes-emu/bsnes.git
Update to higan and icarus v095r17 release.
byuu says: higan supports Event mapping again. Further, icarus can now detect Event ROMs and MSU1 games. Event ROMs must be named "program.rom", "slot-(1,2,3).rom" MSU1 games must contain "msu1.rom"; and tracks must be named "track-#.pcm" When importing the CC'92, PF'94 ROMs, the program.rom and slot-(1,2,3).rom files must be concatenated. The DSP firmware can optionally be separate, but I'd recommend you go ahead and merge it all to one file. Especially since that common "higan DSP pack" floating around on the web left out the DSP1 ROMs (only has DSP1B) for god knows what reason. There is no support for loading "game.sfc+game.msu+game-*.pcm", because I'm not going to support trying to pull in all of those files through importing. Games will have to be distributed as game folders to use MSU1. The MSU1 icarus support is simply so your game folders won't require an unstable manifest.bml file to be played. So once they're in there, they are good for life. Note: the Event sizes in icarus' SFC heuristics are wrong for appended firmware. Change from 0xXX8000 to 0xXX2000 and it works fine. Will be fixed in r18. Added Sintendo's flickering fixes. The window one's a big help for regular controls, but the ListView double buffering does nothing for me on Windows 7 :( Fairly sure I know why, but too lazy to try and fix that now. Also fixes the mMenu thing.
This commit is contained in:
parent
2a4eb1cfc8
commit
0253db8685
|
@ -7,7 +7,7 @@ using namespace nall;
|
||||||
|
|
||||||
namespace Emulator {
|
namespace Emulator {
|
||||||
static const string Name = "higan";
|
static const string Name = "higan";
|
||||||
static const string Version = "095.16";
|
static const string Version = "095.17";
|
||||||
static const string Author = "byuu";
|
static const string Author = "byuu";
|
||||||
static const string License = "GPLv3";
|
static const string License = "GPLv3";
|
||||||
static const string Website = "http://byuu.org/";
|
static const string Website = "http://byuu.org/";
|
||||||
|
|
|
@ -44,6 +44,7 @@ auto mMenu::remove(sAction action) -> type& {
|
||||||
state.actions[n]->adjustOffset(-1);
|
state.actions[n]->adjustOffset(-1);
|
||||||
}
|
}
|
||||||
action->setParent();
|
action->setParent();
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto mMenu::reset() -> type& {
|
auto mMenu::reset() -> type& {
|
||||||
|
|
|
@ -23,7 +23,7 @@ static auto CALLBACK ListView_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPA
|
||||||
|
|
||||||
auto pListView::construct() -> void {
|
auto pListView::construct() -> void {
|
||||||
hwnd = CreateWindowEx(
|
hwnd = CreateWindowEx(
|
||||||
WS_EX_CLIENTEDGE, WC_LISTVIEW, L"",
|
WS_EX_CLIENTEDGE | LVS_EX_DOUBLEBUFFER, WC_LISTVIEW, L"",
|
||||||
WS_CHILD | WS_TABSTOP | LVS_REPORT | LVS_SHOWSELALWAYS,
|
WS_CHILD | WS_TABSTOP | LVS_REPORT | LVS_SHOWSELALWAYS,
|
||||||
0, 0, 0, 0, _parentHandle(), nullptr, GetModuleHandle(0), 0
|
0, 0, 0, 0, _parentHandle(), nullptr, GetModuleHandle(0), 0
|
||||||
);
|
);
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
namespace hiro {
|
namespace hiro {
|
||||||
|
|
||||||
static const unsigned FixedStyle = WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX | WS_BORDER;
|
static const unsigned FixedStyle = WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX | WS_BORDER | WS_CLIPCHILDREN;
|
||||||
static const unsigned ResizableStyle = WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_THICKFRAME;
|
static const unsigned ResizableStyle = WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_THICKFRAME | WS_CLIPCHILDREN;
|
||||||
|
|
||||||
auto pWindow::construct() -> void {
|
auto pWindow::construct() -> void {
|
||||||
hwnd = CreateWindow(L"hiroWindow", L"", ResizableStyle, 128, 128, 256, 256, 0, 0, GetModuleHandle(0), 0);
|
hwnd = CreateWindow(L"hiroWindow", L"", ResizableStyle, 128, 128, 256, 256, 0, 0, GetModuleHandle(0), 0);
|
||||||
|
|
|
@ -3,6 +3,7 @@ auto Icarus::superFamicomManifest(string location) -> string {
|
||||||
auto files = directory::files(location, "*.rom");
|
auto files = directory::files(location, "*.rom");
|
||||||
concatenate(buffer, {location, "program.rom"});
|
concatenate(buffer, {location, "program.rom"});
|
||||||
concatenate(buffer, {location, "data.rom" });
|
concatenate(buffer, {location, "data.rom" });
|
||||||
|
for(auto& file : files.match("slot-*.rom" )) concatenate(buffer, {location, file});
|
||||||
for(auto& file : files.match("*.boot.rom" )) concatenate(buffer, {location, file});
|
for(auto& file : files.match("*.boot.rom" )) concatenate(buffer, {location, file});
|
||||||
for(auto& file : files.match("*.program.rom")) concatenate(buffer, {location, file});
|
for(auto& file : files.match("*.program.rom")) concatenate(buffer, {location, file});
|
||||||
for(auto& file : files.match("*.data.rom" )) concatenate(buffer, {location, file});
|
for(auto& file : files.match("*.data.rom" )) concatenate(buffer, {location, file});
|
||||||
|
@ -23,7 +24,8 @@ auto Icarus::superFamicomManifest(vector<uint8>& buffer, string location, bool*
|
||||||
}
|
}
|
||||||
|
|
||||||
if(settings["icarus/UseHeuristics"].boolean() && !markup) {
|
if(settings["icarus/UseHeuristics"].boolean() && !markup) {
|
||||||
SuperFamicomCartridge cartridge{buffer.data(), buffer.size()};
|
bool hasMSU1 = file::exists({location, "msu1.rom"});
|
||||||
|
SuperFamicomCartridge cartridge{buffer.data(), buffer.size(), hasMSU1};
|
||||||
if(markup = cartridge.markup) {
|
if(markup = cartridge.markup) {
|
||||||
if(firmwareAppended) *firmwareAppended = cartridge.firmware_appended;
|
if(firmwareAppended) *firmwareAppended = cartridge.firmware_appended;
|
||||||
markup.append("\n");
|
markup.append("\n");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
struct SuperFamicomCartridge {
|
struct SuperFamicomCartridge {
|
||||||
SuperFamicomCartridge(const uint8* data, uint size);
|
SuperFamicomCartridge(const uint8* data, uint size, bool has_msu1 = false);
|
||||||
|
|
||||||
string markup;
|
string markup;
|
||||||
|
|
||||||
|
@ -35,6 +35,8 @@ struct SuperFamicomCartridge {
|
||||||
SA1,
|
SA1,
|
||||||
LoROMSatellaview,
|
LoROMSatellaview,
|
||||||
HiROMSatellaview,
|
HiROMSatellaview,
|
||||||
|
CampusChallenge92,
|
||||||
|
Powerfest94,
|
||||||
|
|
||||||
//invalid types
|
//invalid types
|
||||||
Unknown,
|
Unknown,
|
||||||
|
@ -84,7 +86,7 @@ struct SuperFamicomCartridge {
|
||||||
bool has_st018 = false;
|
bool has_st018 = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
SuperFamicomCartridge::SuperFamicomCartridge(const uint8* data, uint size) {
|
SuperFamicomCartridge::SuperFamicomCartridge(const uint8* data, uint size, bool has_msu1) {
|
||||||
//skip copier header
|
//skip copier header
|
||||||
if((size & 0x7fff) == 512) data += 512, size -= 512;
|
if((size & 0x7fff) == 512) data += 512, size -= 512;
|
||||||
|
|
||||||
|
@ -376,6 +378,47 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8* data, uint size) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if(type == Type::CampusChallenge92) {
|
||||||
|
markup.append(
|
||||||
|
" event=CC92 timer=360\n"
|
||||||
|
" map address=c0,e0:0000\n"
|
||||||
|
" map=mcu address=00-1f,80-9f:8000-ffff\n"
|
||||||
|
" rom name=program.rom size=0x40000\n"
|
||||||
|
" rom name=slot-1.rom size=0x80000\n"
|
||||||
|
" rom name=slot-2.rom size=0x80000\n"
|
||||||
|
" rom name=slot-3.rom size=0x80000\n"
|
||||||
|
" ram name=save.ram size=0x2000 volatile\n"
|
||||||
|
" map address=70-7d,f0-ff:0000-7fff mask=0x8000\n"
|
||||||
|
" necdsp model=uPD7725 frequency=8000000\n"
|
||||||
|
" map address=20-3f,a0-bf:8000-ffff mask=0x7fff\n"
|
||||||
|
" prom name=dsp1.program.rom size=0x1800\n"
|
||||||
|
" drom name=dsp1.data.rom size=0x800\n"
|
||||||
|
" dram name=dsp1.data.ram size=0x200 volatile\n"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(type == Type::Powerfest94) {
|
||||||
|
markup.append(
|
||||||
|
" event=PF94 timer=360\n"
|
||||||
|
" map address=10,20:6000\n"
|
||||||
|
" map=mcu address=00-3f,80-bf:8000-ffff\n"
|
||||||
|
" map=mcu address=c0-ff:0000-ffff\n"
|
||||||
|
" rom name=program.rom size=0x40000\n"
|
||||||
|
" rom name=slot-1.rom size=0x80000\n"
|
||||||
|
" rom name=slot-2.rom size=0x80000\n"
|
||||||
|
" rom name=slot-3.rom size=0x100000\n"
|
||||||
|
" ram name=save.ram size=0x2000 volatile\n"
|
||||||
|
" map address=30-3f,b0-bf:6000-7fff mask=0xe000\n"
|
||||||
|
" necdsp model=uPD7725 frequency=8000000\n"
|
||||||
|
" map address=00-0f,80-8f:6000-7fff mask=0xfff\n"
|
||||||
|
" prom name=dsp1.program.rom size=0x1800\n"
|
||||||
|
" drom name=dsp1.data.rom size=0x800\n"
|
||||||
|
" dram name=dsp1.data.ram size=0x200 volatile\n"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(has_sharprtc) {
|
if(has_sharprtc) {
|
||||||
markup.append(
|
markup.append(
|
||||||
" sharprtc\n"
|
" sharprtc\n"
|
||||||
|
@ -481,6 +524,14 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8* data, uint size) {
|
||||||
" dram name=save.ram size=0x4000\n"
|
" dram name=save.ram size=0x4000\n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(has_msu1) {
|
||||||
|
markup.append(
|
||||||
|
" msu1\n"
|
||||||
|
" map address=00-3f,80-bf:2000-2007\n"
|
||||||
|
" rom name=msu1.rom\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SuperFamicomCartridge::readHeader(const uint8* data, uint size) -> void {
|
auto SuperFamicomCartridge::readHeader(const uint8* data, uint size) -> void {
|
||||||
|
@ -500,6 +551,9 @@ auto SuperFamicomCartridge::readHeader(const uint8* data, uint size) -> void {
|
||||||
const uint8 company = data[index + Company];
|
const uint8 company = data[index + Company];
|
||||||
const uint8 regionid = data[index + CartRegion] & 0x7f;
|
const uint8 regionid = data[index + CartRegion] & 0x7f;
|
||||||
|
|
||||||
|
const uint16 complement = data[index + Complement] | data[index + Complement + 1] << 8;
|
||||||
|
const uint16 checksum = data[index + Checksum] | data[index + Checksum + 1] << 8;
|
||||||
|
|
||||||
this->rom_size = size;
|
this->rom_size = size;
|
||||||
ram_size = 1024 << (data[index + RamSize] & 7);
|
ram_size = 1024 << (data[index + RamSize] & 7);
|
||||||
if(ram_size == 1024) ram_size = 0; //no RAM present
|
if(ram_size == 1024) ram_size = 0; //no RAM present
|
||||||
|
@ -544,7 +598,24 @@ auto SuperFamicomCartridge::readHeader(const uint8* data, uint size) -> void {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//detect standard carts
|
//detect competition carts
|
||||||
|
if(!memcmp(data + index, "\x00\x08\x22\x02\x1c\x00\x10\x00\x08\x65\x80\x84\x20\x00\x22\x25\x00\x83\x0c\x80\x10", 21)
|
||||||
|
&& complement == 0x0100 && checksum == 0x2d02 && (size == 0x1c0000 || size == 0x1c8000)) {
|
||||||
|
type = Type::CampusChallenge92; //dark title screen version
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!memcmp(data + index, "\xc9\x80\x80\x44\x15\x00\x62\x09\x29\xa0\x52\x70\x50\x12\x05\x35\x31\x63\xc0\x22\x01", 21)
|
||||||
|
&& complement == 0x2011 && checksum == 0xf8c0 && (size == 0x240000 || size == 0x248000)) {
|
||||||
|
type = Type::Powerfest94; //10,000 points version
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!memcmp(data + index, "PREHISTORIK MAN ", 21)
|
||||||
|
&& complement == 0xffff && checksum == 0x0000 && (size == 0x240000 || size == 0x248000)) {
|
||||||
|
type = Type::Powerfest94; //1,000,000 points version
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//detect presence of BS-X flash cartridge connector (reads extended header information)
|
//detect presence of BS-X flash cartridge connector (reads extended header information)
|
||||||
if(data[index - 14] == 'Z') {
|
if(data[index - 14] == 'Z') {
|
||||||
|
@ -578,8 +649,11 @@ auto SuperFamicomCartridge::readHeader(const uint8* data, uint size) -> void {
|
||||||
type = Type::LoROM;
|
type = Type::LoROM;
|
||||||
} else if(index == 0xffc0) {
|
} else if(index == 0xffc0) {
|
||||||
type = Type::HiROM;
|
type = Type::HiROM;
|
||||||
} else { //index == 0x40ffc0
|
} else if(index == 0x40ffc0) {
|
||||||
type = Type::ExHiROM;
|
type = Type::ExHiROM;
|
||||||
|
} else {
|
||||||
|
type = Type::Unknown;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,8 +80,8 @@ auto CPU::enter() -> void {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto CPU::enable() -> void {
|
auto CPU::enable() -> void {
|
||||||
function<uint8 (uint)> reader = {&CPU::mmio_read, (CPU*)&cpu};
|
function<auto (uint, uint8) -> uint8> reader{&CPU::mmio_read, (CPU*)&cpu};
|
||||||
function<void (uint, uint8)> writer = {&CPU::mmio_write, (CPU*)&cpu};
|
function<auto (uint, uint8) -> void> writer{&CPU::mmio_write, (CPU*)&cpu};
|
||||||
|
|
||||||
bus.map(reader, writer, 0x00, 0x3f, 0x2140, 0x2183);
|
bus.map(reader, writer, 0x00, 0x3f, 0x2140, 0x2183);
|
||||||
bus.map(reader, writer, 0x80, 0xbf, 0x2140, 0x2183);
|
bus.map(reader, writer, 0x80, 0xbf, 0x2140, 0x2183);
|
||||||
|
@ -95,7 +95,7 @@ auto CPU::enable() -> void {
|
||||||
bus.map(reader, writer, 0x00, 0x3f, 0x4300, 0x437f);
|
bus.map(reader, writer, 0x00, 0x3f, 0x4300, 0x437f);
|
||||||
bus.map(reader, writer, 0x80, 0xbf, 0x4300, 0x437f);
|
bus.map(reader, writer, 0x80, 0xbf, 0x4300, 0x437f);
|
||||||
|
|
||||||
reader = [](uint addr) { return cpu.wram[addr]; };
|
reader = [](uint addr, uint8 data) { return cpu.wram[addr]; };
|
||||||
writer = [](uint addr, uint8 data) { cpu.wram[addr] = data; };
|
writer = [](uint addr, uint8 data) { cpu.wram[addr] = data; };
|
||||||
|
|
||||||
bus.map(reader, writer, 0x00, 0x3f, 0x0000, 0x1fff, 0x002000);
|
bus.map(reader, writer, 0x00, 0x3f, 0x0000, 0x1fff, 0x002000);
|
||||||
|
@ -128,8 +128,8 @@ auto CPU::reset() -> void {
|
||||||
regs.mdr = 0x00;
|
regs.mdr = 0x00;
|
||||||
regs.wai = false;
|
regs.wai = false;
|
||||||
|
|
||||||
regs.pc.l = bus.read(0xfffc);
|
regs.pc.l = bus.read(0xfffc, regs.mdr);
|
||||||
regs.pc.h = bus.read(0xfffd);
|
regs.pc.h = bus.read(0xfffd, regs.mdr);
|
||||||
regs.pc.b = 0x00;
|
regs.pc.b = 0x00;
|
||||||
|
|
||||||
status.nmi_valid = false;
|
status.nmi_valid = false;
|
||||||
|
|
|
@ -14,7 +14,7 @@ struct CPU : Processor::R65816, Thread, public PPUcounter {
|
||||||
auto interrupt_pending() -> bool;
|
auto interrupt_pending() -> bool;
|
||||||
auto port_read(uint8 port) -> uint8;
|
auto port_read(uint8 port) -> uint8;
|
||||||
auto port_write(uint8 port, uint8 data) -> void;
|
auto port_write(uint8 port, uint8 data) -> void;
|
||||||
auto mmio_read(uint addr) -> uint8;
|
auto mmio_read(uint addr, uint8 data) -> uint8;
|
||||||
auto mmio_write(uint addr, uint8 data) -> void;
|
auto mmio_write(uint addr, uint8 data) -> void;
|
||||||
|
|
||||||
auto op_io() -> void;
|
auto op_io() -> void;
|
||||||
|
|
|
@ -15,7 +15,7 @@ auto CPU::dma_addr_valid(uint abus) -> bool {
|
||||||
|
|
||||||
auto CPU::dma_read(uint abus) -> uint8 {
|
auto CPU::dma_read(uint abus) -> uint8 {
|
||||||
if(dma_addr_valid(abus) == false) return 0x00;
|
if(dma_addr_valid(abus) == false) return 0x00;
|
||||||
return bus.read(abus);
|
return bus.read(abus, regs.mdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto CPU::dma_write(bool valid, uint addr, uint8 data) -> void {
|
auto CPU::dma_write(bool valid, uint addr, uint8 data) -> void {
|
||||||
|
@ -28,7 +28,7 @@ auto CPU::dma_transfer(bool direction, uint8 bbus, uint abus) -> void {
|
||||||
add_clocks(8);
|
add_clocks(8);
|
||||||
dma_write(dma_transfer_valid(bbus, abus), 0x2100 | bbus, data);
|
dma_write(dma_transfer_valid(bbus, abus), 0x2100 | bbus, data);
|
||||||
} else {
|
} else {
|
||||||
uint8 data = dma_transfer_valid(bbus, abus) ? bus.read(0x2100 | bbus) : 0x00;
|
uint8 data = dma_transfer_valid(bbus, abus) ? bus.read(0x2100 | bbus, regs.mdr) : 0x00;
|
||||||
add_clocks(8);
|
add_clocks(8);
|
||||||
dma_write(dma_addr_valid(abus), abus, data);
|
dma_write(dma_addr_valid(abus), abus, data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ auto CPU::op_io() -> void {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto CPU::op_read(uint addr) -> uint8 {
|
auto CPU::op_read(uint addr) -> uint8 {
|
||||||
regs.mdr = bus.read(addr);
|
regs.mdr = bus.read(addr, regs.mdr);
|
||||||
add_clocks(speed(addr));
|
add_clocks(speed(addr));
|
||||||
return regs.mdr;
|
return regs.mdr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
auto CPU::mmio_read(uint addr) -> uint8 {
|
auto CPU::mmio_read(uint addr, uint8 data) -> uint8 {
|
||||||
if((addr & 0xffc0) == 0x2140) {
|
if((addr & 0xffc0) == 0x2140) {
|
||||||
synchronizeSMP();
|
synchronizeSMP();
|
||||||
return smp.port_read(addr & 3);
|
return smp.port_read(addr & 3);
|
||||||
|
@ -6,7 +6,7 @@ auto CPU::mmio_read(uint addr) -> uint8 {
|
||||||
|
|
||||||
switch(addr & 0xffff) {
|
switch(addr & 0xffff) {
|
||||||
case 0x2180: {
|
case 0x2180: {
|
||||||
uint8 result = bus.read(0x7e0000 | status.wram_addr);
|
uint8 result = bus.read(0x7e0000 | status.wram_addr, regs.mdr);
|
||||||
status.wram_addr = (status.wram_addr + 1) & 0x01ffff;
|
status.wram_addr = (status.wram_addr + 1) & 0x01ffff;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -92,7 +92,7 @@ auto CPU::mmio_read(uint addr) -> uint8 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return regs.mdr;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto CPU::mmio_write(uint addr, uint8 data) -> void {
|
auto CPU::mmio_write(uint addr, uint8 data) -> void {
|
||||||
|
|
|
@ -568,7 +568,7 @@ auto PPU::mmio_r213f() -> uint8 {
|
||||||
return regs.ppu2_mdr;
|
return regs.ppu2_mdr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto PPU::mmio_read(uint addr) -> uint8 {
|
auto PPU::mmio_read(uint addr, uint8 data) -> uint8 {
|
||||||
cpu.synchronizePPU();
|
cpu.synchronizePPU();
|
||||||
|
|
||||||
switch(addr & 0xffff) {
|
switch(addr & 0xffff) {
|
||||||
|
@ -604,7 +604,7 @@ auto PPU::mmio_read(uint addr) -> uint8 {
|
||||||
case 0x213f: return mmio_r213f(); //STAT78
|
case 0x213f: return mmio_r213f(); //STAT78
|
||||||
}
|
}
|
||||||
|
|
||||||
return cpu.regs.mdr;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto PPU::mmio_write(uint addr, uint8 data) -> void {
|
auto PPU::mmio_write(uint addr, uint8 data) -> void {
|
||||||
|
|
|
@ -196,7 +196,7 @@ auto mmio_r213d() -> uint8; //OPVCT
|
||||||
auto mmio_r213e() -> uint8; //STAT77
|
auto mmio_r213e() -> uint8; //STAT77
|
||||||
auto mmio_r213f() -> uint8; //STAT78
|
auto mmio_r213f() -> uint8; //STAT78
|
||||||
|
|
||||||
auto mmio_read(uint addr) -> uint8;
|
auto mmio_read(uint addr, uint8 data) -> uint8;
|
||||||
auto mmio_write(uint addr, uint8 data) -> void;
|
auto mmio_write(uint addr, uint8 data) -> void;
|
||||||
|
|
||||||
auto latch_counters() -> void;
|
auto latch_counters() -> void;
|
||||||
|
|
|
@ -150,8 +150,8 @@ auto PPU::frame() -> void {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto PPU::enable() -> void {
|
auto PPU::enable() -> void {
|
||||||
function<uint8 (uint)> reader = {&PPU::mmio_read, (PPU*)&ppu};
|
function<auto (uint, uint8) -> uint8> reader{&PPU::mmio_read, (PPU*)&ppu};
|
||||||
function<void (uint, uint8)> writer = {&PPU::mmio_write, (PPU*)&ppu};
|
function<auto (uint, uint8) -> void> writer{&PPU::mmio_write, (PPU*)&ppu};
|
||||||
|
|
||||||
bus.map(reader, writer, 0x00, 0x3f, 0x2100, 0x213f);
|
bus.map(reader, writer, 0x00, 0x3f, 0x2100, 0x213f);
|
||||||
bus.map(reader, writer, 0x80, 0xbf, 0x2100, 0x213f);
|
bus.map(reader, writer, 0x80, 0xbf, 0x2100, 0x213f);
|
||||||
|
|
|
@ -155,7 +155,7 @@ auto PPU::mmio_update_video_mode() -> void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto PPU::mmio_read(uint addr) -> uint8 {
|
auto PPU::mmio_read(uint addr, uint8 data) -> uint8 {
|
||||||
cpu.synchronizePPU();
|
cpu.synchronizePPU();
|
||||||
|
|
||||||
switch(addr & 0xffff) {
|
switch(addr & 0xffff) {
|
||||||
|
@ -185,7 +185,7 @@ auto PPU::mmio_read(uint addr) -> uint8 {
|
||||||
|
|
||||||
case 0x2137: { //SLHV
|
case 0x2137: { //SLHV
|
||||||
if(cpu.pio() & 0x80) latch_counters();
|
if(cpu.pio() & 0x80) latch_counters();
|
||||||
return cpu.regs.mdr;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x2138: { //OAMDATAREAD
|
case 0x2138: { //OAMDATAREAD
|
||||||
|
@ -273,7 +273,7 @@ auto PPU::mmio_read(uint addr) -> uint8 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return cpu.regs.mdr;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto PPU::mmio_write(uint addr, uint8 data) -> void {
|
auto PPU::mmio_write(uint addr, uint8 data) -> void {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
public:
|
public:
|
||||||
auto mmio_read(uint addr) -> uint8;
|
auto mmio_read(uint addr, uint8 data) -> uint8;
|
||||||
auto mmio_write(uint addr, uint8 data) -> void;
|
auto mmio_write(uint addr, uint8 data) -> void;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -101,8 +101,8 @@ auto PPU::frame() -> void {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto PPU::enable() -> void {
|
auto PPU::enable() -> void {
|
||||||
function<uint8 (uint)> reader = {&PPU::mmio_read, (PPU*)&ppu};
|
function<auto (uint, uint8) -> uint8> reader{&PPU::mmio_read, (PPU*)&ppu};
|
||||||
function<void (uint, uint8)> writer = {&PPU::mmio_write, (PPU*)&ppu};
|
function<auto (uint, uint8) -> void> writer{&PPU::mmio_write, (PPU*)&ppu};
|
||||||
|
|
||||||
bus.map(reader, writer, 0x00, 0x3f, 0x2100, 0x213f);
|
bus.map(reader, writer, 0x00, 0x3f, 0x2100, 0x213f);
|
||||||
bus.map(reader, writer, 0x80, 0xbf, 0x2100, 0x213f);
|
bus.map(reader, writer, 0x80, 0xbf, 0x2100, 0x213f);
|
||||||
|
|
|
@ -177,44 +177,21 @@ auto Cartridge::parseMarkupEvent(Markup::Node root) -> void {
|
||||||
parseMarkupMemory(event.ram, root["ram"], ID::EventRAM, true);
|
parseMarkupMemory(event.ram, root["ram"], ID::EventRAM, true);
|
||||||
|
|
||||||
event.board = Event::Board::CampusChallenge92;
|
event.board = Event::Board::CampusChallenge92;
|
||||||
if(root["name"].text() == "Campus Challenge '92") event.board = Event::Board::CampusChallenge92;
|
if(root.text() == "CC92") event.board = Event::Board::CampusChallenge92;
|
||||||
if(root["name"].text() == "Powerfest '94") event.board = Event::Board::Powerfest94;
|
if(root.text() == "PF94") event.board = Event::Board::Powerfest94;
|
||||||
|
event.timer = root["timer"].natural();
|
||||||
event.revision = root["revision"].text() == "B" ? 2 : 1;
|
|
||||||
lstring part = root["timer"].text().split(":", 1L);
|
|
||||||
if(part.size() == 1) event.timer = part[0].natural();
|
|
||||||
if(part.size() == 2) event.timer = part[0].natural() * 60 + part[1].natural();
|
|
||||||
|
|
||||||
for(auto node : root.find("map")) {
|
for(auto node : root.find("map")) {
|
||||||
|
if(node.text() == "mcu") {
|
||||||
|
parseMarkupMap(node, {&Event::mcuRead, &event}, {&Event::mcuWrite, &event});
|
||||||
|
} else {
|
||||||
parseMarkupMap(node, {&Event::read, &event}, {&Event::write, &event});
|
parseMarkupMap(node, {&Event::read, &event}, {&Event::write, &event});
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
//todo: define and support markup for coprocessor/event
|
|
||||||
if(node["id"].text() == "rom") {
|
|
||||||
Mapping m({&Event::rom_read, &event}, [](unsigned, uint8) {});
|
|
||||||
parseMarkupMap(m, node);
|
|
||||||
mapping.append(m);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(node["id"].text() == "ram") {
|
for(auto node : root["ram"].find("map")) {
|
||||||
Mapping m({&Event::ram_read, &event}, {&Event::ram_write, &event});
|
parseMarkupMap(node, event.ram);
|
||||||
parseMarkupMap(m, node);
|
|
||||||
mapping.append(m);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(node["id"].text() == "dr") {
|
|
||||||
Mapping m([](uint, uint8 data) -> uint8 { return data; }, {&Event::dr, &event});
|
|
||||||
parseMarkupMap(m, node);
|
|
||||||
mapping.append(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(node["id"].text() == "sr") {
|
|
||||||
Mapping m({&Event::sr, &event}, [](uint, uint8) {});
|
|
||||||
parseMarkupMap(m, node);
|
|
||||||
mapping.append(m);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Cartridge::parseMarkupSA1(Markup::Node root) -> void {
|
auto Cartridge::parseMarkupSA1(Markup::Node root) -> void {
|
||||||
|
|
|
@ -4,7 +4,9 @@ namespace SuperFamicom {
|
||||||
|
|
||||||
Event event;
|
Event event;
|
||||||
|
|
||||||
auto Event::Enter() -> void { event.enter(); }
|
auto Event::Enter() -> void {
|
||||||
|
event.enter();
|
||||||
|
}
|
||||||
|
|
||||||
auto Event::enter() -> void {
|
auto Event::enter() -> void {
|
||||||
while(true) {
|
while(true) {
|
||||||
|
@ -60,19 +62,7 @@ auto Event::reset() -> void {
|
||||||
scoreSecondsRemaining = 0;
|
scoreSecondsRemaining = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Event::sr(uint, uint8) -> uint8 {
|
auto Event::mcuRead(uint addr, uint8 data) -> uint8 {
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto Event::dr(uint, uint8 data) -> void {
|
|
||||||
select = data;
|
|
||||||
if(timer && data == 0x09) {
|
|
||||||
timerActive = true;
|
|
||||||
timerSecondsRemaining = timer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto Event::rom_read(uint addr, uint8 data) -> uint8 {
|
|
||||||
if(board == Board::CampusChallenge92) {
|
if(board == Board::CampusChallenge92) {
|
||||||
uint id = 0;
|
uint id = 0;
|
||||||
if(select == 0x09) id = 1;
|
if(select == 0x09) id = 1;
|
||||||
|
@ -108,19 +98,24 @@ auto Event::rom_read(uint addr, uint8 data) -> uint8 {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Event::ram_read(uint addr, uint8 data) -> uint8 {
|
auto Event::mcuWrite(uint addr, uint8 data) -> void {
|
||||||
return ram.read(bus.mirror(addr, ram.size()), data);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto Event::ram_write(uint addr, uint8 data) -> void {
|
|
||||||
return ram.write(bus.mirror(addr, ram.size()), data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Event::read(uint addr, uint8 data) -> uint8 {
|
auto Event::read(uint addr, uint8 data) -> uint8 {
|
||||||
|
if(addr == 0x106000 || addr == 0xc00000) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Event::write(uint addr, uint8 data) -> void {
|
auto Event::write(uint addr, uint8 data) -> void {
|
||||||
|
if(addr == 0x206000 || addr == 0xe00000) {
|
||||||
|
select = data;
|
||||||
|
if(timer && data == 0x09) {
|
||||||
|
timerActive = true;
|
||||||
|
timerSecondsRemaining = timer;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Event::serialize(serializer& s) -> void {
|
auto Event::serialize(serializer& s) -> void {
|
||||||
|
|
|
@ -11,13 +11,8 @@ struct Event : Coprocessor {
|
||||||
auto power() -> void;
|
auto power() -> void;
|
||||||
auto reset() -> void;
|
auto reset() -> void;
|
||||||
|
|
||||||
auto submitScore() -> void;
|
auto mcuRead(uint addr, uint8) -> uint8;
|
||||||
|
auto mcuWrite(uint addr, uint8) -> void;
|
||||||
auto sr(uint, uint8) -> uint8;
|
|
||||||
auto dr(uint, uint8 data) -> void;
|
|
||||||
auto rom_read(uint addr, uint8) -> uint8;
|
|
||||||
auto ram_read(uint addr, uint8) -> uint8;
|
|
||||||
auto ram_write(uint addr, uint8 data) -> void;
|
|
||||||
|
|
||||||
auto read(uint addr, uint8 data) -> uint8;
|
auto read(uint addr, uint8 data) -> uint8;
|
||||||
auto write(uint addr, uint8 data) -> void;
|
auto write(uint addr, uint8 data) -> void;
|
||||||
|
@ -28,7 +23,6 @@ struct Event : Coprocessor {
|
||||||
MappedRAM ram;
|
MappedRAM ram;
|
||||||
|
|
||||||
enum class Board : uint { CampusChallenge92, Powerfest94 } board;
|
enum class Board : uint { CampusChallenge92, Powerfest94 } board;
|
||||||
uint revision;
|
|
||||||
uint timer;
|
uint timer;
|
||||||
|
|
||||||
privileged:
|
privileged:
|
||||||
|
|
Loading…
Reference in New Issue