aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkrolxon <krolyxon@tutanota.com>2026-01-04 18:47:43 +0530
committerkrolxon <krolyxon@tutanota.com>2026-01-04 18:47:43 +0530
commit798ac8ce75e2784e9e412f9ea7778b80b077c1dd (patch)
treef59a7fe2ff085f8a250d36d361a2b70e35feff0a
parent4809d7159f373a358da4932571e2219b39b561ed (diff)
refactor the cpu logic to cpu module
-rw-r--r--src/cpu.rs113
-rw-r--r--src/main.rs121
2 files changed, 118 insertions, 116 deletions
diff --git a/src/cpu.rs b/src/cpu.rs
index 8b63433..ceef8a3 100644
--- a/src/cpu.rs
+++ b/src/cpu.rs
@@ -1,3 +1,5 @@
+use crate::memory::{self, Memory};
+
#[derive(Default)]
#[derive(Debug)]
pub struct CPU{
@@ -19,4 +21,115 @@ impl CPU {
pub fn inc_cp(&mut self) {
self.pc += 1;
}
+
+ pub fn halt(&mut self) {
+ self.halted = true;
+ }
+
+ pub fn mov(&mut self, mem: &mut Memory) {
+ let reg = mem.read(self.pc); self.inc_cp();
+ let val = mem.read(self.pc); self.inc_cp();
+
+ match reg {
+ 0 => self.a = val,
+ 1 => self.b = val,
+ 2 => self.c = val,
+ 3 => self.d = val,
+ _ => {}
+ }
+ }
+
+ pub fn add(&mut self, mem:&mut Memory) {
+
+ let dest = mem.read(self.pc); self.pc += 1;
+ let src = mem.read(self.pc); self.pc += 1;
+
+ let (result, carry) = match (dest, src) {
+ // What the fuck do these tuples mean?
+ // so basically they are the numbers assigned to register
+ // 0 => A, 1 => B ....
+ // so when it is (0, 0), it basically says add the
+ // value of register B into register A,
+ // thats exactly whats replicated in the code below
+ (0, 0) => self.a.overflowing_add(self.a),
+ (0, 1) => self.a.overflowing_add(self.b),
+ (0, 2) => self.a.overflowing_add(self.c),
+ (0, 3) => self.a.overflowing_add(self.d),
+
+ (1, 0) => self.b.overflowing_add(self.a),
+ (1, 1) => self.b.overflowing_add(self.b),
+ (1, 2) => self.b.overflowing_add(self.c),
+ (1, 3) => self.b.overflowing_add(self.d),
+
+ (2, 0) => self.c.overflowing_add(self.a),
+ (2, 1) => self.c.overflowing_add(self.b),
+ (2, 2) => self.c.overflowing_add(self.c),
+ (2, 3) => self.c.overflowing_add(self.d),
+
+ (3, 0) => self.d.overflowing_add(self.a),
+ (3, 1) => self.d.overflowing_add(self.b),
+ (3, 2) => self.d.overflowing_add(self.c),
+ (3, 3) => self.d.overflowing_add(self.d),
+
+ _ => (0, false),
+ };
+
+ match dest {
+ 0 => self.a = result,
+ 1 => self.b = result,
+ 2 => self.c = result,
+ 3 => self.d = result,
+ _ => {}
+ }
+
+ self.zero = result == 0;
+ self.carry = carry;
+ }
+
+ pub fn sub(&mut self, mem: &mut Memory) {
+ let dest = mem.read(self.pc); self.pc += 1;
+ let src = mem.read(self.pc); self.pc += 1;
+
+ let (result, borrow) = match (dest, src) {
+ // What the fuck do these tuples mean?
+ // so basically they are the numbers assigned to register
+ // 0 => A, 1 => B ....
+ // so when it is (0, 0), it basically says add the
+ // value of register B into register A,
+ // thats exactly whats replicated in the code below
+ (0, 0) => self.a.overflowing_sub(self.a),
+ (0, 1) => self.a.overflowing_sub(self.b),
+ (0, 2) => self.a.overflowing_sub(self.c),
+ (0, 3) => self.a.overflowing_sub(self.d),
+
+ (1, 0) => self.b.overflowing_sub(self.a),
+ (1, 1) => self.b.overflowing_sub(self.b),
+ (1, 2) => self.b.overflowing_sub(self.c),
+ (1, 3) => self.b.overflowing_sub(self.d),
+
+ (2, 0) => self.c.overflowing_sub(self.a),
+ (2, 1) => self.c.overflowing_sub(self.b),
+ (2, 2) => self.c.overflowing_sub(self.c),
+ (2, 3) => self.c.overflowing_sub(self.d),
+
+ (3, 0) => self.d.overflowing_sub(self.a),
+ (3, 1) => self.d.overflowing_sub(self.b),
+ (3, 2) => self.d.overflowing_sub(self.c),
+ (3, 3) => self.d.overflowing_sub(self.d),
+
+ _ => (0, false),
+ };
+
+ match dest {
+ 0 => self.a = result,
+ 1 => self.b = result,
+ 2 => self.c = result,
+ 3 => self.d = result,
+ _ => {}
+ }
+
+ self.zero = result == 0;
+ self.carry = borrow;
+ }
+
}
diff --git a/src/main.rs b/src/main.rs
index 26db2f0..7c638ba 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -20,7 +20,7 @@ fn main() {
// b = 2
mem.write(0x0003, Instruction::MOV as u8);
mem.write(0x0004, 1);
- mem.write(0x0005, 10);
+ mem.write(0x0005, 1);
// a = a + b
mem.write(0x0006, Instruction::SUB as u8);
@@ -40,123 +40,12 @@ fn main() {
cpu.inc_cp();
match opcode {
- x if x == Instruction::MOV as u8 => {
- let reg = mem.read(cpu.pc); cpu.inc_cp();
- let val = mem.read(cpu.pc); cpu.inc_cp();
-
- match reg {
- 0 => cpu.a = val,
- 1 => cpu.b = val,
- 2 => cpu.c = val,
- 3 => cpu.d = val,
- _ => {}
- }
- }
-
- x if x == Instruction::ADD as u8 => {
- let dest = mem.read(cpu.pc); cpu.pc += 1;
- let src = mem.read(cpu.pc); cpu.pc += 1;
-
- let (result, carry) = match (dest, src) {
- // What the fuck do these tuples mean?
- // so basically they are the numbers assigned to register
- // 0 => A, 1 => B ....
- // so when it is (0, 0), it basically says add the
- // value of register B into register A,
- // thats exactly whats replicated in the code below
- (0, 0) => cpu.a.overflowing_add(cpu.a),
- (0, 1) => cpu.a.overflowing_add(cpu.b),
- (0, 2) => cpu.a.overflowing_add(cpu.c),
- (0, 3) => cpu.a.overflowing_add(cpu.d),
-
- (1, 0) => cpu.b.overflowing_add(cpu.a),
- (1, 1) => cpu.b.overflowing_add(cpu.b),
- (1, 2) => cpu.b.overflowing_add(cpu.c),
- (1, 3) => cpu.b.overflowing_add(cpu.d),
-
- (2, 0) => cpu.c.overflowing_add(cpu.a),
- (2, 1) => cpu.c.overflowing_add(cpu.b),
- (2, 2) => cpu.c.overflowing_add(cpu.c),
- (2, 3) => cpu.c.overflowing_add(cpu.d),
-
- (3, 0) => cpu.d.overflowing_add(cpu.a),
- (3, 1) => cpu.d.overflowing_add(cpu.b),
- (3, 2) => cpu.d.overflowing_add(cpu.c),
- (3, 3) => cpu.d.overflowing_add(cpu.d),
-
- _ => (0, false),
- };
-
-
-
- match dest {
- 0 => cpu.a = result,
- 1 => cpu.b = result,
- 2 => cpu.c = result,
- 3 => cpu.d = result,
- _ => {}
- }
-
- cpu.zero = result == 0;
- cpu.carry = carry;
- }
- x if x == Instruction::SUB as u8 => {
- let dest = mem.read(cpu.pc); cpu.pc += 1;
- let src = mem.read(cpu.pc); cpu.pc += 1;
-
- let (result, borrow) = match (dest, src) {
- // What the fuck do these tuples mean?
- // so basically they are the numbers assigned to register
- // 0 => A, 1 => B ....
- // so when it is (0, 0), it basically says add the
- // value of register B into register A,
- // thats exactly whats replicated in the code below
- (0, 0) => cpu.a.overflowing_sub(cpu.a),
- (0, 1) => cpu.a.overflowing_sub(cpu.b),
- (0, 2) => cpu.a.overflowing_sub(cpu.c),
- (0, 3) => cpu.a.overflowing_sub(cpu.d),
-
- (1, 0) => cpu.b.overflowing_sub(cpu.a),
- (1, 1) => cpu.b.overflowing_sub(cpu.b),
- (1, 2) => cpu.b.overflowing_sub(cpu.c),
- (1, 3) => cpu.b.overflowing_sub(cpu.d),
-
- (2, 0) => cpu.c.overflowing_sub(cpu.a),
- (2, 1) => cpu.c.overflowing_sub(cpu.b),
- (2, 2) => cpu.c.overflowing_sub(cpu.c),
- (2, 3) => cpu.c.overflowing_sub(cpu.d),
-
- (3, 0) => cpu.d.overflowing_sub(cpu.a),
- (3, 1) => cpu.d.overflowing_sub(cpu.b),
- (3, 2) => cpu.d.overflowing_sub(cpu.c),
- (3, 3) => cpu.d.overflowing_sub(cpu.d),
-
- _ => (0, false),
- };
-
-
-
- match dest {
- 0 => cpu.a = result,
- 1 => cpu.b = result,
- 2 => cpu.c = result,
- 3 => cpu.d = result,
- _ => {}
- }
-
- cpu.zero = result == 0;
- cpu.carry = borrow;
- }
-
-
+ x if x == Instruction::MOV as u8 => cpu.mov(&mut mem),
+ x if x == Instruction::ADD as u8 => cpu.add(&mut mem),
+ x if x == Instruction::SUB as u8 => cpu.sub(&mut mem),
x if x == Instruction::JMP as u8 => {}
-
x if x == Instruction::JZ as u8 => {}
-
- x if x == Instruction::HLT as u8 => {
- cpu.halted = true;
- }
-
+ x if x == Instruction::HLT as u8 => cpu.halt(),
_ => panic!("Unknown opcode {:02X}", opcode),
}
}