feat: create timer struct and stub 0xff07

This commit is contained in:
Rekai Nyangadzayi Musuka 2021-01-03 01:21:19 -06:00 committed by Rekai Musuka
parent 911f0f9c86
commit e693ad8a3c
3 changed files with 80 additions and 2 deletions

View File

@ -1,5 +1,6 @@
use super::cartridge::Cartridge; use super::cartridge::Cartridge;
use super::ppu::PPU; use super::ppu::PPU;
use super::timer::Timer;
use super::work_ram::{VariableWorkRAM, WorkRAM}; use super::work_ram::{VariableWorkRAM, WorkRAM};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Bus { pub struct Bus {
@ -8,6 +9,7 @@ pub struct Bus {
ppu: PPU, ppu: PPU,
wram: WorkRAM, wram: WorkRAM,
vwram: VariableWorkRAM, vwram: VariableWorkRAM,
timer: Timer,
} }
impl Default for Bus { impl Default for Bus {
@ -18,6 +20,7 @@ impl Default for Bus {
ppu: Default::default(), ppu: Default::default(),
wram: Default::default(), wram: Default::default(),
vwram: Default::default(), vwram: Default::default(),
timer: Default::default(),
} }
} }
} }
@ -86,7 +89,10 @@ impl Bus {
0xFEA0..=0xFEFF => unimplemented!("{:#06X} is not allowed to be used", addr), 0xFEA0..=0xFEFF => unimplemented!("{:#06X} is not allowed to be used", addr),
0xFF00..=0xFF7F => { 0xFF00..=0xFF7F => {
// IO Registers // IO Registers
unimplemented!("Unable to read {:#06X} in I/O Registers", addr); match addr {
0xFF07 => self.timer.control.into(),
_ => unimplemented!("Unable to read {:#06X} in I/O Registers", addr),
}
} }
0xFF80..=0xFFFE => { 0xFF80..=0xFFFE => {
// High RAM // High RAM
@ -139,7 +145,10 @@ impl Bus {
0xFEA0..=0xFEFF => unimplemented!("{:#06X} is not allowed to be used", addr), 0xFEA0..=0xFEFF => unimplemented!("{:#06X} is not allowed to be used", addr),
0xFF00..=0xFF7F => { 0xFF00..=0xFF7F => {
// IO Registers // IO Registers
unimplemented!("Unable to write to {:#06X} in I/O Registers", addr); match addr {
0xFF07 => self.timer.control = byte.into(),
_ => unimplemented!("Unable to write to {:#06X} in I/O Registers", addr),
};
} }
0xFF80..=0xFFFE => { 0xFF80..=0xFFFE => {
// High RAM // High RAM

View File

@ -3,4 +3,5 @@ mod cartridge;
pub mod cpu; pub mod cpu;
mod instruction; mod instruction;
mod ppu; mod ppu;
mod timer;
mod work_ram; mod work_ram;

68
src/timer.rs Normal file
View File

@ -0,0 +1,68 @@
#[derive(Debug, Clone, Copy)]
pub struct Timer {
pub control: TimerControl,
}
impl Default for Timer {
fn default() -> Self {
Self {
control: 0x00.into(),
}
}
}
#[derive(Debug, Clone, Copy)]
enum TimerSpeed {
Freq4096Hz,
Freq262144Hz,
Freq65536Hz,
Freq16384Hz,
}
impl From<u8> for TimerSpeed {
fn from(byte: u8) -> Self {
match byte {
0x00 => Self::Freq4096Hz,
0x01 => Self::Freq262144Hz,
0x10 => Self::Freq65536Hz,
0x11 => Self::Freq16384Hz,
_ => unreachable!(),
}
}
}
impl From<TimerSpeed> for u8 {
fn from(speed: TimerSpeed) -> Self {
match speed {
TimerSpeed::Freq4096Hz => 0x00,
TimerSpeed::Freq262144Hz => 0x01,
TimerSpeed::Freq65536Hz => 0x10,
TimerSpeed::Freq16384Hz => 0x11,
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct TimerControl {
enabled: bool,
speed: TimerSpeed,
}
impl From<u8> for TimerControl {
fn from(byte: u8) -> Self {
let byte = byte & 0x07; // Clear everything but last 3 bits
Self {
enabled: (byte >> 2) == 0x01,
speed: (byte & 0x03).into(), // Clear everything but last 2 bits
}
}
}
impl From<TimerControl> for u8 {
fn from(control: TimerControl) -> Self {
let byte: u8 = control.speed.into(); // Get bit 1 and 0.
(byte & !(1u8 << 2)) | ((control.enabled as u8) << 2) // specifically manibulate bit 2
}
}