Krolyxon
Commit a566c17

Branches

Tags

Refs →

bench51srccpu.rs

164 lines · 4.2 KB · Rust

1use crate::memory::Memory;
2#[derive(Default, Debug)]
3pub struct CPU {
4 pub a: u8,
5 pub b: u8,
6 pub c: u8,
7 pub d: u8,
8
9 pub pc: u16,
10 pub sp: u16,
11
12 pub zero: bool,
13 pub carry: bool,
14
15 pub halted: bool,
16}
17
18impl CPU {
19 pub fn inc_pc(&mut self) {
20 self.pc += 1;
21 }
22
23 pub fn halt(&mut self) {
24 self.halted = true;
25 }
26
27 pub fn mov(&mut self, mem: &mut Memory) {
28 let reg = mem.read(self.pc);
29 self.inc_pc();
30 let val = mem.read(self.pc);
31 self.inc_pc();
32
33 match reg {
34 0 => self.a = val,
35 1 => self.b = val,
36 2 => self.c = val,
37 3 => self.d = val,
38 _ => {}
39 }
40
41 self.zero = val == 0;
42 }
43
44 pub fn add(&mut self, mem: &mut Memory) {
45 let dest = mem.read(self.pc);
46 self.pc += 1;
47 let src = mem.read(self.pc);
48 self.pc += 1;
49
50 let (result, carry) = match (dest, src) {
51 (0, 0) => self.a.overflowing_add(self.a),
52 (0, 1) => self.a.overflowing_add(self.b),
53 (0, 2) => self.a.overflowing_add(self.c),
54 (0, 3) => self.a.overflowing_add(self.d),
55
56 (1, 0) => self.b.overflowing_add(self.a),
57 (1, 1) => self.b.overflowing_add(self.b),
58 (1, 2) => self.b.overflowing_add(self.c),
59 (1, 3) => self.b.overflowing_add(self.d),
60
61 (2, 0) => self.c.overflowing_add(self.a),
62 (2, 1) => self.c.overflowing_add(self.b),
63 (2, 2) => self.c.overflowing_add(self.c),
64 (2, 3) => self.c.overflowing_add(self.d),
65
66 (3, 0) => self.d.overflowing_add(self.a),
67 (3, 1) => self.d.overflowing_add(self.b),
68 (3, 2) => self.d.overflowing_add(self.c),
69 (3, 3) => self.d.overflowing_add(self.d),
70
71 _ => (0, false),
72 };
73
74 match dest {
75 0 => self.a = result,
76 1 => self.b = result,
77 2 => self.c = result,
78 3 => self.d = result,
79 _ => {}
80 }
81
82 self.zero = result == 0;
83 self.carry = carry;
84 }
85
86 pub fn sub(&mut self, mem: &mut Memory) {
87 let dest = mem.read(self.pc);
88 self.pc += 1;
89 let src = mem.read(self.pc);
90 self.pc += 1;
91
92 let (result, borrow) = match (dest, src) {
93 (0, 0) => self.a.overflowing_sub(self.a),
94 (0, 1) => self.a.overflowing_sub(self.b),
95 (0, 2) => self.a.overflowing_sub(self.c),
96 (0, 3) => self.a.overflowing_sub(self.d),
97
98 (1, 0) => self.b.overflowing_sub(self.a),
99 (1, 1) => self.b.overflowing_sub(self.b),
100 (1, 2) => self.b.overflowing_sub(self.c),
101 (1, 3) => self.b.overflowing_sub(self.d),
102
103 (2, 0) => self.c.overflowing_sub(self.a),
104 (2, 1) => self.c.overflowing_sub(self.b),
105 (2, 2) => self.c.overflowing_sub(self.c),
106 (2, 3) => self.c.overflowing_sub(self.d),
107
108 (3, 0) => self.d.overflowing_sub(self.a),
109 (3, 1) => self.d.overflowing_sub(self.b),
110 (3, 2) => self.d.overflowing_sub(self.c),
111 (3, 3) => self.d.overflowing_sub(self.d),
112
113 _ => (0, false),
114 };
115
116 match dest {
117 0 => self.a = result,
118 1 => self.b = result,
119 2 => self.c = result,
120 3 => self.d = result,
121 _ => {}
122 }
123
124 self.zero = result == 0;
125 self.carry = borrow;
126 }
127
128 pub fn jmp(&mut self, mem: &mut Memory) {
129 let low = mem.read(self.pc) as u16;
130 self.inc_pc();
131 let high = mem.read(self.pc) as u16;
132 self.inc_pc();
133
134 let addrs = (high << 8) | low;
135
136 self.pc = addrs;
137 }
138
139 pub fn jz(&mut self, mem: &mut Memory) {
140 let low = mem.read(self.pc) as u16;
141 self.inc_pc();
142 let high = mem.read(self.pc) as u16;
143 self.inc_pc();
144
145 let addrs = (high << 8) | low;
146
147 if self.zero {
148 self.pc = addrs;
149 }
150 }
151
152 pub fn jnz(&mut self, mem: &mut Memory) {
153 let low = mem.read(self.pc) as u16;
154 self.inc_pc();
155 let high = mem.read(self.pc) as u16;
156 self.inc_pc();
157
158 let addrs = (high << 8) | low;
159
160 if !self.zero {
161 self.pc = addrs;
162 }
163 }
164}