mirror of https://github.com/bsnes-emu/bsnes.git
Update to v089r02 release.
(r01 was not posted to the WIP thread) byuu says: r01 changelog: - major improvements to SPC7110 MCU (memory controller unit) - revised SPC7110 memory map to reflect aforementioned improvements - added "Toggle Tracer" hotkey to target-ethos (only works for SFC so far, I plan to use this as a lightweight laevateinn for FEoEZ) r02 changelog: - quick fix: SRAM is mapped to 00-3f|80-bf:6000-7fff - quick fix: $4830.d7 is SRAM chip enable, not SRAM write enable. Reads return 0x00 when this bit is clear
This commit is contained in:
parent
73ebe093b8
commit
a1e4c67a05
|
@ -3,7 +3,7 @@
|
|||
|
||||
namespace Emulator {
|
||||
static const char Name[] = "bsnes";
|
||||
static const char Version[] = "089";
|
||||
static const char Version[] = "089.02";
|
||||
static const char Author[] = "byuu";
|
||||
static const char License[] = "GPLv3";
|
||||
}
|
||||
|
|
|
@ -98,7 +98,10 @@ struct Interface {
|
|||
virtual void cheatSet(const lstring& = lstring{}) {}
|
||||
|
||||
//utility functions
|
||||
virtual void updatePalette() {}
|
||||
virtual void paletteUpdate() {}
|
||||
|
||||
//debugger functions
|
||||
virtual bool tracerEnable(bool) { return false; }
|
||||
|
||||
Interface() : bind(nullptr) {}
|
||||
};
|
||||
|
|
|
@ -76,7 +76,7 @@ void Interface::cheatSet(const lstring &list) {
|
|||
cheat.synchronize();
|
||||
}
|
||||
|
||||
void Interface::updatePalette() {
|
||||
void Interface::paletteUpdate() {
|
||||
video.generate_palette();
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ struct Interface : Emulator::Interface {
|
|||
|
||||
void cheatSet(const lstring&);
|
||||
|
||||
void updatePalette();
|
||||
void paletteUpdate();
|
||||
|
||||
Interface();
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ void Interface::cheatSet(const lstring &list) {
|
|||
cheat.synchronize();
|
||||
}
|
||||
|
||||
void Interface::updatePalette() {
|
||||
void Interface::paletteUpdate() {
|
||||
video.generate_palette();
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ struct Interface : Emulator::Interface {
|
|||
|
||||
void cheatSet(const lstring&);
|
||||
|
||||
void updatePalette();
|
||||
void paletteUpdate();
|
||||
|
||||
Interface();
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ bool Interface::unserialize(serializer &s) {
|
|||
return system.unserialize(s);
|
||||
}
|
||||
|
||||
void Interface::updatePalette() {
|
||||
void Interface::paletteUpdate() {
|
||||
video.generate_palette();
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ struct Interface : Emulator::Interface {
|
|||
serializer serialize();
|
||||
bool unserialize(serializer&);
|
||||
|
||||
void updatePalette();
|
||||
void paletteUpdate();
|
||||
|
||||
Interface();
|
||||
|
||||
|
|
|
@ -158,26 +158,11 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size)
|
|||
|
||||
else if(has_spc7110) {
|
||||
markup.append(
|
||||
" <rom>\n"
|
||||
" <map mode='shadow' address='00-0f:8000-ffff'/>\n"
|
||||
" <map mode='shadow' address='80-bf:8000-ffff'/>\n"
|
||||
" <map mode='linear' address='c0-cf:0000-ffff'/>\n"
|
||||
" </rom>\n"
|
||||
" <spc7110>\n"
|
||||
" <ram size='0x", hex(ram_size), "'>\n"
|
||||
" <map mode='linear' address='00:6000-7fff'/>\n"
|
||||
" <map mode='linear' address='30:6000-7fff'/>\n"
|
||||
" </ram>\n"
|
||||
" <mmio>\n"
|
||||
" <map address='00-3f:4800-483f'/>\n"
|
||||
" <map address='80-bf:4800-483f'/>\n"
|
||||
" </mmio>\n"
|
||||
" <mcu>\n"
|
||||
" <map address='d0-ff:0000-ffff' offset='0x100000' size='0x", hex(size - 0x100000), "'/>\n"
|
||||
" </mcu>\n"
|
||||
" <dcu>\n"
|
||||
" <map address='50:0000-ffff'/>\n"
|
||||
" </dcu>\n"
|
||||
);
|
||||
if(has_spc7110rtc) markup.append(
|
||||
" <rtc>\n"
|
||||
|
@ -186,6 +171,22 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size)
|
|||
" </rtc>\n"
|
||||
);
|
||||
markup.append(
|
||||
" <dcu>\n"
|
||||
" <map address='50:0000-ffff'/>\n"
|
||||
" </dcu>\n"
|
||||
" <mcu>\n"
|
||||
" <rom>\n"
|
||||
" <program offset='0x000000' size='0x100000'/>\n"
|
||||
" <data offset='0x100000' size='", hex(rom_size - 0x100000), "'/>\n"
|
||||
" <map address='00-0f:8000-ffff'/>\n"
|
||||
" <map address='80-bf:8000-ffff'/>\n"
|
||||
" <map address='c0-cf:0000-ffff'/>\n"
|
||||
" </rom>\n"
|
||||
" <ram size='0x", hex(ram_size), "'>\n"
|
||||
" <map address='00-3f:6000-7fff'/>\n"
|
||||
" <map address='80-bf:6000-7fff'/>\n"
|
||||
" </ram>\n"
|
||||
" </mcu>\n"
|
||||
" </spc7110>\n"
|
||||
);
|
||||
}
|
||||
|
|
|
@ -424,9 +424,5 @@ void R65816::disassemble_opcode(char *output, uint32 addr) {
|
|||
regs.p.z ? 'Z' : 'z', regs.p.c ? 'C' : 'c');
|
||||
}
|
||||
|
||||
strcat(s, t);
|
||||
//strcat(s, " ");
|
||||
|
||||
//sprintf(t, "V:%3d H:%4d", cpu.vcounter(), cpu.hcounter());
|
||||
strcat(s, t);
|
||||
}
|
||||
|
|
|
@ -400,19 +400,19 @@ void Cartridge::parse_markup_spc7110(XML::Node &root) {
|
|||
has_spc7110 = true;
|
||||
has_spc7110rtc = root["rtc"].exists();
|
||||
|
||||
auto &ram = root["ram"];
|
||||
auto &mmio = root["mmio"];
|
||||
auto &mcu = root["mcu"];
|
||||
auto &dcu = root["dcu"];
|
||||
auto &rtc = root["rtc"];
|
||||
auto &dcu = root["dcu"];
|
||||
auto &mcurom = root["mcu"]["rom"];
|
||||
auto &mcuram = root["mcu"]["ram"];
|
||||
|
||||
ram_size = numeral(ram["size"].data);
|
||||
for(auto &node : ram) {
|
||||
if(node.name != "map") continue;
|
||||
Mapping m({ &SPC7110::ram_read, &spc7110 }, { &SPC7110::ram_write, &spc7110 });
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
spc7110.prom_base = numeral(mcurom["program"]["offset"].data);
|
||||
spc7110.prom_size = numeral(mcurom["program"]["size"].data);
|
||||
|
||||
spc7110.drom_base = numeral(mcurom["data"]["offset"].data);
|
||||
spc7110.drom_size = numeral(mcurom["data"]["size"].data);
|
||||
|
||||
ram_size = numeral(mcuram["size"].data);
|
||||
|
||||
for(auto &node : mmio) {
|
||||
if(node.name != "map") continue;
|
||||
|
@ -421,11 +421,9 @@ void Cartridge::parse_markup_spc7110(XML::Node &root) {
|
|||
mapping.append(m);
|
||||
}
|
||||
|
||||
spc7110.data_rom_offset = numeral(mcu["offset"].data);
|
||||
if(spc7110.data_rom_offset == 0) spc7110.data_rom_offset = 0x100000;
|
||||
for(auto &node : mcu) {
|
||||
for(auto &node : rtc) {
|
||||
if(node.name != "map") continue;
|
||||
Mapping m({ &SPC7110::mcu_read, &spc7110 }, { &SPC7110::mcu_write, &spc7110 });
|
||||
Mapping m({&SPC7110::mmio_read, &spc7110}, {&SPC7110::mmio_write, &spc7110});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
|
@ -437,9 +435,16 @@ void Cartridge::parse_markup_spc7110(XML::Node &root) {
|
|||
mapping.append(m);
|
||||
}
|
||||
|
||||
for(auto &node : rtc) {
|
||||
for(auto &node : mcurom) {
|
||||
if(node.name != "map") continue;
|
||||
Mapping m({ &SPC7110::mmio_read, &spc7110 }, { &SPC7110::mmio_write, &spc7110 });
|
||||
Mapping m({&SPC7110::mcurom_read, &spc7110}, {&SPC7110::mcurom_write, &spc7110});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
|
||||
for(auto &node : mcuram) {
|
||||
if(node.name != "map") continue;
|
||||
Mapping m({&SPC7110::mcuram_read, &spc7110}, {&SPC7110::mcuram_write, &spc7110});
|
||||
parse_markup_map(m, node);
|
||||
mapping.append(m);
|
||||
}
|
||||
|
|
|
@ -24,9 +24,8 @@ void SPC7110::Decomp::write(uint8 data) {
|
|||
}
|
||||
|
||||
uint8 SPC7110::Decomp::dataread() {
|
||||
unsigned size = cartridge.rom.size() - spc7110.data_rom_offset;
|
||||
while(decomp_offset >= size) decomp_offset -= size;
|
||||
return cartridge.rom.read(spc7110.data_rom_offset + decomp_offset++);
|
||||
unsigned addr = Bus::mirror(decomp_offset++, spc7110.drom_size);
|
||||
return cartridge.rom.read(spc7110.drom_base + addr);
|
||||
}
|
||||
|
||||
void SPC7110::Decomp::init(unsigned mode, unsigned offset, unsigned index) {
|
||||
|
|
|
@ -65,10 +65,6 @@ void SPC7110::serialize(serializer &s) {
|
|||
s.integer(r4833);
|
||||
s.integer(r4834);
|
||||
|
||||
s.integer(dx_offset);
|
||||
s.integer(ex_offset);
|
||||
s.integer(fx_offset);
|
||||
|
||||
s.integer(r4840);
|
||||
s.integer(r4841);
|
||||
s.integer(r4842);
|
||||
|
|
|
@ -71,9 +71,9 @@ void SPC7110::reset() {
|
|||
r482f = 0x00;
|
||||
|
||||
r4830 = 0x00;
|
||||
mmio_write(0x4831, 0);
|
||||
mmio_write(0x4832, 1);
|
||||
mmio_write(0x4833, 2);
|
||||
r4831 = 0x00;
|
||||
r4832 = 0x01;
|
||||
r4833 = 0x02;
|
||||
r4834 = 0x00;
|
||||
|
||||
r4840 = 0x00;
|
||||
|
@ -88,9 +88,8 @@ void SPC7110::reset() {
|
|||
}
|
||||
|
||||
unsigned SPC7110::datarom_addr(unsigned addr) {
|
||||
unsigned size = cartridge.rom.size() - data_rom_offset;
|
||||
while(addr >= size) addr -= size;
|
||||
return data_rom_offset + addr;
|
||||
addr = Bus::mirror(addr, drom_size);
|
||||
return drom_base + addr;
|
||||
}
|
||||
|
||||
unsigned SPC7110::data_pointer() { return r4811 + (r4812 << 8) + (r4813 << 16); }
|
||||
|
@ -194,6 +193,7 @@ uint8 SPC7110::mmio_read(unsigned addr) {
|
|||
addr &= 0xffff;
|
||||
|
||||
switch(addr) {
|
||||
|
||||
//==================
|
||||
//decompression unit
|
||||
//==================
|
||||
|
@ -333,6 +333,7 @@ uint8 SPC7110::mmio_read(unsigned addr) {
|
|||
r4842 &= 0x7f;
|
||||
return status;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return cpu.regs.mdr;
|
||||
|
@ -342,6 +343,7 @@ void SPC7110::mmio_write(unsigned addr, uint8 data) {
|
|||
addr &= 0xffff;
|
||||
|
||||
switch(addr) {
|
||||
|
||||
//==================
|
||||
//decompression unit
|
||||
//==================
|
||||
|
@ -530,24 +532,11 @@ void SPC7110::mmio_write(unsigned addr, uint8 data) {
|
|||
//memory mapping unit
|
||||
//===================
|
||||
|
||||
case 0x4830: r4830 = data; break;
|
||||
|
||||
case 0x4831: {
|
||||
r4831 = data;
|
||||
dx_offset = datarom_addr(data * 0x100000);
|
||||
} break;
|
||||
|
||||
case 0x4832: {
|
||||
r4832 = data;
|
||||
ex_offset = datarom_addr(data * 0x100000);
|
||||
} break;
|
||||
|
||||
case 0x4833: {
|
||||
r4833 = data;
|
||||
fx_offset = datarom_addr(data * 0x100000);
|
||||
} break;
|
||||
|
||||
case 0x4834: r4834 = data; break;
|
||||
case 0x4830: r4830 = data & 0x87; break;
|
||||
case 0x4831: r4831 = data & 0x07; break;
|
||||
case 0x4832: r4832 = data & 0x07; break;
|
||||
case 0x4833: r4833 = data & 0x07; break;
|
||||
case 0x4834: r4834 = data & 0x07; break;
|
||||
|
||||
//====================
|
||||
//real-time clock unit
|
||||
|
@ -628,26 +617,13 @@ void SPC7110::mmio_write(unsigned addr, uint8 data) {
|
|||
} break;
|
||||
} //switch(rtc_state)
|
||||
} break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
SPC7110::SPC7110() {
|
||||
}
|
||||
|
||||
//============
|
||||
//SPC7110::MCU
|
||||
//============
|
||||
|
||||
uint8 SPC7110::mcu_read(unsigned addr) {
|
||||
if(addr <= 0xdfffff) return cartridge.rom.read(dx_offset + (addr & 0x0fffff));
|
||||
if(addr <= 0xefffff) return cartridge.rom.read(ex_offset + (addr & 0x0fffff));
|
||||
if(addr <= 0xffffff) return cartridge.rom.read(fx_offset + (addr & 0x0fffff));
|
||||
return cpu.regs.mdr;
|
||||
}
|
||||
|
||||
void SPC7110::mcu_write(unsigned addr, uint8 data) {
|
||||
}
|
||||
|
||||
//============
|
||||
//SPC7110::DCU
|
||||
//============
|
||||
|
@ -659,16 +635,86 @@ uint8 SPC7110::dcu_read(unsigned) {
|
|||
void SPC7110::dcu_write(unsigned, uint8) {
|
||||
}
|
||||
|
||||
//============
|
||||
//SPC7110::RAM
|
||||
//============
|
||||
//===============
|
||||
//SPC7110::MCUROM
|
||||
//===============
|
||||
|
||||
uint8 SPC7110::ram_read(unsigned addr) {
|
||||
return cartridge.ram.read(addr & 0x1fff);
|
||||
uint8 SPC7110::mcurom_read(unsigned addr) {
|
||||
unsigned bank = 0;
|
||||
|
||||
if((addr & 0x708000) == 0x008000 //$00-0f|80-8f:8000-ffff
|
||||
|| (addr & 0xf00000) == 0xc00000 // $c0-cf:0000-ffff
|
||||
) {
|
||||
addr &= 0x0fffff;
|
||||
if(true) { //8mbit PROM
|
||||
return cartridge.rom.read(prom_base + bus.mirror(0x000000 + addr, prom_size));
|
||||
}
|
||||
return mcurom_read_data(r4830 & 7, addr);
|
||||
}
|
||||
|
||||
void SPC7110::ram_write(unsigned addr, uint8 data) {
|
||||
if(r4830 & 0x80) cartridge.ram.write(addr & 0x1fff, data);
|
||||
if((addr & 0x708000) == 0x108000 //$10-1f|90-9f:8000-ffff
|
||||
|| (addr & 0xf00000) == 0xd00000 // $d0-df:0000-ffff
|
||||
) {
|
||||
addr &= 0x0fffff;
|
||||
if(r4834 & 4) { //16mbit PROM
|
||||
return cartridge.rom.read(prom_base + bus.mirror(0x100000 + addr, prom_size));
|
||||
}
|
||||
return mcurom_read_data(r4831 & 7, addr);
|
||||
}
|
||||
|
||||
if((addr & 0x708000) == 0x208000 //$20-2f|a0-af:8000-ffff
|
||||
|| (addr & 0xf00000) == 0xe00000 // $e0-ef:0000-ffff
|
||||
) {
|
||||
addr &= 0x0fffff;
|
||||
return mcurom_read_data(r4832 & 7, addr);
|
||||
}
|
||||
|
||||
if((addr & 0x708000) == 0x308000 //$30-3f|b0-bf:8000-ffff
|
||||
|| (addr & 0xf00000) == 0xf00000 // $f0-ff:0000-ffff
|
||||
) {
|
||||
addr &= 0x0fffff;
|
||||
return mcurom_read_data(r4833 & 7, addr);
|
||||
}
|
||||
|
||||
return cpu.regs.mdr;
|
||||
}
|
||||
|
||||
uint8 SPC7110::mcurom_read_data(unsigned bank, unsigned addr) {
|
||||
unsigned mask = (1 << (r4834 & 3)) - 1; //8mbit, 16mbit, 32mbit, 64mbit DROM
|
||||
unsigned range = 0x100000 * (1 + mask);
|
||||
unsigned offset = 0x100000 * (bank & mask);
|
||||
|
||||
//mirroring behavior is non-sensical. assuming a 32mbit data ROM:
|
||||
//banks 4-7 with mask 0-2 returns 0x00; banks 4-7 with mask 3 mirrors banks 0-3
|
||||
if(range <= drom_size && offset >= drom_size) return 0x00;
|
||||
|
||||
return cartridge.rom.read(drom_base + bus.mirror(offset + addr, drom_size));
|
||||
}
|
||||
|
||||
void SPC7110::mcurom_write(unsigned addr, uint8 data) {
|
||||
}
|
||||
|
||||
//===============
|
||||
//SPC7110::MCURAM
|
||||
//===============
|
||||
|
||||
uint8 SPC7110::mcuram_read(unsigned addr) {
|
||||
//$00-3f|80-bf:6000-7fff
|
||||
if(r4830 & 0x80) {
|
||||
unsigned bank = (addr >> 16) & 0x3f;
|
||||
addr = bus.mirror(bank * 0x2000 + (addr & 0x1fff), cartridge.ram.size());
|
||||
return cartridge.ram.read(addr);
|
||||
}
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
void SPC7110::mcuram_write(unsigned addr, uint8 data) {
|
||||
//$00-3f|80-bf:6000-7fff
|
||||
if(r4830 & 0x80) {
|
||||
unsigned bank = (addr >> 16) & 0x3f;
|
||||
addr = bus.mirror(bank * 0x2000 + (addr & 0x1fff), cartridge.ram.size());
|
||||
cartridge.ram.write(addr, data);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
|
||||
struct SPC7110 {
|
||||
uint8 rtc[20];
|
||||
unsigned data_rom_offset;
|
||||
unsigned prom_base, prom_size; //program ROM
|
||||
unsigned drom_base, drom_size; //data ROM
|
||||
|
||||
void init();
|
||||
void load();
|
||||
|
@ -25,14 +26,15 @@ struct SPC7110 {
|
|||
uint8 mmio_read(unsigned addr);
|
||||
void mmio_write(unsigned addr, uint8 data);
|
||||
|
||||
uint8 mcu_read(unsigned addr);
|
||||
void mcu_write(unsigned addr, uint8 data);
|
||||
|
||||
uint8 dcu_read(unsigned);
|
||||
void dcu_write(unsigned, uint8);
|
||||
|
||||
uint8 ram_read(unsigned addr);
|
||||
void ram_write(unsigned addr, uint8 data);
|
||||
uint8 mcurom_read(unsigned addr);
|
||||
uint8 mcurom_read_data(unsigned bank, unsigned addr);
|
||||
void mcurom_write(unsigned addr, uint8 data);
|
||||
|
||||
uint8 mcuram_read(unsigned addr);
|
||||
void mcuram_write(unsigned addr, uint8 data);
|
||||
|
||||
//spc7110decomp
|
||||
void decomp_init();
|
||||
|
@ -101,15 +103,11 @@ private:
|
|||
//===================
|
||||
//memory mapping unit
|
||||
//===================
|
||||
uint8 r4830; //SRAM write enable
|
||||
uint8 r4831; //$[d0-df]:[0000-ffff] mapping
|
||||
uint8 r4832; //$[e0-ef]:[0000-ffff] mapping
|
||||
uint8 r4833; //$[f0-ff]:[0000-ffff] mapping
|
||||
uint8 r4834; //???
|
||||
|
||||
unsigned dx_offset;
|
||||
unsigned ex_offset;
|
||||
unsigned fx_offset;
|
||||
uint8 r4830; //bank 0 mapping + SRAM write enable
|
||||
uint8 r4831; //bank 1 mapping
|
||||
uint8 r4832; //bank 2 mapping
|
||||
uint8 r4833; //bank 3 mapping
|
||||
uint8 r4834; //bank mapping control
|
||||
|
||||
//====================
|
||||
//real-time clock unit
|
||||
|
|
|
@ -86,6 +86,11 @@ void CPU::enter() {
|
|||
|
||||
void CPU::op_step() {
|
||||
debugger.op_exec(regs.pc.d);
|
||||
if(interface->tracer.open()) {
|
||||
char text[4096];
|
||||
disassemble_opcode(text, regs.pc.d);
|
||||
interface->tracer.print(text, "\n");
|
||||
}
|
||||
|
||||
(this->*opcode_table[op_readpc()])();
|
||||
}
|
||||
|
|
|
@ -174,6 +174,7 @@ void Interface::save(unsigned id, const stream &stream) {
|
|||
|
||||
void Interface::unload() {
|
||||
cartridge.unload();
|
||||
tracerEnable(false);
|
||||
}
|
||||
|
||||
void Interface::connect(unsigned port, unsigned device) {
|
||||
|
@ -230,10 +231,30 @@ void Interface::cheatSet(const lstring &list) {
|
|||
cheat.synchronize();
|
||||
}
|
||||
|
||||
void Interface::updatePalette() {
|
||||
void Interface::paletteUpdate() {
|
||||
video.generate_palette();
|
||||
}
|
||||
|
||||
bool Interface::tracerEnable(bool trace) {
|
||||
string pathname = path(group(ID::ROM));
|
||||
|
||||
if(trace == true && !tracer.open()) {
|
||||
for(unsigned n = 0; n <= 999; n++) {
|
||||
string filename = {pathname, "trace-", decimal<3, '0'>(n), ".log"};
|
||||
if(file::exists(filename)) continue;
|
||||
tracer.open(filename, file::mode::write);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if(trace == false && tracer.open()) {
|
||||
tracer.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Interface::Interface() {
|
||||
interface = this;
|
||||
system.init();
|
||||
|
|
|
@ -53,11 +53,13 @@ struct Interface : Emulator::Interface {
|
|||
|
||||
void cheatSet(const lstring&);
|
||||
|
||||
void updatePalette();
|
||||
void paletteUpdate();
|
||||
|
||||
bool tracerEnable(bool);
|
||||
|
||||
Interface();
|
||||
|
||||
private:
|
||||
file tracer;
|
||||
vector<Device> device;
|
||||
};
|
||||
|
||||
|
|
|
@ -51,6 +51,24 @@ MappedRAM::MappedRAM() : data_(nullptr), size_(0), write_protect_(false) {}
|
|||
|
||||
//Bus
|
||||
|
||||
unsigned Bus::mirror(unsigned addr, unsigned size) {
|
||||
unsigned base = 0;
|
||||
if(size) {
|
||||
unsigned mask = 1 << 23;
|
||||
while(addr >= size) {
|
||||
while(!(addr & mask)) mask >>= 1;
|
||||
addr -= mask;
|
||||
if(size > mask) {
|
||||
size -= mask;
|
||||
base += mask;
|
||||
}
|
||||
mask >>= 1;
|
||||
}
|
||||
base += addr;
|
||||
}
|
||||
return base;
|
||||
}
|
||||
|
||||
uint8 Bus::read(unsigned addr) {
|
||||
if(cheat.override[addr]) return cheat.read(addr);
|
||||
return reader[lookup[addr]](target[addr]);
|
||||
|
|
|
@ -5,24 +5,6 @@ namespace SuperFamicom {
|
|||
|
||||
Bus bus;
|
||||
|
||||
unsigned Bus::mirror(unsigned addr, unsigned size) {
|
||||
unsigned base = 0;
|
||||
if(size) {
|
||||
unsigned mask = 1 << 23;
|
||||
while(addr >= size) {
|
||||
while(!(addr & mask)) mask >>= 1;
|
||||
addr -= mask;
|
||||
if(size > mask) {
|
||||
size -= mask;
|
||||
base += mask;
|
||||
}
|
||||
mask >>= 1;
|
||||
}
|
||||
base += addr;
|
||||
}
|
||||
return base;
|
||||
}
|
||||
|
||||
void Bus::map(
|
||||
MapMode mode,
|
||||
unsigned bank_lo, unsigned bank_hi,
|
||||
|
|
|
@ -42,7 +42,7 @@ private:
|
|||
};
|
||||
|
||||
struct Bus {
|
||||
unsigned mirror(unsigned addr, unsigned size);
|
||||
alwaysinline static unsigned mirror(unsigned addr, unsigned size);
|
||||
|
||||
alwaysinline uint8 read(unsigned addr);
|
||||
alwaysinline void write(unsigned addr, uint8 data);
|
||||
|
|
|
@ -74,6 +74,8 @@ ifeq ($(USER),root)
|
|||
@echo The installer needs to know your home directory to install important files.
|
||||
else ifeq ($(platform),x)
|
||||
sudo install -D -m 755 out/$(name) $(DESTDIR)$(prefix)/bin/$(name)
|
||||
sudo install -D -m 644 data/$(name).png $(DESTDIR)$(prefix)/share/pixmaps/$(name).png
|
||||
sudo install -D -m 644 data/$(name).desktop $(DESTDIR)$(prefix)/share/applications/$(name).desktop
|
||||
|
||||
mkdir -p ~/.config/$(name)
|
||||
cp -R profile/* ~/.config/$(name)
|
||||
|
|
|
@ -119,6 +119,16 @@ void InputManager::appendHotkeys() {
|
|||
};
|
||||
}
|
||||
|
||||
{
|
||||
auto hotkey = new HotkeyInput;
|
||||
hotkey->name = "Toggle Tracer";
|
||||
hotkey->mapping = "None";
|
||||
|
||||
hotkey->press = [&] {
|
||||
utility->tracerToggle();
|
||||
};
|
||||
}
|
||||
|
||||
for(auto &hotkey : hotkeyMap) {
|
||||
string name = {"Hotkey::", hotkey->name};
|
||||
name.replace(" ", "");
|
||||
|
|
|
@ -59,5 +59,5 @@ void VideoSettings::synchronize() {
|
|||
overscanHorizontal.value.setText({config->video.maskOverscanHorizontal, "px"});
|
||||
overscanVertical.value.setText({config->video.maskOverscanVertical, "px"});
|
||||
|
||||
if(application->active) system().updatePalette();
|
||||
if(application->active) system().paletteUpdate();
|
||||
}
|
||||
|
|
|
@ -99,7 +99,7 @@ void Utility::load() {
|
|||
|
||||
loadMemory();
|
||||
|
||||
system().updatePalette();
|
||||
system().paletteUpdate();
|
||||
synchronizeDSP();
|
||||
|
||||
resize();
|
||||
|
@ -109,6 +109,7 @@ void Utility::load() {
|
|||
|
||||
void Utility::unload() {
|
||||
if(application->active == nullptr) return;
|
||||
if(tracerEnable) tracerToggle();
|
||||
|
||||
saveMemory();
|
||||
system().unload();
|
||||
|
@ -143,6 +144,16 @@ void Utility::loadState(unsigned slot) {
|
|||
showMessage({"Loaded from slot ", slot});
|
||||
}
|
||||
|
||||
void Utility::tracerToggle() {
|
||||
if(application->active == nullptr) return;
|
||||
tracerEnable = !tracerEnable;
|
||||
bool result = system().tracerEnable(tracerEnable);
|
||||
if( tracerEnable && result) return utility->showMessage("Tracer activated");
|
||||
if( tracerEnable && !result) return tracerEnable = false, utility->showMessage("Unable to activate tracer");
|
||||
if(!tracerEnable && result) return utility->showMessage("Tracer deactivated");
|
||||
if(!tracerEnable && !result) return utility->showMessage("Unable to deactivate tracer");
|
||||
}
|
||||
|
||||
void Utility::synchronizeDSP() {
|
||||
if(application->active == nullptr) return;
|
||||
|
||||
|
@ -280,5 +291,6 @@ void Utility::showMessage(const string &message) {
|
|||
}
|
||||
|
||||
Utility::Utility() {
|
||||
tracerEnable = false;
|
||||
statusTime = 0;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@ struct Utility {
|
|||
void saveState(unsigned slot);
|
||||
void loadState(unsigned slot);
|
||||
|
||||
void tracerToggle();
|
||||
|
||||
void synchronizeDSP();
|
||||
void synchronizeRuby();
|
||||
void updateShader();
|
||||
|
@ -32,6 +34,7 @@ struct Utility {
|
|||
lstring pathname;
|
||||
|
||||
private:
|
||||
bool tracerEnable;
|
||||
string statusText;
|
||||
string statusMessage;
|
||||
time_t statusTime;
|
||||
|
|
Loading…
Reference in New Issue