mirror of https://github.com/bsnes-emu/bsnes.git
Update to v088r16 release.
byuu says: Changelog: - fixed BGnxOFS to not cache when MOSAIC is not in effect [fixes Air Strike Patrol "Good Luck" text] - added GameBoy::Interface::Hook for SGB bindings [SGB works again] - do not create bsnes/ folder unless it is absolutely needed (eg you create a save state or state manager archive) - SuperFX works [needed to call system.init() in Interface::Interface()] Last chance for any bug reports, at this point I pretty much consider ethos to be finished. It's shipping without BS-X BIOS game loading support. Sorry, I can't figure that one out.
This commit is contained in:
parent
689fc49047
commit
c3f9d421da
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
namespace Emulator {
|
namespace Emulator {
|
||||||
static const char Name[] = "bsnes";
|
static const char Name[] = "bsnes";
|
||||||
static const char Version[] = "088.15";
|
static const char Version[] = "088.16";
|
||||||
static const char Author[] = "byuu";
|
static const char Author[] = "byuu";
|
||||||
static const char License[] = "GPLv3";
|
static const char License[] = "GPLv3";
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,14 @@ namespace GameBoy {
|
||||||
|
|
||||||
Interface *interface = nullptr;
|
Interface *interface = nullptr;
|
||||||
|
|
||||||
|
void Interface::lcdScanline() {
|
||||||
|
if(hook) hook->lcdScanline();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Interface::joypWrite(bool p15, bool p14) {
|
||||||
|
if(hook) hook->joypWrite(p15, p14);
|
||||||
|
}
|
||||||
|
|
||||||
double Interface::videoFrequency() {
|
double Interface::videoFrequency() {
|
||||||
return 4194304.0 / (154.0 * 456.0);
|
return 4194304.0 / (154.0 * 456.0);
|
||||||
}
|
}
|
||||||
|
@ -97,6 +105,7 @@ void Interface::updatePalette() {
|
||||||
|
|
||||||
Interface::Interface() {
|
Interface::Interface() {
|
||||||
interface = this;
|
interface = this;
|
||||||
|
hook = nullptr;
|
||||||
|
|
||||||
information.name = "Game Boy";
|
information.name = "Game Boy";
|
||||||
information.width = 160;
|
information.width = 160;
|
||||||
|
|
|
@ -19,8 +19,13 @@ struct ID {
|
||||||
|
|
||||||
struct Interface : Emulator::Interface {
|
struct Interface : Emulator::Interface {
|
||||||
//Super Game Boy bindings
|
//Super Game Boy bindings
|
||||||
virtual void lcdScanline() {}
|
struct Hook {
|
||||||
virtual void joypWrite(bool p15, bool p14) {}
|
virtual void lcdScanline() {}
|
||||||
|
virtual void joypWrite(bool p15, bool p14) {}
|
||||||
|
} *hook;
|
||||||
|
|
||||||
|
void lcdScanline();
|
||||||
|
void joypWrite(bool p15, bool p14);
|
||||||
|
|
||||||
double videoFrequency();
|
double videoFrequency();
|
||||||
double audioFrequency();
|
double audioFrequency();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//ARMv3 (ARM6)
|
//ARMv3 (ARM6)
|
||||||
|
|
||||||
struct ArmDSP : Processor::ARM, public Coprocessor {
|
struct ArmDSP : Processor::ARM, Coprocessor {
|
||||||
uint8 *firmware;
|
uint8 *firmware;
|
||||||
uint8 *programROM;
|
uint8 *programROM;
|
||||||
uint8 *dataROM;
|
uint8 *dataROM;
|
||||||
|
|
|
@ -8,11 +8,11 @@ void BSXCartridge::init() {
|
||||||
void BSXCartridge::load() {
|
void BSXCartridge::load() {
|
||||||
sram.map(allocate<uint8>(32 * 1024, 0xff), 32 * 1024);
|
sram.map(allocate<uint8>(32 * 1024, 0xff), 32 * 1024);
|
||||||
sram.write_protect(false);
|
sram.write_protect(false);
|
||||||
interface->memory.append({ID::BsxRAM, "bsx.ram"});
|
interface->memory.append({ID::BsxRAM, "save.ram"});
|
||||||
|
|
||||||
psram.map(allocate<uint8>(512 * 1024, 0xff), 512 * 1024);
|
psram.map(allocate<uint8>(512 * 1024, 0xff), 512 * 1024);
|
||||||
psram.write_protect(false);
|
psram.write_protect(false);
|
||||||
interface->memory.append({ID::BsxPSRAM, "bsx.psram"});
|
interface->memory.append({ID::BsxPSRAM, "bsx.ram"});
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSXCartridge::unload() {
|
void BSXCartridge::unload() {
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class BSXCartridge {
|
struct BSXCartridge {
|
||||||
public:
|
|
||||||
MappedRAM sram;
|
MappedRAM sram;
|
||||||
MappedRAM psram;
|
MappedRAM psram;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class BSXFlash : public Memory {
|
struct BSXFlash : Memory {
|
||||||
public:
|
|
||||||
MappedRAM memory;
|
MappedRAM memory;
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class BSXSatellaview {
|
struct BSXSatellaview {
|
||||||
public:
|
|
||||||
void init();
|
void init();
|
||||||
void load();
|
void load();
|
||||||
void unload();
|
void unload();
|
||||||
|
|
|
@ -33,12 +33,15 @@ void ICD2::init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ICD2::load() {
|
void ICD2::load() {
|
||||||
interface = GameBoy::interface->bind;
|
bind = GameBoy::interface->bind;
|
||||||
|
hook = GameBoy::interface->hook;
|
||||||
GameBoy::interface->bind = this;
|
GameBoy::interface->bind = this;
|
||||||
|
GameBoy::interface->hook = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ICD2::unload() {
|
void ICD2::unload() {
|
||||||
GameBoy::interface->bind = interface;
|
GameBoy::interface->bind = bind;
|
||||||
|
GameBoy::interface->hook = hook;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ICD2::power() {
|
void ICD2::power() {
|
||||||
|
@ -56,7 +59,7 @@ void ICD2::reset() {
|
||||||
r6005 = 0xff;
|
r6005 = 0xff;
|
||||||
r6006 = 0xff;
|
r6006 = 0xff;
|
||||||
r6007 = 0xff;
|
r6007 = 0xff;
|
||||||
for(unsigned n = 0; n < 16; n++) r7000[n] = 0x00;
|
for(auto &r : r7000) r = 0x00;
|
||||||
r7800 = 0x0000;
|
r7800 = 0x0000;
|
||||||
mlt_req = 0;
|
mlt_req = 0;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
struct ICD2 : Emulator::Interface::Bind, Coprocessor {
|
struct ICD2 : Emulator::Interface::Bind, GameBoy::Interface::Hook, Coprocessor {
|
||||||
unsigned revision;
|
unsigned revision;
|
||||||
|
|
||||||
static void Enter();
|
static void Enter();
|
||||||
|
@ -16,7 +16,8 @@ struct ICD2 : Emulator::Interface::Bind, Coprocessor {
|
||||||
void serialize(serializer&);
|
void serialize(serializer&);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Emulator::Interface::Bind *interface;
|
Emulator::Interface::Bind *bind;
|
||||||
|
GameBoy::Interface::Hook *hook;
|
||||||
#include "interface/interface.hpp"
|
#include "interface/interface.hpp"
|
||||||
#include "mmio/mmio.hpp"
|
#include "mmio/mmio.hpp"
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class Link : public Coprocessor, public library {
|
struct Link : Coprocessor, library {
|
||||||
public:
|
|
||||||
string program;
|
string program;
|
||||||
|
|
||||||
static void Enter();
|
static void Enter();
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class MSU1 : public Coprocessor {
|
struct MSU1 : Coprocessor {
|
||||||
public:
|
|
||||||
static void Enter();
|
static void Enter();
|
||||||
void enter();
|
void enter();
|
||||||
void init();
|
void init();
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class OBC1 {
|
struct OBC1 {
|
||||||
public:
|
|
||||||
void init();
|
void init();
|
||||||
void load();
|
void load();
|
||||||
void unload();
|
void unload();
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class SDD1 {
|
struct SDD1 {
|
||||||
public:
|
|
||||||
void init();
|
void init();
|
||||||
void load();
|
void load();
|
||||||
void unload();
|
void unload();
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
//SPC7110 emulator - version 0.05 (2011-06-27)
|
//SPC7110 emulator - version 0.05 (2011-06-27)
|
||||||
//Copyright (c) 2008-2011, byuu and neviksti
|
//Copyright (c) 2008-2011, byuu and neviksti
|
||||||
|
|
||||||
class SPC7110 {
|
struct SPC7110 {
|
||||||
public:
|
|
||||||
uint8 rtc[20];
|
uint8 rtc[20];
|
||||||
unsigned data_rom_offset;
|
unsigned data_rom_offset;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class SRTC {
|
struct SRTC {
|
||||||
public:
|
|
||||||
uint8 rtc[20];
|
uint8 rtc[20];
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class SufamiTurbo {
|
struct SufamiTurbo {
|
||||||
public:
|
|
||||||
struct Slot {
|
struct Slot {
|
||||||
MappedRAM rom;
|
MappedRAM rom;
|
||||||
MappedRAM ram;
|
MappedRAM ram;
|
||||||
|
|
|
@ -39,8 +39,8 @@ void SuperFX::enter() {
|
||||||
|
|
||||||
void SuperFX::init() {
|
void SuperFX::init() {
|
||||||
initialize_opcode_table();
|
initialize_opcode_table();
|
||||||
regs.r[14].modify = { &SuperFX::r14_modify, this };
|
regs.r[14].modify = {&SuperFX::r14_modify, this};
|
||||||
regs.r[15].modify = { &SuperFX::r15_modify, this };
|
regs.r[15].modify = {&SuperFX::r15_modify, this};
|
||||||
}
|
}
|
||||||
|
|
||||||
void SuperFX::load() {
|
void SuperFX::load() {
|
||||||
|
|
|
@ -228,6 +228,7 @@ void Interface::updatePalette() {
|
||||||
|
|
||||||
Interface::Interface() {
|
Interface::Interface() {
|
||||||
interface = this;
|
interface = this;
|
||||||
|
system.init();
|
||||||
|
|
||||||
information.name = "Super Famicom";
|
information.name = "Super Famicom";
|
||||||
information.width = 256;
|
information.width = 256;
|
||||||
|
|
|
@ -2,6 +2,16 @@
|
||||||
|
|
||||||
#include "mode7.cpp"
|
#include "mode7.cpp"
|
||||||
|
|
||||||
|
unsigned PPU::Background::voffset() const {
|
||||||
|
if(regs.mosaic) return cache.voffset;
|
||||||
|
return regs.voffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned PPU::Background::hoffset() const {
|
||||||
|
if(regs.mosaic) return cache.hoffset;
|
||||||
|
return regs.hoffset;
|
||||||
|
}
|
||||||
|
|
||||||
//V = 0, H = 0
|
//V = 0, H = 0
|
||||||
void PPU::Background::frame() {
|
void PPU::Background::frame() {
|
||||||
}
|
}
|
||||||
|
@ -10,7 +20,7 @@ void PPU::Background::frame() {
|
||||||
void PPU::Background::scanline() {
|
void PPU::Background::scanline() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//H = 60
|
//H = 28
|
||||||
void PPU::Background::begin() {
|
void PPU::Background::begin() {
|
||||||
bool hires = (self.regs.bgmode == 5 || self.regs.bgmode == 6);
|
bool hires = (self.regs.bgmode == 5 || self.regs.bgmode == 6);
|
||||||
x = -7;
|
x = -7;
|
||||||
|
@ -65,8 +75,8 @@ void PPU::Background::get_tile() {
|
||||||
unsigned px = x << hires;
|
unsigned px = x << hires;
|
||||||
unsigned py = (regs.mosaic == 0 ? y : mosaic.voffset);
|
unsigned py = (regs.mosaic == 0 ? y : mosaic.voffset);
|
||||||
|
|
||||||
unsigned hscroll = cache.hoffset;
|
unsigned hscroll = hoffset();
|
||||||
unsigned vscroll = cache.voffset;
|
unsigned vscroll = voffset();
|
||||||
if(hires) {
|
if(hires) {
|
||||||
hscroll <<= 1;
|
hscroll <<= 1;
|
||||||
if(self.regs.interlace) py = (py << 1) + self.field();
|
if(self.regs.interlace) py = (py << 1) + self.field();
|
||||||
|
@ -79,8 +89,8 @@ void PPU::Background::get_tile() {
|
||||||
uint16 offset_x = (x + (hscroll & 7));
|
uint16 offset_x = (x + (hscroll & 7));
|
||||||
|
|
||||||
if(offset_x >= 8) {
|
if(offset_x >= 8) {
|
||||||
unsigned hval = self.bg3.get_tile((offset_x - 8) + (self.bg3.cache.hoffset & ~7), self.bg3.cache.voffset + 0);
|
unsigned hval = self.bg3.get_tile((offset_x - 8) + (self.bg3.hoffset() & ~7), self.bg3.voffset() + 0);
|
||||||
unsigned vval = self.bg3.get_tile((offset_x - 8) + (self.bg3.cache.hoffset & ~7), self.bg3.cache.voffset + 8);
|
unsigned vval = self.bg3.get_tile((offset_x - 8) + (self.bg3.hoffset() & ~7), self.bg3.voffset() + 8);
|
||||||
unsigned valid_mask = (id == ID::BG1 ? 0x2000 : 0x4000);
|
unsigned valid_mask = (id == ID::BG1 ? 0x2000 : 0x4000);
|
||||||
|
|
||||||
if(self.regs.bgmode == 4) {
|
if(self.regs.bgmode == 4) {
|
||||||
|
|
|
@ -30,6 +30,9 @@ struct Background {
|
||||||
uint16 voffset;
|
uint16 voffset;
|
||||||
} cache;
|
} cache;
|
||||||
|
|
||||||
|
unsigned voffset() const;
|
||||||
|
unsigned hoffset() const;
|
||||||
|
|
||||||
struct Output {
|
struct Output {
|
||||||
struct Pixel {
|
struct Pixel {
|
||||||
unsigned priority; //0 = none (transparent)
|
unsigned priority; //0 = none (transparent)
|
||||||
|
|
|
@ -5,7 +5,7 @@ signed PPU::Background::clip(signed n) {
|
||||||
return n & 0x2000 ? (n | ~1023) : (n & 1023);
|
return n & 0x2000 ? (n | ~1023) : (n & 1023);
|
||||||
}
|
}
|
||||||
|
|
||||||
//H = 60
|
//H = 28
|
||||||
void PPU::Background::begin_mode7() {
|
void PPU::Background::begin_mode7() {
|
||||||
cache.hoffset = self.regs.mode7_hoffset;
|
cache.hoffset = self.regs.mode7_hoffset;
|
||||||
cache.voffset = self.regs.mode7_voffset;
|
cache.voffset = self.regs.mode7_voffset;
|
||||||
|
|
|
@ -124,7 +124,7 @@ string Browser::select(const string &title, const string &extension) {
|
||||||
if(path.empty()) path = application->basepath;
|
if(path.empty()) path = application->basepath;
|
||||||
setPath(path, selection);
|
setPath(path, selection);
|
||||||
|
|
||||||
filterLabel.setText({"Files of type: *.", extension});
|
filterLabel.setText({"Filter: *.", extension});
|
||||||
|
|
||||||
audio.clear();
|
audio.clear();
|
||||||
setTitle(title);
|
setTitle(title);
|
||||||
|
|
|
@ -101,6 +101,8 @@ bool StateManager::save(const string &filename, unsigned revision) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
directory::create(dir(filename));
|
||||||
|
|
||||||
file fp;
|
file fp;
|
||||||
if(fp.open(filename, file::mode::write) == false) return false;
|
if(fp.open(filename, file::mode::write) == false) return false;
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,6 @@ void Utility::saveMemory() {
|
||||||
system().save(memory.id, fs);
|
system().save(memory.id, fs);
|
||||||
}
|
}
|
||||||
|
|
||||||
directory::create({pathname[0], "bsnes/"});
|
|
||||||
cheatEditor->save({pathname[0], "cheats.xml"});
|
cheatEditor->save({pathname[0], "cheats.xml"});
|
||||||
stateManager->save({pathname[0], "bsnes/states.bsa"}, 1);
|
stateManager->save({pathname[0], "bsnes/states.bsa"}, 1);
|
||||||
}
|
}
|
||||||
|
@ -138,9 +137,9 @@ void Utility::saveState(unsigned slot) {
|
||||||
void Utility::loadState(unsigned slot) {
|
void Utility::loadState(unsigned slot) {
|
||||||
if(application->active == nullptr) return;
|
if(application->active == nullptr) return;
|
||||||
auto memory = file::read({pathname[0], "bsnes/state-", slot, ".bsa"});
|
auto memory = file::read({pathname[0], "bsnes/state-", slot, ".bsa"});
|
||||||
if(memory.size() == 0) return;
|
if(memory.size() == 0) return showMessage({"Unable to locate slot ", slot, " state"});
|
||||||
serializer s(memory.data(), memory.size());
|
serializer s(memory.data(), memory.size());
|
||||||
if(system().unserialize(s) == false) return;
|
if(system().unserialize(s) == false) return showMessage({"Slot ", slot, " state incompatible"});
|
||||||
showMessage({"Loaded from slot ", slot});
|
showMessage({"Loaded from slot ", slot});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue