From 3876eba0504bfe13e9522d48130bfafc7d8b1e8d Mon Sep 17 00:00:00 2001 From: Jason Hilder Date: Wed, 27 May 2026 07:16:39 +0200 Subject: [PATCH] added the last set of instructions. --- src/machine/cpu.odin | 78 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 70 insertions(+), 8 deletions(-) diff --git a/src/machine/cpu.odin b/src/machine/cpu.odin index 87d89bd..a024317 100644 --- a/src/machine/cpu.odin +++ b/src/machine/cpu.odin @@ -1,6 +1,7 @@ package machine import "core:log" +import "core:math/rand" import "base:intrinsics" // CPU.odin -> instructions, fetch, decode, execute, run loop @@ -51,10 +52,22 @@ cycle :: proc(s: ^System) { case 0x9: op_skip_reg_condition(s, vx_idx, vy_idx, false) case 0xA: op_set(s, nnn) case 0xB: op_jp_offset(s, nnn) + case 0xC: op_rnd(s, vx_idx, kk) case 0xD: op_draw(s, vx_idx, vy_idx, last_nibble) + case 0xE: { + switch kk { + case 0x9E: op_skip_on_keypress(s, vx_idx) + case 0xA1: op_skip_on_nokeypress(s, vx_idx) + } + } case 0xF: { switch kk { + case 0x07: op_ld_dt(s, vx_idx) + case 0x0A: op_get_key(s, vx_idx) + case 0x15: op_set_dt(s, vx_idx) + case 0x18: op_set_st(s, vx_idx) case 0x1E: op_add_i(s, vx_idx) + case 0x29: op_set_i(s, vx_idx) case 0x33: op_split_i(s, vx_idx) case 0x55: op_mem_set(s, vx_idx) case 0x65: op_mem_get(s, vx_idx) @@ -194,7 +207,11 @@ op_jp_offset :: proc(s: ^System, nnn: u16) { s.pc += u16(s.v[0]) } -// Cxkk - RND Vx, byte : @TODO! +// Cxkk - RND Vx, byte +op_rnd :: proc(s: ^System, vx_idx: u16, kk: u8) { + rand_int := u8(rand.int_max(256)) + s.v[vx_idx] = (rand_int & kk) +} // Dxyn - DRW Vx, Vy, nibble op_draw :: proc(s: ^System, vx_idx, vy_idx, n: u16) { @@ -233,12 +250,54 @@ op_draw :: proc(s: ^System, vx_idx, vy_idx, n: u16) { } } -// Ex9E - SKP Vx : @TODO -// ExA1 - SKNP Vx : @TODO -// Fx07 - LD Vx, DT : @TODO -// Fx0A - LD Vx, K : @TODO -// Fx15 - LD DT, Vx : @TODO -// Fx18 - LD ST, Vx : @TODO +// Ex9E - SKP Vx +op_skip_on_keypress :: proc(s: ^System, vx_idx: u16) { + reg_value := s.v[vx_idx] + if s.keypad[reg_value] { + s.pc += 2 + } +} + +// ExA1 - SKNP Vx +op_skip_on_nokeypress :: proc(s: ^System, vx_idx: u16) { + reg_value := s.v[vx_idx] + if !s.keypad[reg_value] { + s.pc += 2 + } +} + +// Fx07 - LD Vx, DT +op_ld_dt :: proc(s: ^System, vx_idx: u16) { + s.v[vx_idx] = s.delay_timer +} + +// Fx0A - LD Vx, K +op_get_key :: proc(s: ^System, vx_idx: u16) { + for val, kp_idx in s.keypad { + if val == true { + s.v[vx_idx] = u8(kp_idx) + + // return here so it does not decrement + return + } + } + + // if loop does not return decrement go into loop + s.pc -= 2 +} + + +// Fx15 - LD DT, Vx +op_set_dt :: proc(s: ^System, vx_idx: u16) { + // set delay timer to value of x register + s.delay_timer = s.v[vx_idx] +} + +// Fx18 - LD ST, Vx +op_set_st :: proc(s: ^System, vx_idx: u16) { + // set sound timer to value of x register + s.sound_timer = s.v[vx_idx] +} // Fx1E - ADD I, Vx op_add_i :: proc(s: ^System, vx_idx: u16) { @@ -246,7 +305,10 @@ op_add_i :: proc(s: ^System, vx_idx: u16) { s.v[0xF] = u8(1) if s.i > 0xFFF else u8(0) } -// Fx29 - LD F, Vx : @TODO +// Fx29 - LD F, Vx +op_set_i :: proc(s: ^System, vx_idx: u16) { + s.i = u16(s.v[vx_idx]) * 5 +} // Fx33 - LD B, Vx op_split_i :: proc(s: ^System, vx_idx: u16) {