Codebase64 on the Kernal behaviour

I found out that codebase64 mentions the issue I reported about reading the error channel/status info from devices that are not on the IEC bus. The author of the article refers to the issue as a deadlock.

An interesting thing I found out back when I was writing the “serial-device” API in IECHost (the API that sits on top of the TALK/LISTEN API) is that in the following snippet of code (presented at the bottom the above mentioned page on codebase64) the LISTEN/UNLISTEN part is absolutely vital when the code runs on a Commodore home-computer:

        LDA #$00
        STA $90       ; clear STATUS flags

        LDA $BA       ; device number
        JSR $FFB1     ; call LISTEN
        LDA #$6F      ; secondary address 15 (command channel)
        JSR $FF93     ; call SECLSN (SECOND)
        JSR $FFAE     ; call UNLSN
        LDA $90       ; get STATUS flags
        BNE .devnp    ; device not present

        LDA $BA       ; device number
        JSR $FFB4     ; call TALK
        LDA #$6F      ; secondary address 15 (error channel)
        JSR $FF96     ; call SECTLK (TKSA)

.loop   LDA $90       ; get STATUS flags
        BNE .eof      ; either EOF or error
        JSR $FFA5     ; call IECIN (get byte from IEC bus)
        JSR $FFD2     ; call CHROUT (print byte to screen)
        JMP .loop     ; next byte
        JSR $FFAB     ; call UNTLK
        ... device not present handling ...

In fact, the LISTEN/UNLISTEN block serves an important purpose: the earliest time a “device not present” condition can be detected is after the secondary address is sent (after LISTEN). In other words, when the request to send LISTEN is made, the Kernal does not signal the “device not present” condition to the code that made the request.

A TALK/UNTALK block is unsuitable for detecting if a device is present because after the secondary address (after TALK) is sent, the bus turnaround process is initiated as well, which is where the code hangs 🙂

The equivalent code using IECHost’s LISTEN/TALK API directly (which is essentially knowing which commands to send using IEC bus routines) is:

st = 0;		/* Clear status flags */

iec_send_listen(device_number, &st);
iec_send_secondary_address_after_listen(CTRL_CODE_DATA | CHANNEL_CMD, &st);
_delay_us(20);	/* Some delay is mandatory before sending UNLISTEN */
if (st)

iec_send_talk(device_number, &st);
iec_send_secondary_address_after_talk(CTRL_CODE_DATA | CHANNEL_CMD, &st);
iec_read(buff, szBuff, &bytesRead, &st);

Another interesting thing is that the file abstraction (OPEN/CLOSE) cannot be used for the same purpose. The reason is that a command such as the one below:

OPEN 15,8,15

does not actually cause any communication to device 8. It only sets up the file table on the host computer.
One might be tempted to try the below command instead, in order to send LISTEN/secondary address after LISTEN/UNLISTEN to a device and then check ST ($90) to detect if the device is present or not:

OPEN 15,8,15,""

Unfortunately for us, the host computer still won’t initiate any IEC communication at all as it understands that the length of the parameter is 0 so there’s no need to go through the LISTEN/secondary address after LISTEN/UNLISTEN sending process.

Posted in Retrocomputing, Technical | Tagged , , , | Leave a comment

More on the INPUT# command

Recently I commented on how an INPUT# command can cause execution to hang on a Commodore home-computer if the device for which it is intended is not on the IEC bus. I thought to provide some more details on what the right course of action is to avoid the hanging and what one might be doing that causes a hanging.

In a BASIC program genuinely interested in working with a disk drive, such as the ones listed in Inside Commodore DOS, it is not uncommon to read something along these lines:

10 OPEN 15,8,15
20 PRINT#15,"I0"
30 INPUT#15,EN$,EM$,ET$,ES$
40 IF EN$="00" GOTO 70
50 PRINT EN$", "EM$","ET$","ES$
60 END
200 CLOSE 15

The lesson to take home here is that at the beginning of a disk utility you issue a disk initialization (line 20). This operation fails with “?DEVICE NOT PRESENT  ERROR IN 20” if drive number 8 is not on the IEC bus. And that’s all good as we don’t get to line 30 where execution would hang.

Now let’s suppose we remove line 20 because we want to check the DOS version of a drive at power-on or after a drive reset. A 1541 would return:

73,CBM DOS V2.6 1541,00,00

However, if drive 8 is not on the IEC bus and the above BASIC program is run without line 20, execution hangs at line 30 (executing the loop at $EDD6 – on a Commodore 64 – until the serial clock is pulled low by the non-existing device, which obviously does not happen).

Posted in Retrocomputing, Technical | Tagged , , , | Leave a comment

Kernal “patch” in the IECHost firmware

This evening I was contemplating the idea of adding a “disk certification” option in IECHost, as per Inside Commodore DOS – program on page 91, which uses direct access programming, including job execution.
I was admiring how beautifully error checking is done within the BASIC listing there when I was struck again by something I noticed quite some time ago when I was first testing the IECHost firmware. Long story short, the following INPUT# command on a Commodore home-computer hangs if device 8 is not present on the IEC bus:

OPEN 15,8,15

I hadn’t really tracked down the cause of the hanging so far, so I decided to look into it.

I found out that the Commodore Kernal code that sends the secondary address after TALK (at $EDC7) does not check ST before requesting a bus turnaround. Within the bus turnaround process a few things happen, one of which is that the IEC master waits for the CLOCK line to be pulled low: that never happens in absence of the device for which the TALK request is sent on the bus.

I’ve now changed the IECHost firmware (which was designed using the Commodore Kernal code as reference) so that a bus turnaround is not initiated if the secondary address after TALK fails to be transmitted: that’s the case when the addressed device is not on the bus.

Happy days 🙂

Posted in Retrocomputing, Technical, Uncategorized | Tagged , , , , | 1 Comment

D64 Browser update

As the IECHost client might not be provided with some low level features required to e.g. set all 5 bytes of the disk ID, I decided to also update my “D64 Browser” application in order to add a number of useful features to prepare custom D64 files.

D64 Browser: Edit menu by Luigi Di Fraia

D64 Browser: Edit menu

In fact, working on D64 files using my libd64fs library is way easier for low level stuff than using the direct access paradigm (block read, RAM read, RAM write, block write, buffer pointer, etc.).

However, the direct access stuff is quite exciting to use and the IECHost firmware is capable to handle direct access commands fully. You never know, I might actually progress both routes 🙂

Posted in Retrocomputing, Technical | Tagged , , , , , , | Leave a comment

IECHost PCB design sent to manufacturing

Motivated by the manufacturing of a few more DC2N5-LC PCBs, I decided to also submit an order for IECHost PCBs.

It would be great to get access to a 3D printer to print ad-hoc cases for these new PCBs 🙂

IECHost client running on Windows 10 by Luigi Di Fraia

IECHost client running on Windows 10

Posted in Retrocomputing, Technical | Tagged , , , , , , , | Leave a comment

TAPClean Front End update!

TAPClean Front End version 0.37 has just been published! Binaries are available for Windows and Linux on my Software page. For user convenience these binaries also provide the latest released version of TAPClean, 0.34.

An updated version of the user manual is provided too, covering the latest change, i.e. the ability to generate IDX records using the tape split tool 🙂


Posted in Retrocomputing, Technical | Tagged , , , , , | Leave a comment

IECHost disk restore video update

As I had changed the interleave value used to write back tracks 1-17 in a more reliable way, here’s a video update about the process 🙂

Posted in Retrocomputing, Technical | Tagged , , , , , , , , , | Leave a comment