Standard Input - Output and the CLI
The Z88 operating system has, at any one time, a standard input source and a standard output destination. A number of calls use these standard I/O streams:
OS_In     Â
read a character from standard inputOS_Tin    Â
timed read a character from standard outputOS_Out    Â
write a character to standard outputOS_Sout  Â
write a string to standard outputOS_Bout  Â
write a string at extended address to standard outputGN_Sip    Â
fetch an input line using standard I/OGN_Sdo    Â
write date to standard output
Initially standard input and output are bound to the keyboard and screen respectively, but may be redefined to any file or device. The user may do this via the Command Line Interpreter (CLI). CLI commands are prefixed by a full stop and must be the first thing on the line.
.< INFILEÂ Â Â Â Â Â Â Â Â Â Â Â Â Â take input from file/device "INFILE"
.> OUTFILEÂ Â Â Â Â Â Â Â Â Â Â Â Â send output to file/device "OUTFILE"
which binds the standard input to "infile" and the standard output to "outfile". Redirection can also be done as T-fashion, where the ordinary streams remain in place, but copies of their contents are sent to a file or a device.
.T< INFILEÂ Â Â Â Â Â Â Â Â Â Â Â Â send copy of input to file/device "INFILE"
.T> INFILEÂ Â Â Â Â Â Â Â Â Â Â Â Â send copy of output to file/device "OUTFILE"
The printer output can be redirected in both ways:
.= PRTFILEÂ Â Â Â Â Â Â Â Â Â Â Â Â redirect pre-filter printer output to file/device
.T= PRTFILEÂ Â Â Â Â Â Â Â Â Â Â Â as .=, but also send the output to the printer filter.
Certain keystroke operations (such as <SQUARE> and <DIAMOND> sequences) have a special representation which is used when input is redirected. These sequences are generated when input is T-redirected and can be used in ordinary redirection to simulate the effect of the keyboard. Note that there are some keyboard features which have no representation, such as: the CAPS LOCK key, <SHIFT> or <DIAMOND> with <ESC>, the effect of holding down <SHIFT> and <DIAMOND> to stop output scrolling.
Sequence   Significance
#Â Â Â Â Â Â Â Â Â Â holding down <SQUARE> and pressing another key
|Â Â Â Â Â Â Â Â Â Â holding down <DIAMOND> and pressing another key
~AÂ Â Â Â Â Â Â Â Â pressing <SQUARE> and releasing it before another keypress
~CÂ Â Â Â Â Â Â Â Â pressing <DIAMOND> and releasing it before another keypress
|[Â Â Â Â Â Â Â Â Â <ESC> key
~EÂ Â Â Â Â Â Â Â Â <ENTER> key
~SÂ Â Â Â Â Â Â Â Â <SHIFT> key (only generated if <SHIFT> had an effect)
~IÂ Â Â Â Â Â Â Â Â <INDEX> key
~MÂ Â Â Â Â Â Â Â Â <MENU> key
~HÂ Â Â Â Â Â Â Â Â <HELP> key
~XÂ Â Â Â Â Â Â Â Â <DEL> key
~UÂ Â Â Â Â Â Â Â Â <UP> arrow key
~DÂ Â Â Â Â Â Â Â Â <DOWN> arrow key
~LÂ Â Â Â Â Â Â Â Â <LEFT> arrow key
~RÂ Â Â Â Â Â Â Â Â <RIGHT> arrow key
##Â Â Â Â Â Â Â Â Â a single # (hash) character
||Â Â Â Â Â Â Â Â Â a single | character
~~Â Â Â Â Â Â Â Â Â a single ~ tilde (pronounced 'tilda' or 'twiddle')
The CLI also has the following commands:
.SÂ Â Â Â Â Â Â Â Â suspend the current CLI but maintain all rebindings
.D n       delay for n centiseconds (if <ESC> is pressed during a delay then
           subsequent delays will fail for the rest of the current CLI)
.JÂ Â Â Â Â Â Â Â Â Jammer. Ignore all special sequences for the rest of the CLI (eg.
           after this command #B will generate '#B' and try and enter a BBC
           BASIC application)
.* file    Invoke a new CLI file
.;Â Â Â Â Â Â Â Â Â CLI comment (rest of line until CR is ignore by CLI)
NOTE: All CLI commands prefixed by a single dot must be at the start of a line. Any number of dots at the start of the line will be ignored. One way to produce a single dot is to use '~.' at the start of a line to generate a full stop. Subsequent dots (ie. ones which do not appear as the first character of the line) are treated like ordinary alpha characters.
CLI files can invoke other CLI files. A CLI file is terminated when the end of a file is reached or a suspension command is issued. CLI's can be forcibly removed one at a time by pressing <SHIFT> and <ESC>, or all current CLI's can be removed by using <DIAMOND> and <ESC>. Note that <DIAMOND> must be actually held down while <ESC> is pressed, ie. the usual latching operation does not apply. The CLI can be accessed by BBC BASIC by using the *CLI command or the OSCLI command. For example, to create a 10 second delay:
*CLI .D 100Â
OSCLI ("*CLI .D 100"): REM these two lines are equivalent
Most CLI use will be in the form of executable files, consisting of lines of CLI commands and text. These can be generated in PipeDream and saved as text files. Or generated by hand and then executed. CLI files can be executed from the FILER (using <>EX command) or from BBC BASIC using:
OSCLI ("*CLI .*"+fname$)
where fname$ contains the filename. Typical CLI files consist of short sequences like:
.T> copyout .S
The first line sends a copy of all output to the file 'copyout', and the second line maintains this new binding on exit from the CLI file. The binding (T-output to 'copyout') will now stay in place until the CLI is terminated by <SHIFT><ESC> to remove the current CLI (or <><ESC>, which removes all CLI's running). This situation will generally be undesirable, because it requires user intervention, since the program cannot simulate the effect of <SHIFT> <ESC>. Ideally the CLI should be avoided. Redirection can be easily achieved in applications by using file I/O, however, if necessary the CLI can be accessed fairly directly from an application. The operating system call DC_Icl invokes a new CLI, and is effectively the equivalent of BASIC's *CLI. The call DC_Rbd is used to directly rebind streams in the current CLI layer and can also terminate the CLI.
Example
The program below starts a CLI, using DC_Rbd, rebinds the T-output stream, and finally closes the stream and terminates the CLI. Refer to "System Calls Reference" for details of the calls used:
Â
include "director.def"            ; director and CLI call definitions include "stdio.def"               ; standard I/O call defs. & parameters include "fileio.def"              ; standard file I/O call defs. & parameters include "errors.def"              ; error code calls and definitions ; entry point is .main ; on entry, (name) contains the address of a buffer which hold a filename ; to be used with the CLI, and (scratch) holds the address of a scratch ; buffer which need be no more than a few bytes in length .main      ld  hl, cli_string    ; string to pass the CLI            ld  c, 2              ; length            ld  b, 0              ; must be zero            oz DC_Icl         ; invoke a new CLI            ld  bc, 0             ; key read to allow CLI to be processed            oz OS_Tin            ld  b, 0              ; HL is a local address            ld  hl, (name)        ; filename            ld  de, (scratch)     ; address of scratch buffer            ld  c, 1              ; explicit filename length            ld  a, OP_OUT         ; open a file for output            oz GN_Opf         ; open...            jr  nc, rebind            oz GN_Err         ; display error in box            ret                    ; note that on exit the CLI will                                    ; still be active ; code to rebind standard output .rebind    ld  a, 4              ; T-output code            oz DC_Rbd         ; rebind to stream IX            jr  nc, continue            oz GN_Cl          ; something has gone badly wrong            ret                    ; attempt to close the file and exit ; write to standard output, and hence also to the file .continue  ld  hl, message            oz GN_Sop         ; output message to std. output and file            ld  ix, 0             ; close off CLI and file            ld  a, 4              ; T-output code            oz DC_Rbd         ; close file and quit CLI            ret                    ; return (ignore all errors) .message   defm "This should go to the file and the screen.", 0 .cli_string defm ".S", 0