	[const sp $5d][const sph $5e]
	[const sreg $5f]
	  [const c 0][const z 1]

	[const pina $39][const porta $3b]
	  [const rx 0]
	[const pinb $36][const ddrb $37][const portb $38]

	[const eearl $3e][const eearh $3f][const eedr $3d]
	[const eecr $3c]
	  [const eere 0][const eepe 1][const eempe 2]
	[const tccr0a $50][const tccr0b $53][const tcnt0 $52][const ocr0a $56]
	[const timsk0 $59][const tifr0 $58]

	[const pixel-port portb][const pixel-ddr ddrb][const pixpin 2]

	[const powerup-flag $60][const can-stop $61]
	[const monsp $62][const monsph $63]	; get clobbered by reset
	[const seed $64][const seedh $65]
	[const timer-t0 $66][const timer-t0h $67]
	[const brightness $68][const cmd $69]
	[const globals $6a]

	[const pixel-buf $80]

	[namereg t-d0 13][namereg t-sreg 12]
	[namereg t-ticksh 11][namereg t-ticks 10]
	

	[const boot-putc $0f]
	[const cc $8000]		; start of eeprom
	[const powerup-addr $81f0]	
	[const runcmd-addr $81f4]	

	[const putc-addr 15]


	[org $100]

start	[rjmp init]
	[rjmp bad-int][rjmp bad-int][rjmp bad-int][rjmp bad-int]
	[rjmp bad-int][rjmp bad-int][rjmp bad-int][rjmp bad-int]
	[rjmp timer0_compa][rjmp bad-int][rjmp bad-int][rjmp bad-int]
	[rjmp bad-int][rjmp bad-int]

bad-int	[cli]
	[ldi d0 $bb][rcall putc]
	[rjmp 0]

init	[lds d7 powerup-flag]
	[or d7 d7][brne run-code]
	[push d0]
	[ldi d7 $a5][sts d7 powerup-flag]
	[ldi d7 2][out d7 tccr0a]		; ctc mode
	[ldi d7 3][out d7 tccr0b]		; / 64
	[ldi d7 125][out d7 ocr0a]
	[ldi d7 2][sts d7 timsk0]	; oca int
	[ldi d7 20][sts d7 brightness]
	[sbi pixel-ddr pixpin]
	[rcall clear-pixels]
	[pop d0]
	[sei]

;---------------
;
; vm
;

run-code
	[cpi d0 0][breq run-cc]
	[cpi d0 1][breq run-powerup]
run-runcmd
	[sts d0 cmd]
	[ldi d0 1][sts d0 can-stop]
	[ldi ip [byte0 :runcmd-addr]]
	[ldi iph [byte1 :runcmd-addr]]
	[rjmp start-eval]

run-cc
	[ldi d0 1][sts d0 can-stop]
	[ldi ip [byte0 :cc]]
	[ldi iph [byte1 :cc]]
	[rjmp start-eval]


run-powerup
	[ldi d0 0][sts d0 can-stop]
	[ldi ip [byte0 :powerup-addr]]
	[ldi iph [byte1 :powerup-addr]]

start-eval
	[lds d0 sp][sts d0 monsp]
	[lds d0 sph][sts d0 monsph]
	[mov d0 t-ticks][ori d0 1][sts d0 seed]
	[mov d0 t-ticksh][ori d0 1][sts d0 seedh]
poll	[lds d0 can-stop][or d0 d0][breq eval]
	[sbis pina rx][rjmp eval-done]
eval	[rcall fetch]
	[ldi z [byte0 :eval-table]]
	[ldi zh [byte1 :eval-table]]
	[ldi d0 0][add z t0][adc zh d0]
	[ijmp]

eval-table
	[rjmp eval-done]
	[rjmp eval-byte][rjmp eval-num]
	[rjmp eval-list][rjmp eval-eol][rjmp eval-eolr]
	[rjmp eval-lthing][rjmp eval-lmake]
	[rjmp eval-gthing][rjmp eval-gmake]
	[rjmp eval-ufun]
	[rjmp prim-stop][rjmp prim-output]
	[rjmp prim-loop][rjmp prim-repeat]
	[rjmp prim-if][rjmp prim-ifelse]
	[rjmp prim-waituntil]
	[rjmp prim-sum][rjmp prim-diff]
	[rjmp prim-mul][rjmp prim-div]
	[rjmp prim-rem]
	[rjmp prim-gr][rjmp prim-lt]
	[rjmp prim-eq][rjmp prim-neq]
	[rjmp prim-and][rjmp prim-or]
	[rjmp prim-xor][rjmp prim-not]
	[rjmp prim-byte1][rjmp prim-byte0]
	[rjmp prim-leftshift]
	[rjmp prim-random]
	[rjmp prim-readfb]
	[rjmp prim-readb][rjmp prim-writeb]
	[rjmp prim-bsetb][rjmp prim-bclrb][rjmp prim-btstb] 
	[rjmp prim-read][rjmp prim-write]
	[rjmp prim-bset][rjmp prim-bclr] 
	[rjmp prim-wait][rjmp prim-mwait]
	[rjmp prim-resett][rjmp prim-timer][rjmp prim-ticks]
	[rjmp prim-print][rjmp prim-prh][rjmp prim-prhb]
	[rjmp prim-prs][rjmp prim-prf]
	[rjmp prim-alloff][rjmp prim-shift-pixels]
	[rjmp prim-dot][rjmp prim-dotoff][rjmp prim-brightness]
	[rjmp prim-cmd][rjmp prim-putc]

eval-done
	[lds d0 can-stop][cpi d0 0][breq evd30]
evd20	[sbis pina rx][rjmp evd20]
evd30	[lds d0 monsp][sts d0 sp]
	[lds d0 monsph][sts d0 sph]
	[ret]

eval-byte
	[rcall fetch]
	[ldi d0 0]
	[push d0][push t0]
	[rjmp eval]

eval-num
	[rcall fetch][mov d0 t0]
	[rcall fetch]
	[push t0][push d0]
	[rjmp eval]

eval-list
	[rcall fetch][mov d0 t0]
	[rcall fetch]
	[push iph][push ip]
	[add ip d0][adc iph t0]
	[rjmp eval]

eval-eolr
	[pop d0][pop d1]
	[pop zh][pop z]
	[push d1][push d0]
	[ijmp]

eval-eol
	[ret]

get-local-address
	[rcall fetch]
	[ldi d0 0]
	[sbrc t0 7][ldi d0 $ff]
	[movw y fp]
	[sbrs t0 7][adiw y 7]
	[sbrc t0 7][adiw y 1]
	[add y t0][adc yh d0]
	[add y t0][adc yh d0]
	[ret]

eval-lthing
	[rcall get-local-address]
	[ld@y+ d0][ld@y+ d1]
	[push d1][push d0]
        [rjmp eval]

eval-lmake
	[rcall get-local-address]
	[pop d0][pop d1]
	[st@y+ d0][st@y+ d1]
	[rjmp poll]

eval-gthing
	[rcall fetch]
	[add t0 t0][sub t1 t1]
	[ldi x [byte0 :globals]]
	[ldi xh [byte1 :globals]]
	[add x t0][adc xh t1]
	[ld@x+ d0][ld@x d1]
	[push d1][push d0]
	[rjmp eval]

eval-gmake
	[pop d0][pop d1]
	[rcall fetch]
	[add t0 t0][sub t1 t1]
	[ldi x [byte0 :globals]]
	[ldi xh [byte1 :globals]]
	[add x t0][adc xh t1]
	[st@x+ d0][st@x d1]
	[rjmp eval]

eval-ufun
	[rcall fetch][mov x t0]
	[rcall fetch][mov xh t0]
	[push iph][push ip]
	[movw ip x]
	[rcall fetch]
	[eor t1 t1][push t1][push t0]
	[rcall fetch]		; fetch locals (ignored for now)
	[push fph][push fp]
	[lds fp sp][lds fph sph]
	[or t0 t0][breq eu90]
eu20	[push t0][push t0]
	[dec t0][brne eu20]
eu90	[rjmp eval]


prim-stop
	[sts fp sp][sts fph sph]
	[pop fp][pop fph]
	[pop t0][pop t1]
	[pop ip][pop iph]
	[lds t2 sp][lds t3 sph]
	[add t0 t0][adc t1 t1]
	[add t0 t2][adc t1 t3]
	[sts t0 sp][sts t1 sph]
	[rjmp poll]

prim-output
	[pop d0][pop d1]
	[sts fp sp][sts fph sph]
	[pop fp][pop fph]
	[pop t0][pop t1]
	[pop ip][pop iph]
	[lds t2 sp][lds t3 sph]
	[add t0 t0][adc t1 t1]
	[add t0 t2][adc t1 t3]
	[sts t0 sp][sts t1 sph]
	[push d1][push d0]
	[rjmp poll]

prim-loop
	[pop ip][pop iph]
	[push iph][push ip]
	[ldi d0 [byte0 :prim-loop]][push d0]
	[ldi d0 [byte1 :prim-loop]][push d0]
	[rjmp eval]
	
prim-repeat
	[push iph][push ip]
rep20	[lds y sp][lds yh sph]
	[ldd@y x 5][ldd@y xh 6]
	[mov d0 x][or d0 xh][breq rep80]
	[sbiw x 1]
	[std@y x 5][std@y xh 6]
	[ldd@y ip 3][ldd@y iph 4]
	[rcall eval]
	[rjmp rep20]
rep80	[pop ip][pop iph]
	[pop d0][pop d0]
	[pop d0][pop d0]
	[rjmp poll]


prim-ifelse
	[pop d0][pop d1]
	[pop d2][pop d3]
	[pop t0][pop t1]
	[or t0 t1][breq run-r0]
	[movw d0 d2]
	[rjmp run-r0]

prim-if	[pop d0][pop d1]
	[pop d2][pop d3]
	[or d3 d2][breq if90]
run-r0	[push iph][push ip]
	[movw ip d0]
	[rcall eval]
	[pop ip][pop iph]
if90	[rjmp poll]

prim-waituntil
	[push iph][push ip]
wun20	[lds y sp][lds yh sph]
        [ldd@y ip 5][ldd@y iph 6]
        [rcall poll]
	[pop d0][pop d1]
        [or d0 d1][breq wun20]
        [pop ip][pop iph]
        [pop d0][pop d0]
        [rjmp poll]

prim-sum
	[pop d0][pop d1]
	[pop d2][pop d3]
	[add d0 d2][adc d1 d3]
	[push d1][push d0]
	[rjmp eval]

prim-diff
	[pop d2][pop d3]
	[pop d0][pop d1]
	[sub d0 d2][sbc d1 d3]
	[push d1][push d0]
	[rjmp eval]

prim-mul
        [rcall pop-signed-nums]
	[rcall unsigned-mul]
	[brtc mul50]
	[eor t0 t0][eor t1 t1]
	[sub t0 d0][sbc t1 d1]
	[movw d0 t0]
mul50	[push d1][push d0]
	[rjmp eval]

unsigned-mul
	[ldi d0 0][ldi d1 0]
	[ldi d6 16]
mul20	[lsr d3][ror d2]
	[brcc mul30]
	[add d0 d4][adc d1 d5]
mul30	[add d4 d4][adc d5 d5]
	[dec d6][brne mul20]
	[ret]

prim-div
	[rcall pop-signed-nums]
	[rcall unsigned-divide]
	[brtc div50]
	[eor t0 t0][eor t1 t1]
	[sub t0 d0][sbc t1 d1]
	[movw d0 t0]
div50	[push d1][push d0]
	[rjmp eval]
	
prim-rem
	[rcall pop-signed-nums]
	[rcall unsigned-divide]
	[mov t0 d2][or t0 d3][breq rem80]
	[cpi yh 0][brmi negmod]
	[cpi xh 0][brpl rem80]
	[sub y d2][sbc yh d3][movw d2 y]
	[rjmp rem80]
negmod	[cpi xh 0][brmi rem50]
	[add d2 y][adc d3 yh]
	[rjmp rem80]
rem50	[eor t0 t0][eor t1 t1]
	[sub t0 d2][sbc t1 d3]
	[movw d2 t0]
rem80	[push d3][push d2]
	[rjmp eval]

unsigned-divide
        [eor d0 d0][eor d1 d1]           ; clear the result register
        [mov t0 d4][or t0 d5]
        [breq div90]     		 ; don't divide by zero
        [eor d7 d7][ldi d6 1] 		 ; set the addend to 1
div20   [rcall cmp-nums]
        [brcc div40]
        [add d6 d6][adc d7 d7]
        [add d4 d4][adc d5 d5]
        [brcc div20]
div40	[lsr d7][ror d6]
        [lsr d5][ror d4]
        [mov t0 d6][or t0 d7]
        [breq div90]
        [rcall cmp-nums]
        [brcc div40]
	[sub d2 d4][sbc d3 d5]
	[add d0 d6][adc d1 d7]
        [rjmp div40]
div90	[ret]

cmp-nums[cp d5 d3]             ; compare the high bytes
        [brne cpn90]            ; if neq then return right away
        [cp d4 d2]             ; otherwise check the low bytes
	[brne cpn90]
	[sec]
cpn90   [ret]

pop-signed-nums
	[pop zh][pop z]
	[pop d4][pop d5]
	[movw y d4]		; save the signed second arg
	[pop d2][pop d3]
	[movw x d2]		; save the signed first arg
	[mov t0 d5][eor t0 d3]
	[bst t0 7]
	[sbrs d5 7][rjmp psn50]
	[eor t0 t0][eor t1 t1]
	[sub t0 d4][sbc t1 d5]
	[movw d4 t0]
psn50	[sbrs d3 7][rjmp psn90]
	[eor t0 t0][eor t1 t1]
	[sub t0 d2][sbc t1 d3]
	[movw d2 t0]
psn90	[ijmp]

prim-gr	[pop d2][pop d3]
	[pop d0][pop d1]
	[mov t0 d1][eor t0 d3]
	[sbrc t0 7][rjmp gr80]	
	[sub d0 d2][sbc d1 d3]
	[mov t0 d0][or t0 d1][breq return-false]
gr80	[sbrs d1 7][rjmp return-true]
	[rjmp return-false]

prim-lt	[pop d2][pop d3]
	[pop d0][pop d1]
	[mov t0 d1][eor t0 d3]
	[sbrc t0 7][rjmp lt80]	
	[sub d0 d2][sbc d1 d3]
lt80	[sbrs d1 7][rjmp return-false]
	[rjmp return-true]

prim-eq	[pop d2][pop d3]
	[pop d0][pop d1]
	[cp d0 d2][brne return-false]
	[cp d1 d3][brne return-false]
return-true
	[eor d0 d0][push d0]
	[ldi d0 1][push d0]
	[rjmp eval]
	
prim-neq
	[pop d2][pop d3]
	[pop d0][pop d1]
	[cp d0 d2][brne return-true]
	[cp d1 d3][brne return-true]
return-false
	[eor d0 d0]
	[push d0][push d0]
	[rjmp eval]

prim-and
	[pop d0][pop d1]
	[pop d2][pop d3]
	[and d0 d2][and d1 d3]
	[push d1][push d0]
	[rjmp eval]

prim-or
	[pop d0][pop d1]
	[pop d2][pop d3]
	[or d0 d2][or d1 d3]
	[push d1][push d0]
	[rjmp eval]

prim-xor
	[pop d0][pop d1]
	[pop d2][pop d3]
	[eor d0 d2][eor d1 d3]
	[push d1][push d0]
	[rjmp eval]

prim-not
	[pop d0][pop d1]
	[or d0 d1][breq not90]
	[rjmp return-false]
not90	[rjmp return-true]

prim-byte1
	[pop d0][pop d1]
	[eor d2 d2]
	[push d2][push d1]
	[rjmp eval]

prim-byte0
	[pop d0][pop d1]
	[eor d2 d2]
	[push d2][push d0]
	[rjmp eval]

prim-leftshift
	[pop d2][pop d3]
	[pop d0][pop d1]
	[or d2 d2][breq lsh90][brmi rightshift]
lsh20	[add d0 d0][adc d1 d1]
	[dec d2][brne lsh20]
lsh90	[push d1][push d0]
	[rjmp eval]

rightshift
	[neg d2]
rsh20	[lsr d1][ror d0]
	[dec d2][brne rsh20]
	[push d1][push d0]
	[rjmp eval]

prim-random
	[pop d4][pop d5]
	[pop t2][pop t3]
	[sub d4 t2][sbc d5 t3]
	[ldi d2 1][ldi d3 0]
	[add d4 d2][adc d5 d3]
	[lds d0 seed][lds d1 seedh]
	[ldi d2 17]
ran20	[eor d3 d3]
	[sbrc d1 7][inc d3]
	[sbrc d0 4][inc d3]
	[sbrc d0 2][inc d3]
	[sbrc d0 1][inc d3]
	[add d0 d0][adc d1 d1]
	[andi d3 1][add d0 d3]
	[dec d2][brne ran20]
	[sts d0 seed][sts d1 seedh]
	[andi d1 $7f]
	[movw d2 d0]
	[rcall unsigned-divide]
	[add d2 t2][adc d3 t3]
	[push d3][push d2]
	[rjmp eval]

prim-readfb
	[pop z][pop zh]
	[call readfb][eor d0 d0]
	[push d0][push t0]
	[rjmp eval]

prim-readb
	[pop x][pop xh]
	[ld@x d0][eor d1 d1]
	[push d1][push d0]
	[rjmp eval]

prim-writeb
	[pop d0][pop d1]
	[pop x][pop xh]
	[st@x d0]
	[rjmp poll]

prim-bsetb
	[pop d0][pop d1]
	[pop x][pop xh]
	[ld@x d2][or d2 d0][st@x d2]
	[rjmp poll]

prim-bclrb
	[pop d0][pop d1]
	[pop x][pop xh]
	[ldi d2 $ff][eor d0 d2]
	[ld@x d2][and d2 d0][st@x d2]
	[rjmp poll]

prim-btstb
	[pop d0][pop d1]
	[pop x][pop xh]
	[ld@x d2][and d2 d0]
	[breq btstb80]
	[rjmp return-true]
btstb80	[rjmp return-false]


prim-read
	[pop x][pop xh]
	[ld@x+ d0][ld@x d1]
	[push d1][push d0]
	[rjmp eval]

prim-write
	[pop d0][pop d1]
	[pop x][pop xh]
	[st@x+ d0][st@x d1]
	[rjmp poll]

prim-bset
	[pop d0][pop d1]
	[pop x][pop xh]
	[ld@x d2][or d2 d0][st@x+ d2]
	[ld@x d2][or d2 d1][st@x d2]
	[rjmp poll]

prim-bclr
	[pop d0][pop d1]
	[pop x][pop xh]
	[ldi d2 $ff][eor d0 d2][eor d1 d2]
	[ld@x d2][and d2 d0][st@x+ d2]
	[ld@x d2][and d2 d1][st@x d2]
	[rjmp poll]

prim-resett
	[cli]
	[sts t-ticks timer-t0][sts t-ticksh timer-t0h]
	[sei]
	[rjmp poll]
	
prim-timer
	[cli][mov d0 t-ticks][mov d1 t-ticksh][sei]
	[lds d2 timer-t0][lds d3 timer-t0h]
	[sub d0 d2][sbc d1 d3]
	[andi d1 $7f]
	[push d1][push d0]
	[rjmp eval]

prim-ticks
	[cli]
	[push t-ticksh][push t-ticks]
	[sei]
	[rjmp eval]

prim-wait
	[ldi x 100][ldi xh 0]
	[pop y][pop yh]
	[rcall milli-wait]
	[sbiw y 1][push yh][push y]
	[brne prim-wait]
	[pop t0][pop t0]
	[rjmp poll]

prim-mwait
	[pop x][pop xh]
	[rcall milli-wait]
	[rjmp poll]

milli-wait
	[mov t0 t-ticks]
mw50	[lds d0 can-stop][or d0 d0][breq mw70]
	[sbis pina rx][rjmp eval-done]
mw70	[cp t0 t-ticks][breq mw50]
	[sbiw x 1][brne milli-wait]
mw90	[ret]

prim-prf
	[pop d2][pop d3]
	[pop z][pop zh]
prf20	[rcall readfb][mov d0 t0][adiw z 1]
	[cpi d0 0][breq prf90]
	[cpi d0 37][brne prf50]
	[rcall prf-escape]
	[rjmp prf20]
prf50	[rcall putc]
	[rjmp prf20]
prf90	[rjmp poll]

prf-escape
	[rcall readfb][mov d0 t0][adiw z 1]
	[cpi d0 98][breq prfhb]		; %b
	[cpi d0 119][breq prfh]		; %w
	[cpi d0 100][breq prfd]		; %d
	[rjmp putc]
prfhb	[rjmp prhb]
prfh	[rjmp prh]
prfd	[mov t0 d2][mov t1 d3]
	[rjmp prd]
	
prim-prs
	[pop z][pop zh]
prs20	[rcall readfb][mov d0 t0][adiw z 1]
	[or d0 d0][breq prs90]
	[rcall putc]
	[rjmp prs20]
prs90	[ldi d0 13][rcall putc]
	[rjmp poll]

prim-print
	[pop t0][pop t1]
	[rcall prd]
	[ldi d0 13][rcall putc]
	[rjmp poll]


prd	[sbrs t1 7][rjmp pp20]
	[movw t2 t0]
	[eor t0 t0][eor t1 t1]
	[sub t0 t2][sbc t1 t3]
	[ldi d0 [ascii "-]][rcall putc]
pp20	[clt]
        [ldi d0 [byte0 10000]]
        [ldi d1 [byte1 10000]]
        [rcall do-digit]
        [ldi d0 [byte0 1000]]
        [ldi d1 [byte1 1000]]
        [rcall do-digit]
        [ldi d0 [byte0 100]]
        [ldi d1 [byte1 100]]
        [rcall do-digit]
        [ldi d0 [byte0 10]]
        [ldi d1 [byte1 10]]
        [rcall do-digit]
        [ldi d0 48]     ;convert to ascii
	[add d0 t0]
	[rjmp putc]

do-digit
        [eor t2 t2]
dd20    [sub t0 d0][sbc t1 d1]
        [inc t2]
        [sbrs t1 7] [rjmp dd20]
        [add t0 d0][adc t1 d1]
        [dec t2][brne dd60]
        [brts dd60]
        [ret]                   ; got a leading zero so don't print
dd60    [set]
        [ldi d0 48]     ;convert to ascii
	[add d0 t2]
	[rjmp putc]

prim-prh
	[pop d2][pop d3]
	[rcall prh]
	[ldi d0 13][rcall putc]
	[rjmp poll]

prim-prhb
	[pop d2][pop d3]
	[rcall prhb]
	[ldi d0 13][rcall putc]
	[rjmp poll]

prh	[push d2][mov d2 d3]
	[rcall prhb]
	[pop d2]
prhb	[mov d0 d2]
	[lsr d0][lsr d0]
	[lsr d0][lsr d0]
	[rcall prh-digit]
	[mov d0 d2][andi d0 $0f]
prh-digit
	[ldi d1 7]
	[cpi d0 10][in t0 sreg]
	[sbrs t0 c][add d0 d1]
	[ldi d1 $30][add d0 d1]
	[rjmp putc]

prim-shift-pixels
	[rcall shift-pixels]
	[rjmp poll]


shift-pixels
	[cli]
	[ldi x [byte0 :pixel-buf]][ldi xh [byte1 :pixel-buf]]
	[ldi y [byte0 192]][ldi yh [byte1 192]]
shpx20	[ld@x+ d0]
	[sbi pixel-port pixpin]			;2
	[sbrs d0 7][cbi pixel-port pixpin]	;2/3
	[sbrc d0 7][cbi pixel-port pixpin]	;2/3
	[mov d0 d0][mov d0 d0]			;2
	[sbi pixel-port pixpin]			;2
	[sbrs d0 6][cbi pixel-port pixpin]	;2/3
	[sbrc d0 6][cbi pixel-port pixpin]	;2/3
	[mov d0 d0][mov d0 d0]			;2
	[sbi pixel-port pixpin]			;2
	[sbrs d0 5][cbi pixel-port pixpin]	;2/3
	[sbrc d0 5][cbi pixel-port pixpin]	;2/3
	[mov d0 d0][mov d0 d0]			;2
	[sbi pixel-port pixpin]			;2
	[sbrs d0 4][cbi pixel-port pixpin]	;2/3
	[sbrc d0 4][cbi pixel-port pixpin]	;2/3
	[mov d0 d0][mov d0 d0]			;2
	[sbi pixel-port pixpin]			;2
	[sbrs d0 3][cbi pixel-port pixpin]	;2/3
	[sbrc d0 3][cbi pixel-port pixpin]	;2/3
	[mov d0 d0][mov d0 d0]			;2
	[sbi pixel-port pixpin]			;2
	[sbrs d0 2][cbi pixel-port pixpin]	;2/3
	[sbrc d0 2][cbi pixel-port pixpin]	;2/3
	[mov d0 d0][mov d0 d0]			;2
	[sbi pixel-port pixpin]			;2
	[sbrs d0 1][cbi pixel-port pixpin]	;2/3
	[sbrc d0 1][cbi pixel-port pixpin]	;2/3
	[mov d0 d0][mov d0 d0]			;2
	[sbi pixel-port pixpin]			;2
	[sbrs d0 0][cbi pixel-port pixpin]	;2/3
	[sbrc d0 0][cbi pixel-port pixpin]	;2/3
	[sbiw y 1]
	[brne shpx20]
	[sei]
	[ret]

prim-alloff
	[rcall clear-pixels]
	[rjmp poll]

clear-pixels
	[ldi x [byte0 :pixel-buf]][ldi xh [byte1 :pixel-buf]]
	[ldi y [byte0 192]][ldi yh [byte1 192]]
	[ldi d0 0]
cp50	[st@x+ d0]
	[sbiw y 1]
	[brne cp50]
	[ret]

prim-dot
	[pop d0][pop d1]
	[pop d2][pop t0]
	[ldi d3 0]
	[ldi x [byte0 :pixel-buf]][ldi xh [byte1 :pixel-buf]]
	[add x d2][adc xh d3]
	[add x d2][adc xh d3]
	[add x d2][adc xh d3]
	[cpi d1 1][breq dot-white]
	[ldi z [byte0 :ctab]][ldi zh [byte1 :ctab]]
	[ldi d1 0][add d0 d0]
	[add z d0][adc zh d1]
	[add z z][adc zh zh]
	[lpm@z+ d0][rcall dim-d0][st@x+ d0]
	[lpm@z+ d0][rcall dim-d0][st@x+ d0]
	[lpm@z+ d0][rcall dim-d0][st@x+ d0]
	[rjmp poll]
dot-white
	[ldi d0 $ff][rcall dim-d0]
	[st@x+ d0][st@x+ d0][st@x+ d0]
	[rjmp poll]


dim-d0	[lds d4 brightness][ldi d5 0]
	[ldi d2 0][ldi d3 0]	
	[ldi d1 8]
mul8-20	[lsr d0]
	[brcc mul8-30]
	[add d2 d4][adc d3 d5]
mul8-30	[add d4 d4][adc d5 d5]
	[dec d1][brne mul8-20]
	[mov d0 d3]
	[ret]

prim-dotoff
	[pop d2][pop t0]
	[ldi d3 0]
	[ldi x [byte0 :pixel-buf]][ldi xh [byte1 :pixel-buf]]
	[add x d2][adc xh d3]
	[add x d2][adc xh d3]
	[add x d2][adc xh d3]
	[st@x+ d3][st@x+ d3][st@x+ d3]
	[rjmp poll]


prim-brightness
	[pop d0][pop t0]
	[sts d0 brightness]
	[rjmp poll]

prim-cmd
	[ldi d1 0][lds d0 cmd]
	[push d1][push d0]
	[rjmp eval]

prim-putc
	[pop d0][pop t0]
	[rcall putc]
	[rjmp eval]


fetch	[movw z ip][adiw ip 1]
readfb	[sbrc zh 7][rjmp ee-readfb]
	[lpm]
	[ret]
	
ee-readfb
	[sts z eearl]
	[sts zh eearh]
	[sbi eecr eere]
	[lds t0 eedr]
	[ret]

timer0_compa
	[mov t-d0 d0]
	[in t-sreg sreg]
	[ldi d0 1][add t-ticks d0]
	[ldi d0 0][adc t-ticksh d0]
	[out t-sreg sreg]
	[mov d0 t-d0]
	[reti]

putc	[push d2][push d3]
	[rcall boot-putc]
	[pop d3][pop d2]
	[ret]

ctab [dcw
	$FF00 $0000 $FF0D $0000 $FF1A $0000 $FF26 $0000 $FF33 $0000 $FF40 $0000 $FF4D $0000 $FF59 $0000 $FF66 $0000 $FF73 $0000
	$FF80 $0000 $FF8C $0000 $FF99 $0000 $FFA6 $0000 $FFB3 $0000 $FFBF $0000 $FFCC $0000 $FFD9 $0000 $FFE6 $0000 $FFF2 $0000
	$FFFF $0000 $E6FF $0000 $CCFF $0000 $B3FF $0000 $99FF $0000 $80FF $0000 $66FF $0000 $4DFF $0000 $33FF $0000 $1AFF $0000
	$00FF $0000 $00FF $000D $00FF $001A $00FF $0026 $00FF $0033 $00FF $0040 $00FF $004D $00FF $0059 $00FF $0066 $00FF $0073
	$00FF $0080 $00FF $008C $00FF $0099 $00FF $00A6 $00FF $00B3 $00FF $00BF $00FF $00CC $00FF $00D9 $00FF $00E6 $00FF $00F2
	$00FF $00FF $00F2 $00FF $00E6 $00FF $00D9 $00FF $00CC $00FF $00BF $00FF $00B3 $00FF $00A6 $00FF $0099 $00FF $008C $00FF
	$0080 $00FF $0073 $00FF $0066 $00FF $0059 $00FF $004D $00FF $0040 $00FF $0033 $00FF $0026 $00FF $001A $00FF $000D $00FF
	$0000 $00FF $0D00 $00FF $1A00 $00FF $2600 $00FF $3300 $00FF $4000 $00FF $4D00 $00FF $5900 $00FF $6600 $00FF $7300 $00FF
	$8000 $00FF $8C00 $00FF $9900 $00FF $A600 $00FF $B300 $00FF $BF00 $00FF $CC00 $00FF $D900 $00FF $E600 $00FF $F200 $00FF
	$FF00 $00FF $FF00 $00E6 $FF00 $00CC $FF00 $00B3 $FF00 $0099 $FF00 $0080 $FF00 $0066 $FF00 $004D $FF00 $0033 $FF00 $001A
	$FF00 $0000]  

end
