Trailing-Edge
-
PDP-10 Archives
-
bb-j939f-bm
-
bliss/ezio20.b36
There are 3 other files named ezio20.b36 in the archive. Click here to see a list.
MODULE EZIO20 ( ! Provides basic file I/O to BLISS-36 programs
! running on TOPS-20
ENVIRONMENT (BLISS36C_OTS) ,
LINKAGE (BLISS36C) ,
IDENT = '7'
) =
!<BLF/MACRO>
!<BLF/UPPERCASE_KEY>
!<BLF/LOWERCASE_USER>
!<BLF/WIDTH:80>
BEGIN
!
! COPYRIGHT (c) 1978 BY
! DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
!
! 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.
!
!++
! Functional Description:
! This module declares the routines to Open, Close, Read and
! write files. The functionality provided is very basic and is intended
! only to be transportable and easy to use.
! Its counterparts on other Operating Systems are EZIO10 (TOPS-10),
! EZIO11 (RMS-11), EZIO32 (RMS-32), and EZIOFC (FCS-11).
! This module has a counter part (EZIO20) that runs under BLS36C in
! the field. This module is setup for the BLS36C calling sequence, and uses
! the BLISS-36 compiler BUILTIN JSYS. It is very dependent upon the BLISS-36
! compiler (it won't compile under BLS36C).
!
! Environment: User mode
!
! Author: Bruce Dawson, Creation Date: 16-Nov-77
!
! Modified by:
! Who, date - resultant version
! edit - explaination
! Bruce Dawson, November 21, 1977 - still version 1
! 1 - Problems when outputting a string of length 0. FILOUT affected.
! 2 - FILIN: Cleaned up ACx usage after RDTTY.
! Bruce Dawson, 30-June-78 - version 1A
! 3 - Declarations: SUCCESS changed from -1 to 1
! Bruce Dawson, 5-July-78
! 4 - FILIN: Stand-alone LF messing things up. Created the RETURN_SIZE
! macro.
! 5 - FILIN: RDTTY breaks on first character instead of waiting for next
! (possibly editing) character. Gave it 3 characters minimum.
! 6 - FILIN: If the last line of the file did not have CRLF after it,
! then it was not properly returned. It is now.
! 7 - Module Prolog, FILOPN, FILIN, FILOUT. Added (for 2nd time) the
! MAXCHANS parameter.
!--
!
! Table of Contents:
!
FORWARD ROUTINE
filopn, ! Opens a file on a channel.
filcls, ! Closes a file opened on a channel.
filin, ! Reads from a channel.
filout; ! Writes onto a channel.
!
! Macros:
!
MACRO
fld$who =
0, 18, 18, 0 %, ! Who failed.
fld$cod =
0, 0, 18, 0 %, ! ERROR CODE.
fld$lh =
0, 18, 18, 0 %,
fld$rh =
0, 0, 18, 0 %,
fld$of_bsz =
0, 30, 6, 0 %, ! Byte size
fld$of_mod =
0, 26, 3, 0 %, ! Data mode.
fld$of_rd =
0, 16, 1, 0 %, ! Read access
fld$of_wr =
0, 15, 1, 0 %, ! Write access
fld$of_ex =
0, 14, 1, 0 %, ! Execute access
fld$of_app =
0, 13, 1, 0 %, ! Append access
fld$gj_sht =
0, 18, 1, 0 %,
fld$gj_new =
0, 34, 1, 0 %,
fld$gj_fou =
0, 35, 1, 0 %,
fld$gj_old =
0, 33, 1, 0 %,
fld$rd_bel =
0, 32, 1, 0 %, ! Break at EOL
fld$gs_eof =
0, 27, 1, 0 %, ! Read past EOF.
fld$rd_btm =
0, 23, 1, 0 %; ! Break character terminated input.
MACRO ! CROCKS
jsys_crock (typ, fun, a1, a2, a3, a4) =
BEGIN
REGISTER
rac1 = 1,
rac2 = 2,
rac3 = 3,
rac4 = 4;
BUILTIN
jsys;
LOCAL
val;
%IF NOT %NULL (a1)
%THEN
rac1 = .a1;
%FI
%IF NOT %NULL (a2)
%THEN
rac2 = .a2;
%FI
%IF NOT %NULL (a3)
%THEN
rac3 = .a3;
%FI
%IF NOT %NULL (a4)
%THEN
rac4 = .a4;
%FI
val = jsys (typ, fun, rac1, rac2, rac3, rac4);
%IF NOT %NULL (a1)
%THEN
%IF %DECLARED (a1)
%THEN
a1 = .rac1;
%FI
%FI
%IF NOT %NULL (a2)
%THEN
%IF %DECLARED (a2)
%THEN
a2 = .rac2;
%FI
%FI
%IF NOT %NULL (a3)
%THEN
%IF %DECLARED (a3)
%THEN
a3 = .rac3;
%FI
%FI
%IF NOT %NULL (a4)
%THEN
%IF %DECLARED (a4)
%THEN
a4 = .rac4;
%FI
%FI
.val
END %;
!
! Equated Symbols:
!
LITERAL
maxchans = 3, ! Maximum number of channels (biased at 0)
success = 1, ! Return to call successfully completed.
failure = 0, ! Return to caller after an error.
myspacesize = 1000; ! Number of bytes in my buffer
LITERAL ! JSYS definitions
gtjfn = %O'20', ! Get a JFN
openf = %O'21', ! Open a file
closf = %O'22', ! Close a JFN
gtsts = %O'24', ! Get JFN status
rdtty = %O'523', ! Read from TTY
sin = %O'52', ! String input.
sout = %O'53', ! String output
psout = %O'76'; ! String output to TTY:
!
! OWN storage
!
OWN
chan_tab : VECTOR [maxchans] INITIAL(REP maxchans OF (0)),
! Table of JFNs for each channel opened.
error : BLOCK [1], ! Has error on a JSYS failure. Not of use yet,
crlf : VECTOR [CH$ALLOCATION (2)] INITIAL(%CHAR (%O'15', %O'12')),
! A string with CRLF in it.
space : VECTOR [CH$ALLOCATION(myspacesize)]; ! Workspace.
GLOBAL ROUTINE filopn (channel, num_chars, filespec, direction) =
! Open a file
!++
! Functional Description:
! This routine Opens a file for either Input or Output on the
! specified channel. If it fails (syntax error in file name, non-
! existant file on input, etc...), the routine returns 0 (False).
! Otherwise it returns a nonzero value.
!
! Formal Parameters:
! CHANNEL: A number between -1 and 2. Subsequent I/O to the file
! must specify this channel number. (-1 means the TTY:)
! NUM_CHARS: The number of ASCII bytes in the filename.
! FILESPEC: A BLISS-36 character pointer pointing to the first
! character of the filename.
! DIRECTION: If 1 then the file will be opened for WRITE access.
! Otherwise it will be opened for reading.
!
! Implicit Inputs:
! CHAN_TAB: Contains the JFN for the respective channel.
!
! Implicit Outputs:
! CHAN_TAB: If a file was successfully opened, then contains the
! JFN for that file on this channel.
! ERROR: If any JSYS fails, then this contains the failing JSYS
! and the error returned by the JSYS.
!
! Completion Codes:
! 0 = Could not open file.
! #0 = File opened.
!
! Side effects:
! OWN variable SPACE is used to hold the filespec in ASCIZ
! format.
!--
BEGIN
LOCAL
ac1 : BLOCK [1], ! Parameter for JSYS
ac2 : BLOCK [1]; ! Parameter for JSYS
IF .channel GTR maxchans - 1
THEN RETURN failure;
IF .channel EQL -1
THEN ! TTY I/O always works, therefore always return
RETURN success;
IF .chan_tab [.channel] NEQ 0
THEN ! Channel already opened.
BEGIN
error = 0; ! Indicate "nonsense call" error.
RETURN failure; ! Chastise caller.
END;
CH$MOVE (.num_chars, .filespec, CH$PTR (space));
! Move caller's filespec to my work space
CH$WCHAR (0, CH$PLUS (CH$PTR (space), .num_chars)); ! Make it ASCIZ
ac1 = 0; ! Clear AC1 first
ac1 [fld$gj_sht] = 1; ! Short form for defaulting
IF .direction EQL 1 ! Writing
THEN
BEGIN
ac1 [fld$gj_fou] = 1; ! New generation number
ac1 [fld$gj_new] = 1;
END
ELSE
BEGIN
ac1 [fld$gj_old] = 1;
END;
ac2 = CH$PTR (space);
IF jsys_crock (1, gtjfn, ac1, ac2)
THEN
chan_tab [.channel] = .ac1 [fld$rh]
! Set channel to open on successful monitor return
ELSE
BEGIN ! JSYS failed.
error [fld$who] = gtjfn;
error [fld$cod] = .ac1;
RETURN failure; ! Tell caller.
END;
ac1 = .chan_tab [.channel]; ! Get JFN.
ac2 = 0;
ac2 [fld$of_bsz] = 7; ! Byte size is 7 bits for ASCII
ac2 [fld$of_mod] = 0; ! Mode is zero for text file.
! Set proper bits for reading or writing.
IF .direction EQL 1
THEN
ac2 [fld$of_wr] = 1
ELSE
ac2 [fld$of_rd] = 1;
IF jsys_crock (1, openf, ac1, ac2)
THEN
RETURN success ! OPENF worked. Channel is now available for use.
ELSE
BEGIN ! OPENF failed.
error [fld$who] = openf;
error [fld$cod] = .ac1;
RETURN failure; ! Tell user.
END;
END;
GLOBAL ROUTINE filcls (channel) =
! Close the file on the specified channel.
!++
! Functional Description:
! This routine closes the file opened on the specified channel.
!
! Formal Parameters:
! CHANNEL: A number between -1 and 2 specifing the channel to close.
!
! Implicit Inputs:
! CHAN_TAB: If the respective entry for the channel already has a
! zero, then this indicates that the channel has already been
! closed (or never opened). An error return is given to tell
! the user that the call was nonsense.
!
! Implicit Outputs:
! CHAN_TAB: The respective entry for the channel is made zero to
! indicate the channel is closed.
! ERROR: If an error was encountered, then this is changed to indicate
! who caused the error, and what the error was.
!
! Completion Codes:
! 0 = Nonsense call or JSYS failure.
! #0 = Successful return.
!
! Side effects: None
!--
!
BEGIN
LOCAL
ac1 : BLOCK [1]; ! Parameter for JSYS
IF .channel GTR maxchans - 1
THEN RETURN failure;
IF .channel EQL -1
THEN
RETURN success; ! Don't worry about TTY:
IF .chan_tab [.channel] EQL 0
THEN
BEGIN ! Nonsense call.
error = 0; ! Inform caller of such.
RETURN failure;
END;
ac1 = .chan_tab [.channel]; ! Get JFN
IF NOT jsys_crock (1, closf, ac1)
THEN
BEGIN ! CLOSF JSYS failed.
error [fld$who] = closf; ! Indicate which JSYS failed;
error [fld$cod] = .ac1; ! And save error code
RETURN failure; ! Inform caller.
END;
chan_tab [.channel] = 0;
RETURN success;
END;
GLOBAL ROUTINE filin (channel, bufsiz, pointer) =
! Read from the channel.
!++
! Functional Description:
! This routine reads data from the specified channel and
! deposits it in the specified string. Data transfer stops if
! CRLF is encountered or if the string is filled.
! Returns the number of characters transefered to the string,
! (0 characters means a null line), or -1 for EOF.
! The CRLF is trimmed from the returned string. Line numbers are
! ignored (won't appear in the string).
!
! Formal Parameters:
! CHANNEL: A number between -1 and 2 specifiing the channel from
! which to read from.
! BUFSIZ: The maximum number of characters to transfer to the string.
! POINTER: A BLISS-36 character pointer pointing to the string to
! which data is to be transfered.
!
! Implicit Inputs:
! CHAN_TAB: Used to determine the JFN for the respective channel.
!
! Implicit Outputs:
! ERROR: If an error occurs, then ERROR si changed to indicate who
! caused the error and what the error was.
!
! Condition Codes:
! Routine Value:
! -1 if EOF encountered.
! -2 if an error happened.
! >=0 if data was successfully transfered.
!
! Side Effects: None
!--
BEGIN
LOCAL
ac1 : BLOCK [1], ! Parameter for JSYS
ac2 : BLOCK [1], ! Parameter for JSYS
ac3 : BLOCK [1], ! Parameter for JSYS
ac4 : BLOCK [1]; ! Parameter for JSYS
LOCAL
len, ! Number of characters left in buffer
updptr; ! Updated string pointer from SIN
MACRO
return_size = ! Return the size of the string
IF CH$RCHAR (CH$PLUS (.updptr, -2)) LEQ %O'15'
AND CH$RCHAR (CH$PLUS (.updptr, -2)) GEQ %O'13'
! See if line terminator or full buffer
THEN
RETURN MAX (.bufsiz - .len - 2, 0)
! Effectively remove CRLF by returning shorter length
ELSE
IF .len EQL 0
THEN RETURN .bufsiz ! Full buffer
! WARNING*** This MUST be the last line of the macro, and can't have a ";"
ELSE RETURN .bufsiz - .len - 1 ! Everything up to LF
%;
IF .channel GTR maxchans - 1
THEN RETURN failure;
IF .channel EQL -1
THEN ! Read from TTY:
BEGIN
ac1 = CH$PTR (space); ! Point to buffer
ac2 = 0;
ac2 [fld$rd_bel] = 1; ! Set Break On End Of Line
ac2 [fld$rh] = MAX (.bufsiz+2, myspacesize); ! Set max size of string
ac3 = 0; ! No prompting
IF jsys_crock (1, rdtty, ac1, ac2, ac3)
! Use RDTTY so user can edit input.
THEN
BEGIN
!
! Return length of input string.
!
ROUTINE acutalsize (len, updptr, bufsiz) =
return_size;
LOCAL
len;
len = acutalsize (.ac2[fld$rh], .ac1, myspacesize);
CH$MOVE (.len, CH$PTR (space), .pointer);
RETURN .len;
END
ELSE
BEGIN ! RDTTY Failed.
error [fld$who] = rdtty;
error [fld$cod] = .ac1;
RETURN -2; ! Inform caller.
END;
END;
!
! Got here if NOT reading from TTY:.
!
ac1 = .chan_tab [.channel]; ! Get JFN
ac2 = .pointer; ! Get input buffer pointer.
ac3 = .bufsiz; ! Get max. buffer size
ac4 = %O'12'; ! Break on <LF>
IF jsys_crock (-1, sin, ac1, ac2, ac3, ac4)
THEN
BEGIN
len = .AC3;
updptr = .AC2;
return_size;
END
ELSE
BEGIN ! SIN JSYS failed, find out why.
len = .ac3; ! Preserve returned length of string
error [fld$who] = sin; ! Preset who failed.
error [fld$cod] = .ac1; ! Preset why it failed.
ac1 = .chan_tab [.channel]; ! Get JFN
ac2 = 0;
jsys_crock (0, gtsts, ac1, ac2);
! See what monitor thinks of file.
IF .ac2 [fld$gs_eof]
THEN
IF .len EQL .bufsiz ! See if nothing actually read
THEN RETURN -1
ELSE return_size + 1
ELSE RETURN -2; ! Indicate error occurred.
END;
END;
GLOBAL ROUTINE filout (channel, num_chars, pointer) =
! Write data on a channel.
!++
! Functional Description:
! This routine writes data from the specified string to the
! specified channel. A CRLF is appended to the data after output.
! Will return an error (zero) if NUM_CHARS is less than zero,
! or if a JSYS failed.
!
! Formal Parameters:
! CHANNEL: A number between -1 and 2 that specifies the channel which
! output is to occur on.
! NUM_CHARS: The number of characters in the string.
! POINTER: A BLISS-36 character pointer pointing to the string
! from which data is transfered.
!
! Implicit Inputs:
! CHAN_TAB: Used to determine the JFN for the channel.
!
! Implicit Outputs:
! ERROR: If an error occurs, then this will contain who caused the
! error, and the error code.
!
! Completion Codes:
! 0 = Error occured.
! #0 = Data transfer completed without errors.
!
! Side Effects: None
!--
BEGIN
LOCAL
ac1 : BLOCK [1], ! Parameter to JSYS
ac2 : BLOCK [1], ! Parameter to JSYS
ac3 : BLOCK [1], ! Parameter to JSYS
ac4 : BLOCK [1]; ! Parameter to JSYS
IF .channel GTR maxchans - 1
THEN RETURN failure;
IF .num_chars LSS 0 ! Nonsense call check.
THEN
RETURN failure; ! Chastise caller.
IF .channel EQL -1
THEN
BEGIN ! Use PSOUT for TTY.
IF .num_chars GTR 0
THEN
BEGIN
CH$MOVE (.num_chars, .pointer, CH$PTR (space));
! Move his string to my work space
CH$WCHAR (%O'15', CH$PLUS (CH$PTR (space), .num_chars));
! Append CR
CH$WCHAR (%O'12', CH$PLUS (CH$PTR (space), .num_chars + 1));
! And LF
CH$WCHAR (0, CH$PLUS (CH$PTR (space), .num_chars + 2));
! Make the whole thing ASCIZ.
ac1 = CH$PTR (space); ! Set up for monitor call.
END
ELSE
ac1 = CH$PTR (crlf);
IF NOT jsys_crock (-1, psout, ac1)
THEN
BEGIN ! Failed for some reason
error [fld$cod] = psout; ! Record who failed.
error [fld$who] = .ac1; ! Record why.
RETURN failure; ! Inform caller
END
ELSE
RETURN success; ! Done, return to caller.
END;
!
! Got here if NOT writing to TTY:.
!
IF .num_chars GTR 0
THEN
BEGIN
ac1 = .chan_tab [.channel]; ! Get JFN
ac2 = .pointer; ! Get string pointer
ac3 = -.num_chars; ! Get negative number chars in string
ac4 = 0; ! Don't break output.
IF NOT jsys_crock (-1, sout, ac1, ac2, ac3, ac4)
THEN
BEGIN ! Indicate error
error [fld$who] = sout;
error [fld$cod] = .ac1;
RETURN failure;
END;
END;
ac1 = .chan_tab [.channel];
ac2 = CH$PTR (crlf);
ac3 = -2;
ac4 = 0;
IF jsys_crock (-1, sout, ac1, ac2, ac3, ac4)
THEN
RETURN success;
!
! Got here if an error occured above.
!
error [fld$who] = sout;
error [fld$cod] = .ac1;
RETURN failure;
END;
END
ELUDOM