More on using Sprites
Assembler coding - Lesson 6
In Lesson 6 we will learn better programming techniques than lesson 5 to get the sprite moving up & down. And this time instead of just boring up & down movement we will produce a bounce effect.
Lets get straight into the coding:
10 LDA #147
20 JSR $FFD2
30 LDA #00
40 STA 53280
50 STA 53281
60 LDA #255
70 STA 53269
80 STA 53276
90 LDA #02
100 STA 53285
110 LDA #03
120 STA 53286
130 LDX #00
140 COLOUR LDA #04
150 STA 53287,X
160 INX
170 CPX #08
180 BNE COLOUR
190 LDA #64
200 LDX #00
210 BACK STA 2040,X
220 INX
230 CPX #08
240 BEQ DONE
250 LDA 2040,X
260 TAY
270 INY
280 TYA
290 JMP BACK
300 DONE CLC
310 LDA #30
320 LDX #00
330 XPOS STA 53248,X
340 ADC #30
350 INX
360 INX
370 CPX #16
380 BNE XPOS
390 MOVE LDX #00
400 DATA LDA TABLE,X
410 CMP #255
420 BNE NOTFIN
430 JMP MOVE
440 LDY #00
450 YPOS STA 53249,Y
460 INY
470 INY
480 CPY #16
490 BNE YPOS
500 INX
510 JSR DELAY
520 JMP DATA
530 DELAY LDA #50
540 STA FLAG1
550 LOOP1 LDA #50
560 STA FLAG2
570 LOOP DEC FLAG2
580 BNE LOOP
590 DEC FLAG1
600 BNE LOOP1
610 RTS
520 TABLE DFB 50,50,50,50,51,51,51,52,52,53
530 DFB 54,55,56,57,58,60,62,64,66,68
540 DFB 72,76,80,84,88,92,96,100,105,110
550 DFB 115,120,125,130,135,140,145,150,155,160
560 DFB 165,170,176,182,188,195,202,195,188,182
570 DFB 176,170,165
580 DFB 160,155,150,145,140,135,130,125,120,115
590 DFB 110,105,100,96,92,88,84,80,76,72
600 DFB 68,66,64,62,60,58,57,56,55,54
610 DFB 53,52,52,51,51,51,255
620 FLAG1 DFB 00
630 FLAG2 DFB 00
Don't be put off by all the numbers and stuff you have not seen before, i will explain everything. It is very simple, Honest!
Ok here's the run down:
10 - 180 These are exactly the same as LESSON 5 (You can change the colours etc to suit you)
190 - 290 These lines setup the sprite pointers. Sprite data again at 1000 Hex like LESSON 5. Here we use a little routine instead of like before. Here's how the routine works:
Start by loading accumulator with first value of 64 which will make Sprite 0 data pointer at 1000 Hex
Reset X register to 0
We then store the accumulator at the address (2040 + X) = 2040 i.e. here we actually make Sprite 0 data pointer point to location 1000 Hex
(Remember the formula from LESSON 5)
We then add 1 to X register and check to see if it is = 8 (i.e. done all sprite data pointers)
Then we use the BEQ instruction i.e Branch if Equal to 8 to the line labelled DONE. If not = 8 then fall through to line 250
Line 250 loads the value from location (2040 + X), remember X is still 0, giving us location 2040, and the value 64
We then transfer the Accumulator to the Y Register
Increment the Y register by 1
Transfer the Y register back to the accumulator (We did this transfer as you can't directly increment the accumulator)
Then we jump back to the line labelled back to do the next sprite data pointer
300 - 380 These set up the X position for each sprite. Again using a routine rather than set each individually.
Firstly we Clear the Carry Flag (CLC) - It is wise to do this when Adding which we will be doing shortly. The carry flag is set when you add two numbers with a result greater than 255.
We then load the accumulator with the initial x position for sprite 0 (30 Decimal)
Reset X reg to 0
Then we store the accumulator at location ( 53248 + X ), here it is 53248 + 0 = 53248 i.e. the location for Sprite 0 X position (Value 30)
We then add 30 to the accumulator -ADC #30 (Value now 60 Decimal)
+1 to the X register
+1 to the X register (We add 2 to the X register because Sprite 1 X position = 53250)
Then check to see if x = 16, i.e. all done
If not then branch to line labelled XPOS, otherwise fall through to following line
You can see that each time around 30 is added to the X position value and stored at the corresponding Sprite X position location.
390 - 520 These lines of code produce movement of the sprite in the Y direction. It is really simple to follow, it uses similar techniques to what we just did for the X position, only this time we fetch the Y position data from a data table (Termed - LOOK UP TABLE).
We load the value from the look up table
We then check the value for 255 Decimal (this is the value we have placed in the table to mean THE END)
If the value is not 255 we store the value at each Sprites Y position, and then jump to a subroutine (JSR) called DELAY.
The delay subroutine is like the delay used in LESSON 5, however this time as we already using the X and Y registers (and we don't want to overwrite them) we use the accumulator for the delay. When the routine is finished, the main program is returned to (RTS) - Return from Subroutine. The main program continues from the line below where the JSR was that called the subroutine.
If the value is 255, then this is the last data needed and so we start all over again.
It is the values in the look up table that make the bounce effect, you simply slow down the rate of movement at the top, and speed it up at the bottom of the screen. Have a look at the numbers and you will see. Please be aware that WITHOUT additional coding, the maximum number of points in the TABLE is 255 Decimal.
This is because the C64 is 8 bit, 8 bits = 255 Decimal, thus for example:
LDA TABLE,X (Max value fetched would be from location TABLE + 255)
Well, i hope again that you could follow this. You can see that it is quite straight forward to produce other effects like the caterpillar just by placing each Sprite at different heights instead of the same like this example. Have a go at moving in the X direction at the same time. Don't worry about the MSB, we will do that in another lesson.
You will also notice that the sprites flicker, which is pretty awful to look at. You use INTERRUPTS to solve this annoying problem. Using interrupts also has many other advantages like for example having more than 8 sprites on the screen at once. We will learn interrupts again in future lessons.