REDIRECTING INPUT OUTPUT The Max-FORTH System provides for redirecting system I/O through the use of two USER variables that select control blocks that determinae how the built in I/O subroutines work, and three low level vectors in USER variables that point to the built in I/O subroutines that handle the serial channel. The word locations, KEY-CB-PTR and EMIT-CB-PTR, ($0012 and $0014) point to control blocks that determine how the built in I/O routines work. Alternate control blocks can be constructed to handle alternate I/O devices without modifying the I/O routines. The blocks are six bytes long. They each consist of a two byte address of the I/O device status register to be read, a one byte mask with which the status value read will be AND'ed to screen out extraneous bits, a one byte mask with which the AND'ed result will be XOR'ed to obtain a non-zero result when the device is ready for transfer, and a two byte address of the I/O device data register. KEY-CB-PTR and EMIT-CB-PTR The KEY-CB-PTR and the EMIT-CB-PTR are initialized to point to the beginning of the default Serial Communications Interface con- trol blocks. The pointer can be modified to point to control blocks that handle LCD displays and keypad controllers or alter- nate serial chips, etc. to redirect system I/O. The following is an example of programming the New Micros Max- FORTH system for use with of an external R65C52 DACIA at address 8000. This example may be typed verbatim when using a NMIS-5002 (R65C52) board. It switches the Max-FORTH terminal I/O from the on-chip SCI to Channel 1 of the Dual ACIA. COLD HEX 100 TIB ! 50 TIB 2+ ! 200 DP ! CREATE KEY-CB 8000 , ( Status Register Location ) 01 C, ( bit 0, Receive Data Register Full ) 00 C, ( 1 = Receive Data Register is FULL ) 8003 , ( Receive Data Register Location ) CREATE EMIT-CB 8000 , ( Status Register Location ) 40 C, ( bit 6, Transmit Data Register Empty ) 00 C, ( 1 = Transmit Data Register is EMPTY ) 1 8003 , ( Transmit Data Register Location ) : INIT ( Used to initialize the external UART ) 0C 8001 C! ( 9600 BAUD, ONE STOP BIT ) F0 8001 C! ( NO PARITY, DTR' AND RTS' LOW ) ; : SET-EXTERNAL-I/O KEY-CB 12 ! EMIT-CB 14 ! ; : SET-INTERNAL-I/O [ 12 @ ] LITERAL 12 ! [ 14 @ ] LITERAL 14 ! ; : TEST ( A word which uses the external UART for serial I/O ) INIT SET-EXTERNAL-I/O ( All I/O will now go to the external UART. ) 100 . ( Example of using "." ) ( Using standard text string functions. ) ." This is a test of external I/O " CR ." After this is sent I will return to internal I/O " CR SET-INTERNAL-I/O ( Returning System I/O to the 68HC11. ) ; Typing SET-EXTERNAL-I/O will cause Max-FORTH to use the external UART as the system serial port. If no terminal or device is hooked to this external serial port, control can not be returned to the internal system serial port without doing a COLD reboot. If a terminal or device is hooked to this external port, then is- suing the command SET-INTERNAL-I/O from the terminal will return system I/O to the internal serial I/O port. Max-FORTH words may temporarily re-direct serial I/O by issuing the SET-EXTERNAL-I/O command before using the standard Max-FORTH serial I/O words. After the serial transfer is complete, the words should return control back to the standard serial I/O chan- nel with the command SET-INTERAL-I/O before terminating. In the example, TEST shows this procedure. UKEY, UEMIT and U?TERMINAL The following three USER locations ($0016, $0018 and $001A) are the actual machine level vectors to the I/O subroutines that provide the functions mentioned above. If a control block solu- tion is not sufficient, you may write your own machine code sub- routine. Its address is installed in UKEY , UEMIT or U?TERMINAL as appropriate. 2 Possible applications using these vectors include the addition of XON/XOFF capabilities to the normal serial channel by adding more intelligent drivers. The following example illustrates that pos- sibility. When properly installed, one should be able to start a WORDS listing and then hit a S, which is an XOFF, and hold the listing until a Q, which is XON, is sent. HEX CODE-SUB NEW-KEY-SUBROUTINE ( STRIPS OUT XON Q 11'S AND XOFF S 13'S) ( USES EXISTING I/O ROUTINES TO GET THE CHAR ) BEGIN, BEGIN, 16 @ JSR, TOP LDD, INY, INY, 13 # CMPB, .NE. UNTIL, 11 # CMPB, .NE. UNTIL, DEY, DEY, TOP STD, RTS, END-CODE CODE-SUB NEW-EMIT-SUBROUTINE ( WAITS IF A S IN SERIAL REG UNTIL Q ) 1A @ JSR, ( ?TERMINAL TOP LDD, INY, INY, 0 # CMPB, .NE. IF, 16 @ JSR, ( UKEY TOP LDD, INY, INY, 13 # CMPB, .EQ. IF, BEGIN, 16 @ JSR, ( UKEY TOP LDD, INY, INY, 11 # CMPB, .EQ. UNTIL, THEN, THEN, 18 @ JSR, ( UEMIT RTS, 3 END-CODE : DO-NORMAL [ 16 @ ] LITERAL 16 ! [ 18 @ ] LITERAL 18 ! ; : DO-XON-XOFF [ ' NEW-KEY-SUBROUTINE @ ] LITERAL 16 ! [ ' NEW-EMIT-SUBROUTINE @ ] LITERAL 18 ! ; Typing DO-XON-XOFF will cause Max-FORTH to use the XON/XOFF protocall. The command DO-NORMAL will return system I/O to the default UKEY and UEMIT settings. The only disadvantage of this example is that incoming characters can be lost if they come during an output. There is no way to re-stuff a character back into the serial channel once it has been taken out by the new emit routine. The function of ?TERMINAL is overridden during output of characters, since the output routine gets to the SCI to check for characters before it can. WORDS does not stop when any other characters are entered. A more complex version that did buffering of the input characters could overcome this, but is beyond the scope of this example. 4