136 lines
3.6 KiB
C++
Executable File
136 lines
3.6 KiB
C++
Executable File
struct Memory {
|
|
virtual unsigned size() const { return 0; }
|
|
virtual uint8 read(unsigned addr) = 0;
|
|
virtual void write(unsigned addr, uint8 data) = 0;
|
|
};
|
|
|
|
struct MMIO {
|
|
virtual uint8 mmio_read(unsigned addr) = 0;
|
|
virtual void mmio_write(unsigned addr, uint8 data) = 0;
|
|
};
|
|
|
|
struct UnmappedMemory : Memory {
|
|
uint8 read(unsigned);
|
|
void write(unsigned, uint8);
|
|
};
|
|
|
|
struct UnmappedMMIO : MMIO {
|
|
uint8 mmio_read(unsigned);
|
|
void mmio_write(unsigned, uint8);
|
|
};
|
|
|
|
struct StaticRAM : Memory {
|
|
uint8* handle() { return data; }
|
|
unsigned size() const { return datasize; }
|
|
|
|
inline uint8 read(unsigned addr) { return data[addr]; }
|
|
inline void write(unsigned addr, uint8 n) { data[addr] = n; }
|
|
inline uint8& operator[](unsigned addr) { return data[addr]; }
|
|
inline const uint8& operator[](unsigned addr) const { return data[addr]; }
|
|
|
|
StaticRAM(unsigned n) : datasize(n) { data = new uint8[datasize]; }
|
|
~StaticRAM() { delete[] data; }
|
|
|
|
private:
|
|
uint8 *data;
|
|
unsigned datasize;
|
|
};
|
|
|
|
struct MappedRAM : Memory {
|
|
void map(uint8 *source, unsigned length) { data = source; datasize = length > 0 ? length : -1U; }
|
|
void write_protect(bool status) { write_protection = status; }
|
|
uint8* handle() { return data; }
|
|
unsigned size() const { return datasize; }
|
|
|
|
inline uint8 read(unsigned addr) { return data[addr]; }
|
|
inline void write(unsigned addr, uint8 n) { if(!write_protection) data[addr] = n; }
|
|
inline const uint8& operator[](unsigned addr) const { return data[addr]; }
|
|
|
|
MappedRAM() : data(0), datasize(0), write_protection(false) {}
|
|
|
|
private:
|
|
uint8 *data;
|
|
unsigned datasize;
|
|
bool write_protection;
|
|
};
|
|
|
|
struct MMIOAccess : Memory {
|
|
void map(unsigned addr, MMIO &access);
|
|
MMIO* get(unsigned addr);
|
|
uint8 read(unsigned addr);
|
|
void write(unsigned addr, uint8 data);
|
|
|
|
private:
|
|
MMIO *mmio[0x4000];
|
|
};
|
|
|
|
class Bus {
|
|
public:
|
|
unsigned mirror(unsigned addr, unsigned size);
|
|
void map(unsigned addr, Memory &access, unsigned offset);
|
|
enum MapMode { MapDirect, MapLinear, MapShadow };
|
|
void map(MapMode mode,
|
|
uint8 bank_lo, uint8 bank_hi,
|
|
uint16 addr_lo, uint16 addr_hi,
|
|
Memory &access, unsigned offset = 0, unsigned size = 0);
|
|
|
|
alwaysinline uint8 read(unsigned addr) {
|
|
#if defined(CHEAT_SYSTEM)
|
|
if(cheat.active() && cheat.exists(addr)) {
|
|
uint8 r;
|
|
if(cheat.read(addr, r)) return r;
|
|
}
|
|
#endif
|
|
|
|
Page &p = page[addr >> 8];
|
|
return p.access->read(p.offset + addr);
|
|
}
|
|
|
|
alwaysinline void write(unsigned addr, uint8 data) {
|
|
Page &p = page[addr >> 8];
|
|
return p.access->write(p.offset + addr, data);
|
|
}
|
|
|
|
void set_speed(bool fast) {
|
|
fastSpeed = fast ? 6 : 8;
|
|
}
|
|
|
|
alwaysinline unsigned speed(unsigned addr) const {
|
|
if(addr & 0x408000) {
|
|
if(addr & 0x800000) return fastSpeed;
|
|
return 8;
|
|
}
|
|
if((addr + 0x6000) & 0x4000) return 8;
|
|
if((addr - 0x4000) & 0x7e00) return 6;
|
|
return 12;
|
|
}
|
|
|
|
virtual bool load_cart() = 0;
|
|
virtual void unload_cart() = 0;
|
|
|
|
virtual void power() = 0;
|
|
virtual void reset() = 0;
|
|
|
|
Bus() {}
|
|
virtual ~Bus() {}
|
|
|
|
protected:
|
|
struct Page {
|
|
Memory *access;
|
|
unsigned offset;
|
|
} page[65536];
|
|
unsigned fastSpeed;
|
|
};
|
|
|
|
namespace memory {
|
|
extern MMIOAccess mmio; //S-CPU, S-PPU
|
|
extern StaticRAM wram; //S-CPU
|
|
extern StaticRAM apuram; //S-SMP, S-DSP
|
|
extern StaticRAM vram; //S-PPU
|
|
extern StaticRAM oam; //S-PPU
|
|
extern StaticRAM cgram; //S-PPU
|
|
|
|
extern UnmappedMemory memory_unmapped;
|
|
extern UnmappedMMIO mmio_unmapped;
|
|
};
|