|
@@ -84,16 +84,37 @@ void mmu_power(MMU *mmu) |
|
|
map_slot(mmu, slot, slot); |
|
|
map_slot(mmu, slot, slot); |
|
|
|
|
|
|
|
|
memset(mmu->system_ram, 0xFF, MMU_SYSTEM_RAM_SIZE); |
|
|
memset(mmu->system_ram, 0xFF, MMU_SYSTEM_RAM_SIZE); |
|
|
// TODO: set system_ram to correct values at 0xFFFC-0xFFFF |
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
|
|
|
Read a byte from a memory bank, or return 0xFF if the bank is not mapped. |
|
|
|
|
|
*/ |
|
|
|
|
|
static inline uint8_t bank_byte_read(const uint8_t* bank, uint16_t addr) |
|
|
|
|
|
{ |
|
|
|
|
|
return bank ? bank[addr] : 0xFF; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/* |
|
|
/* |
|
|
Read a byte of memory from the given address. |
|
|
Read a byte of memory from the given address. |
|
|
|
|
|
|
|
|
|
|
|
Memory region information is based on: |
|
|
|
|
|
- http://www.smspower.org/Development/MemoryMap |
|
|
|
|
|
- http://www.smspower.org/Development/Mappers |
|
|
*/ |
|
|
*/ |
|
|
uint8_t mmu_read_byte(MMU *mmu, uint16_t addr) |
|
|
uint8_t mmu_read_byte(MMU *mmu, uint16_t addr) |
|
|
{ |
|
|
{ |
|
|
// TODO |
|
|
|
|
|
return 0x00; |
|
|
|
|
|
|
|
|
if (addr < 0x0400) // First kilobyte is unpaged, for interrupt handlers |
|
|
|
|
|
return bank_byte_read(mmu->rom_banks[0], addr); |
|
|
|
|
|
else if (addr < 0x4000) // Slot 0 (0x0400 - 0x3FFF) |
|
|
|
|
|
return bank_byte_read(mmu->map_slots[0], addr); |
|
|
|
|
|
else if (addr < 0x8000) // Slot 1 (0x4000 - 0x7FFF) |
|
|
|
|
|
return bank_byte_read(mmu->map_slots[1], addr - 0x4000); |
|
|
|
|
|
else if (addr < 0xC000) // Slot 2 (0x8000 - 0xBFFF) |
|
|
|
|
|
return bank_byte_read(mmu->map_slots[2], addr - 0x8000); |
|
|
|
|
|
else if (addr < 0xE000) // System RAM (0xC000 - 0xDFFF) |
|
|
|
|
|
return mmu->system_ram[addr - 0xC000]; |
|
|
|
|
|
else // System RAM, mirrored (0xE000 - 0xFFFF) |
|
|
|
|
|
return mmu->system_ram[addr - 0xE000]; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/* |
|
|
/* |
|
@@ -104,6 +125,21 @@ uint8_t mmu_read_byte(MMU *mmu, uint16_t addr) |
|
|
*/ |
|
|
*/ |
|
|
bool mmu_write_byte(MMU *mmu, uint16_t addr, uint8_t value) |
|
|
bool mmu_write_byte(MMU *mmu, uint16_t addr, uint8_t value) |
|
|
{ |
|
|
{ |
|
|
// TODO |
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
|
if (addr < 0xC000) { // TODO: implement writes to on-cartridge RAM |
|
|
|
|
|
return false; |
|
|
|
|
|
} else if (addr < 0xE000) { // System RAM (0xC000 - 0xDFFF) |
|
|
|
|
|
mmu->system_ram[addr - 0xC000] = value; |
|
|
|
|
|
return true; |
|
|
|
|
|
} else { // System RAM, mirrored (0xE000 - 0xFFFF) |
|
|
|
|
|
if (addr == 0xFFFC) { |
|
|
|
|
|
// TODO: handle cartridge RAM mapping control |
|
|
|
|
|
} else if (addr == 0xFFFD) |
|
|
|
|
|
map_slot(mmu, 0, value & 0x3F); |
|
|
|
|
|
else if (addr == 0xFFFE) |
|
|
|
|
|
map_slot(mmu, 1, value & 0x3F); |
|
|
|
|
|
else if (addr == 0xFFFF) |
|
|
|
|
|
map_slot(mmu, 2, value & 0x3F); |
|
|
|
|
|
mmu->system_ram[addr - 0xE000] = value; |
|
|
|
|
|
return true; |
|
|
|
|
|
} |
|
|
} |
|
|
} |