/// 4) Opcode subgroup (d) / Number of bytes (n). / Integer (kk) / Memory address (nnn).
struct CPU {
- registers: [u8; 16],
- position_in_memory: usize,
+ registers: [u8; 16], // 4 bits can address a 16 positions register. The last position (0xF) is used to indicate an overflow.
+ position_in_memory: usize, // Programm counter.
memory: [u8; 0x1000], // 4 KB of memory.
}
impl CPU {
+ fn new() -> CPU {
+ CPU {
+ registers: [0; 16],
+ position_in_memory: 0,
+ memory: [0; 0x1000],
+ }
+ }
+
fn read_opcode(&self) -> u16 {
- self.current_operation
+ let p = self.position_in_memory;
+ let op_byte1 = self.memory[p] as u16;
+ let op_byte2 = self.memory[p + 1] as u16;
+ op_byte1 << 8 | op_byte2
}
fn run(&mut self) {
- // loop {
+ loop {
let opcode = self.read_opcode();
+ self.position_in_memory += 2;
+
let c = ((opcode & 0xF000) >> 12) as u8;
let x = ((opcode & 0x0F00) >> 8) as u8;
let y = ((opcode & 0x00F0) >> 4) as u8;
let d = ((opcode & 0x000F) >> 0) as u8;
match (c, x, y, d) {
+ (0, 0, 0, 0) => { return; }
(0x8, _, _, 0x4) => self.add_xy(x, y),
_ => todo!("opcode: {:04x}", opcode),
}
- //}
+ }
}
fn add_xy(&mut self, x: u8, y: u8) {
- self.registers[x as usize] += self.registers[y as usize];
+ let arg1 = self.registers[x as usize];
+ let arg2 = self.registers[y as usize];
+
+ let (val, overflow) = arg1.overflowing_add(arg2);
+ self.registers[x as usize] = val;
+
+ if overflow {
+ self.registers[0xF] = 1;
+ } else {
+ self.registers[0xF] = 0;
+ }
}
}
mod tests {
use super::*;
+ /// 5 + 10 + 10 + 10 = 35. (three operations).
#[test]
fn addition() {
- let mut cpu = CPU {
- current_operation: 0,
- registers: [0; 2]
- };
+ let mut cpu = CPU::new();
+
+ cpu.memory[0] = 0x80;
+ cpu.memory[1] = 0x14;
+
+ cpu.memory[2] = 0x80;
+ cpu.memory[3] = 0x24;
+
+ cpu.memory[4] = 0x80;
+ cpu.memory[5] = 0x34;
- cpu.current_operation = 0x8014;
cpu.registers[0] = 5;
cpu.registers[1] = 10;
+ cpu.registers[2] = 10;
+ cpu.registers[3] = 10;
cpu.run();
- assert_eq!(cpu.registers[0], 15);
+ assert_eq!(cpu.registers[0], 35);
}
}
\ No newline at end of file