Trailing-Edge
-
PDP-10 Archives
-
TOPS-20_V6.1_DECnetSrc_7-23-85
-
mcb/tkb36/tfio20.bli
There is 1 other file named tfio20.bli in the archive. Click here to see a list.
!<REL4A.TKB-VNP>FIO20.BLI.8, 3-Dec-79 14:30:05, Edit by SROBINSON
MODULE FIO20 ( !File I/O for TOPS-20
IDENT = 'X2.0'
) =
BEGIN
!
! COPYRIGHT (c) 1980, 1981, 1982
! DIGITAL EQUIPMENT CORPORATION
! Maynard, Massachusetts
!
! This software is furnished under a license and may be used
! and copied only in accordance with the terms of such license
! and with the inclusion of the above copyright notice. This
! software or any other copies thereof may not be provided or
! otherwise made available to any other person. No title to
! and ownership of the software is hereby transferred.
!
! The information in this software is subject to change
! without notice and should not be construed as a commitment
! by DIGITAL EQUIPMENT CORPORATION.
!
! DIGITAL assumes no responsibility for the use or reliability
! of its software on equipment which is not supplied by
! DIGITAL.
!
!++
! FACILITY: TKB-20 and VNP-20
!
! ABSTRACT:
!
! This module does all I/O operations associated with the processing
! of files by VNP-20 and TKB-20. It also contains routines that are
! system dependent.
!
! The I/O routines supported are:
! RESET_ALL - initialization of I/O system
! OPEN - open a file
! CLOSE - close a file
! INPUT - get data from a file
! OUTPUT - put data onto a file
!
! The system dependent routines are:
! STOP_PROGRAM - terminate program
!
! Channel 0 is always the terminal. Other channels are assigned at
! will and are an artifact of programs written for TOPS-10 I/O.
!
! ENVIRONMENT: TOPS-20 User Mode
!
! AUTHOR: Scott G. Robinson, CREATION DATE: 25-NOV-78
!
! MODIFIED BY:
!
! Scott G. Robinson, 5-MAR-79 : VERSION X0.2
! - Modify to use JSYS_CALL macro to resolve register conflicts
!
! Scott G. Robinson, 13-JUN-79 : VERSION X0.3
! - Add routine STOP_PROGRAM
!-----------------------------------------------------------------------
!
! Scott G. Robinson, 3-DEC-79 : Version X2.0
! - Ensure DECnet-10 Compatibility
!
! , : VERSION
! 01 -
!--
!
! TABLE OF CONTENTS:
!
FORWARD ROUTINE
RESET_ALL : NOVALUE, !Reset all I/O
OPEN, !Open a file
CLOSE : NOVALUE, !Close a file
INPUT, !Read from a file
OUTPUT : NOVALUE, !Write on a file
STOP_PROGRAM : NOVALUE; !Terminate execution
!
! INCLUDE FILES:
!
LIBRARY 'BLI:MONSYM';
LIBRARY 'BLI:TENDEF';
!
! MACROS:
!
MACRO
JSYS_CALL (TYPE, FUNC, AC1, AC2, AC3, AC4) =
BEGIN
REGISTER T1=1,T2=2,T3=3,T4=4;
LOCAL VALUE;
BUILTIN JSYS;
%IF NOT %NULL(AC1) %THEN T1=.AC1; %FI
%IF NOT %NULL(AC2) %THEN T2=.AC2; %FI
%IF NOT %NULL(AC3) %THEN T3=.AC3; %FI
%IF NOT %NULL(AC4) %THEN T4=.AC4; %FI
VALUE = JSYS(TYPE,FUNC,T1,T2,T3,T4);
%IF NOT %NULL(AC1) %THEN %IF %DECLARED(AC1) %THEN AC1=.T1; %FI %FI
%IF NOT %NULL(AC2) %THEN %IF %DECLARED(AC2) %THEN AC2=.T2; %FI %FI
%IF NOT %NULL(AC3) %THEN %IF %DECLARED(AC3) %THEN AC3=.T3; %FI %FI
%IF NOT %NULL(AC4) %THEN %IF %DECLARED(AC4) %THEN AC4=.T4; %FI %FI
.VALUE
END %;
!
! EQUATED SYMBOLS:
!
LITERAL
DEBUG = 0,
LEN_LINE_BUFF = 160;
!
! OWN STORAGE:
!
OWN
CHAN_MODE : VECTOR [16], !1=Character, 2=Word
CHAN_DIRECTION : VECTOR [16], !0=Input, 1=Output
CHAN_JFN : VECTOR [16], !Channel to JFN Mapping
CHAN_NEXT : VECTOR [16], !Next byte in word mode
LINE_BUFF : VECTOR [CH$ALLOCATION (LEN_LINE_BUFF)]; !Input line buffer
!
! BOUND STORAGE FOR TERMINAL INPUT PROCESSING
!
BIND
LINE_LEN = CHAN_MODE [0],
LINE_STATUS = CHAN_DIRECTION [0],
LINE_PTR = CHAN_NEXT [0];
!
! EXTERNAL REFERENCES:
!
EXTERNAL ROUTINE
ERROR : NOVALUE, !Programming Error
ERRMSG : NOVALUE; !Standard Error Message
GLOBAL ROUTINE RESET_ALL : NOVALUE = !Reset all I/O
!++
! FUNCTIONAL DESCRIPTION:
!
! Initializes the I/O system
!
! FORMAL PARAMETERS:
!
! NONE
!
! IMPLICIT INPUTS:
!
! NONE
!
! IMPLICIT OUTPUTS:
!
! NONE
!
! COMPLETION CODES:
!
! NONE
!
! SIDE EFFECTS:
!
! All Files currently open are dropped
!
!--
BEGIN
BIND
ROUTINE_NAME = UPLIT (%ASCIZ'RESET_ALL');
JSYS_CALL (0, RESET);
END; !of RESET_ALL
GLOBAL ROUTINE OPEN (CHANX, FNAME, MODE, IO, DEFEXT) : = !Open a File
!++
! FUNCTIONAL DESCRIPTION:
!
! Opens a file on channel "CHANX" with name "FNAME" in mode "MODE"
! with direction "IO" with default extension "DEFEXT".
!
! FORMAL PARAMETERS:
!
! CHANX - Contains the channel number to associate with the file
! FNAME - Points at the file name
! MODE - File Mode (1=Character, 2= Word)
! IO - Direction (0=Input,1=Output)
! DEFEXT - Default extension if none specified in FNAME
!
! IMPLICIT INPUTS:
!
! NONE
!
! IMPLICIT OUTPUTS:
!
! NONE
!
! ROUTINE VALUE:
!
! 1 If OPEN Successful, 0 If not.
!
! SIDE EFFECTS:
!
! Modifies OWN storage to reflect associated file information.
!
!--
BEGIN
BIND
ROUTINE_NAME = UPLIT (%ASCIZ'OPEN');
LOCAL
CHAN,
GTJFN_BLOCK : VECTOR [9],
BYTE_SIZE,
AC1,
AC2,
AC3;
!
! Check on legality of channel number
!
CHAN = .CHANX;
IF (.CHAN EQL 0)
THEN
ERROR (UPLIT (%ASCIZ'May not OPEN channel 0 - OPEN'))
ELSE
IF ((.CHAN GTR 15) OR (.CHAN LSS 0))
THEN
ERROR (UPLIT (%ASCIZ'Invalid Channel Number - OPEN'))
ELSE
IF (.CHAN_JFN [.CHAN] NEQ 0)
THEN
ERROR (UPLIT (%ASCIZ'Attempting to OPEN an already OPEN channel - OPEN'))
ELSE
!
! We now have what appears to be a valid request: The channel number is within
! range and it is not open.
!
! Build a GTJFN Block to attempt and access the file.
!
BEGIN
GTJFN_BLOCK [$GJGEN] = (CASE .IO FROM 0 TO 1 OF
SET
[0] : GJ_OLD;
[1] : GJ_FOU + GJ_NEW;
[OUTRANGE] : -1;
TES);
INCR FOO FROM $GJDEV TO $GJJFN DO
GTJFN_BLOCK [.FOO] = 0;
GTJFN_BLOCK [$GJSRC] = %O'377777377777'; !.NULIO,,.NULIO
GTJFN_BLOCK [$GJEXT] = CH$PTR (.DEFEXT);
AC2 = CH$PTR (.FNAME);
AC1 = GTJFN_BLOCK;
IF NOT JSYS_CALL (1, GTJFN, AC1, AC2) !Get the JFN
THEN
BEGIN !and if in error
ERRMSG (0, 2, ROUTINE_NAME, .FNAME, 0, 0, 0);
RETURN 0
END;
CHAN_JFN [.CHAN] = .AC1; !Save returned JFN
CHAN_MODE [.CHAN] = .MODE; ! and mode
CHAN_DIRECTION [.CHAN] = .IO; ! with direction
CHAN_NEXT [.CHAN] = -1; !Indicate Initial State
!
! Because we were apparently successful in accessing the file, open
! it.
!
BYTE_SIZE = (CASE .MODE FROM 1 TO 2 OF
SET
[1] : 7; !Character mode
[2] : 18; !16-bit word mode
[OUTRANGE] : 0; !Use default
TES);
AC2 = FLD (.BYTE_SIZE, OF_BSZ) + (CASE .IO FROM 0 TO 1 OF
SET
[0] : OF_RD;
[1] : OF_WR;
[OUTRANGE] : 0;
TES);
AC1 = .CHAN_JFN [.CHAN];
IF NOT JSYS_CALL (1, OPENF, AC1, AC2)
THEN
BEGIN !OPENF Failed!!!
ERRMSG (0, 3, ROUTINE_NAME, .FNAME, 0, 0, 0);
CHAN_JFN [.CHAN] = 0;
RETURN 0
END;
END;
1
END; !End of OPEN
GLOBAL ROUTINE CLOSE (CHANX) : NOVALUE = !Close a channel
!++
! FUNCTIONAL DESCRIPTION:
!
! Close a file channel
!
! FORMAL PARAMETERS:
!
! CHANX - the channel to close
!
! IMPLICIT INPUTS:
!
! NONE
!
! IMPLICIT OUTPUTS:
!
! NONE
!
! COMPLETION CODES:
!
! NONE
!
! SIDE EFFECTS:
!
! Minipulation of the OWN data base occurs
!
!--
BEGIN
BIND
ROUTINE_NAME = UPLIT (%ASCIZ'CLOSE');
LOCAL
CHAN,
AC1;
!
! Validate Channel number
!
CHAN = .CHANX;
IF (.CHAN EQL 0)
THEN
ERROR (UPLIT (%ASCIZ'You May Not Close Channel 0 - CLOSE'))
ELSE
IF ((.CHAN LSS 0) OR (.CHAN GTR 15))
THEN
ERROR (UPLIT (%ASCIZ'Invalid Channel Number - CLOSE'))
ELSE
IF (.CHAN_JFN [.CHAN] EQL 0)
THEN
ERROR (UPLIT (%ASCIZ'Channel is not OPEN - CLOSE'))
ELSE
BEGIN
AC1 = .CHAN_JFN [.CHAN];
JSYS_CALL (1, CLOSF, AC1);
CHAN_JFN [.CHAN] = 0;
END;
END; !End of CLOSE
GLOBAL ROUTINE INPUT (CHANX) : = !Read from file
!++
! FUNCTIONAL DESCRIPTION:
!
! Returns the next character (or PDP-11) word from a file.
!
! FORMAL PARAMETERS:
!
! CHANX - the channel number associated with the file
!
! IMPLICIT INPUTS:
!
! NONE
!
! IMPLICIT OUTPUTS:
!
! NONE
!
! ROUTINE VALUE:
!
! The character or word is returned.
! If EOF or an ERROR is reached then -1 is returned.
!
! SIDE EFFECTS:
!
! NONE
!
!--
BEGIN
BIND
ROUTINE_NAME = UPLIT (%ASCIZ'INPUT');
LOCAL
CHAN,
CHAN_CHAR,
AC1,
AC2,
AC3;
!
! Determine whether the channel is for the terminal or a file then
! process accordingly.
!
CHAN = .CHANX;
IF (.CHAN EQL 0)
THEN
BEGIN
IF (.LINE_PTR EQL 0)
THEN
BEGIN
AC3 = 0;
AC2 = RD_TOP + RD_RAI + LEN_LINE_BUFF;
AC1 = CH$PTR (LINE_BUFF);
LINE_STATUS = (IF NOT JSYS_CALL (1, RDTTY, AC1, AC2, AC3) THEN -1 ELSE .AC2);
LINE_PTR = CH$PTR (LINE_BUFF);
LINE_LEN = LEN_LINE_BUFF - (.LINE_STATUS AND %O'777777');
END;
CHAN_CHAR = CH$RCHAR_A (LINE_PTR);
IF ((LINE_LEN = .LINE_LEN - 1) EQL 0) THEN LINE_PTR = 0;
END
ELSE
BEGIN
IF ((.CHAN LSS 0) OR (.CHAN GTR 15))
THEN
BEGIN
ERROR (UPLIT (%ASCIZ'Channel number out of range - INPUT'));
AC1 = 0;
END
ELSE
AC1 = .CHAN_JFN [.CHAN];
IF (.AC1 EQL 0)
THEN
BEGIN
ERROR (UPLIT (%ASCIZ'Channel not OPEN - INPUT'));
RETURN -1
END;
!
! The next section of code either returns the character just read for a
! character mode file or the next byte of a word mode file.
! CHAN_NEXT[.CHAN] is -1 if a new BIN JSYS should be done.
!
IF (.CHAN_NEXT [.CHAN] LSS 0)
THEN
BEGIN
CHAN_CHAR = (IF NOT JSYS_CALL (-1, BIN, AC1, AC2) THEN -1 ELSE .AC2);
IF ((.CHAN_MODE [.CHAN] EQL 2) AND (.CHAN_CHAR GEQ 0))
THEN
BEGIN
CHAN_NEXT [.CHAN] = .CHAN_CHAR<8, 8>; !Next character
CHAN_CHAR = .CHAN_CHAR<0, 8>; !Current Character
END;
END
ELSE
BEGIN !The second byte of the word
CHAN_CHAR = .CHAN_NEXT [.CHAN]; !The character to return
CHAN_NEXT [.CHAN] = -1;
END;
END;
.CHAN_CHAR
END; !End of INPUT
GLOBAL ROUTINE OUTPUT (CHANX, OUTWRD) : NOVALUE = !Output to a file
!++
! FUNCTIONAL DESCRIPTION:
!
! Output a byte or word to a file.
!
! FORMAL PARAMETERS:
!
! CHANX - the channel number
! OUTWRD - the byte or word to output
!
! IMPLICIT INPUTS:
!
! NONE
!
! IMPLICIT OUTPUTS:
!
! NONE
!
! COMPLETION CODES:
!
! NONE
!
! SIDE EFFECTS:
!
! NONE
!
!--
BEGIN
BIND
ROUTINE_NAME = UPLIT (%ASCIZ'OUTPUT');
LOCAL
CHAN,
AC1,
AC2;
!
! Determine whether the channel is for the terminal or a file then
! process accordingly.
!
CHAN = .CHANX;
IF (.CHAN EQL 0)
THEN
AC1 = $PRIOU !For Primary OUTPUT media
ELSE
IF ((.CHAN LSS 0) OR (.CHAN GTR 15))
THEN
BEGIN
ERROR (UPLIT (%ASCIZ'Channel number out of range - OUTPUT'));
AC1 = 0
END
ELSE
AC1 = .CHAN_JFN [.CHAN];
IF (.AC1 EQL 0)
THEN
BEGIN
ERROR (UPLIT (%ASCIZ'Channel not OPEN - OUTPUT'));
RETURN
END;
!
! The following code either outputs a character immediately in
! character mode or waits for two bytes in word mode.
!
IF ((.CHAN_NEXT [.CHAN] LSS 0) OR (.CHAN EQL 0))
THEN
IF (.CHAN_MODE [.CHAN] EQL 2)
THEN
CHAN_NEXT [.CHAN] = .OUTWRD<0, 8> !First Byte of word
ELSE
BEGIN
AC2 = .OUTWRD;
JSYS_CALL (0, BOUT, AC1, AC2);
END
ELSE
BEGIN
AC2 = ((.OUTWRD<0, 8>)^8) + .CHAN_NEXT [.CHAN];
JSYS_CALL (0, BOUT, AC1, AC2);
CHAN_NEXT [.CHAN] = -1;
END;
END; !End of OUTPUT
GLOBAL ROUTINE STOP_PROGRAM : NOVALUE = !Terminate execution
!++
! FUNCTIONAL DESCRIPTION:
!
! Terminates the program. Usually used to stop program when some
! abnormal condition occurs.
!
! FORMAL PARAMETERS:
!
! NONE
!
! IMPLICIT INPUTS:
!
! NONE
!
! IMPLICIT OUTPUTS:
!
! NONE
!
! COMPLETION CODES:
!
! NONE
!
! SIDE EFFECTS:
!
! The program is halted.
!
!--
BEGIN
BIND
ROUTINE_NAME = UPLIT (%ASCIZ'STOP_PROGRAM');
JSYS_CALL (0, HALTF);
END; !of RESET_ALL
END !End of module
ELUDOM
! Local Modes:
! Comment Column:36
! Comment Start:!
! Auto Save Mode:2
! Mode:Fundamental
! End: