2318 Commits
Author SHA1 Message Date
chris 81ab3b41e1 fix(arnitech): INS in insert mode opens another space
In the spaces INS opened the Terminal driver sent INS to Literal, which
drew it as a glyph. On a C64 the INST key "inserts spaces normally" in
insert mode and shows as a reverse character only in quote mode
(Programmer's Reference Guide, the screen editor, p. 96), so INS now
goes to Output there and counts INSRT up when it opened a space.
2026-10-18 12:05:12 +02:00
chris 86d6dd0916 docs(arnitech): the network entries find the chip by its PacketPage Pointer too 2026-10-18 10:13:21 +02:00
chris d42102d039 docs(arnitech): ARNI_FINDCARD lists the Terminal Card, type $04 2026-10-18 10:13:21 +02:00
chris e8870b4c6c docs(arnitech): the controller's code is in the mc64blade build too
ARNITECH_CONTROLLER is on in mc64 and mc64blade, so the headers of the
controller's, the TOD's, and the network's code, the jump table's, and
CONFIG.md no longer say mc64 only.
2026-10-18 10:13:13 +02:00
chris ea0c8bc9ba style(init): mark the end of the reset's ARNITECH_BLADE block 2026-10-18 10:12:18 +02:00
chris 1a6c821cfa fix(arnitech): the network entries also check the PacketPage Pointer
Without a chip the RR-Net's ports read the floating bus, which can read like
the Product ID by chance. The probe now also reads back the PacketPage
Pointer it set to $0000: on a CS8900A its bits C-E always read 011b
(DS271F5 4.10.5), so the high byte reads $30. Seven bytes.
2026-10-18 10:04:44 +02:00
chris 05e4b67858 fix(arnitech): NET_SEND writes the chip's data port with plain stores
The copy loop wrote each byte with STA RRNET_RX_TX_DATA,X, and an indexed
store reads its address first. Reads of RxTxData take the bytes of a received
frame (AN181), so on a real CS8900A each byte sent took one of a frame the
program had started reading. The loop now stores to the port's low or high
byte by address, as ip65's and Contiki's drivers do; reads stay indexed, which
read once.
2026-10-18 10:04:40 +02:00
chris 0838c4e310 docs: the ARNITECH_BLADE option and the mc64blade configuration 2026-10-18 08:57:01 +02:00
chris 9ad7e292f8 feat(arnitech): a Blade autoboots the first program on device 8
With ARNITECH_BLADE, BASIC's cold start calls blade_autoboot before READY.: it
loads "*" from device 8 to BASIC's start, as LOAD"*",8 does, and BASIC then
ends that LOAD as a program's, which RUNs what it loaded. RUN/STOP held on the
Terminal Card, no Floppy, or no file goes on to READY.
2026-10-18 08:57:01 +02:00
chris b1fbc1c693 feat(init): no Cartridge or VIC-II at a Blade's reset and NMI
A Blade has no expansion port for Cartridges and no VIC-II: with
ARNITECH_BLADE the reset neither looks for a Cartridge nor blanks the screen,
and the NMI handler looks for no Cartridge.
2026-10-18 08:57:01 +02:00
chris f809b9b7ea feat(arnitech): the Terminal Card is a Blade's screen and keyboard
With ARNITECH_BLADE the screen editor, the keyboard matrix scan, and the VIC-II
set-up are left out, and devices 3 and 0 are the Terminal Card the Arnitech
controller finds by its type, $04. CHROUT writes each byte to its Output, or
to its Literal while quote or insert mode is on, keeping QTSW and INSRT as the
screen editor does. CHRIN marks where input starts, echoes the keys typed, and
on RETURN has the Card take the logical line under the cursor and reads it
back. SCNKEY moves the Card's keys into the keyboard buffer up to XMAX, UDTIM
sets STKEY from its RUN/STOP, SCREEN answers 80x25, PLOT moves and reads its
cursor, and CINT resets it and puts the native-mode vectors in place. With no
Terminal Card, bytes printed go nowhere and no key comes.
2026-10-18 08:57:01 +02:00
chris b7fef8abe6 feat(arnitech): handlers for a 65816's native-mode interrupts on a Blade
A Blade reads the 65816's native-mode vectors from the RAM under the KERNAL
at $FFE4-$FFEF. native_vectors_init puts handlers' addresses there: IRQ and
NMI save A, X, and Y at full width, the direct page, and the data bank, push
the frame an emulation-mode interrupt makes, and run the KERNAL's handlers
through CINV and NMINV in 8-bit native mode, whose RTI comes back to restore
everything. BRK, COP, and ABORT go to the BRK handler, which on a Blade first
sets the direct page and data bank to 0 and returns to emulation mode.
2026-10-18 08:57:01 +02:00
chris 90b921ac5e feat(init): a Blade is PAL without detecting it
With ARNITECH_BLADE, setup_pal_ntsc skips the raster wait that tells PAL from
NTSC, which would hang with no VIC-II, and sets PAL: a Blade runs at the PAL
C64's clock.
2026-10-18 08:57:01 +02:00
chris 80fb110391 feat(iec): on a Blade the 1 ms wait counts on CIA1's timer B
A Blade has no VIC-II whose raster lines iec_wait1ms could count, so with
ARNITECH_BLADE it runs CIA1's timer B, which only the tape used, once for 1024
cycles, and waits for its START bit to clear. Its ICR flag would not do, as
the IRQ handler's read of the ICR clears it.
2026-10-18 08:57:01 +02:00
chris 9f922287c6 feat(config): the mc64blade configuration and its Makefile targets
The Blade Firmware of arnitech's Blades: the mc64 configuration with its own
ID ($6E), the brand "MC64 BLADE", and no tape, programmable keys, joystick
cursor, panic screen, or feature list. Its new ARNITECH_BLADE option does
nothing yet. The targets build/kernal_mc64blade.rom and
build/basic_mc64blade.rom are made the same way as mc64's.
2026-10-18 08:35:45 +02:00
chris f1ade3b7d3 docs(notice): list the IEC IRQ fix 2026-10-18 08:16:40 +02:00
chris b4f334bbbf fix(iec): disable IRQs before releasing CLK to send a byte
iec_tx_byte and iec_tx_command released CLK and only then disabled IRQs. An
IRQ in between took about 500 cycles, longer than a listener's EOI wait and
acknowledgement, so the talker waited for an acknowledgement that had come and
gone, and a LOAD over the bus hung after its file name. Which byte an IRQ hit
depended on where the build placed the code.
2026-10-18 08:16:40 +02:00
chris 93c4932309 docs(notice): list the changes of 2026-10-18 2026-10-18 07:37:45 +02:00
chris 5fc29014f4 docs(config): ARNITECH_CONTROLLER also covers the network entries 2026-10-18 07:37:45 +02:00
chris 1aaed55bc7 feat(arnitech): network entries NET_INIT, NET_MAC, NET_SEND, NET_RECV at $FF0C-$FF15
Version 2 of the Arnitech jump table, with 6 entries: whole Ethernet frames
through the CS8900A at the RR-Net socket (arnitech's ADR 0027), found by its
Product ID and polled, from the CS8900A datasheet's PacketPage registers and
its 8-bit mode. NET_INIT resets the chip and turns on receiving its own and
broadcast frames and sending; NET_MAC copies the Individual Address; NET_SEND
bids and writes a frame; NET_RECV copies the oldest frame received, or drops
one longer than the buffer with Skip_1. Carry is the result, with an error
code in A, and the pointer and count go in SAL and EAL.
2026-10-18 07:36:43 +02:00
chris aa39286d9d fix(wedge): print a DOS command's status, not the OK after closing it
@<command> closed every file before it read the status, and a drive says
00, OK once its command channel closes, so @S: never showed FILES SCRATCHED.
It now reads the status through the channel it sent the command on.
2026-10-18 07:27:18 +02:00
chris 18520d8dc0 feat(config): the DOS wedge on in mc64, the transcendental functions off
The wedge's @, @$, and @<command> read the error channel, list a directory,
and send DOS commands from direct mode, so the F-keys' @8$-style commands work.
BASIC has room for it only without the transcendental functions, which stay
?NOT IMPLEMENTED until BASIC evaluates functions at all.
2026-10-18 07:27:18 +02:00
chris a45f63e34e feat(kernal): $E5B4, $EA24, and $ECF0 at their well-known addresses
cc65's C64 runtime and ip65 call past the jump table: $E5B4 takes the first
key from the keyboard buffer (cgetc), $EA24 points USER at the colour RAM of
PNT's line (cursor positioning), and $ECF0 holds the low bytes of the screen
lines' addresses (ip65's VT100 code), as Mapping the Commodore 64 describes
them. vicii_init's work moves out of $E5A0-$E5C8 to free $E5B4, and on the
standard layout PNT and USER are worked out through the routine at $EA24.
2026-10-18 07:24:08 +02:00
chris ec4dc7df62 fix(screen): CHROUT prints PETSCII $E0-$FF as screen codes $60-$7E and pi
PETSCII $E0-$FE became the reverse screen codes $A0-$BE. A C64 prints them as
$60-$7E, as it does $A0-$BE, and $FF, pi, as $5E, as it does $DE (C64
Programmer's Reference Guide, appendices B and C).
2026-10-18 07:20:45 +02:00
chris e9a64fb7a8 fix(chargen): draw the '#' of the upper case and graphics set
Screen code 35 was blank in the first character set, and its reverse (163)
was not its inverse. It now has the second set's '#', whose reverse the
first set already held, as both sets of a C64 share screen codes 32-63.
2026-10-18 07:20:45 +02:00
chris b4b48b195d NOTICE: list the Arnitech controller option 2026-10-17 02:17:45 +02:00
chris 03e2d4a4b8 Arnitech controller: the TOD set at boot, and a jump table at $FF00
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.
2026-10-17 02:17:45 +02:00
chris 0ec343a727 NOTICE: list the serial-bus fixes that leave the bus released 2026-10-15 14:21:36 +02:00
chris 729a410079 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).
2026-10-15 14:21:36 +02:00
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
chris 840c5f1b61 Add the mc64 configuration, the Firmware of arnitech's mc64
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.
2026-10-14 18:32:24 +02:00
Rikard Nordgren ad178dbe4d Add build for the original C64 2026-05-16 22:31:48 +02:00
Rikard Nordgren 93b6a2460e Update STATUS for exp and FIN 2026-05-09 17:01:44 +02:00
Rikard Nordgren e8191ccbac Add similarity strings 2026-05-09 17:01:44 +02:00
Rikard Nordgren a587990f3e Do not print out similarities of 3 bytes 2026-05-09 17:01:44 +02:00
Rikard Nordgren 781ad9ee6c Add pwr_FAC2_FAC1 2026-05-09 17:01:44 +02:00
Rikard Nordgren ec3c7c05dc Add exp_FAC1
Had to deactivate it for MEGA65 because of conflicting code also placed at e000
2026-05-09 17:01:44 +02:00
Rikard Nordgren 6ea0dc74be Remove unused math helpers 2026-05-09 17:01:44 +02:00
Rikard Nordgren 1ec43e8cd7 Update FIN 2026-05-09 17:01:44 +02:00
Rikard Nordgren 1b1d0c4329 Remove no longer used mov_FAC1_MEM 2026-05-09 17:01:44 +02:00
Rikard Nordgren 1adfa10462 Update -32768 2026-05-09 17:01:44 +02:00
Rikard Nordgren d65db6a049 Update const_PI
Allow a patched best rounded value or the original value from the MS BASIC
2026-05-09 17:01:44 +02:00