Take the freeze slot number in the byte order the code actually uses - #944
Open
mlund wants to merge 1 commit into
Open
Take the freeze slot number in the byte order the code actually uses#944mlund wants to merge 1 commit into
mlund wants to merge 1 commit into
Conversation
syspart_locate_freezeslot documents X as the low byte, but it pushes X then Y and pops plx before ply, so the multiply reads the low byte from Y. freeze_to_slot already asks for "Slot in XXYY", and callers follow the code rather than the comment, so correct the comment and the bounds check rather than the pops. That check rejected nothing: it fell through to the low byte whichever way the high byte compared. Fixing it exposed error paths that returned without pulling the pushed slot number. Also say why syspart_unfreeze_from_slot_trap restores only X: the trap dispatch clobbers it with tax, while Y reaches the handler untouched. Under Xemu: slot 2145 of 2045 was accepted, now refused; 0 and 1 unchanged.
mlund
force-pushed
the
fix/syspart-slot-number-byte-order
branch
from
August 20, 2026 08:35
9b7bcaa to
4e58c24
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.
syspart_locate_freezeslotsays X holds the low byte of the slot number and Y the high byte. It does the opposite and pushes X then Y, and pops with plx before ply, so plx gets what phy pushed. The multiply reads the low byte from Y.freeze_to_slotinfreeze.asmalready does it correctly, asking for "Slot in XXYY".Callers have followed the code, not the comment: the cc65 freeze menu carries ;; XXX - We had to swap the X/Y byte order around for this to work: Why???. This changes the comment and bounds check only as swapping the pops would break every caller that works today.
Measured on an R3 with 1888 slots, and under Xemu with 2045: a slot passed the documented way lands 256 slots on. Slot 1 gave base + $40000 where the slot size is $400.
Other fixes:
Bounds check never rejected anything. After comparing the high byte it fell through into the low byte comparison whichever way the first test went, so the high byte's answer was thrown away. An out-of-range slot was accepted and returned a sector past the end of the slot area. Under Xemu, slot 2145 of 2045 was accepted before this change and is refused after; slots 0 and 1 are unchanged.
Both error paths returned without pulling the slot number the routine had pushed, so rts took the caller's return address off the stack instead. Nothing triggered it, because the check accepted everything. Fixing the check hung the machine until this was fixed too.
syspart_unfreeze_from_slot_trapdeliberately restores only X. The dispatch clobbers X with tax, while Y reaches the handler from the caller untouched. TrapToHypervisor in gs4510.vhdl copies registers to the shadow set and assigns only reg_sp, reg_sph and the flags — never reg_y.Tested by assembling HICKUP and running it under Xemu with -hickup, reading the sector back from $D681 for slots 0, 1 and one past the end.