finish ch4
This commit is contained in:
parent
ee8f45608f
commit
edb573333b
60
src/bus.rs
Normal file
60
src/bus.rs
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
use crate::cpu::Mem;
|
||||||
|
|
||||||
|
const RAM: u16 = 0x0000;
|
||||||
|
const RAM_MIRRORS_END: u16 = 0x1FFF;
|
||||||
|
const PPU_REGISTERS: u16 = 0x2000;
|
||||||
|
const PPU_REGISTERS_MIRRORS_END: u16 = 0x3FFF;
|
||||||
|
|
||||||
|
pub struct Bus {
|
||||||
|
cpu_vram: [u8; 2048],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Bus {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Bus {
|
||||||
|
pub fn new() -> Bus {
|
||||||
|
Bus {
|
||||||
|
cpu_vram: [0; 2048],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Mem for Bus {
|
||||||
|
fn mem_read(&self, addr: u16) -> u8 {
|
||||||
|
match addr {
|
||||||
|
RAM..=RAM_MIRRORS_END => {
|
||||||
|
let mirror_down_addr = addr & 0x07FF;
|
||||||
|
self.cpu_vram[mirror_down_addr as usize]
|
||||||
|
}
|
||||||
|
PPU_REGISTERS..=PPU_REGISTERS_MIRRORS_END => {
|
||||||
|
let _mirror_down_addr = addr & 0x2007;
|
||||||
|
todo!("PPU not implemented")
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
println!("Read from unimplemented memory address: {:#X}", addr);
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mem_write(&mut self, addr: u16, data: u8) {
|
||||||
|
match addr {
|
||||||
|
RAM..=RAM_MIRRORS_END => {
|
||||||
|
let mirror_down_addr = addr & 0x07FF;
|
||||||
|
self.cpu_vram[mirror_down_addr as usize] = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
PPU_REGISTERS..=PPU_REGISTERS_MIRRORS_END => {
|
||||||
|
let _mirror_down_addr = addr & 0x2007;
|
||||||
|
todo!("ppu not implemented");
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
println!("Write to unimplemented memory address: {:#X}", addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
28
src/cpu.rs
28
src/cpu.rs
@ -1,3 +1,5 @@
|
|||||||
|
use crate::bus;
|
||||||
|
use crate::bus::Bus;
|
||||||
use crate::opcodes;
|
use crate::opcodes;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
@ -46,7 +48,7 @@ pub struct CPU {
|
|||||||
pub status: CpuFlags,
|
pub status: CpuFlags,
|
||||||
pub program_counter: u16,
|
pub program_counter: u16,
|
||||||
pub stack_pointer: u8,
|
pub stack_pointer: u8,
|
||||||
memory: [u8; 0xFFFF],
|
pub bus: bus::Bus,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for CPU {
|
impl Default for CPU {
|
||||||
@ -76,11 +78,19 @@ pub trait Mem {
|
|||||||
|
|
||||||
impl Mem for CPU {
|
impl Mem for CPU {
|
||||||
fn mem_read(&self, addr: u16) -> u8 {
|
fn mem_read(&self, addr: u16) -> u8 {
|
||||||
self.memory[addr as usize]
|
self.bus.mem_read(addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mem_write(&mut self, addr: u16, data: u8) {
|
fn mem_write(&mut self, addr: u16, data: u8) {
|
||||||
self.memory[addr as usize] = data;
|
self.bus.mem_write(addr, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mem_read_u16(&self, pos: u16) -> u16 {
|
||||||
|
self.bus.mem_read_u16(pos)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mem_write_u16(&mut self, pos: u16, data: u16) {
|
||||||
|
self.bus.mem_write_u16(pos, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,7 +118,7 @@ impl CPU {
|
|||||||
status: CpuFlags::from_bits_truncate(0b0010_0100),
|
status: CpuFlags::from_bits_truncate(0b0010_0100),
|
||||||
program_counter: 0,
|
program_counter: 0,
|
||||||
stack_pointer: STACK_RESET,
|
stack_pointer: STACK_RESET,
|
||||||
memory: [0; 0xFFFF],
|
bus: Bus::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,13 +134,19 @@ impl CPU {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn load(&mut self, program: Vec<u8>) {
|
pub fn load(&mut self, program: Vec<u8>) {
|
||||||
self.memory[0x8000..(0x8000 + program.len())].copy_from_slice(&program[..]);
|
for i in 0..(program.len() as u16) {
|
||||||
|
self.mem_write(0x8000 + i, program[i as usize]);
|
||||||
|
}
|
||||||
|
|
||||||
self.mem_write_u16(0xFFFC, 0x8000);
|
self.mem_write_u16(0xFFFC, 0x8000);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TEMPORARY
|
// TEMPORARY
|
||||||
pub fn load_sneak(&mut self, program: Vec<u8>) {
|
pub fn load_sneak(&mut self, program: Vec<u8>) {
|
||||||
self.memory[0x0600..(0x0600 + program.len())].copy_from_slice(&program[..]);
|
for i in 0..(program.len() as u16) {
|
||||||
|
self.mem_write(0x0600 + i, program[i as usize]);
|
||||||
|
}
|
||||||
|
|
||||||
self.mem_write_u16(0xFFFC, 0x0600);
|
self.mem_write_u16(0xFFFC, 0x0600);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
pub mod bus;
|
||||||
pub mod cpu;
|
pub mod cpu;
|
||||||
pub mod opcodes;
|
pub mod opcodes;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user