PET/CBM IEEE Bus Error
Gary R. Huckell
There is an error in the PET/CBM IEEE Input/output routines that can cause an inactive device on the IEEE bus to randomly become enabled. The problem exists in both old and new ROM PETs, but has now been corrected in the new 80 column units (BASIC 4.0).
The problem normally occurs when reading from the disk and can result in the transfer of part of the file being read to a printer that is also on the bus, in a slowing of the transfer of data, or in an error that causes the transfer to be aborted. It appears that Commodore peripheral equipment is immune to the problem. Unfortunately, non-Commodore equipment can often cause trouble.
The error is caused by an improper control handshake when the PET/CBM signals a device to UNTALK. After the PET/CBM has made a device on the IEEE bus a talker, it then assumes the role of a LISTENER. While listening, it controls the reading of data by raising and lowering signals NRFD and NDAC. After reading a character (GET#) or a string of characters (INPUT#) these control signals are both low to indicate that no more data is requested. The PET/CBM must now switch its role to that of a controller and UNTALK the device. The proper procedure in switching to the controller role is to first drive the signal ATN low, and then raise signals NRFD and NDAC. The PET/CBM first raises signals NRFD and NDAC, and then drives ATN low. This causes two problems:
First, when the signal NRFD is raised, the device that is currently a TALKER assumes that the PET/CBM is ready for another character, so it places another byte of data on the bus and lowers DAV. The PET/CBM then raises signal NDAC which normally indicates that the data has been accepted. Many IEEE devices lose a character because of this error.
The second problem occurs after raising NRFD and NDAC, when the PET drives the ATN signal low. As soon as ATN is low, all devices on the bus prepare for a command from the controller by raising their NRFD signals. If the device to be UNTALKED is slow in responding to changes to the IEEE interface, as the CBM disk is, there is a short time period where the controller is driving ATN and the device to be UNTALKED has data on the bus. Other devices on the bus now see the ATN signal and the data, and may read the current data on the bus as a control word. If the data on the bus happens to be a LISTEN command, an unwanted device can become a listener.
Any time data is input from the disk there is the possibility that another device on the bus may become a LISTENER. If this device is not always ready to receive data, it can then slow or stop the transfer of data to the PET/CBM. LOADing a program from the disk never causes the problem since the disk is only UNTALKED once, at the end of the LOAD. For the same reason, using INPUT# causes less trouble than GET#. Even though the problem is very easy to demonstrate, many users never see the problem. TNW's interfaces work with the Commodore Word Processor without problems, probably because this program reads a disk file as one block.
Since the UNTALK error looks so much like a proper data read operation, it may be hard to modify an IEEE device that is subject to this problem. We have a fix for our modem (the TNW488/103) that seems to work. We know our serial interfaces have the problem but we have received only a couple of complaints, fewer then we would have expected. Though it is hard to correct the problem by modifying the hardware, it is easy to program the PET around the problem. Two software corrections are shown here, one to be used with a machine language program and the second that can be used in a BASIC program.
Machine Language Fix
OPEN I/O files in the usual way in BASIC. Then the following routines permit use of the PET/CBM's IEEE-488 bus from programs written in 6502 machine language:
FFC6: LDX with the file number of an open input file, JSR FFC6 makes the device a TALKER.
FFC9: LDX with the file number of an open output file, then JSR FFC9 makes the device a LISTENER.
FFCC: JSR FFCC issues UNLISTEN and UNTALK commands on the IEEE-488 bus, and restores I/O to the keyboard and screen. This is the routine that contains the error. It also "clobbers" the accumulator A.
FFD2: LDA with a byte, then JSR FFD2 to "PRINT#" the character to the current output file.
FFE4: JSR FFE4 "GET#s" a character from the current input file, leaves it in the accumulator A.
The only change required to correct the UNTALK error is to set the ATN signal before calling the UNTALK routine. Do not set ATN before calling the same routine to perform an UNLISTEN.
;UNTALK LDA E840 ; READ IEEE SIGNALS AND #$FB ; SET ATN STA E840 ; WRITE IEEE SIGNALS JSR FFCC ; UNTALK
The following routine will store a machine language program in the second cassette buffer that can then be called using the SYS statement to GET# a byte.
10 FOR I = 826 TO 847 : READ D : POKE I, D : NEXT 20 DATA 162, 0, 32, 198, 255, 32, 228, 255, 133, 1, 173 30 DATA 64, 232, 41, 251, 141, 64, 232, 32, 204, 255, 96
OPEN I/O files in the usual way, then POKE 827 with the file number of the input device. Instead of using the GET# statement to read a byte of data, use SYS(826). The machine language program will read a single data byte and store it in memory cell 0001 where it can be read using PEEK(1). Output normally using the PRINT# statement. The following program will read a file from the disk and list it to the screen.
40 OPEN 1, 8, 2, "FILE 1, SEQ, READ" 50 POKE 827, 1 60 SYS 826 : D-PEEK(1) : IF ST = 0 THEN PRINT CHR$(D); : GOTO 60 70 CLOSE 1 : END
Commodore has now fixed this problem in the new 80 column PETs, so the above software corrections are not necessary with these units, but they should not cause a problem. All software written by TNW Corporation that uses the CBM disk incorporates the above software fix. We would like to hear from other PET/CBM users that have encountered this problem and hope that this fix is of value.