chore: small code-cleanup changes

This commit is contained in:
2021-10-20 02:48:44 -03:00
parent 999f661e6b
commit 293e5762c3
10 changed files with 245 additions and 71 deletions

View File

@@ -1,6 +1,7 @@
use crate::bus::BusIo;
use crate::emu::SM83_CLOCK_SPEED;
use gen::SampleProducer;
use tracing::warn;
use types::ch1::{Sweep, SweepDirection};
use types::ch3::Volume as Ch3Volume;
use types::ch4::{CounterWidth, Frequency as Ch4Frequency, PolynomialCounter};
@@ -54,7 +55,7 @@ impl BusIo for Apu {
0x26 => self.ctrl.status(self),
0x30..=0x3F => self.ch3.read_byte(addr),
_ => {
eprintln!("Read 0xFF from unused IO register {:#06X} [APU]", addr);
warn!("Attempted read from {:#06X}", addr);
0xFF
}
}
@@ -85,10 +86,7 @@ impl BusIo for Apu {
0x26 => self.set_status(byte),
0x30..=0x3F => self.ch3.write_byte(addr, byte),
_ if !self.ctrl.enabled => {}
_ => eprintln!(
"Wrote {:#04X} to unused IO register {:#06X} [APU]",
byte, addr
),
_ => warn!("Attempted write of {:#04X} to {:#06X}", byte, addr),
}
}
}

View File

@@ -1,3 +1,5 @@
use tracing::warn;
use crate::apu::Apu;
use crate::cartridge::Cartridge;
use crate::high_ram::HighRam;
@@ -14,7 +16,7 @@ pub(crate) const BOOT_SIZE: usize = 0x100;
pub struct Bus {
boot: Option<[u8; BOOT_SIZE]>, // Boot ROM is 256b long
cart: Option<Cartridge>,
pub(crate) ppu: Ppu,
ppu: Ppu,
work_ram: WorkRam,
var_ram: VariableWorkRam,
pub(crate) timer: Timer,
@@ -100,6 +102,11 @@ impl Bus {
pub(crate) fn cart_mut(&mut self) -> Option<&mut Cartridge> {
self.cart.as_mut()
}
#[inline]
pub fn ppu(&self) -> &Ppu {
&self.ppu
}
}
impl Bus {
@@ -251,7 +258,7 @@ impl BusIo for Bus {
0x4A => self.ppu.pos.window_y,
0x4B => self.ppu.pos.window_x,
_ => {
eprintln!("Read 0xFF from unused IO register {:#06X}.", addr);
warn!("Attempted read from {:#06X} on IO", addr);
0xFF
}
}
@@ -368,7 +375,7 @@ impl BusIo for Bus {
self.boot = None;
}
}
_ => eprintln!("Wrote {:#04X} to unused IO register {:#06X}.", byte, addr),
_ => warn!("Attempted write of {:#04X} to {:#06X} on IO", byte, addr),
};
}
0xFF80..=0xFFFE => {

View File

@@ -1,3 +1,5 @@
use tracing::{info, warn};
use crate::bus::BusIo;
const RAM_SIZE_ADDRESS: usize = 0x0149;
@@ -15,7 +17,7 @@ pub(crate) struct Cartridge {
impl Cartridge {
pub(crate) fn new(memory: Vec<u8>) -> Self {
let title = Self::find_title(&memory);
eprintln!("Cartridge Title: {:?}", title);
info!("Title: {:?}", title);
Self {
mbc: Self::detect_mbc(&memory),
@@ -39,20 +41,20 @@ impl Cartridge {
let ram_cap = ram_size.capacity();
let rom_cap = rom_size.capacity();
eprintln!("Cartridge Ram Size: {} bytes", ram_cap);
eprintln!("Cartridge ROM Size: {} bytes", rom_size.capacity());
eprintln!("MBC Type: {:?}", mbc_kind);
info!("RAM size: {} bytes", ram_cap);
info!("ROM size: {} bytes", rom_size.capacity());
info!("MBC kind: {:?}", mbc_kind);
match mbc_kind {
MBCKind::None => Box::new(NoMBC),
MBCKind::MBC1 => Box::new(MBC1::new(ram_size, rom_size)),
MBCKind::MBC1WithBattery => Box::new(MBC1::with_battery(ram_size, rom_size)), // TODO: Implement Saving
MBCKind::MBC1WithBattery => Box::new(MBC1::with_battery(ram_size, rom_size)),
MBCKind::MBC2 => Box::new(MBC2::new(rom_cap)),
MBCKind::MBC2WithBattery => Box::new(MBC2::with_battery(rom_cap)), // TODO: Implement Saving
MBCKind::MBC2WithBattery => Box::new(MBC2::with_battery(rom_cap)),
MBCKind::MBC3 => Box::new(MBC3::new(ram_cap)),
MBCKind::MBC3WithBattery => Box::new(MBC3::with_battery(ram_cap)), // TODO: Implement Saving
MBCKind::MBC3WithBattery => Box::new(MBC3::with_battery(ram_cap)),
MBCKind::MBC5 => Box::new(MBC5::new(ram_cap, rom_cap)),
MBCKind::MBC5WithBattery => Box::new(MBC5::with_battery(ram_cap, rom_cap)), // TDO: Implement Saving
MBCKind::MBC5WithBattery => Box::new(MBC5::with_battery(ram_cap, rom_cap)),
}
}
@@ -596,8 +598,8 @@ impl MBCIo for NoMBC {
MBCResult::Address(addr as usize)
}
fn handle_write(&mut self, _addr: u16, _byte: u8) {
// eprintln!("Tried to write {:#04X} to a read-only cartridge", byte);
fn handle_write(&mut self, _: u16, byte: u8) {
warn!("Attempted write of {:#04X} to cartridge w/out MBC", byte);
}
}

View File

@@ -7,7 +7,7 @@ use std::fmt::{Display, Formatter, Result as FmtResult};
#[derive(Debug, Default)]
pub struct Cpu {
pub bus: Bus,
pub(crate) bus: Bus,
reg: Registers,
flags: Flags,
ime: ImeState,
@@ -118,13 +118,10 @@ impl Cpu {
use HaltKind::*;
self.bus.clock();
let elapsed = match kind {
return match kind {
ImeEnabled | NonePending => 4,
SomePending => todo!("Implement HALT bug"),
};
return elapsed;
}
let opcode = self.fetch();
@@ -133,11 +130,11 @@ impl Cpu {
self.handle_ei();
// For use in Blargg's Test ROMs
if self.read_byte(0xFF02) == 0x81 {
let c = self.read_byte(0xFF01) as char;
self.write_byte(0xFF02, 0x00);
eprint!("{}", c);
}
// if self.read_byte(0xFF02) == 0x81 {
// let c = self.read_byte(0xFF01) as char;
// self.write_byte(0xFF02, 0x00);
// eprint!("{}", c);
// }
elapsed
}

View File

@@ -31,7 +31,7 @@ pub fn run_frame(emu: &mut Emulator, gamepad: &mut Gilrs, key: &WinitInputHelper
}
pub fn draw_frame(emu: &Emulator, buf: &mut [u8; GB_HEIGHT * GB_WIDTH * 4]) {
buf.copy_from_slice(emu.cpu.bus().ppu.frame_buf());
buf.copy_from_slice(emu.cpu.bus().ppu().frame_buf());
}
pub struct Emulator {
@@ -121,6 +121,8 @@ pub mod build {
use std::io::{Read, Result};
use std::path::Path;
use tracing::info;
use crate::bus::BOOT_SIZE;
use crate::cpu::Cpu;
@@ -159,8 +161,14 @@ pub mod build {
pub fn finish(mut self) -> Emulator {
let mut emu = Emulator::new(match self.boot {
Some(rom) => Cpu::with_boot(rom),
None => Cpu::with_boot(*include_bytes!("../bin/bootix_dmg.bin")),
Some(rom) => {
info!("User-provided Boot ROM");
Cpu::with_boot(rom)
}
None => {
info!("Built-in Boot ROM");
Cpu::with_boot(*include_bytes!("../bin/bootix_dmg.bin"))
}
});
if let Some(rom) = self.cart.take() {

View File

@@ -116,7 +116,7 @@ impl std::fmt::Debug for Instruction {
impl Instruction {
pub(crate) fn execute(cpu: &mut Cpu, instruction: Self) -> Cycle {
match instruction {
Instruction::NOP => (4),
Instruction::NOP => 4,
Instruction::LD(target, src) => match (target, src) {
(LDTarget::IndirectImmediateWord, LDSource::SP) => {
// LD (u16), SP | Store stack pointer in byte at 16-bit register
@@ -361,12 +361,12 @@ impl Instruction {
let (cycles, sum) = match reg {
B | C | D | E | H | L | A => {
let right = cpu.register(reg.cpu_register());
((4), Self::add(left, right, &mut flags))
(4, Self::add(left, right, &mut flags))
}
IndirectHL => {
let addr = cpu.register_pair(RegisterPair::HL);
let right = Self::read_byte(&mut cpu.bus, addr);
((8), Self::add(left, right, &mut flags))
(8, Self::add(left, right, &mut flags))
}
};
@@ -610,13 +610,13 @@ impl Instruction {
B | C | D | E | H | L | A => {
let right = cpu.register(reg.cpu_register());
let sum = Self::add_with_carry_bit(left, right, flags.c(), &mut flags);
((4), sum)
(4, sum)
}
IndirectHL => {
let addr = cpu.register_pair(RegisterPair::HL);
let right = Self::read_byte(&mut cpu.bus, addr);
let sum = Self::add_with_carry_bit(left, right, flags.c(), &mut flags);
((8), sum)
(8, sum)
}
};
cpu.set_register(CpuRegister::A, sum);
@@ -646,12 +646,12 @@ impl Instruction {
let (cycles, diff) = match reg {
B | C | D | E | H | L | A => {
let right = cpu.register(reg.cpu_register());
((4), Self::sub(left, right, &mut flags))
(4, Self::sub(left, right, &mut flags))
}
IndirectHL => {
let addr = cpu.register_pair(RegisterPair::HL);
let right = Self::read_byte(&mut cpu.bus, addr);
((8), Self::sub(left, right, &mut flags))
(8, Self::sub(left, right, &mut flags))
}
};
cpu.set_register(CpuRegister::A, diff);
@@ -681,13 +681,13 @@ impl Instruction {
B | C | D | E | H | L | A => {
let right = cpu.register(reg.cpu_register());
let diff = Self::sub_with_carry(left, right, flags.c(), &mut flags);
((4), diff)
(4, diff)
}
IndirectHL => {
let addr = cpu.register_pair(RegisterPair::HL);
let right = Self::read_byte(&mut cpu.bus, addr);
let diff = Self::sub_with_carry(left, right, flags.c(), &mut flags);
((8), diff)
(8, diff)
}
};
cpu.set_register(CpuRegister::A, diff);
@@ -717,7 +717,7 @@ impl Instruction {
IndirectHL => {
let addr = cpu.register_pair(RegisterPair::HL);
let right = Self::read_byte(&mut cpu.bus, addr);
((8), left & right)
(8, left & right)
}
};
cpu.set_register(CpuRegister::A, acc);
@@ -743,7 +743,7 @@ impl Instruction {
IndirectHL => {
let addr = cpu.register_pair(RegisterPair::HL);
let right = Self::read_byte(&mut cpu.bus, addr);
((8), left ^ right)
(8, left ^ right)
}
};
cpu.set_register(CpuRegister::A, acc);
@@ -769,7 +769,7 @@ impl Instruction {
IndirectHL => {
let addr = cpu.register_pair(RegisterPair::HL);
let right = Self::read_byte(&mut cpu.bus, addr);
((8), left | right)
(8, left | right)
}
};
cpu.set_register(CpuRegister::A, acc);
@@ -1053,14 +1053,14 @@ impl Instruction {
let byte = cpu.register(reg);
let rotated = byte.rotate_left(1);
cpu.set_register(reg, rotated);
((8), byte >> 7, rotated)
(8, byte >> 7, rotated)
}
IndirectHL => {
let addr = cpu.register_pair(RegisterPair::HL);
let byte = Self::read_byte(&mut cpu.bus, addr);
let rotated = byte.rotate_left(1);
Self::write_byte(&mut cpu.bus, addr, rotated);
((16), byte >> 7, rotated)
(16, byte >> 7, rotated)
}
};
cpu.update_flags(rotated == 0, false, false, most_sgfnt == 0x01);
@@ -1076,14 +1076,14 @@ impl Instruction {
let byte = cpu.register(reg);
let rotated = byte.rotate_right(1);
cpu.set_register(reg, rotated);
((8), byte & 0x01, rotated)
(8, byte & 0x01, rotated)
}
IndirectHL => {
let addr = cpu.register_pair(RegisterPair::HL);
let byte = Self::read_byte(&mut cpu.bus, addr);
let rotated = byte.rotate_right(1);
Self::write_byte(&mut cpu.bus, addr, rotated);
((16), byte & 0x01, rotated)
(16, byte & 0x01, rotated)
}
};
cpu.update_flags(rotated == 0, false, false, least_sgfnt == 0x01);
@@ -1101,14 +1101,14 @@ impl Instruction {
let byte = cpu.register(reg);
let (rotated, carry) = Self::rl_thru_carry(byte, flags.c());
cpu.set_register(reg, rotated);
((8), rotated, carry)
(8, rotated, carry)
}
IndirectHL => {
let addr = cpu.register_pair(RegisterPair::HL);
let byte = Self::read_byte(&mut cpu.bus, addr);
let (rotated, carry) = Self::rl_thru_carry(byte, flags.c());
Self::write_byte(&mut cpu.bus, addr, rotated);
((16), rotated, carry)
(16, rotated, carry)
}
};
cpu.update_flags(rotated == 0, false, false, carry);
@@ -1126,14 +1126,14 @@ impl Instruction {
let byte = cpu.register(reg);
let (rotated, carry) = Self::rr_thru_carry(byte, flags.c());
cpu.set_register(reg, rotated);
((8), rotated, carry)
(8, rotated, carry)
}
IndirectHL => {
let addr = cpu.register_pair(RegisterPair::HL);
let byte = Self::read_byte(&mut cpu.bus, addr);
let (rotated, carry) = Self::rr_thru_carry(byte, flags.c());
Self::write_byte(&mut cpu.bus, addr, rotated);
((16), rotated, carry)
(16, rotated, carry)
}
};
cpu.update_flags(rotated == 0, false, false, carry);
@@ -1149,14 +1149,14 @@ impl Instruction {
let byte = cpu.register(reg);
let shifted = byte << 1;
cpu.set_register(reg, shifted);
((8), (byte >> 7) & 0x01, shifted)
(8, (byte >> 7) & 0x01, shifted)
}
IndirectHL => {
let addr = cpu.register_pair(RegisterPair::HL);
let byte = Self::read_byte(&mut cpu.bus, addr);
let shifted = byte << 1;
Self::write_byte(&mut cpu.bus, addr, shifted);
((16), (byte >> 7) & 0x01, shifted)
(16, (byte >> 7) & 0x01, shifted)
}
};
cpu.update_flags(shifted == 0, false, false, most_sgfnt == 0x01);
@@ -1172,14 +1172,14 @@ impl Instruction {
let byte = cpu.register(reg);
let shifted = ((byte >> 7) & 0x01) << 7 | byte >> 1;
cpu.set_register(reg, shifted);
((8), byte & 0x01, shifted)
(8, byte & 0x01, shifted)
}
IndirectHL => {
let addr = cpu.register_pair(RegisterPair::HL);
let byte = Self::read_byte(&mut cpu.bus, addr);
let shifted = ((byte >> 7) & 0x01) << 7 | byte >> 1;
Self::write_byte(&mut cpu.bus, addr, shifted);
((16), byte & 0x01, shifted)
(16, byte & 0x01, shifted)
}
};
cpu.update_flags(shifted == 0, false, false, least_sgfnt == 0x01);
@@ -1194,14 +1194,14 @@ impl Instruction {
let reg = reg.cpu_register();
let swapped = Self::swap_bits(cpu.register(reg));
cpu.set_register(reg, swapped);
((8), swapped)
(8, swapped)
}
IndirectHL => {
let addr = cpu.register_pair(RegisterPair::HL);
let swapped = Self::swap_bits(Self::read_byte(&mut cpu.bus, addr));
Self::write_byte(&mut cpu.bus, addr, swapped);
((16), swapped)
(16, swapped)
}
};
cpu.update_flags(swapped == 0, false, false, false);
@@ -1217,14 +1217,14 @@ impl Instruction {
let byte = cpu.register(reg);
let shifted = byte >> 1;
cpu.set_register(reg, shifted);
((8), byte & 0x01, shifted)
(8, byte & 0x01, shifted)
}
IndirectHL => {
let addr = cpu.register_pair(RegisterPair::HL);
let byte = Self::read_byte(&mut cpu.bus, addr);
let shifted = byte >> 1;
Self::write_byte(&mut cpu.bus, addr, shifted);
((16), byte & 0x01, shifted)
(16, byte & 0x01, shifted)
}
};
cpu.update_flags(shift_reg == 0, false, false, least_sgfnt == 0x01);
@@ -1239,12 +1239,12 @@ impl Instruction {
B | C | D | E | H | L | A => {
let reg = reg.cpu_register();
let byte = cpu.register(reg);
((8), ((byte >> bit) & 0x01) == 0x01)
(8, ((byte >> bit) & 0x01) == 0x01)
}
IndirectHL => {
let addr = cpu.register_pair(RegisterPair::HL);
let byte = Self::read_byte(&mut cpu.bus, addr);
((12), ((byte >> bit) & 0x01) == 0x01)
(12, ((byte >> bit) & 0x01) == 0x01)
}
};
flags.set_z(!is_set);

View File

@@ -1,12 +1,15 @@
use std::convert::TryInto;
use anyhow::{anyhow, Result};
use anyhow::Result;
use clap::{crate_authors, crate_description, crate_name, crate_version, App, Arg};
use gb::emu::build::EmulatorBuilder;
use gb::emu::CYCLES_IN_FRAME;
use gb::{Cycle, GB_HEIGHT, GB_WIDTH};
use gilrs::Gilrs;
use pixels::{PixelsBuilder, SurfaceTexture};
use rodio::{OutputStream, Sink};
use tracing::info;
use tracing_subscriber::EnvFilter;
use winit::dpi::{LogicalSize, PhysicalSize};
use winit::event::{Event, VirtualKeyCode};
use winit::event_loop::{ControlFlow, EventLoop};
@@ -41,6 +44,15 @@ fn main() -> Result<()> {
)
.get_matches();
// Set up subscriber
if std::env::var("RUST_LOG").is_err() {
std::env::set_var("RUST_LOG", "gb=info");
}
tracing_subscriber::fmt::fmt()
.with_env_filter(EnvFilter::from_default_env())
.init();
let mut emu_build =
EmulatorBuilder::new().with_cart(m.value_of("rom").expect("ROM path provided"))?;
@@ -51,9 +63,11 @@ fn main() -> Result<()> {
let mut emu = emu_build.finish();
// Load Save file if it exists
info!("Attempt to load .sav");
emu.try_load_sav().expect("Load save if exists");
let rom_title = emu.title();
info!("Initialize Gamepad");
let mut gamepad = Gilrs::new().expect("Initialize Controller Support");
// Initialize GUI
@@ -84,6 +98,7 @@ fn main() -> Result<()> {
emu.set_prod(prod);
info!("Spawn Audio Thread");
std::thread::spawn(move || {
sink.sleep_until_end();
});
@@ -93,11 +108,7 @@ fn main() -> Result<()> {
event_loop.run(move |event, _, control_flow| {
if let Event::RedrawRequested(_) = event {
if pixels
.render()
.map_err(|e| anyhow!("pixels.render() failed: {}", e))
.is_err()
{
if pixels.render().is_err() {
emu.try_write_sav().expect("Write game save if need be");
*control_flow = ControlFlow::Exit;
@@ -119,8 +130,8 @@ fn main() -> Result<()> {
cycle_count += gb::emu::run_frame(&mut emu, &mut gamepad, &input);
if cycle_count >= gb::emu::CYCLES_IN_FRAME {
cycle_count %= gb::emu::CYCLES_IN_FRAME;
if cycle_count >= CYCLES_IN_FRAME {
cycle_count %= CYCLES_IN_FRAME;
let buf: &mut [u8; GB_WIDTH * GB_HEIGHT * 4] = pixels
.get_frame()

View File

@@ -413,7 +413,6 @@ impl Ppu {
self.pos.line_y = 0;
self.stat.set_mode(PpuMode::HBlank);
// TODO: Is this an unnecessary performance hit?
let mut blank = WHITE.repeat(self.frame_buf.len() / 4);
self.frame_buf.swap_with_slice(&mut blank);
}