MODULE KERTRM (IDENT = '1.0.000'
) =
BEGIN
!++
! FACILITY:
!
! KERMIT-32 terminal processing.
!
! ABSTRACT:
!
! This module will do all of the terminal processing for KERMIT-32.
! It contains the output routines for the terminal to send and
! receive messages as well as the routines to output text for debugging.
!
! ENVIRONMENT:
!
! VAX/VMS user mode.
!
! AUTHOR: Robert C. McQueen, CREATION DATE: 25-March-1983
!--
%SBTTL 'Table of Contents'
!
! TABLE OF CONTENTS:
!
%SBTTL 'Revision History'
!++
!
! Start of version 1. 25-March-1983
!
! 1.0.000 By: Robert C. McQueen On: 25-March-1983
! Create this module.
!
!--
%SBTTL 'Forward routine definitions'
FORWARD ROUTINE
TT_CHAR : NOVALUE, ! Process a single character
TT_OUTPUT : NOVALUE; ! Output the buffer to SYS$OUTPUT
%SBTTL 'Library files'
!
! INCLUDE FILES:
!
!
! System definitions
!
LIBRARY 'SYS$LIBRARY:STARLET';
!
! KERMIT common definitions
!
REQUIRE 'KERCOM';
REQUIRE 'KERERR';
%SBTTL 'Structure definitions -- $GETDVI arguments'
!
! $GETDVI interface fields and structure definition
!
LITERAL
DVI_SIZE = 3; ! Length of a DVI item list entry
!
! Fields for accessing the items in a DVI item list
!
FIELD
DVI_FIELDS =
SET
DVI_BFR_LENGTH = [0, 0, 16, 0],
DVI_ITEM_CODE = [0, 16, 16, 0],
DVI_BFR_ADDRESS = [1, 0, 32, 0],
DVI_RTN_LENGTH = [2, 0, 32, 0]
TES;
!
! Structure definition for item list
STRUCTURE
DVI_ITEM_LIST [I, O, P, S, E; N] =
[(N + 1)*DVI_SIZE*4]
(DVI_ITEM_LIST + ((I*DVI_SIZE) + O)*4)
;
%SBTTL 'Structures definitions -- Terminal characteristics'
!
! Terminal characteristics words
!
LITERAL
TC$_CHAR_LENGTH = 12;
!
! Fields for accessing the items in a characteristic block
!
FIELD
TC$_FIELDS =
SET
TC$_CLASS = [0, 0, 8, 0],
TC$_TYPE = [0, 8, 8, 0],
TC$_BFR_SIZE = [0, 16, 16, 0],
TC$_PAGE_LEN = [1, 24, 8, 0],
TC$_CHAR = [1, 0, 24, 0],
TC$_CHAR_2 = [2, 0, 32, 0]
TES;
!
! Structure definition for item list
!
STRUCTURE
TC$_CHAR_STR [O, P, S, E; N] =
[TC$_CHAR_LENGTH]
(TC$_CHAR_STR + O*4)
;
%SBTTL 'Macro definitions'
!
! MACROS:
!
%(/*macro-decl*/)%
%SBTTL 'Symbol definitions'
!
! EQUATED SYMBOLS:
!
LITERAL
TEXT_BFR_LENGTH = 256; ! Length of the text buffer
%SBTTL 'Storage'
!
! OWN STORAGE:
!
!
! TT_xxxxx routine storage
!
OWN
TEXT_POINTER, ! Pointer to store characters
TEXT_BUFFER : VECTOR [CH$ALLOCATION (TEXT_BFR_LENGTH)], ! Buffer of characters
TEXT_DESC : BLOCK [8, BYTE];
!
! Communications routines storage
!
OWN
TERM_CHAN, ! Channel the terminal is opened on
OLD_PARITY : BLOCK [8, BYTE], ! Old IOSB information
OLD_TERM_CHAR : TC$_CHAR_STR FIELD (TC$_FIELDS), ! Old terminal chars
NEW_TERM_CHAR : TC$_CHAR_STR FIELD (TC$_FIELDS); ! New terminal chars
GLOBAL
TERM_FLAG; ! Terminal open flag
%SBTTL 'External routines'
!
! EXTERNAL REFERENCES:
!
!
! System library routines
!
EXTERNAL ROUTINE
LIB$SIGNAL : ADDRESSING_MODE (GENERAL),
LIB$PUT_OUTPUT : ADDRESSING_MODE (GENERAL);
%SBTTL 'External storage'
!++
! The following is the various external storage locations that are
! referenced from this module.
!--
!
! KERMSG storage
!
EXTERNAL
RCV_EOL, ! Receive EOL character
RCV_TIMEOUT, ! Receive time out counter
CONNECT_FLAG; ! Flag if communications line is TT:
!
! KERMIT storage
!
EXTERNAL
TERM_NAME, ! Terminal name
TERM_DESC : BLOCK [8, BYTE]; ! Descriptor for terminal name
%SBTTL 'Terminal routines -- TT_INIT - Initialize this module'
GLOBAL ROUTINE TT_INIT : NOVALUE =
!++
! FUNCTIONAL DESCRIPTION:
!
! This routine will initialize the terminal processing module. It will
! initialize the various data locations in this module.
!
! CALLING SEQUENCE:
!
! TT_INIT();
!
! INPUT PARAMETERS:
!
! None.
!
! IMPLICIT INPUTS:
!
! None.
!
! OUPTUT PARAMETERS:
!
! None.
!
! IMPLICIT OUTPUTS:
!
! None.
!
! COMPLETION CODES:
!
! None.
!
! SIDE EFFECTS:
!
! None.
!
!--
BEGIN
!
! Initialize the text descriptor
!
TEXT_DESC [DSC$B_CLASS] = DSC$K_CLASS_S;
TEXT_DESC [DSC$B_DTYPE] = DSC$K_DTYPE_T;
TEXT_DESC [DSC$A_POINTER] = TEXT_BUFFER;
TEXT_DESC [DSC$W_LENGTH] = 0;
!
! Now initialize the various pointers
!
TEXT_POINTER = CH$PTR (TEXT_BUFFER);
!
! Set up the terminal name descriptor
TERM_DESC [DSC$B_CLASS] = DSC$K_CLASS_S;
TERM_DESC [DSC$B_DTYPE] = DSC$K_DTYPE_T;
TERM_DESC [DSC$A_POINTER] = TERM_NAME;
TERM_DESC [DSC$W_LENGTH] = 12;
CH$COPY (10, CH$PTR (UPLIT ('SYS$INPUT:')), 0, 11, CH$PTR (TERM_NAME));
!
! Initialize the flags
!
TERM_FLAG = FALSE;
END; ! End of TT_INIT
%SBTTL 'Terminal routines -- TT_TEXT - Output a text string'
GLOBAL ROUTINE TT_TEXT (ADDRESS) : NOVALUE =
!++
! FUNCTIONAL DESCRIPTION:
!
! This routine will output text on the user's terminal. It will
! assume that it must check to determine if it can output the text
! or not.
!
! CALLING SEQUENCE:
!
! TT_TEXT(TEXT_ADDRESS);
!
! INPUT PARAMETERS:
!
! None.
!
! IMPLICIT INPUTS:
!
! None.
!
! OUPTUT PARAMETERS:
!
! None.
!
! IMPLICIT OUTPUTS:
!
! None.
!
! COMPLETION CODES:
!
! None.
!
! SIDE EFFECTS:
!
! None.
!
!--
BEGIN
LOCAL
CHARACTER, ! Character being processed
ARG_POINTER; ! Pointer to the argument's text
!
! Construct a pointer to the argument.
!
ARG_POINTER = CH$PTR (.ADDRESS);
!
! Get the first character that was passed.
!
CHARACTER = CH$RCHAR_A (ARG_POINTER);
!
! Loop reading characters and calling the output routine to process
! them
!
WHILE .CHARACTER NEQ CHR_NUL DO
BEGIN
TT_CHAR (.CHARACTER);
CHARACTER = CH$RCHAR_A (ARG_POINTER);
END;
END; ! End of TT_TEXT
%SBTTL 'Terminal routines -- TT_NUMBER - Output a three digit number'
GLOBAL ROUTINE TT_NUMBER (NUMBER) : NOVALUE =
!++
! FUNCTIONAL DESCRIPTION:
!
! This routine will store a three digit number into the text buffer.
! It will just return if the number is greater than 999.
!
! CALLING SEQUENCE:
!
! TT_NUMBER(Value);
!
! INPUT PARAMETERS:
!
! Value - Value to output.
!
! IMPLICIT INPUTS:
!
! None.
!
! OUPTUT PARAMETERS:
!
! None.
!
! IMPLICIT OUTPUTS:
!
! None.
!
! COMPLETION CODES:
!
! None.
!
! SIDE EFFECTS:
!
! None.
!
!--
BEGIN
IF .NUMBER LEQ 999
THEN
BEGIN
TT_CHAR ((.NUMBER/100) + %C'0');
TT_CHAR (((.NUMBER/10) MOD 10) + %C'0');
TT_CHAR ((.NUMBER MOD 10) + %C'0');
END;
END; ! End of TT_NUMBER
%SBTTL 'Terminal routines -- TT_QCHAR - Output a single character'
GLOBAL ROUTINE TT_QCHAR (CHARACTER) : NOVALUE =
!++
! FUNCTIONAL DESCRIPTION:
!
! This routine will output a quoted character to the terminal buffer.
! It will convert control characters to printing characters.
!
! CALLING SEQUENCE:
!
! TT_QCHAR(Character);
!
! INPUT PARAMETERS:
!
! Character - Character to store into the text buffer.
!
! IMPLICIT INPUTS:
!
! None.
!
! OUPTUT PARAMETERS:
!
! None.
!
! IMPLICIT OUTPUTS:
!
! None.
!
! COMPLETION CODES:
!
! None.
!
! SIDE EFFECTS:
!
! None.
!
!--
BEGIN
LOCAL
TEMP_CHAR; ! Temp holding place for the characters
!
! Copy the character first
!
TEMP_CHAR = .CHARACTER;
!
! Determine if this is a control character. If so then convert it to be
! a ^
!
IF .TEMP_CHAR LSS CHR_SP
THEN
BEGIN
TT_CHAR (%C'^');
TEMP_CHAR = %C'A' - 1 + .TEMP_CHAR;
END;
!
! Output the character after any conversion
!
TT_CHAR (.TEMP_CHAR);
!
END; ! End of TT_QCHAR
%SBTTL 'Terminal routines -- TT_CHAR - Output a single character'
GLOBAL ROUTINE TT_CHAR (CHARACTER) : NOVALUE =
!++
! FUNCTIONAL DESCRIPTION:
!
! This routine will store a character into the text buffer. It will
! cause the text to be output if the character is a line terminator.
!
! CALLING SEQUENCE:
!
! TT_CHAR(Character);
!
! INPUT PARAMETERS:
!
! Character - Character to store into the text buffer.
!
! IMPLICIT INPUTS:
!
! None.
!
! OUPTUT PARAMETERS:
!
! None.
!
! IMPLICIT OUTPUTS:
!
! None.
!
! COMPLETION CODES:
!
! None.
!
! SIDE EFFECTS:
!
! None.
!
!--
BEGIN
!
! If this is a line feed then just output the text string and return
!
IF .CHARACTER EQL CHR_LFD
THEN
TT_OUTPUT ()
ELSE
BEGIN
!
! Increment the count of the characters
!
TEXT_DESC [DSC$W_LENGTH] = .TEXT_DESC [DSC$W_LENGTH] + 1;
!
! And store the character
!
CH$WCHAR_A (.CHARACTER, TEXT_POINTER);
IF .TEXT_DESC [DSC$W_LENGTH] EQL TEXT_BFR_LENGTH THEN TT_OUTPUT ();
END;
!
END; ! End of TT_CHAR
%SBTTL 'Terminal routines -- TT_CRLF - Output a CRLF'
GLOBAL ROUTINE TT_CRLF : NOVALUE =
!++
! FUNCTIONAL DESCRIPTION:
!
! This routine will cause the contents of the terminal buffer to be
! output to SYS$OUTPUT:.
!
! CALLING SEQUENCE:
!
! TT_CRLF();
!
! INPUT PARAMETERS:
!
! None.
!
! IMPLICIT INPUTS:
!
! None.
!
! OUPTUT PARAMETERS:
!
! None.
!
! IMPLICIT OUTPUTS:
!
! None.
!
! COMPLETION CODES:
!
! None.
!
! SIDE EFFECTS:
!
! None.
!
!--
BEGIN
TT_CHAR (CHR_LFD);
END; ! End of TT_CRLF
%SBTTL 'Terminal routines -- TT_OUTPUT - Output the buffer'
ROUTINE TT_OUTPUT : NOVALUE =
!++
! FUNCTIONAL DESCRIPTION:
!
! This routine will dump the text buffer on the output device.
!
! CALLING SEQUENCE:
!
! TT_OUTPUT();
!
! INPUT PARAMETERS:
!
! None.
!
! IMPLICIT INPUTS:
!
! None.
!
! OUPTUT PARAMETERS:
!
! None.
!
! IMPLICIT OUTPUTS:
!
! None.
!
! COMPLETION CODES:
!
! None.
!
! SIDE EFFECTS:
!
! None.
!
!--
BEGIN
LOCAL
STATUS; ! Status returned by the library routine
!
! Output the text
!
STATUS = LIB$PUT_OUTPUT (TEXT_DESC);
!
! Now reset the descriptor and the pointer to a virgin state
!
TEXT_DESC [DSC$W_LENGTH] = 0;
TEXT_POINTER = CH$PTR (TEXT_BUFFER);
!
END; ! End of TT_OUTPUT
%SBTTL 'Communcations line -- TERM_OPEN'
GLOBAL ROUTINE TERM_OPEN =
!++
! FUNCTIONAL DESCRIPTION:
!
! This routine will assign a channel that is used in the CONNECT
! processing and to send/receive a file from.
!
! CALLING SEQUENCE:
!
! TERM_OPEN();
!
! INPUT PARAMETERS:
!
! None.
!
! IMPLICIT INPUTS:
!
! TERM_NAME - Vector of ASCII characters that represent the name of
! the terminal to use.
!
! OUTPUT PARAMETERS:
!
! None.
!
! IMPLICIT OUTPUTS:
!
! TERM_CHAN - Channel number of the terminal line we are using.
!
! COMPLETION CODES:
!
! SS$_NORMAL or error condition.
!
! SIDE EFFECTS:
!
! None.
!
!--
BEGIN
BIND
SYS_OUTPUT = %ASCID'TT:';
LOCAL
STATUS,
OUTPUT_ITM : DVI_ITEM_LIST [2] FIELD (DVI_FIELDS),
OUTPUT_NAME : VECTOR [65, BYTE],
OUTPUT_LENGTH,
OUTPUT_CLASS,
OUTPUT_STATUS,
TERM_ITM : DVI_ITEM_LIST [2] FIELD (DVI_FIELDS),
TERM_NAME : VECTOR [65, BYTE],
TERM_LENGTH,
TERM_CLASS,
TERM_STATUS;
!
! Initialize the first character to be an underscore, incase we have a
! concealed device name
!
OUTPUT_NAME [0] = %C'_';
TERM_NAME [0] = %C'_';
!
! Initialize the GETDVI call for the TT:
!
OUTPUT_ITM [0, DVI_ITEM_CODE] = DVI$_DEVCLASS;
OUTPUT_ITM [0, DVI_BFR_LENGTH] = 4;
OUTPUT_ITM [0, DVI_BFR_ADDRESS] = OUTPUT_CLASS;
OUTPUT_ITM [0, DVI_RTN_LENGTH] = 0;
!
OUTPUT_ITM [1, DVI_ITEM_CODE] = DVI$_DEVNAM;
OUTPUT_ITM [1, DVI_BFR_LENGTH] = 64;
OUTPUT_ITM [1, DVI_BFR_ADDRESS] = OUTPUT_NAME [1];
OUTPUT_ITM [1, DVI_RTN_LENGTH] = OUTPUT_LENGTH;
!
OUTPUT_ITM [2, DVI_ITEM_CODE] = 0;
OUTPUT_ITM [2, DVI_BFR_LENGTH] = 0;
!
! Initialize the GETDVI call for the terminal name given
!
TERM_ITM [0, DVI_ITEM_CODE] = DVI$_DEVCLASS;
TERM_ITM [0, DVI_BFR_LENGTH] = 4;
TERM_ITM [0, DVI_BFR_ADDRESS] = TERM_CLASS;
TERM_ITM [0, DVI_RTN_LENGTH] = 0;
!
TERM_ITM [1, DVI_ITEM_CODE] = DVI$_DEVNAM;
TERM_ITM [1, DVI_BFR_LENGTH] = 64;
TERM_ITM [1, DVI_BFR_ADDRESS] = TERM_NAME [1];
TERM_ITM [1, DVI_RTN_LENGTH] = TERM_LENGTH;
!
TERM_ITM [2, DVI_ITEM_CODE] = 0;
TERM_ITM [2, DVI_BFR_LENGTH] = 0;
!
! Get the device information
!
OUTPUT_STATUS = $GETDVI (EFN = 2, DEVNAM = SYS_OUTPUT, ITMLST = OUTPUT_ITM);
IF NOT .OUTPUT_STATUS
THEN
BEGIN
LIB$SIGNAL (.OUTPUT_STATUS);
RETURN .OUTPUT_STATUS;
END;
STATUS = $WAITFR (EFN = 2);
IF NOT .STATUS
THEN
BEGIN
LIB$SIGNAL (.STATUS);
RETURN .STATUS;
END;
!
! For both of the device names
!
TERM_STATUS = $GETDVI (EFN = 2, DEVNAM = TERM_DESC, ITMLST = TERM_ITM);
IF NOT .TERM_STATUS
THEN
BEGIN
LIB$SIGNAL (.TERM_STATUS);
RETURN .STATUS;
END;
STATUS = $WAITFR (EFN = 2);
IF NOT .STATUS
THEN
BEGIN
LIB$SIGNAL (.STATUS);
RETURN .STATUS;
END;
!
! Make sure that they are terminals
!
IF .TERM_CLASS EQL DC$_TERM AND .OUTPUT_CLASS EQL DC$_TERM
THEN
BEGIN
IF .OUTPUT_STATUS EQL SS$_CONCEALED
THEN
BEGIN
OUTPUT_LENGTH = .OUTPUT_LENGTH + 1;
OUTPUT_ITM [1, DVI_BFR_ADDRESS] = .OUTPUT_ITM [1, DVI_BFR_ADDRESS] - 1;
END;
IF .TERM_STATUS EQL SS$_CONCEALED
THEN
BEGIN
TERM_LENGTH = .TERM_LENGTH + 1;
TERM_ITM [1, DVI_BFR_ADDRESS] = .TERM_ITM [1, DVI_BFR_ADDRESS] - 1;
END;
IF CH$NEQ (.OUTPUT_LENGTH, CH$PTR (.OUTPUT_ITM [1, DVI_BFR_ADDRESS]), .TERM_LENGTH,
CH$PTR (.TERM_ITM [1, DVI_BFR_ADDRESS]), CHR_NUL)
THEN
CONNECT_FLAG = FALSE
ELSE
CONNECT_FLAG = TRUE;
END
ELSE
BEGIN
RETURN KER_LINTERM;
END;
STATUS = $ASSIGN (DEVNAM = TERM_DESC, CHAN = TERM_CHAN);
IF NOT .STATUS
THEN
BEGIN
LIB$SIGNAL (.STATUS);
RETURN .STATUS;
END;
STATUS = $QIOW (CHAN = .TERM_CHAN, FUNC = IO$_SENSEMODE, P1 = OLD_TERM_CHAR, P2 = TC$_CHAR_LENGTH, IOSB = OLD_PARITY);
IF NOT .STATUS
THEN
BEGIN
LIB$SIGNAL (.STATUS);
RETURN .STATUS;
END;
NEW_TERM_CHAR [TC$_BFR_SIZE] = .OLD_TERM_CHAR [TC$_BFR_SIZE];
NEW_TERM_CHAR [TC$_TYPE] = .OLD_TERM_CHAR [TC$_TYPE];
NEW_TERM_CHAR [TC$_CLASS] = .OLD_TERM_CHAR [TC$_CLASS];
NEW_TERM_CHAR [TC$_PAGE_LEN] = .OLD_TERM_CHAR [TC$_PAGE_LEN];
NEW_TERM_CHAR [TC$_CHAR] = (.OLD_TERM_CHAR [TC$_CHAR] OR TT$M_EIGHTBIT OR TT$M_NOBRDCST) AND NOT (
TT$M_CRFILL OR TT$M_LFFILL OR TT$M_WRAP);
NEW_TERM_CHAR [TC$_CHAR_2] = .OLD_TERM_CHAR [TC$_CHAR_2];
STATUS = $QIOW (CHAN = .TERM_CHAN, FUNC = IO$_SETMODE, P1 = NEW_TERM_CHAR, P2 = TC$_CHAR_LENGTH, P5 = TT$M_ALTRPAR);
IF NOT .STATUS
THEN
BEGIN
LIB$SIGNAL (.STATUS);
RETURN .STATUS;
END;
TERM_FLAG = TRUE; ! Terminal now open
RETURN KER_NORMAL;
END; ! End of TERM_OPEN
%SBTTL 'Communications line -- TERM_CLOSE'
GLOBAL ROUTINE TERM_CLOSE =
!++
! FUNCTIONAL DESCRIPTION:
!
! This routine will deassign the channel that was assigned by
! TERM_OPEN.
!
! CALLING SEQUENCE:
!
! TERM_CLOSE();
!
! INPUT PARAMETERS:
!
! None.
!
! IMPLICIT INPUTS:
!
! TERM_CHAN - Channel number to deassign.
!
! OUTPUT PARAMETERS:
!
! None.
!
! IMPLICIT OUTPUTS:
!
! None.
!
! COMPLETION CODES:
!
! SS$_NORMAL or error condition.
!
! SIDE EFFECTS:
!
! None.
!
!--
BEGIN
LOCAL
PAR, ! Parity being set
STATUS; ! Status returned by system service
CONNECT_FLAG = FALSE;
PAR = .OLD_PARITY [1, 8, 8, 0] OR TT$M_ALTRPAR;
STATUS = $QIOW (CHAN = .TERM_CHAN, FUNC = IO$_SETMODE, P1 = OLD_TERM_CHAR, P2 = TC$_CHAR_LENGTH, P5 = .PAR);
IF NOT .STATUS
THEN
BEGIN
LIB$SIGNAL (.STATUS);
RETURN .STATUS;
END;
STATUS = $DASSGN (CHAN = .TERM_CHAN);
IF .STATUS
THEN
BEGIN
TERM_FLAG = FALSE;
RETURN KER_NORMAL
END
ELSE
BEGIN
LIB$SIGNAL (.STATUS);
RETURN .STATUS;
END;
END; ! End of TERM_CLOSE
%SBTTL 'Communications line -- SEND'
GLOBAL ROUTINE SEND (ADDRESS, LENGTH) =
!++
! FUNCTIONAL DESCRIPTION:
!
! This routine will send a stream of 8-bit bytes over the terminal
! line to the remote KERMIT. This routine is called from KERMSG.
!
! CALLING SEQUENCE:
!
! SEND(Address-of-msg, Length-of-msg);
!
! INPUT PARAMETERS:
!
! None.
!
! IMPLICIT INPUTS:
!
! TERM_CHAN - Channel number to deassign.
!
! OUTPUT PARAMETERS:
!
! None.
!
! IMPLICIT OUTPUTS:
!
! None.
!
! COMPLETION CODES:
!
! SS$_NORMAL or error condition.
!
! SIDE EFFECTS:
!
! None.
!
!--
BEGIN
LOCAL
STATUS; ! Status returned by $QIOW
STATUS = $QIOW (CHAN = .TERM_CHAN, FUNC = IO$_WRITEVBLK + IO$M_NOFORMAT, P1 = .ADDRESS, P2 = .LENGTH);
IF .STATUS EQL SS$_NORMAL
THEN
RETURN KER_NORMAL
ELSE
BEGIN
LIB$SIGNAL (.STATUS);
RETURN .STATUS;
END;
END; ! End of SEND
%SBTTL 'Communications line -- RECEIVE'
GLOBAL ROUTINE RECEIVE (ADDRESS, LENGTH) =
!++
! FUNCTIONAL DESCRIPTION:
!
! This routine will receive a stream of 8-bit bytes over the terminal
! line to the remote KERMIT. This routine is called from KERMSG.
! The text that is stored will always contain the control-A as the
! first character.
!
! CALLING SEQUENCE:
!
! RECEIVE(Address-of-msg);
!
! INPUT PARAMETERS:
!
! None.
!
! IMPLICIT INPUTS:
!
! TERM_CHAN - Channel number to deassign.
!
! OUTPUT PARAMETERS:
!
! None.
!
! IMPLICIT OUTPUTS:
!
! None.
!
! COMPLETION CODES:
!
! SS$_NORMAL or error condition.
!
! SIDE EFFECTS:
!
! None.
!
!--
BEGIN
LOCAL
TERMINATOR : VECTOR [2, LONG],
IO_STATUS : VECTOR [4, WORD],
POINTER, ! Pointer into the message
STATUS; ! Status returned by $QIO
TERMINATOR [0] = 0;
TERMINATOR [1] = 1^.RCV_EOL;
STATUS = $QIOW (CHAN = .TERM_CHAN, FUNC = IO$_TTYREADALL + IO$M_NOECHO, IOSB = IO_STATUS, P1 = .ADDRESS,
P2 = MAX_MSG, P3 = .RCV_TIMEOUT, P4 = TERMINATOR);
.LENGTH = .IO_STATUS [1] + 1;
POINTER = CH$FIND_CH(.IO_STATUS [1] + 1, CH$PTR(.ADDRESS, 0, CHR_SIZE), CHR_CTL_Y);
IF CH$FAIL(POINTER) THEN RETURN KER_ABORTED;
IF .STATUS EQL SS$_TIMEOUT THEN RETURN KER_TIMEOUT;
IF .STATUS EQL SS$_NORMAL THEN RETURN KER_NORMAL;
! LIB$SIGNAL(KER_RECERR, .STATUS);
RETURN KER_RECERR;
END; ! End of RECEIVE
%SBTTL 'End of KERTRM'
END ! End of module
ELUDOM