Skip to content

Commit

Permalink
Timer
Browse files Browse the repository at this point in the history
  • Loading branch information
IsaacMarovitz committed Dec 14, 2023
1 parent 3dce172 commit b2c8e6f
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 3 deletions.
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ mod mode;
mod registers;
mod ppu;
mod serial;
mod timer;

pub const CLOCK_FREQUENCY: u32 = 4_194_304;
pub const STEP_TIME: u32 = 16;
Expand Down
11 changes: 9 additions & 2 deletions src/mmu.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
use bitflags::bitflags;
use crate::ppu::PPU;
use crate::timer::Timer;
use crate::mode::GBMode;
use crate::serial::Serial;

pub struct MMU {
rom: Vec<u8>,
pub ppu: PPU,
serial: Serial,
timer: Timer,
wram: [u8; 0x8000],
hram: [u8; 0x7F],
intf: Interrupts,
Expand All @@ -31,6 +33,7 @@ impl MMU {
rom,
ppu: PPU::new(mode),
serial: Serial::new(),
timer: Timer::new(),
wram: [0; 0x8000],
hram: [0; 0x7f],
intf: Interrupts::empty(),
Expand All @@ -40,6 +43,10 @@ impl MMU {
}

pub fn cycle(&mut self, cycles: u32) -> bool {
self.timer.cycle(cycles);
self.intf |= self.timer.interrupts;
self.timer.interrupts = Interrupts::empty();

let did_draw = self.ppu.cycle(cycles);
self.intf |= self.ppu.interrupts;
self.ppu.interrupts = Interrupts::empty();
Expand All @@ -65,6 +72,7 @@ impl MMU {
0xFF68..=0xFF6B => self.ppu.read(a),
0xFF80..=0xFFFE => self.hram[a as usize - 0xFF80],
0xFF01..=0xFF02 => self.serial.read(a),
0xFF04..=0xFF07 => self.timer.read(a),
0xFF0F => self.intf.bits(),
0xFF70 => self.wram_bank as u8,
0xFFFF => self.inte.bits(),
Expand All @@ -90,8 +98,7 @@ impl MMU {
// TODO: Joypad
0xFF00 => {},
0xFF01..=0xFF02 => self.serial.write(a, v),
// TODO: Timer
0xFF04..=0xFF07 => {},
0xFF04..=0xFF07 => self.timer.write(a, v),
// TODO: APU
0xFF10..=0xFF3F => {},
0xFF0F => self.intf = Interrupts::from_bits(v).unwrap(),
Expand Down
1 change: 0 additions & 1 deletion src/ppu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,6 @@ impl PPU {

// Location of Tile Attributes
let tile_address = tile_map_base + tile_index_y * 32 + tile_index_x;
// TODO: This seems to be returning the wrong value
let tile_index = self.read_ram0(tile_address);

// If we're using the secondary address mode,
Expand Down
88 changes: 88 additions & 0 deletions src/timer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
use crate::mmu::Interrupts;

pub struct Timer {
div: u8,
tima: u8,
tma: u8,
pub interrupts: Interrupts,
enabled: bool,
step: u32,
internal_count: u32,
internal_divider: u32
}

impl Timer {
pub fn new() -> Self {
Self {
div: 0x00,
tima: 0x00,
tma: 0x00,
interrupts: Interrupts::empty(),
enabled: false,
step: 256,
internal_count: 0,
internal_divider: 0
}
}

pub fn cycle(&mut self, cycles: u32) {
self.internal_divider += cycles;
while self.internal_divider >= 256 {
self.div = self.div.wrapping_add(1);
self.internal_divider -= 256;
}

if self.enabled {
self.internal_count += cycles;

while self.internal_count >= self.step {
self.tima = self.tima.wrapping_add(1);
if self.tima == 0x00 {
self.tima = self.tma;
self.interrupts |= Interrupts::TIMER;
}
self.internal_count -= self.step;
}
}
}

pub fn read(&self, a: u16) -> u8 {
match a {
0xFF04 => self.div,
0xFF05 => self.tima,
0xFF06 => self.tma,
0xFF07 => {
let mut v = 0xF8;
v |= if self.enabled { 0b0000_0100 } else { 0x00 };
v |= match self.step {
1024 => 1,
16 => 2,
64 => 3,
_ => panic!("Unknown timer step ({})!", self.step)
};

v
},
_ => panic!("Read to unsupported timer address ({:#06x})!", a),
}
}

pub fn write(&mut self, a: u16, v: u8) {
match a {
0xFF04 => self.div = 0x00,
0xFF05 => self.tima = v,
0xFF06 => self.tma = v,
0xFF07 => {
self.enabled = (v & 0b0000_0100) != 0;
self.step = match v & 0b0000_0011 {
0 => 1024,
1 => 16,
2 => 64,
3 => 256,
_ => panic!("Unknown timer step ({})!", v)
}
},
_ => panic!("Write to unsupported timer address ({:#06x})!", a),
}
}
}

0 comments on commit b2c8e6f

Please sign in to comment.