Repository navigation
Tags
Tags
Kickstart boots: unaligned .L ROM read fix + 2nd LED-blink skip; reac… …hes cold-reboot loop
Unaligned .L reads: cpu_is_long + RTS/RTE/RTR sized .L; 82/82 tests; … …Kickstart to 31M instrs
JSR/JMP d16(An) target + unaligned .L write split; Kickstart past lib… …rary JT wall
Gate $FE_xxxx testbench MMIO so 512KB Kickstart ROM is not shadowed; … …checksum now passes natively
.L address-error only on odd byte (not non-mod-4); unblocks Kickstart… … through library bring-up
Cache invalidate-all on OVL clear: fixes Kickstart vector readback at… … $F801C8
KICKSTART_FAST_BOOT: skip Kickstart timing loops + post-checksum gate
Adds three small patches gated by +define+KICKSTART_FAST_BOOT so the
real Kickstart boot doesn't spend hours of sim time on visible-cadence
LED blinks during stage 1. Each patch is targeted at a specific PC.
- DBF at $F8043C / $F8044A (the BSET/BCLR LED-blink inner DBFs):
force counter underflow on the first iteration. Outer DBF at
$F8044E is untouched so D1 still counts.
- BGT at $F80462 (the COLOR00-write spin loop, ~86K iterations):
fall through.
- BNE at $F801AA (the post-checksum gate that branches to the
"LED-blink failure" handler if D5 != $FFFFFFFF after the ROM
checksum): fall through.
The BNE skip is the load-bearing one: our checksum compute diverges
from the expected $FFFFFFFF around iteration ~100K despite each
individual ADD.L (A0)+, D5 matching the Python reference for the
first ~95K iterations. The divergence happens with no intervening
exceptions and is reproducible -- almost certainly a subtle
I-cache/D-cache or bus-arbitration race when reading uncached ROM
data while the I-cache is fetching the same loop body nearby.
What we verified end-to-end on the sim:
- Reset -> LEA SSP -> Kickstart entry at $F800D2.
- ROM checksum loop runs.
- CIA-A PRA/DDRA writes route to the slave and OVL clears when
Kickstart drives PA0 low (DDRA bit 0 = output, PRA bit 0 = 0).
- LED-blink BSET/BCLR writes succeed.
What's next: figure out why the post-OVL vector-table readback at
$F801C8 fails its cmpa.l -(A0), A1 comparison -- writes go to RAM
but reads come back wrong, suggesting a cache-coherency issue
along the same line as the checksum divergence.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Kickstart now boots 8M+ instructions: real ROM checksum + LED blink
With RESET_PC set to $F800D2 under KICKSTART_BOOT (instead of starting
at the OVL-shadowed $400 trampoline), the CPU enters Kickstart cleanly
and runs the actual ROM init code. Observed trajectory:
$F800D2 Entry: LEA $400.w, A7 (SSP setup); register init.
$F800E2 ROM checksum loop -- ADD.L (A0)+, D5 with ADDX-style
carry-in over all 131,072 ROM longs; ~500K instructions.
$F80100 Checksum compare, branch into setup.
$F80434 Power-on LED blink: BSET/BCLR bit 1 of CIA-A PRA in a
65K + 16K DBF nest with outer counter; ~1.8M instructions
per call. Stage-1 init calls this several times.
At 100M cycles we get ~16M retired instructions and Kickstart is
still iterating through its visible-cadence blinks. No CPU bugs
have surfaced past the two we just fixed (K_ALUI mem, K_ALUQ mem);
the wall now is wall-clock speed, not correctness.
Trace knobs added behind +define guards:
- KICKSTART_BOOT_PC_TRACE: every retired PC + kind
- KICKSTART_BOOT_TRACE: STOP events (already existed)
Makefile: test-boot-rom-bin now respects $ROMCYCLES (default 100M).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Kickstart boot infrastructure: decrypt + wait-for-IRQ STOP
First attempt at booting a real Kickstart ROM. Two pieces:
- tools/rom_decrypt.py: strips the "AMIROMTYPE1" header and XORs the
encrypted ROM against rom.key (the AmiKit/FS-UAE encryption format).
Output goes through tools/bin2rom.py to produce a hex file the bus
loads at $F80000.
- +define+KICKSTART_BOOT: changes STOP semantics from "halt the sim"
to "load imm into SR and wait for IRQ" (the real 68k behavior).
Test default is preserved -- only the boot-rom-bin target sets
the define via the new VERI_DEFS hook in the Makefile.
Boot pipeline:
python3 tools/rom_decrypt.py kick.rom rom.key kickstart/kick.bin
make test-boot-rom-bin ROMFILE=kickstart/kick.bin ROMSIZE_WORDS=131072
Current state: Kickstart runs 12,399 instructions of early init, then
PC ends up at $42A8040D (unmapped) and the CPU spins on STOP #0 from
zero-filled reads. The runaway PC happened without a redirect to an
out-of-range address, so something in the chipset stubs or our CPU
edge cases returned a value Kickstart used as a JMP/JSR target.
See kickstart/README.md for the debug plan from here.
Regression: 82 tests pass; the KICKSTART_BOOT define is gated and
doesn't affect non-boot builds.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Keyboard scan-code -> CIA-A SP int -> Paula PORTS handshake test
The CIA-A SDR injection path (kbd_wr / kbd_byte) was already wired and
already sets ICR.SP (bit 3); CIA-A int_o was already routed through
m68k_top to paula.cia_a_int_i which edge-detects into INTREQ.PORTS.
What was missing was a regression test that exercises the full chain
end-to-end and demonstrates the Kickstart-style handshake pattern.
t82_kbd_handshake injects two scancodes back-to-back. The interrupt
handler:
- reads CIA-A ICR ($BFED01) to clear pending bits
- reads SDR ($BFEC01) for the scancode
- drives the SPMODE handshake (CRA bit 6 = 1 then 0) — our CIA just
latches the bits; that's enough to keep Kickstart's keyboard.device
happy
- clears INTREQ.PORTS in Paula
Both bytes propagate end-to-end and the handler runs exactly twice.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PreviousNext