Skip to content

Commit

Permalink
make devices read mut
Browse files Browse the repository at this point in the history
  • Loading branch information
goooosick committed Oct 30, 2023
1 parent 287e8d4 commit f57a59c
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 77 deletions.
2 changes: 1 addition & 1 deletion les_nes/src/apu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ impl Apu {
self.resampler.clear();
}

pub fn read(&self, addr: u16) -> u8 {
pub fn read(&mut self, addr: u16) -> u8 {
match addr {
0x4015 => {
let mut data = 0;
Expand Down
13 changes: 6 additions & 7 deletions les_nes/src/apu/units/frame.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use bit_field::BitField;
use std::cell::Cell;

const FRAME_FREQUENCY: f32 = 240.0;
const FRAME_PERIOD: f32 = crate::CPU_FREQUENCY / FRAME_FREQUENCY;
Expand Down Expand Up @@ -29,7 +28,7 @@ pub struct FrameCounter {
step: usize,
mode: Mode,
irq_on: bool,
irq_level: Cell<bool>,
irq_level: bool,
}

impl FrameCounter {
Expand All @@ -39,7 +38,7 @@ impl FrameCounter {
step: 0,
mode: Mode::Step4,
irq_on: false,
irq_level: Cell::default(),
irq_level: false,
}
}

Expand All @@ -54,7 +53,7 @@ impl FrameCounter {
step.set(Step::LENGTH, self.step == 1 || self.step == 3);
step.set(Step::ENVELOPE, true);
if self.irq_on && self.step == 3 {
self.irq_level.set(true);
self.irq_level = true;
}
}
Mode::Step5 => {
Expand Down Expand Up @@ -82,11 +81,11 @@ impl FrameCounter {

self.irq_on = !data.get_bit(6);
if !self.irq_on {
self.irq_level.take();
self.irq_level = false;
}
}

pub fn irq(&self) -> bool {
self.irq_level.replace(false)
pub fn irq(&mut self) -> bool {
std::mem::take(&mut self.irq_level)
}
}
2 changes: 1 addition & 1 deletion les_nes/src/bus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ impl Bus {
}
}

pub fn inspect(&self, addr: u16) -> u8 {
pub fn inspect(&mut self, addr: u16) -> u8 {
match addr {
0x0000..=0x1fff => self.ram[addr as usize & 0x07ff],
0x2000..=0x3fff => self.ppu.read(&self.cart, addr),
Expand Down
16 changes: 7 additions & 9 deletions les_nes/src/bus/joystick.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::cell::Cell;

#[derive(Debug, Default)]
pub struct Joystick {
input0: Input,
Expand All @@ -8,7 +6,7 @@ pub struct Joystick {
}

impl Joystick {
pub fn read(&self, addr: u16) -> u8 {
pub fn read(&mut self, addr: u16) -> u8 {
if !self.reading {
self.input0.load();
self.input1.load();
Expand Down Expand Up @@ -69,17 +67,17 @@ impl InputStates {
#[derive(Debug, Default)]
struct Input {
states: InputStates,
input: Cell<u8>,
input: u8,
}

impl Input {
fn load(&self) {
self.input.set(self.states.to_u8())
fn load(&mut self) {
self.input = self.states.to_u8();
}

fn next(&self) -> u8 {
let b = self.input.get();
self.input.set(b >> 1);
fn next(&mut self) -> u8 {
let b = self.input;
self.input = b >> 1;
!b & 0b01
}
}
2 changes: 1 addition & 1 deletion les_nes/src/cpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ impl Cpu {
self.pc = addr;
}

pub fn dump(&self, bus: &Bus) {
pub fn dump(&self, bus: &mut Bus) {
use op_code::OP_NAMES;

print!("{:04X} ", self.pc);
Expand Down
34 changes: 17 additions & 17 deletions les_nes/src/ppu.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use self::regs::*;
use crate::cart::Cartridge;
use bit_field::BitField;
use std::{cell::Cell, ops::IndexMut};
use std::ops::IndexMut;

pub use self::palettes::PALETTES;

Expand Down Expand Up @@ -54,12 +54,12 @@ pub struct Ppu {
mask: PpuMask,
status: PpuStatus,
oam_addr: usize,
data_buf: Cell<u8>,
data_buf: u8,

v: VramAddr,
t: VramAddr,
x: usize,
w: Cell<WriteLatch>,
w: WriteLatch,
frames: usize,
line: usize,
dot: usize,
Expand All @@ -78,12 +78,12 @@ impl Default for Ppu {
mask: PpuMask::default(),
status: PpuStatus::default(),
oam_addr: 0,
data_buf: Cell::new(0),
data_buf: 0,

v: VramAddr::default(),
t: VramAddr::default(),
x: 0,
w: Cell::new(WriteLatch::Step0),
w: WriteLatch::Step0,
frames: 0,
line: 0,
dot: 0,
Expand Down Expand Up @@ -361,7 +361,7 @@ impl Ppu {
self.v = VramAddr::default();
self.t = VramAddr::default();
self.x = 0;
self.w = Cell::new(WriteLatch::Step0);
self.w = WriteLatch::Step0;
self.nametables.fill(0);
self.palettes.fill(0);
}
Expand All @@ -380,15 +380,15 @@ impl Ppu {
}

impl Ppu {
pub fn read(&self, cart: &Cartridge, addr: u16) -> u8 {
pub fn read(&mut self, cart: &Cartridge, addr: u16) -> u8 {
let addr = (addr - 0x2000) & 0x07;
match addr {
0x00 => 0x00,
0x01 => 0x00,
0x02 => {
let b = self.status.get();
self.status.set_vblank(false);
self.w.set(WriteLatch::Step0);
self.w = WriteLatch::Step0;
b
}
0x03 => 0x00,
Expand All @@ -397,15 +397,15 @@ impl Ppu {
0x06 => 0x00,
0x07 => {
let addr = self.v.addr();
let data = self.data_buf.get();
let data = self.data_buf;

self.data_buf.set(self.read_vram(cart, addr));
self.data_buf = self.read_vram(cart, addr);
self.v.inc(self.ctrl.addr_inc());

if addr < 0x3f00 {
data
} else {
self.data_buf.get()
self.data_buf
}
}

Expand All @@ -428,24 +428,24 @@ impl Ppu {
self.oam_addr = (self.oam_addr + 1) & 0xff;
}
0x05 => {
if self.w.get() == WriteLatch::Step0 {
if self.w == WriteLatch::Step0 {
self.t.set_coarse_x((data >> 3) as u16);
self.x = (data & 0b0111) as usize;
self.w.set(WriteLatch::Step1);
self.w = WriteLatch::Step1;
} else {
self.t.set_coarse_y((data >> 3) as u16);
self.t.set_y((data & 0b0111) as u16);
self.w.set(WriteLatch::Step0);
self.w = WriteLatch::Step0;
}
}
0x06 => {
if self.w.get() == WriteLatch::Step0 {
if self.w == WriteLatch::Step0 {
self.t.set_bits(0x08..0x0f, (data & 0b0011_1111) as u16);
self.w.set(WriteLatch::Step1);
self.w = WriteLatch::Step1;
} else {
self.t.set_bits(0x00..0x08, data as u16);
self.v = self.t.clone();
self.w.set(WriteLatch::Step0);
self.w = WriteLatch::Step0;
}
}
0x07 => {
Expand Down
80 changes: 39 additions & 41 deletions les_nes/src/ppu/regs.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use bit_field::BitField;
use std::cell::Cell;

/// PPU control register
#[derive(Debug, Default)]
Expand Down Expand Up @@ -90,23 +89,23 @@ impl PpuMask {

/// PPU status register
#[derive(Debug, Default)]
pub struct PpuStatus(Cell<u8>);
pub struct PpuStatus(u8);

impl PpuStatus {
pub fn set_sp_overflow(&self, b: bool) {
self.0.set(*self.0.get().set_bit(5, b));
pub fn set_sp_overflow(&mut self, b: bool) {
self.0.set_bit(5, b);
}

pub fn set_sp0_hit(&self, b: bool) {
self.0.set(*self.0.get().set_bit(6, b));
pub fn set_sp0_hit(&mut self, b: bool) {
self.0.set_bit(6, b);
}

pub fn set_vblank(&self, b: bool) {
self.0.set(*self.0.get().set_bit(7, b));
pub fn set_vblank(&mut self, b: bool) {
self.0.set_bit(7, b);
}

pub fn get(&self) -> u8 {
self.0.get()
self.0
}
}

Expand All @@ -118,28 +117,27 @@ const VY_MASK: u16 = 0b0111_1011_1110_0000;

/// PPU vram address
#[derive(Debug, Default, Clone)]
pub struct VramAddr(Cell<u16>);
pub struct VramAddr(u16);

impl VramAddr {
pub fn addr(&self) -> u16 {
self.0.get().get_bits(0x00..0x0e)
self.0.get_bits(0x00..0x0e)
}

pub fn tile_addr(&self) -> u16 {
let v = self.0.get();
0x2000 | (v & 0x0fff)
0x2000 | (self.0 & 0x0fff)
}

pub fn attr_addr(&self) -> u16 {
let v = self.0.get();
let v = self.0;
0x23C0 | (v & 0x0c00) | ((v >> 4) & 0x38) | ((v >> 2) & 0x07)
}

pub fn inc(&self, offset: u16) {
self.0.set(self.0.get() + offset);
pub fn inc(&mut self, offset: u16) {
self.0 += offset;
}

pub fn inc_coarse_x(&self) {
pub fn inc_coarse_x(&mut self) {
let cx = self.coarse_x();
if cx == 31 {
self.set_coarse_x(0);
Expand All @@ -149,7 +147,7 @@ impl VramAddr {
}
}

pub fn inc_y(&self) {
pub fn inc_y(&mut self) {
let y = self.y();
if y < 7 {
self.set_y(y + 1);
Expand All @@ -168,55 +166,55 @@ impl VramAddr {
}

pub fn coarse_x(&self) -> u16 {
self.0.get().get_bits(0x00..0x05)
self.0.get_bits(0x00..0x05)
}

pub fn set_coarse_x(&self, b: u16) {
self.0.set(*self.0.get().set_bits(0x00..0x05, b));
pub fn set_coarse_x(&mut self, b: u16) {
self.0.set_bits(0x00..0x05, b);
}

pub fn coarse_y(&self) -> u16 {
self.0.get().get_bits(0x05..0x0a)
self.0.get_bits(0x05..0x0a)
}

pub fn set_coarse_y(&self, b: u16) {
self.0.set(*self.0.get().set_bits(0x05..0x0a, b));
pub fn set_coarse_y(&mut self, b: u16) {
self.0.set_bits(0x05..0x0a, b);
}

pub fn nm(&self) -> u16 {
self.0.get().get_bits(0x0a..0x0c)
self.0.get_bits(0x0a..0x0c)
}

pub fn set_nm(&self, b: u16) {
self.0.set(*self.0.get().set_bits(0x0a..0x0c, b));
pub fn set_nm(&mut self, b: u16) {
self.0.set_bits(0x0a..0x0c, b);
}

pub fn switch_nm(&self, b: u16) {
pub fn switch_nm(&mut self, b: u16) {
self.set_nm(self.nm() ^ b);
}

pub fn y(&self) -> u16 {
self.0.get().get_bits(0x0c..0x0f)
self.0.get_bits(0x0c..0x0f)
}

pub fn set_y(&self, b: u16) {
self.0.set(*self.0.get().set_bits(0x0c..0x0f, b));
pub fn set_y(&mut self, b: u16) {
self.0.set_bits(0x0c..0x0f, b);
}

pub fn set_bits<T: std::ops::RangeBounds<usize>>(&self, range: T, b: u16) {
self.0.set(*self.0.get().set_bits(range, b));
pub fn set_bits<T: std::ops::RangeBounds<usize>>(&mut self, range: T, b: u16) {
self.0.set_bits(range, b);
}

pub fn copy_vx(&self, other: &VramAddr) {
let v0 = self.0.get();
let v1 = other.0.get();
self.0.set((v0 & !VX_MASK) | (v1 & VX_MASK));
pub fn copy_vx(&mut self, other: &VramAddr) {
let v0 = self.0;
let v1 = other.0;
self.0 = (v0 & !VX_MASK) | (v1 & VX_MASK);
}

pub fn copy_vy(&self, other: &VramAddr) {
let v0 = self.0.get();
let v1 = other.0.get();
self.0.set((v0 & !VY_MASK) | (v1 & VY_MASK));
pub fn copy_vy(&mut self, other: &VramAddr) {
let v0 = self.0;
let v1 = other.0;
self.0 = (v0 & !VY_MASK) | (v1 & VY_MASK);
}
}

Expand Down

0 comments on commit f57a59c

Please sign in to comment.