chore: replace pub with pub(crate) when possible
This commit is contained in:
parent
b7b213b6b9
commit
878edd4082
20
src/bus.rs
20
src/bus.rs
|
@ -46,7 +46,7 @@ impl Default for Bus {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Bus {
|
impl Bus {
|
||||||
pub fn with_boot(path: &str) -> anyhow::Result<Self> {
|
pub(crate) fn with_boot(path: &str) -> anyhow::Result<Self> {
|
||||||
let mut file = File::open(path)?;
|
let mut file = File::open(path)?;
|
||||||
let mut boot_rom = [0u8; 256];
|
let mut boot_rom = [0u8; 256];
|
||||||
|
|
||||||
|
@ -58,29 +58,29 @@ impl Bus {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_cartridge(&mut self, path: &str) -> std::io::Result<()> {
|
pub(crate) fn load_cartridge(&mut self, path: &str) -> std::io::Result<()> {
|
||||||
self.cartridge = Some(Cartridge::new(path)?);
|
self.cartridge = Some(Cartridge::new(path)?);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rom_title(&self) -> Option<&str> {
|
pub(crate) fn rom_title(&self) -> Option<&str> {
|
||||||
self.cartridge.as_ref()?.title()
|
self.cartridge.as_ref()?.title()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn step(&mut self, cycles: Cycle) {
|
pub(crate) fn step(&mut self, cycles: Cycle) {
|
||||||
self.step_dma(cycles);
|
self.step_dma(cycles);
|
||||||
self.ppu.step(cycles);
|
self.ppu.step(cycles);
|
||||||
self.timer.step(cycles);
|
self.timer.step(cycles);
|
||||||
self.sound.step(cycles);
|
self.sound.step(cycles);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn timer(&self) -> Timer {
|
pub(crate) fn timer(&self) -> Timer {
|
||||||
self.timer
|
self.timer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Bus {
|
impl Bus {
|
||||||
pub fn read_byte(&self, addr: u16) -> u8 {
|
pub(crate) fn read_byte(&self, addr: u16) -> u8 {
|
||||||
match addr {
|
match addr {
|
||||||
0x0000..=0x3FFF => {
|
0x0000..=0x3FFF => {
|
||||||
// 16KB ROM bank 00
|
// 16KB ROM bank 00
|
||||||
|
@ -193,7 +193,7 @@ impl Bus {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_byte(&mut self, addr: u16, byte: u8) {
|
pub(crate) fn write_byte(&mut self, addr: u16, byte: u8) {
|
||||||
match addr {
|
match addr {
|
||||||
0x0000..=0x3FFF => {
|
0x0000..=0x3FFF => {
|
||||||
// 16KB ROM bank 00
|
// 16KB ROM bank 00
|
||||||
|
@ -323,11 +323,11 @@ impl Bus {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_word(&self, addr: u16) -> u16 {
|
pub(crate) fn read_word(&self, addr: u16) -> u16 {
|
||||||
(self.read_byte(addr + 1) as u16) << 8 | self.read_byte(addr) as u16
|
(self.read_byte(addr + 1) as u16) << 8 | self.read_byte(addr) as u16
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_word(&mut self, addr: u16, word: u16) {
|
pub(crate) fn write_word(&mut self, addr: u16, word: u16) {
|
||||||
self.write_byte(addr + 1, (word >> 8) as u8);
|
self.write_byte(addr + 1, (word >> 8) as u8);
|
||||||
self.write_byte(addr, (word & 0x00FF) as u8);
|
self.write_byte(addr, (word & 0x00FF) as u8);
|
||||||
}
|
}
|
||||||
|
@ -376,7 +376,7 @@ impl Bus {
|
||||||
self.timer.set_interrupt(timer);
|
self.timer.set_interrupt(timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn boot_enabled(&self) -> bool {
|
pub(crate) fn boot_enabled(&self) -> bool {
|
||||||
self.boot.is_some()
|
self.boot.is_some()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,14 +7,14 @@ const ROM_SIZE_ADDRESS: usize = 0x0148;
|
||||||
const MBC_TYPE_ADDRESS: usize = 0x0147;
|
const MBC_TYPE_ADDRESS: usize = 0x0147;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub struct Cartridge {
|
pub(crate) struct Cartridge {
|
||||||
memory: Vec<u8>,
|
memory: Vec<u8>,
|
||||||
title: Option<String>,
|
title: Option<String>,
|
||||||
mbc: Box<dyn MemoryBankController>,
|
mbc: Box<dyn MemoryBankController>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Cartridge {
|
impl Cartridge {
|
||||||
pub fn new<P: AsRef<Path> + ?Sized>(path: &P) -> io::Result<Self> {
|
pub(crate) fn new<P: AsRef<Path> + ?Sized>(path: &P) -> io::Result<Self> {
|
||||||
let mut memory = vec![];
|
let mut memory = vec![];
|
||||||
let mut rom = File::open(path)?;
|
let mut rom = File::open(path)?;
|
||||||
rom.read_to_end(&mut memory)?;
|
rom.read_to_end(&mut memory)?;
|
||||||
|
@ -59,7 +59,7 @@ impl Cartridge {
|
||||||
str_with_nulls.map(|s| s.trim_matches('\0').to_string())
|
str_with_nulls.map(|s| s.trim_matches('\0').to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn title(&self) -> Option<&str> {
|
pub(crate) fn title(&self) -> Option<&str> {
|
||||||
self.title.as_deref()
|
self.title.as_deref()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ impl Cartridge {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Cartridge {
|
impl Cartridge {
|
||||||
pub fn read_byte(&self, addr: u16) -> u8 {
|
pub(crate) fn read_byte(&self, addr: u16) -> u8 {
|
||||||
use MbcResult::*;
|
use MbcResult::*;
|
||||||
|
|
||||||
match self.mbc.handle_read(addr) {
|
match self.mbc.handle_read(addr) {
|
||||||
|
@ -95,15 +95,15 @@ impl Cartridge {
|
||||||
Value(byte) => byte,
|
Value(byte) => byte,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn write_byte(&mut self, addr: u16, byte: u8) {
|
pub(crate) fn write_byte(&mut self, addr: u16, byte: u8) {
|
||||||
self.mbc.handle_write(addr, byte);
|
self.mbc.handle_write(addr, byte);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_word(&self, addr: u16) -> u16 {
|
pub(crate) fn read_word(&self, addr: u16) -> u16 {
|
||||||
(self.read_byte(addr + 1) as u16) << 8 | self.read_byte(addr) as u16
|
(self.read_byte(addr + 1) as u16) << 8 | self.read_byte(addr) as u16
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_word(&mut self, addr: u16, word: u16) {
|
pub(crate) fn write_word(&mut self, addr: u16, word: u16) {
|
||||||
self.write_byte(addr + 1, (word >> 8) as u8);
|
self.write_byte(addr + 1, (word >> 8) as u8);
|
||||||
self.write_byte(addr, (word & 0x00FF) as u8);
|
self.write_byte(addr, (word & 0x00FF) as u8);
|
||||||
}
|
}
|
||||||
|
@ -294,7 +294,7 @@ enum RamSize {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RamSize {
|
impl RamSize {
|
||||||
pub fn as_byte_count(&self) -> u32 {
|
pub(crate) fn as_byte_count(&self) -> u32 {
|
||||||
use RamSize::*;
|
use RamSize::*;
|
||||||
|
|
||||||
match *self {
|
match *self {
|
||||||
|
@ -354,7 +354,7 @@ impl Default for BankCount {
|
||||||
|
|
||||||
impl BankCount {
|
impl BankCount {
|
||||||
// https://hacktix.github.io/GBEDG/mbcs/#rom-size
|
// https://hacktix.github.io/GBEDG/mbcs/#rom-size
|
||||||
pub fn to_byte_count(self) -> u32 {
|
pub(crate) fn to_byte_count(self) -> u32 {
|
||||||
use BankCount::*;
|
use BankCount::*;
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
|
|
52
src/cpu.rs
52
src/cpu.rs
|
@ -42,15 +42,15 @@ impl Cpu {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ime(&self) -> ImeState {
|
pub(crate) fn ime(&self) -> ImeState {
|
||||||
self.ime
|
self.ime
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_ime(&mut self, state: ImeState) {
|
pub(crate) fn set_ime(&mut self, state: ImeState) {
|
||||||
self.ime = state;
|
self.ime = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn halt(&mut self, state: HaltState) {
|
pub(crate) fn halt(&mut self, state: HaltState) {
|
||||||
self.halted = Some(state);
|
self.halted = Some(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,11 +58,11 @@ impl Cpu {
|
||||||
self.halted = None;
|
self.halted = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn halted(&self) -> Option<HaltState> {
|
pub(crate) fn halted(&self) -> Option<HaltState> {
|
||||||
self.halted
|
self.halted
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn inc_pc(&mut self) {
|
pub(crate) fn inc_pc(&mut self) {
|
||||||
self.reg.pc += 1;
|
self.reg.pc += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,15 +76,15 @@ impl Cpu {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Cpu {
|
impl Cpu {
|
||||||
pub fn fetch(&self) -> u8 {
|
pub(crate) fn fetch(&self) -> u8 {
|
||||||
self.bus.read_byte(self.reg.pc)
|
self.bus.read_byte(self.reg.pc)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn decode(&mut self, opcode: u8) -> Instruction {
|
pub(crate) fn decode(&mut self, opcode: u8) -> Instruction {
|
||||||
Instruction::from_byte(self, opcode)
|
Instruction::from_byte(self, opcode)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn execute(&mut self, instruction: Instruction) -> Cycle {
|
pub(crate) fn execute(&mut self, instruction: Instruction) -> Cycle {
|
||||||
Instruction::execute(self, instruction)
|
Instruction::execute(self, instruction)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,30 +128,30 @@ impl Cpu {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Cpu {
|
impl Cpu {
|
||||||
pub fn read_imm_byte(&mut self, addr: u16) -> u8 {
|
pub(crate) fn read_imm_byte(&mut self, addr: u16) -> u8 {
|
||||||
self.inc_pc(); // NB: the addr read in the line below will be equal to PC - 1 after this function call
|
self.inc_pc(); // NB: the addr read in the line below will be equal to PC - 1 after this function call
|
||||||
self.bus.read_byte(addr)
|
self.bus.read_byte(addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_imm_word(&mut self, addr: u16) -> u16 {
|
pub(crate) fn read_imm_word(&mut self, addr: u16) -> u16 {
|
||||||
self.inc_pc();
|
self.inc_pc();
|
||||||
self.inc_pc(); // NB: the addr read in the line below will be equal to PC - 2 after this function call
|
self.inc_pc(); // NB: the addr read in the line below will be equal to PC - 2 after this function call
|
||||||
self.bus.read_word(addr)
|
self.bus.read_word(addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_byte(&self, addr: u16) -> u8 {
|
pub(crate) fn read_byte(&self, addr: u16) -> u8 {
|
||||||
self.bus.read_byte(addr)
|
self.bus.read_byte(addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_byte(&mut self, addr: u16, byte: u8) {
|
pub(crate) fn write_byte(&mut self, addr: u16, byte: u8) {
|
||||||
self.bus.write_byte(addr, byte);
|
self.bus.write_byte(addr, byte);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_word(&mut self, addr: u16) -> u16 {
|
pub(crate) fn read_word(&mut self, addr: u16) -> u16 {
|
||||||
self.bus.read_word(addr)
|
self.bus.read_word(addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_word(&mut self, addr: u16, word: u16) {
|
pub(crate) fn write_word(&mut self, addr: u16, word: u16) {
|
||||||
self.bus.write_word(addr, word)
|
self.bus.write_word(addr, word)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -260,7 +260,7 @@ impl Default for State {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Cpu {
|
impl Cpu {
|
||||||
pub fn set_register(&mut self, register: Register, value: u8) {
|
pub(crate) fn set_register(&mut self, register: Register, value: u8) {
|
||||||
use Register::*;
|
use Register::*;
|
||||||
|
|
||||||
match register {
|
match register {
|
||||||
|
@ -275,7 +275,7 @@ impl Cpu {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register(&self, register: Register) -> u8 {
|
pub(crate) fn register(&self, register: Register) -> u8 {
|
||||||
use Register::*;
|
use Register::*;
|
||||||
|
|
||||||
match register {
|
match register {
|
||||||
|
@ -290,7 +290,7 @@ impl Cpu {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register_pair(&self, pair: RegisterPair) -> u16 {
|
pub(crate) fn register_pair(&self, pair: RegisterPair) -> u16 {
|
||||||
use RegisterPair::*;
|
use RegisterPair::*;
|
||||||
|
|
||||||
match pair {
|
match pair {
|
||||||
|
@ -303,7 +303,7 @@ impl Cpu {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_register_pair(&mut self, pair: RegisterPair, value: u16) {
|
pub(crate) fn set_register_pair(&mut self, pair: RegisterPair, value: u16) {
|
||||||
use RegisterPair::*;
|
use RegisterPair::*;
|
||||||
|
|
||||||
let high = (value >> 8) as u8;
|
let high = (value >> 8) as u8;
|
||||||
|
@ -331,17 +331,17 @@ impl Cpu {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn flags(&self) -> &Flags {
|
pub(crate) fn flags(&self) -> &Flags {
|
||||||
&self.flags
|
&self.flags
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_flags(&mut self, flags: Flags) {
|
pub(crate) fn set_flags(&mut self, flags: Flags) {
|
||||||
self.flags = flags;
|
self.flags = flags;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Cpu {
|
impl Cpu {
|
||||||
pub fn log_state(&self, mut writer: impl std::io::Write) -> std::io::Result<()> {
|
pub(crate) fn log_state(&self, mut writer: impl std::io::Write) -> std::io::Result<()> {
|
||||||
write!(writer, "A: {:02X} ", self.reg.a)?;
|
write!(writer, "A: {:02X} ", self.reg.a)?;
|
||||||
write!(writer, "F: {:02X} ", u8::from(self.flags))?;
|
write!(writer, "F: {:02X} ", u8::from(self.flags))?;
|
||||||
write!(writer, "B: {:02X} ", self.reg.b)?;
|
write!(writer, "B: {:02X} ", self.reg.b)?;
|
||||||
|
@ -363,7 +363,7 @@ impl Cpu {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub enum Register {
|
pub(crate) enum Register {
|
||||||
A,
|
A,
|
||||||
B,
|
B,
|
||||||
C,
|
C,
|
||||||
|
@ -375,7 +375,7 @@ pub enum Register {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub enum RegisterPair {
|
pub(crate) enum RegisterPair {
|
||||||
AF,
|
AF,
|
||||||
BC,
|
BC,
|
||||||
DE,
|
DE,
|
||||||
|
@ -407,7 +407,7 @@ bitfield! {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Flags {
|
impl Flags {
|
||||||
pub fn update(&mut self, z: bool, n: bool, h: bool, c: bool) {
|
pub(crate) fn update(&mut self, z: bool, n: bool, h: bool, c: bool) {
|
||||||
self.set_z(z);
|
self.set_z(z);
|
||||||
self.set_n(n);
|
self.set_n(n);
|
||||||
self.set_h(h);
|
self.set_h(h);
|
||||||
|
@ -469,14 +469,14 @@ impl From<u8> for Flags {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum HaltState {
|
pub(crate) enum HaltState {
|
||||||
ImeEnabled,
|
ImeEnabled,
|
||||||
NonePending,
|
NonePending,
|
||||||
SomePending,
|
SomePending,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum ImeState {
|
pub(crate) enum ImeState {
|
||||||
Disabled,
|
Disabled,
|
||||||
Pending,
|
Pending,
|
||||||
PendingEnd,
|
PendingEnd,
|
||||||
|
|
|
@ -19,7 +19,7 @@ pub struct Egui {
|
||||||
render_pass: RenderPass,
|
render_pass: RenderPass,
|
||||||
paint_jobs: Vec<ClippedMesh>,
|
paint_jobs: Vec<ClippedMesh>,
|
||||||
|
|
||||||
pub config: Configuration,
|
pub(crate) config: Configuration,
|
||||||
|
|
||||||
show_flags: bool,
|
show_flags: bool,
|
||||||
show_cpu_info: bool,
|
show_cpu_info: bool,
|
||||||
|
@ -30,7 +30,7 @@ pub struct Egui {
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
show_disasm: bool,
|
show_disasm: bool,
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
pub break_point: Option<u16>,
|
pub(crate) break_point: Option<u16>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Egui {
|
impl Egui {
|
||||||
|
@ -367,14 +367,14 @@ impl Egui {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Configuration {
|
pub(crate) struct Configuration {
|
||||||
/// Show Configuration egui menu
|
/// Show Configuration egui menu
|
||||||
show: bool,
|
show: bool,
|
||||||
|
|
||||||
/// How many [`LR35902`] .step() do we want to do at once
|
/// How many [`LR35902`] .step() do we want to do at once
|
||||||
/// when pressing the spacebar key?
|
/// when pressing the spacebar key?
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
pub spacebar_step: u16,
|
pub(crate) spacebar_step: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Configuration {
|
impl Default for Configuration {
|
||||||
|
|
|
@ -2,7 +2,7 @@ const HIGH_RAM_SIZE: usize = 0x7F;
|
||||||
const HIGH_RAM_START_ADDRESS: usize = 0xFF80;
|
const HIGH_RAM_START_ADDRESS: usize = 0xFF80;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct HighRam {
|
pub(crate) struct HighRam {
|
||||||
buf: Box<[u8; HIGH_RAM_SIZE]>,
|
buf: Box<[u8; HIGH_RAM_SIZE]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,11 +15,11 @@ impl Default for HighRam {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HighRam {
|
impl HighRam {
|
||||||
pub fn write_byte(&mut self, addr: u16, byte: u8) {
|
pub(crate) fn write_byte(&mut self, addr: u16, byte: u8) {
|
||||||
self.buf[addr as usize - HIGH_RAM_START_ADDRESS] = byte;
|
self.buf[addr as usize - HIGH_RAM_START_ADDRESS] = byte;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_byte(&self, addr: u16) -> u8 {
|
pub(crate) fn read_byte(&self, addr: u16) -> u8 {
|
||||||
self.buf[addr as usize - HIGH_RAM_START_ADDRESS]
|
self.buf[addr as usize - HIGH_RAM_START_ADDRESS]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ use std::{convert::TryFrom, fmt::Debug};
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
#[allow(clippy::upper_case_acronyms)]
|
#[allow(clippy::upper_case_acronyms)]
|
||||||
pub enum Instruction {
|
pub(crate) enum Instruction {
|
||||||
NOP,
|
NOP,
|
||||||
LD(LDTarget, LDTarget),
|
LD(LDTarget, LDTarget),
|
||||||
STOP,
|
STOP,
|
||||||
|
@ -51,26 +51,26 @@ pub enum Instruction {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub enum JPTarget {
|
pub(crate) enum JPTarget {
|
||||||
RegisterPair(RegisterPair),
|
RegisterPair(RegisterPair),
|
||||||
ImmediateWord(u16),
|
ImmediateWord(u16),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub enum Registers {
|
pub(crate) enum Registers {
|
||||||
Byte(InstrRegister),
|
Byte(InstrRegister),
|
||||||
Word(RegisterPair),
|
Word(RegisterPair),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub enum MATHTarget {
|
pub(crate) enum MATHTarget {
|
||||||
Register(InstrRegister),
|
Register(InstrRegister),
|
||||||
RegisterPair(RegisterPair),
|
RegisterPair(RegisterPair),
|
||||||
ImmediateByte(u8),
|
ImmediateByte(u8),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub enum LDTarget {
|
pub(crate) enum LDTarget {
|
||||||
IndirectC,
|
IndirectC,
|
||||||
Register(InstrRegister),
|
Register(InstrRegister),
|
||||||
IndirectRegister(InstrRegisterPair),
|
IndirectRegister(InstrRegisterPair),
|
||||||
|
@ -82,7 +82,7 @@ pub enum LDTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub enum InstrRegisterPair {
|
pub(crate) enum InstrRegisterPair {
|
||||||
AF,
|
AF,
|
||||||
BC,
|
BC,
|
||||||
DE,
|
DE,
|
||||||
|
@ -94,7 +94,7 @@ pub enum InstrRegisterPair {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub enum InstrRegister {
|
pub(crate) enum InstrRegister {
|
||||||
A,
|
A,
|
||||||
B,
|
B,
|
||||||
C,
|
C,
|
||||||
|
@ -106,7 +106,7 @@ pub enum InstrRegister {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub enum JumpCondition {
|
pub(crate) enum JumpCondition {
|
||||||
NotZero,
|
NotZero,
|
||||||
Zero,
|
Zero,
|
||||||
NotCarry,
|
NotCarry,
|
||||||
|
@ -122,7 +122,7 @@ struct Table;
|
||||||
pub struct Cycle(u32);
|
pub struct Cycle(u32);
|
||||||
|
|
||||||
impl Instruction {
|
impl Instruction {
|
||||||
pub fn execute(cpu: &mut Cpu, instruction: Self) -> Cycle {
|
pub(crate) fn execute(cpu: &mut Cpu, instruction: Self) -> Cycle {
|
||||||
match instruction {
|
match instruction {
|
||||||
Instruction::NOP => Cycle::new(4),
|
Instruction::NOP => Cycle::new(4),
|
||||||
Instruction::LD(lhs, rhs) => match (lhs, rhs) {
|
Instruction::LD(lhs, rhs) => match (lhs, rhs) {
|
||||||
|
@ -1608,7 +1608,7 @@ impl Instruction {
|
||||||
(lower << 4) | upper
|
(lower << 4) | upper
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reset(cpu: &mut Cpu, vector: u8) -> Cycle {
|
pub(crate) fn reset(cpu: &mut Cpu, vector: u8) -> Cycle {
|
||||||
let addr = cpu.register_pair(RegisterPair::PC);
|
let addr = cpu.register_pair(RegisterPair::PC);
|
||||||
Self::push(cpu, addr);
|
Self::push(cpu, addr);
|
||||||
cpu.set_register_pair(RegisterPair::PC, vector as u16);
|
cpu.set_register_pair(RegisterPair::PC, vector as u16);
|
||||||
|
@ -1617,7 +1617,7 @@ impl Instruction {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Instruction {
|
impl Instruction {
|
||||||
pub fn from_byte(cpu: &mut Cpu, byte: u8) -> Self {
|
pub(crate) fn from_byte(cpu: &mut Cpu, byte: u8) -> Self {
|
||||||
if byte == 0xCB {
|
if byte == 0xCB {
|
||||||
Self::from_prefixed_byte(cpu)
|
Self::from_prefixed_byte(cpu)
|
||||||
} else {
|
} else {
|
||||||
|
@ -1911,7 +1911,7 @@ impl TryFrom<InstrRegister> for Register {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Table {
|
impl Table {
|
||||||
pub fn r(index: u8) -> InstrRegister {
|
pub(crate) fn r(index: u8) -> InstrRegister {
|
||||||
match index {
|
match index {
|
||||||
0 => InstrRegister::B,
|
0 => InstrRegister::B,
|
||||||
1 => InstrRegister::C,
|
1 => InstrRegister::C,
|
||||||
|
@ -1925,7 +1925,7 @@ impl Table {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rp2(index: u8) -> RegisterPair {
|
pub(crate) fn rp2(index: u8) -> RegisterPair {
|
||||||
match index {
|
match index {
|
||||||
0 => RegisterPair::BC,
|
0 => RegisterPair::BC,
|
||||||
1 => RegisterPair::DE,
|
1 => RegisterPair::DE,
|
||||||
|
@ -1935,7 +1935,7 @@ impl Table {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rp(index: u8) -> RegisterPair {
|
pub(crate) fn rp(index: u8) -> RegisterPair {
|
||||||
match index {
|
match index {
|
||||||
0 => RegisterPair::BC,
|
0 => RegisterPair::BC,
|
||||||
1 => RegisterPair::DE,
|
1 => RegisterPair::DE,
|
||||||
|
@ -1945,7 +1945,7 @@ impl Table {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cc(index: u8) -> JumpCondition {
|
pub(crate) fn cc(index: u8) -> JumpCondition {
|
||||||
match index {
|
match index {
|
||||||
0 => JumpCondition::NotZero,
|
0 => JumpCondition::NotZero,
|
||||||
1 => JumpCondition::Zero,
|
1 => JumpCondition::Zero,
|
||||||
|
@ -1955,7 +1955,7 @@ impl Table {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn x2_alu(index: u8, r_index: u8) -> Instruction {
|
pub(crate) fn x2_alu(index: u8, r_index: u8) -> Instruction {
|
||||||
match index {
|
match index {
|
||||||
0 => Instruction::ADD(
|
0 => Instruction::ADD(
|
||||||
// ADD A, r[z]
|
// ADD A, r[z]
|
||||||
|
@ -1973,7 +1973,7 @@ impl Table {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn x3_alu(index: u8, n: u8) -> Instruction {
|
pub(crate) fn x3_alu(index: u8, n: u8) -> Instruction {
|
||||||
match index {
|
match index {
|
||||||
0 => Instruction::ADD(
|
0 => Instruction::ADD(
|
||||||
// ADD A, n
|
// ADD A, n
|
||||||
|
@ -1991,7 +1991,7 @@ impl Table {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rot(index: u8, r_index: u8) -> Instruction {
|
pub(crate) fn rot(index: u8, r_index: u8) -> Instruction {
|
||||||
match index {
|
match index {
|
||||||
0 => Instruction::RLC(Self::r(r_index)), // RLC r[z]
|
0 => Instruction::RLC(Self::r(r_index)), // RLC r[z]
|
||||||
1 => Instruction::RRC(Self::r(r_index)), // RRC r[z]
|
1 => Instruction::RRC(Self::r(r_index)), // RRC r[z]
|
||||||
|
@ -2275,13 +2275,13 @@ impl From<Cycle> for u32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InstrRegisterPair {
|
impl InstrRegisterPair {
|
||||||
pub fn to_register_pair(self) -> RegisterPair {
|
pub(crate) fn to_register_pair(self) -> RegisterPair {
|
||||||
RegisterPair::try_from(self).expect("Failed to convert InstrRegisterPair to RegisterPair")
|
RegisterPair::try_from(self).expect("Failed to convert InstrRegisterPair to RegisterPair")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InstrRegister {
|
impl InstrRegister {
|
||||||
pub fn to_register(self) -> Register {
|
pub(crate) fn to_register(self) -> Register {
|
||||||
Register::try_from(self).expect("Failed to convert from InstrRegister to Register")
|
Register::try_from(self).expect("Failed to convert from InstrRegister to Register")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
use bitfield::bitfield;
|
use bitfield::bitfield;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Default)]
|
#[derive(Debug, Clone, Copy, Default)]
|
||||||
pub struct Interrupt {
|
pub(crate) struct Interrupt {
|
||||||
pub flag: InterruptFlag,
|
pub(crate) flag: InterruptFlag,
|
||||||
pub enable: InterruptEnable,
|
pub(crate) enable: InterruptEnable,
|
||||||
}
|
}
|
||||||
|
|
||||||
bitfield! {
|
bitfield! {
|
||||||
pub struct InterruptEnable(u8);
|
pub struct InterruptEnable(u8);
|
||||||
impl Debug;
|
impl Debug;
|
||||||
pub vblank, set_vblank: 0;
|
pub vblank, set_vblank: 0;
|
||||||
pub lcd_stat, set_lcd_stat: 1;
|
pub lcd_stat, set_lcd_stat: 1;
|
||||||
pub timer, set_timer: 2;
|
pub timer, set_timer: 2;
|
||||||
pub serial, set_serial: 3;
|
pub serial, set_serial: 3;
|
||||||
pub joypad, set_joypad: 4;
|
pub joypad, set_joypad: 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Copy for InterruptEnable {}
|
impl Copy for InterruptEnable {}
|
||||||
|
|
|
@ -7,11 +7,11 @@ pub struct Joypad {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Joypad {
|
impl Joypad {
|
||||||
pub fn interrupt(&self) -> bool {
|
pub(crate) fn interrupt(&self) -> bool {
|
||||||
self.interrupt
|
self.interrupt
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_interrupt(&mut self, value: bool) {
|
pub(crate) fn set_interrupt(&mut self, value: bool) {
|
||||||
self.interrupt = value;
|
self.interrupt = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
124
src/ppu.rs
124
src/ppu.rs
|
@ -4,7 +4,7 @@ use crate::GB_WIDTH;
|
||||||
use dma::DmaProcess;
|
use dma::DmaProcess;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
pub use types::PpuMode;
|
pub(crate) use types::PpuMode;
|
||||||
use types::{
|
use types::{
|
||||||
BackgroundPalette, GrayShade, LCDControl, LCDStatus, ObjectFlags, ObjectPalette,
|
BackgroundPalette, GrayShade, LCDControl, LCDStatus, ObjectFlags, ObjectPalette,
|
||||||
ObjectPaletteId, ObjectSize, Pixels, RenderPriority, TileDataAddress,
|
ObjectPaletteId, ObjectSize, Pixels, RenderPriority, TileDataAddress,
|
||||||
|
@ -34,13 +34,13 @@ const BLACK: [u8; 4] = 0x202020FFu32.to_be_bytes();
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Ppu {
|
pub struct Ppu {
|
||||||
pub int: Interrupt,
|
pub(crate) int: Interrupt,
|
||||||
pub control: LCDControl,
|
pub(crate) control: LCDControl,
|
||||||
pub monochrome: Monochrome,
|
pub(crate) monochrome: Monochrome,
|
||||||
pub pos: ScreenPosition,
|
pub(crate) pos: ScreenPosition,
|
||||||
pub vram: Box<[u8; VRAM_SIZE]>,
|
pub(crate) vram: Box<[u8; VRAM_SIZE]>,
|
||||||
pub stat: LCDStatus,
|
pub(crate) stat: LCDStatus,
|
||||||
pub oam: ObjectAttributeTable,
|
pub(crate) oam: ObjectAttributeTable,
|
||||||
pub(crate) dma: DmaProcess,
|
pub(crate) dma: DmaProcess,
|
||||||
scan_state: OamScanState,
|
scan_state: OamScanState,
|
||||||
fetch: PixelFetcher,
|
fetch: PixelFetcher,
|
||||||
|
@ -53,17 +53,17 @@ pub struct Ppu {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ppu {
|
impl Ppu {
|
||||||
pub fn read_byte(&self, addr: u16) -> u8 {
|
pub(crate) fn read_byte(&self, addr: u16) -> u8 {
|
||||||
self.vram[addr as usize - PPU_START_ADDRESS]
|
self.vram[addr as usize - PPU_START_ADDRESS]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_byte(&mut self, addr: u16, byte: u8) {
|
pub(crate) fn write_byte(&mut self, addr: u16, byte: u8) {
|
||||||
self.vram[addr as usize - PPU_START_ADDRESS] = byte;
|
self.vram[addr as usize - PPU_START_ADDRESS] = byte;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ppu {
|
impl Ppu {
|
||||||
pub fn step(&mut self, cycles: Cycle) {
|
pub(crate) fn step(&mut self, cycles: Cycle) {
|
||||||
let start: u32 = self.cycle.into();
|
let start: u32 = self.cycle.into();
|
||||||
let end: u32 = cycles.into();
|
let end: u32 = cycles.into();
|
||||||
|
|
||||||
|
@ -459,63 +459,63 @@ impl Default for Ppu {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Default)]
|
#[derive(Debug, Clone, Copy, Default)]
|
||||||
pub struct Interrupt {
|
pub(crate) struct Interrupt {
|
||||||
_vblank: bool,
|
_vblank: bool,
|
||||||
_lcd_stat: bool,
|
_lcd_stat: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Interrupt {
|
impl Interrupt {
|
||||||
pub fn vblank(&self) -> bool {
|
pub(crate) fn vblank(&self) -> bool {
|
||||||
self._vblank
|
self._vblank
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_vblank(&mut self, enabled: bool) {
|
pub(crate) fn set_vblank(&mut self, enabled: bool) {
|
||||||
self._vblank = enabled;
|
self._vblank = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lcd_stat(&self) -> bool {
|
pub(crate) fn lcd_stat(&self) -> bool {
|
||||||
self._lcd_stat
|
self._lcd_stat
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_lcd_stat(&mut self, enabled: bool) {
|
pub(crate) fn set_lcd_stat(&mut self, enabled: bool) {
|
||||||
self._lcd_stat = enabled;
|
self._lcd_stat = enabled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Default)]
|
#[derive(Debug, Clone, Copy, Default)]
|
||||||
pub struct ScreenPosition {
|
pub(crate) struct ScreenPosition {
|
||||||
pub scroll_y: u8,
|
pub(crate) scroll_y: u8,
|
||||||
pub scroll_x: u8,
|
pub(crate) scroll_x: u8,
|
||||||
pub line_y: u8,
|
pub(crate) line_y: u8,
|
||||||
pub ly_compare: u8,
|
pub(crate) ly_compare: u8,
|
||||||
pub window_y: u8,
|
pub(crate) window_y: u8,
|
||||||
pub window_x: u8,
|
pub(crate) window_x: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Default)]
|
#[derive(Debug, Clone, Copy, Default)]
|
||||||
pub struct Monochrome {
|
pub(crate) struct Monochrome {
|
||||||
pub bg_palette: BackgroundPalette,
|
pub(crate) bg_palette: BackgroundPalette,
|
||||||
pub obj_palette_0: ObjectPalette,
|
pub(crate) obj_palette_0: ObjectPalette,
|
||||||
pub obj_palette_1: ObjectPalette,
|
pub(crate) obj_palette_1: ObjectPalette,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct ObjectAttributeTable {
|
pub(crate) struct ObjectAttributeTable {
|
||||||
buf: Box<[u8; OAM_SIZE]>,
|
buf: Box<[u8; OAM_SIZE]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ObjectAttributeTable {
|
impl ObjectAttributeTable {
|
||||||
pub fn read_byte(&self, addr: u16) -> u8 {
|
pub(crate) fn read_byte(&self, addr: u16) -> u8 {
|
||||||
let index = (addr - 0xFE00) as usize;
|
let index = (addr - 0xFE00) as usize;
|
||||||
self.buf[index]
|
self.buf[index]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_byte(&mut self, addr: u16, byte: u8) {
|
pub(crate) fn write_byte(&mut self, addr: u16, byte: u8) {
|
||||||
let index = (addr - 0xFE00) as usize;
|
let index = (addr - 0xFE00) as usize;
|
||||||
self.buf[index] = byte;
|
self.buf[index] = byte;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn attribute(&self, index: usize) -> ObjectAttribute {
|
pub(crate) fn attribute(&self, index: usize) -> ObjectAttribute {
|
||||||
let start = index * 4;
|
let start = index * 4;
|
||||||
|
|
||||||
let slice: &[u8; 4] = self.buf[start..(start + 4)]
|
let slice: &[u8; 4] = self.buf[start..(start + 4)]
|
||||||
|
@ -535,7 +535,7 @@ impl Default for ObjectAttributeTable {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
|
||||||
pub struct ObjectAttribute {
|
pub(crate) struct ObjectAttribute {
|
||||||
y: u8,
|
y: u8,
|
||||||
x: u8,
|
x: u8,
|
||||||
tile_index: u8,
|
tile_index: u8,
|
||||||
|
@ -571,7 +571,7 @@ struct ObjectBuffer {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ObjectBuffer {
|
impl ObjectBuffer {
|
||||||
pub fn iter(&self) -> std::slice::Iter<'_, Option<ObjectAttribute>> {
|
pub(crate) fn iter(&self) -> std::slice::Iter<'_, Option<ObjectAttribute>> {
|
||||||
self.into_iter()
|
self.into_iter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -597,21 +597,21 @@ impl<'a> IntoIterator for &'a mut ObjectBuffer {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ObjectBuffer {
|
impl ObjectBuffer {
|
||||||
pub fn is_full(&self) -> bool {
|
pub(crate) fn is_full(&self) -> bool {
|
||||||
self.len == OBJECT_LIMIT
|
self.len == OBJECT_LIMIT
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear(&mut self) {
|
pub(crate) fn clear(&mut self) {
|
||||||
self.buf = [Default::default(); 10];
|
self.buf = [Default::default(); 10];
|
||||||
self.len = 0;
|
self.len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add(&mut self, attr: ObjectAttribute) {
|
pub(crate) fn add(&mut self, attr: ObjectAttribute) {
|
||||||
self.buf[self.len] = Some(attr);
|
self.buf[self.len] = Some(attr);
|
||||||
self.len += 1;
|
self.len += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove(&mut self, attr: &ObjectAttribute) {
|
pub(crate) fn remove(&mut self, attr: &ObjectAttribute) {
|
||||||
let maybe_index = self.buf.iter().position(|maybe_attr| match maybe_attr {
|
let maybe_index = self.buf.iter().position(|maybe_attr| match maybe_attr {
|
||||||
Some(other_attr) => attr == other_attr,
|
Some(other_attr) => attr == other_attr,
|
||||||
None => false,
|
None => false,
|
||||||
|
@ -640,13 +640,13 @@ struct PixelFetcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PixelFetcher {
|
impl PixelFetcher {
|
||||||
pub fn hblank_reset(&mut self) {
|
pub(crate) fn hblank_reset(&mut self) {
|
||||||
self.back.hblank_reset();
|
self.back.hblank_reset();
|
||||||
self.obj.hblank_reset();
|
self.obj.hblank_reset();
|
||||||
self.x_pos = 0;
|
self.x_pos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn vblank_reset(&mut self) {
|
pub(crate) fn vblank_reset(&mut self) {
|
||||||
self.back.vblank_reset();
|
self.back.vblank_reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -716,7 +716,11 @@ impl PixelFetcher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_obj_addr(attr: &ObjectAttribute, pos: &ScreenPosition, size: ObjectSize) -> u16 {
|
pub(crate) fn get_obj_addr(
|
||||||
|
attr: &ObjectAttribute,
|
||||||
|
pos: &ScreenPosition,
|
||||||
|
size: ObjectSize,
|
||||||
|
) -> u16 {
|
||||||
let line_y = pos.line_y;
|
let line_y = pos.line_y;
|
||||||
|
|
||||||
// TODO: Why is the offset 14 and 30 respectively?
|
// TODO: Why is the offset 14 and 30 respectively?
|
||||||
|
@ -837,21 +841,21 @@ struct WindowLineCounter {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WindowLineCounter {
|
impl WindowLineCounter {
|
||||||
pub fn increment(&mut self) {
|
pub(crate) fn increment(&mut self) {
|
||||||
self.count += 1;
|
self.count += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn vblank_reset(&mut self) {
|
pub(crate) fn vblank_reset(&mut self) {
|
||||||
self.count = 0;
|
self.count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn count(&self) -> u8 {
|
pub(crate) fn count(&self) -> u8 {
|
||||||
self.count
|
self.count
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum FetcherState {
|
pub(crate) enum FetcherState {
|
||||||
TileNumber,
|
TileNumber,
|
||||||
ToLowByteSleep,
|
ToLowByteSleep,
|
||||||
TileLowByte,
|
TileLowByte,
|
||||||
|
@ -890,15 +894,15 @@ struct FifoRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FifoRenderer {
|
impl FifoRenderer {
|
||||||
pub fn is_enabled(&self) -> bool {
|
pub(crate) fn is_enabled(&self) -> bool {
|
||||||
self.enabled
|
self.enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pause(&mut self) {
|
pub(crate) fn pause(&mut self) {
|
||||||
self.enabled = false;
|
self.enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resume(&mut self) {
|
pub(crate) fn resume(&mut self) {
|
||||||
self.enabled = true;
|
self.enabled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -921,19 +925,19 @@ struct TileBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TileBuilder {
|
impl TileBuilder {
|
||||||
pub fn with_id(&mut self, id: u8) {
|
pub(crate) fn with_id(&mut self, id: u8) {
|
||||||
self.id = Some(id);
|
self.id = Some(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_low_byte(&mut self, data: u8) {
|
pub(crate) fn with_low_byte(&mut self, data: u8) {
|
||||||
self.low = Some(data);
|
self.low = Some(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_high_byte(&mut self, data: u8) {
|
pub(crate) fn with_high_byte(&mut self, data: u8) {
|
||||||
self.high = Some(data);
|
self.high = Some(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bytes(&self) -> Option<(u8, u8)> {
|
pub(crate) fn bytes(&self) -> Option<(u8, u8)> {
|
||||||
self.high.zip(self.low)
|
self.high.zip(self.low)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -945,25 +949,25 @@ struct OamScanState {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OamScanState {
|
impl OamScanState {
|
||||||
pub fn increase(&mut self) {
|
pub(crate) fn increase(&mut self) {
|
||||||
self.count += 1;
|
self.count += 1;
|
||||||
self.count %= 40;
|
self.count %= 40;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reset(&mut self) {
|
pub(crate) fn reset(&mut self) {
|
||||||
self.count = Default::default();
|
self.count = Default::default();
|
||||||
self.mode = Default::default();
|
self.mode = Default::default();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn count(&self) -> u8 {
|
pub(crate) fn count(&self) -> u8 {
|
||||||
self.count
|
self.count
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mode(&self) -> OamScanMode {
|
pub(crate) fn mode(&self) -> OamScanMode {
|
||||||
self.mode
|
self.mode
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next(&mut self) {
|
pub(crate) fn next(&mut self) {
|
||||||
use OamScanMode::*;
|
use OamScanMode::*;
|
||||||
|
|
||||||
self.mode = match self.mode {
|
self.mode = match self.mode {
|
||||||
|
@ -995,19 +999,19 @@ struct WindowStatus {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WindowStatus {
|
impl WindowStatus {
|
||||||
pub fn should_draw(&self) -> bool {
|
pub(crate) fn should_draw(&self) -> bool {
|
||||||
self.should_draw
|
self.should_draw
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn coincidence(&self) -> bool {
|
pub(crate) fn coincidence(&self) -> bool {
|
||||||
self.coincidence
|
self.coincidence
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_should_draw(&mut self, value: bool) {
|
pub(crate) fn set_should_draw(&mut self, value: bool) {
|
||||||
self.should_draw = value;
|
self.should_draw = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_coincidence(&mut self, value: bool) {
|
pub(crate) fn set_coincidence(&mut self, value: bool) {
|
||||||
self.coincidence = value;
|
self.coincidence = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,7 +88,7 @@ impl Default for DmaControl {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DmaControl {
|
impl DmaControl {
|
||||||
pub fn update(&mut self, byte: u8, state: &mut DmaState) {
|
pub(crate) fn update(&mut self, byte: u8, state: &mut DmaState) {
|
||||||
let left = (byte as u16) << 8 | 0x0000;
|
let left = (byte as u16) << 8 | 0x0000;
|
||||||
let right = (byte as u16) << 8 | 0x009F;
|
let right = (byte as u16) << 8 | 0x009F;
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ bitfield! {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LCDStatus {
|
impl LCDStatus {
|
||||||
pub fn update(&mut self, byte: u8) {
|
pub(crate) fn update(&mut self, byte: u8) {
|
||||||
// Bytes 2 -> 0 are read only
|
// Bytes 2 -> 0 are read only
|
||||||
let mask = 0b00000111;
|
let mask = 0b00000111;
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ pub enum TileMapAddress {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TileMapAddress {
|
impl TileMapAddress {
|
||||||
pub fn into_address(self) -> u16 {
|
pub(crate) fn into_address(self) -> u16 {
|
||||||
match self {
|
match self {
|
||||||
TileMapAddress::X9800 => 0x9800,
|
TileMapAddress::X9800 => 0x9800,
|
||||||
TileMapAddress::X9C00 => 0x9C00,
|
TileMapAddress::X9C00 => 0x9C00,
|
||||||
|
@ -184,7 +184,7 @@ pub enum ObjectSize {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ObjectSize {
|
impl ObjectSize {
|
||||||
pub fn as_u8(&self) -> u8 {
|
pub(crate) fn as_u8(&self) -> u8 {
|
||||||
use ObjectSize::*;
|
use ObjectSize::*;
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
|
@ -226,7 +226,7 @@ bitfield! {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BackgroundPalette {
|
impl BackgroundPalette {
|
||||||
pub fn shade(&self, id: u8) -> GrayShade {
|
pub(crate) fn shade(&self, id: u8) -> GrayShade {
|
||||||
match id & 0b11 {
|
match id & 0b11 {
|
||||||
0b00 => self.i0_colour(),
|
0b00 => self.i0_colour(),
|
||||||
0b01 => self.i1_colour(),
|
0b01 => self.i1_colour(),
|
||||||
|
@ -271,7 +271,7 @@ bitfield! {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ObjectPalette {
|
impl ObjectPalette {
|
||||||
pub fn shade(&self, id: u8) -> Option<GrayShade> {
|
pub(crate) fn shade(&self, id: u8) -> Option<GrayShade> {
|
||||||
match id & 0b11 {
|
match id & 0b11 {
|
||||||
0b00 => None,
|
0b00 => None,
|
||||||
0b01 => Some(self.i1_colour()),
|
0b01 => Some(self.i1_colour()),
|
||||||
|
@ -307,16 +307,16 @@ impl From<ObjectPalette> for u8 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Pixels(u8, u8);
|
pub(crate) struct Pixels(u8, u8);
|
||||||
|
|
||||||
impl Pixels {
|
impl Pixels {
|
||||||
pub const PIXEL_COUNT: usize = 8;
|
pub(crate) const PIXEL_COUNT: usize = 8;
|
||||||
|
|
||||||
pub fn from_bytes(higher: u8, lower: u8) -> Self {
|
pub(crate) fn from_bytes(higher: u8, lower: u8) -> Self {
|
||||||
Self(higher, lower)
|
Self(higher, lower)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn shade_id(&self, x: usize) -> u8 {
|
pub(crate) fn shade_id(&self, x: usize) -> u8 {
|
||||||
let bit = 7 - x;
|
let bit = 7 - x;
|
||||||
|
|
||||||
let higher = self.0 >> bit;
|
let higher = self.0 >> bit;
|
||||||
|
@ -427,7 +427,7 @@ pub enum GrayShade {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GrayShade {
|
impl GrayShade {
|
||||||
pub fn into_rgba(self) -> [u8; 4] {
|
pub(crate) fn into_rgba(self) -> [u8; 4] {
|
||||||
match self {
|
match self {
|
||||||
GrayShade::White => WHITE,
|
GrayShade::White => WHITE,
|
||||||
GrayShade::LightGray => LIGHT_GRAY,
|
GrayShade::LightGray => LIGHT_GRAY,
|
||||||
|
@ -436,7 +436,7 @@ impl GrayShade {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_rgba(slice: &[u8]) -> Self {
|
pub(crate) fn from_rgba(slice: &[u8]) -> Self {
|
||||||
let rgba: [u8; 4] = slice
|
let rgba: [u8; 4] = slice
|
||||||
.try_into()
|
.try_into()
|
||||||
.expect("Unable to interpret &[u8] as [u8; 4]");
|
.expect("Unable to interpret &[u8] as [u8; 4]");
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use bitfield::bitfield;
|
use bitfield::bitfield;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Default)]
|
#[derive(Debug, Clone, Copy, Default)]
|
||||||
pub struct Serial {
|
pub(crate) struct Serial {
|
||||||
pub next: u8,
|
pub(crate) next: u8,
|
||||||
pub control: SerialControl,
|
pub(crate) control: SerialControl,
|
||||||
}
|
}
|
||||||
|
|
||||||
bitfield! {
|
bitfield! {
|
||||||
|
|
34
src/sound.rs
34
src/sound.rs
|
@ -1,22 +1,22 @@
|
||||||
use crate::instruction::Cycle;
|
use crate::instruction::Cycle;
|
||||||
use bitfield::bitfield;
|
use bitfield::bitfield;
|
||||||
#[derive(Debug, Clone, Copy, Default)]
|
#[derive(Debug, Clone, Copy, Default)]
|
||||||
pub struct Sound {
|
pub(crate) struct Sound {
|
||||||
pub control: SoundControl,
|
pub(crate) control: SoundControl,
|
||||||
pub ch1: Channel1,
|
pub(crate) ch1: Channel1,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Sound {
|
impl Sound {
|
||||||
pub fn step(&mut self, _cycles: Cycle) {
|
pub(crate) fn step(&mut self, _cycles: Cycle) {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Default)]
|
#[derive(Debug, Clone, Copy, Default)]
|
||||||
pub struct SoundControl {
|
pub(crate) struct SoundControl {
|
||||||
pub channel: ChannelControl,
|
pub(crate) channel: ChannelControl,
|
||||||
pub output: SoundOutput,
|
pub(crate) output: SoundOutput,
|
||||||
pub status: SoundStatus,
|
pub(crate) status: SoundStatus,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: What to do about the separation of freq bits
|
// TODO: What to do about the separation of freq bits
|
||||||
|
@ -79,7 +79,7 @@ impl From<u8> for FrequencyLow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_11bit_freq(low: &FrequencyLow, high: FrequencyHigh) -> u16 {
|
pub(crate) fn get_11bit_freq(low: &FrequencyLow, high: FrequencyHigh) -> u16 {
|
||||||
let high_bits = high.0 & 0b111;
|
let high_bits = high.0 & 0b111;
|
||||||
|
|
||||||
(low.0 as u16) << 8 | ((high_bits as u16) << 4)
|
(low.0 as u16) << 8 | ((high_bits as u16) << 4)
|
||||||
|
@ -143,11 +143,11 @@ impl From<SoundStatus> for u8 {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Default)]
|
#[derive(Debug, Clone, Copy, Default)]
|
||||||
pub struct Channel1 {
|
pub(crate) struct Channel1 {
|
||||||
pub sound_duty: SoundDuty,
|
pub(crate) sound_duty: SoundDuty,
|
||||||
pub vol_envelope: VolumeEnvelope,
|
pub(crate) vol_envelope: VolumeEnvelope,
|
||||||
pub freq_hi: FrequencyHigh,
|
pub(crate) freq_hi: FrequencyHigh,
|
||||||
pub freq_lo: FrequencyLow,
|
pub(crate) freq_lo: FrequencyLow,
|
||||||
}
|
}
|
||||||
|
|
||||||
bitfield! {
|
bitfield! {
|
||||||
|
@ -206,10 +206,10 @@ impl Default for EnvelopeDirection {
|
||||||
}
|
}
|
||||||
|
|
||||||
bitfield! {
|
bitfield! {
|
||||||
pub struct SoundDuty(u8);
|
pub struct SoundDuty(u8);
|
||||||
impl Debug;
|
impl Debug;
|
||||||
pub from into WavePattern, wave_pattern, set_wave_pattern: 7, 6;
|
pub from into WavePattern, wave_pattern, set_wave_pattern: 7, 6;
|
||||||
pub _, set_sound_length: 5, 0; // TODO: Getter only used if bit 6 in NR14 is set
|
pub _, set_sound_length: 5, 0; // TODO: Getter only used if bit 6 in NR14 is set
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Copy for SoundDuty {}
|
impl Copy for SoundDuty {}
|
||||||
|
|
16
src/timer.rs
16
src/timer.rs
|
@ -2,17 +2,17 @@ use crate::Cycle;
|
||||||
use bitfield::bitfield;
|
use bitfield::bitfield;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct Timer {
|
pub(crate) struct Timer {
|
||||||
pub control: TimerControl,
|
pub(crate) control: TimerControl,
|
||||||
pub counter: u8,
|
pub(crate) counter: u8,
|
||||||
pub modulo: u8,
|
pub(crate) modulo: u8,
|
||||||
pub divider: u16,
|
pub(crate) divider: u16,
|
||||||
prev_and_result: Option<u8>,
|
prev_and_result: Option<u8>,
|
||||||
interrupt: bool,
|
interrupt: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Timer {
|
impl Timer {
|
||||||
pub fn step(&mut self, cycles: Cycle) {
|
pub(crate) fn step(&mut self, cycles: Cycle) {
|
||||||
use TimerSpeed::*;
|
use TimerSpeed::*;
|
||||||
|
|
||||||
for _ in 0..cycles.into() {
|
for _ in 0..cycles.into() {
|
||||||
|
@ -52,11 +52,11 @@ impl Timer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn interrupt(&self) -> bool {
|
pub(crate) fn interrupt(&self) -> bool {
|
||||||
self.interrupt
|
self.interrupt
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_interrupt(&mut self, value: bool) {
|
pub(crate) fn set_interrupt(&mut self, value: bool) {
|
||||||
self.interrupt = value;
|
self.interrupt = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,16 +4,16 @@ const WORK_RAM_START_ADDRESS: usize = 0xC000;
|
||||||
const VARIABLE_WORK_RAM_START_ADDRESS: usize = 0xD000;
|
const VARIABLE_WORK_RAM_START_ADDRESS: usize = 0xD000;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct WorkRam {
|
pub(crate) struct WorkRam {
|
||||||
bank: Box<[u8; WORK_RAM_SIZE]>,
|
bank: Box<[u8; WORK_RAM_SIZE]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WorkRam {
|
impl WorkRam {
|
||||||
pub fn write_byte(&mut self, addr: u16, byte: u8) {
|
pub(crate) fn write_byte(&mut self, addr: u16, byte: u8) {
|
||||||
self.bank[addr as usize - WORK_RAM_START_ADDRESS] = byte;
|
self.bank[addr as usize - WORK_RAM_START_ADDRESS] = byte;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_byte(&self, addr: u16) -> u8 {
|
pub(crate) fn read_byte(&self, addr: u16) -> u8 {
|
||||||
self.bank[addr as usize - WORK_RAM_START_ADDRESS]
|
self.bank[addr as usize - WORK_RAM_START_ADDRESS]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ impl Default for WorkRam {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum BankNumber {
|
pub(crate) enum BankNumber {
|
||||||
One = 1,
|
One = 1,
|
||||||
Two = 2,
|
Two = 2,
|
||||||
Three = 3,
|
Three = 3,
|
||||||
|
@ -38,7 +38,7 @@ pub enum BankNumber {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct VariableWorkRam {
|
pub(crate) struct VariableWorkRam {
|
||||||
current: BankNumber,
|
current: BankNumber,
|
||||||
bank_n: Box<[[u8; VARIABLE_WORK_RAM_SIZE]; 7]>, // 4K for Variable amount of Banks (Banks 1 -> 7) in Game Boy Colour
|
bank_n: Box<[[u8; VARIABLE_WORK_RAM_SIZE]; 7]>, // 4K for Variable amount of Banks (Banks 1 -> 7) in Game Boy Colour
|
||||||
}
|
}
|
||||||
|
@ -53,19 +53,19 @@ impl Default for VariableWorkRam {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VariableWorkRam {
|
impl VariableWorkRam {
|
||||||
pub fn set_current_bank(&mut self, bank: BankNumber) {
|
pub(crate) fn set_current_bank(&mut self, bank: BankNumber) {
|
||||||
self.current = bank;
|
self.current = bank;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_current_bank(&self) -> BankNumber {
|
pub(crate) fn get_current_bank(&self) -> BankNumber {
|
||||||
self.current
|
self.current
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_byte(&mut self, addr: u16, byte: u8) {
|
pub(crate) fn write_byte(&mut self, addr: u16, byte: u8) {
|
||||||
self.bank_n[self.current as usize][addr as usize - VARIABLE_WORK_RAM_START_ADDRESS] = byte;
|
self.bank_n[self.current as usize][addr as usize - VARIABLE_WORK_RAM_START_ADDRESS] = byte;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_byte(&self, addr: u16) -> u8 {
|
pub(crate) fn read_byte(&self, addr: u16) -> u8 {
|
||||||
self.bank_n[self.current as usize][addr as usize - VARIABLE_WORK_RAM_START_ADDRESS]
|
self.bank_n[self.current as usize][addr as usize - VARIABLE_WORK_RAM_START_ADDRESS]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue