{deck}
version:1
card:0
size:[512,342]
name:"chip8.deck"

{card:home}
script:"home.0"
{widgets}
display:{"type":"canvas","size":[256,128],"pos":[238,25],"locked":1,"border":1,"scale":4}
keypad:{"type":"canvas","size":[160,160],"pos":[291,166],"locked":1,"border":1,"scale":1}
rom:{"type":"field","size":[193,63],"pos":[23,159],"scrollbar":1,"style":"plain"}
button1:{"type":"button","size":[98,20],"pos":[23,129],"script":"home.1","text":"Load .CH8 ROM"}
button2:{"type":"button","size":[86,20],"pos":[130,129],"locked":1,"script":"home.2","text":"Run"}
roms:{"type":"grid","size":[193,102],"pos":[23,224],"locked":1,"script":"home.3","lines":0,"widths":[166,12],"value":{"Choose a ROM":["Slippery Slope","WDL","Keyboard Test","Octojam 10 Greeting"],"rom":["%%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AQAAAAAABQAFAAAABQUAAAAABQUAAAAFBQUFAAAFBQAAAAAABQUFAAAABQUAAAAABQUAAAAFBQUAAAAABQAAAAAABQAAAAAFBQUAAQQFBQUFBQUFBQAAAAUFBQAAAAUFAAAAAAUFAAAUAAAFAAAAAAAFBQAAAAUFBQUABQUFBQAAAAUFBQAAAAUFBQAAAAUFBQUFBQUJAwIDAAAAAAAAAAAAAAAUDwAAAAAAAAUAAAAAAAAAAA8AABQAAAAAAAAAAAAAAAAAAAAADwAABQAUAA8AAAAAAAAAAAAAAAAADwAACgMBAQAUAAAPAAAAAAAAAAAAAAAAFA8AAAAAABQAAAAAAA8ADwAAFBQUDxQADw8AAAAAFBQUAAAADw8AAA8AFAoUDwAADwAUDxQPFAsAAAIKCgoKCgoKAAAAAAoKAAAAAAoKAAAAAAoKAAAAAAoKAFAyAAoKAF9BAAoKAAAAAAoKAAAAAAoKAAAAAAoKAAAAAAoKCgoKCgoJAwICAAAANwAAAAAAAAAFBQ8AAAAAAAAAFABLAAAAAAAABQUFAAAABQUFABQABRQAABQAAAAADwAAAAAAAAAAAAAAAAAAWjIACgAUAwAIAAUFBQUFBQUFBQUFBQUFBQAFBQUFBQAFBQUAAB4AAAUFAAAFBQUFAAAFBQAAGQAABQUFAAUFBQUFAAUFBQUFBQUFBQUFBQUFBQkCAgMPFAAAFA8AAA8AIwAUAAAAABQADwAAAA8AHgAUAAAtAAAAABQAFA8UAAAAAAAAGQAUABQAABQAAAAUIwAAAAAADwAUDwAUABQCAgoBAAAKBQUAAAAACgUABQUAAAAAMgAZAAAURgAeAAAPRgAeHgAURgAeHgAPRgAZAAAURgAeGQAPQQAeAAAUAAAFAAAAAAAFAAAAAAULAQ==","%%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","%%DAT0EikAAAAAAAAAAAAAAAAAAAAAAQIDDAQFBg0HCAkOCgALD37//////35hEmIBYwCiEvMe8GXwKdElcQhBMnIIQTJhEnMBMxASL2EBYhBjAKIC8GUwABJj4Z4SYWABoiLSNxJt4aESbWAAoiLSN6IC8FVhAmIYYwCiA/BlMAASi+GeEolgAaIi0jcSleGhEpVgAKIi0jeiA/BVYQNiIGMAogTwZTAAErPhnhKxYAGiItI3Er3hoRK9YACiItI3ogTwVWEMYihjAKIF8GUwABLb4Z4S2WABoiLSNxLl4aES5WAAoiLSN6IF8FVhBGIQYwiiBvBlMAATA+GeEwFgAaIi0jcTDeGhEw1gAKIi0jeiBvBVYQViGGMIogfwZTAAEyvhnhMpYAGiItI3EzXhoRM1YACiItI3ogfwVWEGYiBjCKII8GUwABNT4Z4TUWABoiLSNxNd4aETXWAAoiLSN6II8FVhDWIoYwiiCfBlMAATe+GeE3lgAaIi0jcTheGhE4VgAKIi0jeiCfBVYQdiEGMQogrwZTAAE6PhnhOhYAGiItI3E63hoROtYACiItI3ogrwVWEIYhhjEKIL8GUwABPL4Z4TyWABoiLSNxPV4aET1WAAoiLSN6IL8FVhCWIgYxCiDPBlMAAT8+GeE/FgAaIi0jcT/eGhE/1gAKIi0jeiDPBVYQ5iKGMQog3wZTAAFBvhnhQZYAGiItI3FCXhoRQlYACiItI3og3wVWEKYhBjGKIO8GUwABRD4Z4UQWABoiLSNxRN4aEUTWAAoiLSN6IO8FVhAGIYYxiiD/BlMAAUa+GeFGlgAaIi0jcUdeGhFHVgAKIi0jeiD/BVYQtiIGMYohDwZTAAFJPhnhSRYAGiItI3FJ3hoRSdYACiItI3ohDwVWEPYihjGKIR8GUwABS74Z4UuWABoiLSNxTF4aEUxWAAoiLSN6IR8FUSSQ==","%%DAT0YQFiEGMPotLQH/Me0C/zHnAI0B/zHtAv8x5wCNAf8x7QL/MecAjQH/Me0C/zHnAI0B/zHtAv8x5wCNAf8x7QL/MecAjQH/Me0C/zHnAI0B/zHtAv8x5wCGADo8IiviK+Ir4iviK+Ir4iviK+Ir4iviK+Ir4iviK+Ir4iviK+Ir4iviK+Ir4iviK+Ir4iviK+Ir4iviK+Ir4iviK+Ir4iviK+Ir4iviK+Ir4iviK+Ir4iviK+Ir4iviK+Ir4SWtAf8x7QL/Me/wc/ABLGbwP/FQDuDx8cGBgYHB8PAA8fHBgYGBwfDwAfHx8DAwMDAwMAwODgYGBg4ODAAMDg4AAAAODgwADg4OAAAAAAAAAAAD8/f38AAAAAQWFzPz8eAAAAAAAAAAAAAAAAAAAAAP/+/Px5+fPz5+7M2LAgAAEDBw8DAwMDAwMDHx8AADx+f//vz///hwcDAwMAAODh4+Pj4+Pj4+Pj+fgAAPh8fz+7vbzc3s7u7+/vAP7/x8/P19fX5+fH//4AADA4fP7/9/dzMxEBAAAAAAAAgICAgICAgICAAAAAAAAAAAAAgMDA4ODg8PDwAAAAAAAAAAAAAAAAAAAAgRgkAAAkGIF+foEYJwAAJxiBfv8AAOcAAAAAABh+GCQAACQYgX5+gRgnAAAnGIF+/wAA5wAAAAAAGH6BJAAAJBiBfn6BGCcAACcYgX7/AADnAAAAAAAYfoEYAAAkGIF+foEYJwAAJxiBfv8AAOcAAAAAABh+gRgkACQYgX5+gRgnAAAnGIF+/wAA5wAAAAAAGH6BGCQAJBiBfn6BGCcAACcYgX7/AADnAAAAAAAYfoEYJAAAGIF+foEYJwAAJxiBfv8AAOcAAAAAABh+gRgkAAAkgX5+gRgnAAAnGIF+/wAA5wAAAAAAGH6BGCQAACQYfn6BGCcAACcYgX7/AADnAAAAAAAYfoEYJAAAJBiBfoEYJwAAJxiBfv8AAOcAAAAAABh+gRgkAAAkGIF+gRgnAAAnGIF+/wAA5wAAAAAAGH6BGCQAACQYgX4AGCcAACcYgX7/AADnAAAAAAAYfoEYJAAAJBiBfgAAJwAAJxiBfv8AAOcAAAAAABh+gRgkAAAkGIF+AAAAAAAnGIF+/wAA5wAAAAAAGH6BGCQAACQYgX4AAAAAACcYgX7/AADnAAAAAAAYfoEYJAAAJBiBfgAAAAAAJxiBfv8AAOcAAAAAABh+gRgkAAAkGIF+AAAAAAAAGIF+/wAA5wAAAAAAGH6BGCQAACQYgX4AAAAAAAAAgX7/AADnAAAAAAAYfoEYJAAAJBiBfgAAAAAAAAAAfv8AAOcAAAAAABh+gRgkAAAkGIF+AAAAAAAAAAB+/wAA5wAAAAAAGH6BGCQAACQYgX4AAAAAAAAAAH6BAADnAAAAAAAYfoEYJAAAJBiBfgAAAAAAAAAAfoEYAOcAAAAAABh+gRgkAAAkGIF+AAAAAAAAAAB+gRgk5wAAAAAAGH6BGCQAACQYgX4AAAAAAAAAAH6BGCQAAAAAAAAYfoEYJAAAJBiBfgAAAAAAAAAAfoEYJAAAAAAAABh+gRgkAAAkGIF+AAAAAAAAAAB+gRgkAAAkAAAAGH6BGCQAACQYgX4AAAAAAAAAAH6BGCQAACQYAAAYfoEYJAAAJBiBfgAAAAAAAAAAfoEYJAAAJBiBABh+gRgkAAAkGIF+AAAAAAAAAAB+gRgkAAAkGIF+GH6BGCQAACQYgX4AAAAAAAAAAH6BGCQAACQYgX5+foEYJAAAJBiBfgAAAAAAAAAAfoEYJAAAJBiBfn6BgRgkAAAkGIF+AAAAAAAAAAB+gRgkAAAkGIF+foEYGCQAACQYgX4AAAAAAAAAAH6BGCQAACQYgX5+gRgnJAAAJBiBfgAAAAAAAAAAfoEYJAAAJBiBfn6BGCcAAAAkGIF+AAAAAAAAAAB+gRgkAAAkGIF+foEYJwAAACQYgX4AAAAAAAAAAH6BGCQAACQYgX5+gRgnAAAnJBiBfgAAAAAAAAAAfoEYJAAAJBiBfn6BGCcAACcYGIF+AAAAAAAAAAB+gRgkAAAkGIF+foEYJwAAJxiBgX4AAAAAAAAAAH6BGCQAACQYgX5+gRgnAAAnGIF+fgAAAAAAAAAAfoEYJAAAJBiBfn6BGCcAACcYgX7/AAAAAAAAAAB+gRgkAAAkGIF+foEYJwAAJxiBfv8AAAAAAAAAAH6BGCQAACQYgX5+gRgnAAAnGIF+/wAAAAAAAAAAfoEYJAAAJBiBfn6BGCcAACcYgX7/AADnAAAAAAB+gRgkAAAkGIF+foEYJwAAJxiBfv8AAOcAAAAAAH6BGCQAACQYgX5+gRgnAAAnGIF+/wAA5wAAAAAAfoEYJAAAJBiBfn6BGCcAACcYgX7/AADnAAAAAAB+gRgkAAAkGIF+foEYJwAAJxiBfv8AAOcAAAAAAH6BGCQAACQYgX5+gRgnAAAnGIF+/wAA5wAAAAAAfoEYJAAAJBiBfn6BGCcAACcYgX7/AADnAAAAAAAY"]}}
speed:{"type":"slider","size":[193,25],"pos":[23,95],"interval":[1,1000],"value":20,"format":"%f cycles per frame","style":"compact"}
field1:{"type":"field","size":[193,59],"pos":[23,26],"locked":1,"border":0,"value":{"text":["This is an interpreter for ","CHIP8",", a virtual game console from 1977. Why not try your hand at making a new game for this year's ","octojam","?"],"font":["","","","",""],"arg":["","https://en.wikipedia.org/wiki/CHIP-8","","http://octojam.com/",""]}}
ex:{"type":"button","size":[26,20],"pos":[238,163],"show":"none","style":"check"}

{script:home.0}
on view do
 button2.text:if ex.value & !octo_emu.halted[]
  octo_emu.frame[speed.value]
  go[card]
  "Stop"
 else
  "Run"
 end
 button2.locked:!count rom.text
 button1.locked:rom.locked:ex.value
end
{end}

{script:home.1}
on click do
 rom.text:read["array"].encoded
 view[]
end
{end}

{script:home.2}
on click do
 if !ex.value
  octo_emu.init[array[rom.text] display keypad]
  ex.value:1
  view[]
 else
  ex.value:0
 end
end
{end}

{script:home.3}
on click do
 rom.text:me.rowvalue.rom
 view[]
end
{end}

{module:octo_emu}
description:"a basic chip8 emulator."
{script}

local pc:0               # program counter
local ix:0               # index register
local st:0               # sound timer
local dt:0               # delay timer
local rs:()              # return stack
local m:array[4096 "u8"] # memory
local v:array[16   "u8"] # chip8 registers
local d:0                # display
local k:0                # keypad
local kd:-1              # which keys is held (if any)
local halt:0             # program has halted

local font:array["%%DAT08JCQkPAgYCAgcPAQ8IDw8BDwEPCQkPAQEPCA8BDw8IDwkPDwECBAQPCQ8JDw8JDwEPDwkPCQkOCQ4JDg8ICAgPDgkJCQ4PCA8IDw8IDwgIA="]
local keycaps:"1234QWERASDFZXCV"
local keyvals:"%h" parse "" split "123C456D789EA0BF"

math[ 0]:on mov d x y do v[d]:y                  end
math[ 1]:on or  d x y do v[d]:bits.or [x y]      end 
math[ 2]:on and d x y do v[d]:bits.and[x y]      end
math[ 3]:on xor d x y do v[d]:bits.xor[x y]      end
math[ 4]:on add d x y do v[d]:x+y v[15]:255<x+y  end
math[ 5]:on sub d x y do v[d]:x-y v[15]:!x<y     end
math[ 7]:on bus d x y do v[d]:y-x v[15]:!y<x     end
math[ 6]:on shr d x y do v[d]:y/2 v[15]:2%y      end
math[14]:on shl d x y do v[d]:y*2 v[15]:y>127    end

misc[  7]:on gdel  x do v[x]:dt                      end
misc[ 21]:on sdel  x do dt:v[x]                      end
misc[ 24]:on ssnd  x do st:v[x]                      end
misc[ 30]:on addi  x do ix:ix+v[x]                   end
misc[ 41]:on fnt   x do ix:5*16%v[x]                 end
misc[ 51]:on bcd   x do m[ix,3]:10%v[x]/100,10,1     end
misc[ 85]:on save  x do m[ix,x+1]:v ix:ix+x+1        end
misc[101]:on load  x do v[0,x+1]:m[ix,x+1] ix:ix+x+1 end
misc[ 10]:on inkey x do
 while  kd<0 sleep[] kd:getkey[] end v[x]:kd
 while !kd<0 sleep[] kd:getkey[] end dt:0
end

on sprite x y n do
 v[15]:0
 each py in range n
  p:m[ix+py]
  each px in 7-range 8
   if 2%p
    c:(64,32)%(px,py)+(x,y)
    if d[c] v[15]:1 d[c]:0 else d[c]:1 end
   end
   p:floor p/2
  end
 end
end

module.getkey:on getkey do
 p:(pointer.pos-k.pos)/k.size
 if pointer.held&(min p>0)&(min p<1)
  i:floor(p*4)
  keyvals[i[0]+i[1]*4]
 else
  -1
 end
end

module.step:on step do
 a:m[pc]
 b:m[pc+1]
 x:16%a
 y:floor b/16
 o:floor a/16
 nnn:b+256*x
 pc:pc+2
 if o~0
  if     b~224 d.clear[]
  elseif b~238 pc:last rs rs:-1 drop rs
  else   halt:1
  end
 elseif o~14
  if     b~158 pc:pc+2* v[x]~kd
  elseif b~161 pc:pc+2*!v[x]~kd
  else   halt:1
  end
 elseif o~1   pc:nnn
 elseif o~2   rs:rs,pc pc:nnn
 elseif o~3   pc:pc+2*  v[x]~b
 elseif o~4   pc:pc+2* !v[x]~b
 elseif o~5   pc:pc+2*  v[x]~v[y]
 elseif o~6   v[x]:b
 elseif o~7   v[x]:v[x]+b
 elseif o~8   math[16%b][x v[x] v[y]]
 elseif o~9   pc:pc+2* !v[x]~v[y]
 elseif o~10  ix:nnn
 elseif o~11  pc:nnn+v[0]
 elseif o~12  v[x]:bits.and[b random[256]]
 elseif o~13  sprite[v[x] v[y] 16%b]
 elseif o~15  misc[b][x]
 end
end

module.init:on init rom display keypad do
 ix:bt:dt:halt:0 rs:() pc:512
 m[  0, 512]:font
 m[512,3584]:rom
 v[0,16]:0
 d:display
 k:keypad
 d.lsize:64,32
 d.clear[]

 keysize:k.size/4
 keycorn:flip 2+keysize*flip 4 cross 4
 k.clear[]
 k.pattern:1
 each key i in keycaps
  k.box[keycorn[i] keysize-4]
  k.text[key -2+keycorn[i]+keysize/2 "center"]
 end
end

module.halted:on halted do
 halt
end

module.frame:on frame ticks do
 kd:getkey[]
 q:16 unless ticks
 while (q>0)&!halt step[] q:q-1 end
 dt:dt-dt>0
 st:st-st>0
end
{end}

