Difference between revisions of "Timex Sinclair Video Mode Control"

From SpecNext official Wiki
Jump to: navigation, search
(Added extra technical info, how the board is expected to handle Timex Hi-Res colouring vs ULANext-palette enabled.)
(Final confirmation of how ZXN internally composes the Timex hi-res mode image for display + added photo with example.)
Line 20: Line 20:
 
|}
 
|}
  
[[User:Ped7g|Ped7g]] ([[User talk:Ped7g|talk]]) 02:09, December 23, 2018 (UTC): I '''guess''' the hi-res colours are still fetched through ULANext palette, i.e. any two colours combination is possible through palette modification of the two colours (for example White/Black are 15/136 (bright variant, or maybe black paper is black 128)?).
+
The hi-res mode (and some parts also about other Timex modes) HW implementation details:
  
[[User:Ped7g|Ped7g]] ([[User talk:Ped7g|talk]]) 07:01, January 15, 2019 (UTC) internally the HW "ULA" part is providing pixel byte and attribute byte, and attribute byte contains %01pppiii, where %iii is the ink colour set in bits 3-5 on this port, and %ppp is complement of it. The %01 part is "no flash, bright yes". If ULANext mode is enabled, this value is then decomposed into ink/paper values according to {{NextRegNo|$42}}, so for the White/Black example and INK-mask 15 the INK value is %0111 = 7, and PAPER/BORDER %0100 = 4 + 128 (132). For INK-mask 7 it would be INK 7, PAPER/BORDER = 8 + 128 (136) (not 15/136 as I guessed previously).
+
The border colour is identical to paper (including the brightness), so everything described for paper does apply to border too (the hi-res mode overrides port 254 border colour, which gets ignored while hi-res mode is selected).
  
This is only theoretical reasoning, going by information provided by Jim Bagley in forums, and has to be yet confirmed with actual HW board (what I can confirm at the moment, that both available emulators ZEsarUX7.2 and CSpect2.2.0 are emulating HiRes in completely different way, not resembling this "pixel_byte -> ULA adds attrib byte -> ULANext translates into palette -> final pixel going into layer combining + transparency check" pipeline, so they can't be used to validate this).
+
The Next display pipeline starts at reading the pixel data from "bank 5", which resides in BRAM of FPGA, and is mapped to $4000 and $6000 in default memory mapping (the display data are read from the BRAM, so mapping different ram into $4000..$8000 Z80 address space does not modify the screen output, to modify screen output you have to map "bank 5" to some memory and write there). These pixel data are half of "ULA" result, other half is attribute byte, which is composed as "01pppiii" value, where "iii" are the bits 3-5 from (this) $FF port, and "ppp" are complement of "iii".
 +
 
 +
For example for bits set as %100 the ULA does accompany every pixel byte with attribute byte %01011100, i.e. "INK 4, PAPER 3, BRIGHT 1".
 +
 
 +
If ULANext mode is enabled (bit 0 in {{NextRegNo|$43}}), this attribute byte is decomposed by ink-mask ({{NextRegNo|$42}}) into ink-index and paper-index, then the selected ULA palette is used to fetch particular colours (the constant 128 is added to paper and border index as in normal ULA modes), so in the example above with attribute byte %01011100 and ink-mask 7 the resulting colour will be current-ULA-palette[4] for filled-pixels, and current-ULA-palette[128+11] for paper (empty pixel) and border (with default ink-mask 15 the indices will be 12 for ink and 128+5 for paper+border).
 +
 
 +
If the colour in palette is a match with {{NextRegNo|$14}}, the colour is treated as transparent, and the final output will display non-transparent pixel belonging to other layer (Layer2 or Sprites) - if there is some non-transparent pixel in other layers, or {{NextRegNo|$4A}} colour (of course if the layer priorities put Layer2/Sprites above ULA layer, and there's non-transparent pixel already there, it is displayed over hi-res pixels).
 +
 
 +
I.e. the "pipeline" is like:
 +
hi-res VRAM data (or "empty" for border area) + attribute composed from port $FF -> ULANext palette conversion -> transparency check -> Next layers mixer -> final output to display.
 +
 
 +
The various mixing modes and results can be seen for example in "LayersMixingHiRes" test of [https://github.com/MrKWatkins/ZXSpectrumNextTests ZXSpectrumNextTests] project, the resulting image (the cyan pixels are drawn by Timex hi-res layer, green are part of Layer2 and yellow are from Sprites) (colours are selected by Next ULA palette, allowing any two ink/paper colours combination from the total 512-colour space even for hi-res mode):
 +
[[File:LmxHiRes.jpg|400px]]

Revision as of 11:22, 16 January 2019

Number $xxFF
Decimal
Short desc. Controls Timex Sinclair video modes and colours in hi-res mode.
Bit Mask %---- ---- 1111 1111
Readable No
Writable Yes
Subsystem Enhanced ULA
Bit Function
0-2 000=Screen 0. 001=Screen 1. 010=Hi-colour. 110=Hi-res.
3-5 Sets screen color combination for hi-res mode.

The bit pattern does set INK colour, PAPER+BORDER colour is deducted as complement value, both colours are of BRIGHT variant. I.e. only some combinations are possible, like White/Black, Yellow/Blue, ..

6 Disables interrupts. Does the same as DI, but cannot be turned on again with EI. Use with caution!
7 Used for memory paging on the Timex Sinclair, not relevant on the Next.

The hi-res mode (and some parts also about other Timex modes) HW implementation details:

The border colour is identical to paper (including the brightness), so everything described for paper does apply to border too (the hi-res mode overrides port 254 border colour, which gets ignored while hi-res mode is selected).

The Next display pipeline starts at reading the pixel data from "bank 5", which resides in BRAM of FPGA, and is mapped to $4000 and $6000 in default memory mapping (the display data are read from the BRAM, so mapping different ram into $4000..$8000 Z80 address space does not modify the screen output, to modify screen output you have to map "bank 5" to some memory and write there). These pixel data are half of "ULA" result, other half is attribute byte, which is composed as "01pppiii" value, where "iii" are the bits 3-5 from (this) $FF port, and "ppp" are complement of "iii".

For example for bits set as %100 the ULA does accompany every pixel byte with attribute byte %01011100, i.e. "INK 4, PAPER 3, BRIGHT 1".

If ULANext mode is enabled (bit 0 in Enhanced ULA Control Register ($43)), this attribute byte is decomposed by ink-mask (Enhanced ULA Ink Color Mask ($42)) into ink-index and paper-index, then the selected ULA palette is used to fetch particular colours (the constant 128 is added to paper and border index as in normal ULA modes), so in the example above with attribute byte %01011100 and ink-mask 7 the resulting colour will be current-ULA-palette[4] for filled-pixels, and current-ULA-palette[128+11] for paper (empty pixel) and border (with default ink-mask 15 the indices will be 12 for ink and 128+5 for paper+border).

If the colour in palette is a match with Global Transparency Register ($14), the colour is treated as transparent, and the final output will display non-transparent pixel belonging to other layer (Layer2 or Sprites) - if there is some non-transparent pixel in other layers, or Transparency colour fallback Register ($4A) colour (of course if the layer priorities put Layer2/Sprites above ULA layer, and there's non-transparent pixel already there, it is displayed over hi-res pixels).

I.e. the "pipeline" is like: hi-res VRAM data (or "empty" for border area) + attribute composed from port $FF -> ULANext palette conversion -> transparency check -> Next layers mixer -> final output to display.

The various mixing modes and results can be seen for example in "LayersMixingHiRes" test of ZXSpectrumNextTests project, the resulting image (the cyan pixels are drawn by Timex hi-res layer, green are part of Layer2 and yellow are from Sprites) (colours are selected by Next ULA palette, allowing any two ink/paper colours combination from the total 512-colour space even for hi-res mode): 400px