Serial bus: a data byte with no listener says DEVICE NOT PRESENT

iec_tx_byte never checked that anyone was listening. With no listener,
DATA stays released, so the wait for listeners to be ready returned at
once, and a byte sent with EOI then waited forever for an EOI
acknowledgement that never came. UNLSN, which sends the byte CIOUT holds
back with EOI, hung the C64 after CHKOUT to a channel the drive refuses
(DOS 2.6 leaves the bus when no write channel is open), or to a channel
a CLOSE 15 has closed.

The contract (Michael Steil, "Commodore Peripheral Bus: Part 4",
https://www.pagetable.com/?p=1135): a listener holds DATA until the
talker releases CLK; if at the beginning of a byte no receiver pulls
DATA within 256 us, that is a DEVICE NOT PRESENT error. The C64
Programmer's Reference Guide's READST gives it as ST bit 7 ($80).
iec_tx_byte now waits up to about 256 us for DATA to be pulled, and
without it sets ST $80 and returns with DEVICE NOT PRESENT. Commodore's
ROMs give the same ST in the same scenarios, as a differential test in
arnitech shows.

Not reported upstream (https://github.com/MEGA65/open-roms).
This commit is contained in:
chris committed 2026-10-15 02:31:56 +02:00
1 parent b95a6ff057
commit 74ef17d292
1 file changed
+11
+11
View File
@@ -51,6 +51,17 @@ iec_tx_byte:
+phx_trash_a
+phy_trash_a
; A listener holds DATA until we release CLK; if nobody pulls it
; within 256us, no device is present - see https://www.pagetable.com/?p=1135
ldx #$18
@0:
lda CIA2_PRA
bpl @1 ; branch if DATA is pulled
dex
bne @0
jsr kernalstatus_DEVICE_NOT_FOUND
jmp iec_return_DEVICE_NOT_FOUND
@1:
; Notify all devices that we are going to send a byte
; and it is going to be a data byte (released ATN)
jsr iec_release_atn_clk_data