Jump to content

Open Club  ·  60 members

DASM
IGNORED

6502 assembly code optimisation


RevEng

Recommended Posts

Despite both devices using rotary encoders, reading a Trakball is a different problem being solved. The trakball is much closer to a mouse in resolution, and this sort of device doesn't have the same resolution problems as the driving controller being used like a paddle. The relatively unoptimised mouse driver I presently have performs smooth as silk on the 7800. To use a picture analogy, you won't notice the occasional bad pixel in a high-res photo, but if you expand a 16x16 icon to the same size as that photo, one bad pixel sticks out like a sore thumb.

 

Even if they were comparable controls, the Arkanoid WIP has a little more DMA burden than Centipede.

Link to comment
Share on other sites

2 hours ago, RevEng said:

To use a picture analogy, you won't notice the occasional bad pixel in a high-res photo, but if you expand a 16x16 icon to the same size as that photo, one bad pixel sticks out like a sore thumb.

True, but slow movements (in your analogy "zooming in") may give odd results. If there are only one or two changes per frame and busy DMA, then there is a high chance the changes get misinterpreted by the code into opposite direction. But if you make sure, that two consecutive reads are within a reasonable number of cycles, you either get the reads or no movement at all. But never into the wrong direction.

BTW: The C64 had DMA too, but much less interfering (just 40 cycles every 8 lines vs 63 cycles/line). I wonder why the 7800 is so different.

Edited by Thomas Jentzsch
Link to comment
Share on other sites

Sure, but a quick clockwise overturn isn't trivially detectable from a slow counterclockwise turn. I don't think it's a common enough failure to warrant potentially throwing what might be good samples, but I guess I need to do some testing to back that up.

 

The C64 had hardware sprites, so it's DMA wasn't quite so involved. The 7800 renders everything - sprites and characters - to a scanline buffer. (technically there's 2 buffers, and while one is used for rendering, the other is displayed.) As part of that, Maria needs to traverse data structures you setup in RAM that describe the objects in the current set of scanlines (aka the zone). It's a sort of cross between hardware sprites and soft sprites - I've always described it as hardware-assisted soft-sprites - and as a result the whole thing is quicker than soft sprites, and slower than hardware sprites.

 

It has it's pros and cons. The main pro is that the 7800 can throw a lot of sprites at the screen with this system, at the cost of losing CPU time that you'd otherwise have access to. Its a very unique machine.

 

 

  • Like 1
Link to comment
Share on other sites

9 minutes ago, RevEng said:

Sure, but a quick clockwise overturn isn't trivially detectable from a slow counterclockwise turn. I don't think it's a common enough failure to warrant potentially throwing what might be good samples, but I guess I need to do some testing to back that up.

An overturn within a scanline or so should be extremely unlikely at 75 DPI. But if the scans are quite a few scanlines apart, then it becomes more likely. How big the gap between scans can become, I don't know. And yes, testing will tell the truth.

 

Impressive demo.

Link to comment
Share on other sites

I ran though a test where I entirely disabled the branch at the end, and added "inc leftmove" and "inc rightmove" to the relevant parts of the driver. (fire button in the demo clears the values, to make it easy to see changes) Allowing only one pass simulates a near-worst case for DMA. 100% DMA usage, while possible in theory, would be quite difficult to achieve with a real game design.

 

With this demo, turning the driving control at quick speeds with my fingers or palm on the control at all times, I can't get backwards values to register at all. (clearly the controller does get stalled values at quicker rates, as it slows down when it should be going faster). I can get some small number negative values on a positive spin if I slap spin it, the same way one might keep a basketball spinning on their finger, but otherwise don't see negative values with any technique that seems useful for game play.

 

Going back to the numbers... The wheel has 16 positions encoded per 360 degree turn, which means to get it to miss a value you need to be spinning faster than 1/16 revolutions per frame, and to start getting false negative values, you need to exceed 1/8 revolutions per frame. Converting to rotations/second (using PAL) for those numbers gives you 3.125 rotations/second, and 6.25 rotations/second, respectively. The lower threshold comes into play, but the upper one seems difficult enough to hit that it doesn't warrant worrying about it.

 

Anyway, thanks again for the help. Your version of the driver is in place and working well. ?

Link to comment
Share on other sites

5 minutes ago, RevEng said:

The wheel has 16 positions encoded per 360 degree turn...

Just 16 positions? Are you sure? That's the resolution of an Atari 2600 driving controller. Which usually is read only once per frame. 

 

I thought it has higher resolutions when you mentioned it acts like a paddle.

Link to comment
Share on other sites

10 minutes ago, Thomas Jentzsch said:

Just 16 positions? Are you sure? That's the resolution of an Atari 2600 driving controller. Which usually is read only once per frame. 

 

I thought it has higher resolutions when you mentioned it acts like a paddle.

 

mentioned previously I was referring to the 2600 driving wheel, but using it as a paddle replacement. :) Reading it once per frame is great when you're using it like a 16-position steering wheel. When you spin moderately fast (like I did in my demo) it misses values all over the place.

 

To get traction on the screen from the 16 position wheel, I'm doubling the distance, and also applying an acceleration curve.

Link to comment
Share on other sites

6 minutes ago, RevEng said:

 

mentioned previously I was referring to the 2600 driving wheel, but using it as a paddle replacement. :) Reading it once per frame is great when you're using it like a 16-position steering wheel. When you spin moderately fast (like I did in my demo) it misses values all over the place.

Got you now. With such a low resolution, I think the current code is (way) more than save.

Alternatively you could just read once before and once after the kernel. That would almost double the distance.

Link to comment
Share on other sites

It's a good idea. I tried that a while back. It definitely helps push that lower threshold, but the separation between the bottom and top of visible is about 70 lines, vs 192 between the top and bottom, so it's not perfect. Also the bottom of the visible screen marks the beginning of non-visible CPU time, which is very precious on the 7800. Ideally I'd have an interrupt for a second check smack-dab in the lower section of the visible screen, but I try to avoid mid-screen interrupts, as it will likely tie my hands with other features I have planned, like vertical scrolling.

 

For now anyway, allowing the game designer to tune the timing of the driver will work. If the game is using driving controls as paddles, it will almost certainly support paddles too, so the game will have to budget CPU time for reading those.

Link to comment
Share on other sites

  • Recently Browsing   0 members

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