From d2241f193157652ae8126265a2aa31145b3c4afc Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Tue, 17 Apr 2012 22:16:54 +1000 Subject: [PATCH] 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. --- bsnes/base/base.hpp | 2 +- bsnes/gb/apu/apu.cpp | 2 +- bsnes/gb/system/system.cpp | 7 +++++++ bsnes/gba/apu/apu.cpp | 2 +- bsnes/gba/apu/serialization.cpp | 1 + bsnes/gba/cartridge/cartridge.cpp | 13 +++++++++---- bsnes/gba/cartridge/eeprom.cpp | 25 ++++++++++++++++++++++--- bsnes/gba/cartridge/flashrom.cpp | 13 +++++++++++++ bsnes/gba/cartridge/memory.hpp | 8 +++++++- bsnes/gba/cartridge/serialization.cpp | 4 ++-- bsnes/gba/ppu/ppu.cpp | 2 +- bsnes/gba/system/serialization.cpp | 2 ++ bsnes/processor/arm/registers.hpp | 2 +- bsnes/processor/arm/serialization.cpp | 4 +++- bsnes/snes/chip/armdsp/memory.cpp | 11 ++++++++--- 15 files changed, 79 insertions(+), 19 deletions(-) diff --git a/bsnes/base/base.hpp b/bsnes/base/base.hpp index 6286f9c7..a91c400f 100755 --- a/bsnes/base/base.hpp +++ b/bsnes/base/base.hpp @@ -1,7 +1,7 @@ #ifndef BASE_HPP #define BASE_HPP -static const char Version[] = "087.26"; +static const char Version[] = "087.27"; #include #include diff --git a/bsnes/gb/apu/apu.cpp b/bsnes/gb/apu/apu.cpp index d235657b..e3c80ba8 100755 --- a/bsnes/gb/apu/apu.cpp +++ b/bsnes/gb/apu/apu.cpp @@ -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); } } diff --git a/bsnes/gb/system/system.cpp b/bsnes/gb/system/system.cpp index e324608b..f1231a4b 100755 --- a/bsnes/gb/system/system.cpp +++ b/bsnes/gb/system/system.cpp @@ -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() { diff --git a/bsnes/gba/apu/apu.cpp b/bsnes/gba/apu/apu.cpp index 54ed33b3..6a46d747 100755 --- a/bsnes/gba/apu/apu.cpp +++ b/bsnes/gba/apu/apu.cpp @@ -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() { diff --git a/bsnes/gba/apu/serialization.cpp b/bsnes/gba/apu/serialization.cpp index b2b277a4..129416db 100755 --- a/bsnes/gba/apu/serialization.cpp +++ b/bsnes/gba/apu/serialization.cpp @@ -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); diff --git a/bsnes/gba/cartridge/cartridge.cpp b/bsnes/gba/cartridge/cartridge.cpp index 8c20a534..4fa60d04 100755 --- a/bsnes/gba/cartridge/cartridge.cpp +++ b/bsnes/gba/cartridge/cartridge.cpp @@ -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]; } diff --git a/bsnes/gba/cartridge/eeprom.cpp b/bsnes/gba/cartridge/eeprom.cpp index 33ffadec..898029d8 100755 --- a/bsnes/gba/cartridge/eeprom.cpp +++ b/bsnes/gba/cartridge/eeprom.cpp @@ -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); +} diff --git a/bsnes/gba/cartridge/flashrom.cpp b/bsnes/gba/cartridge/flashrom.cpp index cbb3408f..84b7d7e8 100755 --- a/bsnes/gba/cartridge/flashrom.cpp +++ b/bsnes/gba/cartridge/flashrom.cpp @@ -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); +} diff --git a/bsnes/gba/cartridge/memory.hpp b/bsnes/gba/cartridge/memory.hpp index 3af3f33c..47ded28d 100755 --- a/bsnes/gba/cartridge/memory.hpp +++ b/bsnes/gba/cartridge/memory.hpp @@ -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; diff --git a/bsnes/gba/cartridge/serialization.cpp b/bsnes/gba/cartridge/serialization.cpp index e1d8106c..3d606c61 100755 --- a/bsnes/gba/cartridge/serialization.cpp +++ b/bsnes/gba/cartridge/serialization.cpp @@ -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); } diff --git a/bsnes/gba/ppu/ppu.cpp b/bsnes/gba/ppu/ppu.cpp index dd713d7e..3ddb44ce 100755 --- a/bsnes/gba/ppu/ppu.cpp +++ b/bsnes/gba/ppu/ppu.cpp @@ -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() { diff --git a/bsnes/gba/system/serialization.cpp b/bsnes/gba/system/serialization.cpp index 14d2bb16..cd5f21bf 100755 --- a/bsnes/gba/system/serialization.cpp +++ b/bsnes/gba/system/serialization.cpp @@ -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) { diff --git a/bsnes/processor/arm/registers.hpp b/bsnes/processor/arm/registers.hpp index 1d83d241..ec993fd3 100755 --- a/bsnes/processor/arm/registers.hpp +++ b/bsnes/processor/arm/registers.hpp @@ -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) { diff --git a/bsnes/processor/arm/serialization.cpp b/bsnes/processor/arm/serialization.cpp index 774f8032..269b3d15 100755 --- a/bsnes/processor/arm/serialization.cpp +++ b/bsnes/processor/arm/serialization.cpp @@ -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); } diff --git a/bsnes/snes/chip/armdsp/memory.cpp b/bsnes/snes/chip/armdsp/memory.cpp index a14d55da..5d1ccb7c 100755 --- a/bsnes/snes/chip/armdsp/memory.cpp +++ b/bsnes/snes/chip/armdsp/memory.cpp @@ -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) {