Blitter support for VIDC1/20 and palette changes

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

Blitter support for VIDC1/20 and palette changes

Post by JonAbbott »

Code that requires changing to support these are detailed below. Note that all VIDC1 register writes are translated to VIDC20 registers, so we only need to take account of VIDC20 values. The latest code is in /development/32bit/cpu on the dev site.


adffs.vectors.DA2_frame_buffer

blit_DA2_frame: sets up the following registers, then calls _1bit_mode, _2bit_mode, _4bit_mode or _8bit_mode to do the blit:

R0 - MEMC_Vinit
R1 - start of GPU framebuffer
R2-R11 - free to use by the blitting code
R12 - Palette table (256 words, containing a converted palette value ready to write to the GPU framebuffer)

other variables of use, which can be loaded/pre-setup as required:

MEMC_Vstart
MEMC_Vend

vidc20_regs (table of VIDC20 registers)
+0 = HCR
+4 = HSWR
..
+88 = VCSR
+92 = VCER
IOC_registers (table of IOC registers, 1 byte per register)
+0 = IOC register 0
+1 = IOC register 1
..
+31 = IOC register 31
T1_value current value of T1 timer
IOC_ticks_per_raster IOC clock ticks per raster

HAL_vidc_list (VIDC type 3 list as passed by GraphicsV 2)
+20 = physical screen width (which will be rounded up to the next 32 pixel boundary)
+44 = physical screen height
_1bit_mode, _2bit_mode, _4bit_mode, _8bit_mode: must exit via _exit and need to take account of the VIDC20 parameters, MEMC Vend/Vstart and must call IOC_timers (which corrupts R4-R6) before starting and then every four pixels or per raster (TBC).

To access VIDC20 registers, setup a pointer register as follows:

Code: Select all

ADR R11, vidc20_regs - (VIDC20_HCR << 2)
and then load the registers via:

Code: Select all

LDR R2, [R11, #VIDC20_<register name> << 2]

eg.
ADR R11, vidc20_regs - (VIDC20_HCR << 2)
LDR R2, [R11, #VIDC20_HDSR << 2]

Timers

IOC_ticks_per_raster should be set at the start of the frame blit to the numer of IOC clock ticks per raster.

IOC_timers should be called at the start of each raster, R4-R6 are corrupted on return.

NOTE: In adffs.aborts.ioc_abort IOC_timers - uncomment the IOC_ticks_per_raster code.
steve3000
Posts: 198
Joined: Thu May 02, 2013 9:25 pm

Re: Blitter support for VIDC1/20 and palette changes

Post by steve3000 »

Ok, looks good - so after I've sorted out LCDgm for VIDC20, I'll tidy up my 'blitter' module (which handles 1/2/4bpp to 32bpp with raster-level palette changes) and see if we can't patch this into the above ADFFS code and get mid-screen palette redefinitions going.
JonAbbott
Posts: 2938
Joined: Thu Apr 11, 2013 12:13 pm
Location: Essex
Contact:

Re: Blitter support for VIDC1/20 and palette changes

Post by JonAbbott »

Great, if we can decide how we want the raster palette table(s) to look, I'll make a start on the changes to adffs.aborts.vidc1_abort / vidc20_abort as they're closely tied in with the IOC code I'm currently working on...calculating the timing etc.

Option 1
A 16 word table per raster, with SSBBGGRR entries is the obvious choice and pre-fill them on VSync to FF000000 so a simply negative check will indicate if the palette entry has changed, or if it should come from the master palette table. When a palette change is received the raster palette entries from that raster on are also filled with the change.

Option 2
A 16 word pointer table per raster, which points to the SSBBGGRR entry. By default they all point to the master palette table entries.

For example, assuming R1 points to the current raster palette table and R2 is the pixel value.

Code: Select all

LDR R0, [R1, R2, LSL #2] ;load the palette pointer
LDR R0, [R0] ;load the actual palette entry
The master palette table incidentally, is the one set via legal SWI's and RISC OS.

How do we want to cover 8 bpp modes though where VIDC1 does its funky thing to make up the 240 you can't alter directly. Do we want to calculate them in the blitter on-the-fly? Or expand the raster palette entries to 256 and have the palette code write all the entries at the time they're changed?
JonAbbott
Posts: 2938
Joined: Thu Apr 11, 2013 12:13 pm
Location: Essex
Contact:

Re: Blitter support for VIDC1/20 and palette changes

Post by JonAbbott »

Option 3

Extend the master palette table. The first word contains the start raster no, followed by N AABBGGRR entries and a -1 terminator. When the palette changes mid-frame another palette table is written, so -1 becomes the start raster, followed by N AABBGGRR entries and a -1 terminator. N being the number of palette entries for the current mode.

The blitter then starts off using the palette until it hits the raster of the next palette or the last visible raster, whichever comes first. This removes the need for a palette per raster, so should improve cache hits and also caters for 8bpp modes where the 256 entries can be calculated by the palette code. It also merges the master and raster palettes into one table.

eg for 4bpp

Code: Select all

LDR R11, [R12, #16 * 4] ;load next palette raster
MOV R10, #0 ;start raster
MOV R9, #256 ;setup R9 as last raster
._VLoop
._Hloop
;get pixel value into R2
LDR R2, [R12, R2] ;convert to 32bpp
STR R2, [R1], #4 ;write to GPU buffer
;loop to Hloop until all pixels done

ADD R10, R10, #1 ;go to next raster line
TEQ R10, R11 ;does the palette change here?
ADDEQ R12, R12, #4 + (16 * 4) ;YES, go to next palette table
LDREQ R11, [R12, #16 * 4] ; |+  load next palette raster
TEQ R10, R9 ;last visible raster?
BNE _Vloop
I think this is my preferred method out of the three I've listed.
steve3000
Posts: 198
Joined: Thu May 02, 2013 9:25 pm

Re: Blitter support for VIDC1/20 and palette changes

Post by steve3000 »

Good options! No. 2 is closest to what I have right now, but not necessarily the optimum. Let me think on this and run some tests.

256 colour mode with fixed palette - we can treat the same, I have some code to quickly convert from the 16 entry palette -> 256 colours, in 32bpp output.

Steve
JonAbbott
Posts: 2938
Joined: Thu Apr 11, 2013 12:13 pm
Location: Essex
Contact:

Re: Blitter support for VIDC1/20 and palette changes

Post by JonAbbott »

James Pond is now close to working, it gets into the game at least. This will be a good candidate for checking both palette swapping and VIDC parameters.

The HAL timer and code to calculate the palette change raster are now in place, once we've decided on the palette table structure I can modify the VIDC palette code.
steve3000
Posts: 198
Joined: Thu May 02, 2013 9:25 pm

Re: Blitter support for VIDC1/20 and palette changes

Post by steve3000 »

Good to hear!

I've also made progress with LCDgm, hopefully have something out by end of month. As for palette table structure, this is important to get right as it will have a bearing on performance and flexibility. But I've also had a think about another option...

Option 4...

This could be flakey, and may not be ideal... but if you're also having trouble using real timers this may be interesting... why not emulate them?

We'd need some thought behind it, but in theory if a timer (say T1) is just being used to time palette swap code, ADFFS could store its latch values, then the blitter code could read this from ADFFS, subtract a fixed amount for Vsync flyback, and during actual screen copy code (from 4bpp to 32bpp), the translation code could subtract a raster-time period as it outputs each line, and when the value crosses 0, it could call an ADFFS entry point, which in turn calls the T1 IRQ vector and allows the game code itself to make the actual palette swap.

This could even work for sub-raster level accuracy.

Thoughts...
JonAbbott
Posts: 2938
Joined: Thu Apr 11, 2013 12:13 pm
Location: Essex
Contact:

Re: Blitter support for VIDC1/20 and palette changes

Post by JonAbbott »

I agree, the palette structure needs to be right and will have a large affect on blitter speed.

Emulating T1 may be our only option. It's already calculating the per raster Timer period so is simply a matter of decreasing the counter and triggering the T1 interrupt when it crosses zero. And the beauty of this option...no need for a palette structure beyond the normal one. I like your thinking and will code this up today as I'm sick to death of HAL Timers!
JonAbbott
Posts: 2938
Joined: Thu Apr 11, 2013 12:13 pm
Location: Essex
Contact:

Re: Blitter support for VIDC1/20 and palette changes

Post by JonAbbott »

JonAbbott wrote:I like your thinking and will code this up today as I'm sick to death of HAL Timers!
Coded and working...no more Timer related crashing. extASM237a is on the dev site.

There's still some work to do though as James Pond for example is corrupting SVC, I've made ADFFS preserve SVC for the moment. Both James Pond and Jahangir Khan are now working correctly. I had to modify the blitter to latch T1 (reducing for flyback) before it starts and call the T1 timer code every four pixels, so it's quite accurate.

Flyback time needs calculating correctly, for the time being I've set it to 12544 clock ticks, which is just below the value Jahangir uses to set the palette on the 1st raster.

I should have done this on Monday, it would have saved a whole week wasted trying to get HAL Timers to work.
Attachments
James Pond with IOC T1 emulation on Pi
James Pond with IOC T1 emulation on Pi
JamesPond-pi1.png (26.48 KiB) Viewed 7635 times
Jahangir Khan World Championship Squash with IOC T1 emulation on the Pi
Jahangir Khan World Championship Squash with IOC T1 emulation on the Pi
JahKhan-pi1.png (30.26 KiB) Viewed 7635 times
JonAbbott
Posts: 2938
Joined: Thu Apr 11, 2013 12:13 pm
Location: Essex
Contact:

Re: Blitter support for VIDC1/20 and palette changes

Post by JonAbbott »

Although it's currently decreasing T1 every 4 pixels, that was just a botch to save me recoding the blitter. Unless there's a requirement for per-pixel accuracy it could be changed to reduce T1 per raster.

Either way, it needs to calculate the number of IOC clock ticks per pixel/raster based on the pixel clock. For the time being it's reducing T1 by 3 every four pixels which looks about right for 320x256 @ 50Hz. I matched the butterfly flapping to the A440/1 to roughly work out the ticks/pixel.
Post Reply