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 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.