@@ 1,118 @@
+package main
+
+import (
+ "fmt"
+ "math"
+ "time"
+
+ "github.com/faiface/pixel"
+ "github.com/faiface/pixel/pixelgl"
+ "golang.org/x/image/colornames"
+)
+
+const (
+ memSize = 4 * 1024
+ memReserved = 0x200
+ romStart = memReserved
+)
+
+type Chip8 struct {
+ mem [memSize]byte
+ v [16]byte
+ i uint16
+ dt byte
+ st byte
+ pc uint16
+ sp byte
+}
+
+func (c *Chip8) LoadRom(rom []byte) error {
+ copy(c.mem[romStart:], rom)
+ return nil
+}
+
+func run() {
+ d := NewDisplay(640, 320)
+ cfg := pixelgl.WindowConfig{
+ Title: "Octa-Chip",
+ Bounds: d.bounds,
+ VSync: true,
+ }
+
+ d.buffer[0] = 1
+ d.buffer[2] = 1
+
+ d.buffer[64] = 1
+ d.buffer[64+4] = 1
+
+ d.buffer[31*64] = 1
+
+ win, err := pixelgl.NewWindow(cfg)
+ if err != nil {
+ panic(err)
+ }
+
+ win.Clear(colornames.Black)
+
+ go func() {
+ i := 10
+ ticker := time.NewTicker(time.Second)
+ for {
+ select {
+ case <-ticker.C:
+ d.buffer[i] = 1
+ i += 2
+ fmt.Println(i)
+ }
+ }
+ }()
+
+ for !win.Closed() {
+ sprite := pixel.NewSprite(d, d.Bounds())
+ sprite.Draw(win, pixel.IM.Moved(win.Bounds().Center()))
+ win.Update()
+ }
+}
+
+func (c *Chip8) Run() {
+ pixelgl.Run(run)
+}
+
+type Display struct {
+ bounds pixel.Rect
+ xm, ym float64
+ buffer []byte
+ modeX, modeY int
+}
+
+func NewDisplay(w, h float64) *Display {
+ modeX := 64
+ modeY := 32
+
+ return &Display{
+ bounds: pixel.R(0, 0, w, h),
+ xm: w / float64(modeX),
+ ym: h / float64(modeY),
+ modeX: modeX,
+ modeY: modeY,
+ buffer: make([]byte, modeX*modeY),
+ }
+}
+
+func (d Display) Bounds() pixel.Rect {
+ return d.bounds
+}
+
+func (d Display) Color(at pixel.Vec) pixel.RGBA {
+ x := int(math.Floor(at.X / d.xm))
+ y := int(math.Floor(at.Y / d.ym))
+
+ y = d.modeY - y - 1
+
+ idx := y*d.modeX + x
+ set := d.buffer[idx]
+ if set == 1 {
+ return pixel.RGB(1, 1, 1)
+ }
+ return pixel.RGB(255, 255, 255)
+}