diff options
-rw-r--r-- | src/core.rs | 70 |
1 files changed, 55 insertions, 15 deletions
diff --git a/src/core.rs b/src/core.rs index f2fa7e0..021b04f 100644 --- a/src/core.rs +++ b/src/core.rs @@ -1,11 +1,32 @@ use std::fmt; -#[derive(Debug)] -pub enum Op { +#[derive(Debug, Clone)] +pub enum Opcode { Nop, + Push, + Pop, Illegal, } +#[derive(Debug, Clone)] +pub struct Op { + opcode: Opcode, + size: usize, + operand1: Option<u8>, + operand2: Option<u8>, + operand3: Option<u8>, +} + +const OPCODE_NOP: u8 = 0x00; +const OPCODE_PUSH: u8 = 0xC0; +const OPCODE_POP: u8 = 0xD0; + +impl fmt::Display for Opcode { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:?}", self) + } +} + impl fmt::Display for Op { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?}", self) @@ -19,33 +40,52 @@ pub struct Core { impl Core { pub fn new() -> Self { - Core { pc: 0, ram: [0; u16::max_value() as usize + 1] } + Core { pc: 0, ram: [0; u16::max_value() as usize + 1]} } pub fn step(&mut self) -> u16 { - self.pc += self.ram[self.pc as usize].op_size(); + let op = self.fetch(); + self.exec(op); self.pc } - pub fn op(&self) -> Op { - self.ram[self.pc as usize].op() + pub fn op(&self) -> Opcode { + self.ram[self.pc as usize].op().0 + } + + fn fetch(&mut self) -> Op { + let (opcode, size) = self.ram[self.pc as usize].op(); + self.pc += size as u16; + Op { + opcode, + size, + operand1: None, + operand2: None, + operand3: None, + } + } + + fn exec(&mut self, op: Op) -> () { + match op.opcode { + Opcode::Nop => (), + Opcode::Illegal => (), + Opcode::Push => (), + Opcode::Pop => (), + } } } pub trait Isa { - fn op(&self) -> Op; - fn op_size(&self) -> u16; + fn op(&self) -> (Opcode, usize); } impl Isa for u8 { - fn op(&self) -> Op { + fn op(&self) -> (Opcode, usize) { match *self { - 0 => Op::Nop, - _ => Op::Illegal + OPCODE_NOP => (Opcode::Nop, 1), + OPCODE_PUSH => (Opcode::Push, 2), + OPCODE_POP => (Opcode::Pop, 2), + _ => (Opcode::Illegal, 1), } } - - fn op_size(&self) -> u16 { - 1 - } } |