Beyond Basic - Part 4
Written By: Tony Cruise
First Published: Micro’s Gazette – Issue 002 (March/April 1989)
This issue I will start to cover some of the routines that will be used in our extended Basic. We will start off with the new sprite commands.
You can have up to 32 sprites on the screen at once but if you want to move more than about five or six, your program slows down considerably. The routines this issue allow you to specify X and Y velocities for each of the 32 sprites and then they will be moved independently of your Basic program.
I have included an assembler listing explaining how it works as well as a basic loader program for those people who do not have assemblers and a demonstration program.
Machine Code Program
1 ; | Program to move sprites by velocity | |||
2 ; | ||||
D000 | 3 ORIGIN | ORG D000H | ||
4 ; | ||||
5 ; | Label settings | |||
6 ; | ||||
7 HTIMI | EQU FD9FH | ; Hook jump – Timer | ||
8 SCRMOD | EQU FCAFH | ; RAM storage – Screen mode | ||
9 SETWRT | EQU 0053H | ; ROM routine – Set video write | ||
10 SETRD | EQU 0050H | ; ROM routine – Set video read | ||
11 ; | ||||
D000 | 3EC3 | 12 START | LD A,C3H | ; Value for JUMP instruction |
D002 | 329FFD | 13 | LD (HTIMI),A | ; Load into Hook |
D005 | 210CD0 | 14 | LD HL,QUE | ; Address to jump to |
D008 | 22A0FD | 15 | LD (HTIMI+1),HL | ; Load into Hook |
D00B | C9 | 16 | RET | ; |
17 ; | ||||
D00C | CD14D0 | 18 QUE | CALL SPRMOV | ; Call SPRMOV routine |
D00F | F7879C77 | 19 | DEFB F7H,87H,9CH,77H | ; Disk delay routine, remove if |
D013 | C9 | 20 | RET | ; up do not have a disk drive |
21 ; | ||||
D014 | 3AAFFC | 22 SPRMOV | LD A,(SCRMOD) | ; Get screen mode |
D017 | FE00 | 23 | CP 0 | ; |
D019 | C8 | 24 | RET Z | ; Make sure not screen 0 |
D01A | 3A47D1 | 25 | LD A,(MOVFLG) | ; |
D01D | FE00 | 26 | CP 0 | ; Get move flag |
D01F | C8 | 27 | RET Z | ; |
D020 | 21001B | 28 | LD HL,1B00H | ; Return if move set to off |
D023 | 1187D0 | 29 | LD DE,SPRTBL | ; |
D026 | 018000 | 30 | LD BC,128 | ; |
D029 | CD78D0 | 31 | CALL LDIRVM | ; Get sprite table |
D02C | 2187D0 | 32 | LD HL,SPRTBL | ; Set pointer to sprite table |
D02F | 0620 | 33 | LD B,32 | ; Set loop counter |
D031 | 1107D1 | 34 | LD DE,SPRVEL | ; Set point to velocities |
D034 | 7E | 35 LOOP1 | LD A,(HL) | ; |
D035 | FED1 | 36 | CP 209 | ; Is the sprite on screen? |
D037 | 281A | 37 | JR Z,LOOP2 | ; No skip |
D039 | 4F | 38 | LD C,A | ; |
D03A | 1A | 39 | LD A,(DE) | ; Get Y velocity |
D03B | 81 | 40 | ADD A,C | ; Add Y velocity |
D03C | FEDC | 41 | CP 220 | ; Off Top of screen |
D03E | 3804 | 42 | JR C,LOOP3 | ; No skip |
D040 | 3EC0 | 43 | LD A,192 | ; Yes, correct value |
D042 | 1805 | 44 | JR LOOP4 | ; |
D044 | FEC0 | 45 LOOP3 | CP 192 | ; Off bottom of screen? |
D046 | 3801 | 46 | JR C,LOOP4 | ; No skip |
D048 | AF | 47 | XOR A | ; Yes, correct value |
D049 | 77 | 48 LOOP4 | LD (HL),A | ; Store new value |
D04A | 23 | 49 | INC HL | ; |
D04B | 13 | 50 | INC DE | ; Increment pointers |
D04C | 7E | 51 | LD A,(HL) | ; |
D04D | 4F | 52 | LD C,A | ; |
D04E | 1A | 53 | LD A,(DE) | ; Get X velocity |
D04F | 81 | 54 | ADD A,C | ; Add X velocity |
D050 | 77 | 55 | LD (HL),A | ; Store new value |
D051 | 2B | 56 | DEC HL | ; |
D052 | 1B | 57 | DEC DE | ; Restore pointers |
D053 | 13 | 58 LOOP2 | INC DE | ; |
D054 | 13 | 59 | INC DE | ; |
D055 | 23 | 60 | INC HL | ; |
D056 | 23 | 61 | INC HL | ; |
D057 | 23 | 62 | INC HL | ; |
D058 | 23 | 63 | INC HL | ; Update pointers |
D059 | 05 | 64 | DEC B | ; Decrease loop counter |
D05A | 20D8 | 65 | JR NZ,LOOP1 | ; Next loop |
D05C | 21001B | 66 | LD HL,1B00H | ; |
D05F | 1187D0 | 67 | LD DE,SPRTBL | ; |
D062 | 018000 | 68 | LD BC,128 | ; |
D065 | CD69D0 | 69 | CALL LDIRMV | ; Save sprite table |
D068 | C9 | 70 | RET | ; |
71 ; | ||||
72 ; | Move a block of memory from video RAM | |||
73 ; | ||||
D069 | CD5300 | 74 LDIRMV | CALL SETWRT | |
D06C | 1A | 75 LP1 | LD A,(DE) | |
D06D | D398 | 76 | OUT (98H),A | |
D06F | 13 | 77 | INC DE | |
D070 | 0B | 78 | DEC BC | |
D071 | 78 | 79 | LD A,B | |
D072 | B1 | 80 | OR C | |
D073 | FE00 | 81 | CP 0 | |
D075 | 20F5 | 82 | JR NZ,LP1 | |
D077 | C9 | 83 | RET | |
84 ; | ||||
85 ; | Move a block of memory to video RAM | |||
86 ; | ||||
D078 | CD5000 | 87 LDIRVM | CALL SETRD | |
D07B | DB98 | 88 LP2 | IN A,(98H) | |
D07D | 12 | 89 | LD (DE),A | |
D07E | 13 | 90 | INC DE | |
D07F | 0B | 91 | DEC BC | |
D080 | 78 | 92 | LD A,B | |
D081 | B1 | 93 | OR C | |
D082 | FE00 | 94 | CP 0 | |
D084 | 20F5 | 95 | JR NZ,LP2 | |
D086 | C9 | 96 | RET | |
97 ; | ||||
98 ; | Data storage | |||
99 ; | ||||
D087 | 100 SPRTBL | DEFS 128 | ||
D107 | 101 SPRVEL | DEFS 64 | ||
D147 | 00 | 102 MOVFLG | DEFB 0 | |
103 END |
Basic Loader
10 CLS:CLEAR 200,&HCFFF:DEFINTA-Z:A=&HD000
20 READ A$:IF A$ <> “@” THEN POKE A, VAL(“&H”+A$):A=A+1:GOTO 20
30 POKE &HD147,0
40 PRINT” INSERT TAPE/DISK TO SAVE PROGRAM”
50 PRINT” AND PRESS ANY KEY”
60 A$=INPUT$(1):PRINT:PRINT “ SAVING ....”
70 BSAVE”SPRITE.OBJ”,&HD000,&HD147
80 END
100 DATA 3E,C3,32,9F,FD,21,0C,D0,22,A0,FD,C9,CD,14,D0
110 DATA F7,87,9C,77 (or DATA 00,00,00,00 if you don’t have a disk drive)
120 DATA C9,3A,AF,FC,FE,00,C8,3A,47,D1,FE,00,C8,21,00
130 DATA 1B,11,87,D0,01,80,00,CD,78,D0,21,87,D0,06,20
140 DATA 11,07,D1,7E,FE,D1,28,1A,4F,1A,81,FE,DC,38,04
150 DATA 3E,C0,18,05,FE,C0,38,01,AF,77,23,13,7E,4F,1A
160 DATA 81,77,2B,1B,13,13,23,23,23,23,05,20,D8,21,00
170 DATA 1B,11,87,D0,01,80,00,CD,69,D0,C9,CD,53,00,1A
180 DATA D3,98,13,0B,78,B1,FE,00,20,F5,C9,CD,50,00,DB
190 DATA 98,12,13,0B,78,B1,FE,00,20,F5,C9,@
Basic Program Example
10 COLOR 15,1,9:SCREEN 2,2:SPRITE$(0) = STRING$(32,244):DEF FNA(X) = INT(RND(1)*X)+1:A = RND(-TIME)
20 STOP ON:ON STOP GOSUB 110
30 POKE &HD147,1:FOR A=0 TO 31
40 PUT SPRITE A,(128,96),FNA(15),0
50 XV=FNA(5)-3:IF XV<0 THEN XV=XV+256
60 YV=FNA(5)-3:IF YV<0 THEN YV=YV+256
70 IF XV+YV=0 THEN 50
80 POKE &HD107+A*2,YV:POKE &HD108+A*2,XV:NEXT
90 IF NOT(STRIG(0)) THEN 90 ELSE POKE &HD147,0
100 IF NOT(STRIG(0)) THEN 100 ELSE POLE &HD147,1:GOTO 80
110 POKE &HD147,0:END
Type in the machine code loader first and save it to disk or tape. Now type in the Basic example program and save it to tape or disk. Then use BLOAD”SPRITE.OBJ”,R to run the machine code program and then RUN the example Basic program.
Next month I will cover the collision testing routines. Bye for now!