Compare commits
2 Commits
a77d0a0f62
...
aa22e93049
Author | SHA1 | Date |
---|---|---|
Rekai Nyangadzayi Musuka | aa22e93049 | |
Rekai Nyangadzayi Musuka | 6215eccb2f |
|
@ -164,8 +164,7 @@ impl Apu {
|
||||||
|
|
||||||
if self.ctrl.enabled {
|
if self.ctrl.enabled {
|
||||||
// Frame Sequencer reset to Step 0
|
// Frame Sequencer reset to Step 0
|
||||||
// TODO: With the current implementation of the frame sequencer,
|
// TODO: With the current implementation of the frame sequencer, what does this even mean?
|
||||||
// what does this even mean?
|
|
||||||
|
|
||||||
// Square Duty units are reset to first step
|
// Square Duty units are reset to first step
|
||||||
self.ch1.duty_pos = 0;
|
self.ch1.duty_pos = 0;
|
||||||
|
@ -181,8 +180,6 @@ impl Apu {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reset(&mut self) {
|
fn reset(&mut self) {
|
||||||
// TODO: Clear readable sound registers
|
|
||||||
|
|
||||||
self.ch1.sweep = Default::default();
|
self.ch1.sweep = Default::default();
|
||||||
self.ch1.duty = Default::default();
|
self.ch1.duty = Default::default();
|
||||||
self.ch1.envelope = Default::default();
|
self.ch1.envelope = Default::default();
|
||||||
|
@ -426,7 +423,6 @@ impl Channel1 {
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.freq_timer == 0 {
|
if self.freq_timer == 0 {
|
||||||
// TODO: Why is this 2048?
|
|
||||||
self.freq_timer = (2048 - self.frequency()) * 4;
|
self.freq_timer = (2048 - self.frequency()) * 4;
|
||||||
self.duty_pos = (self.duty_pos + 1) % 8;
|
self.duty_pos = (self.duty_pos + 1) % 8;
|
||||||
}
|
}
|
||||||
|
@ -572,7 +568,6 @@ impl Channel2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.freq_timer == 0 {
|
if self.freq_timer == 0 {
|
||||||
// TODO: Why is this 2048?
|
|
||||||
self.freq_timer = (2048 - self.frequency()) * 4;
|
self.freq_timer = (2048 - self.frequency()) * 4;
|
||||||
self.duty_pos = (self.duty_pos + 1) % 8;
|
self.duty_pos = (self.duty_pos + 1) % 8;
|
||||||
}
|
}
|
||||||
|
|
|
@ -178,7 +178,7 @@ pub(crate) mod ch4 {
|
||||||
pub struct Frequency(u8);
|
pub struct Frequency(u8);
|
||||||
impl Debug;
|
impl Debug;
|
||||||
_initial, _: 7;
|
_initial, _: 7;
|
||||||
_length_disable, _: 6; // TODO: same as FrequencyHigh, figure out what this is
|
_length_disable, _: 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Frequency {
|
impl Frequency {
|
||||||
|
@ -224,7 +224,7 @@ pub(crate) mod common {
|
||||||
pub struct FrequencyHigh(u8);
|
pub struct FrequencyHigh(u8);
|
||||||
impl Debug;
|
impl Debug;
|
||||||
_initial, _: 7;
|
_initial, _: 7;
|
||||||
_length_disable, _: 6; // TODO: Figure out what the hell this is
|
_length_disable, _: 6;
|
||||||
pub freq_bits, set_freq_bits: 2, 0;
|
pub freq_bits, set_freq_bits: 2, 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,7 +342,7 @@ pub(crate) mod common {
|
||||||
pub struct SoundDuty(u8);
|
pub struct SoundDuty(u8);
|
||||||
impl Debug;
|
impl Debug;
|
||||||
from into WavePattern, _wave_pattern, _: 7, 6;
|
from into WavePattern, _wave_pattern, _: 7, 6;
|
||||||
_sound_length, _: 5, 0; // TODO: Getter only used if bit 6 in NR14 is set
|
_sound_length, _: 5, 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SoundDuty {
|
impl SoundDuty {
|
||||||
|
|
|
@ -240,7 +240,6 @@ impl BusIo for Bus {
|
||||||
0x49 => self.ppu.monochrome.obj_palette_1.into(),
|
0x49 => self.ppu.monochrome.obj_palette_1.into(),
|
||||||
0x4A => self.ppu.pos.window_y,
|
0x4A => self.ppu.pos.window_y,
|
||||||
0x4B => self.ppu.pos.window_x,
|
0x4B => self.ppu.pos.window_x,
|
||||||
0x4D => 0xFF, // TODO: CGB Specific Register
|
|
||||||
_ => {
|
_ => {
|
||||||
eprintln!("Read 0xFF from unused IO register {:#06X}.", addr);
|
eprintln!("Read 0xFF from unused IO register {:#06X}.", addr);
|
||||||
0xFF
|
0xFF
|
||||||
|
@ -312,7 +311,7 @@ impl BusIo for Bus {
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
0xFEA0..=0xFEFF => {} // TODO: As far as I know, writes to here do nothing.
|
0xFEA0..=0xFEFF => {} // FIXME: As far as I know, writes to here do nothing.
|
||||||
0xFF00..=0xFF7F => {
|
0xFF00..=0xFF7F => {
|
||||||
// IO Registers
|
// IO Registers
|
||||||
|
|
||||||
|
|
|
@ -114,10 +114,7 @@ impl Cartridge {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_mbc(memory: &[u8]) -> MBCKind {
|
fn find_mbc(memory: &[u8]) -> MBCKind {
|
||||||
let id = memory[MBC_TYPE_ADDRESS];
|
match memory[MBC_TYPE_ADDRESS] {
|
||||||
|
|
||||||
// TODO: Refactor this to match the other enums in this module
|
|
||||||
match id {
|
|
||||||
0x00 => MBCKind::None,
|
0x00 => MBCKind::None,
|
||||||
0x01 => MBCKind::MBC1,
|
0x01 => MBCKind::MBC1,
|
||||||
0x02 => MBCKind::MBC1,
|
0x02 => MBCKind::MBC1,
|
||||||
|
@ -125,7 +122,7 @@ impl Cartridge {
|
||||||
0x19 => MBCKind::MBC5,
|
0x19 => MBCKind::MBC5,
|
||||||
0x13 => MBCKind::MBC3WithBattery,
|
0x13 => MBCKind::MBC3WithBattery,
|
||||||
0x11 => MBCKind::MBC3,
|
0x11 => MBCKind::MBC3,
|
||||||
_ => unimplemented!("id {:#04X} is an unsupported MBC", id),
|
id => unimplemented!("id {:#04X} is an unsupported MBC", id),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
36
src/cpu.rs
36
src/cpu.rs
|
@ -14,8 +14,6 @@ pub struct Cpu {
|
||||||
reg: Registers,
|
reg: Registers,
|
||||||
flags: Flags,
|
flags: Flags,
|
||||||
ime: ImeState,
|
ime: ImeState,
|
||||||
// TODO: Merge halted and state properties
|
|
||||||
halted: Option<HaltKind>,
|
|
||||||
state: State,
|
state: State,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,24 +43,34 @@ impl Cpu {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn ime(&self) -> &ImeState {
|
pub(crate) fn ime(&self) -> ImeState {
|
||||||
&self.ime
|
self.ime
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn set_ime(&mut self, state: ImeState) {
|
pub(crate) fn set_ime(&mut self, state: ImeState) {
|
||||||
self.ime = state;
|
self.ime = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn halt(&mut self, state: HaltKind) {
|
pub(crate) fn halt_cpu(&mut self, kind: HaltKind) {
|
||||||
self.halted = Some(state);
|
self.state = State::Halt(kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resume(&mut self) {
|
fn resume_execution(&mut self) {
|
||||||
self.halted = None;
|
self.state = State::Execute;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn halted(&self) -> Option<HaltKind> {
|
pub(crate) fn is_halted(&self) -> bool {
|
||||||
self.halted
|
match self.state {
|
||||||
|
State::Halt(_) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn halt_kind(&self) -> Option<HaltKind> {
|
||||||
|
match self.state {
|
||||||
|
State::Halt(kind) => Some(kind),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_cartridge(&mut self, path: &str) -> std::io::Result<()> {
|
pub fn load_cartridge(&mut self, path: &str) -> std::io::Result<()> {
|
||||||
|
@ -119,7 +127,7 @@ impl Cpu {
|
||||||
return elapsed;
|
return elapsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(kind) = self.halted() {
|
if let Some(kind) = self.halt_kind() {
|
||||||
use HaltKind::*;
|
use HaltKind::*;
|
||||||
|
|
||||||
self.bus.clock();
|
self.bus.clock();
|
||||||
|
@ -192,7 +200,7 @@ impl Cpu {
|
||||||
let enable = self.int_enable();
|
let enable = self.int_enable();
|
||||||
|
|
||||||
// TODO: Ensure that this behaviour is correct
|
// TODO: Ensure that this behaviour is correct
|
||||||
if self.halted.is_some() {
|
if self.is_halted() {
|
||||||
// When we're here either a HALT with IME set or
|
// When we're here either a HALT with IME set or
|
||||||
// a HALT with IME not set and No pending Interrupts was called
|
// a HALT with IME not set and No pending Interrupts was called
|
||||||
|
|
||||||
|
@ -201,7 +209,7 @@ impl Cpu {
|
||||||
// nothing actually needs to be added here. This is just documentation
|
// nothing actually needs to be added here. This is just documentation
|
||||||
// since it's a bit weird why nothing is being done
|
// since it's a bit weird why nothing is being done
|
||||||
|
|
||||||
self.resume();
|
self.resume_execution();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,7 +272,7 @@ impl Cpu {
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
enum State {
|
enum State {
|
||||||
Execute,
|
Execute,
|
||||||
// Halt,
|
Halt(HaltKind),
|
||||||
// Stop,
|
// Stop,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -590,12 +590,12 @@ impl Instruction {
|
||||||
// HALT | Enter CPU low power consumption mode until interrupt occurs
|
// HALT | Enter CPU low power consumption mode until interrupt occurs
|
||||||
use HaltKind::*;
|
use HaltKind::*;
|
||||||
|
|
||||||
let kind = match *cpu.ime() {
|
let kind = match cpu.ime() {
|
||||||
ImeState::Enabled => ImeEnabled,
|
ImeState::Enabled => ImeEnabled,
|
||||||
_ if cpu.int_request() & cpu.int_enable() != 0 => SomePending,
|
_ if cpu.int_request() & cpu.int_enable() != 0 => SomePending,
|
||||||
_ => NonePending,
|
_ => NonePending,
|
||||||
};
|
};
|
||||||
cpu.halt(kind);
|
cpu.halt_cpu(kind);
|
||||||
Cycle::new(4)
|
Cycle::new(4)
|
||||||
}
|
}
|
||||||
Instruction::ADC(source) => match source {
|
Instruction::ADC(source) => match source {
|
||||||
|
|
18
src/main.rs
18
src/main.rs
|
@ -63,16 +63,16 @@ fn main() -> Result<()> {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Initialize Audio
|
// Initialize Audio
|
||||||
let spsc: AudioSPSC<f32> = Default::default();
|
// let spsc: AudioSPSC<f32> = Default::default();
|
||||||
let (prod, cons) = spsc.init();
|
// let (prod, cons) = spsc.init();
|
||||||
let (_stream, stream_handle) = OutputStream::try_default().expect("Initialized Audio");
|
// let (_stream, stream_handle) = OutputStream::try_default().expect("Initialized Audio");
|
||||||
let sink = Sink::try_new(&stream_handle)?;
|
// let sink = Sink::try_new(&stream_handle)?;
|
||||||
sink.append(cons);
|
// sink.append(cons);
|
||||||
game_boy.apu_mut().set_producer(prod);
|
// game_boy.apu_mut().set_producer(prod);
|
||||||
|
|
||||||
std::thread::spawn(move || {
|
// std::thread::spawn(move || {
|
||||||
sink.sleep_until_end();
|
// sink.sleep_until_end();
|
||||||
});
|
// });
|
||||||
|
|
||||||
let mut start = Instant::now();
|
let mut start = Instant::now();
|
||||||
let frame_time = Duration::from_secs_f64(1.0 / 59.73); // 59.73 Hz on Host
|
let frame_time = Duration::from_secs_f64(1.0 / 59.73); // 59.73 Hz on Host
|
||||||
|
|
Loading…
Reference in New Issue