Classic Computer Magazine Archive COMPUTE! ISSUE 11 / APRIL 1981 / PAGE 144

Pet File I/O In Machine Language

Raymond A. Diedrichs

The PET's I/O scheme is very flexible. A BASIC language program can effortlessly specify that the PET read data from an input device (tape, disk, or keyboard) and send processed data to an output device (printer, plotter, or CRT). At all times the PET knows which devices are for input, which are for output, and when and how each should be used.

But there are occasions when we need an assembly language program. Must we give up the PET's facile I/O because we choose to use machine language? No, indeed. It is as easy to perform standard PET I/O in machine language as it is in BASIC, and this article will explore the necessary techniques.

Let's first be certain that we understand exactly what it is that we specify when we write BASIC language I/O statements. Consider this simple-minded program:

10 REM EXAMPLE ONE
20 INPUT A
30 PRINT A

The I/O actions ("INPUT" and "PRINT") are indicated, but the I/O devices are not. The PET therefore uses the default devices: the keyboard for input in line 20 and the CRT for output in line 30.

A second example uses explicit device indication:

10 REM EXAMPLE TWO
20 OPEN l, 2, 0, "SAMPLE"
30 INPUT #1,A
40 INPUT B
50 PRINT A,B

In line 20 logical file 1 is created for input of file "SAMPLE" from cassette unit 2. In line 30 file 1 ("#") is the input source, so the PET seeks input from cassette 2, which is the device associated with the file. In line 40 the PET once again uses the keyboard for input, and in line 50 the output is sent to the CRT.

There are multiple I/O devices in example two, but the PET copes by temporarily ignoring all devices except the pair which are in current use for input and output. If a file number is attached to the I/O statement, the file device is made current; if no file is indicated, the PET reverts to the default device.

When we use machine language, the default input and output devices remain the same as in BASIC. Therefore, when

JSR $FFCF

is executed, the next character in the input stream is returned in register A. Likewise, when

LDA #ASCII-CHARACTER
JSR $FFD2

is executed, the character in register A is displayed on the CRT in the next print position.

To use devices other than the default in machine language, we must open a logical file for each device and supply the same information that is supplied by the equivalent BASIC OPEN statement. The following routine performs this function:

!
! MACHINE LANGUAGE OPEN STATEMENT [NEW ROM PET]
!
     LDA #FILE-NUMBER
     STA $D2
!
! IF THE DEVICE HAS A BUFFER, DECLARE THE BUFFER START ADDRESS
! IF NO BUFFER IS NEEDED, SKIP THIS SECTION
!
     LDA #.LOW.ADDRESS-OF-DEVICE-BUFFER
     STA $D6
     LDA #.HI.ADDRESS OF DEVICE BUFFER
     STA $D7
!
! IF THE FILE HAS A NAME, THE NAME MUST RESIDE SOMEWHERE IN MEMORY
! AS AN ASCII CHARACTER STRING. DECLARE THE LENGTH OF THE NAME IN
! CHARACTERS AND THE STARTING MEMORY LOCATION OF THE NAME STRING.
! IF THE FILE DOESN'T HAVE A NAME, DECLARE A NAME LENGTH OF 0
     LDA #FILENAME-CHARACTER-STRING-LENGTH
     STA $D1
     LDA #.LOW.ADDRESS-OF-FILENAME-CHARACTER-STRING
     STA $DA
     LDA #.HI.ADDRESS-OF-FILENAME-CHARACTER-STRING
     STA $DB
!
! CALL A PET SYSTEM SUBROUTINE WHICH OPENS FILE USING THE
! INITIALIZED SYSTEM VARIABLE SET
!
     JSR $F524

This set of system variables can assume any values which make sense in the equivalent BASIC OPEN statement. The secondary address for a cassette file, for example, can be 0 (for READ), 1 for (WRITE), or 2 (for WRITE with EOT).

When input or output is required from a file device, we must make that device a current I/O device:

!
! ROUTINE TO MAKE A DEVICE THE CURRENT INPUT DEVICE [NEW ROM PET]
!
     LDX #FILE-NUMBER
     JSR $FFC6
!
! ROUTINE TO MAKE A DEVICE THE CURRENT OUTPUT DEVICE [NEW ROM PET]
!
     LDX #FILE-NUMBER
     JSR $FFC9

If, for example, a printer is attached in this manner, then the output routine at $FFD2 sends output directly to the printer on the IEEE-488 bus; all 'LISTEN' and 'UNLISTEN' commands are included. When the cassette is attached for input or output, the PET performs all cassette motor control, data buffering, prompting ("PRESS PLAY AND RECORD"), and logging ("SEARCHING FOR SAMPLE").

When the attached device is no longer needed (or temporarily not needed — I/O can be mixed just as example two showed), restore the default devices in this manner:

JSR $FFCC

The file device is now detached, and the file can be closed:

!
! ROUTINE TO CLOSE A LOGICAL FILE [NEW ROM PET]
!
     LDA #FILE-NUMBER
     JSR $F2AE

In this article, we have seen that standard PET I/O in machine language is simple, uniform, and economical of user program space.