Skip to content

Commit

Permalink
Fixes type casting on key presses.
Browse files Browse the repository at this point in the history
Implements remainder of opcodes.
  • Loading branch information
danmrichards committed Nov 16, 2018
1 parent fcfa0af commit 7d4e111
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 14 deletions.
4 changes: 1 addition & 3 deletions cmd/chip8/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ var (
window *pixelgl.Window

// TODO: Abstract this.
keys = map[uint16]pixelgl.Button{
keys = map[byte]pixelgl.Button{
0x1: pixelgl.Key1, 0x2: pixelgl.Key2, 0x3: pixelgl.Key3, 0xC: pixelgl.Key4,
0x4: pixelgl.KeyQ, 0x5: pixelgl.KeyW, 0x6: pixelgl.KeyE, 0xD: pixelgl.KeyR,
0x7: pixelgl.KeyA, 0x8: pixelgl.KeyS, 0x9: pixelgl.KeyD, 0xE: pixelgl.KeyF,
Expand Down Expand Up @@ -73,8 +73,6 @@ func run() {
log.Fatal("Could not create window:", err)
}

// TODO: Setup input.

vm = chip8.New()
vm.Debug = debug

Expand Down
69 changes: 59 additions & 10 deletions internal/chip8/opcodes.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,10 @@ func (v *VM) registerHandlers() {
opcode: "ANNN",
handler: v.setAddress,
},
// TODO: BNNN
0xB000: {
opcode: "BNNN",
handler: v.jumpV0,
},
0xC000: {
opcode: "CXNN",
handler: v.setVxRand,
Expand Down Expand Up @@ -359,8 +362,8 @@ func (v *VM) decVxVy(x, y uint16) opcodeHandlerFunc {
// to the right by 1.
func (v *VM) setVFLeastVx(x, y uint16) opcodeHandlerFunc {
return func() (uint16, error) {
v.v[0xF] = v.v[x] & 1
v.v[x] >>= 1
v.v[0xF] = v.v[x] & 1

v.pc += 2

Expand Down Expand Up @@ -389,8 +392,8 @@ func (v *VM) setVxVyMinusVx(x, y uint16) opcodeHandlerFunc {
// to the left by 1.
func (v *VM) setVFMostVx(x, y uint16) opcodeHandlerFunc {
return func() (uint16, error) {
v.v[0xF] = v.v[x] & 7
v.v[x] <<= 1
v.v[0xF] = v.v[x] & 7

v.pc += 2

Expand Down Expand Up @@ -423,6 +426,14 @@ func (v *VM) setAddress() (uint16, error) {
return v.opc, nil
}

// jumpV0 jumps to the address NNN plus V0.
func (v *VM) jumpV0() (uint16, error) {
// Jump to NNN.
v.pc = uint16(v.v[0]) + v.opc&0x0FFF

return v.opc, nil
}

// setVxRand sets VX to the result of a bitwise and operation on a random
// number (typically: 0 to 255) and NN.
func (v *VM) setVxRand() (uint16, error) {
Expand Down Expand Up @@ -497,9 +508,9 @@ func (v *VM) skipVxKeyPressed() (uint16, error) {
// instead of the usual 2.
if v.keys[k] == 1 {
v.keys[k] = 0
v.pc += 2
} else {
v.pc += 4
} else {
v.pc += 2
}

return v.opc & 0xFFFF, nil
Expand Down Expand Up @@ -530,23 +541,26 @@ func (v *VM) handle0xF000() (uint16, error) {
case 0x0007:
return v.getDelayTimer()

// TODO: FX0A
case 0x000A:
return v.getKey()

case 0x0015:
return v.setDelayTimer()

case 0x0018:
return v.setSoundTimer()

// TODO: FX1E
case 0x001E:
return v.incIVx()

case 0x0029:
return v.loadFont()

case 0x0033:
return v.setBCD()

// TODO: FX55
case 0x0055:
return v.regDump()

case 0x0065:
return v.regLoad()
Expand All @@ -556,14 +570,29 @@ func (v *VM) handle0xF000() (uint16, error) {
}
}

// getDelayTimer the delay timer to VX.
// getDelayTimer sets the delay timer to VX.
func (v *VM) getDelayTimer() (uint16, error) {
v.v[(v.opc&0x0F00)>>8] = v.delayTimer
v.pc += 2

return v.opc & 0xFFFF, nil
}

// getKey waits for a key press and then stores in VX. Blocking Operation. All
// instruction halted until next key event.
func (v *VM) getKey() (uint16, error) {
x := (v.opc & 0x0F00) >> 8
for i := range v.keys {
if v.keys[i] == 1 {
v.v[x] = v.keys[i]
v.pc += 2
break
}
}

return v.opc & 0xFFFF, nil
}

// setDelayTimer sets the delay timer to VX.
func (v *VM) setDelayTimer() (uint16, error) {
v.delayTimer = v.v[(v.opc&0x0F00)>>8]
Expand All @@ -580,6 +609,14 @@ func (v *VM) setSoundTimer() (uint16, error) {
return v.opc & 0xFFFF, nil
}

// incIVx adds VX to I.
func (v *VM) incIVx() (uint16, error) {
v.i += uint16(v.v[(v.opc&0x0F00)>>8])
v.pc += 2

return v.opc & 0xFFFF, nil
}

// loadFont sets i to the location of the sprite for the character in VX.
// Characters 0-F (in hexadecimal) are represented by a 4x5 font.
func (v *VM) loadFont() (uint16, error) {
Expand All @@ -605,7 +642,19 @@ func (v *VM) setBCD() (uint16, error) {
return v.opc & 0xFFFF, nil
}

// fillV0Vx stores V0 to VX (including VX) in mem starting at address i. The
// regDump stores V0 to VX (including VX) in memory starting at address i. The
// offset from i is increased by 1 for each value written, but i itself is left
// unmodified.
func (v *VM) regDump() (uint16, error) {
for i := uint16(0); i <= (v.opc&0x0F00)>>8; i++ {
v.mem[v.i+i] = v.v[i]
}
v.pc += 2

return v.opc & 0xFFFF, nil
}

// regLoad stores V0 to VX (including VX) in mem starting at address i. The
// offset from i is increased by 1 for each value written, but i itself is left
// unmodified.
func (v *VM) regLoad() (uint16, error) {
Expand Down
2 changes: 1 addition & 1 deletion internal/chip8/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ func (v *VM) Beep() <-chan struct{} {
}

// KeyDown marks key as pressed.
func (v *VM) KeyDown(key uint16) {
func (v *VM) KeyDown(key byte) {
v.keys[key] = 1
}

Expand Down

0 comments on commit 7d4e111

Please sign in to comment.