Hi,
this is more an Atari question than a Hatari one but knowing how many
knowledgeable people are here... :)
Even though I'm not actively coding on ST/E machines, out of curiosity
I'd like to know how a programmer is supposed to handle double buffering
on ST/E.
On Falcon it is easy:
- do your code
- swap buffers
- Vsync() // wait for vbl
- VsetScreen(-1, new_buffer, -1, -1) // set physbase
This works because VsetScreen just writes to FFFF8201 & friends which
gets reloaded at the line defined by VDB (btw, you can consider this as
a feature request, Hatari doesn't do this yet ;-)). And since we know
that the write to FFFF820x is happening during VBL, it's 100% safe to
assume that this never happens:
move.b vbasehi,$ffff8201
// VDB --> Videl reloads its internal video base pointer from $ffff8201,
$ffff8203 and $ffff820d
move.b vbasemi,$ffff8203 // too late guys...
move.b vbaselo,$ffff820d //
But what about the ST/E shifter? AFAIK the video base is taken into
account at line 310 (end of the visible area / start of VBL). So if I do
the steps above, Setscreen() will have no effect for the whole frame
because when setting it during VBL, the video base has already been read.
I was considering:
- do your code
- swap buffers
- Setscreen(-1, new_buffer, -1) // set physbase
- Vsync() // wait for vbl
which does the trick but then there's the danger of reading only the
partially set video base address, isn't it? (see my example above, just
replace VDB with line 310...) Assuming that your code may take a
variable amount of frames (i.e. you can't set the logical buffer in
advance so it reloads by the end of the frame), is there a way to do a
100% safe double buffering on ST/E?
I can think of only one way, optimize the Setscreen() call into one
instruction, i.e. align the screen buffer on 256 bytes (8203 = $00) and just
move.l new_buffer,d0 ; $00123400
lsr.w #8,d0 ; $00120034
move.l d0,$ffff8200.w ; not interruptible by the Shifter?