feat: create timer struct and stub 0xff07
This commit is contained in:
parent
911f0f9c86
commit
e693ad8a3c
13
src/bus.rs
13
src/bus.rs
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue