ZXUNO Radastan mode description and usage example

Avatar de Usuario
Mensajes: 828
Registrado: 27 Sep 2015, 00:14
Ubicación: Jerez de la Frontera

ZXUNO Radastan mode description and usage example

Mensaje por mcleod_ideafix » 22 Ago 2020, 14:41

The Radastan video mode shows 128x96 pixels on screen, with a border. Each pixel uses 4 bits of memory, so allowing 16 colours.

It uses linear addressing. One byte of memory holds two pixels. The high nibble (bit 4 to 7) holds the left pixel, and the low nibble (bits 0 to 3) holds the right pixel.

The memory bitmap file is at the same address as the regular ULA screen: banks 5 and 7 of the 128K memory map.

It allows hardware scrolling and raster interrupts can be used to have more than one video mode on screen in the same frame, or the same video mode with a different palette.

While in Radastan mode, there is no video memory contention. CPU can run with no wait states even if reading or writting to video memory banks.

Radastan mode use the tacks per scanline as configured in the ZXUNO ULA timings register. So if ULA 48K or Pentagon is selected, a scanline lasts 224 tacks. If using 128K timings, it's 228 tacks.

Memory organization (for page 5, normally paged in at $4000 - $7FFF)
Byte at $4000 holds pixels 0 and 1 of the first scanline (pixel 0 is stored in bits 4 to 7, pixel 1 in bits 0 to 3).
Byte at $4001 holds pixels 2 and 3, and so on.
Byte at $403F holds pixels 126 and 127.
Byte at $4040 holds pixels 0 and 1 of the second scanline.

The size of the memory bitmap file is therefore 128*96*(1/2) = 6144 bytes, the same size of the standard bitmap ULA screen. Radastan mode does not need a separate attribute area.

If using 128K, a second (shadow) screen is available at bank 7. Standard double buffer techniques can be applied.

Each colour can be chosen from a palette of 256 colours. ULAplus palette and logic is used for this:
- ULAplus palette has 64 entries. This can be viewed as 4 subpalettes of 16 entries each. Radastan mode can be programmed to use on of these 4 subpalettes. By default, first subpalette (entries 0 to 15) is selected.
- Raster interrupts can be used to quickly switch palettes during screen exploration, and allow up to 64 colours on screen with very low CPU effort.
- Border colour can be set to one of the 16 entries of the current subpalette. As there is only 3 bits in port $FE to choose the color, the fourth bit is taken from a configuration register.

To manage Radastan video mode settings, a set of ZXUNO registers is used. These registers are managed through two I/O ports.
$FC3B : keeps the register number to be accessed (read/write)
$FD3B : current value of the currently accessed register (read/write). Note that the high byte of this address is one byte more than the previous I/O port.
Example: to switch the Radastan mode on, the value 3 must be written to ZXUNO register $40, so the following sequence can be used to accomplish this:

Código: Seleccionar todo

ld bc,$fc3b
ld a,$40
out (c),a
inc b
ld a,3
out (c),a
Radastan mode registers (all accessible as ZXUNO registers):

Código: Seleccionar todo

Name          Number  Description
RADASCTRL     $40     Enable/disable Radastan video mode. ULAplus does not need to be active. Only bits 1 and 0
                      are used. Both must be set to 1 to enable Radastan mode. The new video mode is
                      inmediately active.
RADASPALBANK  $43     Subpalette selection. Bits 1 and 0 select which set of ULAplus entries to use.
                      00: entries 0 to 15
                      01: entries 16 to 31
                      10: entries 32 to 47
                      11: entries 48 to 63.
                      Defaults to 00, so Radastan uses ULAplus palette entries 0 to 15.
                      Bit 2 is used as the fourth bit to select which from the 16 entries to apply to border
                      colour. Defaults to 0
RADASOFFSET   $41     Offset in bytes from the beginning of the memory page to the beginning of the bitmap area.
                      Used along with RADASPADDING to achieve hardware scrolling. It's a 16 bit value
                      (14 bits actually) so you need two OUTs to send first the low byte of the offset value,
                      then the high byte (bits 6 and 7 are ignored) of the offset value. Defaults to 0
RADASPADDING  $42     Length in bytes of a scanline in memory. The value stored here is actually length - 64.
                      So a value of 0 in this register actually means a scanline length of 64 bytes (128 pixels).
                      Used to define a screen wider than 128 pixels so you can scroll it horizontally by
                      increasing or decreasing the value of RADASOFFSET. The value stored here is a byte, so the
                      maximum width is 64+255=319 bytes = 638 pixels. Defaults to 0
Take into account that the ULA, while in Radastan mode, won't read past the current video bank, so if a combination of RADASPADDING and RADASOFFSET makes the video address to go beyond $3FFF (being address $0000 the start of the bank) it will wrap around.
The memory address for a pixel (X,Y), related to the beginning of the current video bank, can be expressed as: (RADASOFFSET + Y*(64+RADASPADDING) + (X/2)) mod 16384

See hardware scrolling examples in the ZXUNO SVN repository at: http://svn.zxuno.com/software/modo_radastan/hwscroll
See one (familiar? ;) ) example of NON hardware scrolling at: http://svn.zxuno.com/software/modo_rada ... roll_radas

To set up actual colours for each palette entry, ULAplus registers are used.
ULAplus registers is used in a similar way as ZXUNO registers.
$BF3B : keeps the ULAplus register number ($00 to $40)
$FF3B : current value of the currently accessed ULAplus register.

Register $40 is used to enable/disable ULAplus, and this is not necessary to use Radastan. Only registers $00 to $3F are used.
Each one of these ($00 to $3F) is a palette entry. The colour stored here is 8 bits with the following format: GGGRRRBB

Example: set up Radastan mode and plot a yellow pixel at position (18,48).

Código: Seleccionar todo

;set up ULAplus palette. We will use entry $06 and entry $00
ld bc,$bf3b
ld a,6         ;entry
out (c),a
ld b,$ff
ld a,%1111100  ;colour (yellow)
out (c),a
ld b,$bf       ;
xor a          ;
out (c),a      ; Now set up entry 0 with colour black
ld b,$ff       ;
out (c),a      ;

;enable Radastan video mode and clear screen
ld bc,$fc3b
ld a,$40
out (c),a
inc b
ld a,3
out (c),a
ld hl,$4000
ld de,$4001
ld bc,$17ff
ld (hl),l

;Plots pixel at (18,48)
ld hl,$4000+48*64+(18/2)
ld a,(hl)
and $0f        ; Preserve the current colour of the neighbouring pixel
or $60         ; (X+1,Y) while modifying the one we want (X,Y)
ld (hl),a

;Wait for SPACE key and exit
ld a,$7f
in a,($fe)
jr c,WaitForKey
ld bc,$fd3b    ; ZXUNO register $40 is still the
xor a          ; current register so no need to
out (c),a      ; re-select it. Just write 0 to disbable Radastan
ZX-Uno · Clon de ordenador ZX Spectrum basado en FPGA