Two bugs in the STD (C64-compatible) build prevent channel-based serial reads (OPEN+CHKIN+CHRIN) from working on IEC devices. LOAD is unaffected. It uses its own serial protocol that bypasses both code paths.
Bug 1: TKSA corrupts secondary address
src/kernal/iec/tksa.s applies ora #$90 to the incoming accumulator:
; tksa.s line 31 (CONFIG_IEC path)
ora #$90
jmp common_untlk_tksa
Callers (e.g. chkin_iec.s) pass SA | $60 as required by the IEC protocol and documented in the comment on line 26-27 of the same file: "it is the caller responsibility to provide value ORed with $60." The spurious ora #$90 turns SA | $60 into SA | $F0, which is an OPEN command ($F0), not a talk-secondary-address ($60).
The UNTLK path that shares common_untlk_tksa is unaffected. It enters with lda #$5F at untlk.s:43, before the shared label.
Fix: Remove the ora #$90 from tksa.s.
Bug 2: open_iec skips bus communication for empty filenames
src/kernal/iec/open_iec.s short-circuits when FNLEN == 0:
open_iec:
ldy FNLEN
beq open_iec_done ; ← skips LISTEN + SECOND + UNLISTEN entirely
This skips all IEC bus communication, and LISTEN, SECOND(SA|$F0), and UNLISTEN are never sent. The file is recorded in the internal FAT/LAT/SAT tables, but the drive is never told to open the channel.
This breaks any OPEN lfn,dev,sa,"" with an empty filename. The most common case is reading the drive error channel: OPEN 15,8,15,"" (or OPEN 15,8,15). The stock KERNAL sends LISTEN + SECOND + UNLISTEN even with an empty command string. The drive needs the bus transaction to know channel 15 was opened.
Fix: Remove the beq open_iec_done branch (or move it after the LISTEN+SECOND+UNLISTEN sequence, before iec_send_file_name). The iec_send_file_name routine already handles FNLEN=0 correctly. It sends zero bytes then calls UNLSN.
Impact
Together, these two bugs break every program that uses the standard CBM channel I/O pattern:
SETNAM / SETLFS / OPEN / CHKIN / CHRIN loop / CLOSE
This includes directory listing, error channel reads, and any sequential file reads that use CHRIN instead of LOAD.
Bug 1 alone breaks channel reads even when the filename is non-empty (e.g. OPEN 1,8,0,"$").
Bug 2 alone breaks channel opens with empty filenames (e.g. OPEN 15,8,15).
Test case
Reads the drive error channel and should print 00, OK,00,00 (or similar):
10 OPEN 15,8,15
20 INPUT#15,A$,B$,C$,D$
30 PRINT A$;",";B$;",";C$;",";D$
40 CLOSE 15
Channel-based directory read and should print the first byte of the directory file:
10 OPEN 1,8,0,"$"
20 GET#1,A$
30 PRINT ASC(A$)
40 CLOSE 1
On stock KERNAL both work. On open-roms STD, the first hangs or returns empty (both bugs), the second hangs (bug 1 alone).
Validation
Both bugs were confirmed by binary-patching the built kernal_generic.rom:
- Offset $1388: replaced
09 90 (ora #$90) with EA EA (NOP NOP)
- Offset $1BAF: replaced
F0 15 (beq +21) with EA EA (NOP NOP)
With both patches applied, channel-based error channel reads work correctly in VICE x64sc 3.10 with true drive emulation. Named directory listing still hangs due to issue #117.
Tested with: open-roms STD build (C64-compatible), VICE x64sc 3.10, 1541 D64 disk image.
Two bugs in the STD (C64-compatible) build prevent channel-based serial reads (OPEN+CHKIN+CHRIN) from working on IEC devices. LOAD is unaffected. It uses its own serial protocol that bypasses both code paths.
Bug 1:
TKSAcorrupts secondary addresssrc/kernal/iec/tksa.sappliesora #$90to the incoming accumulator:Callers (e.g.
chkin_iec.s) passSA | $60as required by the IEC protocol and documented in the comment on line 26-27 of the same file: "it is the caller responsibility to provide value ORed with $60." The spuriousora #$90turnsSA | $60intoSA | $F0, which is an OPEN command ($F0), not a talk-secondary-address ($60).The
UNTLKpath that sharescommon_untlk_tksais unaffected. It enters withlda #$5Fatuntlk.s:43, before the shared label.Fix: Remove the
ora #$90fromtksa.s.Bug 2:
open_iecskips bus communication for empty filenamessrc/kernal/iec/open_iec.sshort-circuits whenFNLEN == 0:This skips all IEC bus communication, and LISTEN, SECOND(SA|$F0), and UNLISTEN are never sent. The file is recorded in the internal FAT/LAT/SAT tables, but the drive is never told to open the channel.
This breaks any
OPEN lfn,dev,sa,""with an empty filename. The most common case is reading the drive error channel:OPEN 15,8,15,""(orOPEN 15,8,15). The stock KERNAL sends LISTEN + SECOND + UNLISTEN even with an empty command string. The drive needs the bus transaction to know channel 15 was opened.Fix: Remove the
beq open_iec_donebranch (or move it after the LISTEN+SECOND+UNLISTEN sequence, beforeiec_send_file_name). Theiec_send_file_nameroutine already handles FNLEN=0 correctly. It sends zero bytes then calls UNLSN.Impact
Together, these two bugs break every program that uses the standard CBM channel I/O pattern:
This includes directory listing, error channel reads, and any sequential file reads that use CHRIN instead of LOAD.
Bug 1 alone breaks channel reads even when the filename is non-empty (e.g.
OPEN 1,8,0,"$").Bug 2 alone breaks channel opens with empty filenames (e.g.
OPEN 15,8,15).Test case
Reads the drive error channel and should print
00, OK,00,00(or similar):Channel-based directory read and should print the first byte of the directory file:
On stock KERNAL both work. On open-roms STD, the first hangs or returns empty (both bugs), the second hangs (bug 1 alone).
Validation
Both bugs were confirmed by binary-patching the built
kernal_generic.rom:09 90(ora #$90) withEA EA(NOP NOP)F0 15(beq +21) withEA EA(NOP NOP)With both patches applied, channel-based error channel reads work correctly in VICE x64sc 3.10 with true drive emulation. Named directory listing still hangs due to issue #117.
Tested with: open-roms STD build (C64-compatible), VICE x64sc 3.10, 1541 D64 disk image.