Timex Sinclair Video Mode Control

From SpecNext official Wiki
Revision as of 22:59, 19 April 2019 by Xalior (talk | contribs)
Jump to: navigation, search
Number $xxFF
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.

UPDATE: the index of border colour is under investigation and to be confirmed (core2.00.25 is different from 2.00.24 in this aspect).

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