Update to v105r1 release.

byuu says:

Changelog:

  - higan: readded support for soft-reset to Famicom, Super Famicom,
    Mega Drive cores (work in progress)
      - handhelds lack soft reset obviously
      - the PC Engine also lacks a physical reset button
      - the Master System's reset button acts like a gamepad button, so
        can't show up in the menu
  - Mega Drive: power cycle wasn't initializing CPU (M68K) or APU (Z80)
    RAM
  - Super Famicom: fix SPC700 opcode 0x3b regression; fixes Majuu Ou
    [Jonas Quinn]
  - Super Famicom: fix SharpRTC save regression; fixes Dai Kaijuu
    Monogatari II's real-time clock [Talarubi]
  - Super Famicom: fix EpsonRTC save regression; fixes Tengai Makyou
    Zero's real-time clock [Talarubi]
  - Super Famicom: removed `*::init()` functions, as they were never used
  - Super Famicom: removed all but two `*::load()` functions, as they
    were not used
  - higan: added option to auto-save backup RAM every five seconds
    (enabled by default)
      - this is in case the emulator crashes, or there's a power outage;
        turn it off under advanced settings if you want
  - libco: updated license from public domain to ISC, for consistency
    with nall, ruby, hiro
  - nall: Linux compiler defaults to g++; override with g++-version if
    g++ is <= 4.8
      - FreeBSD compiler default is going to remain g++49 until my dev
        box OS ships with g++ >= 4.9

Errata: I have weird RAM initialization constants, thanks to hex_usr
and onethirdxcubed for both finding this:
http://wiki.nesdev.com/w/index.php?title=CPU_power_up_state&diff=11711&oldid=11184

I'll remove this in the next WIP.
This commit is contained in:
Tim Allen 2017-11-07 09:05:54 +11:00
parent 6d487925d0
commit e9d2d56df9
89 changed files with 166 additions and 314 deletions

View File

@ -12,7 +12,7 @@ using namespace nall;
namespace Emulator {
static const string Name = "higan";
static const string Version = "105 (tr1)";
static const string Version = "105.01";
static const string Author = "byuu";
static const string License = "GPLv3";
static const string Website = "https://byuu.org/";

View File

@ -6,7 +6,8 @@ struct Interface {
struct Information {
string manufacturer;
string name;
bool overscan;
bool overscan = false;
bool resettable = false;
} information;
struct Medium {
@ -59,6 +60,7 @@ struct Interface {
//system interface
virtual auto connect(uint port, uint device) -> void {}
virtual auto power() -> void {}
virtual auto reset() -> void {}
virtual auto run() -> void {}
//time functions

View File

@ -71,7 +71,7 @@ auto APU::setSample(int16 sample) -> void {
cartridgeSample = sample;
}
auto APU::power() -> void {
auto APU::power(bool reset) -> void {
create(APU::Enter, system.frequency());
stream = Emulator::audio.createStream(1, frequency() / rate());
stream->addFilter(Emulator::Filter::Order::First, Emulator::Filter::Type::HighPass, 90.0);

View File

@ -12,7 +12,7 @@ struct APU : Thread {
auto setIRQ() -> void;
auto setSample(int16 sample) -> void;
auto power() -> void;
auto power(bool reset) -> void;
auto readIO(uint16 addr) -> uint8;
auto writeIO(uint16 addr, uint8 data) -> void;

View File

@ -24,16 +24,16 @@ auto CPU::step(uint clocks) -> void {
for(auto peripheral : peripherals) synchronize(*peripheral);
}
auto CPU::power() -> void {
auto CPU::power(bool reset) -> void {
MOS6502::BCD = 0;
MOS6502::power();
create(CPU::Enter, system.frequency());
for(auto addr : range(0x0800)) ram[addr] = 0xff;
ram[0x0008] = 0xf7;
ram[0x0009] = 0xef;
ram[0x000a] = 0xdf;
ram[0x000f] = 0xbf;
if(!reset) for(auto& data : ram) data = 0xff;
ram[0x008] = 0xf7; //todo: what is this about?
ram[0x009] = 0xef;
ram[0x00a] = 0xdf;
ram[0x00f] = 0xbf;
r.pc.byte(0) = bus.read(0xfffc);
r.pc.byte(1) = bus.read(0xfffd);

View File

@ -6,7 +6,7 @@ struct CPU : Processor::MOS6502, Thread {
auto main() -> void;
auto step(uint clocks) -> void;
auto power() -> void;
auto power(bool reset) -> void;
//memory.cpp
auto readRAM(uint11 addr) -> uint8;
@ -37,7 +37,7 @@ struct CPU : Processor::MOS6502, Thread {
//protected:
vector<Thread*> peripherals;
uint8 ram[0x0800];
uint8 ram[0x800];
struct IO {
bool interruptPending;

View File

@ -8,6 +8,7 @@ Interface::Interface() {
information.manufacturer = "Nintendo";
information.name = "Famicom";
information.overscan = true;
information.resettable = true;
media.append({ID::Famicom, "Famicom", "fc"});
@ -137,7 +138,11 @@ auto Interface::connect(uint port, uint device) -> void {
}
auto Interface::power() -> void {
system.power();
system.power(/* reset = */ false);
}
auto Interface::reset() -> void {
system.power(/* reset = */ true);
}
auto Interface::run() -> void {

View File

@ -38,6 +38,7 @@ struct Interface : Emulator::Interface {
auto connect(uint port, uint device) -> void override;
auto power() -> void override;
auto reset() -> void override;
auto run() -> void override;
auto serialize() -> serializer override;

View File

@ -54,18 +54,20 @@ auto PPU::refresh() -> void {
Emulator::video.refresh(buffer, 256 * sizeof(uint32), 256, 240);
}
auto PPU::power() -> void {
auto PPU::power(bool reset) -> void {
create(PPU::Enter, system.frequency());
memory::fill(&io, sizeof(IO));
memory::fill(&latch, sizeof(Latches));
io.vramIncrement = 1;
for(auto& n : ciram ) n = 0;
for(auto& n : cgram ) n = 0;
for(auto& n : oam ) n = 0;
if(!reset) {
for(auto& data : ciram ) data = 0;
for(auto& data : cgram ) data = 0;
for(auto& data : oam ) data = 0;
}
for(auto& n : buffer) n = 0;
for(auto& data : buffer) data = 0;
}
}

View File

@ -11,7 +11,7 @@ struct PPU : Thread {
auto frame() -> void;
auto refresh() -> void;
auto power() -> void;
auto power(bool reset) -> void;
//memory.cpp
auto readCIRAM(uint11 addr) -> uint8;

View File

@ -31,7 +31,7 @@ auto System::unserialize(serializer& s) -> bool {
if(signature != 0x31545342) return false;
if(string{version} != Emulator::SerializerVersion) return false;
power();
power(/* reset = */ false);
serializeAll(s);
return true;
}

View File

@ -62,7 +62,7 @@ auto System::unload() -> void {
information.loaded = false;
}
auto System::power() -> void {
auto System::power(bool reset) -> void {
Emulator::video.reset();
Emulator::video.setInterface(interface);
configureVideoPalette();
@ -73,9 +73,9 @@ auto System::power() -> void {
scheduler.reset();
cartridge.power();
cpu.power();
apu.power();
ppu.power();
cpu.power(reset);
apu.power(reset);
ppu.power(reset);
scheduler.primary(cpu);
controllerPort1.power(ID::Port::Controller1);

View File

@ -11,7 +11,7 @@ struct System {
auto load(Emulator::Interface*) -> bool;
auto save() -> void;
auto unload() -> void;
auto power() -> void;
auto power(bool reset) -> void;
auto init() -> void;
auto term() -> void;

View File

@ -52,11 +52,13 @@ auto APU::enable(bool value) -> void {
state.enabled = value;
}
auto APU::power() -> void {
auto APU::power(bool reset) -> void {
Z80::bus = this;
Z80::power();
bus->grant(false);
create(APU::Enter, system.frequency() / 15.0);
if(!reset) memory::fill(ram, sizeof ram);
state = {};
}

View File

@ -8,7 +8,7 @@ struct APU : Processor::Z80, Processor::Z80::Bus, Thread {
auto synchronizing() const -> bool override;
auto enable(bool) -> void;
auto power() -> void;
auto power(bool reset) -> void;
auto reset() -> void;
auto setNMI(bool value) -> void;

View File

@ -80,11 +80,13 @@ auto CPU::load(Markup::Node node) -> bool {
return true;
}
auto CPU::power() -> void {
auto CPU::power(bool reset) -> void {
M68K::bus = this;
M68K::power();
create(CPU::Enter, system.frequency() / 7.0);
if(!reset) memory::fill(ram, sizeof ram);
io = {};
io.version = tmssEnable;
io.romEnable = !tmssEnable;

View File

@ -19,7 +19,7 @@ struct CPU : Processor::M68K, Processor::M68K::Bus, Thread {
auto lower(Interrupt) -> void;
auto load(Markup::Node) -> bool;
auto power() -> void;
auto power(bool reset) -> void;
//bus.cpp
auto readByte(uint24 address) -> uint16 override;

View File

@ -8,6 +8,7 @@ Interface::Interface() {
information.manufacturer = "Sega";
information.name = "Mega Drive";
information.overscan = true;
information.resettable = true;
media.append({ID::MegaDrive, "Mega Drive", "md"});
@ -122,7 +123,11 @@ auto Interface::connect(uint port, uint device) -> void {
}
auto Interface::power() -> void {
system.power();
system.power(/* reset = */ false);
}
auto Interface::reset() -> void {
system.power(/* reset = */ true);
}
auto Interface::run() -> void {

View File

@ -38,6 +38,7 @@ struct Interface : Emulator::Interface {
auto connect(uint port, uint device) -> void override;
auto power() -> void override;
auto reset() -> void override;
auto run() -> void override;
auto serialize() -> serializer override;

View File

@ -34,7 +34,7 @@ auto PSG::step(uint clocks) -> void {
synchronize(apu);
}
auto PSG::power() -> void {
auto PSG::power(bool reset) -> void {
create(PSG::Enter, system.frequency() / 15.0);
stream = Emulator::audio.createStream(1, frequency() / 16.0);
stream->addFilter(Emulator::Filter::Order::First, Emulator::Filter::Type::HighPass, 20.0);

View File

@ -7,7 +7,7 @@ struct PSG : Thread {
auto main() -> void;
auto step(uint clocks) -> void;
auto power() -> void;
auto power(bool reset) -> void;
//io.cpp
auto write(uint8 data) -> void;

View File

@ -48,7 +48,7 @@ auto System::unserialize(serializer& s) -> bool {
if(signature != 0x31545342) return false;
if(string{version} != Emulator::SerializerVersion) return false;
power();
power(/* reset = */ false);
serializeAll(s);
return true;
}

View File

@ -61,7 +61,7 @@ auto System::unload() -> void {
cartridge.unload();
}
auto System::power() -> void {
auto System::power(bool reset) -> void {
Emulator::video.reset();
Emulator::video.setInterface(interface);
Emulator::video.setPalette();
@ -71,11 +71,11 @@ auto System::power() -> void {
scheduler.reset();
cartridge.power();
cpu.power();
apu.power();
vdp.power();
psg.power();
ym2612.power();
cpu.power(reset);
apu.power(reset);
vdp.power(reset);
psg.power(reset);
ym2612.power(reset);
scheduler.primary(cpu);
controllerPort1.power(ID::Port::Controller1);

View File

@ -15,7 +15,7 @@ struct System {
auto load(Emulator::Interface*, maybe<Region> = nothing) -> bool;
auto save() -> void;
auto unload() -> void;
auto power() -> void;
auto power(bool reset) -> void;
//serialization.cpp
auto serializeInit() -> void;

View File

@ -81,11 +81,17 @@ auto VDP::refresh() -> void {
Emulator::video.refresh(data, 1280 * sizeof(uint32), 1280, 480);
}
auto VDP::power() -> void {
auto VDP::power(bool reset) -> void {
create(VDP::Enter, system.frequency() / 2.0);
output = buffer + 16 * 1280; //overscan offset
if(!reset) {
for(auto& data : vram.memory) data = 0;
for(auto& data : vsram.memory) data = 0;
for(auto& data : cram.memory) data = 0;
}
io = {};
latch = {};
state = {};

View File

@ -6,7 +6,7 @@ struct VDP : Thread {
auto step(uint clocks) -> void;
auto refresh() -> void;
auto power() -> void;
auto power(bool reset) -> void;
//io.cpp
auto read(uint24 addr) -> uint16;
@ -166,7 +166,6 @@ private:
//serialization.cpp
auto serialize(serializer&) -> void;
private:
uint16 memory[32768];
} vram;
@ -179,7 +178,6 @@ private:
//serialization.cpp
auto serialize(serializer&) -> void;
private:
uint10 memory[40];
} vsram;
@ -192,7 +190,6 @@ private:
//serialization.cpp
auto serialize(serializer&) -> void;
private:
uint9 memory[64];
} cram;

View File

@ -154,7 +154,7 @@ auto YM2612::step(uint clocks) -> void {
synchronize(apu);
}
auto YM2612::power() -> void {
auto YM2612::power(bool reset) -> void {
create(YM2612::Enter, system.frequency() / 7.0);
stream = Emulator::audio.createStream(2, frequency() / 144.0);
stream->addFilter(Emulator::Filter::Order::First, Emulator::Filter::Type::HighPass, 20.0);

View File

@ -8,7 +8,7 @@ struct YM2612 : Thread {
auto sample() -> void;
auto step(uint clocks) -> void;
auto power() -> void;
auto power(bool reset) -> void;
//io.cpp
auto readStatus() -> uint8;

View File

@ -259,14 +259,12 @@ auto Cartridge::loadNECDSP(Markup::Node node) -> void {
auto Cartridge::loadEpsonRTC(Markup::Node node) -> void {
has.EpsonRTC = true;
epsonrtc.initialize();
if(auto fp = platform->open(ID::SuperFamicom, node["ram"]["name"].text(), File::Read)) {
uint8 data[16] = {0};
for(auto& byte : data) byte = fp->read();
epsonrtc.load(data);
}
else {
epsonrtc.load();
}
for(auto leaf : node.find("map")) loadMap(leaf, {&EpsonRTC::read, &epsonrtc}, {&EpsonRTC::write, &epsonrtc});
}
@ -274,14 +272,12 @@ auto Cartridge::loadEpsonRTC(Markup::Node node) -> void {
auto Cartridge::loadSharpRTC(Markup::Node node) -> void {
has.SharpRTC = true;
sharprtc.initialize();
if(auto fp = platform->open(ID::SuperFamicom, node["ram"]["name"].text(), File::Read)) {
uint8 data[16] = {0};
for(auto& byte : data) byte = fp->read();
sharprtc.load(data);
}
else {
sharprtc.load();
}
for(auto leaf : node.find("map")) loadMap(leaf, {&SharpRTC::read, &sharprtc}, {&SharpRTC::write, &sharprtc});
}

View File

@ -81,15 +81,6 @@ auto ArmDSP::write(uint24 addr, uint8 data) -> void {
}
}
auto ArmDSP::init() -> void {
}
auto ArmDSP::load() -> void {
}
auto ArmDSP::unload() -> void {
}
auto ArmDSP::power() -> void {
random.array((uint8*)programRAM, sizeof(programRAM));
bridge.reset = false;

View File

@ -19,9 +19,6 @@ struct ArmDSP : Processor::ARM7TDMI, Thread {
auto read(uint24 addr, uint8 data) -> uint8;
auto write(uint24 addr, uint8 data) -> void;
auto init() -> void;
auto load() -> void;
auto unload() -> void;
auto power() -> void;
auto reset() -> void; //soft reset

View File

@ -30,10 +30,7 @@ auto EpsonRTC::main() -> void {
synchronize(cpu);
}
auto EpsonRTC::init() -> void {
}
auto EpsonRTC::load() -> void {
auto EpsonRTC::initialize() -> void {
secondlo = 0;
secondhi = 0;
batteryfailure = 1;
@ -74,9 +71,6 @@ auto EpsonRTC::load() -> void {
test = 0;
}
auto EpsonRTC::unload() -> void {
}
auto EpsonRTC::power() -> void {
create(EpsonRTC::Enter, 32'768 * 64);

View File

@ -4,9 +4,7 @@ struct EpsonRTC : Thread {
static auto Enter() -> void;
auto main() -> void;
auto init() -> void;
auto load() -> void;
auto unload() -> void;
auto initialize() -> void;
auto power() -> void;
auto sync() -> void;

View File

@ -28,12 +28,6 @@ auto Event::main() -> void {
synchronize(cpu);
}
auto Event::init() -> void {
}
auto Event::load() -> void {
}
auto Event::unload() -> void {
rom[0].reset();
rom[1].reset();

View File

@ -5,8 +5,6 @@
struct Event : Thread {
static auto Enter() -> void;
auto main() -> void;
auto init() -> void;
auto load() -> void;
auto unload() -> void;
auto power() -> void;

View File

@ -25,12 +25,6 @@ auto HitachiDSP::main() -> void {
synchronize(cpu);
}
auto HitachiDSP::init() -> void {
}
auto HitachiDSP::load() -> void {
}
auto HitachiDSP::unload() -> void {
rom.reset();
ram.reset();

View File

@ -5,8 +5,6 @@ struct HitachiDSP : Processor::HG51B, Thread {
static auto Enter() -> void;
auto main() -> void;
auto init() -> void;
auto load() -> void;
auto unload() -> void;
auto power() -> void;

View File

@ -31,9 +31,6 @@ auto ICD2::main() -> void {
synchronize(cpu);
}
auto ICD2::init() -> void {
}
auto ICD2::load() -> bool {
GameBoy::superGameBoy = this;
GameBoy::system.load(&gameBoyInterface, GameBoy::System::Model::SuperGameBoy, cartridge.pathID());

View File

@ -6,7 +6,6 @@ struct ICD2 : Emulator::Platform, GameBoy::SuperGameBoyInterface, Thread {
static auto Enter() -> void;
auto main() -> void;
auto init() -> void;
auto load() -> bool;
auto unload() -> void;
auto power() -> void;

View File

@ -5,12 +5,6 @@ namespace SuperFamicom {
#include "serialization.cpp"
MCC mcc;
auto MCC::init() -> void {
}
auto MCC::load() -> void {
}
auto MCC::unload() -> void {
rom.reset();
ram.reset();

View File

@ -4,8 +4,6 @@ struct MCC {
MappedRAM rom;
MappedRAM ram;
auto init() -> void;
auto load() -> void;
auto unload() -> void;
auto power() -> void;

View File

@ -39,12 +39,6 @@ auto MSU1::main() -> void {
synchronize(cpu);
}
auto MSU1::init() -> void {
}
auto MSU1::load() -> void {
}
auto MSU1::unload() -> void {
dataFile.reset();
audioFile.reset();

View File

@ -3,8 +3,6 @@ struct MSU1 : Thread {
static auto Enter() -> void;
auto main() -> void;
auto init() -> void;
auto load() -> void;
auto unload() -> void;
auto power() -> void;

View File

@ -43,15 +43,6 @@ auto NECDSP::writeRAM(uint24 addr, uint8 data) -> void {
return uPD96050::writeDP(addr, data);
}
auto NECDSP::init() -> void {
}
auto NECDSP::load() -> void {
}
auto NECDSP::unload() -> void {
}
auto NECDSP::power() -> void {
uPD96050::power();
create(NECDSP::Enter, Frequency);

View File

@ -8,9 +8,6 @@ struct NECDSP : Processor::uPD96050, Thread {
auto readRAM(uint24 addr, uint8 data) -> uint8;
auto writeRAM(uint24 addr, uint8 data) -> void;
auto init() -> void;
auto load() -> void;
auto unload() -> void;
auto power() -> void;
auto firmware() const -> vector<uint8>;

View File

@ -4,15 +4,6 @@ namespace SuperFamicom {
NSS nss;
auto NSS::init() -> void {
}
auto NSS::load() -> void {
}
auto NSS::unload() -> void {
}
auto NSS::power() -> void {
}

View File

@ -1,7 +1,4 @@
struct NSS {
auto init() -> void;
auto load() -> void;
auto unload() -> void;
auto power() -> void;
auto setDip(uint16 dip) -> void;

View File

@ -5,12 +5,6 @@ namespace SuperFamicom {
#include "serialization.cpp"
OBC1 obc1;
auto OBC1::init() -> void {
}
auto OBC1::load() -> void {
}
auto OBC1::unload() -> void {
ram.reset();
}

View File

@ -1,6 +1,4 @@
struct OBC1 {
auto init() -> void;
auto load() -> void;
auto unload() -> void;
auto power() -> void;

View File

@ -117,12 +117,6 @@ auto SA1::triggerIRQ() -> void {
if(mmio.timer_irqen) mmio.timer_irqcl = 0;
}
auto SA1::init() -> void {
}
auto SA1::load() -> void {
}
auto SA1::unload() -> void {
rom.reset();
iram.reset();

View File

@ -10,8 +10,6 @@ struct SA1 : Processor::WDC65816, Thread {
alwaysinline auto interruptPending() const -> bool override;
auto synchronizing() const -> bool override;
auto init() -> void;
auto load() -> void;
auto unload() -> void;
auto power() -> void;

View File

@ -7,12 +7,6 @@ SDD1 sdd1;
#include "decompressor.cpp"
#include "serialization.cpp"
auto SDD1::init() -> void {
}
void SDD1::load() {
}
auto SDD1::unload() -> void {
rom.reset();
ram.reset();

View File

@ -1,6 +1,4 @@
struct SDD1 {
auto init() -> void;
auto load() -> void;
auto unload() -> void;
auto power() -> void;

View File

@ -18,10 +18,7 @@ auto SharpRTC::main() -> void {
synchronize(cpu);
}
auto SharpRTC::init() -> void {
}
auto SharpRTC::load() -> void {
auto SharpRTC::initialize() -> void {
second = 0;
minute = 0;
hour = 0;
@ -31,9 +28,6 @@ auto SharpRTC::load() -> void {
weekday = 0;
}
auto SharpRTC::unload() -> void {
}
auto SharpRTC::power() -> void {
create(SharpRTC::Enter, 1);

View File

@ -2,9 +2,7 @@ struct SharpRTC : Thread {
static auto Enter() -> void;
auto main() -> void;
auto init() -> void;
auto load() -> void;
auto unload() -> void;
auto initialize() -> void;
auto power() -> void;
auto sync() -> void;

View File

@ -32,12 +32,6 @@ auto SPC7110::addClocks(uint clocks) -> void {
synchronize(cpu);
}
auto SPC7110::init() -> void {
}
auto SPC7110::load() -> void {
}
auto SPC7110::unload() -> void {
prom.reset();
drom.reset();

View File

@ -6,8 +6,6 @@ struct SPC7110 : Thread {
static auto Enter() -> void;
auto main() -> void;
auto init() -> void;
auto load() -> void;
auto unload() -> void;
auto power() -> void;

View File

@ -31,12 +31,6 @@ auto SuperFX::main() -> void {
}
}
auto SuperFX::init() -> void {
}
auto SuperFX::load() -> void {
}
auto SuperFX::unload() -> void {
rom.reset();
ram.reset();

View File

@ -5,8 +5,6 @@ struct SuperFX : Processor::GSU, Thread {
//superfx.cpp
static auto Enter() -> void;
auto main() -> void;
auto init() -> void;
auto load() -> void;
auto unload() -> void;
auto power() -> void;

View File

@ -60,7 +60,7 @@ auto CPU::load(Markup::Node node) -> bool {
return true;
}
auto CPU::power() -> void {
auto CPU::power(bool reset) -> void {
WDC65816::power();
create(Enter, system.cpuFrequency());
coprocessors.reset();
@ -86,7 +86,7 @@ auto CPU::power() -> void {
bus.map(reader, writer, "00-3f,80-bf:0000-1fff", 0x2000);
bus.map(reader, writer, "7e-7f:0000-ffff", 0x20000);
random.array(wram, sizeof(wram));
if(!reset) random.array(wram, sizeof(wram));
//DMA
for(auto& channel : this->channel) {

View File

@ -10,7 +10,7 @@ struct CPU : Processor::WDC65816, Thread, PPUcounter {
static auto Enter() -> void;
auto main() -> void;
auto load(Markup::Node) -> bool;
auto power() -> void;
auto power(bool reset) -> void;
//dma.cpp
auto dmaStep(uint clocks) -> void;

View File

@ -228,11 +228,11 @@ auto DSP::load(Markup::Node node) -> bool {
return true;
}
auto DSP::power() -> void {
auto DSP::power(bool reset) -> void {
create(Enter, system.apuFrequency());
stream = Emulator::audio.createStream(2, frequency() / 768.0);
random.array(apuram, sizeof(apuram));
if(!reset) random.array(apuram, sizeof(apuram));
memory::fill(&state, sizeof(State));
state.noise = 0x4000;

View File

@ -14,7 +14,7 @@ struct DSP : Thread {
auto main() -> void;
auto load(Markup::Node) -> bool;
auto power() -> void;
auto power(bool reset) -> void;
//serialization.cpp
auto serialize(serializer&) -> void;

View File

@ -5,11 +5,10 @@ namespace SuperFamicom {
Settings settings;
Interface::Interface() {
system.init();
information.manufacturer = "Nintendo";
information.name = "Super Famicom";
information.overscan = true;
information.resettable = true;
media.append({ID::SuperFamicom, "Super Famicom", "sfc"});
@ -194,7 +193,11 @@ auto Interface::connect(uint port, uint device) -> void {
}
auto Interface::power() -> void {
system.power();
system.power(/* reset = */ false);
}
auto Interface::reset() -> void {
system.power(/* reset = */ true);
}
auto Interface::run() -> void {

View File

@ -50,6 +50,7 @@ struct Interface : Emulator::Interface {
auto connect(uint port, uint device) -> void override;
auto power() -> void override;
auto reset() -> void override;
auto run() -> void override;
auto rtc() -> bool override;

View File

@ -86,7 +86,7 @@ auto PPU::load(Markup::Node node) -> bool {
return true;
}
auto PPU::power() -> void {
auto PPU::power(bool reset) -> void {
create(Enter, system.cpuFrequency());
PPUcounter::reset();
memory::fill(output, 512 * 480 * sizeof(uint32));
@ -95,7 +95,7 @@ auto PPU::power() -> void {
function<auto (uint24, uint8) -> void> writer{&PPU::writeIO, this};
bus.map(reader, writer, "00-3f,80-bf:2100-213f");
random.array((uint8*)vram.data, sizeof(vram.data));
if(!reset) random.array((uint8*)vram.data, sizeof(vram.data));
ppu1.mdr = random.bias(0xff);
ppu2.mdr = random.bias(0xff);

View File

@ -11,7 +11,7 @@ struct PPU : Thread, PPUcounter {
static auto Enter() -> void;
auto main() -> void;
auto load(Markup::Node) -> bool;
auto power() -> void;
auto power(bool reset) -> void;
auto serialize(serializer&) -> void;

View File

@ -4,13 +4,8 @@ namespace SuperFamicom {
BSMemory bsmemory;
auto BSMemory::init() -> void {
}
auto BSMemory::load() -> void {
if(memory.size() == 0) {
memory.allocate(1024 * 1024);
}
if(!memory.size()) memory.allocate(1024 * 1024);
}
auto BSMemory::unload() -> void {

View File

@ -1,5 +1,4 @@
struct BSMemory : Memory {
auto init() -> void;
auto load() -> void;
auto unload() -> void;
auto power() -> void;

View File

@ -6,9 +6,6 @@ namespace SuperFamicom {
SufamiTurboCartridge sufamiturboA;
SufamiTurboCartridge sufamiturboB;
auto SufamiTurboCartridge::load() -> void {
}
auto SufamiTurboCartridge::unload() -> void {
rom.reset();
ram.reset();

View File

@ -1,5 +1,4 @@
struct SufamiTurboCartridge {
auto load() -> void;
auto unload() -> void;
auto serialize(serializer&) -> void;

View File

@ -32,7 +32,7 @@ auto SMP::load(Markup::Node node) -> bool {
return false;
}
auto SMP::power() -> void {
auto SMP::power(bool reset) -> void {
SPC700::power();
create(Enter, system.apuFrequency() / 12.0);

View File

@ -11,7 +11,7 @@ struct SMP : Processor::SPC700, Thread {
auto main() -> void;
auto load(Markup::Node) -> bool;
auto power() -> void;
auto power(bool reset) -> void;
//serialization.cpp
auto serialize(serializer&) -> void;

View File

@ -31,7 +31,7 @@ auto System::unserialize(serializer& s) -> bool {
if(signature != 0x31545342) return false;
if(string{version} != Emulator::SerializerVersion) return false;
power();
power(/* reset = */ false);
serializeAll(s);
return true;
}

View File

@ -22,29 +22,6 @@ auto System::runToSave() -> void {
for(auto peripheral : cpu.peripherals) scheduler.synchronize(*peripheral);
}
auto System::init() -> void {
icd2.init();
mcc.init();
nss.init();
event.init();
sa1.init();
superfx.init();
armdsp.init();
hitachidsp.init();
necdsp.init();
epsonrtc.init();
sharprtc.init();
spc7110.init();
sdd1.init();
obc1.init();
msu1.init();
bsmemory.init();
}
auto System::term() -> void {
}
auto System::load(Emulator::Interface* interface) -> bool {
information = {};
@ -72,21 +49,7 @@ auto System::load(Emulator::Interface* interface) -> bool {
}
if(cartridge.has.ICD2) icd2.load();
if(cartridge.has.MCC) mcc.load();
if(cartridge.has.NSSDIP) nss.load();
if(cartridge.has.Event) event.load();
if(cartridge.has.SA1) sa1.load();
if(cartridge.has.SuperFX) superfx.load();
if(cartridge.has.ARMDSP) armdsp.load();
if(cartridge.has.HitachiDSP) hitachidsp.load();
if(cartridge.has.NECDSP) necdsp.load();
if(cartridge.has.SPC7110) spc7110.load();
if(cartridge.has.SDD1) sdd1.load();
if(cartridge.has.OBC1) obc1.load();
if(cartridge.has.MSU1) msu1.load();
if(cartridge.has.BSMemorySlot) bsmemory.load();
if(cartridge.has.SufamiTurboSlots) sufamiturboA.load(), sufamiturboB.load();
serializeInit();
this->interface = interface;
@ -109,18 +72,14 @@ auto System::unload() -> void {
if(cartridge.has.ICD2) icd2.unload();
if(cartridge.has.MCC) mcc.unload();
if(cartridge.has.NSSDIP) nss.unload();
if(cartridge.has.Event) event.unload();
if(cartridge.has.SA1) sa1.unload();
if(cartridge.has.SuperFX) superfx.unload();
if(cartridge.has.ARMDSP) armdsp.unload();
if(cartridge.has.HitachiDSP) hitachidsp.unload();
if(cartridge.has.NECDSP) necdsp.unload();
if(cartridge.has.SPC7110) spc7110.unload();
if(cartridge.has.SDD1) sdd1.unload();
if(cartridge.has.OBC1) obc1.unload();
if(cartridge.has.MSU1) msu1.unload();
if(cartridge.has.BSMemorySlot) bsmemory.unload();
if(cartridge.has.SufamiTurboSlots) sufamiturboA.unload(), sufamiturboB.unload();
@ -128,7 +87,7 @@ auto System::unload() -> void {
information.loaded = false;
}
auto System::power() -> void {
auto System::power(bool reset) -> void {
Emulator::video.reset();
Emulator::video.setInterface(interface);
configureVideoPalette();
@ -140,10 +99,10 @@ auto System::power() -> void {
random.entropy(Random::Entropy::Low);
scheduler.reset();
cpu.power();
smp.power();
dsp.power();
ppu.power();
cpu.power(reset);
smp.power(reset);
dsp.power(reset);
ppu.power(reset);
if(cartridge.has.ICD2) icd2.power();
if(cartridge.has.MCC) mcc.power();
@ -160,7 +119,6 @@ auto System::power() -> void {
if(cartridge.has.SDD1) sdd1.power();
if(cartridge.has.OBC1) obc1.power();
if(cartridge.has.MSU1) msu1.power();
if(cartridge.has.BSMemorySlot) bsmemory.power();
if(cartridge.has.ICD2) cpu.coprocessors.append(&icd2);

View File

@ -9,12 +9,10 @@ struct System {
auto run() -> void;
auto runToSave() -> void;
auto init() -> void;
auto term() -> void;
auto load(Emulator::Interface*) -> bool;
auto save() -> void;
auto unload() -> void;
auto power() -> void;
auto power(bool reset) -> void;
//video.cpp
auto configureVideoPalette() -> void;

View File

@ -56,6 +56,8 @@ Settings::Settings() {
set("Input/FocusLoss/Pause", false);
set("Input/FocusLoss/AllowInput", false);
set("Emulation/AutoSaveRAM", true);
set("Crashed", false);
}

View File

@ -72,6 +72,14 @@ auto InputManager::appendHotkeys() -> void {
hotkeys.append(hotkey);
}
{ auto hotkey = new InputHotkey;
hotkey->name = "Soft Reset";
hotkey->press = [] {
program->softReset();
};
hotkeys.append(hotkey);
}
{ auto hotkey = new InputHotkey;
hotkey->name = "Power Cycle";
hotkey->press = [] {

View File

@ -42,7 +42,8 @@ Presentation::Presentation() {
}
systemMenu.setText("System").setVisible(false);
reloadSystem.setText("Power Cycle").onActivate([&] { program->powerCycle(); });
resetSystem.setText("Soft Reset").onActivate([&] { program->softReset(); });
powerSystem.setText("Power Cycle").onActivate([&] { program->powerCycle(); });
unloadSystem.setText("Unload").onActivate([&] { program->unloadMedium(); });
settingsMenu.setText("Settings");
@ -213,6 +214,7 @@ auto Presentation::updateEmulator() -> void {
}
systemMenuSeparatorPorts.setVisible(inputPort1.visible() || inputPort2.visible() || inputPort3.visible());
resetSystem.setVisible(emulator->information.resettable);
emulator->set("Blur Emulation", blurEmulation.checked());
emulator->set("Color Emulation", colorEmulation.checked());

View File

@ -23,7 +23,8 @@ struct Presentation : Window {
Menu inputPort2{&systemMenu};
Menu inputPort3{&systemMenu};
MenuSeparator systemMenuSeparatorPorts{&systemMenu};
MenuItem reloadSystem{&systemMenu};
MenuItem resetSystem{&systemMenu};
MenuItem powerSystem{&systemMenu};
MenuItem unloadSystem{&systemMenu};
Menu settingsMenu{&menuBar};
Menu videoScaleMenu{&settingsMenu};

View File

@ -90,6 +90,13 @@ auto Program::main() -> void {
}
emulator->run();
if(settings["Emulation/AutoSaveRAM"].boolean()) {
time_t currentTime = time(nullptr);
if(currentTime - autoSaveTime >= 5) {
autoSaveTime = currentTime;
emulator->save();
}
}
}
auto Program::quit() -> void {

View File

@ -30,6 +30,7 @@ struct Program : Emulator::Platform {
auto initializeAudioDriver() -> void;
auto initializeInputDriver() -> void;
auto softReset() -> void;
auto powerCycle() -> void;
auto rotateDisplay() -> void;
auto connectDevices() -> void;
@ -49,6 +50,8 @@ struct Program : Emulator::Platform {
vector<string> mediumQueue; //for command-line and drag-and-drop loading
vector<string> mediumPaths; //for keeping track of loaded folder locations
time_t autoSaveTime = 0; //for automatically saving RAM periodically
string statusText;
string statusMessage;
time_t statusTime = 0;

View File

@ -64,10 +64,17 @@ auto Program::initializeInputDriver() -> void {
}
}
auto Program::softReset() -> void {
if(!emulator) return;
if(!emulator->information.resettable) return;
emulator->reset();
showMessage("System has been soft reset");
}
auto Program::powerCycle() -> void {
if(!emulator) return;
emulator->power();
showMessage("Power cycled");
showMessage("System has been power cycled");
}
auto Program::rotateDisplay() -> void {
@ -94,12 +101,12 @@ auto Program::connectDevices() -> void {
}
auto Program::showMessage(const string& text) -> void {
statusTime = time(0);
statusTime = time(nullptr);
statusMessage = text;
}
auto Program::updateStatusText() -> void {
time_t currentTime = time(0);
time_t currentTime = time(nullptr);
string text;
if((currentTime - statusTime) <= 2) {

View File

@ -43,4 +43,9 @@ AdvancedSettings::AdvancedSettings(TabFrame* parent) : TabFrameItem(parent) {
ignoreManifests.setText("Ignore Manifests").setChecked(settings["Library/IgnoreManifests"].boolean()).onToggle([&] {
settings["Library/IgnoreManifests"].setValue(ignoreManifests.checked());
});
otherLabel.setText("Other").setFont(Font().setBold());
autoSaveRAM.setText("Auto-Save RAM Periodically").setChecked(settings["Emulation/AutoSaveRAM"].boolean()).onToggle([&] {
settings["Emulation/AutoSaveRAM"].setValue(autoSaveRAM.checked());
});
}

View File

@ -141,6 +141,8 @@ struct AdvancedSettings : TabFrameItem {
LineEdit libraryLocation{&libraryLayout, Size{~0, 0}};
Button libraryChange{&libraryLayout, Size{0, 0}};
CheckLabel ignoreManifests{&layout, Size{~0, 0}};
Label otherLabel{&layout, Size{~0, 0}, 2};
CheckLabel autoSaveRAM{&layout, Size{~0, 0}};
};
struct SettingsManager : Window {

View File

@ -3,14 +3,10 @@ body {
color: #fff;
}
a {
color: #aaf;
}
a:visited {
color: #faf;
}
code {
background: #444;
}
a {
color: #aaf;
}

View File

@ -6,41 +6,19 @@
<body>
<b>License:</b><br/><br/>
libco is released under the ISC license.<br/>
<br/>
Copyright &copy; 2006-2017 byuu<br/>
<br/>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.<br/>
<br/>
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
<hr/>
<b>Contact:</b><br/><br/>
At present, you may contact me as <b>byuu</b> at
<a href="https://board.byuu.org">https://board.byuu.org</a>.<br/>
I am interested in knowing of any projects that make use of this library,
though this is only a courtesy.
libco is released under the ISC license.
<hr/>
<b>Foreword:</b><br/><br/>
libco is a cross-platform, permissively licensed implementation of
cooperative-multithreading; a feature that is sorely lacking
from the ISO C/C++ standard.<br/>
The library is designed for maximum speed and portability, and
not for safety or features. If safety or extra functionality is desired,
a wrapper API can easily be written to encapsulate all library functions.<br/>
Behavior of executing operations that are listed as not permitted
below result in undefined behavior. They may work anyway, they
may cause undesired / unknown behavior, or they may crash the
program entirely.<br/>
cooperative-multithreading; a feature that is sorely lacking from the ISO C/C++
standard.<br/>
The library is designed for maximum speed and portability, and not for safety or
features. If safety or extra functionality is desired, a wrapper API can easily
be written to encapsulate all library functions.<br/>
Behavior of executing operations that are listed as not permitted below result
in undefined behavior. They may work anyway, they may cause undesired / unknown
behavior, or they may crash the program entirely.<br/>
The goal of this library was to simplify the base API as much as possible,
implementing only that which cannot be implemented using pure C. Additional
functionality after this would only complicate ports of this library to new
@ -50,13 +28,12 @@ platforms.
<b>Porting:</b><br/><br/>
This document is included as a reference for porting libco. Please submit any
ports you create to me, so that libco can become more useful. Please note that
since libco is ISC, you must submit your code as a work of the public domain,
or under the same license, in order for it to be included in the official
distribution. Full credit will be given in the source code of the official
release. Please do not bother submitting code to me under any other
license&mdash;including GPL, LGPL, BSD or CC&mdash;I am not interested in
creating a library with multiple different licenses depending on which targets
are used.
since libco is permissively licensed, you must submit your code as a work of the
public domain in order for it to be included in the official distribution.
Full credit will be given in the source code of the official release. Please
do not bother submitting code to me under any other license -- including GPL,
LGPL, BSD or CC -- I am not interested in creating a library with multiple
different licenses depending on which targets are used.
<hr/>
<b>Synopsis:</b><br/><br/>

View File

@ -1,5 +1,5 @@
/*
libco v18.01 (2017-01-22)
libco v18.02 (2017-11-06)
author: byuu
license: ISC
*/

View File

@ -51,7 +51,7 @@ ifeq ($(compiler),)
else ifeq ($(platform),macos)
compiler := clang++
else ifeq ($(platform),linux)
compiler := g++-4.9
compiler := g++
else ifeq ($(platform),bsd)
compiler := g++49
else
@ -89,6 +89,7 @@ endif
# windows settings
ifeq ($(platform),windows)
link += -lws2_32 -lole32
link += $(if $(findstring $(console),true),-mconsole,-mwindows)
windres := windres
endif