johnnystarr Posted March 7, 2014 Share Posted March 7, 2014 I'm starting to grasp how the TIA works on a more complex level. I understand that updating the registers on different lines can allow for multiple instances of GRP0 and GRP1. I've attached a screenshot of Dragonfire as a good example of this technique. Now, how exactly do you "place" these objects in certain positions horizontally? Is this a matter of using HMOVE during the drawing of the frame? Obviously I need a solution that is very brief in cycles. I want enough time to have multi-colored sprites just like this example. I've read over the Dragonfire source code, but it's a bit dense to find the portion that I am referring to. Quote Link to comment Share on other sites More sharing options...
+SpiceWare Posted March 7, 2014 Share Posted March 7, 2014 There's a lot of comments in the source I posted for this demo of mid-screen sprite repositioning. http://atariage.com/forums/topic/169471-early-hmove-demo/ Quote Link to comment Share on other sites More sharing options...
johnnystarr Posted March 9, 2014 Author Share Posted March 9, 2014 I think that I'm having a hard time understanding RESP0 / RESP1. From what I understand, it's used to position a sprite at a certain color clock, but is it used for anything else? Quote Link to comment Share on other sites More sharing options...
SeaGtGruff Posted March 9, 2014 Share Posted March 9, 2014 The five RESxx ("reset") registers have only one function-- to reset a sprite's horizontal position on the scan line-- so they have no other use per se. However, they can be used to trigger extra copies of the sprites beyond the normal three-copy limit. There are a few things you should know about the RESxx registers. First, writing to ("strobing") a RESxx register lets you position the corresponding sprite at intervals of 3 color clocks (CCs), since 1 machine cycle (MC) equals 3 CCs. The new screen position is equal to 3 times the MC immediately following the completion of the write instruction, minus 68 CCs to get the pixel position on the visible portion of the scan line, plus an extra number of CCs to compensate for the START signal. For the players you need to add 5 CCs, but for the missiles and ball you need to add only 4 CCs, so in theory the possible positions are as follows: MC CC M+4 -68 P+5 -68 -- --- --- --- --- --- 00 000 004 -64 005 -63 01 003 007 -61 008 -60 02 006 010 -58 011 -57 03 009 013 -55 014 -54 04 012 016 -52 017 -51 05 015 019 -49 020 -48 06 018 022 -46 023 -45 07 021 025 -43 026 -42 08 024 028 -40 029 -39 09 027 031 -37 032 -36 10 030 034 -34 035 -33 11 033 037 -31 038 -30 12 036 040 -28 041 -27 13 039 043 -25 044 -24 14 042 046 -22 047 -21 15 045 049 -19 050 -18 16 048 052 -16 053 -15 17 051 055 -13 056 -12 18 054 058 -10 059 -09 19 057 061 -07 062 -06 20 060 064 -04 065 -03 21 063 067 -01 068 000 22 066 070 002 071 003 23 069 073 005 074 006 24 072 076 008 077 009 25 075 079 011 080 012 26 078 082 014 083 015 27 081 085 017 086 018 28 084 088 020 089 021 29 087 091 023 092 024 30 090 094 026 095 027 31 093 097 029 098 030 32 096 100 032 101 033 33 099 103 035 104 036 34 102 106 038 107 039 35 105 109 041 110 042 36 108 112 044 113 045 37 111 115 047 116 048 38 114 118 050 119 051 39 117 121 053 122 054 40 120 124 056 125 057 41 123 127 059 128 060 42 126 130 062 131 063 43 129 133 065 134 066 44 132 136 068 137 069 45 135 139 071 140 072 46 138 142 074 143 075 47 141 145 077 146 078 48 144 148 080 149 081 49 147 151 083 152 084 50 150 154 086 155 087 51 153 157 089 158 090 52 156 160 092 161 093 53 159 163 095 164 096 54 162 166 098 167 099 55 165 169 101 170 102 56 168 172 104 173 105 57 171 175 107 176 108 58 174 178 110 179 111 59 177 181 113 182 114 60 180 184 116 185 117 61 183 187 119 188 120 62 186 190 122 191 123 63 189 193 125 194 126 64 192 196 128 197 129 65 195 199 131 200 132 66 198 202 134 203 135 67 201 205 137 206 138 68 204 208 140 209 141 69 207 211 143 212 144 70 210 214 146 215 147 71 213 217 149 218 150 72 216 220 152 221 153 73 219 223 155 224 156 74 222 226 158 227 159 75 225 229 161 230 162 However, the first 68 CCs correspond to the horizontal blanking period, and due to the way the TIA draws the sprites they can't be positioned "offscreen" inside the HBLANK area-- i.e., you can strobe the RESxx registers during HBLANK, but the sprites won't be positioned within the HBLANK region; instead, they be positioned as though you'd strobed their RESxx registers at cycle 22 (i.e., where cycle 22 is the first cycle following the completion of the write instruction). If you look at the list above, it looks like the players should be able to be positioned at pixel 000 by strobing their RESxx registers at cycle 21, but it doesn't work that way. I'll explain this more in a moment. Second, since you can position a sprite only at intervals of 3 CCs, you'll need to also use the HMxx ("horizontal motion") registers and the HMOVE register to position them at the other pixel positions. Third, when you reset a sprite's position, it may not appear on that scan line-- it depends on whether the sprite has already been drawn on that scan line (at the old position) and whether you're displaying any copies of the sprite, but it can also depend on whether you strobe the RESxx register more than once. To understand why, you need to know how the TIA draws the sprites. When you reset a sprite's position by strobing its RESxx register, the TIA sets the sprite's START signal at that position. The START signal lasts for 4 CCs, but the TIA doesn't actually begin to draw the sprite until after the START signal is turned off again. So, for example, if you were to strobe the RESP0 register at cycle 25 (meaning the write instruction is executed during cycles 22, 23, and 24, with cycle 25 being the first cycle after the write instruction has completed), then player0's START signal would be automatically turned on at CC 075 (or pixel position 007) of each scan line (until you reset the sprite's position to a different location), and automatically turned off again at CC 079 (or pixel position 011). Thus, the sprite won't actually be drawn until CC 079. However, for the players it's as if the players were 9 bits wide but with the first pixel always being blank-- i.e., the drawing of the players is delayed by an extra CC, as follows: MC 22 = CCs 066, 067, and 068 -- begin STA RESxx instruction MC 23 = CCs 069, 070, and 071 -- STA RESxx continues executing MC 24 = CCs 072, 073, and 074 -- STA RESxx completes executing MC 25 = CC 075 -- sprite's START signal begins CC 076 -- START signal continues CC 077 -- START signal continues CC 078 -- START signal continues CC 079 -- drawing begins here for the missiles and the ball CC 080 -- drawing begins here for the players If we use SSSS to represent the 4-CC START signal, then for a player it would look like the following: SSSSx76543210 where "x" represents the extra blank CC and "76543210" represents bits 7 through 0 of the player's GRPx register. However, the TIA doesn't actually generate a START signal after the RESxx register has been strobed-- it doesn't begin generating the START signal until 228 CCs later. So if you're displaying just 1 copy (i.e., the main copy) of player0, and player0 hasn't already been drawn on the scan line where you've strobed RESP0, then player0 won't appear on that scan line at all. But if player0 had already been drawn on that scan line before you strobed RESP0, then player0 will appear at the old position on that scan line, and at the new position on the subsequent scan lines. (Note: I think the ball may be an exception to this rule-- i.e., its START signal may begin immediately rather than being delayed by 228 CCs, as I've seen references in the 2600 literature that say you can trigger the ball multiple times on a scan line-- but I haven't tried it to see whether or not it works.) On the other hand, if you're displaying additional copies of the sprite, the TIA will generate START signals for the additional copies, so they *will* appear on the scan line where you strobe the RESxx register. These additional START signals will occur 16, 32, or 64 CCs after the beginning of the first START signal, as follows: ssssx76543210xxxSSSSx76543210xxxSSSSx76543210xxxxxxxxxxxxxxxxxxxSSSSx76543210xxx In the line above, ssss represents the START signal that's delayed by 228 CCs (1 scan line), which triggers the main copy of the sprite. The other START signals (SSSS) are for the close copy, medium copy, and far copy of the sprite, which *won't* be delayed by 1 scan line-- but they'll occur only if those copies are turned on. The trick that lets you draw more than 3 copies of a sprite on a scan line works because the extra START signals do occur right away-- i.e., you won't get copy 1 (the main copy) on that scan line, but you will get copy 2 and copy 3. So if you strobe RESxx multiple times-- with a suitable delay between the multiple strobes-- you can draw copy 2 and copy 3 multiple times. Now, there's an interesting fact that lets you get all 3 copies if you time things just right. If you strobe RESxx such that the ssss signal for the main copy would occur sometime during one of the SSSS signals, that SSSS signal will act like the new ssss signal, although it will be "repositioned" to be aligned with the sprite's new position. For example, if you have the NUSIZ0 register set to draw 3 close copies of player0, you can draw all 3 copies on the scan line by doing the following: STA RESP0 sleep 3 STA RESP0 This is because the first STA RESP0 sets the main copy's ssss signal (which doesn't actually get triggered until 228 CCs later) at the new position, and the first SSSS signal (for copy 2) occurs 16 CCs later. But the second STA RESP0 is timed so that the ssss signal for the second STA RESP0 occurs 18 CCs later, or 2 CCs into the SSSS signal for copy 2, therefore you end up getting a START signal that's 6 CCs long. This is useful if you want to display more than 3 copies of the sprite, but in most cases you'll want to just strobe RESxx once and then use HMOVE to fine-position the sprite. In that case you'll need to strobe RESxx once, store the desired fine-positioning motion value in the HMxx register, and then use HMOVE (typically right after WSYNC), so you can basically count on needing 1 scan line to position the sprite, such that there will always be at least 1 blank scan line between one version of the sprite (at the old position) and the next version of the sprite (at the new position). The only exception would be if the old position were far enough to the left of the new position, in which case you could theoretically draw the two versions of the sprite with no blank line between them-- although in practice a positioning loop is typically used, so you will get at least one blank line on which you'll call the subroutine that executes the positioning loop. I hope the above explanation wasn't too confusing. You don't need to worry about the intricate details unless you're planning to use the multi-reset trick-- and you probably shouldn't attempt that until after you've understood the basics of sprite positioning. 1 Quote Link to comment Share on other sites More sharing options...
johnnystarr Posted March 11, 2014 Author Share Posted March 11, 2014 [lots of stuff] Wow, thank you for the copious amount of details on that subject. I will probably have to revisit this as a reference until I dedicate this stuff to memory. There's a lot of comments in the source I posted for this demo of mid-screen sprite repositioning. http://atariage.com/forums/topic/169471-early-hmove-demo/ Great resource as well. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.