Creating A More Flexible, Efficient Screen DMA System

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.

Moderator: Moderators

Post Reply
User avatar
neilbaldwin
Posts: 481
Joined: Tue Apr 28, 2009 4:12 am
Contact:

Creating A More Flexible, Efficient Screen DMA System

Post by neilbaldwin »

I'm sketching out high-level ideas for the screen writing code for my next project and have been trying to come up with a nice flexible and efficient DMA system.

The general problems are;

- there is too much information contained on the screen to write in one frame (as always)
- there are several distinct areas that may or may not need updating, depending on what the user is doing. Some actions may require only one particular areas updating whereas other could require several (or maybe all) areas updating

My best stab at this so far is to break the code to update each area into separate subroutines with a jump table. The update routines will most often be just 'blitting' the data to the screen e.g;

lda buffer
sta $2007
lda buffer+1
sta $2007
...
lda buffer+31
sta $2007
rts

Each subroutine will then be given an ID number.

updateArea00 = 00
updateArea01 = 01
updareArea02 = 02
etc

So when you need to update the screen there is a process buffer in RAM. You first update the necessary buffers and then activate the DMA-ing by writing process IDs to the process buffer, terminated by something, say, $FF. So;

00,01,02,FF

would update area00 on the first frame, area01 on the second, area02 on the third and then stop. Each time an ID is processed you shift the buffer to the left until the first ID in the buffer is FF. Higher priority updates should go earlier in the buffer than low priority ones.

Obviously, when adding processes to the buffer, you'd always write them to the end of the buffer by seeking for $FF. There'd have to be some limits to the buffer length too.

Depending on the amount of data per area, you'd probably be able to process 2 IDs per frame but it would require balancing of the amount of data processed by each subroutine.

I'm still trying to get my head around what might happen if (when) the situation arises where you're writing to one of the screen buffers and either a) there's a process already in the queue that hasn't completed yet that is relying on data from that buffer or b) the queue gets big and you add processes to the end causing quite a bit of lag in the screen rewriting.

Thoughts anyone?
User avatar
Bregalad
Posts: 8036
Joined: Fri Nov 12, 2004 2:49 pm
Location: Caen, France

Post by Bregalad »

I guess it's possible to write a buffer system where it computes the cycles it approximately takes to write data to VRAM, and stop when VBlank time is about to end.
Then the system should resume the update next frame etc...
Useless, lumbering half-wits don't scare us.
User avatar
neilbaldwin
Posts: 481
Joined: Tue Apr 28, 2009 4:12 am
Contact:

Post by neilbaldwin »

I implemented a system similar to what I described. It's actually really good.

I'll try to distill the code down to something that I can post up here in case it's of any use to anyone else.

:)
3gengames
Formerly 65024U
Posts: 2281
Joined: Sat Mar 27, 2010 12:57 pm

Post by 3gengames »

Seems like a good idea, and you could limit one section to X sprites for the main character nomatter what, and then also have each other section for a different enemy or object.


Sounds like a great idea, but also at the price of a bit of PRG-ROM space, though. But I guess if it makes speed more efficient it might be worth it.
Post Reply