Added, clear, jmp, ld, add, set and draw ops.

Also cleaned up comments for now will add better clear ones later down
the line for future reference.
This commit is contained in:
2026-05-19 08:06:06 +02:00
parent ebb3de3784
commit 6f4754d235
+73 -5
View File
@@ -31,19 +31,87 @@ cycle :: proc(s: ^System) {
switch opcode {
case 0x00E0: op_cls(s)
}
case 0x1: op_jp_add(s)
case 0xD: log.info("D instruction a draw call!")
case 0x1: op_jp_add(s, opcode)
case 0x6: op_ld(s, opcode)
case 0x7: op_add(s, opcode)
case 0xA: op_set(s, opcode)
case 0xD: op_draw(s, opcode)
}
}
debug_opcode :: proc(opcode: u16) {
log.debugf("opcode: 0x%04X", opcode)
}
// Instruction procs
// -----------------------------------
// CLS: Clear the display
op_cls :: proc(s: ^System) {
log.info("found clear screen instruction, zero out display buffer")
// log.info("found clear screen instruction, zero out display buffer")
// Odin lets you zero a fixed array with just: {} is the zero value,
// so it clears the entire buffer in one shot.
s.display = {}
}
// JP addr: Jump to location nnn
op_jp_add :: proc(s: ^System) {
log.info("found jump instruction, set pc to nnn")
op_jp_add :: proc(s: ^System, opcode: u16) {
addr := (opcode & 0x0FFF)
s.pc = addr
}
// LD: Load value kk into x register
op_ld :: proc(s: ^System, opcode: u16) {
register := (opcode & 0x0F00) >> 8
value := (opcode & 0x00FF)
s.v[register] = u8(value)
}
// ADD: Adds the value kk to the value of register Vx, then stores the result in Vx.
op_add :: proc(s: ^System, opcode: u16) {
register := (opcode & 0x0F00) >> 8
value := (opcode & 0x00FF)
s.v[register] += u8(value)
}
// SET: The value of register I is set to nnn.
op_set :: proc(s: ^System, opcode: u16) {
index_addr := (opcode & 0x0FFF)
s.i = index_addr
}
// DRAW: Display n-byte sprite starting at memory location I at (Vx, Vy), set VF = collision.
op_draw :: proc(s: ^System, opcode: u16) {
x_register := (opcode & 0x0F00) >> 8
y_register := (opcode & 0x00F0) >> 4
// Handle wrapping
x_coord := (s.v[x_register] & 0x03F)
y_coord := (s.v[y_register] & 0x1F)
s.v[0xF] = 0
n_bytes := (opcode & 0x000F)
for row in 0..<n_bytes {
sprite_row := s.memory[s.i + row]
// log.debugf("sr: 0x%X", sprite_row)
for col in 0..<8 {
mask := u8(0x80) >> u8(col)
if sprite_row & mask != 0 {
// this bit is set Xor the pixel
y_pos := ((y_coord + u8(row)) % 32)
x_pos := ((x_coord + u8(col)) % 64)
pixel := &s.display[y_pos][x_pos]
if pixel^ == 1 {
s.v[0xF] = 1
}
pixel^ = pixel^ ~ 1
}
}
}
}