Compare commits

...
9 Commits
Author SHA1 Message Date
chris 7ee9d164e2 NOTICE: list the CLOSE fix for a device that does not answer 2026-10-15 02:50:48 +02:00
chris 51a2a43520 CLOSE: a device that does not answer sets ST to device not present
When LISTEN or the CLOSE command found no device on the serial bus,
close_iec freed the file number but left ST as it was, so READST after
the CLOSE said 0.

The contract: every device on the bus must answer ATN by pulling DATA,
and when none does the result is DEVICE NOT PRESENT (Michael Steil,
"Commodore Peripheral Bus: Part 2", https://www.pagetable.com/?p=1031);
the C64 Programmer's Reference Guide's READST reports that as ST bit 7
($80). close_iec now sets that bit when LISTEN or the CLOSE command
fails, and still frees the file number. Commodore's ROMs give the same
ST in the same scenario, as a differential test in arnitech shows.

Not reported upstream (https://github.com/MEGA65/open-roms).
2026-10-15 02:50:48 +02:00
chris ec7707d4cc NOTICE: list the serial-bus fix for a byte with no listener 2026-10-15 02:32:03 +02:00
chris 74ef17d292 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).
2026-10-15 02:31:56 +02:00
chris b95a6ff057 NOTICE: list the serial-bus fixes of 2026-10-15
CIOUT's buffer, CLOSE's LISTEN/CLOSE/UNLISTEN, CHKIN's and CHKOUT's
secondary address, and TKSA's secondary address.
2026-10-15 02:19:08 +02:00
chris f1df180bf8 TKSA: send the secondary address the caller gives
TKSA ORed the accumulator with $90 before sending it. Its callers pass
the secondary address plus $60, as the routine's own comment asks, so
TKSA turned a TALK secondary address $60-$6F into $F0-$FF, the OPEN
command, on the bus.

The contract (C64 Programmer's Reference Guide, TKSA; Michael Steil,
"Commodore Peripheral Bus: Part 2", https://www.pagetable.com/?p=1031,
which gives TKSA's argument as A = $60 + secondary address): TKSA sends
the byte in A as the secondary address to the device told to TALK.
TKSA now sends A as it is.

Upstream: https://github.com/MEGA65/open-roms/issues/116 (bug 1)
2026-10-15 02:18:55 +02:00
chris 340bbefd06 CHKIN, CHKOUT: address the channel by the file's secondary address
chkin_iec and ckout_iec read the secondary address from LAT, the table
of logical file numbers, instead of SAT, the table of secondary
addresses. A file whose number differed from its secondary address,
such as OPEN 3,8,2, was read from or written to the wrong channel, and
the read-only and write-only checks tested the file number.

The contract (Michael Steil, "Commodore Peripheral Bus: Part 2",
https://www.pagetable.com/?p=1031): CHKIN sends TALK and CHKOUT sends
LISTEN, each followed by the secondary address OPEN was given; Compute!'s
Mapping the Commodore 64 (p. 52) keeps the logical file numbers at
$0259 (LAT) and the secondary addresses at $026D (SAT). Both routines
now read SAT.

Not reported upstream (https://github.com/MEGA65/open-roms); it may be
what upstream issue #117's OPEN 1,8,0,"$" test met:
https://github.com/MEGA65/open-roms/issues/117
2026-10-15 02:17:03 +02:00
chris 29124377fc CLOSE: send LISTEN, CLOSE, UNLISTEN to a serial device
close_iec sent its CLOSE command under ATN without first addressing the
device with LISTEN and without UNLISTEN after it, and built the command
with ORA $E0 (zero page) instead of ORA #$E0, so the byte it sent was
the secondary address ORed with whatever $E0 held. The drive never
learned of the CLOSE, so a file written on a channel was never written
to the disk.

The contract (Michael Steil, "Commodore Peripheral Bus: Part 2",
https://www.pagetable.com/?p=1031): CLOSE of a file on a serial device
sends LISTEN, then $E0 plus the secondary address, then UNLISTEN.
close_iec now does that, as iec_close_load already does for LOAD.

Not reported upstream (https://github.com/MEGA65/open-roms).
2026-10-15 02:15:38 +02:00
chris 264e9792a5 CIOUT: buffer the byte where iec_tx_byte sends it from
CIOUT kept the byte to send next in BSOUR ($95), but iec_tx_byte, which
CIOUT and iec_tx_flush (called by UNLSN, UNTLK, LISTEN, TALK) use to
send it, transmits TBTCNT ($A4). So every byte CHROUT sent to a serial
device was whatever TBTCNT held, and a file written with CHKOUT and
CHROUT held the wrong bytes.

The contract (C64 Programmer's Reference Guide, CIOUT): CIOUT sends a
byte to the listening device, always holding one back so that the last
byte goes with EOI when UNLSN ends the transfer. CIOUT now buffers the
byte in TBTCNT, the one-line fix of upstream PR #113; changing the send
path to read BSOUR would also move LOAD's and SAVE's bytes.

Upstream: https://github.com/MEGA65/open-roms/pull/113
2026-10-15 02:15:38 +02:00
7 changed files with 47 additions and 13 deletions

No files matched your search

+15 -3
View File
@@ -1,9 +1,9 @@
This is a modified version of MEGA65 Open ROMs (https://github.com/MEGA65/open-roms),
forked at upstream commit ad178dbe4d48cd6a317737a8e0e7e662f7e33d32.
Modified by Christian Werner, 2026-10-14, for the mc64 computers of arnitech, a set of
Minecraft mods (https://git.susdog.de/chris/arnitech). The fork lives at
https://git.susdog.de/chris/open-roms, branch mc64.
Modified by Christian Werner, 2026-10-14 and 2026-10-15, for the mc64 computers of
arnitech, a set of Minecraft mods (https://git.susdog.de/chris/arnitech). The fork lives
at https://git.susdog.de/chris/open-roms, branch mc64.
Changes:
@@ -11,6 +11,18 @@ Changes:
own config ID ($6D), the brand "MC64", and BCD_SAFE_INTERRUPTS turned off.
- Makefile: targets for that configuration, build/kernal_mc64.rom and build/basic_mc64.rom,
made the same way as the c64 ones.
- src/kernal/iec/ciout.s (2026-10-15): CIOUT buffers its byte in TBTCNT, where the send
routine takes it from, not in BSOUR (upstream PR #113).
- src/kernal/iec/close_iec.s (2026-10-15): CLOSE sends LISTEN, $E0 plus the secondary
address, and UNLISTEN; it sent a command ORed with zero page $E0 and no LISTEN.
- src/kernal/iec/chkin_iec.s, ckout_iec.s (2026-10-15): CHKIN and CHKOUT take the secondary
address from SAT, not from LAT, the logical file numbers.
- src/kernal/iec/tksa.s (2026-10-15): TKSA sends the secondary address it is given, without
ORing $90 into it (upstream issue #116).
- src/kernal/iec/iec_tx_byte.s (2026-10-15): a data byte that no listener holds DATA for
sets ST to $80 (device not present) and returns, instead of waiting forever.
- src/kernal/iec/close_iec.s (2026-10-15): a CLOSE that finds no device sets ST to $80
(device not present), and still frees the file number.
- NOTICE: this file.
The licence terms are unchanged; see LICENSE, COPYING, and COPYING.LESSER.
+2 -2
View File
@@ -14,7 +14,7 @@ chkin_iec:
; Fail if the file is open for writing (secondary address 1)
lda LAT, Y
lda SAT, Y
cmp #$01
+beq chkin_file_not_input
@@ -24,7 +24,7 @@ chkin_iec:
jsr TALK
+bcs chkinout_device_not_present
lda LAT, Y
lda SAT, Y
ora #$60
jsr TKSA
+bcs chkinout_device_not_present
+3 -2
View File
@@ -28,9 +28,10 @@ CIOUT:
ciout_store_in_buffer:
; Store in the buffer data to be sent next, return
; Store in the buffer data to be sent next, return; iec_tx_byte
; sends the byte from TBTCNT, so that is our buffer, not BSOUR
pla
sta BSOUR
sta TBTCNT
rts
ciout_send_byte:
+2 -2
View File
@@ -14,7 +14,7 @@ ckout_iec:
; Fail if the file is open for reading (secondary address 0)
lda LAT, Y
lda SAT, Y
+beq ckout_file_not_output
; Send LISTEN + SECOND first
@@ -23,7 +23,7 @@ ckout_iec:
jsr LISTEN
+bcs chkinout_device_not_present
lda LAT, Y
lda SAT, Y
ora #$60
jsr SECOND
+bcs chkinout_device_not_present
+14 -2
View File
@@ -23,11 +23,23 @@ close_iec:
jsr iec_close_load
jmp close_remove_from_table
@1:
ora $E0 ; CLOSE command
; LISTEN, CLOSE, UNLISTEN - see https://www.pagetable.com/?p=1031
lda FAT, y
jsr LISTEN
bcs close_iec_not_present
lda SAT, y
ora #$E0 ; CLOSE command
sta TBTCNT
jsr iec_tx_command
bcs close_iec_end
bcs close_iec_not_present
jsr iec_tx_command_finalize
jsr UNLSN
jmp close_remove_from_table
close_iec_not_present:
; The file is closed all the same; READST says device not present
jsr kernalstatus_DEVICE_NOT_FOUND
; FALLTROUGH
+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
-2
View File
@@ -28,8 +28,6 @@ TKSA:
; - https://www.lemon64.com/forum/viewtopic.php?t=57694&sid=531ba3592bcffadef2ac8b9162f2e529
; - https://www.pagetable.com/?p=1031 (Kernal API description)
ora #$90
jmp common_untlk_tksa
} else {