Skip to content

Instantly share code, notes, and snippets.

@steffahn

steffahn/cpu.rs Secret

Last active December 23, 2020 14:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save steffahn/0594a2c945a455a304fa1d76d808c47d to your computer and use it in GitHub Desktop.
Save steffahn/0594a2c945a455a304fa1d76d808c47d to your computer and use it in GitHub Desktop.
Dmg
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
}
}
/* 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 {}
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