Skip to navigation

Revs on the BBC Micro

Screen buffer: CopyDashData

Name: CopyDashData [Show more] Type: Subroutine Category: Screen buffer Summary: Copy the dash data from the main game code to screen memory, and vice versa Deep dive: The jigsaw puzzle binary
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * MainDrivingLoop (Part 1 of 5) calls CopyDashData * MainDrivingLoop (Part 5 of 5) calls CopyDashData

Arguments: A The direction of the copy: * Bit 7 clear = copy from game code to screen memory * Bit 7 set = copy from screen memory to game code
.CopyDashData STA T \ Store A in T, so bit 7 of T determines the direction \ of the copy LDX #3 \ First, we copy the four bytes at dashDataAddress to \ P, Q, R and S, so set a loop counter in X for the four \ bytes .dash1 LDA dashDataAddress,X \ Copy the X-th byte of dashDataAddress to the X-th STA P,X \ byte of P DEX \ Decrement the loop counter BPL dash1 \ Loop back until we have copied all four bytes \ So we now have the following: \ \ (Q P) = the location of the first block in the main \ game code \ \ (S R) = the location of the first block in screen \ memory (i.e. at the end of screen memory, as \ the first block in the game code is the last \ block in screen memory) \ \ We now copy 41 blocks of memory from one address to \ the other, with the direction determined by the value \ of bit 7 in T (which we set above) \ \ We work through each block by starting at offset 79 \ from the start of (Q P) and (S R), and decrementing \ the offset until it matches the dashDataOffset value \ for this block \ \ We store the block number (which goes from 0 to 40) \ in X, and the offset (which goes from 79 down to \ dashDataOffset,X + 1) in Y LDX #0 \ Set a block counter in X to count through 41 blocks .dash2 LDY #79 \ Each block we want to copy ends at the start address \ plus 79, so set an index counter in Y, which we can \ use to work our way backwards through each byte in \ the block LDA #0 \ Set V = 0 to act as a byte counter to go from 0 to the STA V \ number of bytes copied .dash3 BIT T \ If bit 7 of T is set, skip the following two BMI dash4 \ instructions so we copy from (S R) to (Q P) LDA (P),Y \ Copy the Y-th byte of (Q P) to the Y-th byte of (S R) STA (R),Y .dash4 LDA (R),Y \ Copy the Y-th byte of (S R) to the Y-th byte of (Q P) STA (P),Y INC V \ Increment the byte counter DEY \ Decrement the index counter TYA \ If Y <> the dashDataOffset value for block X, loop CMP dashDataOffset,X \ to keep copying the contents of this block BNE dash3 \ We have copied a block of memory, so we now need to \ update (Q P) and (S R) to point to the next block to \ copy \ \ When in screen memory, the blocks are stored one after \ the other, in reverse order, so the address of the \ next block to copy is the start address of the block \ we just copied in (S R), minus the size of the block \ we just copied, which is in V, so the next block will \ be at (S R) - V LDA R \ Set (S R) = (S R) - V SEC \ SBC V \ starting with the low bytes STA R BCS dash5 \ And decrementing the high byte of (S R) if the low DEC S \ byte wraps around .dash5 \ When in the main game code, the blocks are stored \ every &80 bytes, so the address of the next block is \ (Q P) + &80 \ \ Note that each block takes up a different amount of \ memory, as follows: \ \ Block starts at: (Q P) + dashDataOffset,X + 1 \ Block ends at: (Q P) + 79 \ \ It's the value of (Q P) that is spaced out by &80 for \ each block, rather than the actual data in the block \ (for each block, (Q P) to (Q P) + dashDataOffset,X \ is used for other purposes) LDA P \ Set (Q P) = (Q P) + &80 CLC \ ADC #&80 \ starting with the low bytes STA P BCC dash6 \ And incrementing the high byte of (Q P) if the low INC Q \ byte overflows .dash6 INX \ Increment the block counter to point to the next block \ to copy CPX #41 \ Loop back to copy the next block until we have copied BNE dash2 \ all 41 blocks RTS \ Return from the subroutine