File RMKIFACE.DOC ------------------ Chris Kennington 8th July 1985. Research Machines Kermit Software Interfaces -------------------------------------------- 0. Structure of RM Kermit. ----------------------- The bulk of RM Kermit is written in standard C, designed to be portable between micros and micro operating systems. The actual implementations carried out at RML are for the RML 480Z, a Z80-based micro running under CP/M, and for the RM Nimbus, a 80186-based micro running (in this instance) under MSDOS. Since the performace and acceptability of Kermit depends heavily on its handling of keyboard, screen and communications line, no attempt was made to use standard CP/M or MSDOS functions for these purposes. Instead, a software interface to these routines was specified and hardware-dependent low-level routines coded to connect this interface to the necessary functions. (Due to the various possible hardware configurations, there are in fact several different sets of such routines.) There are also a small number of organizational procedures which may differ according to the micro OS used and other characteristics of the environment. Since a set of routines specific to the implementation have to be created and included, opportunity was taken to make some of the texts displayed also variable, so that help and other information is more closely appropriate to the version being run. This document describes these interfaces and lists the texts. For further information about specific cases, see file RMKGEN.DOC. 1. Keyboard/Screen Interface. -------------------------- 1.1 Screen-Handling. Kermit mostly divides the screen into a 4-line parameter area at the top, a fixed divider line, and a 19/20-line scrolling area occupying the rest of the screen. When in one of the menu modes, a further 5-line section plus divider is fixed at the bottom, leaving 14 or 15 lines for the menu. Some optimisation of output has been done, to provide the fastest display of information compatible with reasonable flexibility. Calls to printf() are used where it is necessary to format binary numbers and variable strings into other text, but other procedures are used to display fixed strings and individual characters at the current cursor position. All map into calls to the special screen-output procedure outc(), via a formatting routine outfc() which expands tabs etc. and deals with paging. Output of individual characters and strings to fixed screen-locations is handled by other procedures. All this logic deals with output destined for the physical screen. The built-in C-function putchar() remains the correct procedure for output of escape-sequences etc. which are in fact intercepted by the OS or the micro-firmware and interpreted by it rather than being passed for display. 1.2 Keyboard-Handling There is only one procedure required for reading the keyboard, kbdin(); it is of type char, and returns immediately with or without a character. It is assumed that the keyboard is buffering any characters which are input more rapidly than they are read out (though there is no expectation of readout falling seriously behind input). Kbdin() does not deal with null characters (ctl-@), since the return with this is indestinguishable from the return without a character. See below for the data which it is expected that the arrow and F keys will return. 1.3 Procedures. The keyboard/screen procedures which are used by Kermit are as follows (in all cases, the range of values taken by char variables is assumed to be from 0 to 255):- curset(line,col) position cursor char line, col; No return-code. cursor(sw) remove/replace cursor char sw; If sw = 0, the cursor is removed from the screen; the coordinates of the current position continue to be manipulated (by data-output or otherwise), even though the cursor is not on display. If sw != 0, it is taken as representing a cursor-character to be displayed @ the current position. No return-code. char kbdin() read char from keyboard Returns char in range 1-255, or 0 if no character available. keyconn() set keyboard for connect-mode Performs any reinitializations needed for connect-mode (when the characters to be sent from certain keys may differ from those defined below). No return-code. keyinit() initialize Sets up both keyboard and screen (see below). No return-code. keyrest() restore Restores keyboard and screen to their normal state. No return-code outc(ch) character to screen @ cursor-position char ch; character No return-code. A very limited set of control characters are honoured, see below for details; others are ignored. Characters with the top bit set are displayed as inverse video equivalents of those without. screen(top,bottom) define scrolling-area char top, bottom; No return-code. This defines the scrolling area of the screen to be from "top" to "bottom" inclusive. The parameters may be assumed correct, except that bottom > 23/24 implies the lowest possible line. (Line-numbering 0 - 23/24.) The scrolling area is full screen-width. scroll(n) scroll screen up/down int n; No return-code. The scrolling area of the screen is scrolled up or down by the number of lines defined by n. n > 0 implies normal scrolling (data moves up); n < 0 is the opposite (data moves down); n = 0 is a no-op. Blank lines are scrolled in at top or bottom, so a scroll of more than the size of the scrolling area is a clear-screen. vtout(loc,ch) character to screen @ specified position int loc; screen-position (in HL format as defined below) char ch; character No return-code. All characters are treated as printable. For characters in the range 0-31 those defined for the RML 480Z are assumed, but any similar set should be acceptable. vtline(loc,str) string to screen @ specified position int loc; screen-postion, as above char *str; pointer to string No return-code. All characters treated as printable, as above. If the string runs off the edge, the end is lost. 1.4 Cursor Definition. In defining cursor positions, "HL format" means line*256 + col. In either HL format or when specified as 2 parameters, line and column are in range 0-23 (or 0-24) & 0-79 respectively, and refer to the whole screen, i.e. (0,0) is the top left-hand corner, irrespective of scrolling-area arrangements. Validity checks are reduced to a minimum (taking values > max to be = max and < 0 to be = 0), since Kermit is a (presumably) developed program. 1.5 Control Characters. CR (0x0d) is defined to move the cursor to the left margin, then move it DOWN. LF (0x0a) is defined to move the cursor straight down. The UP (0x0b) & DOWN (0x0a) cursor movements cause screen scrolling if they attempt to go off the scrolling area. The RIGHT (0x18) & LEFT (0x08) cursor movements are no-ops if the cursor is already on the margin. Attempting to store a character (by outc(ch)) when the cursor is at the right margin causes a "CR" to the beginning of the next line (with scrolling if on the bottom line). DEL (7fH) is defined as a destructive backspace, i.e. it deletes the character (if any) to the left of the cursor, then moves the cursor LEFT. Overtyping an existing character has no side-effects (i.e. there is no "insert" mode). 1.6 Initialization. Screen initialization implies clearing, homing the cursor to top left, and setting full-screen scroll. Keyboard initialization includes switching off any specially-treated characters such as ctrl-A & ctrl-F. Kermit uses the arrow-pad and F-keys; the characters to be returned (other than in connect-mode), with and without SHIFT, are:- unshifted shifted --------- ------- arrow right 0f2H 0d2H arrow left 0ecH 0ccH arrow up 0f5H 0d5H arrow down 0e4H 0c4H F1 0e2H 0c2H F2 (TAB) 88H 88H F3 0eeH 0ceH F4 9bH 0bbH DEL/DELT 0x7f 0xff 2. Communications Interface. ------------------------- 2.1 Manner of Working. RM Kermit makes no assumptions about whether polled or interrupt-driven communications are in use. Procedures return immediately (i.e. they do not wait for data to be received or transmitted) with a flag indicating success or error. In one of the implementations there was a hardware requirement to quiesce the communications before issuing any commands to the disk-handling parts of CP/M. A call s4sleep() was therefore provided, and is called before all disk operations. It is a side-effect of any call to the active procedures s4get(), s4put() or s4reset() to wake up (un-sleep) the communications. The interface was designed to be used by other programs as well as Kermit. This has resulted in the existence of parameters which are superfluous, but must be set as shown. All procedures are type integer, and return < 1 for an error; success is indicated by 0 or 1. A call to any routine when comms are not initialized is an error (-1); in most other cases the value returned is that of a status-word (see below) which always has the top bit set. 2.2 Procedures. s4break(len) /* send "break" to comms line */ char len; /* duration in sec/8 */ (this procedure is not expected to return until the break has been completely sent.) s4get(n,buff) /* read character from comms line */ int n; /* number of chars available */ char *buff; /* buffer to receive chars */ (in Kermit the value of n is always 1) returns 0 if no character available, else # of chars actually read (<= n), else error-status. s4get7(n,buff) /* read stripped characters from comms line */ int n; /* number of chars available */ char *buff; /* buffer to receive chars */ as s4get(n,buff) except that it strips the top bit; calls to the two may be intermixed. s4go(); /* open/initialize comms routines */ may be called again after s4stop() to reopen comms; is a no-op if already open. s4put(n,buff) /* write characters to comms line */ int n; /* number of chars available */ char *buff; /* buffer containing chars */ (in Kermit the value of n is always 1) returns 0 if unable to write because line is busy, else # of chars actually written (<= n), else error-status. s4set(options,control); /* set facilities */ int options; /* facilities-word as defined */ char control; /* DTR & CTS bits of Z80sio WR5 */ s4sleep(); /* deactivate comms routines */ provided for cases where use of disks and communications are mutually exclusive, otherwise may be a no-op. s4speed(code) /* set speed of comms line */ char code; /* RML speed-code, 0-9 */ this routine may be called before s4init(). s4stop(); /* close down comms routines */ this routine is a no-op if comms are already stopped s4test(); /* test status of communications */ returns status-word as defined but with top bit set, hence always <0. 2.3 Returned Status-Word. This integer was originally a bit-pattern with meanings assigned to permit careful control of communications. Kermit only requires that a negative value (top bit set) should be returned if there is an error. 2.4 Option-Word and Control-Byte. These were also originally designed with a wide range of possibilities. The only bits of significance to Kermit are as shown below; all other bits may be ignored. Option-word: 0 - RTS/CTS flow-control to be used 1 - XON/XOFF flow-control to be used 8/9 - Parity-Generation on/off The 2-bit code for parity is: 0 - Generation not required 1 - Enforce odd parity 2 - Enforce even parity 3 - Enforce mark parity The only bit of the control-byte which is significant is bit7; this is set to 1 to raise DTR or an equivalent signal, 0 to drop it. 2.5 Speed-Codes. The following speed-codes are defined (though not necessarily all implemented in any given version):- 0 - 110baud (2 stop-bits) 1 - 300baud 2 - 600baud 3 - 1200baud 4 - 2400baud 5 - 4800baud 6 - 9600baud 7 - 19.2Kbaud 8 - 40.8Kbaud 9 - 75baud There is no provision for split-speed working, nor for half-duplex line turnaround. 8-bit data is always set, and 1 stop-bit except at 110baud. 3. Miscellaneous Interface. ------------------------ The following miscellaneous procedures are called by Kermit to perform system-oriented functions:- cpmgo() /* return to micro OS */ this call is used instead of "exit()" to permit a clean return to the micro's operating system after carrying out any required housekeeping. fpanel() /* debug display */ this call is executed after an "ESC-F" break-in to access the micros's built-in lowest-level debugging display. It may be a no-op if no such facility is available or required. unsigned getram(n) /* get storage */ int n; /* # of bytes required */ this call is used instead of "malloc()" to obtain dynamic storage so that the space occupied by initialization-code may be reused; it returns the start-address of the block of storage. If unable to allocate it should printf() a failure-message and call cpmgo(). Storage once allocated is never released. netcool() /* deactivate disk system */ this call is made before reading or writing the communications line; it would normally be a no-op. s4env() /* return environment */ this call returns a small integer value to indicate the communications environment in which it is running. The following values have been defined:- 0 - 480Z via SIO4 1 - 480Z via IDC 2 - Nimbus via Data Comms Controller (n.y.i.) 3 - Nimbus via Aux port 4 - Nimbus via Piconet 5 - 480Z or Nimbus via RML Network (n.y.i.) 6 - non-standard (Any user extending this table will have to amend the entries in arrays locations[] and fuzz[] in RMKDATA.C) The versions of these routines in file RMKNIMB.C should be suitable for most straightforward micros. 4. Data Items. ----------- There is no absolute need to change any of the texts displayed. The versions found in files RMK480Z.C and RMKNIMB.C (for CP/M and MSDOS systems respectively) may well be acceptable; the examples below are those from the Nimbus version. Data items which should be supplied for display are as follows:- char head1[] text-string to identify program, e.g. " RM NIMBUS Kermit File Transfer Program,"; char prompt[] normal prompt to be displayed by RM Kermit (there is no ability to change this dynamically), preceded by CR, e.g. "\rKmNimbus"; char eprompt[] special prompt to be displayed after ESC break-in, e.g. "\rKmF4> "; char backto[] final message to be displayed when Kermit terminates, e.g. " OK - back to MSDOS; "; If these texts are altered, it is recommended that their lengths should not be extended. *******************************************************