mirror of https://github.com/bsnes-emu/bsnes.git
Update to v106r21 release.
byuu says: Changelog: - higan: target-tomoko has been renamed to target-higan - Super Famicom: event has been renamed to processor(architecture=uPD78214) - Super Famicom: SNES-EVENT supported once more; under board IDs EVENT-CC92 and EVENT-PF94 - Super Famicom: SNES-EVENT preliminarily set up to use DIP switch settings ala the Nintendo Super System (incomplete) - Super Famicom: MCC PSRAM moved inside the MCU, as it is remappable - Super Famicom: MCC emulation rewritten from scratch; it is now vastly more accurate than before - Super Famicom: added BSC-1A5B9P-01 board definition to database; corrected BS-MCC-RAM board definition - Super Famicom: moved SHVC-LN3B-01 RAM outside of processor(identifier=SDD1) - higan: when selecting a default game to load for a new system entry, it will change the system option to match the media type - higan: the load text box on the system entry window is now editable; can be used to erase entries - icarus: fixed bug in Famicom importing - icarus: importing unappended SNES coprocessor firmware will now rename the firmware properly - hiro/GTK,Qt: WM_CLASS is now set correctly in `argv[0]`, so applications should show “higan”, “icarus” instead of “hiro” now Note: if you wish to run the BS-X town cartridge, the database currently lists the download RAM as type “PSRAM”. This needs to be changed to “RAM” in order to load properly. Otherwise, the emulator will bomb out on the load window, because BSC-1A5B9P-01 expects PSRAM to always be present, but it won't find it with the wrong memory type. I'll correct this in the database in a later release. For now, you can copy the game portion of the manifest to a new manifest.bml file and drop it into the gamepak folder until I fix the database.
This commit is contained in:
parent
210306e661
commit
8bbbc5e737
|
@ -2,7 +2,7 @@ build := performance
|
|||
include ../nall/GNUmakefile
|
||||
|
||||
binary := application
|
||||
target := tomoko
|
||||
target := higan
|
||||
objects := libco emulator audio video resource
|
||||
|
||||
flags += -I. -I..
|
||||
|
|
|
@ -12,7 +12,7 @@ using namespace nall;
|
|||
|
||||
namespace Emulator {
|
||||
static const string Name = "higan";
|
||||
static const string Version = "106.20";
|
||||
static const string Version = "106.21";
|
||||
static const string Author = "byuu";
|
||||
static const string License = "GPLv3";
|
||||
static const string Website = "https://byuu.org/";
|
||||
|
|
|
@ -53,7 +53,7 @@ auto Cartridge::loadCartridge(Markup::Node node) -> void {
|
|||
if(auto node = board["slot(type=SufamiTurbo)[0]"]) loadSufamiTurboA(node);
|
||||
if(auto node = board["slot(type=SufamiTurbo)[1]"]) loadSufamiTurboB(node);
|
||||
if(auto node = board["dip"]) loadDIP(node);
|
||||
if(auto node = board["event"]) loadEvent(node);
|
||||
if(auto node = board["processor(architecture=uPD78214)"]) loadEvent(node);
|
||||
if(auto node = board["processor(architecture=W65C816S)"]) loadSA1(node);
|
||||
if(auto node = board["processor(architecture=GSU)"]) loadSuperFX(node);
|
||||
if(auto node = board["processor(architecture=ARM6)"]) loadARMDSP(node);
|
||||
|
@ -193,17 +193,13 @@ auto Cartridge::loadMCC(Markup::Node node) -> void {
|
|||
if(auto memory = mcu["memory(type=ROM,content=Program)"]) {
|
||||
loadMemory(mcc.rom, memory, File::Required);
|
||||
}
|
||||
if(auto memory = mcu["memory(type=RAM,content=Download)"]) {
|
||||
loadMemory(mcc.psram, memory, File::Optional);
|
||||
}
|
||||
if(auto slot = mcu["slot(type=BSMemory)"]) {
|
||||
loadBSMemory(slot);
|
||||
}
|
||||
}
|
||||
|
||||
if(auto memory = node["memory(type=RAM,content=Download)"]) {
|
||||
loadMemory(mcc.ram, memory, File::Optional);
|
||||
for(auto map : memory.find("map")) {
|
||||
loadMap(map, mcc.ram);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//slot(type=BSMemory)
|
||||
|
@ -256,6 +252,7 @@ auto Cartridge::loadSufamiTurboB(Markup::Node node) -> void {
|
|||
}
|
||||
}
|
||||
|
||||
//dip
|
||||
auto Cartridge::loadDIP(Markup::Node node) -> void {
|
||||
has.DIP = true;
|
||||
dip.value = platform->dipSettings(node);
|
||||
|
@ -265,22 +262,34 @@ auto Cartridge::loadDIP(Markup::Node node) -> void {
|
|||
}
|
||||
}
|
||||
|
||||
//processor(architecture=uPD78214)
|
||||
auto Cartridge::loadEvent(Markup::Node node) -> void {
|
||||
auto roms = node.find("rom");
|
||||
if(roms.size() != 4) return;
|
||||
|
||||
has.Event = true;
|
||||
event.board = Event::Board::Unknown;
|
||||
if(node["identifier"].text() == "Campus Challenge '92") event.board = Event::Board::CampusChallenge92;
|
||||
if(node["identifier"].text() == "PowerFest '94") event.board = Event::Board::PowerFest94;
|
||||
|
||||
for(uint n : range(4)) loadMemory(event.rom[n], roms[n], File::Required);
|
||||
for(auto map : node.find("map")) {
|
||||
loadMap(map, {&Event::read, &event}, {&Event::write, &event});
|
||||
}
|
||||
|
||||
event.board = Event::Board::CampusChallenge92;
|
||||
if(node.text() == "CC92") event.board = Event::Board::CampusChallenge92;
|
||||
if(node.text() == "PF94") event.board = Event::Board::Powerfest94;
|
||||
event.timer = node["timer"].natural();
|
||||
|
||||
for(auto leaf : node.find("map")) leaf.text() == "mcu"
|
||||
? loadMap(leaf, {&Event::mcuRead, &event}, {&Event::mcuWrite, &event})
|
||||
: loadMap(leaf, {&Event::read, &event}, {&Event::write, &event});
|
||||
if(auto mcu = node["mcu"]) {
|
||||
for(auto map : mcu.find("map")) {
|
||||
loadMap(map, {&Event::mcuRead, &event}, {&Event::mcuWrite, &event});
|
||||
}
|
||||
if(auto memory = mcu["memory(type=ROM,content=Program)"]) {
|
||||
loadMemory(event.rom[0], memory, File::Required);
|
||||
}
|
||||
if(auto memory = mcu["memory(type=ROM,content=Level-1)"]) {
|
||||
loadMemory(event.rom[1], memory, File::Required);
|
||||
}
|
||||
if(auto memory = mcu["memory(type=ROM,content=Level-2)"]) {
|
||||
loadMemory(event.rom[2], memory, File::Required);
|
||||
}
|
||||
if(auto memory = mcu["memory(type=ROM,content=Level-3)"]) {
|
||||
loadMemory(event.rom[3], memory, File::Required);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//processor(architecture=W65C816S)
|
||||
|
|
|
@ -63,8 +63,10 @@ auto Cartridge::saveRAM(Markup::Node node) -> void {
|
|||
|
||||
//processor(identifier=MCC)
|
||||
auto Cartridge::saveMCC(Markup::Node node) -> void {
|
||||
if(auto memory = node["memory(type=RAM,content=Download)"]) {
|
||||
saveMemory(mcc.ram, memory);
|
||||
if(auto mcu = node["mcu"]) {
|
||||
if(auto memory = mcu["memory(type=RAM,content=Download)"]) {
|
||||
saveMemory(mcc.psram, memory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,6 +44,11 @@ auto Event::power() -> void {
|
|||
rom[2].writeProtect(true);
|
||||
rom[3].writeProtect(true);
|
||||
|
||||
//DIP switches 0-3 control the time: 3 minutes + 0-15 extra minutes
|
||||
timer = (3 + dip.value.bits(0,3)) * 60; //in seconds
|
||||
//DIP switches 4-5 serve an unknown purpose
|
||||
//DIP switches 6-7 are not connected
|
||||
|
||||
status = 0x00;
|
||||
select = 0x00;
|
||||
timerActive = false;
|
||||
|
@ -66,7 +71,7 @@ auto Event::mcuRead(uint24 addr, uint8 data) -> uint8 {
|
|||
}
|
||||
}
|
||||
|
||||
if(board == Board::Powerfest94) {
|
||||
if(board == Board::PowerFest94) {
|
||||
uint id = 0;
|
||||
if(select == 0x09) id = 1;
|
||||
if(select == 0x0c) id = 2;
|
||||
|
|
|
@ -1,6 +1,63 @@
|
|||
//SNES-EVENT board emulation:
|
||||
//HLE of the NEC uPD78P214GC processor found on SNES-EVENT PCBs, used by:
|
||||
//* Campus Challenge '92
|
||||
//* Powerfest '94
|
||||
//* PowerFest '94
|
||||
|
||||
//The NEC uPD78214 family are 8-bit microprocessors containing:
|
||||
//* UART/CSI serial interface
|
||||
//* ALU (MUL, DIV, BCD)
|
||||
//* interrupts (12 internal; 7 external; 2 priority levels)
|
||||
//* 16384 x 8-bit ROM
|
||||
//* 512 x 8-bit RAM
|
||||
//* 4 x timer/counters
|
||||
|
||||
//None of the SNES-EVENT games have had their uPD78214 firmware dumped.
|
||||
//As such, our only option is very basic high-level emulation, provided here.
|
||||
|
||||
/* Unverified memory maps:
|
||||
|
||||
game
|
||||
label: Campus Challenge '92
|
||||
board
|
||||
memory type=RAM content=Save size=0x2000 volatile
|
||||
map address=70-7d,f0-ff:0000-7fff mask=0x8000
|
||||
processor manufacturer=NEC architecture=uPD78214
|
||||
map address=c0,e0:0000
|
||||
mcu
|
||||
map address=00-1f,80-9f:8000-ffff
|
||||
memory type=ROM content=Program size=0x40000 label: Menu
|
||||
memory type=ROM content=Level-1 size=0x80000 label: Super Mario World
|
||||
memory type=ROM content=Level-2 size=0x80000 label: F-Zero
|
||||
memory type=ROM content=Level-3 size=0x80000 label: Pilotwings
|
||||
dip switches=8
|
||||
processor manufacturer=NEC architecture=uPD7725 identifier=DSP1
|
||||
map address=20-3f,a0-bf:8000-ffff mask=0x7fff
|
||||
memory type=ROM content=Program size=0x1800 architecture=uPD7725
|
||||
memory type=ROM content=Data size=0x800 architecture=uPD7725
|
||||
memory type=RAM content=Data size=0x200 architecture=uPD7725 volatile
|
||||
oscillator frequency=7600000
|
||||
|
||||
game
|
||||
label: PowerFest '94
|
||||
board
|
||||
memory type=RAM content=Save size=0x2000 volatile
|
||||
map address=30-3f,b0-bf:6000-7fff mask=0xe000
|
||||
processor manufacturer=NEC architecture=uPD78214
|
||||
map address=10,20:6000
|
||||
mcu
|
||||
map address=00-3f,80-bf:8000-ffff
|
||||
map address=c0-ff:0000-ffff
|
||||
memory type=ROM content=Program size=0x40000 label: Menu
|
||||
memory type=ROM content=Level-1 size=0x80000 label: Super Mario Bros.: The Lost Levels
|
||||
memory type=ROM content=Level-2 size=0x80000 label: Super Mario Kart
|
||||
memory type=ROM content=Level-3 size=0x100000 label: Ken Griffey Jr. Presents: Major League Baseball
|
||||
dip switches=8
|
||||
processor manufacturer=NEC architecture=uPD7725 identifier=DSP1
|
||||
map address=00-0f,80-8f:6000-7fff mask=0xfff
|
||||
memory type=ROM content=Program size=0x1800 architecture=uPD7725
|
||||
memory type=ROM content=Data size=0x800 architecture=uPD7725
|
||||
memory type=RAM content=Data size=0x200 architecture=uPD7725 volatile
|
||||
oscillator frequency=7600000
|
||||
*/
|
||||
|
||||
struct Event : Thread {
|
||||
//event.cpp
|
||||
|
@ -18,9 +75,10 @@ struct Event : Thread {
|
|||
//serialization.cpp
|
||||
auto serialize(serializer&) -> void;
|
||||
|
||||
public:
|
||||
MappedRAM rom[4];
|
||||
|
||||
enum class Board : uint { CampusChallenge92, Powerfest94 } board;
|
||||
enum class Board : uint { Unknown, CampusChallenge92, PowerFest94 } board;
|
||||
uint timer;
|
||||
|
||||
private:
|
||||
|
|
|
@ -7,124 +7,254 @@ MCC mcc;
|
|||
|
||||
auto MCC::unload() -> void {
|
||||
rom.reset();
|
||||
ram.reset();
|
||||
psram.reset();
|
||||
}
|
||||
|
||||
auto MCC::power() -> void {
|
||||
rom.writeProtect(true);
|
||||
ram.writeProtect(false);
|
||||
psram.writeProtect(false);
|
||||
|
||||
for(auto n : range(16)) r[n] = 0x00;
|
||||
r[0x07] = 0x80;
|
||||
r[0x08] = 0x80;
|
||||
commit();
|
||||
irq.flag = 0;
|
||||
irq.enable = 0;
|
||||
w.mapping = 1;
|
||||
w.psramEnableLo = 1;
|
||||
w.psramEnableHi = 0;
|
||||
w.psramMapping = 3;
|
||||
w.romEnableLo = 1;
|
||||
w.romEnableHi = 1;
|
||||
w.exEnableLo = 1;
|
||||
w.exEnableHi = 0;
|
||||
w.exMapping = 1;
|
||||
w.bsWritable = 0;
|
||||
w.unknown = 0;
|
||||
x.enable = 0;
|
||||
x.value = 0b0011'1111;
|
||||
memory::copy(&r, &w, sizeof(Registers));
|
||||
}
|
||||
|
||||
auto MCC::memoryAccess(bool write, Memory& memory, uint24 addr, uint8 data) -> uint8 {
|
||||
addr = bus.mirror(addr, memory.size());
|
||||
if(!write) {
|
||||
return memory.read(addr, data);
|
||||
} else {
|
||||
memory.write(addr, data);
|
||||
}
|
||||
}
|
||||
|
||||
//map address=00-3f,80-bf:8000-ffff mask=0x408000
|
||||
//map address=40-7d,c0-ff:0000-ffff
|
||||
auto MCC::mcuAccess(bool write, uint24 addr, uint8 data) -> uint8 {
|
||||
if(addr < 0x400000) {
|
||||
//note: manifest maps 00-3f,80-bf:8000-ffff mask=0x408000 => 00-3f:0000-ffff
|
||||
//the intention is consistency in pre-decoding as much as possible
|
||||
//however, the MCC code is intended to be rewritten; and is too convoluted
|
||||
//so for right now, I'm simply transforming it back to its original state
|
||||
//this is very wasteful; but will be addressed once things are rewritten
|
||||
addr = ((addr & 0x200000) << 2) | ((addr & 0x1f8000) << 1) | 0x8000 | (addr & 0x7fff);
|
||||
}
|
||||
|
||||
if((addr & 0xe08000) == 0x008000) { //$00-1f:8000-ffff
|
||||
if(r07 == 1) {
|
||||
addr = ((addr & 0x1f0000) >> 1) | (addr & 0x7fff);
|
||||
return memoryAccess(write, rom, addr, data);
|
||||
auto MCC::read(uint24 address, uint8 data) -> uint8 {
|
||||
if((address & 0xf0f000) == 0x005000) { //$00-0f:5000-5fff
|
||||
uint4 index = address.bits(16,19);
|
||||
if(x.enable) return x.value.bit(index & 7);
|
||||
switch(index) {
|
||||
case 0: return irq.flag << 7;
|
||||
case 1: return irq.enable << 7;
|
||||
case 2: return r.mapping << 7;
|
||||
case 3: return r.psramEnableLo << 7;
|
||||
case 4: return r.psramEnableHi << 7;
|
||||
case 5: return r.psramMapping.bit(0) << 7;
|
||||
case 6: return r.psramMapping.bit(1) << 7;
|
||||
case 7: return r.romEnableLo << 7;
|
||||
case 8: return r.romEnableHi << 7;
|
||||
case 9: return r.exEnableLo << 7;
|
||||
case 10: return r.exEnableHi << 7;
|
||||
case 11: return r.exMapping << 7;
|
||||
case 12: return r.bsWritable << 7;
|
||||
case 13: return r.unknown << 7;
|
||||
case 14: return 0; //commit (always zero)
|
||||
case 15: return 0; //x.enable (always zero)
|
||||
}
|
||||
}
|
||||
|
||||
if((addr & 0xe08000) == 0x808000) { //$80-9f:8000-ffff
|
||||
if(r08 == 1) {
|
||||
addr = ((addr & 0x1f0000) >> 1) | (addr & 0x7fff);
|
||||
return memoryAccess(write, rom, addr, data);
|
||||
}
|
||||
}
|
||||
|
||||
if((addr & 0xf00000) == 0x400000) { //$40-4f:0000-ffff
|
||||
if(r05 == 0) return memoryAccess(write, ram, addr & 0x0fffff, data);
|
||||
}
|
||||
|
||||
if((addr & 0xf00000) == 0x500000) { //$50-5f:0000-ffff
|
||||
if(r06 == 0) return memoryAccess(write, ram, addr & 0x0fffff, data);
|
||||
}
|
||||
|
||||
if((addr & 0xf00000) == 0x600000) { //$60-6f:0000-ffff
|
||||
if(r03 == 1) return memoryAccess(write, ram, addr & 0x0fffff, data);
|
||||
}
|
||||
|
||||
if((addr & 0xf80000) == 0x700000) { //$70-77:0000-ffff
|
||||
return memoryAccess(write, ram, addr & 0x07ffff, data);
|
||||
}
|
||||
|
||||
if(((addr & 0x408000) == 0x008000) //$00-3f,80-bf:8000-ffff
|
||||
|| ((addr & 0x400000) == 0x400000) //$40-7f,c0-ff:0000-ffff
|
||||
) {
|
||||
if(r02 == 0) addr = ((addr & 0x7f0000) >> 1) | (addr & 0x7fff);
|
||||
Memory& memory = (r01 == 0 ? (Memory&)bsmemory : (Memory&)ram);
|
||||
return memoryAccess(write, memory, addr & 0x7fffff, data);
|
||||
}
|
||||
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
auto MCC::mcuRead(uint24 addr, uint8 data) -> uint8 {
|
||||
return mcuAccess(false, addr, data);
|
||||
}
|
||||
|
||||
auto MCC::mcuWrite(uint24 addr, uint8 data) -> void {
|
||||
mcuAccess(true, addr, data);
|
||||
}
|
||||
|
||||
auto MCC::read(uint24 addr, uint8 data) -> uint8 {
|
||||
if((addr & 0xf0ffff) == 0x005000) { //$00-0f:5000
|
||||
uint8 n = (addr >> 16) & 15;
|
||||
return r[n];
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
auto MCC::write(uint24 addr, uint8 data) -> void {
|
||||
if((addr & 0xf0ffff) == 0x005000) { //$00-0f:5000
|
||||
uint8 n = (addr >> 16) & 15;
|
||||
r[n] = data;
|
||||
if(n == 0x0e && data & 0x80) commit();
|
||||
return;
|
||||
auto MCC::write(uint24 address, uint8 data) -> void {
|
||||
if((address & 0xf0f000) == 0x005000) { //$00-0f:5000-5fff
|
||||
uint4 index = address.bits(16,19);
|
||||
if(x.enable) return x.value.bit(index & 7) = data.bit(7), void();
|
||||
switch(index) {
|
||||
case 1: irq.enable = data.bit(7); break;
|
||||
case 2: w.mapping = data.bit(7); break;
|
||||
case 3: w.psramEnableLo = data.bit(7); break;
|
||||
case 4: w.psramEnableHi = data.bit(7); break;
|
||||
case 5: w.psramMapping.bit(0) = data.bit(7); break;
|
||||
case 6: w.psramMapping.bit(1) = data.bit(7); break;
|
||||
case 7: w.romEnableLo = data.bit(7); break;
|
||||
case 8: w.romEnableHi = data.bit(7); break;
|
||||
case 9: w.exEnableLo = data.bit(7); break;
|
||||
case 10: w.exEnableHi = data.bit(7); break;
|
||||
case 11: w.exMapping = data.bit(7); break;
|
||||
case 12: w.bsWritable = data.bit(7); break;
|
||||
case 13: w.unknown = data.bit(7); break;
|
||||
case 14: if(data.bit(7)) memory::copy(&r, &w, sizeof(Registers)); break;
|
||||
case 15: x.enable = data.bit(7); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto MCC::commit() -> void {
|
||||
r00 = r[0x00] & 0x80;
|
||||
r01 = r[0x01] & 0x80;
|
||||
r02 = r[0x02] & 0x80;
|
||||
r03 = r[0x03] & 0x80;
|
||||
r04 = r[0x04] & 0x80;
|
||||
r05 = r[0x05] & 0x80;
|
||||
r06 = r[0x06] & 0x80;
|
||||
r07 = r[0x07] & 0x80;
|
||||
r08 = r[0x08] & 0x80;
|
||||
r09 = r[0x09] & 0x80;
|
||||
r0a = r[0x0a] & 0x80;
|
||||
r0b = r[0x0b] & 0x80;
|
||||
r0c = r[0x0c] & 0x80;
|
||||
r0d = r[0x0d] & 0x80;
|
||||
r0e = r[0x0e] & 0x80;
|
||||
r0f = r[0x0f] & 0x80;
|
||||
auto MCC::mcuRead(uint24 address, uint8 data) -> uint8 {
|
||||
return mcuAccess(0, address, data);
|
||||
}
|
||||
|
||||
auto MCC::mcuWrite(uint24 address, uint8 data) -> void {
|
||||
return mcuAccess(1, address, data), void();
|
||||
}
|
||||
|
||||
auto MCC::mcuAccess(bool mode, uint24 address, uint8 data) -> uint8 {
|
||||
//[[ROM]]
|
||||
|
||||
if(r.romEnableLo) {
|
||||
if((address & 0xc08000) == 0x008000) { //00-3f:8000-ffff
|
||||
return romAccess(mode, (address & 0x3f0000) >> 1 | (address & 0x7fff), data);
|
||||
}
|
||||
}
|
||||
|
||||
if(r.romEnableHi) {
|
||||
if((address & 0xc08000) == 0x808000) { //80-bf:8000-ffff
|
||||
return romAccess(mode, (address & 0x3f0000) >> 1 | (address & 0x7fff), data);
|
||||
}
|
||||
}
|
||||
|
||||
//[[PSRAM]]
|
||||
|
||||
if(r.psramEnableLo && r.mapping == 0) {
|
||||
if(((address & 0xf08000) == 0x008000 && r.psramMapping == 0) //00-0f:8000-ffff
|
||||
|| ((address & 0xf08000) == 0x208000 && r.psramMapping == 1) //20-2f:8000-ffff
|
||||
|| ((address & 0xf00000) == 0x400000 && r.psramMapping == 2) //40-4f:0000-ffff
|
||||
|| ((address & 0xf00000) == 0x600000 && r.psramMapping == 3) //60-6f:0000-ffff
|
||||
) {
|
||||
return psramAccess(mode, (address & 0x0f0000) >> 1 | (address & 0x7fff), data);
|
||||
}
|
||||
|
||||
if((address & 0xf08000) == 0x700000) { //70-7d:0000-7fff
|
||||
return psramAccess(mode, (address & 0x0f0000) >> 1 | (address & 0x7fff), data);
|
||||
}
|
||||
}
|
||||
|
||||
if(r.psramEnableHi && r.mapping == 0) {
|
||||
if(((address & 0xf08000) == 0x808000 && r.psramMapping == 0) //80-8f:8000-ffff
|
||||
|| ((address & 0xf08000) == 0xa08000 && r.psramMapping == 1) //a0-af:8000-ffff
|
||||
|| ((address & 0xf00000) == 0xc00000 && r.psramMapping == 2) //c0-cf:0000-ffff
|
||||
|| ((address & 0xf00000) == 0xe00000 && r.psramMapping == 3) //e0-ef:0000-ffff
|
||||
) {
|
||||
return psramAccess(mode, (address & 0x0f0000) >> 1 | (address & 0x7fff), data);
|
||||
}
|
||||
|
||||
if((address & 0xf08000) == 0xf00000) { //f0-ff:0000-7fff
|
||||
return psramAccess(mode, (address & 0x0f0000) >> 1 | (address & 0x7fff), data);
|
||||
}
|
||||
}
|
||||
|
||||
if(r.psramEnableLo && r.mapping == 1) {
|
||||
if(((address & 0xf88000) == 0x008000 && r.psramMapping == 0) //00-07:8000-ffff
|
||||
|| ((address & 0xf88000) == 0x108000 && r.psramMapping == 1) //10-17:8000-ffff
|
||||
|| ((address & 0xf88000) == 0x208000 && r.psramMapping == 2) //20-27:8000-ffff
|
||||
|| ((address & 0xf88000) == 0x308000 && r.psramMapping == 3) //30-37:8000-ffff
|
||||
|| ((address & 0xf80000) == 0x400000 && r.psramMapping == 0) //40-47:0000-ffff
|
||||
|| ((address & 0xf80000) == 0x500000 && r.psramMapping == 1) //50-57:0000-ffff
|
||||
|| ((address & 0xf80000) == 0x600000 && r.psramMapping == 2) //60-67:0000-ffff
|
||||
|| ((address & 0xf80000) == 0x700000 && r.psramMapping == 3) //70-77:0000-ffff
|
||||
) {
|
||||
return psramAccess(mode, address & 0x07ffff, data);
|
||||
}
|
||||
|
||||
if((address & 0xe0e000) == 0x206000) { //20-3f:6000-7fff
|
||||
return psramAccess(mode, (address & 0x3f0000) >> 3 | (address & 0x1fff), data);
|
||||
}
|
||||
}
|
||||
|
||||
if(r.psramEnableHi && r.mapping == 1) {
|
||||
if(((address & 0xf88000) == 0x808000 && r.psramMapping == 0) //80-87:8000-ffff
|
||||
|| ((address & 0xf88000) == 0x908000 && r.psramMapping == 1) //90-97:8000-ffff
|
||||
|| ((address & 0xf88000) == 0xa08000 && r.psramMapping == 2) //a0-a7:8000-ffff
|
||||
|| ((address & 0xf88000) == 0xb08000 && r.psramMapping == 3) //b0-b7:8000-ffff
|
||||
|| ((address & 0xf80000) == 0xc00000 && r.psramMapping == 0) //c0-c7:0000-ffff
|
||||
|| ((address & 0xf80000) == 0xd00000 && r.psramMapping == 1) //d0-d7:0000-ffff
|
||||
|| ((address & 0xf80000) == 0xe00000 && r.psramMapping == 2) //e0-e7:0000-ffff
|
||||
|| ((address & 0xf80000) == 0xf00000 && r.psramMapping == 3) //f0-f7:0000-ffff
|
||||
) {
|
||||
return psramAccess(mode, address & 0x07ffff, data);
|
||||
}
|
||||
|
||||
if((address & 0xe0e000) == 0xa06000) { //a0-bf:6000-7fff
|
||||
return psramAccess(mode, (address & 0x3f0000) >> 3 | (address & 0x1fff), data);
|
||||
}
|
||||
}
|
||||
|
||||
//[[EXMEMORY]]
|
||||
|
||||
if(r.exEnableLo && r.mapping == 0) {
|
||||
if(((address & 0xe08000) == 0x008000 && r.exMapping == 0) //00-1f:8000-ffff
|
||||
|| ((address & 0xe00000) == 0x400000 && r.exMapping == 1) //40-5f:0000-ffff
|
||||
) {
|
||||
return exAccess(mode, (address & 0x1f0000) >> 1 | (address & 0x7fff), data);
|
||||
}
|
||||
}
|
||||
|
||||
if(r.exEnableLo && r.mapping == 1) {
|
||||
if(((address & 0xf08000) == 0x008000 && r.exMapping == 0) //00-0f:8000-ffff
|
||||
|| ((address & 0xf08000) == 0x208000 && r.exMapping == 1) //20-2f:8000-ffff
|
||||
|| ((address & 0xf00000) == 0x400000 && r.exMapping == 0) //40-4f:0000-ffff
|
||||
|| ((address & 0xf00000) == 0x600000 && r.exMapping == 1) //60-6f:0000-ffff
|
||||
) {
|
||||
return exAccess(mode, address & 0x0fffff, data);
|
||||
}
|
||||
}
|
||||
|
||||
if(r.exEnableHi && r.mapping == 0) {
|
||||
if(((address & 0xe08000) == 0x808000 && r.exMapping == 0) //80-9f:8000-ffff
|
||||
|| ((address & 0xe00000) == 0xc00000 && r.exMapping == 1) //c0-df:0000-ffff
|
||||
) {
|
||||
return exAccess(mode, (address & 0x1f0000) >> 1 | (address & 0x7fff), data);
|
||||
}
|
||||
}
|
||||
|
||||
if(r.exEnableHi && r.mapping == 1) {
|
||||
if(((address & 0xf08000) == 0x808000 && r.exMapping == 0) //80-8f:8000-ffff
|
||||
|| ((address & 0xf08000) == 0xa08000 && r.exMapping == 1) //a0-af:8000-ffff
|
||||
|| ((address & 0xf00000) == 0xc00000 && r.exMapping == 0) //c0-cf:0000-ffff
|
||||
|| ((address & 0xf00000) == 0xe00000 && r.exMapping == 1) //e0-ef:0000-ffff
|
||||
) {
|
||||
return exAccess(mode, address & 0x0fffff, data);
|
||||
}
|
||||
}
|
||||
|
||||
//[[BSMEMORY]]
|
||||
|
||||
if(bsmemory.memory.size() && r.mapping == 0) {
|
||||
if(((address & 0x408000) == 0x008000) //00-3f,80-bf:8000-ffff
|
||||
|| ((address & 0xc00000) == 0x400000) //40-7d,c0-ff:0000-ffff
|
||||
) {
|
||||
return bsAccess(mode, (address & 0x3f0000) >> 1 | (address & 0x7fff), data);
|
||||
}
|
||||
}
|
||||
|
||||
if(bsmemory.memory.size() && r.mapping == 1) {
|
||||
if(((address & 0x408000) == 0x008000) //00-3f,80-bf:8000-ffff
|
||||
|| ((address & 0xc00000) == 0x400000) //40-7d,c0-ff:0000-ffff
|
||||
) {
|
||||
return bsAccess(mode, address & 0x3fffff, data);
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
auto MCC::romAccess(bool mode, uint24 address, uint8 data) -> uint8 {
|
||||
address = bus.mirror(address, rom.size());
|
||||
if(mode == 0) return rom.read(address);
|
||||
return data;
|
||||
}
|
||||
|
||||
//size: 0x80000
|
||||
auto MCC::psramAccess(bool mode, uint24 address, uint8 data) -> uint8 {
|
||||
address = bus.mirror(address, psram.size());
|
||||
if(mode == 0) return psram.read(address);
|
||||
return psram.write(address, data), data;
|
||||
}
|
||||
|
||||
//size: 0x100000 (?)
|
||||
auto MCC::exAccess(bool mode, uint24 address, uint8 data) -> uint8 {
|
||||
//not physically present on BSC-1A5B9P-01
|
||||
return data;
|
||||
}
|
||||
|
||||
//size: 0x100000, 0x200000, 0x400000
|
||||
auto MCC::bsAccess(bool mode, uint24 address, uint8 data) -> uint8 {
|
||||
address = bus.mirror(address, bsmemory.memory.size());
|
||||
if(mode == 0) return bsmemory.memory.read(address);
|
||||
return bsmemory.memory.write(address, data), data;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,31 +1,55 @@
|
|||
//the MCC is the custom logic chip inside the BS-X Satellaview cartridge
|
||||
//MCC - Memory Controller Chip
|
||||
//Custom logic chip inside the BS-X Satellaview base cartridge
|
||||
|
||||
struct MCC {
|
||||
MappedRAM rom;
|
||||
MappedRAM ram;
|
||||
MappedRAM psram;
|
||||
|
||||
//mcc.cpp
|
||||
auto unload() -> void;
|
||||
auto power() -> void;
|
||||
|
||||
auto memoryAccess(bool write, Memory& memory, uint24 addr, uint8 data) -> uint8;
|
||||
auto mcuAccess(bool write, uint24 addr, uint8 data) -> uint8;
|
||||
auto read(uint24 address, uint8 data) -> uint8;
|
||||
auto write(uint24 address, uint8 data) -> void;
|
||||
|
||||
auto mcuRead(uint24 addr, uint8 data) -> uint8;
|
||||
auto mcuWrite(uint24 addr, uint8 data) -> void;
|
||||
auto mcuRead(uint24 address, uint8 data) -> uint8;
|
||||
auto mcuWrite(uint24 address, uint8 data) -> void;
|
||||
|
||||
auto read(uint24 addr, uint8 data) -> uint8;
|
||||
auto write(uint24 addr, uint8 data) -> void;
|
||||
|
||||
auto commit() -> void;
|
||||
auto mcuAccess(bool mode, uint24 address, uint8 data) -> uint8;
|
||||
auto romAccess(bool mode, uint24 address, uint8 data) -> uint8;
|
||||
auto psramAccess(bool mode, uint24 address, uint8 data) -> uint8;
|
||||
auto exAccess(bool mode, uint24 address, uint8 data) -> uint8;
|
||||
auto bsAccess(bool mode, uint24 address, uint8 data) -> uint8;
|
||||
|
||||
//serialization.cpp
|
||||
auto serialize(serializer&) -> void;
|
||||
|
||||
private:
|
||||
uint8 r[16];
|
||||
bool r00, r01, r02, r03;
|
||||
bool r04, r05, r06, r07;
|
||||
bool r08, r09, r0a, r0b;
|
||||
bool r0c, r0d, r0e, r0f;
|
||||
struct IRQ {
|
||||
uint1 flag; //bit 0
|
||||
uint1 enable; //bit 1
|
||||
} irq;
|
||||
|
||||
struct Registers {
|
||||
uint1 mapping; //bit 2 (0 = ignore A15; 1 = use A15)
|
||||
uint1 psramEnableLo; //bit 3
|
||||
uint1 psramEnableHi; //bit 4
|
||||
uint2 psramMapping; //bits 5-6
|
||||
uint1 romEnableLo; //bit 7
|
||||
uint1 romEnableHi; //bit 8
|
||||
uint1 exEnableLo; //bit 9
|
||||
uint1 exEnableHi; //bit 10
|
||||
uint1 exMapping; //bit 11
|
||||
uint1 bsWritable; //bit 12
|
||||
uint1 unknown; //bit 13
|
||||
} r, w;
|
||||
|
||||
//bit 14 (commit)
|
||||
|
||||
struct ExtendedRegisters {
|
||||
uint1 enable; //bit 15
|
||||
uint8 value; //bits 24-31
|
||||
} x;
|
||||
};
|
||||
|
||||
extern MCC mcc;
|
||||
|
|
|
@ -1,3 +1,29 @@
|
|||
auto MCC::serialize(serializer& s) -> void {
|
||||
s.array(ram.data(), ram.size());
|
||||
s.array(psram.data(), psram.size());
|
||||
s.integer(irq.flag);
|
||||
s.integer(irq.enable);
|
||||
s.integer(r.mapping);
|
||||
s.integer(r.psramEnableLo);
|
||||
s.integer(r.psramEnableHi);
|
||||
s.integer(r.psramMapping);
|
||||
s.integer(r.romEnableLo);
|
||||
s.integer(r.romEnableHi);
|
||||
s.integer(r.exEnableLo);
|
||||
s.integer(r.exEnableHi);
|
||||
s.integer(r.exMapping);
|
||||
s.integer(r.bsWritable);
|
||||
s.integer(r.unknown);
|
||||
s.integer(w.mapping);
|
||||
s.integer(w.psramEnableLo);
|
||||
s.integer(w.psramEnableHi);
|
||||
s.integer(w.psramMapping);
|
||||
s.integer(w.romEnableLo);
|
||||
s.integer(w.romEnableHi);
|
||||
s.integer(w.exEnableLo);
|
||||
s.integer(w.exEnableHi);
|
||||
s.integer(w.exMapping);
|
||||
s.integer(w.bsWritable);
|
||||
s.integer(w.unknown);
|
||||
s.integer(x.enable);
|
||||
s.integer(x.value);
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
database
|
||||
revision: 2018-05-12
|
||||
revision: 2018-05-16
|
||||
|
||||
//Boards (Production)
|
||||
|
||||
database
|
||||
revision: 2018-05-08
|
||||
revision: 2018-05-16
|
||||
|
||||
board: BANDAI-PT-923
|
||||
memory type=ROM content=Program
|
||||
|
@ -20,6 +20,19 @@ board: BANDAI-PT-923
|
|||
ram
|
||||
map address=70-7d,f0-ff:0000-ffff
|
||||
|
||||
board: BSC-1A5B9P-01
|
||||
memory type=RAM content=Save
|
||||
map address=10-17:5000-5fff mask=0xf000
|
||||
processor identifier=MCC
|
||||
map address=00-0f:5000-5fff
|
||||
mcu
|
||||
map address=00-3f,80-bf:8000-ffff
|
||||
map address=40-7d,c0-ff:0000-ffff
|
||||
map address=20-3f,a0-bf:6000-7fff
|
||||
memory type=ROM content=Program
|
||||
memory type=RAM content=Download
|
||||
slot type=BSMemory
|
||||
|
||||
board: BSC-1A5M-02
|
||||
memory type=ROM content=Program
|
||||
map address=00-1f:8000-ffff mask=0x8000 base=0x000000
|
||||
|
@ -519,15 +532,15 @@ board: SHVC-LDH3C-01
|
|||
memory type=RTC content=Time manufacturer=Epson
|
||||
|
||||
board: SHVC-LN3B-01
|
||||
memory type=RAM content=Save
|
||||
map address=00-3f,80-bf:6000-7fff mask=0xe000
|
||||
map address=70-73:0000-ffff
|
||||
processor identifier=SDD1
|
||||
map address=00-3f,80-bf:4800-480f
|
||||
mcu
|
||||
map address=00-3f,80-bf:8000-ffff
|
||||
map address=c0-ff:0000-ffff
|
||||
memory type=ROM content=Program
|
||||
memory type=RAM content=Save
|
||||
map address=00-3f,80-bf:6000-7fff mask=0xe000
|
||||
map address=70-73:0000-ffff
|
||||
|
||||
board: SHVC-SGB2-01
|
||||
memory type=ROM content=Program
|
||||
|
@ -552,7 +565,7 @@ board: SHVC-YJ0N-01
|
|||
//Boards (Generic)
|
||||
|
||||
database
|
||||
revision: 2018-05-12
|
||||
revision: 2018-05-16
|
||||
|
||||
board: ARM-LOROM-RAM
|
||||
memory type=ROM content=Program
|
||||
|
@ -590,16 +603,16 @@ board: BS-LOROM-RAM
|
|||
|
||||
board: BS-MCC-RAM
|
||||
memory type=RAM content=Save
|
||||
map address=10-1f:5000-5fff mask=0xf000
|
||||
map address=10-17:5000-5fff mask=0xf000
|
||||
processor identifier=MCC
|
||||
map address=00-0f:5000
|
||||
map address=00-0f:5000-5fff
|
||||
mcu
|
||||
map address=00-3f,80-bf:8000-ffff mask=0x408000
|
||||
map address=00-3f,80-bf:8000-ffff
|
||||
map address=40-7d,c0-ff:0000-ffff
|
||||
map address=20-3f,a0-bf:6000-7fff
|
||||
memory type=ROM content=Program
|
||||
memory type=RAM content=Download
|
||||
slot type=BSMemory
|
||||
memory type=RAM content=Download
|
||||
map address=00-3f,80-bf:6000-7fff mask=0xe000
|
||||
|
||||
board: BS-SA1-RAM
|
||||
processor architecture=W65C816S
|
||||
|
|
|
@ -11,7 +11,7 @@ include gba/GNUmakefile
|
|||
include ws/GNUmakefile
|
||||
include processor/GNUmakefile
|
||||
|
||||
ui_objects := ui-tomoko ui-program ui-configuration ui-input
|
||||
ui_objects := ui-higan ui-program ui-configuration ui-input
|
||||
ui_objects += ui-settings ui-tools ui-presentation
|
||||
ui_objects += ruby hiro
|
||||
ui_objects += $(if $(call streq,$(platform),windows),ui-resource)
|
||||
|
@ -53,7 +53,7 @@ obj/ruby.o: ../ruby/ruby.cpp $(call rwildcard,../ruby/)
|
|||
obj/hiro.o: ../hiro/hiro.cpp $(call rwildcard,../hiro/)
|
||||
$(compiler) $(hiroflags) -c $< -o $@
|
||||
|
||||
obj/ui-tomoko.o: $(ui)/tomoko.cpp $(call rwildcard,$(ui)/)
|
||||
obj/ui-higan.o: $(ui)/higan.cpp $(call rwildcard,$(ui)/)
|
||||
obj/ui-program.o: $(ui)/program/program.cpp $(call rwildcard,$(ui)/)
|
||||
obj/ui-configuration.o: $(ui)/configuration/configuration.cpp $(call rwildcard,$(ui)/)
|
||||
obj/ui-input.o: $(ui)/input/input.cpp $(call rwildcard,$(ui)/)
|
|
@ -1,4 +1,4 @@
|
|||
#include "../tomoko.hpp"
|
||||
#include "../higan.hpp"
|
||||
Settings settings;
|
||||
|
||||
Settings::Settings() {
|
|
@ -1,4 +1,4 @@
|
|||
#include "tomoko.hpp"
|
||||
#include "higan.hpp"
|
||||
unique_pointer<Video> video;
|
||||
unique_pointer<Audio> audio;
|
||||
unique_pointer<Input> input;
|
|
@ -1,4 +1,4 @@
|
|||
#include "../tomoko.hpp"
|
||||
#include "../higan.hpp"
|
||||
#include "hotkeys.cpp"
|
||||
unique_pointer<InputManager> inputManager;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#include "../tomoko.hpp"
|
||||
#include "../higan.hpp"
|
||||
#include "about.cpp"
|
||||
unique_pointer<AboutWindow> aboutWindow;
|
||||
unique_pointer<Presentation> presentation;
|
|
@ -1,4 +1,4 @@
|
|||
#include "../tomoko.hpp"
|
||||
#include "../higan.hpp"
|
||||
#include <fc/interface/interface.hpp>
|
||||
#include <sfc/interface/interface.hpp>
|
||||
#include <ms/interface/interface.hpp>
|
|
@ -1,4 +1,4 @@
|
|||
#include "../tomoko.hpp"
|
||||
#include "../higan.hpp"
|
||||
|
||||
#include "system-properties.cpp"
|
||||
unique_pointer<SystemProperties> systemProperties;
|
|
@ -7,7 +7,6 @@ SystemProperties::SystemProperties() {
|
|||
systemOption.append(ComboButtonItem().setText(emulator->information.name));
|
||||
}
|
||||
loadLabel.setAlignment(1.0).setText("Load:");
|
||||
loadEdit.setEditable(false);
|
||||
loadBrowse.setText("Browse ...").onActivate([&] {
|
||||
string filters = "Games|";
|
||||
for(auto& emulator : program->emulators) {
|
||||
|
@ -22,6 +21,20 @@ SystemProperties::SystemProperties() {
|
|||
.setFilters(filters)
|
||||
.openFolder()) {
|
||||
loadEdit.setText(location);
|
||||
//change system option to match the media selected
|
||||
auto suffix = Location::suffix(location).trimLeft(".", 1L);
|
||||
for(auto& emulator : program->emulators) {
|
||||
for(auto& media : emulator->media) {
|
||||
if(media.type == suffix) {
|
||||
for(auto item : systemOption.items()) {
|
||||
if(item.text() == emulator->information.name) {
|
||||
item.setSelected();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
aliasLabel.setAlignment(1.0).setText("Alias:");
|
|
@ -1,4 +1,4 @@
|
|||
#include "../tomoko.hpp"
|
||||
#include "../higan.hpp"
|
||||
|
||||
#include "cheat-database.cpp"
|
||||
unique_pointer<CheatDatabase> cheatDatabase;
|
|
@ -43,18 +43,17 @@ auto pApplication::initialize() -> void {
|
|||
#endif
|
||||
|
||||
//set WM_CLASS to Application::name()
|
||||
if(Application::state.name) gdk_set_program_class(Application::state.name);
|
||||
auto name = Application::state.name ? Application::state.name : string{"hiro"};
|
||||
gdk_set_program_class(name);
|
||||
|
||||
#if 1
|
||||
int argc = 1;
|
||||
char* argv[] = {new char[5], nullptr};
|
||||
strcpy(argv[0], "hiro");
|
||||
char* argv[] = {name.get(), nullptr};
|
||||
#else
|
||||
//--g-fatal-warnings will force a trap on Gtk-CRITICAL errors
|
||||
//this allows gdb to perform a backtrace to find an error's origin point
|
||||
int argc = 2;
|
||||
char* argv[] = {new char[5], new char[19], nullptr};
|
||||
strcpy(argv[0], "hiro");
|
||||
char* argv[] = {name.get(), new char[19], nullptr};
|
||||
strcpy(argv[1], "--g-fatal-warnings");
|
||||
#endif
|
||||
char** argvp = argv;
|
||||
|
|
|
@ -41,9 +41,10 @@ auto pApplication::syncX() -> void {
|
|||
auto pApplication::initialize() -> void {
|
||||
display = XOpenDisplay(0);
|
||||
|
||||
static int argc = 1;
|
||||
static char* argv[] = {new char[8], nullptr};
|
||||
strcpy(argv[0], "hiro");
|
||||
auto name = Application::state.name ? Application::state.name : string{"hiro"};
|
||||
|
||||
int argc = 1;
|
||||
char* argv[] = {name.get(), nullptr};
|
||||
char** argvp = argv;
|
||||
|
||||
qtApplication = new QApplication(argc, argvp);
|
||||
|
|
|
@ -44,12 +44,12 @@ auto Icarus::famicomImport(vector<uint8_t>& buffer, string location) -> string {
|
|||
write({target, "ines.rom"}, &buffer[offset], size);
|
||||
offset += size;
|
||||
}
|
||||
if(auto program = document["game/memory(type=ROM,content=Program)"]) {
|
||||
if(auto program = document["game/board/memory(type=ROM,content=Program)"]) {
|
||||
uint size = program["size"].natural();
|
||||
write({target, "program.rom"}, &buffer[offset], size);
|
||||
offset += size;
|
||||
}
|
||||
if(auto character = document["game/memory(type=ROM,content=Character)"]) {
|
||||
if(auto character = document["game/board/memory(type=ROM,content=Character)"]) {
|
||||
uint size = character["size"].natural();
|
||||
write({target, "character.rom"}, &buffer[offset], size);
|
||||
offset += size;
|
||||
|
|
|
@ -46,12 +46,12 @@ auto Icarus::superFamicomImport(vector<uint8_t>& buffer, string location) -> str
|
|||
auto name = string{rom["architecture"].text(), ".", rom["content"].text(), ".rom"}.trimLeft(".", 1L).downcase();
|
||||
auto size = rom["size"].natural();
|
||||
if(size > buffer.size() - offset) {
|
||||
auto name = string{rom["identifier"].text(), ".", rom["content"].text(), ".rom"}.trimLeft(".", 1L).downcase();
|
||||
auto location = locate({"firmware/", name});
|
||||
auto firmware = string{rom["identifier"].text(), ".", rom["content"].text(), ".rom"}.trimLeft(".", 1L).downcase();
|
||||
auto location = locate({"firmware/", firmware});
|
||||
if(location && file::size(location) == size) {
|
||||
write({target, name}, file::read(location));
|
||||
} else {
|
||||
missingFiles.append(name);
|
||||
missingFiles.append(firmware);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue