VIDC1/20 emulation

Discuss development specific to the Pi version of ADFFS
JonAbbott
Posts: 2938
Joined: Thu Apr 11, 2013 12:13 pm
Location: Essex
Contact:

Re: VIDC1/20 emulation

Post by JonAbbott »

ADFFS500223 module now updated, with VIDC1 support.

Palette, HDSR, HDER, VDSR and VDER register writes now update the GPU. I've tested the parameters that James Pond uses and it appears to work okay - I ended up with a visible 300 x 200 MODE at any rate. However, I was expecting the display to become shifted and it doesn't. It looks like GraphicsV 2 only changes the visible display and not the way it handles the underlying data.

Without a working game to test, I also don't know at this point if this will work without flickering. I may well end up having to write a full VIDC emulator to deal with it.

Unrelated to this, there's an issue with certain MODEs not working. For example MODE 9 works, but MODE 15 doesn't - I've no idea why at the minute. All the 1 bit MODEs are double height with blank scanlines being inserted on every alternate scanline. I suspect the VIDC parameter list is being modified by RO, but need to investigate.
JonAbbott
Posts: 2938
Joined: Thu Apr 11, 2013 12:13 pm
Location: Essex
Contact:

Re: VIDC1/20 emulation

Post by JonAbbott »

JonAbbott wrote:I've tested the parameters that James Pond uses and it appears to work okay - I ended up with a visible 300 x 200 MODE at any rate. However, I was expecting the display to become shifted and it doesn't. It looks like GraphicsV 2 only changes the visible display and not the way it handles the underlying data.
The issue here is that the GPU on the Pi requires screen widths in 32 pixel steps, so 320 is valid as is 288, but not 300. I need to code alternative blit routines that take account of this.

I've now coded up the VIDC20 abort handler, although didn't get time to test on Fri, so will get that sorted on Mon along with the above.

The next thing I'll be coding is support for mid-frame palette changes, this will need to use a 16 or 24bit base MODE and handle palette conversion on a scanline by scanline basis. The tricky bit is working out which scanline the palette change occurred on.

I'm fairly certain that games will have to use IOC timers for this, relative to the last VSync, so if I add IOC timer emulation it should just be a matter of converting the IOC ticks since the last VSync to get the scanline.

The next trick is speeding up palette conversion, I'm going to implement a palette lookup table for every scanline. We're only talking 16 32bit palette entries per scanline, so it will neatly fit in 4 cache lines and can be pre-cached via PLD ahead of each line. The table can be pre-populated on a MODE change and updated as palette changes are written to VIDC. Should the timing not be that accurate, I'll pre-populate the table on each VSync.

I have a feeling this will be quick enough for all 16 colour MODEs, so may ditch the 256 colour palettised conversion code in favour on one method for simplicity.
JonAbbott
Posts: 2938
Joined: Thu Apr 11, 2013 12:13 pm
Location: Essex
Contact:

Re: VIDC1/20 emulation

Post by JonAbbott »

JonAbbott wrote:The issue here is that the GPU on the Pi requires screen widths in 32 pixel steps, so 320 is valid as is 288, but not 300. I need to code alternative blit routines that take account of this.
I've coded the 8-bit routine, 4-bit is proving a little problematic although almost there.
JonAbbott wrote:I've now coded up the VIDC20 abort handler, although didn't get time to test on Fri, so will get that sorted on Mon along with the above.
VIDC20 tested and working.

Note that VIDC1/20 currently only handle changes to HDSR and HDER. They need to also work out the refresh rate based on pixelrate etc so ADFFS can generate fake VSyncs to fix timing on games that palette swap.

I also need to code up the IOC and MEMC abort handlers, IOC is relevant to palette swapping and MEMC for hardware scrolling. The basic shell is there for IOC, I just need to add the code to handle Timers 0/1. MEMC needs adding and should track Vinit, Vstart, Vend and Cinit and the blit code take account of Vinit when it does the blit from DA2 to the GPU framebuffer.
JonAbbott
Posts: 2938
Joined: Thu Apr 11, 2013 12:13 pm
Location: Essex
Contact:

Re: VIDC1/20 emulation

Post by JonAbbott »

I've been thinking about mid-frame palette change support for 4 bpp MODEs, this could be done to a 256 palettised MODE. Except for probably a few scene demos, games generally only change the palette twice in a frame, once at the start and again mid-frame. For example, the map in Lemmings and Fire & Ice, or the water in James Pond.

You could keep a 16 byte logical palette conversion table for each scanline and map any palette changes received to the spare 256 colour palette entries above 16, increasing it for each new palette change received.

Lemmings for example would use palette entries 0-15 up to the control bar, write the mid-frame palette changes to colours 16-31 and translate the 4-bit colours 0-15 to the 256 colours 16-31 for the rest of the frame. This would allow 15 complete palette changes mid-frame, or 240 individual palette changes if you mapped them individually instead of in blocks of 16.

For raster bar support, where the same colours cycle, you could even scan the 256 palette entries to see if you've already mapped the colour, to save wasting slots. I think there's one game off the top of my head which uses this and probably plenty of scene demos.

This method would considerable reduce the memory bandwidth required for conversion to a 16/32 bpp MODEs.
JonAbbott
Posts: 2938
Joined: Thu Apr 11, 2013 12:13 pm
Location: Essex
Contact:

Re: VIDC1/20 emulation

Post by JonAbbott »

ADFFS500224 on the dev site, now supports 4-bit MODEs that aren't multiples of 32 pixels. Note, they do however have to be multiples of 4 pixels - I think that complies with VIDC1's restrictions.

I've yet to add any support for 1/2 bpp that aren't multiples of 32 pixels though. I probably won't add this as skimming down the official MODE list, I think they're all multiples of 32 pixels and I'm not aware of any games that change the geometry on 1/2 bpp MODEs.

MEMC abort handler added although I've yet to change the blit code to take account of Vinit. I'll initialise Vinit to DA2's logical address on a MODE change and use Vinit for the blit code. Not forgetting to change Vinit in OS_Byte 113
JonAbbott
Posts: 2938
Joined: Thu Apr 11, 2013 12:13 pm
Location: Essex
Contact:

Re: VIDC1/20 emulation

Post by JonAbbott »

JonAbbott wrote:MEMC abort handler added although I've yet to change the blit code to take account of Vinit. I'll initialise Vinit to DA2's logical address on a MODE change and use Vinit for the blit code. Not forgetting to change Vinit in OS_Byte 113
Now coded, ADFFS500225 on the dev site.

I'm not aware of any games that actually use Vinit for scrolling, so have done basic testing, seems to be okay. Adding this actually simplified some of the code as GraphicsV 6 now handles setting Vinit. It's not doing anything with Vstart, Vend or Cinit. Not sure if any of these will be required, so have left them out for the time being.

Need to look at mid-frame palette swaps in 4 bpp MODEs next, this requires:

1. Full IOC emulation
2. Trigger our own VSync's at 50Hz, claiming the GPU's VSync for frame blits
3. Start a 1MHz timer at start of our VSync, so we can work out the scanline palette that changes occur on (78 ticks per raster)
4. Add a 256 entry palette table, which needs setting on each frame blit
5. Add a logical palette conversion table based on the scanline - 16 bytes containing the 256 colour it's mapped too
6. Add code to the palette change code, which maps mid-frame palette changes to colours 17+ and adds another logical palette table for that scanline on. This could check to see if the colour is already mapped to avoid duplication, although possible only required for scene demos. Cyber Ape is the only game I'm aware of that uses constant palette changes throughout the frame. Below is a summary of the total colours used per frame for some games that use mid-frame palette changes:

Total colour count per frame:

Cyber Ape: 31
Fire & Ice: 36 (this does two mid-frame palette changes, 1 - top of the frame, 2 - top of map, 2 - middle of the map)
Lemmings: 28

I need to get one of these running before I can be sure it's working correctly...or write some example code to do it.
Post Reply