{"id":366,"date":"2025-05-17T17:01:43","date_gmt":"2025-05-17T07:01:43","guid":{"rendered":"http:\/\/electricadventures.net\/?p=366"},"modified":"2025-05-17T17:01:43","modified_gmt":"2025-05-17T07:01:43","slug":"beyond-basic-part-5","status":"publish","type":"post","link":"https:\/\/electricadventures.net\/?p=366","title":{"rendered":"Beyond Basic &#8211; Part 5"},"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 003 (May\/June 1989)<\/p>\n\n\n\n<p>This issue I will start to detail the collision detection routine to go with the automatic sprite routines from last issue.\u00a0But first, here is a list of the conversions for SVI-318\/328 to MSX.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Part 1<\/h2>\n\n\n\n<p>The SVI-318\/328 uses port 8C to change slots.\u00a0So, to change between the RAM and ROM slot,s use:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><strong>ROM to RAM<\/strong><\/td><td><strong>RAM to ROM<\/strong><\/td><\/tr><tr><td>LD A,0FH<\/td><td>LD A,(FE64H)<\/td><\/tr><tr><td>OUT (88H),A<\/td><td>OUT (8CH),A<\/td><\/tr><tr><td>IN A,(90H)<\/td><td><\/td><\/tr><tr><td>LD (FE64H),A<\/td><td><\/td><\/tr><tr><td>AND FDH<\/td><td><\/td><\/tr><tr><td>OUT (8CH),A<\/td><td><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Part 2 Onwards<\/h2>\n\n\n\n<p>Here is a list of ROM calls, RAM locations and HOOK addresses to use instead of the MSX values.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>HGONE = FF57H,<\/li>\n\n\n\n<li>HTIMI = FF5AH,<\/li>\n\n\n\n<li>SCRMOD = FE3AH<\/li>\n\n\n\n<li>SETWRT = 373CH,<\/li>\n\n\n\n<li>SETRD = 3747H<\/li>\n<\/ul>\n\n\n\n<p>Change the following port calls to:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>OUT (98H),A becomes OUT (80H),A<\/li>\n\n\n\n<li>IN A,(98H) becomes IN A,(84H)<\/li>\n<\/ul>\n\n\n\n<p>This list will be expanded if necessary, each issue.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Sprite Collision Detection<\/h2>\n\n\n\n<p>Now onto this month&#8217;s routine.\u00a0\u00a0Our routine will test the collision of one sprite (you specify) with all 31 others.\u00a0A table of flags will be used to show which sprites the one specified is colliding with.\u00a0The size of each sprite will be specified by an X and Y with from 0 to 15 (There is no zero width, work out the real value and subtract one).\u00a0For the routine to work effectively, your sprite shapes should be drawn from the top left-hand corner of the sprite shape pattern.<\/p>\n\n\n\n<p>e.g. X width 5, Y width 2<\/p>\n\n\n\n<p>To make the routine easier to understand, I have split it into two sections.\u00a0The section I will show this issue is the actual test routine, which tests whether two specified sprites are colliding and sets the carry flag if so.\u00a0The values of the registers on entry are:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>HL points to sprite 1 VRAM table location<\/li>\n\n\n\n<li>DE points to sprite 2 VRAM table location<\/li>\n\n\n\n<li>B lower 4 bits, y width and top 4 bits, x width for sprite 1<\/li>\n\n\n\n<li>C lower 4 bits, y width and top 4 bits, x width for sprite 2<\/li>\n<\/ul>\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><\/td><td><\/td><td>1 ;<\/td><td>Subroutine to test the collision of two sprites<\/td><td><\/td><\/tr><tr><td><\/td><td><\/td><td>2 ;<\/td><td><\/td><td><\/td><\/tr><tr><td><\/td><td><\/td><td>3 ;<\/td><td><\/td><td><\/td><\/tr><tr><td><\/td><td><\/td><td>4 ;<\/td><td><\/td><td><\/td><\/tr><tr><td><\/td><td><\/td><td>5 ; Label settings<\/td><td><\/td><td><\/td><\/tr><tr><td><\/td><td><\/td><td>6 ;<\/td><td><\/td><td><\/td><\/tr><tr><td><\/td><td><\/td><td>7 SETRD<\/td><td>EQU 0050H<\/td><td>; Video read<\/td><\/tr><tr><td><\/td><td><\/td><td>8 ;<\/td><td><\/td><td><\/td><\/tr><tr><td>C0FA<\/td><td>E5<\/td><td>9 START<\/td><td>PUSH HL<\/td><td>; Save registers<\/td><\/tr><tr><td>C0FB<\/td><td>D5<\/td><td>10<\/td><td>PUSH DE<\/td><td>;<\/td><\/tr><tr><td>C0FC<\/td><td>C5<\/td><td>11<\/td><td>PUSH BC<\/td><td>;<\/td><\/tr><tr><td>C0FD<\/td><td>78<\/td><td>12<\/td><td>LD A,B<\/td><td>; Get Y velocity 1<\/td><\/tr><tr><td>C0FE<\/td><td>E60F<\/td><td>13<\/td><td>AND 15<\/td><td>;<\/td><\/tr><tr><td>C100<\/td><td>47<\/td><td>14<\/td><td>LD B,A<\/td><td>;<\/td><\/tr><tr><td>C101<\/td><td>79<\/td><td>15<\/td><td>LD A,C<\/td><td>; Get Y velocity 2<\/td><\/tr><tr><td>C102<\/td><td>E60F<\/td><td>16<\/td><td>AND 15<\/td><td>;<\/td><\/tr><tr><td>C104<\/td><td>4F<\/td><td>17<\/td><td>LD C,A<\/td><td>;<\/td><\/tr><tr><td>C105<\/td><td>CD55C1<\/td><td>18<\/td><td>CALL RDVRM<\/td><td>; Get Y1 value<\/td><\/tr><tr><td>C108<\/td><td>80<\/td><td>19<\/td><td>ADD A,B<\/td><td>; Add velocity<\/td><\/tr><tr><td>C109<\/td><td>47<\/td><td>20<\/td><td>LD B,A<\/td><td>;<\/td><\/tr><tr><td>C10A<\/td><td>EB<\/td><td>21<\/td><td>EX DE,HL<\/td><td>; Get Y2 value<\/td><\/tr><tr><td>C10B<\/td><td>CD55C1<\/td><td>22<\/td><td>CALL RDVRM<\/td><td>;<\/td><\/tr><tr><td>C10E<\/td><td>EB<\/td><td>23<\/td><td>EX DE,HL<\/td><td>;<\/td><\/tr><tr><td>C10F<\/td><td>B8<\/td><td>24<\/td><td>CP B<\/td><td>; Hit?<\/td><\/tr><tr><td>C110<\/td><td>3040<\/td><td>25<\/td><td>JR NC,NOHIT<\/td><td>; No \u2013 Exit loop<\/td><\/tr><tr><td>C112<\/td><td>EB<\/td><td>26<\/td><td>EX DE,HL<\/td><td>; Get Y2 value<\/td><\/tr><tr><td>C113<\/td><td>CD55C1<\/td><td>27<\/td><td>CALL RDVRM<\/td><td>;<\/td><\/tr><tr><td>C116<\/td><td>EB<\/td><td>28<\/td><td>EX DE,HL<\/td><td>;<\/td><\/tr><tr><td>C117<\/td><td>81<\/td><td>29<\/td><td>ADD A,C<\/td><td>; Add velocity<\/td><\/tr><tr><td>C118<\/td><td>4F<\/td><td>30<\/td><td>LD C,A<\/td><td>;<\/td><\/tr><tr><td>C119<\/td><td>CD55C1<\/td><td>31<\/td><td>CALL RDVRM<\/td><td>; Get Y1 velocity<\/td><\/tr><tr><td>C11C<\/td><td>B9<\/td><td>32<\/td><td>CP C<\/td><td>; Hit?<\/td><\/tr><tr><td>C11D<\/td><td>3033<\/td><td>33<\/td><td>JR NC,NOHIT<\/td><td>; No \u2013 Exit loop<\/td><\/tr><tr><td>C11F<\/td><td>C1<\/td><td>34<\/td><td>POP BC<\/td><td>; Restore BC<\/td><\/tr><tr><td>C120<\/td><td>C5<\/td><td>35<\/td><td>PUSH BC<\/td><td>; Resave BC<\/td><\/tr><tr><td>C121<\/td><td>23<\/td><td>36<\/td><td>INC HL<\/td><td>; Increment pointers<\/td><\/tr><tr><td>C122<\/td><td>13<\/td><td>37<\/td><td>INC DE<\/td><td>;<\/td><\/tr><tr><td>C123<\/td><td>CB38<\/td><td>38<\/td><td>SRL B<\/td><td>; Get X velocity 1<\/td><\/tr><tr><td>C125<\/td><td>CB38<\/td><td>39<\/td><td>SRL B<\/td><td>;<\/td><\/tr><tr><td>C127<\/td><td>CB38<\/td><td>40<\/td><td>SRL B<\/td><td>;<\/td><\/tr><tr><td>C129<\/td><td>CB38<\/td><td>41<\/td><td>SRL B<\/td><td>;<\/td><\/tr><tr><td>C12B<\/td><td>CB39<\/td><td>42<\/td><td>SRL C<\/td><td>; Get X velocity 2<\/td><\/tr><tr><td>C12D<\/td><td>CB39<\/td><td>43<\/td><td>SRL C<\/td><td>;<\/td><\/tr><tr><td>C12F<\/td><td>CB39<\/td><td>44<\/td><td>SRL C<\/td><td>;<\/td><\/tr><tr><td>C131<\/td><td>CB39<\/td><td>45<\/td><td>SRL C<\/td><td>;<\/td><\/tr><tr><td>C133<\/td><td>CD55C1<\/td><td>46<\/td><td>CALL RDVRM<\/td><td>; Get Y1 value<\/td><\/tr><tr><td>C136<\/td><td>80<\/td><td>47<\/td><td>ADD A,B<\/td><td>; Add velocity<\/td><\/tr><tr><td>C137<\/td><td>47<\/td><td>48<\/td><td>LD B,A<\/td><td>;<\/td><\/tr><tr><td>C138<\/td><td>EB<\/td><td>49<\/td><td>EX DE,HL<\/td><td>; Get Y2 velocity<\/td><\/tr><tr><td>C139<\/td><td>CD55C1<\/td><td>50<\/td><td>CALL RDVRM<\/td><td>;<\/td><\/tr><tr><td>C13C<\/td><td>EB<\/td><td>51<\/td><td>EX DE,HL<\/td><td>;<\/td><\/tr><tr><td>C13D<\/td><td>B8<\/td><td>52<\/td><td>CP B<\/td><td>; Hit?<\/td><\/tr><tr><td>C13E<\/td><td>3012<\/td><td>53<\/td><td>JR NC,NOHIT<\/td><td>; No \u2013 Exit loop<\/td><\/tr><tr><td>C140<\/td><td>EB<\/td><td>54<\/td><td>EX DE,HL<\/td><td>; Get Y2 value<\/td><\/tr><tr><td>C141<\/td><td>CD55C1<\/td><td>55<\/td><td>CALL RDVRM<\/td><td>;<\/td><\/tr><tr><td>C144<\/td><td>EB<\/td><td>56<\/td><td>EX DE,HL<\/td><td>;<\/td><\/tr><tr><td>C145<\/td><td>81<\/td><td>57<\/td><td>ADD A,C<\/td><td>; Add velocity<\/td><\/tr><tr><td>C146<\/td><td>4F<\/td><td>58<\/td><td>LD C,A<\/td><td>;<\/td><\/tr><tr><td>C147<\/td><td>CD55C1<\/td><td>59<\/td><td>CALL RDVRM<\/td><td>; Get Y1 value<\/td><\/tr><tr><td>C14A<\/td><td>B9<\/td><td>60<\/td><td>CP C<\/td><td>; Hit?<\/td><\/tr><tr><td>C14B<\/td><td>3005<\/td><td>61<\/td><td>JR NC,NOHIT<\/td><td>; No \u2013 Exit loop<\/td><\/tr><tr><td>C14D<\/td><td>37<\/td><td>62<\/td><td>SCF<\/td><td>; Set carry flag<\/td><\/tr><tr><td>C14E<\/td><td>C1<\/td><td>63 EXIT<\/td><td>POP BC<\/td><td>; Restore registers<\/td><\/tr><tr><td>C14F<\/td><td>D1<\/td><td>64<\/td><td>POP DE<\/td><td>;<\/td><\/tr><tr><td>C150<\/td><td>E1<\/td><td>65<\/td><td>POP HL<\/td><td>;<\/td><\/tr><tr><td>C151<\/td><td>C9<\/td><td>66<\/td><td>RET<\/td><td>; Return from routine<\/td><\/tr><tr><td>C152<\/td><td>AF<\/td><td>67 NOHIT<\/td><td>XOR A<\/td><td>; Clear flags<\/td><\/tr><tr><td>C153<\/td><td>18F9<\/td><td>68<\/td><td>JR EXIT<\/td><td>; Go to EXIT<\/td><\/tr><tr><td>C155<\/td><td><\/td><td>69 ;<\/td><td><\/td><td><\/td><\/tr><tr><td>C155<\/td><td><\/td><td>70 ;<\/td><td>Subroutine to read a byte from VRAM<\/td><td><\/td><\/tr><tr><td>C155<\/td><td><\/td><td>71 ;<\/td><td><\/td><td><\/td><\/tr><tr><td>C155<\/td><td>CD5000<\/td><td>72 RDVRM<\/td><td>CALL SETRD<\/td><td>; Set screen location<\/td><\/tr><tr><td>C158<\/td><td>D898<\/td><td>73<\/td><td>IN A,(98H)<\/td><td>; Get value<\/td><\/tr><tr><td>C15A<\/td><td>C9<\/td><td>74<\/td><td>RET<\/td><td>;<\/td><\/tr><tr><td>C15B<\/td><td><\/td><td>75 ;<\/td><td><\/td><td><\/td><\/tr><tr><td><\/td><td><\/td><td>76 END<\/td><td><\/td><td><\/td><\/tr><\/tbody><\/table><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>Written by:&nbsp;Tony Cruise First Published:&nbsp;Micro\u2019s Gazette \u2013 Issue 003 (May\/June 1989) This issue I will start to detail the collision detection routine to go with the automatic sprite routines from last issue.\u00a0But first, here is a list of the conversions for SVI-318\/328 to MSX. Part 1 The SVI-318\/328 uses port 8C to change slots.\u00a0So, 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-366","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\/366","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=366"}],"version-history":[{"count":1,"href":"https:\/\/electricadventures.net\/index.php?rest_route=\/wp\/v2\/posts\/366\/revisions"}],"predecessor-version":[{"id":367,"href":"https:\/\/electricadventures.net\/index.php?rest_route=\/wp\/v2\/posts\/366\/revisions\/367"}],"wp:attachment":[{"href":"https:\/\/electricadventures.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=366"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/electricadventures.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=366"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/electricadventures.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=366"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}