Krolyxon
Commit 4166b0e

Branches

Tags

Refs →

bench51srccpu.rs

266 lines · 6.9 KB · Rust

1use crate::instructions::Instruction;
2use crate::memory::Memory;
3
4#[derive(Default, Debug)]
5#[allow(dead_code)]
6pub struct CPU {
7 pub a: u8,
8 pub b: u8,
9 pub c: u8,
10 pub d: u8,
11
12 pub pc: u16,
13 pub sp: u16,
14
15 pub zero: bool,
16 pub carry: bool,
17
18 pub halted: bool,
19}
20
21impl CPU {
22 pub fn debug_instr(&self, mem: &Memory) {
23 let opcode = mem.read(self.pc);
24
25 println!(
26 "PC={:04X} {:<3} | A={:02X} B={:02X} C={:02X} D={:02X} | Z={} C={}",
27 self.pc,
28 Instruction::opcode_name(opcode),
29 self.a,
30 self.b,
31 self.c,
32 self.d,
33 self.zero as u8,
34 self.carry as u8
35 );
36 }
37
38 pub fn step(&mut self, mem: &mut Memory) {
39 let opcode = mem.read(self.pc);
40 self.inc_pc();
41
42 match opcode {
43 x if x == Instruction::MOV_RI as u8 => self.mov_ri(mem),
44 x if x == Instruction::MOV_RR as u8 => self.mov_rr(mem),
45 x if x == Instruction::ADD as u8 => self.add(mem),
46 x if x == Instruction::SUB as u8 => self.sub(mem),
47 x if x == Instruction::JMP as u8 => self.jmp(mem),
48 x if x == Instruction::JZ as u8 => self.jz(mem),
49 x if x == Instruction::JNZ as u8 => self.jnz(mem),
50 x if x == Instruction::CMP_RI as u8 => self.cmp_ri(mem),
51 x if x == Instruction::CMP_RR as u8 => self.cmp_rr(mem),
52 x if x == Instruction::HLT as u8 => self.halt(),
53 _ => panic!("Unknown opcode {:02X}", opcode),
54 }
55 }
56
57 pub fn inc_pc(&mut self) {
58 self.pc += 1;
59 }
60
61 pub fn halt(&mut self) {
62 self.halted = true;
63 }
64
65 pub fn mov_ri(&mut self, mem: &Memory) {
66 let reg = mem.read(self.pc);
67 self.inc_pc();
68 let val = mem.read(self.pc);
69 self.inc_pc();
70
71 match reg {
72 0 => self.a = val,
73 1 => self.b = val,
74 2 => self.c = val,
75 3 => self.d = val,
76 _ => {}
77 }
78
79 self.zero = val == 0;
80 }
81
82 pub fn mov_rr(&mut self, mem: &Memory) {
83 let dest = mem.read(self.pc);
84 self.inc_pc();
85 let src= mem.read(self.pc);
86 self.inc_pc();
87
88 let val = self.get_reg(src);
89 self.set_reg(dest, val);
90
91 self.zero = val == 0;
92 }
93
94
95 pub fn add(&mut self, mem: &Memory) {
96 let dest = mem.read(self.pc);
97 self.pc += 1;
98 let src = mem.read(self.pc);
99 self.pc += 1;
100
101 let (result, carry) = match (dest, src) {
102 (0, 0) => self.a.overflowing_add(self.a),
103 (0, 1) => self.a.overflowing_add(self.b),
104 (0, 2) => self.a.overflowing_add(self.c),
105 (0, 3) => self.a.overflowing_add(self.d),
106
107 (1, 0) => self.b.overflowing_add(self.a),
108 (1, 1) => self.b.overflowing_add(self.b),
109 (1, 2) => self.b.overflowing_add(self.c),
110 (1, 3) => self.b.overflowing_add(self.d),
111
112 (2, 0) => self.c.overflowing_add(self.a),
113 (2, 1) => self.c.overflowing_add(self.b),
114 (2, 2) => self.c.overflowing_add(self.c),
115 (2, 3) => self.c.overflowing_add(self.d),
116
117 (3, 0) => self.d.overflowing_add(self.a),
118 (3, 1) => self.d.overflowing_add(self.b),
119 (3, 2) => self.d.overflowing_add(self.c),
120 (3, 3) => self.d.overflowing_add(self.d),
121
122 _ => (0, false),
123 };
124
125 match dest {
126 0 => self.a = result,
127 1 => self.b = result,
128 2 => self.c = result,
129 3 => self.d = result,
130 _ => {}
131 }
132
133 self.zero = result == 0;
134 self.carry = carry;
135 }
136
137 pub fn sub(&mut self, mem: &Memory) {
138 let dest = mem.read(self.pc);
139 self.pc += 1;
140 let src = mem.read(self.pc);
141 self.pc += 1;
142
143 let (result, borrow) = match (dest, src) {
144 (0, 0) => self.a.overflowing_sub(self.a),
145 (0, 1) => self.a.overflowing_sub(self.b),
146 (0, 2) => self.a.overflowing_sub(self.c),
147 (0, 3) => self.a.overflowing_sub(self.d),
148
149 (1, 0) => self.b.overflowing_sub(self.a),
150 (1, 1) => self.b.overflowing_sub(self.b),
151 (1, 2) => self.b.overflowing_sub(self.c),
152 (1, 3) => self.b.overflowing_sub(self.d),
153
154 (2, 0) => self.c.overflowing_sub(self.a),
155 (2, 1) => self.c.overflowing_sub(self.b),
156 (2, 2) => self.c.overflowing_sub(self.c),
157 (2, 3) => self.c.overflowing_sub(self.d),
158
159 (3, 0) => self.d.overflowing_sub(self.a),
160 (3, 1) => self.d.overflowing_sub(self.b),
161 (3, 2) => self.d.overflowing_sub(self.c),
162 (3, 3) => self.d.overflowing_sub(self.d),
163
164 _ => (0, false),
165 };
166
167 match dest {
168 0 => self.a = result,
169 1 => self.b = result,
170 2 => self.c = result,
171 3 => self.d = result,
172 _ => {}
173 }
174
175 self.zero = result == 0;
176 self.carry = borrow;
177 }
178
179 pub fn jmp(&mut self, mem: &Memory) {
180 let low = mem.read(self.pc) as u16;
181 self.inc_pc();
182 let high = mem.read(self.pc) as u16;
183 self.inc_pc();
184
185 let addrs = (high << 8) | low;
186
187 self.pc = addrs;
188 }
189
190 pub fn jz(&mut self, mem: &Memory) {
191 let low = mem.read(self.pc) as u16;
192 self.inc_pc();
193 let high = mem.read(self.pc) as u16;
194 self.inc_pc();
195
196 let addrs = (high << 8) | low;
197
198 if self.zero {
199 self.pc = addrs;
200 }
201 }
202
203 pub fn jnz(&mut self, mem: &Memory) {
204 let low = mem.read(self.pc) as u16;
205 self.inc_pc();
206 let high = mem.read(self.pc) as u16;
207 self.inc_pc();
208
209 let addrs = (high << 8) | low;
210
211 if !self.zero {
212 self.pc = addrs;
213 }
214 }
215
216 pub fn cmp_rr(&mut self, mem: &Memory) {
217 let r1 = mem.read(self.pc);
218 self.inc_pc();
219 let r2 = mem.read(self.pc);
220 self.inc_pc();
221
222 let v1 = self.get_reg(r1);
223 let v2 = self.get_reg(r2);
224
225 let (result, borrow) = v1.overflowing_sub(v2);
226
227 self.zero = result == 0;
228 self.carry = borrow;
229 }
230
231 pub fn cmp_ri(&mut self, mem: &Memory) {
232 let r1 = mem.read(self.pc);
233 self.inc_pc();
234 let r2 = mem.read(self.pc);
235 self.inc_pc();
236
237 let v1 = self.get_reg(r1);
238
239 let (result, borrow) = v1.overflowing_sub(r2);
240
241 self.zero = result == 0;
242 self.carry = borrow;
243 }
244
245
246 fn get_reg(&self, r: u8) -> u8 {
247 match r {
248 0 => self.a,
249 1 => self.b,
250 2 => self.c,
251 3 => self.d,
252 _ => 0,
253 }
254 }
255
256 fn set_reg(&mut self, dest: u8, val: u8) {
257 match dest {
258 0 => self.a = val,
259 1 => self.b = val,
260 2 => self.c = val,
261 3 => self.d = val,
262 _ => {},
263 }
264 }
265
266}