Update to v089r06 release.

[Yes, the release number is re-used. -Ed.]

byuu says:

I had some bugs in r07 that I couldn't track down, DKJM2's clock was
getting all out of sync.
So I just reverted to r05, blew away both RTCs entirely, and wrote them
cleanly from scratch (obviously looking off the old code.) A bit
extreme, but it worked.
I believe I found the error in the process, day and month were resetting
the counter to 0 instead of 1, it wasn't handling leap year, etc.
While I was at it, I fixed the day-of-week calculation. The SharpRTC
epoch is actually 1000-01-01, and not 1900-01-01.
I'm sure you guys will be really happy that if it ever becomes 1000AD
again and you're playing a ROM hack that uses the SharpRTC and relies on
its weekday value that it will show the correct day now ...
Kind of a pain to compute, but nothing compared to the seventh circle of
hell that was my IBM dBase III Julian<>Gregorian conversion functions :/
Also found a few bugs in the Epson code this way. And I moved the round
seconds actions and flag clear to +125us after flag set.

So, if you had the old r06 or r07, please delete those.

Unfortunately, this took all of my energy today, so the file names
inside manifest changes will have to be in the next WIP.

EDIT: ran a diff against old r07 and new r06.
- added if(days == 31) case twice in EpsonRTC::tick_day()
- forgot weekday = 0; in SharpRTC::load()
- need to move the cartridge+cheat objects up in sfc/Makefile again
- System::init() needs assert(interface != nullptr /* not 0 */)
This commit is contained in:
Tim Allen 2012-05-25 09:26:06 +10:00
parent 5dbd5f4d0f
commit d418eda97c
15 changed files with 166 additions and 155 deletions

View File

@ -3,7 +3,7 @@
namespace Emulator {
static const char Name[] = "bsnes";
static const char Version[] = "089.07";
static const char Version[] = "089.06";
static const char Author[] = "byuu";
static const char License[] = "GPLv3";
}

View File

@ -32,13 +32,13 @@ endif
obj/sfc-interface.o : $(sfc)/interface/interface.cpp $(call rwildcard,$(sfc)/interface)
obj/sfc-system.o : $(sfc)/system/system.cpp $(call rwildcard,$(sfc)/system/)
obj/sfc-controller.o: $(sfc)/controller/controller.cpp $(call rwildcard,$(sfc)/controller/)
obj/sfc-cartridge.o : $(sfc)/cartridge/cartridge.cpp $(sfc)/cartridge/*
obj/sfc-cheat.o : $(sfc)/cheat/cheat.cpp $(sfc)/cheat/*
obj/sfc-memory.o : $(sfc)/memory/memory.cpp $(call rwildcard,$(sfc)/memory/)
obj/sfc-cpu.o : $(sfccpu)/cpu.cpp $(call rwildcard,$(sfccpu)/)
obj/sfc-smp.o : $(sfcsmp)/smp.cpp $(call rwildcard,$(sfcsmp)/)
obj/sfc-dsp.o : $(sfcdsp)/dsp.cpp $(call rwildcard,$(sfcdsp)/)
obj/sfc-ppu.o : $(sfcppu)/ppu.cpp $(call rwildcard,$(sfcppu)/)
obj/sfc-cartridge.o : $(sfc)/cartridge/cartridge.cpp $(sfc)/cartridge/*
obj/sfc-cheat.o : $(sfc)/cheat/cheat.cpp $(sfc)/cheat/*
obj/sfc-icd2.o : $(sfc)/chip/icd2/icd2.cpp $(call rwildcard,$(sfc)/chip/icd2/)
obj/sfc-bsx.o : $(sfc)/chip/bsx/bsx.cpp $(call rwildcard,$(sfc)/chip/bsx/)
@ -52,8 +52,8 @@ obj/sfc-armdsp.o : $(sfc)/chip/armdsp/armdsp.cpp $(call rwildcard,$(sfc)/chi
obj/sfc-hitachidsp.o : $(sfc)/chip/hitachidsp/hitachidsp.cpp $(call rwildcard,$(sfc)/chip/hitachidsp/)
obj/sfc-necdsp.o : $(sfc)/chip/necdsp/necdsp.cpp $(call rwildcard,$(sfc)/chip/necdsp/)
obj/sfc-epsonrtc.o : $(sfc)/chip/epsonrtc/epsonrtc.cpp $(sfc)/chip/epsonrtc/*
obj/sfc-sharprtc.o : $(sfc)/chip/sharprtc/sharprtc.cpp $(sfc)/chip/sharprtc/*
obj/sfc-epsonrtc.o : $(sfc)/chip/epsonrtc/epsonrtc.cpp $(call rwildcard,$(sfc)/chip/epsonrtc/)
obj/sfc-sharprtc.o : $(sfc)/chip/sharprtc/sharprtc.cpp $(call rwildcard,$(sfc)/chip/sharprtc/)
obj/sfc-spc7110.o : $(sfc)/chip/spc7110/spc7110.cpp $(sfc)/chip/spc7110/*
obj/sfc-sdd1.o : $(sfc)/chip/sdd1/sdd1.cpp $(sfc)/chip/sdd1/*

View File

@ -18,18 +18,17 @@ void EpsonRTC::enter() {
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
}
if(wait) { if(--wait == 0) ready = true; }
if(wait) { if(--wait == 0) ready = 1; }
clocks++;
if((clocks & ~0x03fff) == 0) duty(); //1/128th second (frequency / 128 - 1)
if((clocks & ~0x07fff) == 0) irq(0); //1/ 64th second (frequency / 64 - 1)
if((clocks & ~0x3ffff) == 0) roundseconds = 0; //1/ 8th second (frequency / 8 - 1)
if((clocks & ~0x00ff) == 0) round_seconds(); //125 microseconds
if((clocks & ~0x3fff) == 0) duty(); //1/128th second
if((clocks & ~0x7fff) == 0) irq(0); //1/64th second
if(clocks == 0) { //1 second
seconds++;
irq(1);
if(seconds % 60 == 0) irq(2); //1 minute
if(seconds % 1440 == 0) irq(3); //1 hour
if(seconds == 1440) seconds = 0;
if(seconds % 1440 == 0) irq(3), seconds = 0; //1 hour
tick();
}
@ -42,7 +41,7 @@ void EpsonRTC::init() {
}
void EpsonRTC::load() {
if(cartridge.has_epsonrtc()) interface->memory.append({ID::EpsonRTC, "rtc.ram"});
interface->memory.append({ID::EpsonRTC, "rtc.ram"});
secondlo = 0;
secondhi = 0;
@ -100,15 +99,15 @@ void EpsonRTC::reset() {
state = State::Mode;
offset = 0;
wait = 0;
ready = false;
holdtick = false;
ready = 0;
holdtick = 0;
}
void EpsonRTC::sync() {
time_t systime = time(0);
tm *timeinfo = localtime(&systime);
unsigned second = min(59, timeinfo->tm_sec); //round down leap second
unsigned second = min(59, timeinfo->tm_sec);
secondlo = second % 10;
secondhi = second / 10;
@ -123,13 +122,9 @@ void EpsonRTC::sync() {
} else {
meridian = hour >= 12;
hour %= 12;
if(hour == 0) {
hourlo = 2;
hourhi = 1;
} else {
hourlo = hour % 10;
hourhi = hour / 10;
}
if(hour == 0) hour = 12;
hourlo = hour % 10;
hourhi = hour / 10;
}
unsigned day = timeinfo->tm_mday;
@ -146,7 +141,7 @@ void EpsonRTC::sync() {
weekday = timeinfo->tm_wday;
resync = true; //alert RTC that time has changed
resync = true; //alert program that time has changed
}
uint8 EpsonRTC::read(unsigned addr) {
@ -159,10 +154,10 @@ uint8 EpsonRTC::read(unsigned addr) {
if(addr == 1) {
if(chipselect != 1) return 0;
if(ready == false) return 0;
if(ready == 0) return 0;
if(state == State::Write) return mdr;
if(state != State::Read) return 0;
ready = false;
ready = 0;
wait = 8;
return rtc_read(offset++);
}
@ -179,17 +174,17 @@ void EpsonRTC::write(unsigned addr, uint8 data) {
if(addr == 0) {
chipselect = data;
if(chipselect != 1) rtc_reset();
ready = true;
ready = 1;
}
if(addr == 1) {
if(chipselect != 1) return;
if(ready == false) return;
if(ready == 0) return;
if(state == State::Mode) {
if(data != 0x03 && data != 0x0c) return;
state = State::Seek;
ready = false;
ready = 0;
wait = 8;
mdr = data;
}
@ -197,16 +192,15 @@ void EpsonRTC::write(unsigned addr, uint8 data) {
else if(state == State::Seek) {
if(mdr == 0x03) state = State::Write;
if(mdr == 0x0c) state = State::Read;
offset = data;
ready = false;
ready = 0;
wait = 8;
mdr = data;
}
else if(state == State::Write) {
rtc_write(offset++, data);
ready = false;
ready = 0;
wait = 8;
mdr = data;
}

View File

@ -24,7 +24,7 @@ struct EpsonRTC : Coprocessor {
uint4 mdr;
uint4 offset;
unsigned wait;
bool ready;
uint1 ready;
uint1 holdtick;
uint4 secondlo;
@ -77,7 +77,9 @@ struct EpsonRTC : Coprocessor {
//time.cpp
void irq(uint2 period);
void duty();
void round_seconds();
void tick();
void tick_second();
void tick_minute();
void tick_hour();

View File

@ -10,7 +10,7 @@ void EpsonRTC::rtc_reset() {
}
uint4 EpsonRTC::rtc_read(uint4 addr) {
switch(addr) {
switch(addr) { default:
case 0: return secondlo;
case 1: return secondhi | batteryfailure << 3;
case 2: return minutelo;
@ -85,19 +85,12 @@ void EpsonRTC::rtc_write(uint4 addr, uint4 data) {
bool held = hold;
hold = data;
calendar = data >> 1;
//irqflag cannot be set manually
roundseconds = data >> 3;
if(held == 1 && hold == 0 && holdtick) {
//if a second has passed during hold; increment one second upon resuming
holdtick = false;
if(held == 1 && hold == 0 && holdtick == 1) {
//if a second has passed during hold, increment one second upon resuming
holdtick = 0;
tick_second();
}
if(roundseconds) {
roundseconds = 0;
if(secondhi >= 3) tick_minute();
secondlo = 0;
secondhi = 0;
}
} break;
case 14:
irqmask = data;

View File

@ -1,8 +1,7 @@
#ifdef EPSONRTC_CPP
void EpsonRTC::irq(uint2 period) {
if(stop) return;
if(pause) return;
if(stop || pause) return;
if(period == irqperiod) irqflag = 1;
}
@ -11,20 +10,29 @@ void EpsonRTC::duty() {
if(irqduty) irqflag = 0;
}
void EpsonRTC::round_seconds() {
if(roundseconds == 0) return;
roundseconds = 0;
if(secondhi >= 3) tick_minute();
secondlo = 0;
secondhi = 0;
}
void EpsonRTC::tick() {
if(stop) return;
if(pause) return;
if(stop || pause) return;
if(hold) {
holdtick = true;
holdtick = 1;
return;
}
resync = true;
resync = 1;
tick_second();
}
//below code provides bit-perfect emulation of invalid BCD values on the RTC-4513
//code makes extensive use of variable-length integers (see epsonrtc.hpp for sizes)
void EpsonRTC::tick_second() {
if(secondlo <= 8 || secondlo == 12) {
@ -99,7 +107,7 @@ void EpsonRTC::tick_hour() {
}
void EpsonRTC::tick_day() {
if(calendar == false) return;
if(calendar == 0) return;
weekday = (weekday + 1) + (weekday == 6);
//January - December = 0x01 - 0x09; 0x10 - 0x12
@ -139,6 +147,12 @@ void EpsonRTC::tick_day() {
return tick_month();
}
if(days == 31 && (dayhi == 3 && (daylo & 3))) {
daylo = 1;
dayhi = 0;
return tick_month();
}
if(daylo <= 8 || daylo == 12) {
daylo++;
} else {

View File

@ -13,8 +13,8 @@ uint4 SharpRTC::rtc_read(uint4 addr) {
case 10: return year / 10 % 10;
case 11: return year / 100;
case 12: return weekday;
default: return 0;
}
return 0;
}
void SharpRTC::rtc_write(uint4 addr, uint4 data) {

View File

@ -1,7 +1,9 @@
#ifdef SHARPRTC_CPP
void SharpRTC::serialize(serializer &s) {
s.integer(rtc_mode);
Thread::serialize(s);
s.integer((unsigned&)rtc_state);
s.integer(rtc_index);
s.integer(second);

View File

@ -37,7 +37,6 @@ void SharpRTC::load() {
day = 0;
month = 0;
year = 0;
weekday = 0;
}
void SharpRTC::unload() {
@ -49,7 +48,7 @@ void SharpRTC::power() {
void SharpRTC::reset() {
create(SharpRTC::Enter, 1);
rtc_mode = RtcRead;
rtc_state = State::Read;
rtc_index = -1;
}
@ -57,7 +56,7 @@ void SharpRTC::sync() {
time_t systime = time(0);
tm *timeinfo = localtime(&systime);
second = min(59, timeinfo->tm_sec); //round leap second down
second = min(59, timeinfo->tm_sec);
minute = timeinfo->tm_min;
hour = timeinfo->tm_hour;
day = timeinfo->tm_mday;
@ -67,17 +66,17 @@ void SharpRTC::sync() {
}
uint8 SharpRTC::read(unsigned addr) {
addr &= 0xffff;
addr &= 1;
if(addr == 0x2800) {
if(rtc_mode != RtcRead) return 0x00;
if(addr == 0) {
if(rtc_state != State::Read) return 0;
if(rtc_index < 0) {
rtc_index++;
return 0x0f;
return 15;
} else if(rtc_index > 12) {
rtc_index = -1;
return 0x0f;
return 15;
} else {
return rtc_read(rtc_index++);
}
@ -87,41 +86,29 @@ uint8 SharpRTC::read(unsigned addr) {
}
void SharpRTC::write(unsigned addr, uint8 data) {
addr &= 0xffff;
if(addr == 0x2801) {
data &= 0x0f; //only the low four bits are used
addr &= 1, data &= 15;
if(addr == 1) {
if(data == 0x0d) {
rtc_mode = RtcRead;
rtc_state = State::Read;
rtc_index = -1;
return;
}
if(data == 0x0e) {
rtc_mode = RtcCommand;
rtc_state = State::Command;
return;
}
if(data == 0x0f) return; //unknown behavior
if(rtc_mode == RtcWrite) {
if(rtc_index >= 0 && rtc_index < 12) {
rtc_write(rtc_index++, data);
if(rtc_index == 12) {
//day of week is automatically calculated and written
weekday = calculate_weekday(1000 + year, month, day);
}
}
} else if(rtc_mode == RtcCommand) {
if(rtc_state == State::Command) {
if(data == 0) {
rtc_mode = RtcWrite;
rtc_state = State::Write;
rtc_index = 0;
} else if(data == 4) {
rtc_mode = RtcReady;
rtc_state = State::Ready;
rtc_index = -1;
//reset time
second = 0;
minute = 0;
@ -132,8 +119,20 @@ void SharpRTC::write(unsigned addr, uint8 data) {
weekday = 0;
} else {
//unknown behavior
rtc_mode = RtcReady;
rtc_state = State::Ready;
}
return;
}
if(rtc_state == State::Write) {
if(rtc_index >= 0 && rtc_index < 12) {
rtc_write(rtc_index++, data);
if(rtc_index == 12) {
//day of week is automatically calculated and written
weekday = calculate_weekday(1000 + year, month, day);
}
}
return;
}
}
}

View File

@ -14,8 +14,7 @@ struct SharpRTC : Coprocessor {
void serialize(serializer&);
enum RtcMode { RtcReady, RtcCommand, RtcRead, RtcWrite };
unsigned rtc_mode;
enum class State : unsigned { Ready, Command, Read, Write } rtc_state;
signed rtc_index;
unsigned second;

View File

@ -20,14 +20,20 @@ void SharpRTC::tick_hour() {
void SharpRTC::tick_day() {
unsigned days = daysinmonth[month % 12];
//add one day for leap years
if(year % 400 == 0) days++;
else if(year % 100 == 0);
else if(year % 4 == 0) days++;
if(day++ < days) return;
day = 0;
day = 1;
tick_month();
}
void SharpRTC::tick_month() {
if(month++ < 12) return;
month = 0;
month = 1;
tick_year();
}
@ -38,39 +44,38 @@ void SharpRTC::tick_year() {
//returns day of week for specified date
//eg 0 = Sunday, 1 = Monday, ... 6 = Saturday
//usage: weekday(2008, 1, 1) returns weekday of January 1st, 2008
//usage: calculate_weekday(2008, 1, 1) returns weekday of January 1st, 2008
unsigned SharpRTC::calculate_weekday(unsigned year, unsigned month, unsigned day) {
unsigned y = 1900, m = 1; //epoch is 1900-01-01
unsigned y = 1000, m = 1; //SharpRTC epoch is 1000-01-01
unsigned sum = 0; //number of days passed since epoch
year = max(1900, year);
year = max(1000, year);
month = max(1, min(12, month));
day = max(1, min(31, day));
while(y < year) {
bool leapyear = false;
if((y % 4) == 0) {
if(y % 4 == 0) {
leapyear = true;
if((y % 100) == 0 && (y % 400) != 0) leapyear = false;
if(y % 100 == 0 && y % 400 != 0) leapyear = false;
}
sum += leapyear ? 366 : 365;
sum += 365 + leapyear;
y++;
}
while(m < month) {
unsigned days = daysinmonth[m - 1];
bool leapyearmonth = false;
if(days == 28) {
bool leapyear = false;
if((y % 4) == 0) {
leapyear = true;
if((y % 100) == 0 && (y % 400) != 0) leapyear = false;
if(y % 4 == 0) {
leapyearmonth = true;
if(y % 100 == 0 && y % 400 != 0) leapyearmonth = false;
}
if(leapyear) days++;
}
sum += days;
sum += days + leapyearmonth;
m++;
}
sum += day - 1;
return (sum + 1) % 7; //1900-01-01 was a Monday
return (sum + 3) % 7; //1000-01-01 was a Wednesday
}

View File

@ -25,21 +25,18 @@ string Interface::sha256() {
unsigned Interface::group(unsigned id) {
switch(id) {
case ID::Nec7725DSP:
case ID::Nec96050DSP:
case ID::HitachiDSP:
case ID::ArmDSP:
case ID::ROM:
case ID::RAM:
case ID::ArmDSP:
case ID::HitachiDSP:
case ID::Nec7725DSP:
case ID::Nec96050DSP:
case ID::NecDSPRAM:
case ID::EpsonRTC:
case ID::SharpRTC:
case ID::BsxRAM:
case ID::BsxPSRAM:
return 0;
case ID::SuperGameBoyROM:
case ID::SuperGameBoyRAM:
case ID::SuperGameBoyRTC:
return 1;
case ID::BsxFlashROM:
return 2;
@ -58,6 +55,23 @@ void Interface::load(unsigned id, const stream &stream, const string &markup) {
stream.read(smp.iplrom, min(64u, stream.size()));
}
if(id == ID::ROM) {
cartridge.load(markup, stream);
system.power();
}
if(id == ID::RAM) {
stream.read(cartridge.ram.data(), min(cartridge.ram.size(), stream.size()));
}
if(id == ID::ArmDSP) {
stream.read(armdsp.firmware, stream.size());
}
if(id == ID::HitachiDSP) {
for(unsigned n = 0; n < 1024; n++) hitachidsp.dataROM[n] = stream.readl(3);
}
if(id == ID::Nec7725DSP) {
for(unsigned n = 0; n < 2048; n++) necdsp.programROM[n] = stream.readl(3);
for(unsigned n = 0; n < 1024; n++) necdsp.dataROM[n] = stream.readl(2);
@ -68,39 +82,6 @@ void Interface::load(unsigned id, const stream &stream, const string &markup) {
for(unsigned n = 0; n < 2048; n++) necdsp.dataROM[n] = stream.readl(2);
}
if(id == ID::HitachiDSP) {
for(unsigned n = 0; n < 1024; n++) hitachidsp.dataROM[n] = stream.readl(3);
}
if(id == ID::ArmDSP) {
stream.read(armdsp.firmware, stream.size());
}
if(id == ID::ROM) {
cartridge.load(markup, stream);
system.power();
}
if(id == ID::SuperGameBoyROM) {
GameBoy::cartridge.load(GameBoy::System::Revision::SuperGameBoy, markup, stream);
}
if(id == ID::BsxFlashROM) {
bsxflash.memory.copy(stream);
}
if(id == ID::SufamiTurboSlotAROM) {
sufamiturbo.slotA.rom.copy(stream);
}
if(id == ID::SufamiTurboSlotBROM) {
sufamiturbo.slotB.rom.copy(stream);
}
if(id == ID::RAM) {
stream.read(cartridge.ram.data(), min(cartridge.ram.size(), stream.size()));
}
if(id == ID::NecDSPRAM) {
for(unsigned n = 0; n < 2048; n++) necdsp.dataRAM[n] = stream.readl(2);
}
@ -117,6 +98,18 @@ void Interface::load(unsigned id, const stream &stream, const string &markup) {
sharprtc.load(data);
}
if(id == ID::SuperGameBoyROM) {
GameBoy::cartridge.load(GameBoy::System::Revision::SuperGameBoy, markup, stream);
}
if(id == ID::SuperGameBoyRAM) {
stream.read(GameBoy::cartridge.ramdata, GameBoy::cartridge.ramsize);
}
if(id == ID::BsxFlashROM) {
bsxflash.memory.copy(stream);
}
if(id == ID::BsxRAM) {
stream.read(bsxcartridge.sram.data(), min(stream.size(), bsxcartridge.sram.size()));
}
@ -125,8 +118,12 @@ void Interface::load(unsigned id, const stream &stream, const string &markup) {
stream.read(bsxcartridge.psram.data(), min(stream.size(), bsxcartridge.psram.size()));
}
if(id == ID::SuperGameBoyRAM) {
stream.read(GameBoy::cartridge.ramdata, GameBoy::cartridge.ramsize);
if(id == ID::SufamiTurboSlotAROM) {
sufamiturbo.slotA.rom.copy(stream);
}
if(id == ID::SufamiTurboSlotBROM) {
sufamiturbo.slotB.rom.copy(stream);
}
if(id == ID::SufamiTurboSlotARAM) {
@ -159,6 +156,10 @@ void Interface::save(unsigned id, const stream &stream) {
stream.write(data, sizeof data);
}
if(id == ID::SuperGameBoyRAM) {
stream.write(GameBoy::cartridge.ramdata, GameBoy::cartridge.ramsize);
}
if(id == ID::BsxRAM) {
stream.write(bsxcartridge.sram.data(), bsxcartridge.sram.size());
}
@ -167,9 +168,6 @@ void Interface::save(unsigned id, const stream &stream) {
stream.write(bsxcartridge.psram.data(), bsxcartridge.psram.size());
}
if(id == ID::SuperGameBoyRAM) {
stream.write(GameBoy::cartridge.ramdata, GameBoy::cartridge.ramsize);
}
if(id == ID::SufamiTurboSlotARAM) {
stream.write(sufamiturbo.slotA.ram.data(), sufamiturbo.slotA.ram.size());

View File

@ -5,23 +5,28 @@ namespace SuperFamicom {
struct ID {
enum : unsigned {
IPLROM,
ROM,
RAM,
ArmDSP,
HitachiDSP,
Nec7725DSP,
Nec96050DSP,
HitachiDSP,
ArmDSP,
ROM,
SuperGameBoyROM,
BsxFlashROM,
SufamiTurboSlotAROM,
SufamiTurboSlotBROM,
RAM,
NecDSPRAM,
EpsonRTC,
SharpRTC,
SuperGameBoyROM,
SuperGameBoyRAM,
BsxFlashROM,
BsxRAM,
BsxPSRAM,
SuperGameBoyRAM,
SuperGameBoyRTC,
SufamiTurboSlotAROM,
SufamiTurboSlotBROM,
SufamiTurboSlotARAM,
SufamiTurboSlotBRAM,
};

View File

@ -62,7 +62,7 @@ void System::runthreadtosave() {
}
void System::init() {
assert(interface != nullptr);
assert(interface != 0);
bsxsatellaview.init();
icd2.init();
@ -172,8 +172,8 @@ void System::power() {
if(cartridge.has_armdsp()) armdsp.power();
if(cartridge.has_hitachidsp()) hitachidsp.power();
if(cartridge.has_necdsp()) necdsp.power();
if(cartridge.has_sharprtc()) sharprtc.power();
if(cartridge.has_epsonrtc()) epsonrtc.power();
if(cartridge.has_sharprtc()) sharprtc.power();
if(cartridge.has_spc7110()) spc7110.power();
if(cartridge.has_sdd1()) sdd1.power();
if(cartridge.has_obc1()) obc1.power();

View File

@ -120,7 +120,7 @@ Presentation::Presentation() : active(nullptr) {
configurationSettings.onActivate = [&] { settings->setVisible(); settings->panelList.setFocused(); };
for(unsigned n = 0; n < 5; n++) saveStateItem[n].onActivate = [=] { utility->saveState(1 + n); };
for(unsigned n = 0; n < 5; n++) loadStateItem[n].onActivate = [=] { utility->loadState(1 + n); };
synchronizeTime.onActivate = [&] { if(application->active) system().rtcsync(); };
synchronizeTime.onActivate = [&] { system().rtcsync(); };
resizeWindow.onActivate = [&] { utility->resize(true); };
cheatEditor.onActivate = [&] { ::cheatEditor->setVisible(); };
stateManager.onActivate = [&] { ::stateManager->setVisible(); };