diff --git a/src/apu.rs b/src/apu.rs index ab01142..9c7fa7d 100644 --- a/src/apu.rs +++ b/src/apu.rs @@ -17,7 +17,7 @@ const AUDIO_BUFFER_LEN: usize = 512; const CHANNEL_COUNT: usize = 2; const SAMPLE_INCREMENT: u64 = SAMPLE_RATE as u64; -#[derive(Default, Debug, Clone)] +#[derive(Default, Debug)] pub struct Apu { ctrl: SoundControl, /// Tone & Sweep @@ -349,7 +349,7 @@ impl Apu { } } -#[derive(Debug, Clone, Copy, Default)] +#[derive(Debug, Default)] pub(crate) struct SoundControl { /// 0xFF24 | NR50 - Channel Control channel: ChannelControl, @@ -394,7 +394,7 @@ impl SoundControl { } } -#[derive(Debug, Clone, Copy, Default)] +#[derive(Debug, Default)] pub(crate) struct Channel1 { /// 0xFF10 | NR10 - Channel 1 Sweep Register sweep: Sweep, @@ -557,7 +557,7 @@ impl Channel1 { } } -#[derive(Debug, Clone, Copy, Default)] +#[derive(Debug, Default)] pub(crate) struct Channel2 { /// 0xFF16 | NR21 - Channel 2 Sound length / Wave Pattern Duty duty: SoundDuty, @@ -660,7 +660,7 @@ impl Channel2 { } } -#[derive(Debug, Clone, Copy, Default)] +#[derive(Debug, Default)] pub(crate) struct Channel3 { /// 0xFF1A | NR30 - Channel 3 Sound on/off enabled: bool, @@ -798,7 +798,7 @@ impl Channel3 { } } -#[derive(Debug, Clone, Copy, Default)] +#[derive(Debug, Default)] pub(crate) struct Channel4 { /// 0xFF20 | NR41 - Channel 4 Sound Length len: u8, diff --git a/src/apu/gen.rs b/src/apu/gen.rs index 315a8fb..701821b 100644 --- a/src/apu/gen.rs +++ b/src/apu/gen.rs @@ -16,7 +16,7 @@ impl AudioMPSC { } } -#[derive(Debug, Clone)] +#[derive(Debug)] pub struct AudioSender { inner: Sender, } @@ -64,7 +64,7 @@ impl Source for AudioReceiver { } } -#[derive(Debug, Clone)] +#[derive(Debug)] pub(crate) struct AudioBuffer { inner: VecDeque, } diff --git a/src/bus.rs b/src/bus.rs index ece6cd5..e0395fd 100644 --- a/src/bus.rs +++ b/src/bus.rs @@ -11,7 +11,7 @@ use std::{fs::File, io::Read}; const BOOT_ROM_SIZE: usize = 0x100; -#[derive(Debug, Clone)] +#[derive(Debug)] pub struct Bus { boot: Option<[u8; BOOT_ROM_SIZE]>, // Boot ROM is 256b long cartridge: Option, diff --git a/src/cartridge.rs b/src/cartridge.rs index e30154a..7e0403f 100644 --- a/src/cartridge.rs +++ b/src/cartridge.rs @@ -8,7 +8,7 @@ const RAM_SIZE_ADDRESS: usize = 0x0149; const ROM_SIZE_ADDRESS: usize = 0x0148; const MBC_TYPE_ADDRESS: usize = 0x0147; -#[derive(Debug, Clone, Default)] +#[derive(Debug, Default)] pub(crate) struct Cartridge { memory: Vec, title: Option, @@ -144,7 +144,7 @@ impl BusIo for Cartridge { } } -#[derive(Debug, Clone)] +#[derive(Debug)] struct Mbc1 { /// 5-bit number rom_bank: u8, @@ -293,7 +293,7 @@ enum MBC3Device { RealTimeClock, } -#[derive(Debug, Clone, Default)] +#[derive(Debug, Default)] struct MBC3 { /// 7-bit Number rom_bank: u8, @@ -361,7 +361,7 @@ impl MemoryBankController for MBC3 { } } -#[derive(Debug, Clone, Copy)] +#[derive(Debug)] struct NoMbc {} impl MemoryBankController for NoMbc { @@ -374,24 +374,11 @@ impl MemoryBankController for NoMbc { } } -trait MemoryBankController: CloneMbc { +trait MemoryBankController { fn handle_read(&self, addr: u16) -> MbcResult; fn handle_write(&mut self, addr: u16, byte: u8); } -trait CloneMbc { - fn clone_mbc(&self) -> Box; -} - -impl CloneMbc for T -where - T: MemoryBankController + Clone + 'static, -{ - fn clone_mbc<'a>(&self) -> Box { - Box::new(self.clone()) - } -} - #[derive(Debug, Clone, Copy)] enum MbcResult { Address(usize), @@ -485,7 +472,7 @@ impl Default for BankCount { impl BankCount { // https://hacktix.github.io/GBEDG/mbcs/#rom-size - fn size(self) -> u32 { + fn size(&self) -> u32 { use BankCount::*; match self { @@ -533,12 +520,6 @@ impl std::fmt::Debug for Box { } } -impl std::clone::Clone for Box { - fn clone(&self) -> Self { - self.clone_mbc() - } -} - impl Default for Box { fn default() -> Self { Box::new(Mbc1::default()) diff --git a/src/cpu.rs b/src/cpu.rs index 69ca081..fbe74a1 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -8,7 +8,7 @@ use crate::timer::Timer; use bitfield::bitfield; use std::fmt::{Display, Formatter, Result as FmtResult}; -#[derive(Debug, Clone, Default)] +#[derive(Debug, Default)] pub struct Cpu { pub bus: Bus, reg: Registers, @@ -45,8 +45,8 @@ impl Cpu { }) } - pub(crate) fn ime(&self) -> ImeState { - self.ime + pub(crate) fn ime(&self) -> &ImeState { + &self.ime } pub(crate) fn set_ime(&mut self, state: ImeState) { @@ -61,8 +61,8 @@ impl Cpu { self.halted = None; } - pub(crate) fn halted(&self) -> Option { - self.halted + pub(crate) fn halted(&self) -> Option<&HaltState> { + self.halted.as_ref() } fn inc_pc(&mut self) { @@ -267,7 +267,7 @@ impl Cpu { } } -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Clone, Copy)] enum State { Execute, // Halt, @@ -400,7 +400,7 @@ impl Cpu { } } -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Clone, Copy)] pub(crate) enum Register { A, B, @@ -412,7 +412,7 @@ pub(crate) enum Register { Flag, } -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Clone, Copy)] pub(crate) enum RegisterPair { AF, BC, @@ -422,7 +422,7 @@ pub(crate) enum RegisterPair { PC, } -#[derive(Debug, Copy, Clone, Default)] +#[derive(Debug, Default)] struct Registers { a: u8, b: u8, diff --git a/src/instruction.rs b/src/instruction.rs index 126f772..197d97b 100644 --- a/src/instruction.rs +++ b/src/instruction.rs @@ -2,7 +2,7 @@ use crate::bus::BusIo; use crate::cpu::{Cpu, Flags, HaltState, ImeState, Register, RegisterPair}; use std::{convert::TryFrom, fmt::Debug}; -#[derive(Copy, Clone)] +#[derive(Clone, Copy)] #[allow(clippy::upper_case_acronyms)] pub(crate) enum Instruction { NOP, @@ -51,26 +51,26 @@ pub(crate) enum Instruction { SET(u8, InstrRegister), } -#[derive(Copy, Clone)] +#[derive(Clone, Copy)] pub(crate) enum JPTarget { RegisterPair(RegisterPair), ImmediateWord(u16), } -#[derive(Copy, Clone)] +#[derive(Clone, Copy)] pub(crate) enum Registers { Byte(InstrRegister), Word(RegisterPair), } -#[derive(Copy, Clone)] +#[derive(Clone, Copy)] pub(crate) enum MATHTarget { Register(InstrRegister), RegisterPair(RegisterPair), ImmediateByte(u8), } -#[derive(Copy, Clone)] +#[derive(Clone, Copy)] pub(crate) enum LDTarget { IndirectC, Register(InstrRegister), @@ -82,7 +82,7 @@ pub(crate) enum LDTarget { ByteAtAddressWithOffset(u8), } -#[derive(Copy, Clone)] +#[derive(Clone, Copy)] pub(crate) enum InstrRegisterPair { AF, BC, @@ -94,7 +94,7 @@ pub(crate) enum InstrRegisterPair { DecrementHL, } -#[derive(Copy, Clone)] +#[derive(Clone, Copy)] pub(crate) enum InstrRegister { A, B, @@ -106,7 +106,7 @@ pub(crate) enum InstrRegister { IndirectHL, // (HL) } -#[derive(Copy, Clone)] +#[derive(Clone, Copy)] pub(crate) enum JumpCondition { NotZero, Zero, @@ -115,7 +115,7 @@ pub(crate) enum JumpCondition { Always, } -#[derive(Debug, Copy, Clone)] +#[derive(Debug)] struct Table; #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Default)] diff --git a/src/interrupt.rs b/src/interrupt.rs index 7015965..b6aed43 100644 --- a/src/interrupt.rs +++ b/src/interrupt.rs @@ -1,6 +1,6 @@ use bitfield::bitfield; -#[derive(Debug, Clone, Copy, Default)] +#[derive(Debug, Default)] pub(crate) struct Interrupt { pub(crate) flag: InterruptFlag, pub(crate) enable: InterruptEnable, diff --git a/src/joypad.rs b/src/joypad.rs index d475bd1..66537df 100644 --- a/src/joypad.rs +++ b/src/joypad.rs @@ -1,7 +1,7 @@ use gilrs::{Button, Event as GamepadEvent, EventType as GamepadEventType}; use winit_input_helper::WinitInputHelper; -#[derive(Debug, Clone, Copy)] +#[derive(Debug)] pub struct Joypad { /// 0xFF00 | P1/JOYP - Player 1 Joypad pub(crate) p1: u8, @@ -48,7 +48,7 @@ impl Joypad { } } -#[derive(Debug, Clone, Copy, Default)] +#[derive(Debug, Default)] struct JoypadState { // Direction Row dpad_down: ButtonEvent, diff --git a/src/ppu.rs b/src/ppu.rs index 424ae4e..aa04567 100644 --- a/src/ppu.rs +++ b/src/ppu.rs @@ -33,7 +33,7 @@ const LIGHT_GRAY: [u8; 4] = 0xAEBA89FFu32.to_be_bytes(); const DARK_GRAY: [u8; 4] = 0x5E6745FFu32.to_be_bytes(); const BLACK: [u8; 4] = 0x202020FFu32.to_be_bytes(); -#[derive(Debug, Clone)] +#[derive(Debug)] pub struct Ppu { pub(crate) int: Interrupt, /// 0xFF40 | LCDC - LCD Control @@ -489,7 +489,7 @@ impl Default for Ppu { } } -#[derive(Debug, Clone, Copy, Default)] +#[derive(Debug, Default)] pub(crate) struct Interrupt { _vblank: bool, _lcd_stat: bool, @@ -513,7 +513,7 @@ impl Interrupt { } } -#[derive(Debug, Clone, Copy, Default)] +#[derive(Debug, Default)] pub(crate) struct ScreenPosition { /// 0xFF42 | SCY - Scroll Y pub(crate) scroll_y: u8, @@ -529,7 +529,7 @@ pub(crate) struct ScreenPosition { pub(crate) window_x: u8, } -#[derive(Debug, Clone, Copy, Default)] +#[derive(Debug, Default)] pub(crate) struct Monochrome { /// 0xFF47 | BGP - Background Palette Data pub(crate) bg_palette: BackgroundPalette, @@ -539,7 +539,7 @@ pub(crate) struct Monochrome { pub(crate) obj_palette_1: ObjectPalette, } -#[derive(Debug, Clone)] +#[derive(Debug)] pub(crate) struct ObjectAttributeTable { buf: Box<[u8; OAM_SIZE]>, } @@ -606,7 +606,7 @@ impl<'a> From<&'a [u8; 4]> for ObjectAttribute { } } -#[derive(Debug, Clone, Copy)] +#[derive(Debug)] struct ObjectBuffer { buf: [Option; OBJECT_LIMIT], len: usize, @@ -674,7 +674,7 @@ impl Default for ObjectBuffer { } } -#[derive(Debug, Clone, Copy, Default)] +#[derive(Debug, Default)] struct PixelFetcher { x_pos: u8, back: BackgroundFetcher, @@ -793,7 +793,7 @@ trait Fetcher { fn hblank_reset(&mut self); } -#[derive(Debug, Clone, Copy)] +#[derive(Debug)] struct BackgroundFetcher { state: FetcherState, tile: TileBuilder, @@ -859,7 +859,7 @@ impl Default for BackgroundFetcher { } } -#[derive(Debug, Clone, Copy, Default)] +#[derive(Debug, Default)] struct ObjectFetcher { state: FetcherState, tile: TileBuilder, @@ -881,7 +881,7 @@ impl Fetcher for ObjectFetcher { } } -#[derive(Debug, Clone, Copy, Default)] +#[derive(Debug, Default)] struct WindowLineCounter { count: u8, } @@ -918,12 +918,12 @@ impl Default for FetcherState { } } -#[derive(Debug, Clone, Copy, Default)] +#[derive(Debug, Default)] struct BgPixelProperty { shade_id: u8, } -#[derive(Debug, Clone, Copy, Default)] +#[derive(Debug, Default)] struct ObjPixelProperty { shade_id: u8, palette_kind: ObjectPaletteKind, @@ -932,7 +932,7 @@ struct ObjPixelProperty { // FIXME: Fifo Registers have a known size. Are heap allocations // really necessary here? -#[derive(Debug, Clone)] +#[derive(Debug)] struct PixelFifo { back: VecDeque, obj: VecDeque, @@ -963,7 +963,7 @@ impl Default for PixelFifo { } } -#[derive(Debug, Clone, Copy, Default)] +#[derive(Debug, Default)] struct TileBuilder { id: Option, low: Option, @@ -988,7 +988,7 @@ impl TileBuilder { } } -#[derive(Debug, Clone, Copy, Default)] +#[derive(Debug, Default)] struct OamScanState { count: u8, mode: OamScanMode, @@ -1009,8 +1009,8 @@ impl OamScanState { self.count } - fn mode(&self) -> OamScanMode { - self.mode + fn mode(&self) -> &OamScanMode { + &self.mode } fn next(&mut self) { @@ -1035,7 +1035,7 @@ impl Default for OamScanMode { } } -#[derive(Debug, Clone, Copy, Default)] +#[derive(Debug, Default)] struct WindowStatus { /// This will be true if WY == LY at any point in the frame thus far coincidence: bool, diff --git a/src/ppu/dma.rs b/src/ppu/dma.rs index c76e7f1..129d9ca 100644 --- a/src/ppu/dma.rs +++ b/src/ppu/dma.rs @@ -1,6 +1,6 @@ use crate::instruction::Cycle; -#[derive(Debug, Default, Clone)] +#[derive(Debug, Default)] pub(crate) struct DirectMemoryAccess { pub(crate) state: DmaState, cycle: Cycle, @@ -28,7 +28,7 @@ impl DirectMemoryAccess { let src_addr = self .start - .addr + .0 .as_mut() .expect("Source Address present during DMA Transfer"); @@ -58,7 +58,7 @@ impl DirectMemoryAccess { fn reset(&mut self) { self.cycle = Cycle::new(0); self.state = DmaState::Disabled; - self.start.addr = None; + self.start.0 = None; } } @@ -75,26 +75,21 @@ impl Default for DmaState { } } -#[derive(Debug, Default, Clone, Copy)] -pub(crate) struct DmaAddress { - /// The current *source* address of the DMA Transfer - /// - /// NB: Will be None if no DMA Transfer is in progress - addr: Option, -} +#[derive(Debug, Clone, Copy, Default)] +pub(crate) struct DmaAddress(Option); impl DmaAddress { pub(crate) fn update(&mut self, byte: u8, state: &mut DmaState) { let start = (byte as u16) << 8; - self.addr = Some(start); + self.0 = Some(start); *state = DmaState::Pending; } } impl From for u8 { fn from(ctrl: DmaAddress) -> Self { - match ctrl.addr { + match ctrl.0 { Some(addr) => (addr >> 8) as u8, None => 0xFF, // TODO: What garbage value should be here? } diff --git a/src/serial.rs b/src/serial.rs index af51093..f0e8804 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -1,6 +1,6 @@ use bitfield::bitfield; -#[derive(Debug, Clone, Copy, Default)] +#[derive(Debug, Default)] pub(crate) struct Serial { /// 0xFF01 | SB - Serial Transfer Data pub(crate) next: u8, diff --git a/src/timer.rs b/src/timer.rs index 3c7cfa4..c496edf 100644 --- a/src/timer.rs +++ b/src/timer.rs @@ -1,6 +1,6 @@ use bitfield::bitfield; -#[derive(Debug, Clone, Copy)] +#[derive(Debug)] pub(crate) struct Timer { /// 0xFF07 | TAC - Timer Control pub(crate) ctrl: TimerControl, diff --git a/src/work_ram.rs b/src/work_ram.rs index df587f6..c1118d9 100644 --- a/src/work_ram.rs +++ b/src/work_ram.rs @@ -5,7 +5,7 @@ const VARIABLE_WORK_RAM_SIZE: usize = WORK_RAM_SIZE; const WORK_RAM_START_ADDRESS: usize = 0xC000; const VARIABLE_WORK_RAM_START_ADDRESS: usize = 0xD000; -#[derive(Debug, Clone)] +#[derive(Debug)] pub(crate) struct WorkRam { bank: Box<[u8; WORK_RAM_SIZE]>, } @@ -39,7 +39,7 @@ enum BankNumber { Seven = 7, } -#[derive(Debug, Clone)] +#[derive(Debug)] pub(crate) struct VariableWorkRam { current: BankNumber, bank_n: Box<[[u8; VARIABLE_WORK_RAM_SIZE]; 7]>, // 4K for Variable amount of Banks (Banks 1 -> 7) in Game Boy Colour @@ -59,8 +59,8 @@ impl VariableWorkRam { self.current = bank; } - fn get_current_bank(&self) -> BankNumber { - self.current + fn get_current_bank(&self) -> &BankNumber { + &self.current } }