first few functions and unit tests
This commit is contained in:
parent
1b147aa4c7
commit
6776939cde
13
.drone.yml
Normal file
13
.drone.yml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
kind: pipeline
|
||||||
|
type: docker
|
||||||
|
name: default
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name : test
|
||||||
|
image: golang:latest
|
||||||
|
commands:
|
||||||
|
- go test
|
||||||
|
- name : build
|
||||||
|
image: golang:latest
|
||||||
|
commands
|
||||||
|
- go build
|
116
pkg/chip8/chip8.go
Normal file
116
pkg/chip8/chip8.go
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
package chip8
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
const graphicsBufferSize = 64 * 32
|
||||||
|
|
||||||
|
type Chip8 struct {
|
||||||
|
address_register uint16
|
||||||
|
beep_timer uint16
|
||||||
|
draw_required bool
|
||||||
|
delay_timer uint16
|
||||||
|
graphics [graphicsBufferSize]uint8
|
||||||
|
keys [16]uint8
|
||||||
|
memory [4096]uint8
|
||||||
|
opcode uint16
|
||||||
|
pc uint16
|
||||||
|
registers [16]uint8 // an array - has a fixed length
|
||||||
|
stack []uint16 // a slice - basically a c++ vector
|
||||||
|
}
|
||||||
|
|
||||||
|
// we can't have const arrays in go
|
||||||
|
// This is a good a solution as any
|
||||||
|
func getLetters() []uint8 {
|
||||||
|
return []uint8{
|
||||||
|
0xF0, 0x90, 0x90, 0x90, 0xF0, // 0
|
||||||
|
0x20, 0x60, 0x20, 0x20, 0x70, // 1
|
||||||
|
0xF0, 0x10, 0xF0, 0x80, 0xF0, // 2
|
||||||
|
0xF0, 0x10, 0xF0, 0x10, 0xF0, // 3
|
||||||
|
0x90, 0x90, 0xF0, 0x10, 0x10, // 4
|
||||||
|
0xF0, 0x80, 0xF0, 0x10, 0xF0, // 5
|
||||||
|
0xF0, 0x80, 0xF0, 0x90, 0xF0, // 6
|
||||||
|
0xF0, 0x10, 0x20, 0x40, 0x40, // 7
|
||||||
|
0xF0, 0x90, 0xF0, 0x90, 0xF0, // 8
|
||||||
|
0xF0, 0x90, 0xF0, 0x10, 0xF0, // 9
|
||||||
|
0xF0, 0x90, 0xF0, 0x90, 0x90, // A
|
||||||
|
0xE0, 0x90, 0xE0, 0x90, 0xE0, // B
|
||||||
|
0xF0, 0x80, 0x80, 0x80, 0xF0, // C
|
||||||
|
0xE0, 0x90, 0x90, 0x90, 0xE0, // D
|
||||||
|
0xF0, 0x80, 0xF0, 0x80, 0xF0, // E
|
||||||
|
0xF0, 0x80, 0xF0, 0x80, 0x80} // F
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCHIP8(prog []uint8) *Chip8 {
|
||||||
|
cpu := Chip8{pc: 0x200}
|
||||||
|
memory_slice := cpu.memory[:80]
|
||||||
|
copy(memory_slice, getLetters())
|
||||||
|
memory_slice = cpu.memory[200:]
|
||||||
|
copy(memory_slice, prog)
|
||||||
|
|
||||||
|
// Do some extra checking to ensure the right
|
||||||
|
// Stuff is copied
|
||||||
|
|
||||||
|
return &cpu
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cpu *Chip8) GetGraphicsBuffer() [graphicsBufferSize]uint8 {
|
||||||
|
return cpu.graphics
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cpu *Chip8) clearDisplay() {
|
||||||
|
// fuck it the gc can do the hard work for us
|
||||||
|
cpu.graphics = [64 * 32]uint8{}
|
||||||
|
cpu.draw_required = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// what if there's nothing in the stack?
|
||||||
|
// return something sensible
|
||||||
|
func (cpu *Chip8) leaveFunction() {
|
||||||
|
cpu.pc = cpu.stack[len(cpu.stack)-1]
|
||||||
|
cpu.stack[len(cpu.stack)-1] = 0
|
||||||
|
cpu.stack = cpu.stack[:len(cpu.stack)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cpu *Chip8) goTo() {
|
||||||
|
cpu.pc = cpu.opcode & 0x0FFF
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cpu *Chip8) callSubroutine() {
|
||||||
|
cpu.stack = append(cpu.stack, cpu.pc)
|
||||||
|
cpu.pc = cpu.opcode & 0x0FFF
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cpu *Chip8) skipIfRegisterEqual() {
|
||||||
|
r := (cpu.opcode) >> 8 & 0x0F
|
||||||
|
if cpu.registers[r] == uint8(cpu.opcode&0xFF) {
|
||||||
|
cpu.pc += 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cpu *Chip8) skipIfRegisterNotEqual() {
|
||||||
|
r := (cpu.opcode) >> 8 & 0x0F
|
||||||
|
if cpu.registers[r] != uint8(cpu.opcode&0xFF) {
|
||||||
|
cpu.pc += 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cpu *Chip8) skipIfRegistersEqual() {
|
||||||
|
x, y := (cpu.opcode>>8)&0x0F, (cpu.opcode>>4)&0x0F
|
||||||
|
if cpu.registers[x] == cpu.registers[y] {
|
||||||
|
cpu.pc += 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cpu *Chip8) setRegisterToNN() {
|
||||||
|
r := (cpu.opcode >> 8) & 0x0F
|
||||||
|
cpu.registers[r] = uint8(cpu.opcode & 0xFF)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cpu *Chip8) RegisterPlusEqualsNN() {} // QUESTION HERE - WHAT DO IF IT WOULD WRAP ROUND?
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Printf("Hello world!\n")
|
||||||
|
prog := []uint8{1, 2, 3, 4}
|
||||||
|
new_cpu := NewCHIP8(prog)
|
||||||
|
fmt.Printf("%d\n", new_cpu.opcode)
|
||||||
|
}
|
56
pkg/chip8/chip8_test.go
Normal file
56
pkg/chip8/chip8_test.go
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
package chip8
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func slicesEqual(x, y []uint8) bool {
|
||||||
|
if len(x) != len(y) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for i, xi := range x {
|
||||||
|
if xi != y[i] {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// This test is kinda shit, there's so much stuff we ain't testing
|
||||||
|
// Maybe fix
|
||||||
|
func TestCreateCPU(t *testing.T) {
|
||||||
|
prog := []uint8{1, 2, 3, 4}
|
||||||
|
new_cpu := NewCHIP8(prog)
|
||||||
|
if !slicesEqual(new_cpu.memory[200:204], prog) {
|
||||||
|
t.Errorf("CPU not initalized properly")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestClearDisplay(t *testing.T) {
|
||||||
|
cpu := Chip8{}
|
||||||
|
for i := range cpu.graphics {
|
||||||
|
cpu.graphics[i] = uint8(i % 255)
|
||||||
|
}
|
||||||
|
cpu.clearDisplay()
|
||||||
|
graphics_array := cpu.GetGraphicsBuffer()
|
||||||
|
graphics_slice := graphics_array[:]
|
||||||
|
empty_slice := make([]uint8, len(cpu.graphics))
|
||||||
|
if !slicesEqual(graphics_slice, empty_slice) {
|
||||||
|
t.Errorf("Graphics buffer not cleared properly")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLeaveFunction(t *testing.T) {
|
||||||
|
cpu := Chip8{pc: 50}
|
||||||
|
cpu.stack = append(cpu.stack, 1, 2, 3, 4, 5)
|
||||||
|
cpu.leaveFunction()
|
||||||
|
if cpu.pc != 4 && len(cpu.stack) != 4 {
|
||||||
|
t.Errorf("TestLeaveFunction not in expected state")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPasses(t *testing.T) {
|
||||||
|
if 1 != 1 {
|
||||||
|
t.Errorf("We should never get this!")
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user