2023-11-26 12:11:49 -05:00
|
|
|
//
|
|
|
|
// Created by william on 10/15/23.
|
|
|
|
//
|
|
|
|
|
2024-01-06 14:27:09 -05:00
|
|
|
#include <assert.h>
|
2024-04-30 12:28:43 -04:00
|
|
|
#include "log.h"
|
2023-11-26 12:11:49 -05:00
|
|
|
#include "memory.h"
|
2023-12-23 16:35:23 -05:00
|
|
|
#include "../include/rom.h"
|
2023-11-26 12:11:49 -05:00
|
|
|
|
2024-01-06 14:27:09 -05:00
|
|
|
#define RAM_MAX_ADDR 0x2000
|
|
|
|
#define RAM_BANK_SIZE 0x800
|
|
|
|
#define PPU_MAX_ADDR 0x4000
|
|
|
|
#define PPU_BANK_SIZE 0x8
|
|
|
|
#define APU_MAX_ADDR 0x4020
|
|
|
|
#define MAX_ADDR 0xffff
|
2023-12-23 16:35:23 -05:00
|
|
|
|
2024-01-06 14:27:09 -05:00
|
|
|
byte mem_get_byte(System *system, address addr) {
|
|
|
|
assert(addr <= MAX_ADDR);
|
|
|
|
|
|
|
|
if (addr >= RAM_MAX_ADDR && addr < PPU_MAX_ADDR) {
|
|
|
|
byte reg = (addr - RAM_MAX_ADDR) % PPU_BANK_SIZE;
|
|
|
|
ppu_read_register(&system->ppu, reg);
|
|
|
|
return system->ppu.registers[reg];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (addr >= PPU_MAX_ADDR && addr < APU_MAX_ADDR) {
|
|
|
|
byte apu_addr = addr - PPU_MAX_ADDR;
|
|
|
|
return system->apu_registers[apu_addr];
|
2023-12-23 16:35:23 -05:00
|
|
|
}
|
|
|
|
|
2024-01-06 14:27:09 -05:00
|
|
|
return system->ram[addr];
|
2023-11-26 12:11:49 -05:00
|
|
|
}
|
|
|
|
|
2024-01-06 14:27:09 -05:00
|
|
|
word mem_get_word(System *system, address addr) {
|
|
|
|
assert(addr < MAX_ADDR);
|
2023-12-23 16:35:23 -05:00
|
|
|
|
2024-01-06 14:27:09 -05:00
|
|
|
if (addr >= RAM_MAX_ADDR && addr < APU_MAX_ADDR) {
|
|
|
|
assert(false);
|
2023-12-23 16:35:23 -05:00
|
|
|
}
|
|
|
|
|
2024-01-06 14:27:09 -05:00
|
|
|
word word = system->ram[addr];
|
|
|
|
word += system->ram[addr + 1] << 8; // Little endian
|
|
|
|
return word;
|
2023-11-26 12:11:49 -05:00
|
|
|
}
|
|
|
|
|
2024-01-06 14:27:09 -05:00
|
|
|
void mem_set_byte(System *system, address addr, byte byte) {
|
|
|
|
assert(addr < MAX_ADDR);
|
|
|
|
|
|
|
|
log_trace("Writing '%02x' to address 0x%04x", byte, addr);
|
|
|
|
|
|
|
|
if (addr < RAM_MAX_ADDR) {
|
|
|
|
address init_ram_addr = addr % RAM_BANK_SIZE;
|
|
|
|
|
|
|
|
// The value must also be cloned in the three mirrors
|
|
|
|
for (int i = 0; i < 4; i++) {
|
|
|
|
address ram_addr = init_ram_addr + RAM_BANK_SIZE * i;
|
|
|
|
system->ram[ram_addr] = byte;
|
|
|
|
}
|
|
|
|
} else if (addr < PPU_MAX_ADDR) {
|
|
|
|
address reg_addr = (addr - RAM_MAX_ADDR) % PPU_BANK_SIZE;
|
|
|
|
|
|
|
|
int bank_count = (PPU_MAX_ADDR - RAM_MAX_ADDR) / PPU_BANK_SIZE;
|
|
|
|
for (int i = 0; i < bank_count; i++) {
|
|
|
|
address ram_addr = reg_addr + PPU_BANK_SIZE * i;
|
|
|
|
system->ppu.registers[ram_addr] = byte;
|
|
|
|
}
|
|
|
|
|
|
|
|
ppu_write_register(&system->ppu, reg_addr);
|
|
|
|
} else {
|
|
|
|
system->ram[addr] = byte;
|
|
|
|
|
|
|
|
if (addr == PPU_REGISTER_OAM_DMA_ADDR) {
|
|
|
|
// Writing to this address triggers an upload to the PPU memory
|
|
|
|
system->cpu.oam_dma_triggered = true;
|
|
|
|
}
|
|
|
|
}
|
2023-11-26 12:11:49 -05:00
|
|
|
}
|