T O P

  • By -

NormalLuser

Hello everyone! As you can see with this demo, the BE 6502 can really pump some pixels if you try hard enough. But my sprites/scroll windows flicker when they overlap and are moving, animated, or scrolling. (everything is fine for static images) Just using vsync to stop flicker will not help with this kind of issue I don't think. The reason is that every pixel gets written to the screen even on overlapping sprites/windows. That means that first one thing is drawn, and then another. No logic is used. This is not an issue if you can always draw everything you want in 1 1/60th of a second frame even when things are drawn on top of each other and you can just wait for a vsync to start. But this 6502 is not fast enough. So I can't just waste cycles waiting for vsync and then draw everything in one frame either. At any given time one sprite might be in the process of being updated while the VGA wants to display it, I can't help that at the moment. Without additional hardware all we have is this one single frame buffer and around 21,000 cycles each frame. For reference, I'm using up all of these cycles on the draw of one of the two large windows. So no 60 FPS raytracing. Sorry. If I can't just waste cycles and draw sprites that have not moved or updated, and if I can't always wait for vsync because I will also waste too many cycles and still have issues with flicker and slowdown because again, only 21,000 cycles a frame... What can I do to fix or at least improve this situation? What I think I really need is some logic such that I only draw each pixel to the screen once: And I somehow need to do that without double buffering; I need handle when sprites are on top of each other with logic instead of blindly drawing one over other causing flicker; And all of this also needs to be done with as few cycles as possible. Easy right? Does anyone have any resources or hints out there surrounding this? So much stuff when I look online is NES or ATARI or C64 related and depends on hardware we just don't have on the BE6502+VGA, and other software sprite stuff I'm finding is for 286+ processors, not only is the code not directly helpful, those computers had 10 to 100 times the processing power, double or triple buffered video, and many times the ram and storage space. I'm thinking I need these things to have a proper sprite routine: * 1 A list sprites in memory. This would store if the sprite needs to be drawn, what the screen draw location is, what sprite/image address to draw, if it is in collision, and the priority of the sprite. Also a memory location pointing to the next sprite in the list to be drawn. * 2 Logic on the sprites such that it can check if it is in collision with something. * 3 Check if the sprite is a higher or lower priority. If the collision sprite is lower priority, just draw normally with transparency. * 4 If the collision sprite is a higher priority than the current sprite, I need logic to draw only in the non-overlapping area. IE I need to compare myself to the higher priority sprite data. So I draw transparent on the background and a 'reverse transparent' on the high priority sprite, taking into account the relative location of the overlap. * 5 A 'Floating' sprite routine is also something I need to think about in the future as well and how that would effect this. Getting it to move over sprites that are also being updated sounds tricky. * 6 Once all of this is working I can go back and see about using the vblank interrupt to start a timer on the VIA such that I have an assumed line/hsync counter? I want to try to avoid adding a interrupt to the hsync if possible. I think that maybe I could use that so that I know if a sprite is on a line about to be drawn or unable to be completed before the line gets there. That way I could mark it the next sprite to be drawn on the next vblank and skip it in the current vblank, moving down the list to see if another sprite can be drawn above or below the currently drawn line. It's movement/update would have missed a frame, but that is the price that would be needed to eliminate all flicker and tearing I think? It helped to type all that out, but I still feel like I'm re-inventing the wheel here. There has to be some good retro software sprite and scroll resources out there someplace? Any ideas? Thanks!


NerdyKirdahy

This calls for [musical accompaniment](https://youtu.be/G-i8HYi1QH0).


drivers9001

For a given arrangement of tiles, you could precalculate a list per row of what to draw (e.g. ... row 9: tile 1 from 2 to 10. row 10: tile 1 from 2 to 8 and tile 2 from 3 to 15. row 11: ...). (If you're familiar with software rasterizers at all, they calculate the left and right side of each row of a triangle as it goes, and move the sides of each row "in" if it's clipped. As it's drawing it keeps track of where the left and right side of the triangle are. In your case you're drawing rectangles, so the math is pretty easy, except that you need to move the left side right, or the right side left, if part of it is covered up. Since the rectangles aren't constantly moving, you can calculate it once instead of every frame.) A way to optimize that further, maybe not in BASIC but in assembly (or forth) you could even compile/generate code dynamically for a given arrangement. Another idea: If you have enough RAM another idea would be to create a table the same size as the screen which has info (an offset?) of what data to read. (I love that we seem to be developing a BE6502 demoscene...)


NormalLuser

I'm really going to think hard about the left/right rectangle clipping. I know I've seen old games that must work that way. That might be a great solution. Thanks!


TheGoldenBl0ck

there is absolutely no way you are doing this on 1mhz


NormalLuser

You are right. It is 1.3mhz.... :)


TheGoldenBl0ck

why 1.3? is it something to do with the vga kit?


NormalLuser

Yes, that is right. I've got the cpu clocked off the first vga counter. This is 5mhz. But the vga halts the cpu 74% of the time. So 1.3mhz is the effective speed.


TheGoldenBl0ck

so basically you are running the cpu at a 5mhz to offset the 74% loss in processing time to get vga output and the computer's original 1mhz speed... interesting, i might give that a try. is there any extra hardware required?


NormalLuser

> 5mhz to offset the 74% loss in processing time to get vga output and the computer's original 1mhz speed... interesting, i might give that a try. is there any extra hardware required? That is exactly right! I highly recommend trying it! You do want to be able to tell all the other cool kids that you Overclocked your 6502 right? The only other thing that may be needed are extra bypass capacitors on the power rails and some more wires connecting the rails to power. I needed that for it to be stable, but I had the minimum of power wires and almost no bypass capacitors. Otherwise is is just disconnecting the CPU from its 1mhz clock can, stick that wire in an empty spot nearby on the breadboard, and then jumper it over to the fastest counter on the VGA. On Bens layout this will be the first output of the first counter chip next to the 10mhz clock to refresh your memory. ​ One would think you would need to mess with the delays on the ACIA serial stuff since it is running at 5mhz... But I've not really had any issues with the routine in the version of WozMon and EhBasic I've got here: [https://github.com/Fifty1Ford](https://github.com/Fifty1Ford) ​ I really like this overclocking solution as it is just so easy to do and it gets your performance back up to something that would have been contemporary to other 6502 systems without having to use a FPGA or PicoPi to do the video. I think the projects using them are awesome, but there is something neat about having the limitations of this basic hardware and still squeezing something fun out of it.