Classic Computer Magazine Archive COMPUTE! ISSUE 11 / APRIL 1981 / PAGE 107

Speeding Up The Player-Missile Demo

Larry Isaacs, Raleigh, NC

Chris Crawford's article1 on the inner workings of some of the player-missile graphics was very interesting. I'm sure all those who tried the demo program noticed the difference in speed between horizontal movement and vertical movement. This provides a very good example of the difference between the execution speed of machine language' and the execution speed of BASIC.

Horizontal movement of the "player" requires only a POKE statement. The function of the POKE statement is roughly equivalent to a single machine language instruction. This allows it to execute fairly fast. On the other hand, vertical movement of the "player" isn't nearly as simple. A FOR...NEXT statement is needed to move some data in memory. Also, vertical movement requires a more complex POKE statement. This POKE statement not only takes longer to execute, but is executed 7 times. These factors result in noticeably slower vertical movement than horizontal movement. If this FOR... NEXT loop could be replaced with some machine language, vertical movement could be brought to seemingly the same speed as horizontal movement.

The program in Listing 1 will illustrate this point. This program is a duplication of Chris Crawford's original demo with modifications for upward movement of the "player" to be done with the aid of machine language. Downward movement is still done with the FOR... NEXT loop to give a comparison. With this program you will find that it takes around three seconds to move the "player" from the bottom of the screen to the top. It will take around 17 seconds to move the "player" back to the bottom again. If the downward movement is too slow to bear, use the program in Listing 2. It has machine language for both upward and downward movement.

The machine language routines do not contain any absolute addressing, so they are relocateable. This means you can further modify the demo programs and the routines will still work. For those familiar with assembly language, here is the code for the two routines.

UP PLA DOWN PLA
PLA PLA
STA $CC STA $CC
PLA PLA
STA $CB STA $CB
LDY #$01 LDY #$06
UPLOOP LDA ($CB),Y DNLOOP LDA ($CB),Y
DEY INY
STA ($CB),Y STA ($CB),Y
INY DEY
INY DEY
CPY #$07 CPY #$FF
BNE UPLOOP BNE DNLOOP
RTS RTS

As illustrated by this example, where the speed of an operation is concerned, it is faster to use machine language. However, it may not always be better to use machine language, and using it probably won't be easier than using BASIC.

Listing 1

1 GOSUB 1000 : REM Load machine code
10 SETCOLOR 2, 0, 0 : X = 120 : Y = 48 : REM Set background color and player position
20 A = PEEK (106) - 8 : POKE 54279, A : PMBASE = 256 * A : REM Set player-missile address
30 POKE 559, 46 : POKE 53277, 3 : REM Enable PM graphics with 2-line resolution
40 POKE 53248, X : REM Set horizontal position
50 FOR I = PMBASE + 512 TO PMBASE + 640 : POKE I, O : NEXT I : REM Clear out player first
60 POKE 704, 216 : REM Set color to screen
70 FOR I = PMBASE + 512 + Y TO PMBASE + 516 + Y : READ A : POKE I, A : NEXT I : REM Draw player80 DATA 153, 189, 255, 189, 153
90 REM Now comes the motion routine
100 A = STICK(0) : IF A = 15 THEN GOTO 100
110 IF A = 11 THEN X = X - 1 : POKE 53248, X
120 IF A = 7 THEN X = X + 1 : POKE 53248, X
130 IF A = 13 THEN FOR I = 6 TO 0 STEP -1 : POKE PMBASE + 512 + Y + I,
        PEEK(PMBASE + 511 + Y + I) : NEXT I : Y = Y + 1
140 IF A = 14 THEN D = USR(UP, PMBASE + 511 + Y) : Y = Y - 1
150 GOTO 100
1000 DIM UPCODE$ (22) : UP = ADR(UPCODE$)
1010 FOR I = 1 TO 5 : READ A : NEXT I : REM Skip player data
1020 FOR I = UP TO UP+20
1030 READ BYTE : POKE I, BYTE
1040 NEXT I : RESTORE : RETURN
1050 REM Move player up code
1060 DATA 104, 104, 133, 204, 104, 133, 203
1070 DATA 160, 1, 177, 203, 136, 145, 203
1080 DATA 200, 200, 192, 7, 208, 245, 96

Listing 2

1 GOSUB 1000 : GOSUB 1100 : REM Load machine code
10 SETCOLOR 2, 0, 0 : X = 120 : Y = 48 : REM Set background color and player position
20 A = PEEK(106) - 8 : POKE 54279, A : PMBASE = 256 * A : REM Set player-missile address
30 POKE 559, 46 : POKE 53277, 3 : REM Enable PM graphics with 2-line resolution
40 POKE 53248, X : REM Set horizontal position
50 FOR I = PMBASE + 512 TO PMBASE + 640 : POKE I, 0 : NEXT I : REM Clear out player first
60 POKE 704, 216 : REM Set color to green
70 FOR I = PMBASE + 512 + Y TO PMBASE + 516 + Y : READ A : POKE I, A : NEXT I : REM Draw player
80 DATA 153, 189, 255, 189, 153
90 REM Now comes the motion routine
100 A = STICK(0) : IF A = 15 THEN GOTO 100
110 IF A = 11 THEN X = X - 1 : POKE 53248, X : GOTO 100
120 IF A = 7 THEN X = X + 1 : POKE 53248, X : GOTO 100
130 IF A = 13 THEN D = USR(DOWN, PMBASE + 511 + Y) : Y = Y + 1 : GOTO 100
140 IF A = 14 THEN D = USR(UP, PMBASE + 511 + Y) : Y = Y - 1
150 GOTO 100
1000 DIM UPC0DE$(22) : UP = ADR(UPCODE$)
1010 FOR I = 1 TO 5 : READ A : NEXT I : REM Skip player data
1020 FOR I = UP TO UP + 20
1030 READ BYTE : POKE I, BYTE
1040 NEXT I : RETURN
1050 REM Move player up code
1060 DATA 104, 104, 133, 204, 104, 133, 203
1070 DATA 160, 1, 177, 203, 136, 145, 203
1080 DATA 200, 200, 192, 7, 208, 245, 96
1100 DIM DOWNCODE$(22) : DOWN = ADR(DOWNCODE $)
1120 FOR I = DOWN TO DOWN + 20
1130 READ BYTE : POKE I, BYTE
1140 NEXT I : RESTORE : RETURN
1150 REM Move player down code
1160 DATA 104, 104, 133, 204, 104, 133, 203
1170 DATA 160, 6, 177, 203, 200, 145, 203
1180 DATA 136, 136, 192, 255, 208, 245, 96