summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorOxore <oxore@protonmail.com>2019-07-14 22:24:27 +0300
committerOxore <oxore@protonmail.com>2019-07-14 22:24:27 +0300
commitdb5eddf74f52cf10b7342c8d261dd25b49a31700 (patch)
tree952e350e49588a4d5d794d0173f84cc4e56b0fed /src
parent7350d34209983f2943fc28ef0b63d3d87167efeb (diff)
Rework internal operation concept
Rename enum Op to Opcode. Create struct Op that contains all the info about instruction. Implement immutable fetch method that is meant to get the whole instruction. Add exec method skeleton. Add opcodes of NOP, PUSH and POP. Still Don't know what to do with illegal operations.
Diffstat (limited to 'src')
-rw-r--r--src/core.rs70
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
- }
}