6 xxx| hh hh hh hh hh hh hh hh hh hh hh hh hh hh hh hh_| abcd e_.. .... ...._|
9 # | is a vertical delimiter
10 # hh are hex digits of output:
11 # 00-ff actual hex data (bold for stuff we entered)
12 # 0-f under cursor: one digit entered, need the next
13 # abcde_.... are ASCII output:
14 # . things we can't print including SPC and _
16 # space we haven't yet filled
17 # _ cursor when in other tab
18 # xxx number of bytes read/written so far
20 # TAB switch between hex and literal mode
23 # Keystrokes in hex mode only:
24 # RET move to a new line; if already at start of line,
26 # DEL clear any entered hex digit
29 # G-Z record last bytes we transmitted and store in memory
30 # if we were halfway through a hex byte, first digit
31 # is length of string to record
32 # g-z play back memory
34 if {[llength $argv] != 1} { error "need serial port arg" }
36 set port [lindex $argv 0]
39 set lit 0 ;# 1 means literal (ASCII) entry mode
47 if {[catch { set s $tput($args) }]} {
48 set s [eval exec tput $args]
54 proc csr_pos {lit bytenum} {
56 (!$lit ? (3*$bytenum) : 53+$bytenum)
57 + ($bytenum>>2) - (2-$lit)*($bytenum==16)
63 proc csr_this {} { global lit x; csr_pos $lit $x }
64 proc csr_other {} { global lit x; csr_pos [expr {!$lit}] $x }
65 proc csrs_erase {} { csr_this; p " "; csr_other; p " " }
66 proc csr_this_show {} {
68 csr_this; if {[info exists h1]} { p $h1; p "\b" }
77 if {[info exists x]} { csrs_erase; p "\r\n" }
79 p [format "%3x|%*s|%*s|" $count 52 "" 21 ""]
87 if {($x & 3) != 3} return
92 if {[string length $smso]} { tput sgr0 }
98 if {[string length $smso]} { tput $smso }
99 set h [format %02x [expr {$d & 0xff}]]
100 set c [format %c [expr {($d > 33 && $d < 127 && $d != 95) ? $d : 46}]]
102 p $c; csr_other; p $h
107 p $h; csr_other; p $c
113 set count [expr {($count+1) & 0xfff}]
123 if {[eof $p]} { error "eof on device" }
132 puts -nonewline $p [format %c $d]
143 p [format %3x $count]
152 set lit [expr {!$lit}]
163 exec kill -TSTP [info pid]
167 proc k_noparthex {} {
174 proc k_hexdigit {c} {
176 if {![info exists h1]} { set h1 $c; p $c; p "\b"; return }
177 set d [expr 0x${h1}${c}]
188 if {[eof stdin]} { error "eof on stdin" }
192 9 { k_switch; continue }
193 3 - 4 { k_stop; continue }
194 26 { k_suspend; continue }
196 if {$lit} { transmit $d; continue }
198 13 { k_newline; continue }
199 127 { k_noparthex; continue }
200 32 { transmit 0; continue }
202 if {$d >= 48 && $d <= 57} { k_hexdigit $c; continue }
203 set kl [expr {$d | 32}]
204 if {$d >= 97 && $d <= 102} { k_hexdigit $c; continue }
210 if {[catch { uplevel 1 $script } emsg]} {
211 catch { puts stderr "(warning: $emsg)" }
215 proc tryv {variable script} {
216 upvar #0 $variable var
217 if {![info exists var]} return
226 tryv x { puts "\r\n" }
227 try { fconfigure stdin -blocking true }
228 try { fconfigure stdout -blocking true }
229 tryv term_stty { exec stty $term_stty }
234 global term_stty port p
236 set term_stty [exec stty -g]
238 set p [open $port {RDWR NONBLOCK} 0]
240 exec stty min 1 time 0 -istrip -ocrnl -onlcr -onocr -opost \
241 -ctlecho -echo -echoe -echok -echonl -iexten -isig \
243 exec stty -F $port min 1 time 0 -istrip -ocrnl -onlcr -onocr -opost \
244 -ctlecho -echo -echoe -echok -echonl -iexten -isig \
246 9600 clocal cread -crtscts -hup -parenb cs8 -cstopb \
247 -ixoff bs0 cr0 ff0 nl0 -ofill -olcuc
249 fconfigure $p -blocking false -buffering none -encoding binary \
252 fconfigure stdin -blocking false -buffering none -translation binary
253 fconfigure stdout -blocking false -buffering none -translation binary
257 fileevent stdin readable onreadk
258 fileevent $p readable onreadp
264 global errorInfo errorCode
265 puts stderr "$m\n$errorCode\n$errorInfo"
270 if {[catch setup emsg]} {
272 error $emsg $errorInfo $errorCode