Repository navigation
Conversation
wesbiggs
added a commit
to wesbiggs/teensyrom-vdrive
that referenced
this pull request
Oct 31, 2026
The poll from loop() went upstream as SensoriumEmbedded/TeensyROM#85, in a narrower form: Kernal Replace only, a FLASHMEM function, guarded by Fab04_KernalReplace, the AT-command PIT unmask only under Fab04_GlobalKernalReplace. firmware/kernal-fnet-poll.patch is that PR byte for byte and make_tr_patch.sh applies it first; kernalreplace-fixes.patch keeps only KernalFast and the LATE_ISR_TRACE trace, on top of it. The VDrive-specific parts are edits in make_tr_patch.sh: the VDrive Special IOs join the poll list, and the PIT unmask also compiles under Fab04_VDrive (VDrive+SwiftLink runs AT commands with the poll on). Plain SwiftLink on the stock KERNAL no longer switches to the loop poll, as in the PR: it was never measured. Firmware builds for TR+ and TR, fw_host passes, and the patch applies on fa509421 and on open PRs 81-83. Not on hardware. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Once Ethernet is initialized (no cable needed), NativeEthernet runs the whole FNET stack from a 1 ms IntervalTimer (PIT) ISR. That made about 39 phi2 interrupts per second late (>1.1 us), even with the GPIO interrupt at the higher priority; masking IRQ_ENET did not help, masking IRQ_PIT did. Late interrupts hurt most on the first read after a $01 write, where Kernal Replace senses HIRAM before it drives the bus: Quest for the King (which switches $01 constantly) got corrupt reads, NMIs or froze, and so did CCGMS with SwiftLink over TCP under a replaced KERNAL. While Kernal Replace serves the KERNAL and the stack is up, mask IRQ_PIT and call fnet_poll() from loop() every ms (FnetLoopPollService, FLASHMEM). Late phi2 interrupts drop to about one every 2 s. PreStart starts it, because loop() only sees the new handler ~0.4 s after a launch and ~15 late interrupts in that window still crashed Quest for the King; the main menu ends it. Under Fab04_GlobalKernalReplace SwiftLink can run meanwhile, and its AT commands block waiting for the stack (connect, DHCP, DNS), so ProcessATCommand() unmasks IRQ_PIT while one runs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A plain TR has no Kernal Replace (Fab04_KernalReplace is TR+ only), so the poll there never started but still ran its check on every loop() and cost flash and RAM1. Guard it with Fab04_KernalReplace: the TR image is now byte-for-byte the size of main's. The ProcessATCommand() wrapper matters only when SwiftLink can run while the KERNAL is replaced, i.e. under Fab04_GlobalKernalReplace, so it is guarded by that. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
wesbiggs
force-pushed
the
kernal-fnet-loop-poll
branch
from
November 1, 2026 15:13
f9faebd to
aaa2b8c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Once Ethernet is initialized (a cable is not needed), NativeEthernet runs the whole FNET stack from a 1 ms
IntervalTimer(PIT) ISR (FNET_POLL_TIMEinNativeEthernet.h). Measured with late-ISR counters inisrPHI2, about 39 phi2 interrupts per second came in late (>1.1 µs) even though the GPIO interrupt has the higher priority. MaskingIRQ_ENETchanged nothing; maskingIRQ_PITremoved them.Under Kernal Replace, late interrupts hurt most on the first read after a
$01write, whereKernalChecksenses HIRAM before it drives the bus. Programs that switch$01constantly got corrupt reads, NMIs or froze:$01)Change
While Kernal Replace serves the KERNAL and the stack is up,
IRQ_PITis masked andFnetLoopPollService()(Teensy.ino,FLASHMEM) callsfnet_poll()fromloop()every ms. Late phi2 interrupts drop to about one every 2 s. "Serves the KERNAL" means the Kernal Replace Special IO, orfKernReplset underFab04_GlobalKernalReplace.loop()only sees the new handler ~0.4 s after a launch, and the ~15 late interrupts in that window were still enough to crash Quest for the King.InitHndlr_KERNALReplace_PreStart()therefore starts the loop poll at once (FnetLoopPollStart()), andSetUpMainMenuROM()ends it.Fab04_GlobalKernalReplace, SwiftLink can run while the KERNAL is replaced.connect, DHCP and DNS block waiting for the stack, soProcessATCommand()unmasksIRQ_PITwhile an AT command runs. The wrapper is compiled only under that flag.Fab04_KernalReplace, so the plain TR build is unchanged (same link report asmain).docs/Architecture/Constraints.mddescribes the mechanism and its two consequences: TCP is serviced only as often asloop()comes round, and new blocking network calls that can run while the KERNAL is replaced need the PIT back.Memory (link report, before → after)
--no-extensions)Testing
npm testpasses; TR and TR+ firmware build, and TR+ also builds withFab04_GlobalKernalReplacedefined.🤖 Generated with Claude Code