#lang scheme/base
(provide (all-defined-out))
(require
"../tools.ss"
"../scat.ss"
"../target.ss"
"../asm.ss"
"reflection.ss"
"console.ss"
"../port/piklab.ss" "../purrr/repl.ss" (lib "match.ss"))
(define default-portspec '("/dev/ttyUSB0" 9600))
(define (io-debug x)
(with-io-device default-portspec x))
(define-syntax-rule (io> . expr)
(io-debug (lambda () . expr)))
(define (in)
(read-byte-timeout (i-port) 3))
(define (out byte)
(write-byte byte (o-port)))
(define (tnop) (out 0))
(define (>t val) (out 1) (out (int8 val)) (wait-ack))
(define (t>) (out 2) (in))
(define (tstart/b addr) (out 3) (_out addr)) (define (tstart/w addr) (tstart/b (<<< addr 1)))
(define (texec/b addr) (tstart/b addr) (wait-ack)) (define (texec/w addr) (texec/b (<<< addr 1)))
(define (a! addr) (out 4) (_out addr) (wait-ack))
(define (f! addr) (out 5) (_out addr) (wait-ack))
(define (tsync) (out 6) (wait-ack)) (define (cold) (out 7))
(define (n@a+ n) (out 8) (out n))
(define (n@f+ n) (out 9) (out n))
(define (n!a+/async n) (out 10) (out n))
(define (n!f+/async n) (out 11) (out n))
(define (chkblk) (out 12)) (define (echorq) (out 13)) (define (ferase/async) (out 14)) (define (fprog/async) (out 15))
(define (client c) (out 16) (out c))
(define (hub) (out 17))
(define (wait-ack) (in))
(define (byte-split fn)
(lambda (x)
(fn (int8 x))
(fn (int8 (>>> x 8)))))
(define (byte-join fn)
(lambda ()
(let* ((lo (fn))
(hi (fn)))
(bior (<<< hi 8) lo))))
(define _out (byte-split out))
(define _>t (byte-split >t))
(define _in (byte-join in))
(define _t> (byte-join t>))
(define (t@ addr) (a! addr) (n@a+ 1) (in))
(define (twrite . vals)
(n!a+/async (length vals))
(for-each out vals)
(wait-ack))
(define _twrite (byte-split twrite))
(define (t! val addr) (a! addr) (twrite val))
(define (_t! val addr) (a! addr) (_twrite val))
(define (>tstack lst)
(for-each >t (reverse lst)))
(define (tstack> n)
(for/list ((i (in-range n))) (t>)))
(define (nin>list n) (for/list ((i (in-range n))) (in)))
(define (_nin>list n) (for/list ((i (in-range n))) (_in)))
(define (in>list) (nin>list (in)))
(define (in>string) (list->bytes (in>list)))
(define (fbytes n) (unless (zero? n) (n@f+ n)))
(define (abytes n) (unless (zero? n) (n@a+ n)))
(define (fwords n) (fbytes (<<< n 1)))
(define (awords n) (abytes (<<< n 1)))
(define (chunked max-size command reader)
(lambda (total-size)
(flatten
(map
(lambda (n) (command n) (reader n))
(chunk-size-list total-size
max-size)))))
(define abytes>list (chunked #x80 abytes nin>list))
(define fbytes>list (chunked #x80 fbytes nin>list))
(define awords>list (chunked #x40 awords _nin>list))
(define fwords>list (chunked #x40 fwords _nin>list))
(define (fbytes->list f n) (f! f) (fbytes>list n))
(define (abytes->list a n) (a! a) (abytes>list n))
(define (fwords->list f n) (f! f) (fwords>list n))
(define (awords->list a n) (a! a) (awords>list n))
(define (bf! n) (f! (* 64 n)))
(define (ba! n) (f! (* 64 n)))
(define (free-block? b)
(bf! b)
(chkblk)
(= #xff (in)))
(define (stack>list bottom stkptr)
(let* ((top (t@ stkptr))
(n (- top bottom)))
(when (< n 0)
(error 'target-stack-underflow "~s" n))
(a! (add1 bottom)) (reverse (abytes>list n))))
(define (program) (fprog/async) (wait-ack))
(define (erase) (ferase/async) (wait-ack))
(define (erase-block b)
(bf! b) (erase))
(define (erase-blocks b n)
(unless (zero? n)
(erase-block b)
(erase-blocks (+ b 1) (- n 1))))
(define (erase-from-block b)
(if (free-block? b)
(printf "\n")
(begin
(printf "~s " b)
(erase-block b)
(erase-from-block (+ b 1)))))
(define (erase-from/w addr)
(erase-from-block
(ceiling-block addr 32)))
(define (upload-bytes-line org bytes [bits 3])
(define n (<<< 1 bits))
(unless (= n (length bytes))
(error 'non-normalized-line "~s" bytes))
(tsync) (f! org)
(n!f+/async n)
(for ((b bytes)) (out (int8 b)))
(wait-ack)
(program))
(define (upload-bytes bin
[align-bits 3])
(for ((chunk (bin-flatten bin)))
(for (((org line) (in-binchunk/lines chunk align-bits -1)))
(display ".")
(upload-bytes-line org line align-bits)
)))
(define printf-stack stack-print)
(define (psu lst) (printf-stack lst " ~s"))
(define (psx lst) (printf-stack (map byte->string lst) " ~a"))
(define (_psx lst) (printf-stack (map word->string lst) " ~a"))
(define (pss lst) (printf-stack (map (sign-extender 8) lst) " ~s"))
(define (_pss lst) (printf-stack (map (sign-extender 16) lst) " ~s"))
(define (kb n)
(define (current-block)
(if
(begin
(chkblk)
(= #xff (in)))
". " "x "))
(define (print-line)
(printf
"~a\n"
(apply
string-append
(for/list ((i (in-range 8))) (current-block)))))
(bf! 0)
(let ((lines (* 2 n)))
(for ((i (in-range lines)))
(print-line))))
(define (slurp)
(for ((i (in-thunk in))
(p (in-hex-printer))) (p i)))
(define (tsee word [n #x20])
(define addr (if (number? word) word (<<< (tfind word) 1)))
(define dict (target-words))
(when addr (f! addr))
(print-target-word
(disassemble->word (fwords>list n) (>>> addr 1) 16
(lambda (addr)
(or
(reverse-lookup dict 'code addr)
addr)))))
(define (bd block)
(tsee (* 64 block) 32))
(define (sim-or-target name sim-code)
(let ((word (tfind/false name)))
(if word
(scat: ',word texec/w)
sim-code)))
(snarf as-push (scat)
((name code) (sim-or-target)))
(compositions
(scat) scat:
(sim/target sim-or-target run))
(snarf as-void (scat)
((a) (_out >t _>t >tstack
texec/w texec/b tstart/w tstart/b
awords abytes fwords fbytes
a! f! ba! bf!
n@a+ n@f+
n!a+/async n!f+/async
erase-block erase-from-block erase-from/w
kb bd tsee
client
piklab-prog))
((a b) (t! _t!
erase-blocks
))
((a) (psu psx pss _psx _pss))
(() (tnop wait-ack tsync cold chkblk echorq
ferase/async fprog/async program erase hub
)))
(snarf as-push (scat)
(() (_in t> _t> in>string in>list))
((a) (t@ tstack> nin>list _nin>list
fwords>list fbytes>list abytes>list awords>list
free-block?
))
((a b) (stack>list))
)
(compositions (scat) scat:
(>byte round #xff and)
(>hilo dup 8 >>> >byte swap >byte)
(hilo> swap 8 <<< or)
(sim "(sim)" d cr
swap tstack> apply >tstack)
(tlit >t)
(_tlit _>t)
(@f+ 1 n@f+ in)
(identify echorq in>string bytes->string/utf-8)
(ping identify d cr)
(ps 8 sign-extend p)
(_ps 16 sign-extend p)
(px pbyte)
(_px pword)
(_p p)
(pbyte byte->string d) (h pbyte)
(pword word->string d)
(_cold cold)
(_ping ping)
(pfline 4 fwords>list (pword) for-each cr)
(fdump 8 (pfline) for)
(target-stack 128 4073)
(ts>list target-stack stack>list)
(_ts>list ts>list 8 0 join-nibble-list)
(ts ts>list psu)
(tsx ts>list psx)
(tss ts>list pss)
(_ts _ts>list psu)
(_tsx _ts>list _psx)
(_tss _ts>list _pss)
(access-bank dup 7 bit? (#xF00 xor) if)
(codeblock 32 fwords>list)
(paline 8 n@a+ 8 (in pbyte) for cr)
(adump 8 (paline) for)
(abd ba! adump)
(fbd bf! fdump)
(spam 0 out spam)
(fresh? chkblk in #xff =)
(ceil-word->block 1 - -32 and 32 +)
(ceil-byte->block 1 - -64 and 64 +)
(print-dict pp) (print-words (car p) for-each cr)
(print-bin 8 list->table
((dup number?
(word->string d space)
(p) ifte)
for-each cr)
for-each)
)
(snarf as-push (scat)
(() (in))
((a b) (sign-extend bit?))
((number) (word->string byte->string))
((lst a b) (binchunk-split join-nibble-list))
)
(snarf as-void (scat)
(() (slurp))
((byte) (out)))