Screen I/O
----------

1. Display System

	The Force compiler supports 3rd party I/O systems. The display library
routines are designed so that output from the display commands go through a
dword pointer that can be easily modified.

	Force generates calls to the display system by first sending data to a
type specific routine. That is, characters are sent to one routine, integers to
another, logical values to another and so on. Each of these library
routines eventually calls a procedure which is expected to handle the actual
I/O for the system. For example, the command

		? "this is a test"

has the following code generated by the Force compiler:

		push	<display width>
		push	seg of "this is a test"
		push	offset of "this is a test"
		call	_$disp_char

	The "_$disp_char" procedure is responsible for displaying the string
within <display width> column spaces. It sends the character string to the
procedure _$DISPLAY_STR.

	The "_$DISPLAY_STR" routine performs logic pertaining to the alternate
file and printer and then eventually calls the dword [ __$OUTPUT_STR ]. That is,

	call	dword ptr [ __$OUTPUT_STR ]

	At the time of the call, DS:SI point to a NULL terminated string. By
replacing the dword [ __$OUTPUT_STR ] with a pointer to another routine, one
can essentially trap all display I/O requests.

	The Display System will tee its output to the printer depending upon
the state of the __$FLAG_PRINTER word. If this word is TRUE, then the string
will also be sent to the printer device.

	Here is a diagram of the Display System.

			+------------------------------+
			| Call is generated by Force   |
			|  compiler to the procedure   |
			|  _$disp_<type>.(<type>       |
			|  refers to a data type(int,  |
			|  dbl, logical...).           |
			+------------------------------+
				       |
			+--------------------------------+
			| Call is generated by any of    |
			|  the _$disp_<type> procedures  |
			|  to the routine _$DISPLAY_STR. |
			|  A NULL terminated string is   |
			|  pushed onto the stack.        |
			+--------------------------------+
				       |
+-------------------+	+-----------------------------+
| Logic for the SET |	| _$DISPLAY_STR procedure     |
|  commands:	    |	|  generates a call to the    |
| SET ALTERNATE     |-->|  dword variable:            |
| SET PRINT ON/OFF  |	|                             |
| SET PRINTER TO    |	|      [ __$OUTPUT_STR ]      |
|  is accomplished  |	|                             |
|  in this module.  |	+-----------------------------+
+-------------------+		       |
				       |
+-----------------------------------+  |
| DO scrn_dos/bios/direct sets this |  |
+-----------------------------------+  |
		|		       |
		|		       |
		|	+-----------------------------+
		+------>| [ __$OUTOUT_STR ] variable  |
			|  can point to one of these  |
			|  Force I/O routines or      |
			|  a user defined routine     |
			+-----------------------------+
				       |
           +---------------------------+---------------------------+
           |                           |                           |
+----------+------------+  +-----------------------+  +------------+----------+
|        DIRECT         |  |          DOS          |  |           BIOS        |
| This is the default   |  | This routine is the   |  | This routine is the   |
| routine used by Force |  | slowest routine, yet  |  | most dBASE compatible.|
| and is the fastest.   |  | allows for Ctrl-C,    |  | Good for computers    |
| Routine writes to the |  | DOS redirection and   |  | like TI, which don't  |
| screen therefore is   |  | piping.               |  | have video ram in the |
| the least compatible. |  |                       |  | same location as IBM  |
|                       |  |                       |  | computers.            |
+-----------------------+  +-----------------------+  +-----------------------+

	There are two procedures associated with each of the low-level I/O
routines. One procedure is STRING based and the other procedure is CHARACTER
based. It is assumed the dword [ __$OUTPUT_STR ] points to a STRING based
routine. The dword [ __$OUTPUT_CHAR ] points to an output procedure which is
CHARACTER based. That is, the procedure(s) will handle one character at a time,
then return to caller. While a POINTER to a NULL terminated string is sent to
the string based routines, a CHARACTER is sent to the character based routines 
in AL.

	Table of low-level Display System procedures:

	Logic		Procedure Name		String/Character Logic
	--------------------------------------------------------------
	 DIRECT		 _$direct_str		string
	 DIRECT		 _$direct_char		character
	 DOS		 _$dos_str		string
	 DOS		 _$dos_char		character
	 BIOS		 _$bios_str		string
	 BIOS		 _$bios_char		character


	The I/O routines also use the dword pointers [ __$GET_ROW_COL ] and
[ __$SET_ROW_COL ] to retrieve/set the cursor.


2. How to attach your own driver.

	1. Move into the dword [ __$OUTPUT_STR ] a pointer to a
		string based I/O routine. Upon entry, DS:SI will point
		to a NULL terminated string.

	2. Move into the dword [ __$OUTPUT_CHAR ] a pointer to a
		character based I/O routine. Upon entry, AL contains
		the character to output.

	3. Move into the dword [ __$GET_ROW_COL ] a pointer to a
		"get the current row/column position" routine. Return in
		AX the current row and DX the current column.

	4. Move into the dword [ __$SET_ROW_COL ] a pointer to a
		"set the cursor row/col" procedure. Upon entry, DH contains
		the row and DL the column coordinates.

dword		i/o type		exit/entry conditions
------------------------------------------------------------------------------
__$OUTPUT_STR	string			DS:SI points to NULL terminated string
__$OUTPUT_CHAR	character		AL contains character
__$GET_ROW_COL	cursor			AX = row, DX = column
__$SET_ROW_COL	cursor			DH = row, DL = column

2. SAY/GET System

	All output for the SAY/GET system is character based. There are two
major vectors in the SAY/GET system allowing a programmer to establish their
own output drivers.

	The first is the dword [ __$SG_OUTPUT ]. This dword points to a routine
responsible for the output of a character to the screen. At the time of the
call to [ __$SG_OUTPUT ], the registers are set as follows:

	   AL = character to output
	ES:DI = points to location on screen

Only AL and DI may be modified by your output routine.

All template and "function" formatting has been accomplished when the call to 
[ __$SG_OUTPUT ] is made.

	The second pointer is [ __$READ_PROC ]. This vector is used when the
READ command is called. Use this vector to establish an environment important
to the READ that is global, i.e., initializing a cursor system.

	To use [ __$READ_PROC ], set the vector to your own routine. When your
new routine has accomplished its tasks, then call _$READ_DWORD. (_$READ_DWORD
is a FAR procedure). _$READ_DWORD will return to you when the GETs are
finished. Just issue a far return to leave your vector routine.

	To "deinstall" your [ __$READ_PROC ] routine, set the dword [
__$READ_PROC ] to -1.

