TUESDAY MAY 27,1975 FM+2D.18H.3M.18S. NEWIO 1061 - GLS - Note that ONEWIO^K or OQ^K gets an old version of NEWIO (Q). Brief synopsis: [1] MSGFILES controls output of "messages" from LISP. [2] File arrays as arguments to SYSCALL supply channel number. [3] ERRPRINT may take a second arg (output files). [4] (CLOSE foo) does (SSTATUS TTYCONS foo NIL) if foo is a tty. [5] OPEN tends to reset file array attributes. [6] A sample program to do rubout processing. [7] A sample program to use 12-bit chars on Knight keyboards. [8] A sample program to use the echo area. [9] A sample program to hack the line printer. [10] A sample program to create "dribble files" using ECHOFILES. ---------------------------------------------------------------- [1] The variable MSGFILES is like the variable OUTFILES, except that "messages" like GC messages, error messages, ";BKPT barf", etc. are output to MSGFILES files and not to OUTFILES files. (Recall that OUTFILES is the list of default user output files, controlled by ^R. There is no switch equivalent to ^R for MSGFILES.) Initially the value of MSGFILES is (T), i.e. messages go only to the tty. [2] If a file array is given as an input argument to SYSCALL in newio, the system actually gives the .CALL the channel number of the file array. If T is given, the channel number of the input tty file T is supplied. Thus: (SYSCALL 0 'SCML T 7) sets the number of command lines (size of echo area) to 7 for the standard input tty. By the way, if you ever use SYSCALL for something you think LISP might want to provide as a separate function (for ease of use, compatibility with other systems, etc.) please send mail to GLS describing the usage. [3] The ERRPRINT function now takes an optional second argument like PRINT to specify the output files to print the message on. Thus, for example, (ERRPRINT NIL MSGFILES) prints the most recent error message onto the message files. [4] Closing a tty file will undo any (SSTATUS TTYCONS) pair that that file may be engaged in. Since OPEN uses CLOSE if given an actual file as first argument, note that it may be necessary to re-TTYCONS two tty files after re-opening one or both of them. [5] In general, re-opening a file (especially a tty) resets the file array for that tty. LISP makes an effort to save some important attributes about the input and output T files (standard tty) when starting up and re-opening the T tty files, but this is not a general attribute of the OPEN function. Thus, after re-opening a file array, the attributes of that file array (such as (SSTATUS TTYCONS), (SSTATUS TTY), (SSTATUS TTYINT), (EOFFN) or (ENDPAGEFN), etc.) should be set up all over again. [6] Sometimes a user may want to do his own rubout processing without having to hack the ultimately hairy (SSTATUS TTYSCAN) feature. Here is a function showing the correct way to do rubout processing for simple applications. ;;; This function takes two arguments. ;;; The first is the character (a fixnum) which terminates input. ;;; The second is the file to read from (T for tty input). ;;; It works to use this function on a non-tty. ;;; The result returned is a list of fixnums representing the ;;; characters read and not rubbed out. The termination character ;;; is not included in this list, but thrown away. ;;; Over-rubout does not do anything at all. ;;; Example: (SNARF-CHARS-UNTIL 3 t) ;;; reads characters from T (the tty) until a ^C (ascii code 3) ;;; is typed. If the user types "FOOBER<rubout><rubout>AR^C", ;;; then the result will be (106 117 117 102 101 122). ;;; ;;; Note the use of the newio function RUBOUT to rub characters out. ;;; If RUBOUT returns NIL, then it could not rub the character out ;;; (e.g. it was tab or cr); it is necessary then to re-print the ;;; list of buffered characters. ;;; TTYP is non-NIL iff the input file is a tty. ;;; ECHO-FILE is the associated output file of the input tty, ;;; or NIL if the input file has none or isn't a tty. ;;; START-POS is the original cursor position in ECHO-FILE, or NIL. ;;; BUFFER is a list of characters read in reverse order. (DEFUN SNARF-CHARS-UNTIL (ENDCHAR INPUT-FILE) ((LAMBDA (TTYP) ((LAMBDA (ECHO-FILE) (DO ((START-POS (AND ECHO-FILE (CURSORPOS ECHO-FILE))) (BUFFER) (CHAR (TYI INPUT-FILE) (TYI INPUT-FILE))) ((= CHAR ENDCHAR) (NREVERSE BUFFER)) (COND ((= CHAR 177) (AND BUFFER ECHO-FILE (OR (RUBOUT (CAR BUFFER) ECHO-FILE) (PROGN (CURSORPOS (CAR START-POS) (CDR START-POS) ECHO-FILE) (CURSORPOS 'E ECHO-FILE) (MAPC (FUNCTION (LAMBDA (CH) (TYO CH ECHO-FILE))) (REVERSE (CDR BUFFER)))))) (AND BUFFER (SETQ BUFFER (CDR BUFFER)))) (T (SETQ BUFFER (CONS CHAR BUFFER)))))) (AND TTYP (STATUS TTYCONS INPUT-FILE)))) (MEMQ 'TTY (CAR (STATUS FILEMODE INPUT-FILE))))) [7] This function shows the correct way to re-open the tty in 12-bit mode on a Knight keyboard. Note that the LISP system normally folds 12-bit characters down to 7 bits always, except for the TYI function. Thus the READTABLE still only has 200 entries, etc. ;;; Open the tty in 12-bit mode. After (12-BIT-OPEN) is done, ;;; (TYI) from the tty will return 12-bit characters. The characters ;;; are as supplied by ITS: ;;; bit value ITS name correspondence ;;; 2.3 4000 %TXTOP TOP ;;; 2.2 2000 %TXSFL SHIFT LOCK ;;; 2.1 1000 %TXSFT SHIFT ;;; 1.9 400 %TXMTA META ;;; 1.8 200 %TXCTL CONTROL ;;; 1.7-1.1 177 %TXASC ascii code ;;; After re-opening the input tty in 12-bit mode, it is necessary ;;; to restore the attributes of the file array. ;;; In this mode, the LISP system control characters are set up ;;; to ignore control characters which do not actually have the ;;; CONTROL bit set. Thus typing TOP-X to get "beta" will not ;;; invoke the system ^C interrupt. User interrupt character ;;; functions must decide for themselves whether to do such ;;; filtering (they receive the full 12-bit character as an ;;; argument, and so may do this if desired). (DEFUN 12-BIT-OPEN NIL ((LAMBDA (SCAN-FUNCTION) (OPEN T '(TTY IN SINGLE FIXNUM)) ;OPEN IN 12-BIT MODE (SSTATUS TTYCONS T T) ;TIE TO OUTPUT TTY (SSTATUS TTYSCAN SCAN-FUNCTION) ;SET UP RUBOUT HANDLER (MAPC (FUNCTION (LAMBDA (CH INT) ;SET UP STANDARD (SSTATUS TTYINT ; CONTROL CHARACTERS, CH ; REQUIRING "CONTROL" (+ INT 200)))) ; KEY FOR ANY EFFECT '(3 4 7 22 23 24 26 27 30 32) '(3 4 7 22 30 24 26 27 30 32))) (STATUS TTYSCAN))) ;OLD RUBOUT HANDLER [8] Here is a function which opens up and manipulates tty files such that input is typed in the echo area and output appears above. Rubout processing happens correctly in the echo area. Note that it uses TTY-ENDPAGEFN, the **MORE** processor defined in the previous LISP RECENT. (DEFUN SPLITSCREEN (ECHOAREASIZE) ((LAMBDA (ECHOTTY VERTICAL) (SSTATUS TTYCONS T ECHOTTY) ;cons echo area tty to input tty (PAGEL T (- VERTICAL ECHOAREASIZE)) ;set pagel for main area tty (ENDPAGEFN T 'TTY-ENDPAGEFN) ;set endpagefn (SYSCALL 0 'SCML T ECHOAREASIZE) ;set size of echo area (CURSORPOS 'C T) ;clear screen (why not?) 'DONE) (OPEN '((TTY)) '(TTY OUT ECHO)) ;file array for echo area tty output (CAR (STATUS TTYSIZE T)))) Here is a version which causes ALL input and output to happen in the echo area, leaving the main program area free for graphics or whatever else. (DEFUN SMALLSCREEN (ECHOAREASIZE) (OPEN T '(TTY OUT ECHO)) (SSTATUS TTYCONS T T) (SYSCALL 0 'SCML T ECHOAREASIZE) 'DONE) [9] Here are some routines which simulate the old ^B-^E feature of oldio. Since ^B is a break in newio, ^A and ^E are used. The functions WALBEG and WALEND are as in DDT, and are used to open and close the wallpaper file. If ^A discovers that WALBEG has not been called, the TPL device is used. ;;; WALLPAPER ROUTINES ;;; VALUE OF WALLPAPERFILE, IF NON-NIL, IS FILE ARRAY FOR ;;; WALLPAPER. ;;; ^A-HANDLER IS INVOKED BY TYPING ^A. TURNS ON OUTPUT ;;; TO WALLPAPER FILE. ;;; ^E-HANDLER IS INVOKED BY ^E. TURNS OFF WALLPAPER OUTPUT. ;;; WALBEG INITIALIZES SETUP TO SPECIFIED FILE. ;;; WALEND TERMINATES THE CURRENT WALLPAPER FILE, ;;; AND NAMES IT IF DESIRED (DEFAULT IS "WPAPER >"). (DECLARE (SPECIAL WALLPAPERFILE OLD^R)) (SETQ WALLPAPERFILE NIL) (DEFUN ^A-HANDLER (F CH) (OR WALLPAPERFILE (WALBEG TPL)) (OR ^A (SETQ OLD^R ^R)) (SETQ ^A T) (SETQ ^R T) (OR (MEMQ WALLPAPERFILE OUTFILES) (SETQ OUTFILES (CONS WALLPAPERFILE OUTFILES)))) (DEFUN ^E-HANDLER (F CH) (SETQ ^R OLD^R) (SETQ ^A NIL) (SETQ OUTFILES (DELQ WALLPAPERFILE OUTFILES))) (DEFUN WALBEG FEXPR (DEVDIR) (WALEND) (SETQ WALLPAPERFILE (OPEN (LIST (OR DEVDIR (CAR (DEFAULTF NIL))) '_WALL_ 'PAPER) 'OUT)) T) (DEFUN WALEND FEXPR (NAME) (COND (WALLPAPERFILE (^E-HANDLER NIL NIL) (AND NAME (RENAME WALLPAPERFILE NAME)) (CLOSE WALLPAPERFILE) (SETQ WALLPAPERFILE NIL)))) (SSTATUS TTYINT 1 '^A-HANDLER) (SSTATUS TTYINT 5 '^E-HANDLER) [10] Here are some functions to create "dribble files", i.e. files contains both input and output. ;;; (DRIBBLE) opens a dribble output file. ;;; DRIBBLE, if non-nil, is the dribble output file array. ;;; (WIPE FOO BAR) wipes up the current dribble, closing ;;; the file and naming it FOO BAR. (DECLARE (SPECIAL DRIBBLE)) (DEFUN DRIBBLE NIL (WIPE /.DRIB/. OUTPUT) (SETQ DRIBBLE (OPEN '|.DRIB. OUTPUT| 'OUT))) (SETQ OUTFILES (CONS DRIBBLE OUTFILES)) (SETQ ECHOFILES (CONS DRIBBLE ECHOFILES)) (SETQ MSGFILES (CONS DRIBBLE MSGFILES)) (SETQ ^R T)) (DEFUN WIPE FEXPR (NAME) (COND (DRIBBLE (OR (SETQ OUTFILES (DELQ DRIBBLE OUTFILES)) (SETQ ^R NIL)) (SETQ ECHOFILES (DELQ DRIBBLE ECHOFILES)) (SETQ MSGFILES (DELQ DRIBBLE MSGFILES)) (CLOSE (RENAME (PROG2 NIL DRIBBLE (SETQ DRIBBLE NIL)) NAME)))))