nesemu/cpu/memory.c

76 lines
1.8 KiB
C
Raw Normal View History

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"
2024-05-06 20:23:44 -04:00
#include "cpu.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-05-06 20:23:44 -04:00
byte ram[RAM_SIZE];
byte mem_get_byte(address addr) {
2024-01-06 14:27:09 -05:00
assert(addr <= MAX_ADDR);
if (addr >= RAM_MAX_ADDR && addr < PPU_MAX_ADDR) {
byte reg = (addr - RAM_MAX_ADDR) % PPU_BANK_SIZE;
2024-05-06 20:23:44 -04:00
ppu_read_register(reg);
2024-01-06 14:27:09 -05:00
}
2024-05-06 20:23:44 -04:00
return ram[addr];
}
2023-12-23 16:35:23 -05:00
2024-05-06 20:23:44 -04:00
byte *mem_get_ptr(address addr) {
assert(addr <= MAX_ADDR);
return &ram[addr];
2023-11-26 12:11:49 -05:00
}
2024-05-06 20:23:44 -04:00
word mem_get_word(address addr) {
2024-01-06 14:27:09 -05:00
assert(addr < MAX_ADDR);
2023-12-23 16:35:23 -05:00
2024-05-06 20:23:44 -04:00
word word = ram[addr];
word += ram[addr + 1] << 8; // Little endian
2024-01-06 14:27:09 -05:00
return word;
2023-11-26 12:11:49 -05:00
}
2024-05-06 20:23:44 -04:00
void mem_set_byte(address addr, byte byte) {
2024-01-06 14:27:09 -05:00
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;
2024-05-06 20:23:44 -04:00
ram[ram_addr] = byte;
2024-01-06 14:27:09 -05:00
}
} 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++) {
2024-05-06 20:23:44 -04:00
address ram_addr = reg_addr + PPU_BANK_SIZE * i + RAM_MAX_ADDR;
ram[ram_addr] = byte;
2024-01-06 14:27:09 -05:00
}
2024-05-06 20:23:44 -04:00
ppu_write_register(reg_addr);
2024-01-06 14:27:09 -05:00
} else {
2024-05-06 20:23:44 -04:00
ram[addr] = byte;
2024-01-06 14:27:09 -05:00
if (addr == PPU_REGISTER_OAM_DMA_ADDR) {
// Writing to this address triggers an upload to the PPU memory
2024-05-06 20:23:44 -04:00
cpu_trigger_oam_dma();
2024-01-06 14:27:09 -05:00
}
}
2023-11-26 12:11:49 -05:00
}