I/O From CSUBs

This chapter covers the types of I/O available for use by CSUBs. It describes simple I/O from a keyboard to a printer, device I/O, the File Access Library and the more complex keyboard and crt I/O procedures and functions that allow you to access the keyboard and crt control and status registers.

Simple Keyboard and Printer I/O

The FS (support for STRING and INTEGER I/O) and MFS (support for REAL I/O) modules in file CSUBLIB contain routines that make it possible for you to do simple I/O from a CSUB. This allows you to input characters from the keyboard and write to the PRINTER IS device. Use Pascal's READ, READLN, WRITE, or WRITELN in the CSUB. Pascal values of type STRING, CHAR, INTEGER, REAL, and PACKED ARRAY OF CHAR can be read and written this way. BOOLEAN and enumerated are not allowed.

STRREAD and STRWRITE are also supported. They behave normally, including support for INTEGER, REAL, BOOLEAN, enumerated, PACKED ARRAY OF CHAR, or STRING values.

The READ, READLN, WRITE, and WRITELN routines behave as they would in BASIC, which is slightly different than in Pascal. For example, when reading a number, BASIC ignores blanks where Pascal treats them as separators. In addition, reads and writes of Pascal INTEGERs are restricted to the range of BASIC INTEGERs. When trying to read or write Pascal INTEGERs outside the range, an INTEGER OVERFLOW error will be reported.

Error Reporting

Error reporting for READ, READLN, WRITE and WRITELN is also different from Pascal. Errors are not reported back to the compiled code, but are escaped from the READ, READLN, WRITE, or WRITELN code. The escape code values can be translated into standard BASIC error numbers. Refer to the "Trapping Errors" section in the "Advanced Topics" chapter for details.

The $IOCHECK$ directive has no effect on READ, READLN, WRITE and WRITELN since errors for these routines are not reported through IORESULT. It is still valid to use $IOCHECK$ for STRREAD and STRWRITE.

Modules to be Included

To bring these routines into the CSUB, it is necessary to include FS and MFS in the first link routine in the GENC stream file which is described in the "Linking the CSUB Elements" section of the "Preparing CSUBs for Use by BASIC" chapter. FS contains routines that do INTEGER and STRING I/O. MFS has routines to do REAL I/O. If MFS is needed, then the module ALLREALS and FS must also be linked to the file.

Other Types of I/O

Device I/O to HPIB and GPIO peripherals is possible using the CSUB I/O Library. Refer to the "Device I/O" section. Some support is also provided for RS-232C interfaces.

Limited file access to disk files is possible using the File Access Library. Refer to the "File Access Library" section.

Additional keyboard and CRT I/O is possible using the KBDCRT module; see the "Keyboard and CRT I/O" section for details.

Device I/O

Device I/O is possible with the CSUB Utility. Previous versions of CSUBs limited I/O to keyboard and screen I/O performed with the Pascal READ, READLN, WRITE, and WRITELN procedures as discussed in the previous section. Most of the Pascal Procedure Library has now been implemented in CSUBs. Device I/O is supported to HPIB and GPIO devices, although the transfer (buffers) capability is not implemented. Limited support is also provided for RS-232C interfaces.

Pascal Procedure Library I/O Procedures

The CSUB I/O Library exports all the routines, types, and variables found in the following Pascal Procedure Library modules:


IODECLARATIONS          GENERAL_0               HPIB_0
IOCOMASM                GENERAL_1               HPIB_1
                        GENERAL_2               HPIB_2
                        GENERAL_3               HPIB_3

GENERAL_4, SERIAL_0, and SERIAL_3 are not supported by the CSUB I/O Library. See this manual's "Introduction" chapter for a brief description of these modules and the Pascal Procedure Library for tutorial and reference information on using these modules. Differences between using these Pascal procedures with the Pascal system and CSUBs are described in the subsequent "Differences Between BASIC/CSUB and Pascal Procedures" table.

NOTE
If you are going to use IODECLARATIONS or GENERAL_0, you must manually pre-link them before using BUILDC because they contain Pascal globals. This is true of any modules you supply which contain Pascal globals.

The structure of the CSUB I/O Library matches that of the Pascal Procedure Library. This allows the user to write an application and debug it using the Pascal Workstation. Once the application has been proven correct under the Pascal workstation, the code file can be linked to the CSUB I/O Library as long as it doesn't try to access and incorrectly use the items noted as "Differences" specified in the following table. No additional coding is necessary before the CSUB generation process (BUILDC) is executed.

IODECLARATIONSGENERAL_0
Differences Between BASIC/CSUB and Pascal Procedures
Module Procedure \ or Function Differences
IOCOMASM BINAND

BINCMP

BINEOR

BINIOR

BIT_SET

No differences.
Internal use only. Declarations, procedures, etc. in this module are used by other I/O modules.
IOSTATUS

IOCONTROL

Only the following registers are supported: HP-IB: IOCONTROL registers 0 thru 3; IOSTATUS registers 0,1, and 3 thru 7. GPIO: IOCONTROL registers 0 thru 3 (only bits 1 and 0 of register 2); IOSTATUS registers 0,1, and 3 thru 5.
GENERAL_1 IOINITIALIZE

IORESET

IOUNINITIALIZE

READCHAR

READWORD

SET_TIMEOUT

WRITECHAR

WRITEWORD

User must call IOINITIALIZE in the CSUB before performing any I/O and IOUNINITIALIZE before exiting the CSUB.
GENERAL_2 READNUMBER

READNUMBERLN

READSTRING

READSTRING_UNTIL

READUNTIL

SKIPFOR

WRITENUMBER

WRITENUMBERLN

WRITESTRING

WRITESTRINGLN

No differences.

HPIB_0HPIB_1HPIB_2
Differences (Continued)
Module Procedure \ or Function Differences
GENERAL_3 IOERROR_MESSAGE Translates Pascal I/O errors into text messages. The text for errors generated by BASIC will be unrecognized Pascal I/O error. This means that ioerror contains a value from 1001 to 31999 which represents a BASIC error escape (use ioerror MOD 1000 to obtain the corresponding BASIC error
CLEAR_HPIB

HPIB_LINE

SET_HPIB

No differences.
END_SET

MY_ADDRESS

SEND_COMMAND

SYSTEM_CONTROLLER

No differences.
ABORT_HPIB

CLEAR

LISTEN

LOCAL

LOCAL_LOCKOUT

PASS_CONTROL

PPOLL_CONFIGURE

PPOLL_UNCONFIGURE

REMOTE

SECONDARY

TALK

TRIGGER

UNLISTEN

UNTALK

No differences.
HPIB_3 LISTENER

LOCKED_OUT

PPOLL

REMOTED

REQUESTED

REQUEST_SERVICE

SPOLL

TALKER

No differences.

See the Pascal Procedure Library manual for details on the definition and use of these procedures and functions.

Restrictions

The CSUB I/O Library is not intended to replace the unified I/O approach of BASIC. BASIC has a rich and powerful I/O keyword set, and the underlying code called by the interpreter has been highly optimized for performance. However, two reasons for using the CSUB I/O Library are:

General Approach to CSUB Device I/O

Write each application as a "self-contained" module. This minimizes the interaction between a BASIC program and the CSUB. Enter the CSUB, perform the I/O tasks, and exit the CSUB. The CSUB I/O Library exports the same variables and procedures as the Pascal Procedure Library. Eventually, the CSUB library calls the BASIC drivers to do the work. It is conceivable that repeated switching from a BASIC program to a CSUB (intermingling I/O) could lead to errors or system corruption.

The Pascal Procedure Library recommends the use of the IOINITIALIZE and IOUNINITIALIZE procedures in an I/O application. When using the CSUB I/O Library, it is absolutely imperative to surround the application with these procedures. (See "Example Two" in the "Complete Examples" chapter for an example.) IOINITIALIZE sets up the I/O kernel for CSUBs (under Pascal, this is done during the boot process). Each entry to a CSUB should call IOINITIALIZE first. IOINITIALIZE sets up pointers into the CSUB in BASIC COM. Failing to do an IOINITIALIZE upon entry into the CSUB will result in a system crash (due to uninitialized pointers and procedures variables). Then IOUNINITIALIZE should be called before leaving the CSUB.

The major data structures of the Pascal I/O kernel are in place; some of them contain major modifications. In general, an application should only access the isc_table. This is the only data structure which is unchanged. Driver read and write areas are not the same, and attempting to access them returns meaningless results. In contrast to Pascal, if the card_type in the ISC_TABLE is other_card, card_ptr is invalid and using it will cause system errors. All buffer control data structures and DMA structures have been removed. All BUFFER/TRANSFER functions must be performed in BASIC. The driver tables are unchanged and can be called, but it is not recommended.

The CSUB I/O Library is sensitive to being moved around in memory, due to the use of pointers in the COM area. Refer to the "Globals" section of the "Writing CSUBs" chapter for more details. Adhering to the use of IOINITIALIZE and IOUINITTIALIZE should prevent problems.

Module Interdependency

Module interdependency refers to one module (e.g., GENERAL_1) needing items defined in other modules (i.e.,GENERAL_0 and IODECLARATIONS). Interdependency also occurs in the other modules in CSUBLIB, but the I/O modules have an important difference. GENERAL_0 and IODECLARATIONS contain Pascal globals, and therefore must be manually pre-linked before running BUILDC. It is not always clear from the Pascal Procedure Library manual when these hidden dependencies occur. Typically in the Pascal environment, the default library contains all modules and the linking loader automatically resolves hidden dependencies.

When building a CSUB you must provide full run-time support for your code. Manual pre-linking of the required modules (containing Pascal globals) can also include any other modules needed. The following table should help clarify link-time discrepancies for the I/O routines supported from the Pascal Procedure Library. For each module IMPORTed during compilation as listed under the heading "IMPORTed MODULE", you will need to add the appropriate modules listed under the "LINK MODULE" heading to the linking process. The Pascal Procedure Library manual tells which modules must be IMPORTed for compilation; refer to the "Reference" section. This table shows additional run-time dependencies. However, not every module is listed. For example, GENERAL_3 is not required by any other module in the procedure library, while IODECLARATIONS is required by every module.

* *
IMPORT/Link Modules
IMPORTed MODULE LINK MODULE
GENERAL_n HPIB_n
_0 _1 _2 _3 _0 _1 _2 _3
* * IOCOMASH
* * * * * * * IODECLARATIONS
* * * GENERAL_0
* * GENERAL_1
* * HPIB_0
* * * HPIB_1

Most of the general purpose I/O routines are contained in GENERAL_2. Find the vertical column labeled GENERAL_2. Each * in the column beneath it indicates a module which must be added to the link stream file, typically GENC.TEXT. Therefore, we would have to add IODECLARATIONS, GENERAL_1 and HPIB_1 to GENC.TEXT. Remember, IODELARATIONS contains Pascal globals, so it cannot be added to GENC.TEXT; it must be manually pre-linked.

This process should be repeated for each (new) module. GENERAL_1 requires IODECLARATIONS and GENERAL_0, and HPIB_1 requires IOCOMASM. GENERAL_0 also requires IOCOMASM. A required module needs only be linked in once to satisfy all external references to it. See "Example Two: Device I/O" of the "Complete Examples" chapter for a program which demonstrates a manual pre-link.

Preparing CSUBs Containing Device I/O

The following steps are a quick reference to generating CSUBs that perform device I/O:

  1. Boot the BASIC system. Create and store the BASIC program as usual. (This program will contain CALLs to SUBs, but the SUBs need not be implemented as they will be replaced later by CSUBs.)
  2. Boot the Pascal system, and write the application in Pascal (or assembly). Only use routines that are exported from the above modules. The application itself must be written as a module (for the CSUB generation process). There are some restrictions concerning manipulation of certain data structures; refer to the "Restrictions" section of this chapter.
  3. Debug as much of the application as possible. At this point, you can use the Pascal debugger, since the application is running under the Pascal Operating System.
  4. When the application is running correctly, insure it is compiled with $DEBUG OFF$ (the default). Use the Librarian and link all of the application modules with the required modules IODECLARATIONS and GENERAL_0 from CSUBLIB.CODE. Refer to the "Example Two" section of the "Complete Examples" chapter for a typical link file.
  5. Execute BUILDC. This fifth step is explained in more detail in the "Executing BUILDC" section of the "Preparing CSUBs for Use by BASIC" chapter. Supply the name of the linked file as the input file. Since the CSUB I/O Library requires global space, BUILDC will request a COM label name. BUILDC recognizes that the CSUB I/O Library is being used and will supply a default COM label. As shown here:
    
    Enter COM label for global variable space (default is given)
    ? Csub_io_globals
    
    This can be modified with the backspace key and re-typing. The remainder of the CSUB generation process continues unchanged.
  6. Stream the GENC.TEXT file as usual.
  7. Boot the BASIC system and load the CSUB from the keyboard or from the BASIC program using LOADSUB.
  8. [RUN] the BASIC program.

File Access Library

BASIC file I/O is provided through the File Access Library (FAL) found in the CSFA module. The FAL capabilities include creating, purging, opening, closing, reading, writing, and positioning files. The CSFA module implements procedures and functions that do not exist in the Pascal environment. Therefore, CSUBs that use this module cannot be fully tested before being transferred and loaded in the BASIC environment. To debug programs with these procedures, use WRITLEN to printout diagnostics.

FAL_CREATE_BDATFAL_CREATE_ASCIIFAL_CLOSEFAL_EOFFAL_LOADSUB_ALLFAL_LOADSUB_NAMEFAL_OPENFAL_POSITIONFAL_PURGEFAL_READFAL_READ_BDAT_INTFAL_READ_STRINGFAL_WRITEFAL_WRITE_BDAT_INTFAL_WRITE_STRING
FAL Modules
Procedure\ or Function Description
FAL_CREATE creates an HP-UX file
creates a BDAT file
creates an ASCII file
closes a file
writes an end-of-file at the current file position
loads all subprograms from the specified PROG file and appends them to the program in memory
loads the subprogram from the specified PROG file and appends it to the program in memory
opens a file for reading and writing.
positions the file pointer to a specified logical record number
purges a file
reads data from a file
reads a BASIC 16-bit integer from a BDAT file
reads a string from an ASCII, BDAT or HP-UX file
writes data into a file
writes a BASIC 16-bit integer to a BDAT file
writes a string to an ASCII, BDAT or HP-UX file

For details on each of these modules, see "Appendix B: File Access Library Reference".

Keyboard and CRT I/O

BASIC keyboard/CRT I/O is provided through the KBDCRT module. The module implements procedures and functions that access keyboard and CRT control and status registers; put characters on the CRT; read a single character from any location on the CRT; scroll the print area; clear the CRT; and manipulate the cursor.

CONTROLCRTCONTROLKBDCRTREADCHARCRTSCROLLCURSORDISP_AT_XYREAD_KBDSCROLLDNSCROLLUPSTATUSCRTSTATUSKBDSYSTEMD
KBDCRT Modules
Procedures\ and Functions Description
CLEAR_SCREEN clears the alpha CRT exactly as the [CLR SCR] key (or CLEAR SCREEN statement)
sends information to a CRT control register
sends information to a keyboard control register
reads one character from the specified location on the CRT
scrolls the CRT area, from line first to line last, up or down one line
removes the previous cursor and writes a new cursor to any on-screen alpha location
allows text to be written to any alpha location on the CRT
returns the buffer contents trapped and held by ON KBD (same as KBD$)
scrolls the PRINT area of the CRT down one line
scrolls the PRINT area of the CRT up one line
returns the contents of a CRT status register
returns the contents of a keyboard status register
returns a string containing the results of calling the function SYSTEM$ for a given argument
For details on each of these functions/procedures see, "Appendix C: Keyboard and CRT I/O Reference".