Just trying to trigger release #1
@ -1,14 +1,17 @@
|
|||||||
package chip8
|
package chip8
|
||||||
|
|
||||||
import "fmt"
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
|
)
|
||||||
|
|
||||||
const graphicsBufferSize = 64 * 32
|
const graphicsBufferSize = 64 * 32
|
||||||
|
|
||||||
type Chip8 struct {
|
type Chip8 struct {
|
||||||
addressRegister uint16
|
addressRegister uint16
|
||||||
beepTimer uint16
|
beepTimer byte
|
||||||
drawRequired bool
|
drawRequired bool
|
||||||
delayTimer uint16
|
delayTimer byte
|
||||||
graphics [graphicsBufferSize]byte
|
graphics [graphicsBufferSize]byte
|
||||||
keys [16]byte
|
keys [16]byte
|
||||||
memory [4096]byte
|
memory [4096]byte
|
||||||
@ -106,9 +109,9 @@ func (cpu *Chip8) setRegisterTo() {
|
|||||||
cpu.registers[r] = byte(cpu.opcode & 0xFF)
|
cpu.registers[r] = byte(cpu.opcode & 0xFF)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cpu *Chip8) RegisterPlusEqualsNN() {} // QUESTION HERE - WHAT DO IF IT WOULD WRAP ROUND?
|
func (cpu *Chip8) registerPlusEqualsNN() {} // QUESTION HERE - WHAT DO IF IT WOULD WRAP ROUND?
|
||||||
|
|
||||||
func (cpu *Chip8) BitOpsAndMath() {
|
func (cpu *Chip8) bitOpsAndMath() {
|
||||||
instruction := cpu.opcode & 0x0F
|
instruction := cpu.opcode & 0x0F
|
||||||
regX, regY := cpu.opcode>>8&0x0F, cpu.opcode>>4&0x0F
|
regX, regY := cpu.opcode>>8&0x0F, cpu.opcode>>4&0x0F
|
||||||
switch instruction {
|
switch instruction {
|
||||||
@ -166,19 +169,134 @@ func (cpu *Chip8) BitOpsAndMath() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cpu *Chip8) SkipIfRegistersNotEqual() {
|
func (cpu *Chip8) skipIfRegistersNotEqual() {
|
||||||
x, y := (cpu.opcode>>8)&0x0F, (cpu.opcode>>4)&0x0F
|
x, y := (cpu.opcode>>8)&0x0F, (cpu.opcode>>4)&0x0F
|
||||||
if cpu.registers[x] != cpu.registers[y] {
|
if cpu.registers[x] != cpu.registers[y] {
|
||||||
cpu.pc += 2
|
cpu.pc += 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cpu *Chip8) SetAddressRegister() {
|
func (cpu *Chip8) setAddressRegister() {
|
||||||
// ANNN
|
// ANNN
|
||||||
// Sets the address register to NNN
|
// Sets the address register to NNN
|
||||||
cpu.addressRegister = cpu.opcode & 0x0FFF
|
cpu.addressRegister = cpu.opcode & 0x0FFF
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cpu *Chip8) jumpToV0PlusAddress() {
|
||||||
|
// BNNN
|
||||||
|
// PC=V0+NNN
|
||||||
|
cpu.pc = uint16(cpu.registers[0]) + (cpu.opcode & 0x0FFF)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cpu *Chip8) setRegisterToRand() {
|
||||||
|
// CXNN
|
||||||
|
// Vx = rand() & NN
|
||||||
|
cpu.registers[(cpu.opcode>>8)&0x0F] = byte(cpu.opcode&0xFF) & byte(rand.Intn(256))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cpu *Chip8) displaySprite() {
|
||||||
|
// DXYN
|
||||||
|
// Draws a sprite in the graphics buffer
|
||||||
|
// VF is set to 1 if any pixels are flipped and zero otherwise
|
||||||
|
cpu.registers[0x0F] = 0
|
||||||
|
x := int(cpu.registers[(cpu.opcode>>8)&0x0F])
|
||||||
|
y := int(cpu.registers[(cpu.opcode>>4)&0x0F])
|
||||||
|
|
||||||
|
for row := 0; row < int(cpu.opcode&0xF); row++ {
|
||||||
|
pixel := cpu.memory[int(cpu.addressRegister)+row]
|
||||||
|
for column := 0; column < 8; column++ {
|
||||||
|
if pixel&(0x80>>column) != 0 {
|
||||||
|
graphicsPosition := x + column + ((y + row) * 60)
|
||||||
|
if cpu.graphics[graphicsPosition] == 1 {
|
||||||
|
cpu.registers[0xF] = 1
|
||||||
|
}
|
||||||
|
cpu.graphics[graphicsPosition] ^= 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cpu.drawRequired = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cpu *Chip8) SkipOnKeyOpcodes() {
|
||||||
|
opcode := cpu.opcode & 0xFF
|
||||||
|
key := cpu.registers[(cpu.opcode>>8)&0x0F]
|
||||||
|
switch opcode {
|
||||||
|
case 0x9E:
|
||||||
|
// EX9E
|
||||||
|
// skip if key X is pressed
|
||||||
|
if cpu.keys[key] != 0 {
|
||||||
|
cpu.pc += 2
|
||||||
|
}
|
||||||
|
case 0xA1:
|
||||||
|
// EXA1
|
||||||
|
// skip if kkey X is not pressed
|
||||||
|
if cpu.keys[key] == 0 {
|
||||||
|
cpu.pc += 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cpu *Chip8) FifteenIndexOpcodes() {
|
||||||
|
instruction := cpu.opcode & 0xFF
|
||||||
|
reg := int(cpu.opcode>>8) & 0xF
|
||||||
|
switch instruction {
|
||||||
|
// FX07
|
||||||
|
// Set VX to the value of the delay timer
|
||||||
|
case 0x07:
|
||||||
|
cpu.registers[reg] = cpu.delayTimer
|
||||||
|
case 0x0A:
|
||||||
|
// FX0A
|
||||||
|
// block + wait for key press
|
||||||
|
for i, val := range cpu.keys {
|
||||||
|
if val != 0 {
|
||||||
|
cpu.registers[reg] = byte(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 0x15:
|
||||||
|
// FX15
|
||||||
|
// Set delay timer to VX
|
||||||
|
cpu.delayTimer = cpu.registers[reg]
|
||||||
|
case 0x18:
|
||||||
|
// FX18
|
||||||
|
// SET THE BEEP TIMER TO VX
|
||||||
|
// BEEP
|
||||||
|
cpu.beepTimer = cpu.registers[reg]
|
||||||
|
case 0x1E:
|
||||||
|
// FX1E
|
||||||
|
// Add VX to the address register
|
||||||
|
// Set VF to 1 when range overflow
|
||||||
|
if int(cpu.registers[reg])+int(cpu.addressRegister) > 0xFFF {
|
||||||
|
cpu.registers[0x0F] = 1
|
||||||
|
} else {
|
||||||
|
cpu.registers[0x0F] = 0
|
||||||
|
}
|
||||||
|
cpu.addressRegister = uint16((int(cpu.addressRegister) + int(cpu.registers[reg])) & 0xFFF)
|
||||||
|
case 0x29:
|
||||||
|
// FX29
|
||||||
|
// Sets address register to location of char stored in VX
|
||||||
|
cpu.addressRegister = uint16(cpu.registers[reg]) * 5
|
||||||
|
case 0x33:
|
||||||
|
// FX33
|
||||||
|
// Stores BCD representation of VX
|
||||||
|
cpu.memory[cpu.addressRegister] = cpu.registers[reg] / 100
|
||||||
|
cpu.memory[cpu.addressRegister+1] = (cpu.registers[reg] / 10) % 10
|
||||||
|
cpu.memory[cpu.addressRegister+2] = cpu.registers[reg] % 10
|
||||||
|
case 0x55:
|
||||||
|
// FX55
|
||||||
|
// takes values from and including reg X and stores then in memory
|
||||||
|
for i := 0; i <= reg; i++ {
|
||||||
|
cpu.memory[int(cpu.addressRegister)+i] = cpu.registers[i]
|
||||||
|
}
|
||||||
|
case 0x65:
|
||||||
|
// FX65
|
||||||
|
// takes values from memory and stores them in registers
|
||||||
|
for i := 0; i <= reg; i++ {
|
||||||
|
cpu.registers[i] = cpu.memory[int(cpu.addressRegister)+i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
fmt.Printf("Hello world!\n")
|
fmt.Printf("Hello world!\n")
|
||||||
prog := []byte{1, 2, 3, 4}
|
prog := []byte{1, 2, 3, 4}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user