ORG &790E .SwapCode LDA #200 \ Call OSBYTE with A = 200, X = 3 and Y = 0 to disable LDX #3 \ the ESCAPE key and clear memory if the BREAK key is LDY #0 \ pressed JSR OSBYTE LDA #140 \ Call OSBYTE with A = 140 and X = 0 to select the tape LDX #0 \ filing system (i.e. do a *TAPE command) JSR OSBYTE \ We now want to move the track data from trackLoad \ (which is where the loading process loads the track \ file) to trackData (which is where the game expects \ to find the track data) \ \ At the same time, we also want to move the data that \ is currently at trackData, which is part of the \ dashboard image, into screen memory at trackLoad \ \ trackLoad is &70DB and trackData is &5300, so we \ want to do the following: \ \ * Swap &70DB-&77FF and &5300-&5A24 \ \ At the same time, we want to perform a checksum on the \ track data and compare the results with the four \ checksum bytes in trackChecksum \ \ The following does this in batches of 256 bytes, using \ Y as an index that goes from 0 to 255. The checks are \ done at the end of the loop, and they check the value \ of Y first (against &25), and then the high byte of \ the higher address (against &77) but only if the Y \ test fails, so the swaps end up being: \ \ * Swap &5300 + 0-255 with &70DB + 0-255 \ * Swap &5400 + 0-255 with &71DB + 0-255 \ * Swap &5500 + 0-255 with &72DB + 0-255 \ * Swap &5600 + 0-255 with &73DB + 0-255 \ * Swap &5700 + 0-255 with &74DB + 0-255 \ * Swap &5800 + 0-255 with &75DB + 0-255 \ * Swap &5900 + 0-255 with &76DB + 0-255 \ * Swap &5A00 + 0-&24 with &77DB + 0-&24 \ \ So the last operation swaps &5A24 and &77FF LDA #LO(trackData) \ Set (Q P) = trackData STA P \ LDA #HI(trackData) \ so that's one address for the swap STA Q LDA #LO(trackLoad) \ Set (S R) = trackLoad STA R \ LDA #HI(trackLoad) \ so that's the other address for the swap STA S LDY #0 \ Set a byte counter in Y for the swap .swap1 LDA (R),Y \ Swap the Y-th bytes of (Q P) and (S R) PHA LDA (P),Y STA (R),Y PLA STA (P),Y AND #3 \ Decrement the relevant checksum byte TAX \ DEC trackChecksum,X \ The checksum bytes work like this: \ \ * trackChecksum+0 counts the number of data bytes \ ending in %00 \ \ * trackChecksum+1 counts the number of data bytes \ ending in %01 \ \ * trackChecksum+2 counts the number of data bytes \ ending in %10 \ \ * trackChecksum+3 counts the number of data bytes \ ending in %11 \ \ This code checks off the relevant checksum byte for \ the data byte in A, so if all the data is correct, \ this will eventually decrement all four bytes to zero INY \ Increment the loop counter BNE swap2 \ If we have finished swapping a whole page of bytes, INC Q \ increment the high bytes of (Q P) and (S R) to move INC S \ on to the next page .swap2 CPY #&25 \ If we have not yet reached addresses &5A24 and &77FF, BNE swap1 \ jump back to swap1 to keep swapping data LDA S CMP #&77 BNE swap1 LDX #3 \ The data swap is now done, so we now check that all \ three checksum bytes at trackChecksum are zero, so set \ a counter in X to work through the four bytes .swap3 LDA trackChecksum,X \ If the X-th checksum byte is non-zero, the checksum BNE swap4 \ has failed, so jump to swap4 to reset the machine DEX \ Decrement the checksum byte counter BPL swap3 \ Loop back to check the next checksum byte BMI MoveCode \ If we get here then all four checksum bytes are zero, \ so jump to swap4 to keep going (this BMI is \ effectively a JMP as we just passed through a BPL) .swap4 JMP (&FFFC) \ The checksum has failed, so reset the machineName: SwapCode [Show more] Type: Subroutine Category: Setup Summary: Move the track data to the right place and run a checksum on it Deep dive: The jigsaw puzzle binaryContext: See this subroutine in context in the source code References: This subroutine is called as follows: * Entry calls SwapCode
[X]
Subroutine MoveCode (category: Setup)
Move and reset various blocks around in memory
[X]
Configuration variable OSBYTE = &FFF4
The address for the OSBYTE routine
[X]
Label swap1 is local to this routine
[X]
Label swap2 is local to this routine
[X]
Label swap3 is local to this routine
[X]
Label swap4 is local to this routine
[X]
Configuration variable trackChecksum = &7800
The address of the checksums in the track data file after it is loaded but before it is moved in memory
[X]
Workspace trackData (category: Track data)
This is where the track data gets loaded
[X]
Configuration variable trackLoad = &70DB
The load address of the track data file