Skip to content

Instantly share code, notes, and snippets.

@yupferris
Last active January 24, 2020 20:22
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 yupferris/da34f3f64ca9777fd173cfa4d39ac1a2 to your computer and use it in GitHub Desktop.
Save yupferris/da34f3f64ca9777fd173cfa4d39ac1a2 to your computer and use it in GitHub Desktop.
emu shiz
struct Emu {
wram: [u8; lots],
sub_cpu_1: SubCpu1,
sub_cpu_2: SubCpu2,
}
impl Emu {
fn cycle(&mut self) {
self.sub_cpu_1.cycle(&mut self.wram); // "splitting" borrow is ok here since we borrow disjoint elements of self
...
}
}
struct SubCpu1 {
// internal regs/state, no references to anything else, except perhaps local memory
}
impl SubCpu1 {
fn cycle(&mut self, mem: &mut [u8]) {
// Modify local state via self and mem as we please
}
}
...
struct RegFile {
mem: [u32; 32],
read_addr: u32,
write_addr: u32,
write_value: u32,
}
struct Cpu {
reg_file: RegFile,
pc: u32,
// Register between IF / DE stages
if_de_instruction_word: u32,
// Register between DE / EX stages
de_ex_reg_file_read_addr: u32,
}
impl Cpu {
fn cycle(&mut self, &mut instruction_mem /* maybe this is local? I think it is for eg. RSP */) {
// Propagate combinational signals
// IF stage
let if_de_instruction_word_next = instruction_mem[self.pc];
let mut pc_next = self.pc + 1; // Another stage might override this value (modeling a priority encoder)
// DE stage
let de_ex_reg_file_read_addr_next = self.if_de_instruction_word & 0x1f;
// EX stage
let reg = self.reg_file.mem[self.de_ex_reg_file_read_addr];
// pretend we decoded a jmp instruction..
pc_next = reg;
// Clock registers (and maybe update reg_file mem or whatever..)
self.pc = pc_next;
self.if_de_instruction_word = if_de_instruction_word_next;
self.de_ex_reg_file_read_addr = de_ex_reg_file_read_addr_next;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment