Jump to content
IGNORED

Assembly on the 99/4A


matthew180

Recommended Posts

 

If interrupts are not enabled regularly somewhere in your program—yes, you would need to do that. Somehow, you need to avoid a regular sampling of the VDP interrupt timer. That is, I would think that cycling interrupts just before sampling the timer might possibly return the same number every time, reflecting instruction timing. You would need to test that. Maybe someone here better-versed on the TMS9900//TI-99/4A than I can shed light on that.

 

...lee

 

So location >8379 get incremented by one every time interrupts are enabled. That's unfortunately not terribly helpful as a random number...

So I think I'm going to bite the bullet and spend 8 bytes for the RAND routine, but only using the constantly updated seed's MSB. Essentially I'll test that MSB for > or < = 127 to make a crude random determination. I am skipping the storing of the PRN into >8378 since the seed reflects the same number. Stolen code from you below :) I thought I might need to manually put an initial seed in >83C0, but it looks like that with each program start a different value is found in it. Works for me.

LI   R4,>6FE5
MPY  @>83C0,R4
AI   R5,>7AB9
MOV  R5,@>83C0
Link to comment
Share on other sites

since the first suggestion I made to you is /not/ part of Classic99. It's real hardware attached to real TI-99/4A machines.

 

Would you mind sending me some technical details of your keyboard interface? Maybe one day I can add that to the TI emulation in MAME as a "keyboard mod".

Link to comment
Share on other sites

 

 

So location >8379 get incremented by one every time interrupts are enabled. That's unfortunately not terribly helpful as a random number...

So I think I'm going to bite the bullet and spend 8 bytes for the RAND routine, but only using the constantly updated seed's MSB. Essentially I'll test that MSB for > or < = 127 to make a crude random determination. I am skipping the storing of the PRN into >8378 since the seed reflects the same number. Stolen code from you below :) I thought I might need to manually put an initial seed in >83C0, but it looks like that with each program start a different value is found in it. Works for me.

LI   R4,>6FE5
MPY  @>83C0,R4
AI   R5,>7AB9
MOV  R5,@>83C0

 

Waaaay back in the day we had a discussion about RNGs in assembly:

 

http://atariage.com/forums/topic/163646-not-prime/

 

I learned some interesting things during that thread, and IMO the routine that Tursi posted is still one of the best. Also, sometime later (I can't find the thread), I learned that using masking to reduce your random number range causes a bias. The only real way to avoid the bias is to divide, i.e. use DIV or shift if your range is a power of 2. I.e., say you need a random number from 0 to 3; don't take your 16-bit random number from your routine and mask it with >0003. That will introduce a bias and wreck the randomness.

 

Edit: I'm going to retract that, since I can't remember and it was a bad example anyway. I just remember that there were three main problems when producing random numbers (or pseudo-random numbers if anyone is being picky about terms):

 

1. Randomizing the seed.

2. Generating the PRN itself.

3. Reducing the range without introducing bias.

Edited by matthew180
Link to comment
Share on other sites

  • 3 weeks later...

VDP Write-Only Register Questions

 

E/A manual p.326 Yesterday I was reading-up on setting the graphics mode via the VDP Write-Only registers. A few questions come to mind...

 

E/A, The default far Register 3 is >OE in the ~ditor/Assembler,>OC in TI BASIC, and >20 in TI Extended BASIC.

Defines the base address of the Color Table. The Color Table base address is equal to the value of this register times >40.

 

Is there anything advantageous to using the default locations for the Color Table (or any of the defaults for any of the VDP tables) in a pure Assembly environment?

 

Whats the origin of the mysterious (to me) multiplier >40 in the case of defining the Color Table location?

 

Again, the Pattern Descriptor Tables >800 multiplier? On a 2K location binder? Why?

 

Initially, I read the E/A phraseology in this section to mean that the various tables were intended to remain in the recommended locations for each environment: TI BASIC, XB, E/A.

 

Are you guys mostly following these default locations for the VDP tables? Ive swapped the locations around as matthew180 suggested. It doesnt seem to matter...

 

Have the wizards of assembly discovered an optimal arrangement?

 

Thanks! -j

Edited by Airshack
Link to comment
Share on other sites

The PDT has a length of 8 bytes/char * 256 chars = 2048 bytes.

The color table defines a foreground and a background color in one byte (high/low nibble) for 8 chars in one set, so for 256 chars you have 256/8 = 32 sets. TI defined a multiple of 64; maybe they wanted to spare a bit.

 

When you define the tables in such multiples, you do not risk overwriting the tables when you change their base.

  • Like 1
Link to comment
Share on other sites

Is there anything advantageous to using the default locations for the Color Table (or any of the defaults for any of the VDP tables) in a pure Assembly environment?

 

Are you guys mostly following these default locations for the VDP tables? Ive swapped the locations around as matthew180 suggested. It doesnt seem to matter...

 

Have the wizards of assembly discovered an optimal arrangement?

 

I choose the VDP memory layout that works best for each individual game without any consideration of the default values, but always trying to make it the most compact to save VDP RAM. This has never caused any problems, but if you had to write a program that worked together with BASIC or other programs it would be a different story.

 

One of the cool things about the VDP is that you can change the location of tables on the fly to implement double buffering and prevent flicker. For instance, you can have two locations of the name table. one that you show and another that you update. Once your update is complete you switch to the other name table. For smooth scrolling you can also have 8 different pattern tables that you switch between, each containing your character set scrolled to a certain offset. Since 8 tables take up the entire 16K, you need to overlap the other tables with the pattern tables, so you can probably only use 128 of the 256 patterns. Changing the location of the color table is what makes the 3D scrolling effects in the "Don't mess with Texas" demo possible.

 

The ability to change location of VDP tables is an advantage that the TI had over many competitors, but very few games from back then seems to be using it. My advice - as always - is to disable interrupts and use VDP and scratch pad RAM any way you like.

  • Like 3
Link to comment
Share on other sites

In reality you should not consider anything as default because there really isn't a default. Different loaders/enviroments use different WOR values so what is default for one may not be default for another. As a rule I always set up the registers for what I want to do. I think the whole "default" idea is a carry over from a time when the only option was the EA cart and it's manual. Times, they are a changing.

  • Like 1
Link to comment
Share on other sites

In reality you should not consider anything as default because there really isn't a default. Different loaders/enviroments use different WOR values so what is default for one may not be default for another. As a rule I always set up the registers for what I want to do. I think the whole "default" idea is a carry over from a time when the only option was the EA cart and it's manual. Times, they are a changing.

The main example I’m using as a reference is matthews180’s VIEWPORT (this thread) and the E/A manual.

 

Perhaps ALL beginners here will benefit from some additional source code examples. Do we have a source code archive?

 

I now understand the E/A manual’s “defaults” are not a universal best practice concerning VDP tables. I’d love to examine more code to see what approaches are out there.

 

Moving them around to serve the task at hand is good advice but difficult to grasp in this case, for this guy.

 

Definitely appreciate the answers tonight! Thanks guys!

 

-James

 

 

 

 

Sent from my iPhone using Tapatalk Pro

Link to comment
Share on other sites

 

One of the cool things about the VDP is that you can change the location of tables on the fly to implement double buffering and prevent flicker. For instance, you can have two locations of the name table. one that you show and another that you update. Once your update is complete you switch to the other name table. For smooth scrolling you can also have 8 different pattern tables that you switch between, each containing your character set scrolled to a certain offset. Since 8 tables take up the entire 16K, you need to overlap the other tables with the pattern tables, so you can probably only use 128 of the 256 patterns. Changing the location of the color table is what makes the 3D scrolling effects in the "Don't mess with Texas" demo possible.

 

The ability to change location of VDP tables is an advantage that the TI had over many competitors, but very few games from back them seems to be using it. My advice - as always - is to disable interrupts and use VDP and scratch pad RAM any way you like.

Mind blown! I now have a few more programming goals. Thanks Rasmus!

 

 

Sent from my iPhone using Tapatalk Pro

  • Like 1
Link to comment
Share on other sites

The seemingly "magic" multiply values for the VDP registers are based on the number of bits in the VDP Register (VR) used to store the respective table location. Trying not to slip down the slope, it all comes down to building addresses in the VDP while it is generating the display.

 

The 9918A can address 16K, which requires a 14-bit address:

bit:    13  12  11  10   9   8   7   6   5   4   3   2   1   0
weight: 8K  4K  2K  1K  512 256 128 64  32  16   8   4   2   1

If you look at the VRs used to store table locations (see the 9918A datasheet, pg. 2-6):

       7   6   5   4        3  2  1  0
VR2: | 0 | 0 | 0 | 0 | Name Table Base Address |
4-bits

        7  6  5  4  3  2  1  0
VR3: | Color Table Base Address |
8-bits

       7   6   5   4   3          2   1   0
VR4: | 0 | 0 | 0 | 0 | 0 | Pattern Generator Base Address |
3-bits

       7        6   5   4   3   2   1   0
VR5: | 0 | Sprite Attribute Table Base Address |
7-bits

       7   6   5   4   3              2   1   0
VR6: | 0 | 0 | 0 | 0 | 0 | Sprite Pattern Generator Base Address |
3-bits

The bits in the VRs are used as the most-significant bits of the address when the VDP is generating memory addresses to access table data while rendering the display one scan-line at a time.

 

For example, the Name Table Base Address (NTBA) VR2 is 4-bits, and say it has a value of binary 1010, or >A in hex. The VDP will take those 4-bits and use them for address generation like this:

bit:    13  12  11  10   9   8   7   6   5   4   3   2   1   0
weight: 8K  4K  2K  1K  512 256 128 64  32  16   8   4   2   1
         1   0   1   0 |  <---- VRAM address >2800, i.e. >A * >400
          NTBA value

This places the Name Table at a base address of >2800 in VRAM, with the index into the table based on the current raster X and Y values. You can see this address construction on page 3.3 of the 9918A datasheet.

 

So the "1010" from VR2 goes into the MSbits to generate the VRAM address for getting a "name" based on where the VDP is currently rendering the display. Thus, essentially, the "1010" is shifted to the left by 10-bits. Since we know bit-shifting left is the same as multiplying by 2 for every shift, shifting by 10-bits is the same as multiplying by hex >400, or 1024 decimal.

 

That is how you know where in VRAM the Name Table will be located based on the 4-bits you provide in VR2. This also explains why some tables can be located in more locations in VRAM. Since the bits from the VRs are always used as the MSbits of address generation, the more bits in the VRs the more locations. For example, look at what happens when you put "0000" vs "0001" in VR2 for the NTBA:

bit:    13  12  11  10   9   8   7   6   5   4   3   2   1   0
weight: 8K  4K  2K  1K  512 256 128 64  32  16   8   4   2   1
         0   0   0   0 |  <---- VRAM address >0000 (0K)
         0   0   0   1 |  <---- VRAM address >0400 (1K)

You can see that by simply changing VR2 from 0 to 1, the table is moved by 1K in VRAM. So you could never put the NTBA anywhere between 0K and 1K, it is locked to 1K boundaries. Since there are 4-bits used for the NTBA in VR2, you can place the Name Table at any one of 16 locations in VRAM, between 0K and 15K.

 

With the Pattern Tables, there are only 3-bits, which means they can only be located on 2K boundaries for a total of 8 possible locations. The Color Table has the most flexibility since it has 8-bits to define the table location, it can be located at any of 256 locations in VRAM. Also, since is has more bits for the table address, it is shifted fewer times to get it into the most-significant part of the address, i.e. only 6-bits to the left, or the same as multiplying by >40 hex, or 64 decimal. And 64 * 256 = 16384, which is exactly the size of VRAM.

 

I hope this helps. If you understand binary and bit-twiddling it should be very straight forward. This is very common in hardware.

  • Like 3
Link to comment
Share on other sites

I now understand the E/A manuals defaults are not a universal best practice concerning VDP tables. Id love to examine more code to see what approaches are out thère.

 

The point I was trying to convey was not the best use of VDP memory. There's a million ways to skin a cat and all.

 

What I was trying to convey was that any programming you do should include a complete VDP WOR set up. There are several games that work fine from the EA cart's use of VDP RAM but fail from other loaders because the VDP set up is a bit different.

Link to comment
Share on other sites

The multipliers are chosen so the VDP hardware should be able to index the tables. The more bytes in the tables, the less granularity in their base positions.

 

Which is due to how the addresses are formed for addresses VRAM during frame generation. For example, let's use the Name Table again since that is where rendering begins for the tile layer. For every screen location the VDP needs to get the address of the byte that represents the "name" of the tile at that location. The VDP has two counters internally, an X (aka. column or horizontal) counter, and a Y (aka. row, or vertical, or scan-line) counter.

 

The X and Y counters are 0,0 for the upper left corner of the active display area, and increment to scan-out the frame left-to-right, top-to-bottom. X increments from 0 to 341, with the active display being the 0 to 255 part of the counter. Y increments from 0 to 261 (or 312 for PAL), with the active display being the 0 to 191 part of the counter (see pg. 3-8 in the 9918A datasheet). The "active display" is the part of the video frame that you see on the screen, but there are horizontal and vertical blanking parts of a frame too.

 

So, for any given X,Y position in the active display you will essentially have two 8-bit numbers, X going from 0..255 and Y going from 0..191. To convert the current X,Y scan position to a 32x24 tile position, you need to divide each X and Y position by 8: 256 / 8 = 32, and 192 / 8 = 24 (this is the same as converting a sprite position to a tile position).

 

In hardware you divide-by-8 by shifting right by 3-bits, or by simply using the correct 5-bits from each X and Y counter. Thus, the index address for any tile position requires 5-bits from the X counter and 5-bits from the Y counter:

      bit:  8 7 6 5 4 3 2 1 0
x-counter:     0 .. 341
y-counter:     0 .. 261

weight: 8K  4K  2K  1K  512 256 128 64  32  16   8   4   2   1
bit:    13  12  11  10   9   8   7   6   5   4   3   2   1   0
       |    NTBA      | y7  y6  y5  y4  y3 |x7  x6  x5  x4  x3 |

Thus, only 4-bits are left over from the 14-bits needed to address VRAM, and those bits come from VR2, i.e. the NTBA, in this case. Pages 3-3 and 3-4 in the 9918A datasheet show how the addresses are formed for each table.

 

Because bit-twiddling is easy and cheap in hardware (it only requires wires, and is why you always find sizes and placement conveniently divisible by some power of 2), as apersson850 mentioned, table placement granularity is going to be directly related to table size. The bigger the table, the bigger the index, the more bits you need to form the index, the less bits you have to specify the table location.

 

However, had the 9918A used a more costly (both in terms of time and hardware) addition operation to combine the table base location and the index into the table, the table could be placed on any boundary down to byte granularity. Alas, that is not how the 9918A works, so we are left with table placement granularity based on table size.

 

Also, this design is very flexible and unusual for the era. Most "CRT Controller" ICs did not have this flexibility and expected video data to be in fixed locations. It would have been much easier for the 9918A engineers to simple say "the Name Table is always at VRAM address >0000 to >0300", etc. I'm not sure why they made the table placement configurable, maybe it was more experimentation of ideas, like they were doing with the 9900.

  • Like 1
Link to comment
Share on other sites

After reading these answers I was able to open up the TMS9918A VDP data book and follow along with the conversation.

 

The multiply values of the VDP registers are no longer a mystery! Thanks guys.

 

Mark, I see now how it’s imperative to set up the VDP Write-Only Registers (WOR) completely; not relying on any default values in the E/A manual.

 

My incorrect assumption was that there was a place for each table when using TI BASIC, another when using XB, and finally a third “way to do it” in Assembly. What’s true by design for the first two environments (BASIC & XB), is not true in pure Assembly.

 

Assembly shares not these constraints!

 

Noted: BASIC and XB are built around specific locations for tables thus any interaction with them will require “default” locations for tables.

 

Much to my delight the TMS9918A’s design is “very flexible and unusual for the era.” How lucky are we?

 

Noted: Most retro systems have video data tables locked into fixed locations.

 

Again... how lucky are we?! With programmer definable VDP tables we can “display the results of one table, at the same time...modifying another.” Cool! I won’t forget!

 

Matthew, thanks for the references in the VDP data sheet. Table 3-2 showing a visual of the VDP memory address derivation process —along with your detailed reply— cleared this matter of the mysterious multipliers up.

 

-j

 

 

 

Sent from my iPhone using Tapatalk Pro

Link to comment
Share on other sites

  • 1 month later...

Tonight's Question comes from E/A p.339, 21.6.1 Sprite Attribute List, SPRITE EARLY CLOCK:

 

What on earth does the Sprite Early clock really do?

 

I read this section *over and over* about shifting 32-pixels left if it's on and fading in-and-out right if it's off....I don't get it.

 

Perhaps one of the TI faithful has a better way of explaining the reason we need a Sprite Early Clock.

 

And why is the word "Clock" in the name?

Link to comment
Share on other sites

Early Clock allows you to place a sprite so that part of it is outside the screen to the left. Without EC an x value of 0 means at the left border, fully visible. With EC an x value of 0 places the sprite at x=-32, outside the screen. The offset is 32 because then it also works for magnified sprites. For a normal 16x16 sprite, setting x=24 and EC will place it at x=-8, half visible.

 

Code can be something like this:

 

if (desiredX < 0) {

setEC

spriteX = desiredX + 32

} else {

clearEC [edited]

spriteX = desiredX

}

 

See my 4K game Fork for a demo. The blue balls, for instance, are using EC.

 

Edit: I believe the word 'clock' has to do with 'pixel clock' which again has to do with the horizontal timing of the video signal.

 

Also note that desiredX < 0 could be replaced by desiredX < 128 or any other value < 224. It's not important where on the screen we do the shift.

Edited by Asmusr
  • Like 1
Link to comment
Share on other sites

So I’m reading that this all has to do with the sprite origin being identified as the top-left corner of the sprite.

 

Due to the origin being at the top left corner, there’s an issue with horizontally moving sprites fading in and out of the right AND left side of the screen.

 

Right moving sprites fade off the right side of the screen pixel column by pixel column until the left-most sprite pixel column exceeds 255.

 

The problem is aesthetics? As a sprite pixel column approaches 255, part of the sprite is now drawn on the left side of the screen beginning at screen column 0, thus “wrapping” or splitting the sprite image into two images?

 

Same goes for left moving sprites? As they move from screen column 0 to column 255, the sprite again appears split.

 

So with the early clock OFF the left moving sprite X coordinate will countdown like this: 10,9,8,7,6,5,4,3,2,1,0,255,254,253,252...

 

As it passes (moving left) from 0 to 255 the sprite splits with the left sprite column drawn at screen column 255, while the rest of the (ex: 16-bit wide) sprite occupies screen columns 0-14.

 

If my understanding is complete, turning the Early Clock ON causes the left moving sprite position to look like this:

 

10,9,8,7,6,5,4,3,2,1,0,-1,-2,-3...,-32,255,254,253,252...

 

So now the sprite completely disappears off the left side of the screen, pixel column by pixel column, before the first column of sprite pixels appears on screen column 255?

 

For right moving sprites with Early Clock ON the sprite origin moves like this:

 

253, 254, 255, -32, -31, -30, ...-1,0,1,2,3,4...

 

So again, there’s no sprite splitting as the sprite moves off the right side of the screen.

 

So the sprite early clock ON is something I need to use if I want sprites to move in and out of BOTH the left and right screen edges in an aesthetically pleasing manner.

 

Basically, the sprite early clock ON just adds 32 out-of-view pixel columns to the left side of the screen (X positions -32 to -1).

 

Right?

 

 

Sent from my iPhone using Tapatalk Pro

Link to comment
Share on other sites

No, sprites are never split. With an x value of 255 you only see one pixel column of the sprite to the right - nothing on the left.

 

The issue is that one byte can only store numbers 0-255. This is not enough to store the full desired x range, from -32 to 255. Without EC the values of the byte maps to 0 <= x <= 255. With EC the values of the byte maps to -32 <= x <= 223, i.e. each value is shifted by 32.

 

EC is not needed for the right side.

Edited by Asmusr
  • Like 1
Link to comment
Share on other sites

Yeah, the word "fading" is a little confusing, but they basically mean moving a sprite partially off screen. You can have the sprite partially off the left, or partially off the right. You could also think of it as the coordinates referencing the top left or the top right (except that top right is /always/ 32 pixels wide).

  • Like 1
Link to comment
Share on other sites

Also note that the value of 32 was chosen to cover the maximum possibility of a 16x16 sprite with magnification, which becomes 32-pixels tall/wide. The Early-Clock is described in the 9918A datasheet on pg. 2-26 if you want information other than what the E/A manual provides. As Rasmus mentioned, the word "clock" has to do with when the clocking of the shift registers (see pg. 2-2, figure 2-1 of the datasheet) holding sprite pixels begins. You get names like this exposed to the user when you let (or require) the engineer write the documentation. ;-)

  • Like 4
Link to comment
Share on other sites

Also note that the value of 32 was chosen to cover the maximum possibility of a 16x16 sprite with magnification, which becomes 32-pixels tall/wide. The Early-Clock is described in the 9918A datasheet on pg. 2-26 if you want information other than what the E/A manual provides. As Rasmus mentioned, the word "clock" has to do with when the clocking of the shift registers (see pg. 2-2, figure 2-1 of the datasheet) holding sprite pixels begins. You get names like this exposed to the user when you let (or require) the engineer write the documentation. ;-)

Some thoughts from a novice with many questions:

 

No shit the engineers wrote this document! Of course the intended audience was engineers so maybe that’s understandable. Between E/A and this data sheet I’m still lost in the tall weeds.

 

Still, not an excuse for really horrible descriptions of what’s going on in the VDP. Reminds me of engineering classes where the Professor was extremely intelligent but couldn’t teach himself out of a paper bag. My reading of the suggested data sheet material just generates more questions:

 

The Backdrop Pane seems to be more of a Border Pane or Foreground Pane. “The part of the sprite that overlaps the backdrop is hidden from view from the backdrop.”

 

Q1: Why does the pane diagram on data sheet p2-13, fig 2-5, show the backdrop pane way near the bottom of all the other graphics panes when it clearly appears to be a Foreground Pane, concealing all sprites which dare to travel beneath it?

 

Q2: On to the Sprite Attribute Table... Why is the top ROW of y-pixels located a -1 when the leftmost COLUMN of x-pixels are located at 0?

 

The top left pixel position is (-1y,0x)? Why not 0y,0x?

 

Q3: Apparently we may place a sprite vertically from -31 to 255, with -31-0 and 192-255 being off, or partially off screen?

 

Q4: If we allow a Sprite’s vertical position to travel beneath the bottom of the screen (>191), will traveling to position 208 conceal all higher numbered sprites until this now-hidden vertically moving sprite vacates row 208, causing all the higher numbered sprites to magically reappear?

 

Q5: Assuming I set the sprite early clock bit, may I now position a sprite from -31 to 255? Or is the new range -31 to 224? If the limit is 224 then haven’t I just traded a left-side problem with another sprite behavior problem on the right side of the screen?

 

Q6: With the early clock bit clear is the limit simply 0-255? Makes me wonder if this is the XB default setting?

 

Q7: What is “TAG” in Fig 2-20 of the data book? The fourth byte in the screen attribute table was early clock + color code? How’s that “TAG?”

 

Q8: The data book seems to conflict with the E/A Manual when it describes horizontal positioning of sprites off the left side of the viewable screen:

 

“...with EC set to 1...values for horizontal displacement in the range 0 to 32 cause the sprite to overlap with the left-hand border of the backdrop.”

 

This is because a value of say... 16 is moved to -16, since the EC moves sprites 32 pixels left?

 

Q9: Lastly, is the EC something I need to manage (endlessly setting and clearing and setting...) throughout my code? Is this normal or is it either set or cleared upon initialization of the VDP registers at startup?

 

Sorry guys...totally lost apparently. Appreciate y’all and your ability to bring it down to my level.

 

-James

 

 

 

 

 

 

 

 

Sent from my iPhone using Tapatalk Pro

Edited by Airshack
Link to comment
Share on other sites

1) sprites either travel on the screen or off it so I don't get your reference. The backdrop Has nothing (normally) to do with the TI other than background color.

 

2) sprites are processed on the next scan line from when they occur. It's a feature. That's why 254 is the last and 255 is the first. Quirky in an engineering way.

 

3) you can place a sprite horizontally from 0 to 255 (which is what I think you meant.) The early clock bit does the math for you. When your sprite passes a certain point (128ish) then clear that bit on your next write and ,ala peanut butter and jelly sandwiches, it fades right. It's all about fade in and fade out.

 

4) yea but not magic. a sprite at 208 halts further processing. Very useful if you know what your doing.

 

5) Nope. Sprites occur at horizontal 0 to 255. If early clock is set then it will shift it to the left without you doing anything. If unset then it shows the sprite at the position it occurs.

 

6) yes/ Don't know but I doubt XB has that capability.

 

7) Engineers. Remember ? The early clock bit was shoe horned in so they made up a name for it.

 

8) Lots of TI stuff conflicts with other TI stuff. Horrible documentation by that group but what are you gonna do ?

 

9) You control the clock bit with your SAL. Easy method is this. If your Xpos<128 then set the bit. If greater than 128 then clear the bit. Doesn't effect anything else.

 

 

Link to comment
Share on other sites

Q1: Why does the pane diagram on data sheet p2-13, fig 2-5, show the backdrop pane way near the bottom of all the other graphics panes when it clearly appears to be a Foreground Pane, concealing all sprites which dare to travel beneath it?

 

I don't think of the background pane as concealing any sprites, it's just that no sprites are drawn in the border area.

 

Q2: On to the Sprite Attribute Table... Why is the top ROW of y-pixels located a -1 when the leftmost COLUMN of x-pixels are located at 0?

 

The top left pixel position is (-1y,0x)? Why not 0y,0x?

 

Yes that's weird. The VDP is processing sprites on line y but not drawing them until line y+1.

 

Q3: Apparently we may place a sprite vertically from -31 to 255, with -31-0 and 192-255 being off, or partially off screen?

 

For a 16x16 sprite, because the the y weird y coordinate, a value < -1 is partially off screen at the top, and at the bottom a value > 175 places the sprite partially off screen. Note that for a signed byte value -1 = 255, -2 = 254, -3 = 253 and so on. A value of 224, for instance, you can either consider far down outside the bottom of the screen or above the screen (-32 = 224).

 

Q4: If we allow a Sprite’s vertical position to travel beneath the bottom of the screen (>191), will traveling to position 208 conceal all higher numbered sprites until this now-hidden vertically moving sprite vacates row 208, causing all the higher numbered sprites to magically reappear?

 

208 is a special value for the y coordinate that means to stop further processing of sprites. Very useful, for instance, to turn all sprites off by writing a single byte,

 

Q5: Assuming I set the sprite early clock bit, may I now position a sprite from -31 to 255? Or is the new range -31 to 224? If the limit is 224 then haven’t I just traded a left-side problem with another sprite behavior problem on the right side of the screen?

 

The second. You cannot have both at them same time. A byte would need 9 bits to support the full range. [edit: you need to switch between the two to support the full range]

 

Q6: With the early clock bit clear is the limit simply 0-255? Makes me wonder if this is the XB default setting?

 

Yes, XB doesn't use EC. The sprite motion routine built into the ROM doesn't support it. If you want to use EC you need your own sprite motion routine.

 

Q7: What is “TAG” in Fig 2-20 of the data book? The fourth byte in the screen attribute table was early clock + color code? How’s that “TAG?”

 

No idea.

 

Q8: The data book seems to conflict with the E/A Manual when it describes horizontal positioning of sprites off the left side of the viewable screen:

 

“...with EC set to 1...values for horizontal displacement in the range 0 to 32 cause the sprite to overlap with the left-hand border of the backdrop.”

 

This is because a value of say... 16 is moved to -16, since the EC moves sprites 32 pixels left?

 

Yes.

 

Q9: Lastly, is the EC something I need to manage (endlessly setting and clearing and setting...) throughout my code? Is this normal or is it either set or cleared upon initialization of the VDP registers at startup?

 

Yes. If your sprites should be able to move into the left border area you need to consider EC every time you move a sprite. [edit: If you never mover sprites to the right side of the screen you can leave EC on all the time. Since it's an attribute per sprite it does not depend on initialization of VDP registers.]

 

You need to store the desired X coordinate (-32 - 255) in a word (2 bytes) and then translate that into an x coordinate and a value for the EC bit. This is what I tried to show in the pseudo code:

 

http://atariage.com/forums/topic/162941-assembly-on-the-994a/page-28?do=findComment&comment=3990959

Edited by Asmusr
Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...