A new option, ARNITECH_CONTROLLER, on in the mc64 configuration only.
IOINIT starts timer A with CIA #1's TOD on 50 Hz, the mc64's mains, and
if the Arnitech controller's signature "ARNI" is at $DE80, latches its
clock and copies its real time into the TOD, hours first and tenths
last, flipping bit 7 of an hour of 12 first, since the CIA flips it
back when 12 is written. Without the signature the TOD is left alone.
The Arnitech jump table at $FF00: "ARNI", version $01, two entries, and
JMPs from $FF06: $FF06 finds the first Card slot holding a Card of the
type in A (carry clear, the slot in A, its Card window's low byte in
X; carry set if none or no controller), $FF09 sets the TOD as IOINIT
does. $FF48-$FF80 stay clear. The code is in new files under
src/kernal/arnitech; other configurations build as before.
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).
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).
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).
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)
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
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).
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
A copy of the c64 configuration with its own ID ($6D), the brand "MC64",
and BCD_SAFE_INTERRUPTS off, plus its Makefile targets
build/kernal_mc64.rom and build/basic_mc64.rom, made the same way as the
c64 ones. NOTICE says who modified the fork, when, and what changed.