VOGONS


First post, by superfury

User metadata
Rank l33t++
Rank
l33t++

What is the state of the EGA/VGA shift register after shifting out it's 8 pixels? Is it always ROL (shifting out at the left) with 8 bits each Shift/Load Rate clock?

Edit: OK. Thinking about what https://hackaday.io/project/6150-beckman-du-6 … -a-new-vga-mode tells about this.
If the EGA/VGA shift registers pull 2 bits from the low and high planes (this can be done in one go, as UniPCemu performs it this way, in packed shift mode) you'd get a shifted size (on the low planes, planes 0 and 1) of 8 pixels times 2 bits, so 16 bits.
Interestingly, those 16 first bits loaded by UniPCemu end up being at bytes 0 and 1 of the mapped 32-bit little-endian variable.
So it can simply decode it as it used to (using the lower 16 bits (planes 0/1) for the lower 2 bits of the pixels shifted out and the upper 16 bits(planes 2/3) as the upper 2 bits for any pixel).
One of the big pros of an c/c++ union (overlapping the 32-bit integer with 4 bytes for the memory planes) is that it has the planes in a 32-bit variable to be able to read it quickly from VRAM (from any address of VRAM) as well as able to take any bits from a random access plane (0-3) specifically to shift out specific data from planes in a optimized way (don't know how it compares to raw registers though. I guess it's probably optimized away by the compiler to use registers anyway?).
Just remember to, when rotating the data on big-endian processors, remember to rotate in little-endian format for it to work properly 🤣

One interesting case of (S)VGA specific behaviour also shows itself using SLR: effectively, using SLR(Shift/Load rate) in '256-color shift mode' is useless? Since it always shifts out 4 bits values for a total of 8 pixels, you'd get 4x8=32 bits. And since the shift register itself is 32-bits wide, any use of SLR would simply repeat the first 8 pixel attributes over and over for 2 or 4 character clocks. The end position of shifting in both clocking modes (2 and 4 character clocks or anything more than 1 character) would wrap around the register in it's entirety (32 bits shifted left by multiples of 32 bits for every character clock, thus having no effect). All it would do is duplicate the same 8 attributes over and over again.

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 1 of 2, by superfury

User metadata
Rank l33t++
Rank
l33t++

http://www.osdever.net/FreeVGA/vga/vgaseq.htm
Hmmm, looking at the packed shift mode diagram, it's indeed rotating 16 bits for 8 pixels?
The taps are, just like planar shift mode, placed and read after each rotation step.
But instead of rotating 1 bit, it rotates 2 bits left each dot clock (including the first clock).
The taps are then placed at bits 1 and 0 of planes 1 and 3. Those provide the 4 bits shifted out from the shift register.
With planar shift mode it would have the taps at bit 0 of all four planes.
And in 256-color shift mode, it rotates left 4 bits and has the taps at bits 0-3 of plane 3.

That should basically sum up the entire shift register behaviour? Simply a rotate with (probaby using a multiplexer on) the taps (needs to be big-endian inputted from the inputs. Plane 0 needs to shift into plane 3 (thus byte 0 into byte 3)):
- at all planes bit 0 for planar shift mode (1-bit shift). You'd need to rotate the result right once, since the 4-bit result by 1 bit since plane 0 ends up at plane 3 (all bits are shifted left at the 4 bit register from the taps. So basically they're wired:
-- C0=>P3
-- C1=>P0
-- C2=>P1
-- C3=>P2.
--- C0-C3 are the color outputs to the attribute controller, P0-P3 are the shifted register planes bit 0.
- at planes 1 and 3 bits 1 and 0 for packed shift (2-bit shift, plane 3 bits routed to bits 2-3).
- at plane 3 bits 3-0 for 256-color shift (4-bit shift).

Is that correct behaviour?

Edit: Using tweak16b (from http://www.lanet.lv/simtel.net/msdos/vga-pre.html) to set the SLR bit shows that the shift is performing as it should 😁 So using SDL2, use SDL_SwapLE32 before and after performing rotation (Swap on Little-Endian platforms, NOP on Big Endian platforms).

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 2 of 2, by superfury

User metadata
Rank l33t++
Rank
l33t++

Thinking about it, isn't the VGA big endian entirely? Even the 16-bit registers (cursor location and start address) are stored in big endian format?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io