2009-04-22 20:04:28 +02:00

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;
};