/usr/bin/hexterm is in chiark-scripts 5.0.2.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311  | #!/usr/bin/tclsh8.4
set comment {
#
Use of the screen:
0         1         2         3         4         5         6         7
xxxE hh hh hh hh  hh hh hh hh  hh hh hh hh  hh hh hh hh_| abcd e_.. .... ...._|
}
# Display:
#	| is a vertical delimiter
#       E is either | to mean echo is on or ' to mean it is off
#	hh are hex digits of output:
#		00-ff	actual hex data (bold for stuff we entered)
#		0-f	under cursor: one digit entered, need the next
#	abcde_.... are ASCII output:
#		.	things we can't print including SPC and _
#	in both, we may see
#			space we haven't yet filled
#		_	cursor when in other tab
#       xxx     number of bytes read/written so far
# Keystrokes:
#	TAB	switch between hex and literal mode
#	^C, ^D	quit
#	^Z	suspend
# Keystrokes in hex mode only:
#	RET	move to a new line; if already at start of line,
#                set count to 0
#	DEL	clear any entered hex digit
#	SPC	send 00
#	'	toggle echo
# nyi:
#	G-Z	record last bytes we transmitted and store in memory
#		 if we were halfway through a hex byte, first digit
#		 is length of string to record
#	g-z	play back memory
# Copyright 2005 Ian Jackson <ian@chiark.greenend.org.uk>
#
# This script and its documentation (if any) are free software; you
# can redistribute it and/or modify them under the terms of the GNU
# General Public License as published by the Free Software Foundation;
# either version 3, or (at your option) any later version.
# 
# chiark-named-conf and its manpage are distributed in the hope that
# it will be useful, but WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE.  See the GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License along
# with this program; if not, consult the Free Software Foundation's
# website at www.fsf.org, or the GNU Project website at www.gnu.org.
if {[llength $argv] != 1} { error "need serial port arg" }
set port [lindex $argv 0]
set count 0
set lit 0 ;# 1 means literal (ASCII) entry mode
set echo 1
proc p {s} {
    puts -nonewline $s
}
proc tput {args} {
    global tput
    if {[catch { set s $tput($args) }]} {
	set s [eval exec tput $args]
	set tput($args) $s
    }
    p $s
}
proc csr_pos {lit bytenum} {
    set x [expr {
	(!$lit ? (3*$bytenum) : 53+$bytenum)
	+ ($bytenum>>2) - (2-$lit)*($bytenum==16)
	+ 5
    }]
    tput hpa $x
}
proc csr_this {} { global lit x; csr_pos $lit $x }
proc csr_other {} { global lit x; csr_pos [expr {!$lit}] $x }
proc csrs_erase {} { csr_this; p " "; csr_other; p " " }
proc csr_this_show {} {
    global h1
    csr_this; if {[info exists h1]} { p $h1; p "\b" }
}
proc csrs_show {} {
    csr_other; p _
    csr_this_show
}
proc echop {} {
    global echo
    return [expr {$echo ? "|" : "'"}]
}
proc newline {} {
    global x echo count
    if {[info exists x]} { csrs_erase; p "\r\n" }
    set x 0
    p [format "%3x%s%*s|%*s|" $count [echop] 52 "" 21 ""]
    csrs_show
}
proc p_ch_spaces {} {
    global x lit
    if {$x==15} return
    if {$lit} { p " " }
    if {($x & 3) != 3} return
    p " "
}
proc p_rmso {smso} {
    if {[string length $smso]} { tput sgr0 }
}
proc ch {d smso} {
    global lit x count
    if {$x == 16} newline
    if {[string length $smso]} { tput $smso }
    set h [format %02x [expr {$d & 0xff}]]
    set c [format %c [expr {($d > 33 && $d < 127 && $d != 95) ? $d : 46}]]
    if {$lit} {
	p $c; csr_other; p $h
	p_ch_spaces
	p_rmso $smso
	p _
    } else {
	p $h; csr_other; p $c
	p_ch_spaces
	p_rmso $smso
	p _
    }
    incr x
    set count [expr {($count+1) & 0xfff}]
    csr_this_show
}
proc onreadp {} {
    global p
    while 1 {
	set c [read $p 1]
	binary scan $c c* d
	if {![llength $d]} {
	    if {[eof $p]} { error "eof on device" }
	    return
	}
	ch $d {}
    }
}
proc transmit {d} {
    global p echo
    puts -nonewline $p [format %c $d]
    if {$echo} { ch $d bold }
}
proc k_echo {} {
    global echo
    set echo [expr {!$echo}]
    tput hpa 3
    p [echop]
    csr_this
}
proc k_newline {} {
    global count x
    if {$x} {
	newline
    } else {
	set count 0
	p "\r"
	p [format %3x $count]
	csr_this
    }
}
proc k_switch {} {
    global lit h1
    csrs_erase
    catch { unset h1 }
    set lit [expr {!$lit}]
    csrs_show
}
proc k_stop {} {
    restore
    exit 0
}
proc k_suspend {} {
    restore
    exec kill -TSTP [info pid]
    setup
}
proc k_noparthex {} {
    global h1
    csrs_erase
    catch { unset h1 }
    csrs_show
}
proc k_hexdigit {c} {
    global h1 echo
    if {![info exists h1]} { set h1 $c; p $c; p "\b"; return }
    set d [expr 0x${h1}${c}]
    unset h1
    transmit $d
    if {!$echo} { p " \b" }
}
proc onreadk {} {
    global lit
    while 1 {
	set c [read stdin 1]
	binary scan $c c* d
	if {![llength $d]} {
	    if {[eof stdin]} { error "eof on stdin" }
	    return
	}
	switch -exact $d {
	    9 { k_switch; continue }
	    3 - 4 { k_stop; continue }
	    26 { k_suspend; continue }
	}
	if {$lit} { transmit $d; continue }
	switch -exact $d {
	    13 { k_newline; continue }
	    32 { transmit 0; continue }
	    39 { k_echo; continue }
	    127 { k_noparthex; continue }
	}
	if {$d >= 48 && $d <= 57} { k_hexdigit $c; continue }
	set kl [expr {$d | 32}]
	if {$d >= 97 && $d <= 102} { k_hexdigit $c; continue }
	p "\a"
    }
}
proc try {script} {
    if {[catch { uplevel 1 $script } emsg]} {
	catch { puts stderr "(warning: $emsg)" }
    }
}
proc tryv {variable script} {
    upvar #0 $variable var
    if {![info exists var]} return
    uplevel 1 "
        global $variable
        $script
    "
    unset var
}
proc restore {} {
    tryv x { puts "\r\n" }
    try { fconfigure stdin -blocking true }
    try { fconfigure stdout -blocking true }
    tryv term_stty { exec stty $term_stty }
    tryv p { close $p }
}
proc setup {} {
    global term_stty port p
    set term_stty [exec stty -g]
    set p [open $port {RDWR NONBLOCK} 0]
    
    exec stty          min 1 time 0 -istrip -ocrnl -onlcr -onocr -opost \
	               -ctlecho -echo -echoe -echok -echonl -iexten -isig \
		       -icanon -icrnl
    exec stty -F $port min 1 time 0 -istrip -ocrnl -onlcr -onocr -opost \
	               -ctlecho -echo -echoe -echok -echonl -iexten -isig \
		       -icanon -icrnl \
	    9600 clocal cread -crtscts -hup -parenb cs8 -cstopb \
	    -ixoff bs0 cr0 ff0 nl0 -ofill -olcuc
    fconfigure $p -blocking false -buffering none -encoding binary \
	    -translation binary
    fconfigure stdin -blocking false -buffering none -translation binary
    fconfigure stdout -blocking false -buffering none -translation binary
    newline
    fileevent stdin readable onreadk
    fileevent $p readable onreadp
}
proc bgerror {m} {
    try {
	restore
	global errorInfo errorCode
	puts stderr "$m\n$errorCode\n$errorInfo"
    }
    exit 127
}
if {[catch setup emsg]} {
    restore
    error $emsg $errorInfo $errorCode
}
vwait quit
 |