mirror of
https://github.com/devinacker/bsnes-plus.git
synced 2025-04-02 10:52:46 -04:00
126 lines
3.3 KiB
C++
126 lines
3.3 KiB
C++
//Memory
|
|
|
|
unsigned Memory::size() const { return 0; }
|
|
|
|
bool Memory::debugger_access() {
|
|
#if defined(DEBUGGER)
|
|
return debugger.bus_access;
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
//StaticRAM
|
|
|
|
uint8* StaticRAM::data() { return data_; }
|
|
unsigned StaticRAM::size() const { return size_; }
|
|
|
|
uint8 StaticRAM::read(unsigned addr) { return data_[addr]; }
|
|
void StaticRAM::write(unsigned addr, uint8 n) { data_[addr] = n; }
|
|
uint8& StaticRAM::operator[](unsigned addr) { return data_[addr]; }
|
|
const uint8& StaticRAM::operator[](unsigned addr) const { return data_[addr]; }
|
|
|
|
StaticRAM::StaticRAM(unsigned n) : size_(n) { data_ = new uint8[size_]; }
|
|
StaticRAM::~StaticRAM() { delete[] data_; }
|
|
|
|
//MappedRAM
|
|
|
|
void MappedRAM::reset() {
|
|
if(data_) {
|
|
delete[] data_;
|
|
data_ = 0;
|
|
}
|
|
size_ = 0;
|
|
write_protect_ = false;
|
|
}
|
|
|
|
void MappedRAM::map(uint8 *source, unsigned length) {
|
|
reset();
|
|
data_ = source;
|
|
size_ = data_ && length > 0 ? length : 0;
|
|
}
|
|
|
|
void MappedRAM::copy(const uint8 *data, unsigned size) {
|
|
if(!data_) {
|
|
size_ = (size & ~255) + ((bool)(size & 255) << 8);
|
|
data_ = new uint8[size_]();
|
|
}
|
|
memcpy(data_, data, min(size_, size));
|
|
}
|
|
|
|
void MappedRAM::write_protect(bool status) { write_protect_ = status; }
|
|
uint8* MappedRAM::data() { return data_; }
|
|
unsigned MappedRAM::size() const { return size_; }
|
|
|
|
uint8 MappedRAM::read(unsigned addr) { return data_[addr]; }
|
|
void MappedRAM::write(unsigned addr, uint8 n) { if(!write_protect_ || debugger_access()) data_[addr] = n; }
|
|
const uint8& MappedRAM::operator[](unsigned addr) const { return data_[addr]; }
|
|
MappedRAM::MappedRAM() : data_(0), size_(0), write_protect_(false) {}
|
|
|
|
//VRAM
|
|
|
|
void VRAM::reset() {
|
|
MappedRAM::reset();
|
|
bank(false);
|
|
}
|
|
|
|
void VRAM::map(uint8 *source, unsigned length) {
|
|
MappedRAM::map(source, length);
|
|
bank(false);
|
|
}
|
|
|
|
void VRAM::copy(const uint8 *data, unsigned size) {
|
|
MappedRAM::copy(data, size);
|
|
bank(false);
|
|
}
|
|
|
|
void VRAM::bank(bool enable, unsigned num) {
|
|
if (PPU::SupportsVRAMExpansion && enable && (size() >= 1<<17)) {
|
|
// Super V-Power expansion inverts CPU pin 20 -> VRAM A17
|
|
// assume higher address lines (if any are ever used) would also invert
|
|
num ^= 0x3f;
|
|
|
|
access_ = data() + ((num << 17) & (size() - 1));
|
|
mask_ = 0x1ffff;
|
|
} else {
|
|
access_ = data();
|
|
mask_ = 0xffff;
|
|
}
|
|
}
|
|
|
|
uint8& VRAM::operator[](unsigned addr) {
|
|
if (PPU::SupportsVRAMExpansion)
|
|
return access_[addr & mask_];
|
|
|
|
// non-accuracy PPU still uses uint16 for VRAM addresses, no casting/masking needed here
|
|
return access_[addr];
|
|
}
|
|
VRAM::VRAM() : MappedRAM() { reset(); }
|
|
|
|
//Bus
|
|
|
|
uint8 Bus::read(uint24 addr) {
|
|
#if defined(CHEAT_SYSTEM)
|
|
if(cheat.active() && cheat.exists(addr)) {
|
|
uint8 r;
|
|
if(cheat.read(addr, r, *this)) return r;
|
|
}
|
|
#endif
|
|
Page &p = page[addr >> 8];
|
|
return p.access->read(p.offset + addr);
|
|
}
|
|
|
|
void Bus::write(uint24 addr, uint8 data) {
|
|
Page &p = page[addr >> 8];
|
|
p.access->write(p.offset + addr, data);
|
|
}
|
|
|
|
bool Bus::is_mirror(uint24 addr1, uint24 addr2) {
|
|
// if the lower bytes of each address are different then they can't be mirrors
|
|
// since pages are always aligned to 256-byte boundaries
|
|
if((addr1 ^ addr2) & 0xff) return false;
|
|
|
|
Page &p1 = page[addr1 >> 8];
|
|
Page &p2 = page[addr2 >> 8];
|
|
return (p1.access == p2.access) && (p1.offset + addr1 == p2.offset + addr2);
|
|
}
|