Skip to content

Commit df763bd

Browse files
committed
first draft of ppu
1 parent c84e8c9 commit df763bd

6 files changed

Lines changed: 134 additions & 19 deletions

File tree

src/cpu.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
use crate::memory_map::MemoryMap;
1+
use cpu_memory::CpuMemory;
22
use std::fmt;
33
use std::thread::sleep;
44
use std::time::Duration;
55

6+
pub mod cpu_memory;
7+
68
const STATUS_NEGATIVE_BIT: u32 = 7;
79
const STATUS_OVERFLOW_BIT: u32 = 6;
810
const STATUS_IGNORED_BIT: u32 = 5;
@@ -156,7 +158,7 @@ impl Default for CpuOptions {
156158
pub struct Cpu {
157159
options: CpuOptions,
158160
registers: Registers,
159-
memory: MemoryMap,
161+
memory: CpuMemory,
160162
clock_speed: u32,
161163
}
162164

@@ -1291,7 +1293,7 @@ impl Cpu {
12911293
}
12921294

12931295
impl Cpu {
1294-
pub fn new(options: CpuOptions, memory: MemoryMap, clock_speed: u32) -> Self {
1296+
pub fn new(options: CpuOptions, memory: CpuMemory, clock_speed: u32) -> Self {
12951297
Self {
12961298
options,
12971299
registers: Registers::new(memory.reset_vector()),
@@ -1300,7 +1302,7 @@ impl Cpu {
13001302
}
13011303
}
13021304

1303-
pub fn with_nes_options(memory: MemoryMap, clock_speed: u32) -> Self {
1305+
pub fn with_nes_options(memory: CpuMemory, clock_speed: u32) -> Self {
13041306
Self {
13051307
options: NES_CPU_OPTIONS,
13061308
registers: Registers::new(memory.reset_vector()),
@@ -1512,16 +1514,16 @@ impl Cpu {
15121514

15131515
#[cfg(test)]
15141516
mod test {
1515-
use crate::cpu::{Cpu, CpuOptions};
1516-
use crate::memory_map::MemoryMap;
1517+
use crate::cpu::Cpu;
1518+
use crate::cpu::cpu_memory::CpuMemory;
15171519
use crate::nes_rom::NesRom;
15181520
use std::fs::File;
15191521
use std::io::{BufRead, BufReader};
15201522

15211523
#[test]
15221524
fn nestest() {
15231525
let rom = NesRom::read_from_file("./vendor/nestest/nestest.nes").unwrap();
1524-
let memory_map = MemoryMap::new(rom);
1526+
let memory_map = CpuMemory::new(rom);
15251527
let mut cpu = Cpu::with_nes_options(memory_map, 1 << 16);
15261528
cpu.registers.pc = 0xC000;
15271529
cpu.registers.p = 0x24;
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
use crate::nes_rom::NesRom;
22
use crate::ram::Ram;
33

4-
pub struct MemoryMap {
4+
pub struct CpuMemory {
55
sram: Ram,
66
rom: NesRom,
77
prg_ram: Ram
88
}
99

10-
impl MemoryMap {
10+
impl CpuMemory {
1111
pub fn new(rom: NesRom) -> Self {
1212
Self {
1313
sram: Ram::new(0x8000),

src/main.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
mod cpu;
2-
mod memory_map;
32
mod nes_rom;
43
mod ram;
4+
mod ppu;
55

6-
use crate::memory_map::MemoryMap;
6+
use cpu::cpu_memory::CpuMemory;
77
use crate::nes_rom::NesRom;
88
use cpu::Cpu;
99

1010
fn main() -> Result<(), anyhow::Error> {
1111
println!("Starting Emulator!");
1212

13-
let rom = NesRom::read_from_file("./nestest.nes")?;
13+
let rom = NesRom::read_from_file("./vendor/nestest/nestest.nes")?;
1414
println!("{rom:#?}");
1515

16-
let memory_map = MemoryMap::new(rom);
16+
let memory_map = CpuMemory::new(rom);
1717
println!("Entry point: {:#X}", memory_map.reset_vector());
1818

1919
let mut cpu = Cpu::with_nes_options(memory_map, 1 << 16);
20-
cpu.run();
20+
// cpu.run();
2121

2222
Ok(())
2323
}

src/nes_rom.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ use std::io::Read;
33
use std::fmt;
44

55
#[derive(Debug)]
6-
pub enum NametableArrangement {
6+
pub enum NametableMirroring {
77
Vertical,
88
Horizontal,
99
}
1010

11-
impl NametableArrangement {
11+
impl NametableMirroring {
1212
fn from_bit(value: u8) -> Self {
1313
match value {
1414
0 => Self::Vertical,
@@ -45,7 +45,7 @@ pub struct NesRom {
4545
trainer: Option<[u8; TRAINER_SIZE]>,
4646
mapper: u8,
4747
alt_nametable: bool,
48-
nametable_arrangement: NametableArrangement,
48+
nametable_arrangement: NametableMirroring,
4949
battery_backed_prg_ram: bool,
5050
prg_ram_size: u8,
5151
tv_system: TvSystem,
@@ -60,7 +60,7 @@ impl fmt::Debug for NesRom {
6060
_has_trainer: bool,
6161
_mapper: &'a u8,
6262
_alt_nametable: &'a bool,
63-
_nametable_arrangement: &'a NametableArrangement,
63+
_nametable_arrangement: &'a NametableMirroring,
6464
_battery_backed_prg_ram: &'a bool,
6565
_prg_ram_size: &'a u8,
6666
_tv_system: &'a TvSystem,
@@ -111,7 +111,7 @@ impl NesRom {
111111
let flags7 = header[7];
112112
let mapper = (flags7 & 0xF0) | (flags6 >> 4);
113113
let alt_nametable = (flags6 >> 3) & 1 == 1;
114-
let nametable_arrangement = NametableArrangement::from_bit(flags6 & 1);
114+
let nametable_arrangement = NametableMirroring::from_bit(flags6 & 1);
115115
let has_trainer = (flags6 >> 2) & 1 == 1;
116116
let battery_backed_prg_ram = (flags6 >> 1) & 1 == 1;
117117
let prg_ram_size = header[8];

src/ppu.rs

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
use crate::nes_rom::NametableMirroring;
2+
use crate::ppu::ppu_memory::PpuMemory;
3+
4+
mod ppu_memory;
5+
6+
struct PpuAddr {
7+
hi: u8,
8+
lo: u8,
9+
is_hi: bool,
10+
}
11+
12+
impl PpuAddr {
13+
fn new() -> Self {
14+
Self {
15+
hi: 0,
16+
lo: 0,
17+
is_hi: true,
18+
}
19+
}
20+
21+
fn set(&mut self, value: u8) {
22+
if self.is_hi {
23+
self.hi = value;
24+
} else {
25+
self.lo = value;
26+
}
27+
28+
self.is_hi = !self.is_hi;
29+
}
30+
31+
fn get_addr(&self) -> u16 {
32+
const PPU_ADDR_MASK: u16 = 0x3FFF;
33+
((self.hi as u16) << 8 | (self.lo as u16)) & PPU_ADDR_MASK
34+
}
35+
36+
fn increment_addr(&mut self, amount: u16) {
37+
//TODO
38+
}
39+
}
40+
41+
const PPU_CTRL_NAMETABLE_MASK: u8 = 0x3;
42+
const PPU_VRAM_ADD_INCREMENT_BIT: u8 = 2;
43+
const PPU_SPRITE_PATTERN_ADDR_BIT: u8 = 3;
44+
const PPU_BACKRGROUND_ADDR_BIT: u8 = 4;
45+
const PPU_SPRITE_SIZE_BIT: u8 = 5;
46+
const PPU_MASTER_SLAVE_SELECT_BIT: u8 = 6;
47+
const PPU_VBLANK_NMI_BIT: u8 = 7;
48+
49+
struct PpuRegisters {
50+
ctrl: u8,
51+
mask: u8,
52+
status: u8,
53+
oam_addr: u8,
54+
oam_data: u8,
55+
scroll: u8,
56+
addr: PpuAddr,
57+
data_buffer: u8,
58+
oam_dma: u8,
59+
}
60+
61+
impl PpuRegisters {
62+
pub fn new() -> Self {
63+
Self {
64+
ctrl: 0,
65+
mask: 0,
66+
status: 0,
67+
oam_addr: 0,
68+
oam_data: 0,
69+
scroll: 0,
70+
addr: PpuAddr::new(),
71+
data_buffer: 0,
72+
oam_dma: 0,
73+
}
74+
}
75+
}
76+
77+
pub struct Ppu {
78+
registers: PpuRegisters,
79+
memory: PpuMemory,
80+
}
81+
82+
impl Ppu {
83+
pub fn new(chr_rom: Vec<u8>, mirroring: NametableMirroring) -> Self {
84+
Self {
85+
registers: PpuRegisters::new(),
86+
memory: PpuMemory::new(chr_rom, mirroring),
87+
}
88+
}
89+
}

src/ppu/ppu_memory.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
use crate::nes_rom::NametableMirroring;
2+
3+
pub struct PpuMemory {
4+
chr_rom: Vec<u8>,
5+
mirroring: NametableMirroring,
6+
}
7+
8+
impl PpuMemory {
9+
pub fn new(chr_rom: Vec<u8>, mirroring: NametableMirroring) -> Self {
10+
Self { chr_rom, mirroring }
11+
}
12+
13+
fn read(&self, addr: u16) -> u8 {
14+
if addr < 0x2000 {
15+
self.chr_rom[addr as usize]
16+
} else {
17+
unimplemented!()
18+
}
19+
}
20+
21+
fn write(&mut self, addr: u16, data: u8) {
22+
unimplemented!();
23+
}
24+
}

0 commit comments

Comments
 (0)