Skip to content

Commit 1477bcf

Browse files
committed
implemented more opcodes
1 parent 190f535 commit 1477bcf

3 files changed

Lines changed: 70 additions & 28 deletions

File tree

src/main/kotlin/io/github/chip8k/Chip8.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class Chip8 : Application() {
3737

3838
override fun handle(now: Long) {
3939
if (now - lastUpdateTime >= settings.delayInNs) {
40-
if (running && !paused) {
40+
if (running && !paused && !keyHandler.waiting) {
4141
gpu.handleLogs()
4242
gpu.updateDisplay()
4343
cpu.runCycle()

src/main/kotlin/io/github/chip8k/Cpu.kt

Lines changed: 68 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -242,50 +242,91 @@ class Cpu {
242242
//bunch of stuff
243243
0xF -> {
244244
when (nib2) {
245-
//FX07 Timer Vx = get_delay() Sets VX to the value of the delay timer
246-
//FX0A KeyOp Vx = get_key() A key press is awaited, and then stored in VX
247-
//(blocking operation, all instruction halted until next key event, delay and sound timers should continue processing)
248245
0x0 -> {
249246
when (nib3) {
247+
//FX07 Timer Vx = get_delay() Sets VX to the value of the delay timer
250248
0x7 -> {}
251-
0xA -> {}
249+
//FX0A KeyOp Vx = get_key() A key press is awaited, and then stored in VX
250+
//(blocking operation, all instruction halted until next key event, delay and sound timers should continue processing)
251+
0xA -> {
252+
keyHandler.waiting = true
253+
while (keyHandler.waiting) {
254+
for (keys in keyHandler.keys.indices) {
255+
if (keyHandler.keyDown(keys)) {
256+
v[nib1] = keys.toByte()
257+
keyHandler.waiting = false
258+
break
259+
}
260+
}
261+
}
262+
}
252263
else -> log(opcode, "INVALID")
253264
}
254265
}
255-
//FX15 Timer delay_timer(Vx) Sets the delay timer to VX.
256-
//FX18 Sound sound_timer(Vx) Sets the sound timer to VX.
257-
//FX1E MEM I += Vx Adds VX to I. VF is not affected.
258266
0x1 -> {
259-
267+
when (nib3) {
268+
//FX15 Timer delay_timer(Vx) Sets the delay timer to VX.
269+
0x5-> {}
270+
//FX18 Sound sound_timer(Vx) Sets the sound timer to VX.
271+
0x8-> {}
272+
//FX1E MEM I += Vx Adds VX to I. VF is not affected.
273+
0xE-> {
274+
i = (i.toInt() + v[nib1]).toShort()
275+
log(opcode, "i += v[nib1]")
276+
}
277+
else -> log(opcode, "INVALID")
278+
}
260279
}
261-
//FX29 MEM I = sprite_addr[Vx] Sets I to the location of the sprite for the character in VX(only consider the lowest nibble).
262-
//Characters 0-F (in hexadecimal) are represented by a 4x5 font
263280
0x2 -> {
264-
281+
//FX29 MEM I = sprite_addr[Vx] Sets I to the location of the sprite for the character in VX(only consider the lowest nibble).
282+
//Characters 0-F (in hexadecimal) are represented by a 4x5 font
283+
if (nib3 == 0x9) {
284+
i = (v[nib1].toInt() * 5).toShort()
285+
}
286+
else log(opcode, "INVALID")
265287
}
266-
//FX33 BCD
267-
/*set_BCD(Vx)
268-
*(I+0) = BCD(3);
269-
*(I+1) = BCD(2);
270-
*(I+2) = BCD(1);*/
271-
//Stores the binary-coded decimal representation of VX, with the hundreds digit in memory at location in I,
272-
//the tens digit at location I+1, and the ones digit at location I+2.
273-
0x3 -> {
274288

289+
0x3 -> {
290+
//FX33 BCD
291+
/*set_BCD(Vx)
292+
*(I+0) = BCD(3);
293+
*(I+1) = BCD(2);
294+
*(I+2) = BCD(1);*/
295+
//Stores the binary-coded decimal representation of VX, with the hundreds digit in memory at location in I,
296+
//the tens digit at location I+1, and the ones digit at location I+2.
297+
if (nib3 == 0x3) {
298+
val dig1 = v[nib1] / 100
299+
val dig2 = (v[nib1] % 100) / 10
300+
val dig3 = v[nib1] % 10
301+
cpu.memory[i.toInt()] = dig1.toByte()
302+
cpu.memory[i.toInt() + 1] = dig2.toByte()
303+
cpu.memory[i.toInt() + 2] = dig3.toByte()
304+
}
305+
else log(opcode, "INVALID")
275306
}
276-
//FX55 MEM reg_dump(Vx, &I) Stores from V0 to VX (including VX) in memory, starting at address I.
277-
//The offset from I is increased by 1 for each value written, but I itself is left unmodified.
278-
0x5 -> {
279307

308+
0x5 -> {
309+
//FX55 MEM reg_dump(Vx, &I) Stores from V0 to VX (including VX) in memory, starting at address I.
310+
//The offset from I is increased by 1 for each value written, but I itself is left unmodified.
311+
if (nib3 == 0x5) {
312+
for (j in 0..nib1) {
313+
memory[i.toInt() + j] = v[j]
314+
}
315+
}
316+
else log(opcode, "INVALID")
280317
}
281-
//FX65 MEM reg_load(Vx, &I) Fills from V0 to VX (including VX) with values from memory, starting at address I.
282-
//The offset from I is increased by 1 for each value read, but I itself is left unmodified
283-
0x6 -> {
284318

319+
0x6 -> {
320+
//FX65 MEM reg_load(Vx, &I) Fills from V0 to VX (including VX) with values from memory, starting at address I.
321+
//The offset from I is increased by 1 for each value read, but I itself is left unmodified
322+
if (nib3 == 0x5) {
323+
for (j in 0..nib1) {
324+
v[j] = memory[i.toInt() + j]
325+
}
326+
}
327+
else log(opcode, "INVALID")
285328
}
286329
}
287-
288-
log(opcode, "NOT YET IMPLEMENTED")
289330
}
290331
else -> {println("INVALID OPCODE GIVEN: " + opcode.toString(16))}
291332
}

src/main/kotlin/io/github/chip8k/KeyHandler.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class KeyHandler {
1414
KeyCode.Z to 0xA, KeyCode.X to 0x0, KeyCode.C to 0xB, KeyCode.V to 0xF
1515
)
1616

17+
var waiting = false
1718

1819
fun handleInputs() {
1920
gpu.screen.onKeyPressed = EventHandler { event ->

0 commit comments

Comments
 (0)