Sentinel65X-Handbook/Audio & Video.md

10 KiB

Table of Contents

Audio & Video

The VERA FPGA core, implemented on an iCE40 FPGA, is used to generate all audio and video signals produced by Sentinel 65X. This core, developed for the Commander X16 project by Frank van den Hoef, is licensed under the MIT license. It has been modified by Brian Swetland for Sentinel 65X, including porting it to be built using the Yosys open-source FPGA toolchain.

Video

The VERA video generator outputs a fixed 640x480, 60Hz digital RGB signal, with a total of 4,096 possible colours, using a 12-bit R4G4B4 colour space.

The video generation is done using two independent tile/bitmap layers, and a third layer composed of 128 sprites. VERA supports a single palette of 256 colours, freely chosen from the 4,096 possible colours available.

Audio

The VERA FPGA core produces audio output in i2S format, which is fed to the A/V port for conversion into an analog or digital format suitable for the target display device.

Audio is generated using a 16-voice stereo programmable sound generator, with each voice able to generate sounds independently, with the waveform for each chosen freely from among Pulse, Sawtooth, Triangle, and Noise.

VERA also generates sampled 48KHz 16-bit stereo audio from a 4KB on-chip memory buffer.

Interrupts

The VERA implementation in Sentinel 65X has a dedicated vectored interrupt line to the CPU, which can be triggered by any or all of four conditions: Sprite collision, line number, PCM buffer status, or VSYNC.

The Sentinel 65X A/V Port

Audio and video output in Sentinel 65X is directed to a pin header, which is connected to a small daughterboard which actually generates the final audio and video output signals, using electronics and connectors appropriate to the target display.

Pinout

The A/V port is a 24-pin female pin header, with a pin and row pitch of 2.54mm. The pinout of the port, as seen from above, is shown in the following table:

Pin Label Label Pin
1 +3.3V +5V 2
3 HSYNC VSYNC 4
5 RGB_R0 RGB_R1 6
7 RGB_R2 RGB_R3 8
9 RGB_G0 RGB_G1 10
11 RGB_G2 RGB_G3 12
13 RGB_B0 RGB_B1 14
15 RGB_B2 RGB_B3 16
17 LRCK BCK 18
19 ADATA SYSCLK 20
21 SCL SDA 22
23 GND GND 24

VERA Memory

VERA implements 128KB of internal memory, which exists in its own independent address space, connected to the CPU's address space through address and data registers. This RAM's address space is numbered from 0x00000 to 0x1FFFF, and is organized as in the following table:

Address Range Description
0x00000 - 0x1F9BF Video RAM
0x1F9C0 - 0x1F9FF Sound Registers
0x1FA00 - 0x1FBFF Colour Palette
0x1FC00 - 0x1FFFF Sprite Attributes

Hardware Registers

VERA is configured and controlled using a series of 32 memory-mapped I/O registers, located in the address space from 0x00DF00 to 0x00DF1F.

ADDRx_L

The ADDRx_L register is actually two registers, the ADDR0_L and ADDR1_L registers. Which of the two is accessed at memory address 0x00DF00 depends on the contents of ADDRSEL, which is bit 0 of the CTRL register, located at 0x00DF05.

The ADDR0_L and ADDR1_L registers control the low byte of the selected address in VERA memory for reading or writing with the DATA0 and DATA1 registers, located at 0x00DF03 and 0x00DF04 respectively.

ADDRx_M

The ADDRx_M register is actually two registers, the ADDR0_M and ADDR1_M registers. Which of the two is accessed at memory address 0x00DF01 depends on the contents of ADDRSEL, which is bit 0 of the CTRL register, located at 0x00DF05.

The ADDR0ML and ADDR1_M registers control the middle byte of the selected address in VERA memory for reading or writing with the DATA0 and DATA1 registers, located at 0x00DF03 and 0x00DF04 respectively.

ADDRx_H

The ADDRx_H register is actually two registers, the ADDR0_H and ADDR1_H registers. Which of the two is accessed at memory address 0x00DF00 depends on the contents of ADDRSEL, which is bit 0 of the CTRL register, located at 0x00DF05.

The ADDR0_H and ADDR1_H registers control the low byte of the selected address in VERA memory for reading or writing with the DATA0 and DATA1 registers, located at 0x00DF03 and 0x00DF04 respectively.

Bit 0 of the ADDRx_H is bit 16 of the address of the data port selected by ADDRSEL. Bits 1 and 2 of ADDRx_H are unused. Bit 3 is called DECR0 or DECR1; when this bit is clear, the address of the selected data port will increment by the amount set with bits 4-7, called INCR0 or INCR1, according to the table below. When DECR0 or DECR1 is set, then the address will decrement by the same amount when the matching data register is read from or written to.

INCR value Address Increment
0 0
1 1
2 2
3 4
4 8
5 16
6 32
7 64
8 128
9 256
10 512
11 40
12 80
13 160
14 320
15 640

DATA0

The DATA0 register, located at 0x00DF03, is the first of two data registers available from VERA. It reads or writes the address in VERA's internal memory set in ADDR0_L, ADDR0_M, and ADDR0_H.

If the value in INCR0 is nonzero, then after reading or writing from or to DATA0, the address stored in ADDR0_L, ADDR0_M, and ADDR0_H will be incremented by the number of addresses in the table above. If DECR0 is set, then the address will decrement by that amount instead.

DATA1

DATA1, located at 0x00DF04, is identical in function to DATA0, but uses the address and increment settings stored in ADDR1_H instead of ADDR0_H.

CTRL

The CTRL register, located at 0x00DF05, contains three significant bits: bit 0, called ADDRSEL, determines which DATAx register the ADDRx registers refer to. Bit 1, called DCSEL, controls which set of registers are accessed at addresses 0x00DF09 through 0x00DF0C. Bit 7, called RESET, will reset VERA to the initial power-on state when a 1 value is written to it.

IEN

The IEN register, located at 0x00DF06, has six bits which relate to the generation of VERA interrupts:

  • Bit 0, called IEN_VSYNC, enables the VSYNC interrupt when set.
  • Bit 1, called IEN_LINE, enables the raster-line interrupt when set.
  • Bit 2, called IEN_SPRCOL, enables the sprite collision interrupt when set.
  • Bit 3, called IEN_AFLOW, enables the interrupt triggered when the PCM sample buffer is less than 1/4 full.
  • Bit 6 contains the high-order bit of the 9-bit value of the SCANLINE register, located at 0x00DF08. Both this bit and the SCANLINE register are read-only.
  • Bit 7 contains the high-order bit of the 9-bit value of the IRQLINE register, located at 0x00DF08. Both this bit and the IRQLINE register are write-only.

ISR

The ISR register, located at 0x00DF07, contains flag bits which identify the source of the active VERA interrupt:

  • Bit 0, called ISR_VSYNC, identifies a VSYNC interrupt condition when set.
  • Bit 1, called ISR_LINE, identifies a raster line interrupt condition when set.
  • Bit 2, called ISR_SPRCOL, identifies a sprite collision interrupt condition when set.
  • Bit 3, called ISR_AFLOW, identifies a PCM sample buffer low interrupt condition when set.
  • Bits 4-7 store the sprite collision data.

Writing a 1 value to bits 0, 1, or 2 will clear the interrupt state of the relevant interrupt source. Bit 3 can only be cleared by filling the PCM sample buffer to at least 1/4 of its capacity.

IRQLINE_L / SCANLINE_L

The low order 8 bits of the current scanline and the scanline which is set to trigger the scanline interrupt share the address 0x00DF08 -- IRQLINE_L is write-only, and SCANLINE_L is read-only, so there is no conflict.

DC_VIDEO / DC_HSTART

The DC_Video and DC_HSTART registers share the address 0x00DF09; which one is accessed at that address is determined by the DCSEL flag bit in the CTRL register -- a 0 value in DCSEL will enable the DC_VIDEO register, and a 1 value the DC_HSTART register.

DC_VIDEO stores three flag bits:

  • Bit 4 enables tile/bitmap layer 0 when set to 1.
  • Bit 5 enables tile/bitmap layer 1 when set to 1.
  • Bit 6 enables sprites when set to 1.

DC_HSTART controls the first active column of the screen, relative to the 640x480 display area. The value is the top 8 bits of a 10-bit number, the low order 2 bits of which are implied to be 0 -- that is, the value is an 8 bit number which will be multiplied by 4.

DC_HSCALE / DC_HSTOP

The DC_HSCALE and DC_HSTOP registers share the address 0x00DF0A; which one is accessed at that address is determined by the DCSEL flag bit in the CTRL register -- a 0 value in DCSEL will enable the DC_HSCALE register, and a 1 value the DC_HSTOP register.

DC_HSCALE sets a fractional scaling factor of the active part of the screen; a value of 128 will output one pixel for each input pixel, and a value of 64 will output two pixels for each input pixel.

DC_HSTOP controls the first active column of the screen, relative to the 640x480 display area. The value is the top 8 bits of a 10-bit number, the low order 2 bits of which are implied to be 0 -- that is, the value is an 8 bit number which will be multiplied by 4.