Optimizing an Imaginary Sprite Part 4

<< Previous | Next >>

Version 3

This version came from Pere Serrat. In Simon’s own words, “WOW !!! now this rocks….” It’s basically a complete re write, making much better use of nibble testing.


Version 2 on the left, 3 on the right.

Looking at version 3, on the right side:

Lines 3–5 is the same old same old, just preloading everything with the sprite, background and destination (mixbuf).

Lines 6–8 load up registers A and B with the data from the sprite and background in preparation to inspect them.

Lines 9–15, we want to work with the left nibble, so we mask off the right with the ANDA. ANDA will set the zero (Z) flag if the result is 0, and BEQ will branch if Z is set. So what ends up happening is if the left nibble is not zero, we store the byte into the mixbuf (std ,u) then proceed to seeN2 were can can check the right nibble. If however the left nibble is zero, the code ends up at useB1 and will store the background nibble instead.

Lines 17–29 deal with the right nibble in a similar way. However instead of an sta ,u or a stb ,u which would store A or B to the mixbuf, we need to preserve what is already there. We do that at line 22 and 26 with an ora ,u and orb ,u which does a logical or of A and the byte in mixbuf, storing the result in A. Once or’ed together we can store the byte into the mixbuf with sta ,u.

I think line 28 & 29 is a bug. Considering line 24 bra ctrl would end up at the wrong place. I think the ctrl label should be going to line 28, where we check for the end of the buffer.

24                 bra     ctrl            ; go control end
25 useB2           andb    #$0f            ; use right nibble
26                 orb     ,u              ; add dest buffer
27                 stb     ,u+             ; update buffer
28                 cmpx    #sp_end         ; got to end?
29 ctrl            bne     loop1           ; no loopback

Line 28–30 decide if we have processed the last byte of the sprite and jump to the top if not.

Next, Version 5