Jump to content
IGNORED

Display lists and double buffering?


Sdw

Recommended Posts

Anyone have some good "best practice" on how to handle double buffering of display lists?

It's easy to set up a system that switches between display lists:

 

dlist1:
.byte $70,$70,$70
lineptrs:
...(stuff that I change dynamically goes here)
.byte $41,<dlist2,>dlist2


dlist2:
.byte $70,$70,$70
lineptrs:
...(stuff that I change dynamically goes here)
.byte $41,<dlist1,>dlist1

 

This will switch between dlist1 and dlist2 every frame.

However, how do I sync my main code so that I'm updating the code that is NOT currently being displayed?

 

lda #0
!wait:
cmp VCOUNT
bne !wait-
..Here i need to figure out if dlist1 or dlist2 is in use, so I can start updating the other!

 

Or can I somehow avoid using the $41 "jump" instruction in the display list, and control it manually from my main code instead? Which is the best solution?

Link to comment
Share on other sites

Your example will not switch dlist1 a and dlist2 every frame unless you disable OS VBI stage 2 routine where DLIST HW regs at $d402,$d403 gets updated from shadow regs at $230,$231 and dlist will start from this address regardles of $41 JMP instruction address. I think that the "best" solution is to set up dlist1 and update buffer2 data and next frame set up dlist2 and update buffer1 data and so on.

Link to comment
Share on other sites

Well, the dlist switching code I posted works, so I guess I have the OS disabled. I always start my program with a SEI, so I guess this OS stuff you are talking about is set up as an interrupt. I want none of that, all CPU cycles for my code please! :)

 

But back on topic - if going wihtout the $41 instruction, how do I tell the display list it is "done", so that it doesn't continue trying to run crap code that is in memory after my last display lines?

Also, when can I do the $d402/$d403 update? Is it safe as soon as VCOUNT hits 0 to update it, and it will not take effect until next frame?

Link to comment
Share on other sites

Yes.. SEI will disable VBI stage 2 ;)

 

You have to have the $41 instruction to tell ANTIC to stop fetching DLISt instruction. I only meant that the following address is irrelevant if OS VBI is updating HW regs from shadow regs. Writing to HW regs at $d402 and $d403 takes immediate effect, so changing them is safe out of display area. With VCOUNT=0 it's safe, but takes immediate effect as I wrote so it's the display list which will be displayed this frame and you have to draw to the other buffer.

Link to comment
Share on other sites

If you have disabled the OS then you don't have to wait for VCOUNT=0. You can update $d402/3 immediately after the last line of your display. If your display is 240 scanlines tall, that would be VCOUNT=124. You could also wait as late as VCOUNT=3+ and still influence which byte ANTIC fetches for the first displayed scanline which is at VCOUNT=4. Depending on your situation this could give you a few more CPU cycles where you're not polling VCOUNT.

 

See also section 4.5 of the Altirra Hardware Reference Manual:

 

"Valid display list range

 

The display list starts at scan line 8 and ends no later than scan line 248. The maximum height of a display list is thus always 240 scan lines. This is true even in PAL, which has 50 more scan lines than NTSC. If a display list is too long, ANTIC automatically suspends the display list at the beginning of vertical blank at scan line 248 and resumes it at the end of vertical blank on scan line 8 of the next frame. This means that if a display list were exactly 480 scan lines tall and looped with a jump ($01) instruction, it would alternate perfectly between two images. Typically this doesn't happen, though, because the vertical blank routine reloads DLISTL/DLISTH. Otherwise, however, ANTIC will happily keep fetching instructions, wrapping around within 1K of memory over and over."

Link to comment
Share on other sites

1. In my demos I use two display lists - each for each buffer. Some guys modify screen addresses inside one display list. So, as you see - there's no one 'best practice' with this.

2. According to this:

Well, the dlist switching code I posted works, so I guess I have the OS disabled. I always start my program with a SEI, so I guess this OS stuff you are talking about is set up as an interrupt. I want none of that, all CPU cycles for my code please! :)

 

hen can I do the $d402/$d403 update? Is it safe as soon as VCOUNT hits 0 to update it, and it will not take effect until next frame?

Maybe you know, maybe not: to turn off OS (and ROM) you should do:

sei

lda $14

_1 cmp $14

beq *-2

lda #$f2

sta $d301

<set nmi vector>

...

This way you have free whole zeropage and RAM $C000-$CFFF and $D800-$FFFF.

  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

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