chore: improve code quality
This commit is contained in:
parent
1da01a318d
commit
68c9557c43
15
src/bus.rs
15
src/bus.rs
|
@ -1,9 +1,9 @@
|
||||||
use crate::instruction::Cycles;
|
|
||||||
|
|
||||||
use super::cartridge::Cartridge;
|
use super::cartridge::Cartridge;
|
||||||
use super::high_ram::HighRAM;
|
use super::high_ram::HighRAM;
|
||||||
|
use super::instruction::Cycles;
|
||||||
use super::interrupt::Interrupt;
|
use super::interrupt::Interrupt;
|
||||||
use super::ppu::PPU;
|
use super::ppu::PPU;
|
||||||
|
use super::serial::Serial;
|
||||||
use super::sound::Sound;
|
use super::sound::Sound;
|
||||||
use super::timer::Timer;
|
use super::timer::Timer;
|
||||||
use super::work_ram::{VariableWorkRAM, WorkRAM};
|
use super::work_ram::{VariableWorkRAM, WorkRAM};
|
||||||
|
@ -19,12 +19,13 @@ pub struct Bus {
|
||||||
interrupt: Interrupt,
|
interrupt: Interrupt,
|
||||||
sound: Sound,
|
sound: Sound,
|
||||||
hram: HighRAM,
|
hram: HighRAM,
|
||||||
|
serial: Serial,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Bus {
|
impl Default for Bus {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
boot: Some(include_bytes!("../bin/DMG_ROM.bin").to_owned()),
|
boot: None,
|
||||||
cartridge: None,
|
cartridge: None,
|
||||||
ppu: Default::default(),
|
ppu: Default::default(),
|
||||||
wram: Default::default(),
|
wram: Default::default(),
|
||||||
|
@ -33,18 +34,15 @@ impl Default for Bus {
|
||||||
interrupt: Default::default(),
|
interrupt: Default::default(),
|
||||||
sound: Default::default(),
|
sound: Default::default(),
|
||||||
hram: Default::default(),
|
hram: Default::default(),
|
||||||
|
serial: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Bus {
|
impl Bus {
|
||||||
pub fn with_boot() -> Self {
|
pub fn with_boot() -> Self {
|
||||||
Default::default()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn without_boot() -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
boot: None,
|
boot: Some(include_bytes!("../bin/DMG_ROM.bin").to_owned()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -108,6 +106,7 @@ impl Bus {
|
||||||
0xFF00..=0xFF7F => {
|
0xFF00..=0xFF7F => {
|
||||||
// IO Registers
|
// IO Registers
|
||||||
match addr {
|
match addr {
|
||||||
|
// 0xFF01 =>
|
||||||
0xFF07 => self.timer.control.into(),
|
0xFF07 => self.timer.control.into(),
|
||||||
0xFF0F => self.interrupt.flag.into(),
|
0xFF0F => self.interrupt.flag.into(),
|
||||||
0xFF11 => self.sound.ch1.sound_duty.into(),
|
0xFF11 => self.sound.ch1.sound_duty.into(),
|
||||||
|
|
20
src/cpu.rs
20
src/cpu.rs
|
@ -14,12 +14,7 @@ pub struct Cpu {
|
||||||
|
|
||||||
impl Cpu {
|
impl Cpu {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Default::default()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_without_boot() -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
bus: Bus::without_boot(),
|
|
||||||
reg: Registers {
|
reg: Registers {
|
||||||
a: 0x01,
|
a: 0x01,
|
||||||
b: 0x00,
|
b: 0x00,
|
||||||
|
@ -36,6 +31,13 @@ impl Cpu {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn boot_new() -> Self {
|
||||||
|
Self {
|
||||||
|
bus: Bus::with_boot(),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn ime(&self) -> bool {
|
pub fn ime(&self) -> bool {
|
||||||
self.ime
|
self.ime
|
||||||
}
|
}
|
||||||
|
@ -74,10 +76,10 @@ impl Cpu {
|
||||||
let instr = self.decode(opcode);
|
let instr = self.decode(opcode);
|
||||||
let cycles = self.execute(instr);
|
let cycles = self.execute(instr);
|
||||||
|
|
||||||
println!(
|
// println!(
|
||||||
"Addr: {:#06X} | Opcode: {:#04X} | Instr: {:X?}",
|
// "Addr: {:#06X} | Opcode: {:#04X} | Instr: {:X?}",
|
||||||
self.reg.pc, opcode, instr
|
// self.reg.pc, opcode, instr
|
||||||
);
|
// );
|
||||||
|
|
||||||
self.bus.step(cycles);
|
self.bus.step(cycles);
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ mod high_ram;
|
||||||
mod instruction;
|
mod instruction;
|
||||||
mod interrupt;
|
mod interrupt;
|
||||||
mod ppu;
|
mod ppu;
|
||||||
|
mod serial;
|
||||||
mod sound;
|
mod sound;
|
||||||
mod timer;
|
mod timer;
|
||||||
mod work_ram;
|
mod work_ram;
|
||||||
|
|
|
@ -19,7 +19,7 @@ fn main() -> Result<()> {
|
||||||
let mut input = WinitInputHelper::new();
|
let mut input = WinitInputHelper::new();
|
||||||
let window = create_window(&event_loop)?;
|
let window = create_window(&event_loop)?;
|
||||||
let mut pixels = create_pixels(&window)?;
|
let mut pixels = create_pixels(&window)?;
|
||||||
let mut game_boy = LR35902::new();
|
let mut game_boy = LR35902::boot_new();
|
||||||
game_boy.load_cartridge("bin/cpu_instrs.gb");
|
game_boy.load_cartridge("bin/cpu_instrs.gb");
|
||||||
|
|
||||||
event_loop.run(move |event, _, control_flow| {
|
event_loop.run(move |event, _, control_flow| {
|
||||||
|
|
27
src/ppu.rs
27
src/ppu.rs
|
@ -178,10 +178,10 @@ impl From<LCDControl> for u8 {
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
enum GrayShade {
|
enum GrayShade {
|
||||||
White,
|
White = 0,
|
||||||
LightGray,
|
LightGray = 1,
|
||||||
DarkGray,
|
DarkGray = 2,
|
||||||
Black,
|
Black = 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for GrayShade {
|
impl Default for GrayShade {
|
||||||
|
@ -202,17 +202,6 @@ impl From<u8> for GrayShade {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<GrayShade> for u8 {
|
|
||||||
fn from(shade: GrayShade) -> Self {
|
|
||||||
match shade {
|
|
||||||
GrayShade::White => 0b00,
|
|
||||||
GrayShade::LightGray => 0b01,
|
|
||||||
GrayShade::DarkGray => 0b10,
|
|
||||||
GrayShade::Black => 0b11,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Default)]
|
#[derive(Debug, Clone, Copy, Default)]
|
||||||
pub struct BackgroundPalette {
|
pub struct BackgroundPalette {
|
||||||
color3: GrayShade,
|
color3: GrayShade,
|
||||||
|
@ -234,10 +223,10 @@ impl From<u8> for BackgroundPalette {
|
||||||
|
|
||||||
impl From<BackgroundPalette> for u8 {
|
impl From<BackgroundPalette> for u8 {
|
||||||
fn from(palette: BackgroundPalette) -> Self {
|
fn from(palette: BackgroundPalette) -> Self {
|
||||||
let color0: u8 = palette.color0.into();
|
let color0: u8 = palette.color0 as u8;
|
||||||
let color1: u8 = palette.color1.into();
|
let color1: u8 = palette.color1 as u8;
|
||||||
let color2: u8 = palette.color2.into();
|
let color2: u8 = palette.color2 as u8;
|
||||||
let color3: u8 = palette.color0.into();
|
let color3: u8 = palette.color0 as u8;
|
||||||
|
|
||||||
color3 << 6 | color2 << 4 | color1 << 2 | color0
|
color3 << 6 | color2 << 4 | color1 << 2 | color0
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
#[derive(Debug, Clone, Copy, Default)]
|
||||||
|
pub struct Serial {
|
||||||
|
next: u8,
|
||||||
|
control: SerialControl,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, Default)]
|
||||||
|
pub struct SerialControl {
|
||||||
|
transfer_start: bool,
|
||||||
|
speed: ClockSpeed, // CGB Only
|
||||||
|
shift: ShiftClock,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<u8> for SerialControl {
|
||||||
|
fn from(byte: u8) -> Self {
|
||||||
|
Self {
|
||||||
|
transfer_start: byte >> 7 == 0x01,
|
||||||
|
speed: ((byte >> 1) & 0x01).into(),
|
||||||
|
shift: (byte & 0x01).into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<SerialControl> for u8 {
|
||||||
|
fn from(control: SerialControl) -> Self {
|
||||||
|
(control.transfer_start as u8) << 7 | (control.speed as u8) << 1 | control.shift as u8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
enum ShiftClock {
|
||||||
|
External = 0,
|
||||||
|
Internal = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ShiftClock {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::External
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<u8> for ShiftClock {
|
||||||
|
fn from(byte: u8) -> Self {
|
||||||
|
match byte {
|
||||||
|
0b00 => Self::External,
|
||||||
|
0b01 => Self::Internal,
|
||||||
|
_ => unreachable!("{:#04X} is not a valid value for ShiftClock", byte),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
enum ClockSpeed {
|
||||||
|
Normal = 0,
|
||||||
|
Fast = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ClockSpeed {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::Normal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<u8> for ClockSpeed {
|
||||||
|
fn from(byte: u8) -> Self {
|
||||||
|
match byte {
|
||||||
|
0b00 => Self::Normal,
|
||||||
|
0b01 => Self::Fast,
|
||||||
|
_ => unreachable!("{:#04X} is not a valid value for ClockSpeed", byte),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
56
src/sound.rs
56
src/sound.rs
|
@ -29,8 +29,8 @@ pub struct Frequency {
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
enum FrequencyType {
|
enum FrequencyType {
|
||||||
Counter,
|
Counter = 0,
|
||||||
Consequtive,
|
Consequtive = 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<u8> for FrequencyType {
|
impl From<u8> for FrequencyType {
|
||||||
|
@ -43,15 +43,6 @@ impl From<u8> for FrequencyType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<FrequencyType> for u8 {
|
|
||||||
fn from(freq_type: FrequencyType) -> Self {
|
|
||||||
match freq_type {
|
|
||||||
FrequencyType::Counter => 0b00,
|
|
||||||
FrequencyType::Consequtive => 0b01,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for FrequencyType {
|
impl Default for FrequencyType {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::Counter
|
Self::Counter
|
||||||
|
@ -142,7 +133,7 @@ impl From<u8> for VolumeEnvelope {
|
||||||
|
|
||||||
impl From<VolumeEnvelope> for u8 {
|
impl From<VolumeEnvelope> for u8 {
|
||||||
fn from(envelope: VolumeEnvelope) -> Self {
|
fn from(envelope: VolumeEnvelope) -> Self {
|
||||||
let dir_bit: u8 = envelope.direction.into();
|
let dir_bit: u8 = envelope.direction as u8;
|
||||||
let mut byte = envelope.init_vol << 4;
|
let mut byte = envelope.init_vol << 4;
|
||||||
byte |= dir_bit << 3;
|
byte |= dir_bit << 3;
|
||||||
byte |= envelope.sweep_count;
|
byte |= envelope.sweep_count;
|
||||||
|
@ -152,8 +143,8 @@ impl From<VolumeEnvelope> for u8 {
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
enum EnvelopeDirection {
|
enum EnvelopeDirection {
|
||||||
Decrease,
|
Decrease = 0,
|
||||||
Increase,
|
Increase = 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<u8> for EnvelopeDirection {
|
impl From<u8> for EnvelopeDirection {
|
||||||
|
@ -161,23 +152,17 @@ impl From<u8> for EnvelopeDirection {
|
||||||
match byte {
|
match byte {
|
||||||
0b00 => Self::Decrease,
|
0b00 => Self::Decrease,
|
||||||
0b01 => Self::Increase,
|
0b01 => Self::Increase,
|
||||||
_ => unreachable!("{:#04X} is not a possible value for EnvelopeDirection"),
|
_ => unreachable!(
|
||||||
}
|
"{:#04X} is not a possible value for EnvelopeDirection",
|
||||||
}
|
byte
|
||||||
}
|
),
|
||||||
|
|
||||||
impl From<EnvelopeDirection> for u8 {
|
|
||||||
fn from(envelope: EnvelopeDirection) -> Self {
|
|
||||||
match envelope {
|
|
||||||
EnvelopeDirection::Decrease => 0b00,
|
|
||||||
EnvelopeDirection::Increase => 0b01,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for EnvelopeDirection {
|
impl Default for EnvelopeDirection {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::Decrease // Reasoning: Decrease is 0
|
Self::Decrease
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,7 +186,7 @@ impl From<u8> for SoundDuty {
|
||||||
|
|
||||||
impl From<SoundDuty> for u8 {
|
impl From<SoundDuty> for u8 {
|
||||||
fn from(duty: SoundDuty) -> Self {
|
fn from(duty: SoundDuty) -> Self {
|
||||||
let mut byte: u8 = duty.wave_pattern.into();
|
let mut byte: u8 = duty.wave_pattern as u8;
|
||||||
byte = (byte << 6) | duty.sound_length;
|
byte = (byte << 6) | duty.sound_length;
|
||||||
byte
|
byte
|
||||||
}
|
}
|
||||||
|
@ -209,10 +194,10 @@ impl From<SoundDuty> for u8 {
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum WaveDuty {
|
pub enum WaveDuty {
|
||||||
OneEighth, // 12.5% ( _-------_-------_------- )
|
OneEighth = 0, // 12.5% ( _-------_-------_------- )
|
||||||
OneQuarter, // 25% ( __------__------__------ )
|
OneQuarter = 1, // 25% ( __------__------__------ )
|
||||||
OneHalf, // 50% ( ____----____----____---- ) (normal)
|
OneHalf = 2, // 50% ( ____----____----____---- ) (normal)
|
||||||
ThreeQuarters, // 75% ( ______--______--______-- )
|
ThreeQuarters = 3, // 75% ( ______--______--______-- )
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for WaveDuty {
|
impl Default for WaveDuty {
|
||||||
|
@ -221,17 +206,6 @@ impl Default for WaveDuty {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<WaveDuty> for u8 {
|
|
||||||
fn from(wave: WaveDuty) -> Self {
|
|
||||||
match wave {
|
|
||||||
WaveDuty::OneEighth => 0b00,
|
|
||||||
WaveDuty::OneQuarter => 0b01,
|
|
||||||
WaveDuty::OneHalf => 0b10,
|
|
||||||
WaveDuty::ThreeQuarters => 0b11,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<u8> for WaveDuty {
|
impl From<u8> for WaveDuty {
|
||||||
fn from(byte: u8) -> Self {
|
fn from(byte: u8) -> Self {
|
||||||
match byte {
|
match byte {
|
||||||
|
|
21
src/timer.rs
21
src/timer.rs
|
@ -21,10 +21,10 @@ impl Default for Timer {
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
enum TimerSpeed {
|
enum TimerSpeed {
|
||||||
Freq4096Hz,
|
Freq4096Hz = 0,
|
||||||
Freq262144Hz,
|
Freq262144Hz = 1,
|
||||||
Freq65536Hz,
|
Freq65536Hz = 2,
|
||||||
Freq16384Hz,
|
Freq16384Hz = 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<u8> for TimerSpeed {
|
impl From<u8> for TimerSpeed {
|
||||||
|
@ -39,17 +39,6 @@ impl From<u8> for TimerSpeed {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct TimerControl {
|
pub struct TimerControl {
|
||||||
enabled: bool,
|
enabled: bool,
|
||||||
|
@ -69,7 +58,7 @@ impl From<u8> for TimerControl {
|
||||||
|
|
||||||
impl From<TimerControl> for u8 {
|
impl From<TimerControl> for u8 {
|
||||||
fn from(control: TimerControl) -> Self {
|
fn from(control: TimerControl) -> Self {
|
||||||
let byte: u8 = control.speed.into(); // Get bit 1 and 0.
|
let byte: u8 = control.speed as u8; // Get bit 1 and 0.
|
||||||
|
|
||||||
(byte & !(1u8 << 2)) | ((control.enabled as u8) << 2) // specifically manibulate bit 2
|
(byte & !(1u8 << 2)) | ((control.enabled as u8) << 2) // specifically manibulate bit 2
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,27 +23,13 @@ impl Default for WorkRAM {
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum BankNumber {
|
pub enum BankNumber {
|
||||||
One,
|
One = 1,
|
||||||
Two,
|
Two = 2,
|
||||||
Three,
|
Three = 3,
|
||||||
Four,
|
Four = 4,
|
||||||
Five,
|
Five = 5,
|
||||||
Six,
|
Six = 6,
|
||||||
Seven,
|
Seven = 7,
|
||||||
}
|
|
||||||
|
|
||||||
impl From<BankNumber> for usize {
|
|
||||||
fn from(bank_num: BankNumber) -> Self {
|
|
||||||
match bank_num {
|
|
||||||
BankNumber::One => 1,
|
|
||||||
BankNumber::Two => 2,
|
|
||||||
BankNumber::Three => 3,
|
|
||||||
BankNumber::Four => 4,
|
|
||||||
BankNumber::Five => 5,
|
|
||||||
BankNumber::Six => 6,
|
|
||||||
BankNumber::Seven => 7,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -71,12 +57,10 @@ impl VariableWorkRAM {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_byte(&mut self, index: usize, byte: u8) {
|
pub fn write_byte(&mut self, index: usize, byte: u8) {
|
||||||
let num: usize = self.current.into();
|
self.bank_n[self.current as usize][index] = byte;
|
||||||
self.bank_n[num][index] = byte;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_byte(&self, index: usize) -> u8 {
|
pub fn read_byte(&self, index: usize) -> u8 {
|
||||||
let num: usize = self.current.into();
|
self.bank_n[self.current as usize][index]
|
||||||
self.bank_n[num][index]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue