-
-
Save steffahn/0594a2c945a455a304fa1d76d808c47d to your computer and use it in GitHub Desktop.
Dmg
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::ops::{Deref, DerefMut}; | |
pub struct CpuState { | |
pc: u16, | |
} | |
impl CpuState { | |
pub fn new() -> CpuState { | |
CpuState { pc: 0 } | |
} | |
pub fn pc(&self) -> u16 { | |
self.pc | |
} | |
} | |
use ref_cast::RefCast; | |
#[derive(RefCast)] | |
#[repr(transparent)] | |
pub struct Cpu<C> { | |
context: C, | |
} | |
pub trait CpuContext: AsRef<CpuState> + AsMut<CpuState> { | |
fn on_fetch_op(&mut self) -> u8; | |
} | |
impl<C: CpuContext> Deref for Cpu<C> { | |
type Target = CpuState; | |
fn deref(&self) -> &CpuState { | |
self.context.as_ref() | |
} | |
} | |
impl<C: CpuContext> DerefMut for Cpu<C> { | |
fn deref_mut(&mut self) -> &mut CpuState { | |
self.context.as_mut() | |
} | |
} | |
impl<C: CpuContext> Cpu<C> { | |
pub fn tick(&mut self) { | |
let opcode = self.fetch_op(); | |
if opcode == 0xCB { | |
let cb_opcode = self.fetch_op(); | |
self.exec_cb_op(opcode, cb_opcode); | |
} else { | |
self.exec_op(opcode); | |
} | |
} | |
fn fetch_op(&mut self) -> u8 { | |
let opcode = self.context.on_fetch_op(); | |
self.pc += 1; | |
opcode | |
} | |
fn exec_op(&self, code: u8) { | |
// unimplemented | |
} | |
fn exec_cb_op(&self, code: u8, cb_code: u8) { | |
// unimplemented | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* in Cargo.toml: | |
[dependencies] | |
derive_more = "0.99.11" | |
ref-cast = "1.0.3" | |
*/ | |
mod cpu; | |
mod mmu; | |
use cpu::{Cpu, CpuContext, CpuState}; | |
use mmu::{Mmu, MmuContext, MmuState}; | |
use ref_cast::RefCast; | |
use derive_more::*; | |
#[derive(AsRef, AsMut)] | |
pub struct Dmg { | |
cpu_state: CpuState, | |
mmu_state: MmuState, | |
} | |
impl Dmg { | |
fn cpu(&self) -> &Cpu<Self> { | |
Cpu::ref_cast(self) | |
} | |
fn cpu_mut(&mut self) -> &mut Cpu<Self> { | |
Cpu::ref_cast_mut(self) | |
} | |
fn mmu(&self) -> &Mmu<Self> { | |
Mmu::ref_cast(self) | |
} | |
fn mmu_mut(&mut self) -> &mut Mmu<Self> { | |
Mmu::ref_cast_mut(self) | |
} | |
pub fn new() -> Self { | |
Self { | |
cpu_state: CpuState::new(), | |
mmu_state: MmuState::new(), | |
} | |
} | |
} | |
impl CpuContext for Dmg { | |
fn on_fetch_op(&mut self) -> u8 { | |
let pc = self.cpu().pc(); | |
self.mmu_mut().read(pc).unwrap() | |
} | |
} | |
impl MmuContext for Dmg {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::ops::{Deref, DerefMut}; | |
pub struct MmuState; | |
impl MmuState { | |
pub fn new() -> Self { | |
MmuState | |
} | |
} | |
pub trait MmuContext: AsRef<MmuState> + AsMut<MmuState> {} | |
use ref_cast::RefCast; | |
#[derive(RefCast)] | |
#[repr(transparent)] | |
pub struct Mmu<C> { | |
context: C, | |
} | |
impl<C: MmuContext> Deref for Mmu<C> { | |
type Target = MmuState; | |
fn deref(&self) -> &MmuState { | |
self.context.as_ref() | |
} | |
} | |
impl<C: MmuContext> DerefMut for Mmu<C> { | |
fn deref_mut(&mut self) -> &mut MmuState { | |
self.context.as_mut() | |
} | |
} | |
impl<C: MmuContext> Mmu<C> { | |
// guessing the type here | |
pub fn read(&mut self, addr: u16) -> Option<u8> { | |
Some(42) // stub | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment