From 729a410079ef2e391b3228b5eff76158ba889538 Mon Sep 17 00:00:00 2001 From: Christian Werner Date: Thu, 15 Oct 2026 14:21:36 +0200 Subject: [PATCH] Serial bus: UNLSN, UNTLK, and a missing device leave the bus released UNLSN ended through iec_set_idle, which pulls CLK, so the C64 kept holding CLK after UNLISTEN. UNTLK waited for the talker to pull CLK, which no device does after UNTALK, timed out, and left CLK pulled with carry set. And a serial routine that found no device also left CLK pulled. A fastloader that waits for the drive to pull CLK after the KERNAL's UNLSN (Turrican's) then went on too early. The contract (Michael Steil, "Commodore Peripheral Bus: Part 4", https://www.pagetable.com/?p=1135): at the end of a transmission the sender releases CLK and the receivers release DATA, so the bus is idle again, and the controller releases ATN after each command; after UNTALK "the current talker will then release the bus" (Part 2, https://www.pagetable.com/?p=1031). UNLSN and UNTLK now share their end and release CLK and DATA; the device-not-present exit releases ATN, CLK, and DATA. Commodore's ROMs leave the same lines in the same scenarios, as differential tests in arnitech show. Not reported upstream (https://github.com/MEGA65/open-roms). --- src/kernal/iec/iec_return.s | 4 ++-- src/kernal/iec/unlsn.s | 10 +++++++++- src/kernal/iec/untlk.s | 5 +++-- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/kernal/iec/iec_return.s b/src/kernal/iec/iec_return.s index c80323b7..8be97a46 100644 --- a/src/kernal/iec/iec_return.s +++ b/src/kernal/iec/iec_return.s @@ -36,8 +36,8 @@ iec_return_success: iec_return_DEVICE_NOT_FOUND: - ; Set IEC line to normal idle state - jsr iec_set_idle + ; Nobody answers: release all lines, so the bus is idle - see https://www.pagetable.com/?p=1135 + jsr iec_release_atn_clk_data ; BSOUR is certainly not valid anymore lda #$00 diff --git a/src/kernal/iec/unlsn.s b/src/kernal/iec/unlsn.s index 227ff3fb..2ef74cdf 100644 --- a/src/kernal/iec/unlsn.s +++ b/src/kernal/iec/unlsn.s @@ -42,7 +42,15 @@ UNLSN: ; Buffer empty, send the command lda #$3F - jmp common_open_close_unlsn_second +common_unlsn_untlk: ; common part of UNLSN and UNTLK + + jsr common_open_close_unlsn_second + bcs @1 + + ; The transmission is over: release CLK and DATA too, so the bus is idle - see https://www.pagetable.com/?p=1135 + jmp iec_release_clk_data +@1: + rts } else { diff --git a/src/kernal/iec/untlk.s b/src/kernal/iec/untlk.s index f26fdd22..c7998dfa 100644 --- a/src/kernal/iec/untlk.s +++ b/src/kernal/iec/untlk.s @@ -39,10 +39,11 @@ UNTLK: sta IECPROTO } - ; Buffer empty, send the command + ; Buffer empty, send the command; the talker releases the bus - see https://www.pagetable.com/?p=1031 lda #$5F + jmp common_unlsn_untlk -common_untlk_tksa: ; common part of UNTLK and TKSA +common_untlk_tksa: ; the rest of TKSA ; XXX - for TKSA, is it really the right place to do a turnaround? I have some doubts ; (it forces us to send the TKSA command 'manually' sometimes), but