bsnes/higan/sfc/memory/memory-inline.hpp
Tim Allen 4b29f4bad7 Update to v097r15 release.
byuu says:

Changelog:
- higan now uses Natural<Size>/Integer<Size> for its internal types
- Super Famicom emulation now uses uint24 instead of uint for bus
  addresses (it's a 24-bit bus)
- cleaned up gb/apu MMIO writes
- cleaned up sfc/coprocessor/msu1 MMIO writes
- ~3% speed penalty

I've wanted to do that 24-bit bus thing for so long, but have always
been afraid of the speed impact. It's probably going to hurt
balanced/performance once they compile again, but it wasn't significant
enough to harm the accuracy core's frame rate, thankfully. Only lost one
frame per second.

The GBA core handlers are clearly going to take a lot more work. The
bit-ranges will make it substantially easier to handle, though. Lots of
32-bit registers where certain values span multiple bytes, but we have
to be able to read/write at byte-granularity.
2016-02-16 20:32:49 +11:00

93 lines
2.5 KiB
C++

//Memory
auto Memory::size() const -> uint { return 0; }
//StaticRAM
StaticRAM::StaticRAM(uint n) : size_(n) { data_ = new uint8[size_]; }
StaticRAM::~StaticRAM() { delete[] data_; }
auto StaticRAM::data() -> uint8* { return data_; }
auto StaticRAM::size() const -> uint { return size_; }
auto StaticRAM::read(uint24 addr, uint8) -> uint8 { return data_[addr]; }
auto StaticRAM::write(uint24 addr, uint8 data) -> void { data_[addr] = data; }
auto StaticRAM::operator[](uint24 addr) -> uint8& { return data_[addr]; }
auto StaticRAM::operator[](uint24 addr) const -> const uint8& { return data_[addr]; }
//MappedRAM
auto MappedRAM::reset() -> void {
if(data_) {
delete[] data_;
data_ = nullptr;
}
size_ = 0;
write_protect_ = false;
}
auto MappedRAM::map(uint8* source, uint length) -> void {
reset();
data_ = source;
size_ = data_ ? length : 0;
}
auto MappedRAM::copy(const stream& memory) -> void {
if(data_) delete[] data_;
//round size up to multiple of 256-bytes
size_ = (memory.size() & ~255) + ((bool)(memory.size() & 255) << 8);
data_ = new uint8[size_]();
memory.read((uint8_t*)data_, memory.size());
}
auto MappedRAM::read(const stream& memory) -> void {
memory.read((uint8_t*)data_, min(memory.size(), size_));
}
auto MappedRAM::write_protect(bool status) -> void { write_protect_ = status; }
auto MappedRAM::data() -> uint8* { return data_; }
auto MappedRAM::size() const -> uint { return size_; }
auto MappedRAM::read(uint24 addr, uint8) -> uint8 { return data_[addr]; }
auto MappedRAM::write(uint24 addr, uint8 data) -> void { if(!write_protect_) data_[addr] = data; }
auto MappedRAM::operator[](uint24 addr) const -> const uint8& { return data_[addr]; }
//Bus
auto Bus::mirror(uint addr, uint size) -> uint {
if(size == 0) return 0;
uint base = 0;
uint mask = 1 << 23;
while(addr >= size) {
while(!(addr & mask)) mask >>= 1;
addr -= mask;
if(size > mask) {
size -= mask;
base += mask;
}
mask >>= 1;
}
return base + addr;
}
auto Bus::reduce(uint addr, uint mask) -> uint {
while(mask) {
uint bits = (mask & -mask) - 1;
addr = ((addr >> 1) & ~bits) | (addr & bits);
mask = (mask & (mask - 1)) >> 1;
}
return addr;
}
auto Bus::read(uint24 addr, uint8 data) -> uint8 {
data = reader[lookup[addr]](target[addr], data);
if(cheat.enable()) {
if(auto result = cheat.find(addr, data)) return result();
}
return data;
}
auto Bus::write(uint24 addr, uint8 data) -> void {
return writer[lookup[addr]](target[addr], data);
}