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:
Tim Allen 2012-04-17 22:16:54 +10:00
parent 0cd0dcd811
commit d2241f1931
15 changed files with 79 additions and 19 deletions

View File

@ -1,7 +1,7 @@
#ifndef BASE_HPP
#define BASE_HPP
static const char Version[] = "087.26";
static const char Version[] = "087.27";
#include <nall/platform.hpp>
#include <nall/algorithm.hpp>

View File

@ -49,7 +49,7 @@ void APU::main() {
interface->audioSample(master.center, master.left, master.right);
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);
}
}

View File

@ -21,8 +21,15 @@ void System::runtosave() {
scheduler.sync = Scheduler::SynchronizeMode::CPU;
runthreadtosave();
scheduler.sync = Scheduler::SynchronizeMode::All;
scheduler.active_thread = lcd.thread;
runthreadtosave();
scheduler.sync = Scheduler::SynchronizeMode::All;
scheduler.active_thread = apu.thread;
runthreadtosave();
scheduler.sync = Scheduler::SynchronizeMode::None;
}
void System::runthreadtosave() {

View File

@ -76,7 +76,7 @@ void APU::main() {
void APU::step(unsigned 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() {

View File

@ -68,6 +68,7 @@ void APU::serialize(serializer &s) {
s.integer(noise.envelope.direction);
s.integer(noise.envelope.volume);
s.integer(noise.envelope.period);
s.integer(noise.length);
s.integer(noise.divisor);
s.integer(noise.narrowlfsr);

View File

@ -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") {
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") {
@ -31,12 +33,14 @@ bool Cartridge::load(const string &markup, const uint8_t *data, unsigned size) {
eeprom.size = numeral(info["size"].data);
eeprom.mask = size > 16 * 1024 * 1024 ? 0x0fffff00 : 0x0f000000;
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") {
has_flashrom = true;
flashrom.id = numeral(info["id"].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() {
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;
return nullptr;
}
@ -92,7 +96,7 @@ void Cartridge::write(uint8 *data, uint32 addr, uint32 size, uint32 word) {
}
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_flashrom && (addr & 0x0f000000 ) == 0x0e000000 ) return flashrom.read(addr);
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) {
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_flashrom && (addr & 0x0f000000 ) == 0x0e000000 ) return flashrom.write(addr, word);
}
@ -109,6 +113,7 @@ Cartridge::Cartridge() {
loaded = false;
rom.data = new uint8[rom.size = 32 * 1024 * 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];
}

View File

@ -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 bit = 1;
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;
}
@ -43,7 +52,7 @@ void Cartridge::EEPROM::write(bool bit) {
}
else if(mode == Mode::WriteData) {
data[address * 64 + offset] = bit;
write(address * 64 + offset, bit);
if(++offset == 64) {
mode = Mode::WriteValidate;
}
@ -56,10 +65,20 @@ void Cartridge::EEPROM::write(bool bit) {
}
void Cartridge::EEPROM::power() {
data.resize(size);
bits = (size <= 512 ? 6 : 14);
mode = Mode::Wait;
offset = 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);
}

View File

@ -88,3 +88,16 @@ void Cartridge::FlashROM::power() {
writeselect = false;
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);
}

View File

@ -1,10 +1,11 @@
struct Memory {
uint8 *data;
unsigned size;
unsigned mask;
} rom, ram;
struct EEPROM {
bitarray data;
uint8 *data;
unsigned size;
unsigned mask;
unsigned test;
@ -14,9 +15,13 @@ struct EEPROM {
unsigned offset;
unsigned address;
bool read(unsigned addr);
void write(unsigned addr, bool bit);
bool read();
void write(bool bit);
void power();
void serialize(serializer&);
} eeprom;
struct FlashROM {
@ -35,4 +40,5 @@ struct FlashROM {
uint8 read(uint16 addr);
void write(uint16 addr, uint8 byte);
void power();
void serialize(serializer&);
} flashrom;

View File

@ -1,5 +1,5 @@
void Cartridge::serialize(serializer &s) {
if(has_sram) s.array(ram.data, ram.size);
if(has_eeprom) s.array(eeprom.data.data(), eeprom.size);
if(has_flashrom) s.array(flashrom.data, flashrom.size);
if(has_eeprom) eeprom.serialize(s);
if(has_flashrom) flashrom.serialize(s);
}

View File

@ -37,7 +37,7 @@ void PPU::main() {
void PPU::step(unsigned 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() {

View File

@ -33,6 +33,8 @@ bool System::unserialize(serializer &s) {
}
void System::serialize(serializer &s) {
s.integer(bios.size);
s.integer(bios.mdr);
}
void System::serialize_all(serializer &s) {

View File

@ -30,7 +30,7 @@ struct PSR {
inline operator uint32() const {
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) {

View File

@ -52,7 +52,7 @@ void ARM::serialize(serializer &s) {
s.integer(processor.und.lr.data);
processor.und.spsr.serialize(s);
s.integer(processor.pc);
s.integer(processor.pc.data);
processor.cpsr.serialize(s);
s.integer(processor.carryout);
s.integer(processor.sequential);
@ -67,4 +67,6 @@ void ARM::serialize(serializer &s) {
s.integer(pipeline.fetch.instruction);
s.integer(crash);
processor.setMode((Processor::Mode)cpsr().m);
}

View File

@ -7,9 +7,14 @@ void ArmDSP::bus_idle(uint32 addr) {
uint32 ArmDSP::bus_read(uint32 addr, uint32 size) {
step(1);
static auto memory = [&](const uint8 *memory, uint32 addr, uint32 size) {
memory += addr & ~3;
return memory[0] << 0 | memory[1] << 8 | memory[2] << 16 | memory[3] << 24;
static auto memory = [&](const uint8 *memory, uint32 addr, uint32 size) -> uint32 {
switch(size) {
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) {