{"id":364,"date":"2025-05-17T16:59:47","date_gmt":"2025-05-17T06:59:47","guid":{"rendered":"http:\/\/electricadventures.net\/?p=364"},"modified":"2025-05-17T16:59:47","modified_gmt":"2025-05-17T06:59:47","slug":"beyond-basic-part-4","status":"publish","type":"post","link":"https:\/\/electricadventures.net\/?p=364","title":{"rendered":"Beyond Basic &#8211; Part 4"},"content":{"rendered":"\n<p><strong>Written By:<\/strong>&nbsp;Tony Cruise<\/p>\n\n\n\n<p><strong>First Published:<\/strong>&nbsp;Micro\u2019s Gazette \u2013 Issue 002 (March\/April 1989)<\/p>\n\n\n\n<p>&nbsp;This issue I will start to cover some of the routines that will be used in our extended Basic.&nbsp;&nbsp;We will start off with the new sprite commands.<\/p>\n\n\n\n<p>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.\u00a0\u00a0The routines in 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.<\/p>\n\n\n\n<p>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.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Machine Code Program<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>&nbsp;<\/td><td>&nbsp;<\/td><td>1 ;<\/td><td>Program to move sprites by velocity<\/td><td><\/td><\/tr><tr><td>&nbsp;<\/td><td>&nbsp;<\/td><td>2 ;<\/td><td>&nbsp;<\/td><td>&nbsp;<\/td><\/tr><tr><td>D000<\/td><td>&nbsp;<\/td><td>3 ORIGIN<\/td><td>ORG D000H<\/td><td>&nbsp;<\/td><\/tr><tr><td>&nbsp;<\/td><td>&nbsp;<\/td><td>4 ;<\/td><td>&nbsp;<\/td><td>&nbsp;<\/td><\/tr><tr><td>&nbsp;<\/td><td>&nbsp;<\/td><td>5 ;<\/td><td>Label settings<\/td><td>&nbsp;<\/td><\/tr><tr><td>&nbsp;<\/td><td>&nbsp;<\/td><td>6 ;<\/td><td>&nbsp;<\/td><td>&nbsp;<\/td><\/tr><tr><td>&nbsp;<\/td><td>&nbsp;<\/td><td>7 HTIMI<\/td><td>EQU FD9FH<\/td><td>; Hook jump \u2013 Timer<\/td><\/tr><tr><td>&nbsp;<\/td><td>&nbsp;<\/td><td>8 SCRMOD<\/td><td>EQU FCAFH<\/td><td>; RAM storage \u2013 Screen mode<\/td><\/tr><tr><td>&nbsp;<\/td><td>&nbsp;<\/td><td>9 SETWRT<\/td><td>EQU 0053H<\/td><td>; ROM routine \u2013 Set video write<\/td><\/tr><tr><td>&nbsp;<\/td><td>&nbsp;<\/td><td>10 SETRD<\/td><td>EQU 0050H<\/td><td>; ROM routine \u2013 Set video read<\/td><\/tr><tr><td>&nbsp;<\/td><td>&nbsp;<\/td><td>11 ;<\/td><td>&nbsp;<\/td><td>&nbsp;<\/td><\/tr><tr><td>D000<\/td><td>3EC3<\/td><td>12 START<\/td><td>LD A,C3H<\/td><td>; Value for JUMP instruction<\/td><\/tr><tr><td>D002<\/td><td>329FFD<\/td><td>13<\/td><td>LD (HTIMI),A<\/td><td>; Load into Hook<\/td><\/tr><tr><td>D005<\/td><td>210CD0<\/td><td>14<\/td><td>LD HL,QUE<\/td><td>; Address to jump to<\/td><\/tr><tr><td>D008<\/td><td>22A0FD<\/td><td>15<\/td><td>LD (HTIMI+1),HL<\/td><td>; Load into Hook<\/td><\/tr><tr><td>D00B<\/td><td>C9<\/td><td>16<\/td><td>RET<\/td><td>;<\/td><\/tr><tr><td>&nbsp;<\/td><td>&nbsp;<\/td><td>17 ;<\/td><td>&nbsp;<\/td><td>&nbsp;<\/td><\/tr><tr><td>D00C<\/td><td>CD14D0<\/td><td>18 QUE<\/td><td>CALL SPRMOV<\/td><td>; Call SPRMOV routine<\/td><\/tr><tr><td>D00F<\/td><td>F7879C77<\/td><td>19<\/td><td>DEFB F7H,87H,9CH,77H<\/td><td>; Disk delay routine, remove if<\/td><\/tr><tr><td>D013<\/td><td>C9<\/td><td>20<\/td><td>RET<\/td><td>; up do not have a disk drive<\/td><\/tr><tr><td>&nbsp;<\/td><td>&nbsp;<\/td><td>21 ;<\/td><td>&nbsp;<\/td><td>&nbsp;<\/td><\/tr><tr><td>D014<\/td><td>3AAFFC<\/td><td>22 SPRMOV<\/td><td>LD A,(SCRMOD)<\/td><td>; Get screen mode<\/td><\/tr><tr><td>D017<\/td><td>FE00<\/td><td>23<\/td><td>CP 0<\/td><td>;<\/td><\/tr><tr><td>D019<\/td><td>C8<\/td><td>24<\/td><td>RET Z<\/td><td>; Make sure not screen 0<\/td><\/tr><tr><td>D01A<\/td><td>3A47D1<\/td><td>25<\/td><td>LD A,(MOVFLG)<\/td><td>;<\/td><\/tr><tr><td>D01D<\/td><td>FE00<\/td><td>26<\/td><td>CP 0<\/td><td>; Get move flag<\/td><\/tr><tr><td>D01F<\/td><td>C8<\/td><td>27<\/td><td>RET Z<\/td><td>;<\/td><\/tr><tr><td>D020<\/td><td>21001B<\/td><td>28<\/td><td>LD HL,1B00H<\/td><td>; Return if move set to off<\/td><\/tr><tr><td>D023<\/td><td>1187D0<\/td><td>29<\/td><td>LD DE,SPRTBL<\/td><td>;<\/td><\/tr><tr><td>D026<\/td><td>018000<\/td><td>30<\/td><td>LD BC,128<\/td><td>;<\/td><\/tr><tr><td>D029<\/td><td>CD78D0<\/td><td>31<\/td><td>CALL LDIRVM<\/td><td>; Get sprite table<\/td><\/tr><tr><td>D02C<\/td><td>2187D0<\/td><td>32<\/td><td>LD HL,SPRTBL<\/td><td>; Set pointer to sprite table<\/td><\/tr><tr><td>D02F<\/td><td>0620<\/td><td>33<\/td><td>LD B,32<\/td><td>; Set loop counter<\/td><\/tr><tr><td>D031<\/td><td>1107D1<\/td><td>34<\/td><td>LD DE,SPRVEL<\/td><td>; Set point to velocities<\/td><\/tr><tr><td>D034<\/td><td>7E<\/td><td>35 LOOP1<\/td><td>LD A,(HL)<\/td><td>;<\/td><\/tr><tr><td>D035<\/td><td>FED1<\/td><td>36<\/td><td>CP 209<\/td><td>; Is the sprite on screen?<\/td><\/tr><tr><td>D037<\/td><td>281A<\/td><td>37<\/td><td>JR Z,LOOP2<\/td><td>; No skip<\/td><\/tr><tr><td>D039<\/td><td>4F<\/td><td>38<\/td><td>LD C,A<\/td><td>;<\/td><\/tr><tr><td>D03A<\/td><td>1A<\/td><td>39<\/td><td>LD A,(DE)<\/td><td>; Get Y velocity<\/td><\/tr><tr><td>D03B<\/td><td>81<\/td><td>40<\/td><td>ADD A,C<\/td><td>; Add Y velocity<\/td><\/tr><tr><td>D03C<\/td><td>FEDC<\/td><td>41<\/td><td>CP 220<\/td><td>; Off Top of screen<\/td><\/tr><tr><td>D03E<\/td><td>3804<\/td><td>42<\/td><td>JR C,LOOP3<\/td><td>; No skip<\/td><\/tr><tr><td>D040<\/td><td>3EC0<\/td><td>43<\/td><td>LD A,192<\/td><td>; Yes, correct value<\/td><\/tr><tr><td>D042<\/td><td>1805<\/td><td>44<\/td><td>JR LOOP4<\/td><td>;<\/td><\/tr><tr><td>D044<\/td><td>FEC0<\/td><td>45 LOOP3<\/td><td>CP 192<\/td><td>; Off bottom of screen?<\/td><\/tr><tr><td>D046<\/td><td>3801<\/td><td>46<\/td><td>JR C,LOOP4<\/td><td>; No skip<\/td><\/tr><tr><td>D048<\/td><td>AF<\/td><td>47<\/td><td>XOR A<\/td><td>; Yes, correct value<\/td><\/tr><tr><td>D049<\/td><td>77<\/td><td>48 LOOP4<\/td><td>LD (HL),A<\/td><td>; Store new value<\/td><\/tr><tr><td>D04A<\/td><td>23<\/td><td>49<\/td><td>INC HL<\/td><td>;<\/td><\/tr><tr><td>D04B<\/td><td>13<\/td><td>50<\/td><td>INC DE<\/td><td>; Increment pointers<\/td><\/tr><tr><td>D04C<\/td><td>7E<\/td><td>51<\/td><td>LD A,(HL)<\/td><td>;<\/td><\/tr><tr><td>D04D<\/td><td>4F<\/td><td>52<\/td><td>LD C,A<\/td><td>;<\/td><\/tr><tr><td>D04E<\/td><td>1A<\/td><td>53<\/td><td>LD A,(DE)<\/td><td>; Get X velocity<\/td><\/tr><tr><td>D04F<\/td><td>81<\/td><td>54<\/td><td>ADD A,C<\/td><td>; Add X velocity<\/td><\/tr><tr><td>D050<\/td><td>77<\/td><td>55<\/td><td>LD (HL),A<\/td><td>; Store new value<\/td><\/tr><tr><td>D051<\/td><td>2B<\/td><td>56<\/td><td>DEC HL<\/td><td>;<\/td><\/tr><tr><td>D052<\/td><td>1B<\/td><td>57<\/td><td>DEC DE<\/td><td>; Restore pointers<\/td><\/tr><tr><td>D053<\/td><td>13<\/td><td>58 LOOP2<\/td><td>INC DE<\/td><td>;<\/td><\/tr><tr><td>D054<\/td><td>13<\/td><td>59<\/td><td>INC DE<\/td><td>;<\/td><\/tr><tr><td>D055<\/td><td>23<\/td><td>60<\/td><td>INC HL<\/td><td>;<\/td><\/tr><tr><td>D056<\/td><td>23<\/td><td>61<\/td><td>INC HL<\/td><td>;<\/td><\/tr><tr><td>D057<\/td><td>23<\/td><td>62<\/td><td>INC HL<\/td><td>;<\/td><\/tr><tr><td>D058<\/td><td>23<\/td><td>63<\/td><td>INC HL<\/td><td>; Update pointers<\/td><\/tr><tr><td>D059<\/td><td>05<\/td><td>64<\/td><td>DEC B<\/td><td>; Decrease loop counter<\/td><\/tr><tr><td>D05A<\/td><td>20D8<\/td><td>65<\/td><td>JR NZ,LOOP1<\/td><td>; Next loop<\/td><\/tr><tr><td>D05C<\/td><td>21001B<\/td><td>66<\/td><td>LD HL,1B00H<\/td><td>;<\/td><\/tr><tr><td>D05F<\/td><td>1187D0<\/td><td>67<\/td><td>LD DE,SPRTBL<\/td><td>;<\/td><\/tr><tr><td>D062<\/td><td>018000<\/td><td>68<\/td><td>LD BC,128<\/td><td>;<\/td><\/tr><tr><td>D065<\/td><td>CD69D0<\/td><td>69<\/td><td>CALL LDIRMV<\/td><td>; Save sprite table<\/td><\/tr><tr><td>D068<\/td><td>C9<\/td><td>70<\/td><td>RET<\/td><td>;<\/td><\/tr><tr><td>&nbsp;<\/td><td>&nbsp;<\/td><td>71 ;<\/td><td>&nbsp;<\/td><td>&nbsp;<\/td><\/tr><tr><td>&nbsp;<\/td><td>&nbsp;<\/td><td>72 ;<\/td><td>Move a block of memory from video RAM<\/td><td><\/td><\/tr><tr><td>&nbsp;<\/td><td>&nbsp;<\/td><td>73 ;<\/td><td>&nbsp;<\/td><td>&nbsp;<\/td><\/tr><tr><td>D069<\/td><td>CD5300<\/td><td>74 LDIRMV<\/td><td>CALL SETWRT<\/td><td>&nbsp;<\/td><\/tr><tr><td>D06C<\/td><td>1A<\/td><td>75 LP1<\/td><td>LD A,(DE)<\/td><td>&nbsp;<\/td><\/tr><tr><td>D06D<\/td><td>D398<\/td><td>76<\/td><td>OUT (98H),A<\/td><td>&nbsp;<\/td><\/tr><tr><td>D06F<\/td><td>13<\/td><td>77<\/td><td>INC DE<\/td><td>&nbsp;<\/td><\/tr><tr><td>D070<\/td><td>0B<\/td><td>78<\/td><td>DEC BC<\/td><td>&nbsp;<\/td><\/tr><tr><td>D071<\/td><td>78<\/td><td>79<\/td><td>LD A,B<\/td><td>&nbsp;<\/td><\/tr><tr><td>D072<\/td><td>B1<\/td><td>80<\/td><td>OR C<\/td><td>&nbsp;<\/td><\/tr><tr><td>D073<\/td><td>FE00<\/td><td>81<\/td><td>CP 0<\/td><td>&nbsp;<\/td><\/tr><tr><td>D075<\/td><td>20F5<\/td><td>82<\/td><td>JR NZ,LP1<\/td><td>&nbsp;<\/td><\/tr><tr><td>D077<\/td><td>C9<\/td><td>83<\/td><td>RET<\/td><td>&nbsp;<\/td><\/tr><tr><td>&nbsp;<\/td><td>&nbsp;<\/td><td>84 ;<\/td><td>&nbsp;<\/td><td>&nbsp;<\/td><\/tr><tr><td>&nbsp;<\/td><td>&nbsp;<\/td><td>85 ;<\/td><td>Move a block of memory to video RAM<\/td><td><\/td><\/tr><tr><td>&nbsp;<\/td><td>&nbsp;<\/td><td>86 ;<\/td><td>&nbsp;<\/td><td>&nbsp;<\/td><\/tr><tr><td>D078<\/td><td>CD5000<\/td><td>87 LDIRVM<\/td><td>CALL SETRD<\/td><td>&nbsp;<\/td><\/tr><tr><td>D07B<\/td><td>DB98<\/td><td>88 LP2<\/td><td>IN A,(98H)<\/td><td>&nbsp;<\/td><\/tr><tr><td>D07D<\/td><td>12<\/td><td>89<\/td><td>LD (DE),A<\/td><td>&nbsp;<\/td><\/tr><tr><td>D07E<\/td><td>13<\/td><td>90<\/td><td>INC DE<\/td><td>&nbsp;<\/td><\/tr><tr><td>D07F<\/td><td>0B<\/td><td>91<\/td><td>DEC BC<\/td><td>&nbsp;<\/td><\/tr><tr><td>D080<\/td><td>78<\/td><td>92<\/td><td>LD A,B<\/td><td>&nbsp;<\/td><\/tr><tr><td>D081<\/td><td>B1<\/td><td>93<\/td><td>OR C<\/td><td>&nbsp;<\/td><\/tr><tr><td>D082<\/td><td>FE00<\/td><td>94<\/td><td>CP 0<\/td><td>&nbsp;<\/td><\/tr><tr><td>D084<\/td><td>20F5<\/td><td>95<\/td><td>JR NZ,LP2<\/td><td>&nbsp;<\/td><\/tr><tr><td>D086<\/td><td>C9<\/td><td>96<\/td><td>RET<\/td><td>&nbsp;<\/td><\/tr><tr><td>&nbsp;<\/td><td>&nbsp;<\/td><td>97 ;<\/td><td>&nbsp;<\/td><td>&nbsp;<\/td><\/tr><tr><td>&nbsp;<\/td><td>&nbsp;<\/td><td>98 ;<\/td><td>Data storage<\/td><td>&nbsp;<\/td><\/tr><tr><td>&nbsp;<\/td><td>&nbsp;<\/td><td>99 ;<\/td><td>&nbsp;<\/td><td>&nbsp;<\/td><\/tr><tr><td>D087<\/td><td>&nbsp;<\/td><td>100 SPRTBL<\/td><td>DEFS 128<\/td><td>&nbsp;<\/td><\/tr><tr><td>D107<\/td><td>&nbsp;<\/td><td>101 SPRVEL<\/td><td>DEFS 64<\/td><td>&nbsp;<\/td><\/tr><tr><td>D147<\/td><td>00<\/td><td>102 MOVFLG<\/td><td>DEFB 0<\/td><td>&nbsp;<\/td><\/tr><tr><td>&nbsp;<\/td><td>&nbsp;<\/td><td>103 END<\/td><td>&nbsp;<\/td><td>&nbsp;<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Basic Loader<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>10 CLS:CLEAR 200,&amp;HCFFF:DEFINTA-Z:A=&amp;HD000\n20 READ A$:IF A$ &lt;> \u201c@\u201d THEN POKE A, VAL(\u201c&amp;H\u201d+A$):A=A+1:GOTO 20\n30 POKE &amp;HD147,0\n40 PRINT\u201d\u00a0\u00a0INSERT TAPE\/DISK TO SAVE PROGRAM\u201d\n50 PRINT\u201d\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0AND PRESS ANY KEY\u201d\n60 A$=INPUT$(1):PRINT:PRINT \u201c\u00a0\u00a0SAVING ....\u201d\n70 BSAVE\u201dSPRITE.OBJ\u201d,&amp;HD000,&amp;HD147\n80 END\n100 DATA 3E,C3,32,9F,FD,21,0C,D0,22,A0,FD,C9,CD,14,D0\n110 DATA F7,87,9C,77 (or DATA 00,00,00,00 if you don\u2019t have a disk drive)\n120 DATA C9,3A,AF,FC,FE,00,C8,3A,47,D1,FE,00,C8,21,00\n130 DATA 1B,11,87,D0,01,80,00,CD,78,D0,21,87,D0,06,20\n140 DATA 11,07,D1,7E,FE,D1,28,1A,4F,1A,81,FE,DC,38,04\n150 DATA 3E,C0,18,05,FE,C0,38,01,AF,77,23,13,7E,4F,1A\n160 DATA 81,77,2B,1B,13,13,23,23,23,23,05,20,D8,21,00\n170 DATA 1B,11,87,D0,01,80,00,CD,69,D0,C9,CD,53,00,1A\n180 DATA D3,98,13,0B,78,B1,FE,00,20,F5,C9,CD,50,00,DB\n190 DATA 98,12,13,0B,78,B1,FE,00,20,F5,C9,@<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Basic Program Example<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>10 COLOR 15,1,9:SCREEN 2,2:SPRITE$(0) = STRING$(32,244):DEF FNA(X) = INT(RND(1)*X)+1:A = RND(-TIME)\n20 STOP ON:ON STOP GOSUB 110\n30 POKE &amp;HD147,1:FOR A=0 TO 31\n40 PUT SPRITE A,(128,96),FNA(15),0\n50 XV=FNA(5)-3:IF XV&lt;0 THEN XV=XV+256\n60 YV=FNA(5)-3:IF YV&lt;0 THEN YV=YV+256\n70 IF XV+YV=0 THEN 50\n80 POKE &amp;HD107+A*2,YV:POKE &amp;HD108+A*2,XV:NEXT\n90 IF NOT(STRIG(0)) THEN 90 ELSE POKE &amp;HD147,0\n100 IF NOT(STRIG(0)) THEN 100 ELSE POLE &amp;HD147,1:GOTO 80\n110 POKE &amp;HD147,0:END<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<p>Type in the machine code loader first and save it to disk or tape.&nbsp;&nbsp;Now type in the Basic example program and save it to tape or disk.&nbsp;&nbsp;Then use BLOAD\u201dSPRITE.OBJ\u201d,R to run the machine code program and then RUN the example Basic program.<\/p>\n\n\n\n<p>Next month, I will cover the collision testing routines.\u00a0\u00a0Bye for now!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Written By:&nbsp;Tony Cruise First Published:&nbsp;Micro\u2019s Gazette \u2013 Issue 002 (March\/April 1989) &nbsp;This issue I will start to cover some of the routines that will be used in our extended Basic.&nbsp;&nbsp;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<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[61],"tags":[],"class_list":["post-364","post","type-post","status-publish","format-standard","hentry","category-beyond-basic"],"acf":[],"_links":{"self":[{"href":"https:\/\/electricadventures.net\/index.php?rest_route=\/wp\/v2\/posts\/364","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/electricadventures.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/electricadventures.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/electricadventures.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/electricadventures.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=364"}],"version-history":[{"count":1,"href":"https:\/\/electricadventures.net\/index.php?rest_route=\/wp\/v2\/posts\/364\/revisions"}],"predecessor-version":[{"id":365,"href":"https:\/\/electricadventures.net\/index.php?rest_route=\/wp\/v2\/posts\/364\/revisions\/365"}],"wp:attachment":[{"href":"https:\/\/electricadventures.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=364"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/electricadventures.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=364"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/electricadventures.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=364"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}