|
( This file is part of muFORTH: http://pages.nimblemachines.com/muforth Copyright 2002-2008 David Frech. All rights reserved, and all wrongs reversed. (See the file COPYRIGHT for details.) ( Simple terminal and serial expect/send code.) ( 2007-jan-15. Moved v25 and ARM things elsewhere.) ( 2002-mar-27. Converted to muforth.) ( Created 5-aug-1999.) cr " Terminal " file[# decimal ( Open serial device.) variable fd-target ( used /dev/cuad0 on FreeBSD) : tty-target z" /dev/ttyS0" r/w open-file fd-target ! ; : bps ( speed) fd-target @ ram get-termios drop ( returns size of struct) ( speed) ram set-termios-speed fd-target @ ram set-termios ; ( Keymaps) -: ( self) emit 0 ; 256 defarray term-keys ( nop) ' 0 256 defarray term-esc-keys -: drop ( ESC) key term-esc-keys @execute ; #ESC term-keys ! : esc: -: \f char term-esc-keys ! ; comment %use-typing% 256 constant #serialbuf #serialbuf buffer serialbuf ( serial input buffer) %use-typing% comment %coroutines-broken% ( 2003-mar-13. It's coroutine time!) : coroutine ( dstack-safety dstack-size - s0) cells allot ( size) cells ( safety) ram swap - constant ; coroutine serial-s0 %coroutines-broken% variable fdmax : new-fd-set ram fd! buffer ; new-fd-set fds : te-select ( fd0 .. fdn n) fds fd! drop fdmax off for fds over fd-set fdmax @ max fdmax ! next fdmax @ 1+ fds 0 0 0 select drop ; ( Serial input to screen, keyboard input to serial.) : serial->screen fds fd-target @ fd-in-set? if fd-target @ reads tty writes typing type then ; : keyboard->serial ( - done?) fds tty fd-in-set? if tty reads fd-target @ writes key dup term-keys @execute ^ then 0 ; : te-stream begin tty fd-target @ 2 te-select serial->screen keyboard->serial until tty writes ; : <drain begin fd-target @ 1 te-select serial->screen until fd-target @ writes ; : te ( terminal) tty-target fd-target @ raw ( disallows signals) 115200 bps ( default to hi speed) radix @ push tty raw ['] te-stream catch tty cooked fd-target @ close-file pop radix ! throw ; ( Special keys.) ( Echo ESC [ back to serial port, followed by the rest of the chars in the keyboard buffer. This makes AEB-1 autobauding - which works by sending `ESC [5n' - status query - and the Linux console answers with `ESC [0n' - terminal Ok. By echoing the ESC and [ that were eaten by our ESC-dispatch mechanism, we cause the AEB-1 autobaud feature to magically work. This only sort of "works". While the Linux console obliges - as do rxvt and xterm - the FreeBSD syscons driver does _not_. [I have no idea what the NetBSD wscons driver will do.] So rather than be at the mercy of an environment that we cannot control, we handle this ourselves, right here.) : CSI ( handle ESC [ ) #ESC emit char [ emit key dup char 5 = if key dup char n = if ( got ESC [5n, so answer accordingly) nip char 0 then swap emit then emit ; esc: [ ( vt10x) CSI 0 ; -: drop #BS emit 0 ; #DEL term-keys ! ( DEL sends BS) esc: q ( quit) -1 ; 00 [if] ( Test code.) : kb raw begin key dup <ESC> xor while u. repeat cooked ; : wr ( a #) tty-target -rot write drop ; : kb-test if tty keyboard-in 1 read tty keyboard-in 1 write 2drop then ; : kb fds fd! drop fds tty fd-set raw begin te-select drop kb-test again [ [then] #]file |