On Mon, 2 Mar 2026, Chad Jablonski wrote:
+void ati_finish_host_data(ATIVGAState *s)
+{
+ while (ati_flush_host_data(s)) {
+ continue;
+ }
Is this while loop still needed? It looks like it will fill the rest of
the blit rect with the last accumulator value instead of just finishing
the blit in the middle. Is that what the real chip does? Otherwise this
could just flush once and deactivate host data, couldn't it?
This is how the real chip behaves, but it flushes the entire 256-bit
accumulator wrapping around until the blit is complete. Even though
I think I now get how it may work but it's too late to try to model that
for the next release and since the approach limited to 128 bits in v11 is
simple enough and works well for what we need it so I think that's what we
should include in the upcoming release. We may try to improve this in the
future to better model the real chip but that may only really be needed
when we make the 2D engine async which will be a bigger work so we can
address this then.
But before I forget I write it down now. I think there may actually be 8
32bit host data registers behind HOST_DATA0-HOST_DATA7 (that's 256 bits)
but they are not accessed normally as registers but like a circular buffer
or FIFO such as:
reg 0 1 2 3 4 5 6 7
wp ^
rp ^
wp is a write pointer where any data written from any register will be put
(may actually be counted by bytes so one could push data by byte word or
long writes) then the 2D engine is reading from the rp read pointer once
128 bits are available (e.g. in the above figure 3 bytes were written and
writing one more byte would start processing but writing a word would also
store the first byte of the next chunk) so while the engine is processing
data from regs 0-3, regs 4-7 can still accumulate data and then 2D engine
can work on these while further data goes to reg 0-3 again. I don't know
what happens if guest would overwrite data which is being processed but
maybe that should not happen because 2D engine would be busy and guest
should wait for it or these old machines were not fast enough for that? In
any case in QEMU we can delay the write if it would overwrite the read
pointer. So ATIHostDataState.acc should be ATIVGARegs.host_data[8] and
there may be other regs storing the pointers but maybe those are part of
the 2D engine and not exposed.
But anyway this is not needed for now just noted for later.
Regards,
BALATON Zoltan