Jump to content

Photo

Assembly on the 99/4A


889 replies to this topic

#826 sometimes99er OFFLINE  

sometimes99er

    River Patroller

  • 4,225 posts
  • Location:Denmark

Posted Wed Feb 27, 2019 3:52 PM

So lets say I successfully poll the CRU for vsync and eventually detect one...

In my code, I now know Ive hit a 1/60th of a second NTSC (or 1/50th second, PAL) event. I believe thats it.

This vsync event now triggers a decision tree gate which runs a specific segment of code. Perhaps I decide to do three things when vsync is detected:

A. Update the player character position.
B. Hit my roll-ur-own sound routine to update background music.
C. Refresh the game scoreboard.

 

Looks good.
 

How do I know theres enough time to do these things between vsyncs?

 

You don't. We'll get to that.
 

How many tasks may I tie to the vsync event?

 

Well, if any number of tasks takes too much time, one may split things, reorder etc.
 

Im thinking about counting vsyncs and enabling sub-events based on determined vsync counts...

 

Absolutely. You would only update the score if the score has changed.
 

Am I attempting to process as much as I can before the CRT beam travels from bottom right to top left on the screen?

 

Yes. It's actually at the visible bottom just outside the 192 scanlines that makes up the display (24 character lines 32 columns), and just until the display starts again (the 24 lines, a good number of scanlines down the screen). Also called the vertical gap.
 
The vertical gap/blank goes on right after this (the 24th line is blank)

gallery_11132_2341_6588.jpg

and stops just before the colors (1st line of characters)

 

gallery_11132_2341_1855.jpg

 

I guess what Im looking for is a few tips and techniques on the topic.

 

Have a black background. This shows up in the border of the display. Change the background color to red when the vsync is detected. Change the background color to whatever for each of your major tasks (3-12). Change background back to black when all is done.

You will see some nervous color bands representing the time each task takes.
 

The idea of using the vsync signal as a constant interval timer is manageable.


Yep.
 

If I try to do too much after a vsync is detected Im thinking Ill miss the next vsync, and my interval timer will then become inconsistent and result in stuttering video/audio?

 

Yes, that is a concern, but try it out. Obviously one has to update the display right after the vsync (to avoid screen tearing), and game logic, positions, collisions etc. can be done after the update of display (effectively displaying what was computed in the previous frame). Depending on the use of buffers, updating the display can be rather fast (like switching the screen image table).

Hope this helps.


Edited by sometimes99er, Wed Feb 27, 2019 4:39 PM.


#827 Airshack OFFLINE  

Airshack

    Stargunner

  • 1,000 posts
  • Location:Phoenix, AZ

Posted Wed Feb 27, 2019 6:56 PM

^^^^ oh that Vertical Blank Interval Link was a great one! Thanks! Great read for clarity.

So...apparently the Atari 8-bit computer graphics systems had both horizontal and vertical blank interrupts. Powerful tools the TI system lacks.

https://en.wikipedia...blank_interrupt

We’ll never know when each horizontal line has completed as with Atari’s Horizontal Blank Interrupts, so we’re polling the vsync in lieu of a true hardware vertical blank interrupt.

Correct? Link led to this:

“As the VBI will be generated at the start of every displayed frame (50 Hz for PAL, 60 Hz for NTSC), it is also a useful timebase in systems lacking an interrupt from a programmable or fixed interval timer. Regular software functions like scanning a keyboard, reading a joystick or maintaining a time or date measurement can be carried out.”

Edited by Airshack, Wed Feb 27, 2019 7:08 PM.


#828 Airshack OFFLINE  

Airshack

    Stargunner

  • 1,000 posts
  • Location:Phoenix, AZ

Posted Wed Feb 27, 2019 7:18 PM

I remember from XB256 I can place a sprite vertically from 0 - 255, even though 0-191 was the visible range.

So I can hide sprites off screen (virtually in
Memory) at 192 and beyond. As long as I didn’t position them at >D0 which is 208, which terminated the sprite number and all higher sprites.

So for the 9918 the vertical blank interval includes drawing some x amount of lines above and below the 0-192 range, in addition to the electron beam diagonal travel time from bottom right to top left?

Understood all but that part I think.


Sent from my iPhone using Tapatalk Pro

Edited by Airshack, Wed Feb 27, 2019 7:19 PM.


#829 TheBF OFFLINE  

TheBF

    Dragonstomper

  • 988 posts
  • Location:The Great White North

Posted Wed Feb 27, 2019 8:03 PM

So for the 9918 the vertical blank interval includes drawing some x amount of lines above and below the 0-192 range, in addition to the electron beam diagonal travel time from bottom right to top left?

 

 

History Lesson from the Analog Video Age

 

<history>

The reason that there are unused lines at the top of the "raster" as it's called, is because in the early days it was never certain that the image would be stable at the top after the electron beam was dragged back to the top of the screen, so the extra lines at the top were a safety zone and therefore no picture was applied to those lines (22 lines if I remember?)  Remember, making TV actually work was at the limits of the tube technology in the very early days. 

 

In the 80's these unused picture lines were actually used for test signals and digital time code called "vertical interval time code" (VITC)

VITC  was essentially a serial data string applied to 1 line of video.

 

Also the entire image was assumed to be cropped because the TV manufacturer was supposed to "overscan" the image so the top, bottom and sides were hidden behind the edge of the box that held the CRT. :-)  In TV studios we used "underscanned" monitors so we could see the entire image.

</history>



#830 Airshack OFFLINE  

Airshack

    Stargunner

  • 1,000 posts
  • Location:Phoenix, AZ

Posted Wed Feb 27, 2019 9:28 PM

 
History Lesson from the Analog Video Age.
</history>


Thanks for yet another important piece of the puzzle. Interesting.


Sent from my iPhone using Tapatalk Pro

#831 Airshack OFFLINE  

Airshack

    Stargunner

  • 1,000 posts
  • Location:Phoenix, AZ

Posted Wed Feb 27, 2019 9:30 PM

 

 
Have a black background. This shows up in the border of the display. Change the background color to red when the vsync is detected. Change the background color to whatever for each of your major tasks (3-12). Change background back to black when all is done.

A very cool idea I’ll immediately adopt. Having a why-didn’t-I-think-of-that moment.

Edited by Airshack, Wed Feb 27, 2019 9:32 PM.


#832 sometimes99er OFFLINE  

sometimes99er

    River Patroller

  • 4,225 posts
  • Location:Denmark

Posted Thu Feb 28, 2019 1:47 AM

^^^^ oh that Vertical Blank Interval Link was a great one! Thanks! Great read for clarity.

So...apparently the Atari 8-bit computer graphics systems had both horizontal and vertical blank interrupts. Powerful tools the TI system lacks.

https://en.wikipedia...blank_interrupt

Well never know when each horizontal line has completed as with Ataris Horizontal Blank Interrupts, so were polling the vsync in lieu of a true hardware vertical blank interrupt.

Correct?


Yes.

Link led to this:

As the VBI will be generated at the start of every displayed frame (50 Hz for PAL, 60 Hz for NTSC), it is also a useful timebase in systems lacking an interrupt from a programmable or fixed interval timer. Regular software functions like scanning a keyboard, reading a joystick or maintaining a time or date measurement can be carried out.


I still think the TI sets the bit when the "frame is completed" (as in the last line of characters (line 24) has been drawn) - and not "while the beam is tracing up to the upper left corner of the screen".

http://www.unige.ch/...99/tms9918a.htm

#833 sometimes99er OFFLINE  

sometimes99er

    River Patroller

  • 4,225 posts
  • Location:Denmark

Posted Thu Feb 28, 2019 1:59 AM

I remember from XB256 I can place a sprite vertically from 0 - 255, even though 0-191 was the visible range.

So I can hide sprites off screen (virtually in
Memory) at 192 and beyond. As long as I didn’t position them at >D0 which is 208, which terminated the sprite number and all higher sprites.

 
Yes. The first vertical sprite position is >FF (Assembly not XB - there's a reason, but that's another story). Position >FE simply hides the top of a sprite (behind the top border).
 
You have to watch out for sprite magnification and size. At least position >C0 should always hide your sprite.
 

So for the 9918 the vertical blank interval includes drawing some x amount of lines above and below the 0-192 range, in addition to the electron beam diagonal travel time from bottom right to top left?

 

That's how I think I experienced it way back. And I think both MAME and Classic99 will show this if you change the background color when there's a vsync event.


Edited by sometimes99er, Thu Feb 28, 2019 2:00 AM.


#834 sometimes99er OFFLINE  

sometimes99er

    River Patroller

  • 4,225 posts
  • Location:Denmark

Posted Thu Feb 28, 2019 2:04 AM

A very cool idea I’ll immediately adopt. Having a why-didn’t-I-think-of-that moment.

  

I did that way back. It crossed my mind, but I've only used it since Asmusr brought it up. Quite handy.



#835 matthew180 OFFLINE  

matthew180

    River Patroller

  • Topic Starter
  • 2,626 posts
  • Location:Castaic, California

Posted Thu Feb 28, 2019 2:14 AM

With the 9918A the interrupt does not coincide with the actual VSYNC signal sent to the TV/monitor.  The term "VSYNC" is used loosely in conversation, but when talking about timing you should not conflate the two (interrupt and VSYNC).  The interrupt happens right after the active area, which is line 192 if you think of the active area as lines 0..191.  This is a good thing, because it gives you the maximum amount of time between frames to update the VRAM without conflicting with the VDP or worrying about tearing.

 

Some possibly useful calculations:

 

Total lines in one frame = 262 lines

Active area = 192 lines

Blanking area = 262 - 192 = 70 lines

 

One frame = 1/60 = 0.0166666 = ~16.6ms

One line = 16.66ms / 262 lines = 63.61us per line

Blanking period = 63.61us * 70 lines = 4.452ms

 

9900 CPU clock cycle = 3MHz = 333ns

Clocks per blanking period = 4.452ms / 333ns = 13358 cycles

 

The most common instructions in the 9900, i.e. the addition, subtraction, moves, compares, logical (except shift) average between 10 and 14 clocks, with variation depending on the access mode.  If you use a lot of the heavy hitter instructions like MPY, DIV, Shift, BLWP, and others, then those will chew up more time.  The 9900 datasheet shows the clock cycles for every instruction, and Classic99 can also should you actual execution time of instructions.  Anyway, just say an average of 20 clocks per instruction.

 

Average instruction time: 20 * 333ns = 6.6us

Average instructions per blanking period: 13358 / 20 = 667

 

But it is best to just write your code and see how much you can get away with. ;-)



#836 matthew180 OFFLINE  

matthew180

    River Patroller

  • Topic Starter
  • 2,626 posts
  • Location:Castaic, California

Posted Thu Feb 28, 2019 2:31 AM

 
Yes. The first vertical sprite position is >FF (Assembly not XB - there's a reason, but that's another story). Position >FE simply hides the top of a sprite (behind the top border).
 ...

 

Edit: Just adding additional information.  I'm pretty sure sometimes99er is aware of these details.

 

The sprite Y-position is off-by-one because the 9918A has to process sprite information *during* the scan line (as well as during the horizontal blanking period), which it then displays during the next scan line.  So the sprites are processed correctly based on their Y-position, but you don't see them until the next line.  There is a VDP master timing diagram floating around the 'Net that was provided by Karl Guttag (one of the 9918A engineers) if you want to know the gritty details.


Edited by matthew180, Thu Feb 28, 2019 2:33 AM.


#837 apersson850 OFFLINE  

apersson850

    Dragonstomper

  • 594 posts

Posted Thu Feb 28, 2019 7:05 AM

You also have to remember that the memory in a normal TI 99/4A isn't running at full speed. Well, inside the console it is, but not memory in cartridges, DSR or expansion RAM. This has an impact on instruction timing.

I've noticed that if both code and workspace is in slow RAM (normal expansion), the execution time will increase by about 110%, compared to if both code and workspace is in fast, 16-bit wide RAM.

The most common mix is of course to run code in slow memory and have the workspace in fast memory.



#838 TheBF OFFLINE  

TheBF

    Dragonstomper

  • 988 posts
  • Location:The Great White North

Posted Thu Feb 28, 2019 8:43 AM

 

 

Total lines in one frame = 262 lines

 

One frame = 1/60 = 0.0166666 = ~16.6ms

One line = 16.66ms / 262 lines = 63.61us per line

Blanking period = 63.61us * 70 lines = 4.452ms

 

 

 

Minor correction about the details of NTSC video.

I believe the 9918 works this way, but I am not 100% certain.  For it to display on an NTSC TV I think it must work this way.

 

Total lines in one "FIELD"= 262

One FIELD = 1/60 = 0.0166666 = ~16.6ms

Fields per frame = 2

lines per FRAME=525

Frames per second=29.97 (color TV)

 

It is an interlaced picture, showing odd lines, then even lines. This was done to reduce bandwidth requirements for over the air transmission, while maintaining approximately 30 frames per second. (it was 30 for B&W TV, but changed to 29.97 to interleave the **color information with the B&W picture. (backwards compatibility)

 

**The story I was told at RCA ,in Camdon NJ, (1981) was that when they did the first test of the color broadcast system for the FCC, their was a moiré pattern running through the picture. The engineer in charge of the demo, tweeked the control that adjusted the 3.5MHz oscillator until the moiré pattern went away and that became the new "correct" frequency for the oscillator.  3.579545MHz   :D

 

(I cannot verify the validity of the story, but it sounds credible.)



#839 Lee Stewart OFFLINE  

Lee Stewart

    River Patroller

  • 3,966 posts
  • Location:Silver Run, Maryland

Posted Thu Feb 28, 2019 9:16 AM

Minor correction about the details of NTSC video.

I believe the 9918 works this way, but I am not 100% certain.  For it to display on an NTSC TV I think it must work this way.

 

Total lines in one "FIELD"= 262

One FIELD = 1/60 = 0.0166666 = ~16.6ms

Fields per frame = 2

lines per FRAME=525

Frames per second=29.97 (color TV)

 

It is an interlaced picture, showing odd lines, then even lines. This was done to reduce bandwidth requirements for over the air transmission, while maintaining approximately 30 frames per second. (it was 30 for B&W TV, but changed to 29.97 to interleave the **color information with the B&W picture. (backwards compatibility)

 

**The story I was told at RCA ,in Camdon NJ, (1981) was that when they did the first test of the color broadcast system for the FCC, their was a moiré pattern running through the picture. The engineer in charge of the demo, tweeked the control that adjusted the 3.5MHz oscillator until the moiré pattern went away and that became the new "correct" frequency for the oscillator.  3.579545MHz   :D

 

(I cannot verify the validity of the story, but it sounds credible.)

 

Actually, the TMS9918A operates in non-interlaced mode (see Thierry’s site).  I know enough about the electronics involved to get me into trouble and not enough to get me out, but I seem to recall Tursi explaining this as the reason most modern TVs/monitors could not handle the signal properly.

 

...lee



#840 Airshack OFFLINE  

Airshack

    Stargunner

  • 1,000 posts
  • Location:Phoenix, AZ

Posted Thu Feb 28, 2019 11:45 AM

Anyway, just say an average of 20 clocks per instruction.
 
Average instruction time: 20 * 333ns = 6.6us
Average instructions per blanking period: 13358 / 20 = 667


This is amazing to discover. I never looked into the numbers but guessed I probably had time for a dozen or so instructions. Makes my day.


Sent from my iPhone using Tapatalk Pro

#841 matthew180 OFFLINE  

matthew180

    River Patroller

  • Topic Starter
  • 2,626 posts
  • Location:Castaic, California

Posted Thu Feb 28, 2019 5:08 PM

TMS9918A Datasheet, pg. 3-8, sec 3.6.2, third paragraph:

 

"The TMS9918A/9929A operates at 262 lines per frame and approximately 60 frames per second in a noninterlaced mode of operation.  The TMS9929A operates at 313 lines per frame and approximately 50 frames per second in a noninterlaced mode of operation."

 

An NTSC video field is actually 262.5 lines, for a total of 525 lines per interlaced frame.  The 9918A does not generate that final half line, which causes every field to always start at the same time after vertical refresh.  Basically every field is drawn on top of the last instead of being offset by half a line (which would allow the slight vertical displacement required to interlace the fields).

 

Displays like old TVs were very tolerant of loose timing like this and would just sync to the video they were given as best they could.  Modern displays (TVs) seem to have a harder time with this, and as mentioned, some can't deal with the missing half a line.



#842 Asmusr OFFLINE  

Asmusr

    River Patroller

  • 3,113 posts
  • Location:Denmark

Posted Thu Feb 28, 2019 11:56 PM

I guess it would be difficult for the 9918A to generate an interlaced picture when we know that the sprites are processed on the line before they are displayed?

 

What's interesting for me is how this affects the experience on a modern TV. If you play a game that scrolls the screen horizontally at 60 frames per second, do you only see every second frame and/or is every second line displaced?



#843 matthew180 OFFLINE  

matthew180

    River Patroller

  • Topic Starter
  • 2,626 posts
  • Location:Castaic, California

Posted Fri Mar 1, 2019 5:49 PM

I don't think it affects modern TVs much at all.  TVs always were (are) 60Hz (or 50Hz PAL), it is just that a full "frame" was split into two "fields" (even and odd), which means the "frame rate" is 30Hz, but the refresh of the display is still 60Hz.  You see every 60Hz field the 9918A is generating.  Starting the even/odd fields at half-a-line from one another is just a function of the video signal itself and not really the sync timing.



#844 Tursi OFFLINE  

Tursi

    Quadrunner

  • 5,638 posts
  • HarmlessLion
  • Location:BUR

Posted Fri Mar 1, 2019 6:48 PM

You do get a little weirdness on displays that try to be too smart... for instance when I released the flicker color demo for Convert9918's half-multicolor mode, my LCD TV tried to de-interlace the image, and gave me alternating lines of color instead of flickering them. But it was imperfect, sometimes the deinterlace would blend instead, and then back again. In short, it looked awful. ;)

But for the most part, you don't see anything too weird. Sometimes a combing effect caused by the above on things that change at 60hz, not not often.

#845 Asmusr OFFLINE  

Asmusr

    River Patroller

  • 3,113 posts
  • Location:Denmark

Posted Sat Mar 2, 2019 5:09 AM

Is there any reason these two ways of checking for vsync should give different results?

Edit: and I'm not talking about the end value of r12 but whether they wait the same time.

vsync  movb @vdpsta,r12
       andi r12,>8000
       jeq  vsync

vsync  movb @vdpsta,r12
       jgt  vsync
       jeq  vsync


Edited by Asmusr, Sat Mar 2, 2019 5:14 AM.


#846 Airshack OFFLINE  

Airshack

    Stargunner

  • 1,000 posts
  • Location:Phoenix, AZ

Posted Sat Mar 2, 2019 8:31 AM

Will the faster of the two be more likely encounter the hardware race or hazard?

Edited by Airshack, Sat Mar 2, 2019 11:15 AM.


#847 Asmusr OFFLINE  

Asmusr

    River Patroller

  • 3,113 posts
  • Location:Denmark

Posted Sat Mar 2, 2019 10:19 AM

The second variant is what I have used in Pyjamarama. It is failing on my TI, missing a large number of interrupts, but is apparently working on other people's computers. If I change to the first variant Pyjamarama is working fine. The strange thing is that if I isolate the code for the first variant, pulling it into a test program, it works fine on the same computer. I don't know what to make of it.



#848 nanochess OFFLINE  

nanochess

    Processorus Polyglotus

  • 5,871 posts
  • Coding something good
  • Location:Mexico City

Posted Sat Mar 2, 2019 10:26 AM

I can say for experience that reading too fast the status register misses interrupts in Z80, even more as the VDP gets hot. It's so weird that I prefer *always* to use interrupts.

I'm surprised that polling in TI99/4A works just fine. Glad I didn't use the 2nd variant in Borzork or still I would be crashing my head against the wall.

#849 sometimes99er OFFLINE  

sometimes99er

    River Patroller

  • 4,225 posts
  • Location:Denmark

Posted Sat Mar 2, 2019 2:12 PM

Is there any reason these two ways of checking for vsync should give different results?
Edit: and I'm not talking about the end value of r12 but whether they wait the same time.

vsync  movb @vdpsta,r12
       andi r12,>8000
       jeq  vsync

vsync  movb @vdpsta,r12
       jgt  vsync
       jeq  vsync


What happens if you leave out "jeq vsync" in the second one?

#850 Asmusr OFFLINE  

Asmusr

    River Patroller

  • 3,113 posts
  • Location:Denmark

Posted Sat Mar 2, 2019 2:22 PM

What happens if you leave out "jeq vsync" in the second one?

 

Then, as far as I remember, it also fails on the F18A where the 5th sprite bits can be zero.






0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users