  Introduction to Byte-Oriented File Input/Output Routines
 Byte-Oriented IO File Open   - Fxn$OPEN
 Byte-Oriented IO File Close  - Fxn$CLOSE
 Byte-Oriented Input/Output   - Fn$GET, Fn$PUT
  Error Return Codes
  Byte-Oriented File I/O Routines with Variable Buffers
 Input and Output File Open   - FXx$OPEN
 Input and Output File Close  - FXx$CLOSE
 Input and Output             - FX$GET, FX$PUT
  Byte-Oriented File I/O Routines with Variable Buffers and UNGET
 Input and Output File Open   - FYx$OPEN
 Input and Output File Close  - FYx$CLOSE
 Input, Unget, and Output     - FY$GET/FY$UNGET/FY$PUT
:        Byte-Oriented File Input/Output Routines 

The following documentation covers the series of byte-oriented
file input/output routines in SYSLIB.  These routines allow you
to sequentially read from (GET) and write to (PUT) a file on a
byte-for-byte basis.  Hence, these routines provide an exception-
ally simple method for handling input from and output to a file.

A typical program which employs these routines must open the
required files before doing any processing, must then perform
the processing on the opened files, and must then close the
files when the processing is complete (closing the files is
optional for input files and mandatory for output files).


SYSLIB provides four sets of routines for byte-oriented file
input and output.  These routines are --

Input Open  Output Open    GET    PUT   Input Close  Output Close
----------  -----------    ---    ---   -----------  ------------
 FI0$OPEN    FO0$OPEN    F0$GET  F0$PUT  FI0$CLOSE    FO0$CLOSE
 FI1$OPEN    FO1$OPEN    F1$GET  F1$PUT  FI1$CLOSE    FO1$CLOSE
 FI2$OPEN    FO2$OPEN    F2$GET  F2$PUT  FI2$CLOSE    FO2$CLOSE
 FI3$OPEN    FO3$OPEN    F3$GET  F3$PUT  FI3$CLOSE    FO3$CLOSE


This system allows the user to have up to 8 files open simul-
taneously -- four are open for input using GET and four are
open for output using PUT.  For example, the following is a
sample code section using these routines for two files:


	EXT	FI0$OPEN	; Declare Library references
	EXT	FO0$OPEN
	EXT	FI0$CLOSE
	EXT	FO0$CLOSE
	EXT	F0$GET
	EXT	F0$PUT
	...
	LD	DE,FCBI		; Pt to FCB of Input File
	CALL	FI0$OPEN
	LD	DE,FCBO		; Pt to FCB of Output File
	CALL	FO0$OPEN
	...
	  [body containing CALL F0$GET and CALL F0$PUT]
	...
	CALL	FI0$CLOSE	; Close File
	CALL	FO0$CLOSE
	...
	END


Note that only the routines to be used are referenced in the
EXT statements.  If you do not need a particular routine, do
not reference it.  Not referencing an unneeded routine usually
saves the overhead memory space of loading it from the library.

Each set of INPUT OPEN, INPUT CLOSE, OUTPUT OPEN, OUTPUT CLOSE,
GET, and PUT routines is contained in one library module, so
referencing any of these routines causes the entire module to
be loaded, and all the routines are accessable to the user
(provided they are mentioned in the external definitions) with-
out any additional memory overhead.  Specifically, FI0$OPEN,
FI0$CLOSE, FO0$OPEN, FO0$CLOSE, F0$GET, and F0$PUT are contained
in one module, and reference to any of these routines loads the
entire module; the same is true for the other sets of routines.


The CLOSE routine for output (FOn$CLOSE) is ALWAYS required; it
fills the rest of the current block with Ctrl-Z followed by
<NULL> bytes and properly closes file.  The CLOSE routine for
input (FIn$CLOSE) is required ONLY IF you are going to later
open another file for input using the corresponding OPEN routine
(FIn$OPEN).  FIn$CLOSE only serves to reset the OPEN flag (used
to GET to ascertain that the file has been properly opened).

:FI0$OPEN, FI1$OPEN, FI2$OPEN, FI3$OPEN - Open File for Byte Input
 FO0$OPEN, FO1$OPEN, FO2$OPEN, FO3$OPEN - Open File for Byte Output

  ENTER: DE = Address of FCB of file to Open
  EXIT :  A = 0, Zero Flag Set (Z) if Open Successful
              A = Error Code, Zero Flag Clear (NZ) if Error
  USES : AF

 Usage:  These routines is used to open the specified file for
  Input (use with F$GET), and Output (use with F$PUT).  They
  initialize the FCB fields, so further initialization is not
  necessary.  The output Open functions also create the
  indicated file if it does not already exist.

:FI0$CLOSE, FI1$CLOSE, FI2$CLOSE, FI3$CLOSE - Close Byte Input File
 FO0$CLOSE, FO1$CLOSE, FO2$CLOSE, FO3$CLOSE - Close Byte Output File

  ENTER: - None
  EXIT :  A = 0, Zero Flag Set (Z) if Close Successful
              A = Error Code, Zero Flag Clear (NZ) if Error
  USES : AF

 Usage:  These routines are used to close files previously
  opened by the corresponding FI$OPEN or FO$OPEN routines.
  While closing an input file is optional if another file will
  not be opened later by the corresponding FI$OPEN routine, it
  is poor programming practice which may cause problems in more
  advanced operating systems.  Closing output files is MANDATORY
  if you want to retain the file.

:F0$GET, F1$GET, F2$GET, F3$GET - Get next byte from Input File
 F0$PUT, F1$PUT, F2$PUT, F3$PUT - Put a byte to Output File

  ENTER: (GET) - None
         (PUT) A = Byte to add to file
  EXIT : (GET) A = Byte from File, Zero Set (Z) if Ok
                   A = Error Code, Zero Clear (NZ) if Error
         (PUT) A = 0, Zero Flag Set (Z) if Ok
                   A = Error Code, Zero Clear (NZ) if Error
  USES : AF

 Usage:  These routines Get or Put a byte to/from the file
  specified in the corresponding Fn$OPEN routine.

:                   Error Return Codes 

For each of the routines in this set of byte-oriented file
I/O routines, the Zero Flag and the A Register play a key role
in indicating the error conditions of the routines.

If the Zero Flag is Set (Z) after a routine has been executed,
then this indicates that no error has occurred.  The A Register
is either unaffected (in most cases) or contains a returned
value (if so indicated, as in Fn$GET routines).

If the Zero Flag is Clear (NZ) after a routine has been
executed, then this indicates that an error has occurred.  The A
Register now contains the Error Code.  The following screen
display summarizes the Error Codes.


                   Summary of Error Codes
        Returned by Byte-Oriented File I/O Routines

     Code Meaning
     ---- -------

       1  GET or PUT attempted on an unopened file
       2  Disk Full (Ran out of space)
       3  Input File Not Found
       4  Attempt to Read Past EOF
       5  Directory Full
       6  Error in Closing a File
       7  Attempt to Open a File which is already Open

:      Byte-Oriented File I/O with Variable Buffers 

In addition to the routines mentioned previously, a set of
byte-oriented file I/O routines is available under SYSLIB 3
which permits the user to define the size and location of the
buffers to be used.  The routines mentioned above all use 128-
byte buffers, and, on larger capacity disk systems (and on any
systems in general), it may be more efficient to buffer more
than 128 bytes at a time.  This will cut down on disk activity
and leave more memory-based processing overhead.  The routines
described in this section are:

   Routine      Function
   -------      --------
   FXI$OPEN     Open File for Input   (similar to FIn$OPEN)
   FXO$OPEN     Open File for Output  (similar to FOn$OPEN)
   FXI$CLOSE    Close Input File      (similar to FIn$CLOSE)
   FXO$CLOSE    Close Output File     (similar to FOn$CLOSE)
   FX$GET       Get a Byte            (similar to Fn$GET)
   FX$PUT       Put a Byte            (similar to Fn$PUT)

  All of the File Extended Byte I/O Routines (FX means File
Extended) work with an I/O Control Block which is structured as:

Block     Length    User-
Offset    (Bytes)   Set?*     Function
------    -------   -----     --------
   0         1        Y       Number of 128-Byte Pages in
                                   Working Buffer
   1         1        N       End of File Flag
   2         2        N       Byte Counter
   4         2        N       Next Byte Pointer
   6         2        Y       Address of Working Buffer
   8        36        Y       FCB of File (Only FN and FT
                                   Fields Set by User)


  * "User-Set" means that you must initialize this
    value before these routines are called.

  The following DEFB/DEFS structure can be used in the calling
program to implement the I/O Control Block:

 IOCTL:	DEFB	8		; Use 8 128-Byte Pages (1K)
	DEFS	1		; Filled in by FXIO
	DEFS	2		; Filled in by FXIO
	DEFS	2		; Filled in by FXIO
	DEFW	WORK		; Address of Working Buffer
 IOCFCB:
	DEFS	1		; Filled in by FXIO to 0
	DEFB	'MYFILE  '	; File Name
	DEFB	'TXT'		; File Type
	DEFS	24		; Filled in by FXIO
 WORK:	DEFS	128*8		; Working Buffer (1K)

  All of the FXIO routines are consistent in that DE always
points to the I/O Control Block (IOCTL above) and A and the PSW
are used to pass flags and values.  A sample program body which
illustrates the calling procedures:

	...
   < Init IOCTL1 and IOCTL2, where 1 is input, 2 is output>
	...
	LD	DE,IOCTL1
	CALL	FXI$OPEN	; Open 1 for Input
	JR	Z,FNF		; File Not Found Error
	LD	DE,IOCTL2
	CALL	FXO$OPEN	; Open 2 for Output
	JR	Z,NODIR		; No Dir Space Error
	...


	...
	LD	DE,IOCTL1
	CALL	FX$GET		; Get Next Input Byte in A
	JR	Z,EOF		; Process EOF
	...
	LD	DE,IOCTL2
	CALL	FX$PUT		; Put Byte in A to Output File
	JR	Z,WERR		; Process Write Error
	...
	LD	DE,IOCTL1
	CALL	FXI$CLOSE	; Close Input File
	JR	Z,FCERR		; File Close Error
	LD	DE,IOCTL2
	CALL	FXO$CLOSE	; Close Output File
	JR	Z,FCERR
          ...


This simple example illustrates the flexibility of the FXIO
routines.  As many files as desired may be open for input or
output, each file having its own I/O Control Block and Working
Buffer.  The advantages in efficient disk accessing with this
set of routines over the previous ones are notable.

The major disadvantage of using these routines is that the
buffers are larger and the overhead of always ensuring that DE
points to the proper I/O Control Block before each routine is
called is present.

:FXI$OPEN, FXO$OPEN - Open File for Input/Output

  ENTER: DE = Address of I/O Control Block of file to Open
  EXIT :  A <> 0, Zero Flag Clear (NZ) if Ok
              A = 0, Zero Flag Set (Z) if Error
  USES : AF

 Usage:  Open the file specified by the addressed I/O Control
  Block for Input (FXI$OPEN) or Output (FXO$OPEN).  FXI$OPEN
  opens the file in the current directory after initializing the
  FCB and loads as much of the buffer space as possible with
  data from the file.  If the file does not exist, FXI$OPEN
  returns an error code.  FXO$OPEN deletes the file referenced
  by the FCB if it exists and opens the referenced file for
  output.  If there is no directory space remaining in which to
  store the file's entry, FXO$OPEN returns an error code.

  The FXIO standard error return codes are used.  A=0 and Zero
  Flag Set (Z) if error.

:FXI$CLOSE, FXO$CLOSE - File Close Routines

  ENTER: DE = Address of an I/O Control Block
  EXIT :  A <> 0, Zero Flag Clear (NZ) if Ok
              A = 0, Zero Flag Set (Z) if Close Error
  USES : AF

 Usage:  These routines are used to close the file whose I/O
  Control Block is addressed by DE.  FXI$CLOSE simply closes
  the file, while FXO$CLOSE flushes the working buffer to disk,
  filling the last 128-byte block with ^Z's if not completely
  filled already, and closes the file on disk.

  The FXIO standard error return codes are used with A=0 and
  the Zero Flag Set (Z) if an Error occured.

:FX$GET, FX$PUT - Byte Input and Output Routines

  ENTER: (GET) - None
         (PUT) A = Byte to Output to specified file
  EXIT : (GET) A = Next byte from file, Zero Clear (NZ) if No Error
                   A = 0, Zero Flag Set (Z) if Read Past EOF
         (PUT) A = Output Byte, Zero Clear (NZ) if Put Ok
                   A = 0, Zero Flag Set if Write Error
  USES : AF

 Usage:  FX$GET gets the next byte from the file whose I/O
  Control Block is pointed to by DE.  FX$PUT puts the specified
  byte into the file specified in the I/O Control Block.  The
  respective Open function (FXI$OPEN or FXO$OPEN) must have been
  called before any call to FX$GET or FX$PUT respectively.

:   Byte-Oriented File I/O with Variable Buffers and UNGET 

In addition to the FX routines covered in the previous section
are the FY routines.  For only a slight increase in memory
requirements, the FY prefix routines provide the same functions
as the FX routines and add the UNGET function.

FY$UNGET sets the next character to be returned by FY$GET.  Only
one character ahead can be set.  This function is extremely
useful in applications which read and parse an input file in a
single pass.  Often the end of a token is detected only when the
character after the token is picked up and examined.  FY$UNGET
allows you to put this character back, so that the next FY$GET
picks it up and can process it in its own right as opposed to
being a part of the token processing routine.


Aside from the new FY$UNGET function, FY prefix routines provide
the same functions as the FX prefix routines.  The I/O Control
Block for the FY routines, however, is two bytes larger than the
IOCB for the FX routines.

The routines described in this section are:

       Routine     Similar to    Function
       -------     ----------    --------
       FYI$OPEN    FXI$OPEN      Open File for Input
       FYO$OPEN    FXO$OPEN      Open File for Output
       FYI$CLOSE   FXI$CLOSE     Close Input File
       FYO$CLOSE   FXO$CLOSE     Close Output File
       FY$GET      FX$GET        Get Byte
       FY$UNGET                  Unget Byte
       FY$PUT      FX$PUT        Put Byte

  All of the File Extended Byte I/O Routines (FY means File
Extended beyond FX) work with an I/O Control Block structured as:

 Block     Length    User-
 Offset    (Bytes)   Set?*     Function
 ------    -------   -----     --------
    0         1        Y       Number of 128-Byte Pages in
                                   Working Buffer
    1         1        N       End of File Flag
    2         2        N       Byte Counter
    4         2        N       Next Byte Pointer
    6         1        N       Character Pending Flag
    7         1        N       Pending Character
    8         2        Y       Address of Working Buffer
   10        36        Y       FCB of File (Only FN and FT
                                   Fields Set by User)

  * "User-Set" means that you must initialize this
    value before these routines are called.


The following DEFB/DEFS structure can be used in the calling
program to implement the I/O Control Block:

 IOCTL:	DEFB	8		; Use 8 128-Byte Pages (1K)
	DEFS	7		; Filled in by FYIO
	DEFW	WORK		; Address of Working Buffer
 IOCFCB:
	DEFS	1		; Filled in by FYIO to 0
	DEFB	'MYFILE  '	; File Name
	DEFB	'TXT'		; File Type
	DEFS	24		; Filled in by FYIO
 WORK:	DEFS	128*8		; Working Buffer (1K)


All of the FYIO routines are consistent in that DE always points
to the I/O Control Block (IOCTL above) and A and the PSW are
used to pass flags and values.  A sample program body which
illustrates the calling procedures:

	...
   < Init IOCTL1 and IOCTL2, where 1 is input, 2 is output>
	...
	LD	D,IOCTL1
	CALL	FYI$OPEN	; Open 1 for Input
	JR	Z,FNF		; ..jump if File Not Found Err
	LD	D,IOCTL2
	CALL	FYO$OPEN	; Open 2 for Output
	JR	Z,NODIR		; ..jump if No Dir Space Error
	...

	...
	LD	D,IOCTL1
	CALL	FY$GET		; Get Next Input Byte in A
	JR	Z,EOF		; ..jump to Process EOF
	...
	LD	D,IOCTL1
	LD	A,CH		; Unget character CH
	CALL	FY$UNGET
	...
	LD	D,IOCTL2
	CALL	FY$PUT		; Put Byte in A to Output File
	JR	Z,WERR		; ..jump to Process Write Error
	...
	LD	D,IOCTL1
	CALL	FYI$CLOSE	; Close Input File
	JR	Z,FCERR		; ..jump if File Close Error
	LD	D,IOCTL2
	CALL	FYO$CLOSE	; Close Output File
	JR	Z,FCERR		; ..jump if error
	...

This simple example illustrates the flexibility of the FYIO
routines.  As many files as desired may be open for input or
output, each file having its own I/O Control Block and Working
Buffer.  The advantages in efficient disk accessing with this set
of routines over the previous ones are notable.

The major disadvantage of using these routines is that the
buffers are larger and the overhead of always ensuring that DE
points to the proper I/O Control Block before each routine is
called is present.

:FYI$OPEN, FYO$OPEN - FYIO Open Routines

  ENTER: DE = Pointer to I/O Control Block of file to Open
  EXIT :  A <> 0, Zero Flag Clear (NZ) if Ok
              A = 0, Zero Flag Set (Z) if Error
  USES : AF

 Usage:  These routines are used to open files for subsequent
  processing by other FY-prefix routines.  FYI$OPEN opens the
  file in the current directory after initializing the FCB and
  loads as much of the buffer space as possible with data from
  the file.  If the file does not exist, FYI$OPEN returns an
  error code.  FYO$OPEN deletes the file referenced by the FCB
  if it exists and opens the referenced file for output.  If
  there is no directory space remaining in which to store the
  file's entry, FYO$OPEN returns an error code.

:FYI$CLOSE, FYO$CLOSE - FYIO File Close Routines

  ENTER: DE = Pointer to I/O Control Block
  EXIT : A <> 0, Zero Flag Clear (NZ) if Ok
             A = 0, Zero Flag Set (Z) if Close Error
  USES : AF

 Usage:  These routines are used to close files opened by the
  respective FY-prefix Open routines.  FYI$CLOSE simply closes
  the file.  FYO$CLOSE flushes the working buffer to disk,
  filling the last 128-byte block with Control-Z characters if
  not completely filled already, and closes the file.

:FY$GET, FY$UNGET, FY$PUT - FYIO Input, Unget, and Output Routines

  ENTER: (GET) - None
         (PUT) A = Byte to Output
       (UNGET) A = Byte to "Unget"
  EXIT : (GET) A = Next byte, Zero Clear (NZ) if No Error
                   A = 0, Zero Flag Set (Z) if past EOF
         (PUT) A = Character, Zero Flag Clear (NZ) if Ok
                   A = 0, Zero Flag Set (Z) if Write Error
       (UNGET) A = Character, Zero Flag Clear (NZ) if Ok
                   A = Char, Zero Set (Z) if Byte Pending Already
  USES : AF

 Usage:  These routines are used to read or change the contents
  of files opened by appropriate FY-prefix Open routines. FY$GET
  gets the next byte from the specified file.  FY$PUT puts the
  next byte into the specified file.  FYI$OPEN and or FYO$OPEN
  must have been called before any call to FY$GET or FY$PUT
  respectively.


  FY$UNGET is used to set the next byte to be returned by FY$GET.
  FY$UNGET may only be called once before the next FY$GET, since
  it works only one byte ahead.  If a byte was already pending,
  FY$UNGET returns an error code with no UNGET function.  A call
  to FYI$OPEN is required before FY$UNGET can be used.  
