mirror of https://github.com/bsnes-emu/bsnes.git
Update to v087r27 release.
byuu says: Changelog: - serialize processor.pc.data, not processor.pc - call CPU processor.setMode() in ARM serialize - serialize BIOS.mdr - support SRAM > 32KB - EEPROM, FlashROM serialize - EEPROM lose nall/bitarray.hpp - noise line feed after envelope - space out PSR read - ST018 needs byte reads fixed (don't align) [fixes HNMS2] - flush sram/eeprom/flashrom to 0 on cartridge load - APU/PPU dont sync back to CPU if syncing for state - fixed APU sync problems in GB/GBC core that could possibly wreck save states as well Quite a lot of little problems there. I believe GBA save states are fixed now.
This commit is contained in:
parent
0cd0dcd811
commit
d2241f1931
|
@ -1,7 +1,7 @@
|
||||||
#ifndef BASE_HPP
|
#ifndef BASE_HPP
|
||||||
#define BASE_HPP
|
#define BASE_HPP
|
||||||
|
|
||||||
static const char Version[] = "087.26";
|
static const char Version[] = "087.27";
|
||||||
|
|
||||||
#include <nall/platform.hpp>
|
#include <nall/platform.hpp>
|
||||||
#include <nall/algorithm.hpp>
|
#include <nall/algorithm.hpp>
|
||||||
|
|
|
@ -49,7 +49,7 @@ void APU::main() {
|
||||||
interface->audioSample(master.center, master.left, master.right);
|
interface->audioSample(master.center, master.left, master.right);
|
||||||
|
|
||||||
clock += 1 * cpu.frequency;
|
clock += 1 * cpu.frequency;
|
||||||
if(clock >= 0) co_switch(scheduler.active_thread = cpu.thread);
|
if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(scheduler.active_thread = cpu.thread);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,15 @@ void System::runtosave() {
|
||||||
scheduler.sync = Scheduler::SynchronizeMode::CPU;
|
scheduler.sync = Scheduler::SynchronizeMode::CPU;
|
||||||
runthreadtosave();
|
runthreadtosave();
|
||||||
|
|
||||||
|
scheduler.sync = Scheduler::SynchronizeMode::All;
|
||||||
scheduler.active_thread = lcd.thread;
|
scheduler.active_thread = lcd.thread;
|
||||||
runthreadtosave();
|
runthreadtosave();
|
||||||
|
|
||||||
|
scheduler.sync = Scheduler::SynchronizeMode::All;
|
||||||
|
scheduler.active_thread = apu.thread;
|
||||||
|
runthreadtosave();
|
||||||
|
|
||||||
|
scheduler.sync = Scheduler::SynchronizeMode::None;
|
||||||
}
|
}
|
||||||
|
|
||||||
void System::runthreadtosave() {
|
void System::runthreadtosave() {
|
||||||
|
|
|
@ -76,7 +76,7 @@ void APU::main() {
|
||||||
|
|
||||||
void APU::step(unsigned clocks) {
|
void APU::step(unsigned clocks) {
|
||||||
clock += clocks;
|
clock += clocks;
|
||||||
if(clock >= 0) co_switch(cpu.thread);
|
if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
void APU::power() {
|
void APU::power() {
|
||||||
|
|
|
@ -68,6 +68,7 @@ void APU::serialize(serializer &s) {
|
||||||
s.integer(noise.envelope.direction);
|
s.integer(noise.envelope.direction);
|
||||||
s.integer(noise.envelope.volume);
|
s.integer(noise.envelope.volume);
|
||||||
s.integer(noise.envelope.period);
|
s.integer(noise.envelope.period);
|
||||||
|
|
||||||
s.integer(noise.length);
|
s.integer(noise.length);
|
||||||
s.integer(noise.divisor);
|
s.integer(noise.divisor);
|
||||||
s.integer(noise.narrowlfsr);
|
s.integer(noise.narrowlfsr);
|
||||||
|
|
|
@ -23,7 +23,9 @@ bool Cartridge::load(const string &markup, const uint8_t *data, unsigned size) {
|
||||||
|
|
||||||
if(info["type"].data == "SRAM" || info["type"].data == "FRAM") {
|
if(info["type"].data == "SRAM" || info["type"].data == "FRAM") {
|
||||||
has_sram = true;
|
has_sram = true;
|
||||||
ram.size = 32 * 1024;
|
ram.size = numeral(info["size"].data);
|
||||||
|
ram.mask = ram.size - 1;
|
||||||
|
for(unsigned n = 0; n < ram.size; n++) ram.data[n] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(info["type"].data == "EEPROM") {
|
if(info["type"].data == "EEPROM") {
|
||||||
|
@ -31,12 +33,14 @@ bool Cartridge::load(const string &markup, const uint8_t *data, unsigned size) {
|
||||||
eeprom.size = numeral(info["size"].data);
|
eeprom.size = numeral(info["size"].data);
|
||||||
eeprom.mask = size > 16 * 1024 * 1024 ? 0x0fffff00 : 0x0f000000;
|
eeprom.mask = size > 16 * 1024 * 1024 ? 0x0fffff00 : 0x0f000000;
|
||||||
eeprom.test = size > 16 * 1024 * 1024 ? 0x0dffff00 : 0x0d000000;
|
eeprom.test = size > 16 * 1024 * 1024 ? 0x0dffff00 : 0x0d000000;
|
||||||
|
for(unsigned n = 0; n < eeprom.size; n++) eeprom.data[n] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(info["type"].data == "FlashROM") {
|
if(info["type"].data == "FlashROM") {
|
||||||
has_flashrom = true;
|
has_flashrom = true;
|
||||||
flashrom.id = numeral(info["id"].data);
|
flashrom.id = numeral(info["id"].data);
|
||||||
flashrom.size = numeral(info["size"].data);
|
flashrom.size = numeral(info["size"].data);
|
||||||
|
for(unsigned n = 0; n < flashrom.size; n++) flashrom.data[n] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +62,7 @@ void Cartridge::power() {
|
||||||
|
|
||||||
uint8* Cartridge::ram_data() {
|
uint8* Cartridge::ram_data() {
|
||||||
if(has_sram) return ram.data;
|
if(has_sram) return ram.data;
|
||||||
if(has_eeprom) return eeprom.data.data();
|
if(has_eeprom) return eeprom.data;
|
||||||
if(has_flashrom) return flashrom.data;
|
if(has_flashrom) return flashrom.data;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -92,7 +96,7 @@ void Cartridge::write(uint8 *data, uint32 addr, uint32 size, uint32 word) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 Cartridge::read(uint32 addr, uint32 size) {
|
uint32 Cartridge::read(uint32 addr, uint32 size) {
|
||||||
if(has_sram && (addr & 0x0e000000 ) == 0x0e000000 ) return read(ram.data, addr & 0x7fff, size);
|
if(has_sram && (addr & 0x0e000000 ) == 0x0e000000 ) return read(ram.data, addr & ram.mask, size);
|
||||||
if(has_eeprom && (addr & eeprom.mask) == eeprom.test) return eeprom.read();
|
if(has_eeprom && (addr & eeprom.mask) == eeprom.test) return eeprom.read();
|
||||||
if(has_flashrom && (addr & 0x0f000000 ) == 0x0e000000 ) return flashrom.read(addr);
|
if(has_flashrom && (addr & 0x0f000000 ) == 0x0e000000 ) return flashrom.read(addr);
|
||||||
if(addr < 0x0e000000) return read(rom.data, addr & 0x01ffffff, size);
|
if(addr < 0x0e000000) return read(rom.data, addr & 0x01ffffff, size);
|
||||||
|
@ -100,7 +104,7 @@ uint32 Cartridge::read(uint32 addr, uint32 size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cartridge::write(uint32 addr, uint32 size, uint32 word) {
|
void Cartridge::write(uint32 addr, uint32 size, uint32 word) {
|
||||||
if(has_sram && (addr & 0x0e000000 ) == 0x0e000000 ) return write(ram.data, addr & 0x7fff, size, word);
|
if(has_sram && (addr & 0x0e000000 ) == 0x0e000000 ) return write(ram.data, addr & ram.mask, size, word);
|
||||||
if(has_eeprom && (addr & eeprom.mask) == eeprom.test) return eeprom.write(word & 1);
|
if(has_eeprom && (addr & eeprom.mask) == eeprom.test) return eeprom.write(word & 1);
|
||||||
if(has_flashrom && (addr & 0x0f000000 ) == 0x0e000000 ) return flashrom.write(addr, word);
|
if(has_flashrom && (addr & 0x0f000000 ) == 0x0e000000 ) return flashrom.write(addr, word);
|
||||||
}
|
}
|
||||||
|
@ -109,6 +113,7 @@ Cartridge::Cartridge() {
|
||||||
loaded = false;
|
loaded = false;
|
||||||
rom.data = new uint8[rom.size = 32 * 1024 * 1024];
|
rom.data = new uint8[rom.size = 32 * 1024 * 1024];
|
||||||
ram.data = new uint8[ram.size = 32 * 1024];
|
ram.data = new uint8[ram.size = 32 * 1024];
|
||||||
|
eeprom.data = new uint8[eeprom.size = 8 * 1024];
|
||||||
flashrom.data = new uint8[flashrom.size = 128 * 1024];
|
flashrom.data = new uint8[flashrom.size = 128 * 1024];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,17 @@
|
||||||
|
bool Cartridge::EEPROM::read(unsigned addr) {
|
||||||
|
return data[addr >> 3] & 0x80 >> (addr & 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cartridge::EEPROM::write(unsigned addr, bool bit) {
|
||||||
|
if(bit == 0) data[addr >> 3] &=~ (0x80 >> (addr & 7));
|
||||||
|
if(bit == 1) data[addr >> 3] |= (0x80 >> (addr & 7));
|
||||||
|
}
|
||||||
|
|
||||||
bool Cartridge::EEPROM::read() {
|
bool Cartridge::EEPROM::read() {
|
||||||
bool bit = 1;
|
bool bit = 1;
|
||||||
|
|
||||||
if(mode == Mode::ReadData) {
|
if(mode == Mode::ReadData) {
|
||||||
if(offset >= 4) bit = data[address * 64 + (offset - 4)];
|
if(offset >= 4) bit = read(address * 64 + (offset - 4));
|
||||||
if(++offset == 68) mode = Mode::Wait;
|
if(++offset == 68) mode = Mode::Wait;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +52,7 @@ void Cartridge::EEPROM::write(bool bit) {
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(mode == Mode::WriteData) {
|
else if(mode == Mode::WriteData) {
|
||||||
data[address * 64 + offset] = bit;
|
write(address * 64 + offset, bit);
|
||||||
if(++offset == 64) {
|
if(++offset == 64) {
|
||||||
mode = Mode::WriteValidate;
|
mode = Mode::WriteValidate;
|
||||||
}
|
}
|
||||||
|
@ -56,10 +65,20 @@ void Cartridge::EEPROM::write(bool bit) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cartridge::EEPROM::power() {
|
void Cartridge::EEPROM::power() {
|
||||||
data.resize(size);
|
|
||||||
bits = (size <= 512 ? 6 : 14);
|
bits = (size <= 512 ? 6 : 14);
|
||||||
|
|
||||||
mode = Mode::Wait;
|
mode = Mode::Wait;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
address = 0;
|
address = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Cartridge::EEPROM::serialize(serializer &s) {
|
||||||
|
s.array(data, size);
|
||||||
|
s.integer(size);
|
||||||
|
s.integer(mask);
|
||||||
|
s.integer(test);
|
||||||
|
s.integer(bits);
|
||||||
|
s.integer((unsigned&)mode);
|
||||||
|
s.integer(offset);
|
||||||
|
s.integer(address);
|
||||||
|
}
|
||||||
|
|
|
@ -88,3 +88,16 @@ void Cartridge::FlashROM::power() {
|
||||||
writeselect = false;
|
writeselect = false;
|
||||||
bank = 0;
|
bank = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Cartridge::FlashROM::serialize(serializer &s) {
|
||||||
|
s.array(data, size);
|
||||||
|
s.integer(size);
|
||||||
|
s.integer(id);
|
||||||
|
s.integer(unlockhi);
|
||||||
|
s.integer(unlocklo);
|
||||||
|
s.integer(idmode);
|
||||||
|
s.integer(erasemode);
|
||||||
|
s.integer(bankselect);
|
||||||
|
s.integer(writeselect);
|
||||||
|
s.integer(bank);
|
||||||
|
}
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
struct Memory {
|
struct Memory {
|
||||||
uint8 *data;
|
uint8 *data;
|
||||||
unsigned size;
|
unsigned size;
|
||||||
|
unsigned mask;
|
||||||
} rom, ram;
|
} rom, ram;
|
||||||
|
|
||||||
struct EEPROM {
|
struct EEPROM {
|
||||||
bitarray data;
|
uint8 *data;
|
||||||
unsigned size;
|
unsigned size;
|
||||||
unsigned mask;
|
unsigned mask;
|
||||||
unsigned test;
|
unsigned test;
|
||||||
|
@ -14,9 +15,13 @@ struct EEPROM {
|
||||||
unsigned offset;
|
unsigned offset;
|
||||||
unsigned address;
|
unsigned address;
|
||||||
|
|
||||||
|
bool read(unsigned addr);
|
||||||
|
void write(unsigned addr, bool bit);
|
||||||
|
|
||||||
bool read();
|
bool read();
|
||||||
void write(bool bit);
|
void write(bool bit);
|
||||||
void power();
|
void power();
|
||||||
|
void serialize(serializer&);
|
||||||
} eeprom;
|
} eeprom;
|
||||||
|
|
||||||
struct FlashROM {
|
struct FlashROM {
|
||||||
|
@ -35,4 +40,5 @@ struct FlashROM {
|
||||||
uint8 read(uint16 addr);
|
uint8 read(uint16 addr);
|
||||||
void write(uint16 addr, uint8 byte);
|
void write(uint16 addr, uint8 byte);
|
||||||
void power();
|
void power();
|
||||||
|
void serialize(serializer&);
|
||||||
} flashrom;
|
} flashrom;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
void Cartridge::serialize(serializer &s) {
|
void Cartridge::serialize(serializer &s) {
|
||||||
if(has_sram) s.array(ram.data, ram.size);
|
if(has_sram) s.array(ram.data, ram.size);
|
||||||
if(has_eeprom) s.array(eeprom.data.data(), eeprom.size);
|
if(has_eeprom) eeprom.serialize(s);
|
||||||
if(has_flashrom) s.array(flashrom.data, flashrom.size);
|
if(has_flashrom) flashrom.serialize(s);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ void PPU::main() {
|
||||||
|
|
||||||
void PPU::step(unsigned clocks) {
|
void PPU::step(unsigned clocks) {
|
||||||
clock += clocks;
|
clock += clocks;
|
||||||
if(clock >= 0) co_switch(cpu.thread);
|
if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPU::power() {
|
void PPU::power() {
|
||||||
|
|
|
@ -33,6 +33,8 @@ bool System::unserialize(serializer &s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void System::serialize(serializer &s) {
|
void System::serialize(serializer &s) {
|
||||||
|
s.integer(bios.size);
|
||||||
|
s.integer(bios.mdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void System::serialize_all(serializer &s) {
|
void System::serialize_all(serializer &s) {
|
||||||
|
|
|
@ -30,7 +30,7 @@ struct PSR {
|
||||||
|
|
||||||
inline operator uint32() const {
|
inline operator uint32() const {
|
||||||
return (n << 31) + (z << 30) + (c << 29) + (v << 28)
|
return (n << 31) + (z << 30) + (c << 29) + (v << 28)
|
||||||
+ (i << 7) + (f << 6) + (t << 5) + (m << 0);
|
+ (i << 7) + (f << 6) + (t << 5) + (m << 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline PSR& operator=(uint32 d) {
|
inline PSR& operator=(uint32 d) {
|
||||||
|
|
|
@ -52,7 +52,7 @@ void ARM::serialize(serializer &s) {
|
||||||
s.integer(processor.und.lr.data);
|
s.integer(processor.und.lr.data);
|
||||||
processor.und.spsr.serialize(s);
|
processor.und.spsr.serialize(s);
|
||||||
|
|
||||||
s.integer(processor.pc);
|
s.integer(processor.pc.data);
|
||||||
processor.cpsr.serialize(s);
|
processor.cpsr.serialize(s);
|
||||||
s.integer(processor.carryout);
|
s.integer(processor.carryout);
|
||||||
s.integer(processor.sequential);
|
s.integer(processor.sequential);
|
||||||
|
@ -67,4 +67,6 @@ void ARM::serialize(serializer &s) {
|
||||||
s.integer(pipeline.fetch.instruction);
|
s.integer(pipeline.fetch.instruction);
|
||||||
|
|
||||||
s.integer(crash);
|
s.integer(crash);
|
||||||
|
|
||||||
|
processor.setMode((Processor::Mode)cpsr().m);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,9 +7,14 @@ void ArmDSP::bus_idle(uint32 addr) {
|
||||||
uint32 ArmDSP::bus_read(uint32 addr, uint32 size) {
|
uint32 ArmDSP::bus_read(uint32 addr, uint32 size) {
|
||||||
step(1);
|
step(1);
|
||||||
|
|
||||||
static auto memory = [&](const uint8 *memory, uint32 addr, uint32 size) {
|
static auto memory = [&](const uint8 *memory, uint32 addr, uint32 size) -> uint32 {
|
||||||
memory += addr & ~3;
|
switch(size) {
|
||||||
return memory[0] << 0 | memory[1] << 8 | memory[2] << 16 | memory[3] << 24;
|
case Word:
|
||||||
|
memory += addr & ~3;
|
||||||
|
return memory[0] << 0 | memory[1] << 8 | memory[2] << 16 | memory[3] << 24;
|
||||||
|
case Byte:
|
||||||
|
return memory[addr];
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
switch(addr & 0xe0000000) {
|
switch(addr & 0xe0000000) {
|
||||||
|
|
Loading…
Reference in New Issue