VBLANK

Christopher Tumber Asked

Only 19 scanlines of VBLANK? Only 2166 cycles for game calcs per frame? Who the hell thought that was acceptable? That's less than half the 2600 for crying out loud!! Why does MARIA need to halt the 6502? Why doesn't MARIA just run in the background, like, oh, EVERY OTHER SYSTEM AFTER THE 2600!!!

Anyway, attached is a demo of sprite handling routines I'm working on. This demo displays 41 sprites. It's currently limited to 20 sprites per zone for a maximum of 480 sprites on screen (though RAM would be difficult as each sprite is 5 byes (X,Y,BitmapPointer,Width/Palette) and there's already a huge chunk of RAM dedicated to the DLs). It does some movement but it's very regimented because there's no checking for >20 sprites on a line and it tends to crash due to memory overwrites if 20 is exceeded.

It also flickers like crazy because my routines are too slow to complete every frame (I'm rebuilding the Display Lists from scratch each frame which may no be the best way to handle things) since there only 2166 cycles available (!!!!!).

Eric Ball Answered

MARIA needs to halt the 6502 because it shares the memory bus with it. I don't know how the Atari 8bits/5200 work, but the NES has a separate memory bus for the GPU.

Anyway, it's a little better than that. MARIA only halts the 6502 while it's reading from memory. So most of the cycles during the offscreen potion (~50 lines) are also available. And if you don't use every cycle per line the 6502 will get some more CPU time.

Yeah, for my balldemo each sprite requires 224 cycles, or two scanlines to add to the display list. I don't know if there is a more efficient way to do it.

Greg DeMent Answered

Though there's only 19 scanlines of official vblank, there's also 51 scanlines that are not reliably visible on the screen. It's up to you how many scanlines you want to draw, but if you stick with the official 192 lines, then you've got 70 scanlines that are either empty or vblank. You could use a DLI at the end of the visible screen and just consider that the beginning of vblank.

If that still isn't enough, you could try inserting DLI's after every several zones, and use them as triggers to update some display lists as soon as their zones have been drawn. That way you're taking some advantage of leftover CPU time during the visible screen. But if you try that you have to make sure that every DLI finishes execution before the next one hits, otherwise be prepared for an unexpected jump back to the start of your DLI function.

Redrawing the displaylists on every frame would generally be a bad way to go, but if everything on the screen is always moving then it might not make much difference. If you do keep rebuilding the display lists, then you might as well pack them tight instead of allocating 20 sprites per zone even when they're not needed. Right now you're getting the worst of both worlds - wasted memory and slower rendering.

If you decide to stop rebuilding displaylists on each frame, and instead only update the objects that have moved, then you'll get more performance but it will waste some memory. I know you said you aren't really working on galaga, but at least for this demo 20 sprites per zone seems excessive. The exact number depends on what you're working on, but I'd try setting the sprite limit to something that will almost never be exceeded, and write a flicker routine to handle rare exceptions.

Matthias Answered

Well, I am not sure about that. You should have about 40 (15+25) scanlines before the first visible scanline. That means that you have 4560 cycles minus the cycles maria needs to read the dl's that "build" the blank lines (see APPENDIX 4 in the software guide). Additionally you have 30 invisible scanlines at the bottom that you could use.

Matthias Answered

ANTIC halts the 6502 to do memory refresh and fetch graphics data.Â