Work on fleshing out sections

This commit is contained in:
Kyle Cardoza 2024-03-23 20:44:00 -04:00
parent a7c6bbf645
commit 448f617fe1
2 changed files with 283 additions and 2 deletions

View File

@ -5,12 +5,30 @@ include_toc: true
# Audio & Video
## VERA 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.
## VERA Audio
## 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:
@ -29,3 +47,264 @@ The A/V port is a 24-pin female pin header, with a pin and row pitch of 2.54mm.
| 19 | ADATA | | SYSCLK | 20 |
| 21 | SCL | | SDA | 22 |
| 23 | GND | | GND | 24 |
## 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`.
<table>
<tr>
<th>Addr</th>
<th>Name</th>
<th>Bit&nbsp;7</th>
<th>Bit&nbsp;6</th>
<th>Bit&nbsp;5 </th>
<th>Bit&nbsp;4</th>
<th>Bit&nbsp;3 </th>
<th>Bit&nbsp;2</th>
<th>Bit&nbsp;1 </th>
<th>Bit&nbsp;0</th>
</tr>
<tr>
<td>$00</td>
<td>ADDRx_L (x=ADDRSEL)</td>
<td colspan="8" align="center">VRAM Address (7:0)</td>
</tr>
<tr>
<td>$01</td>
<td>ADDRx_M (x=ADDRSEL)</td>
<td colspan="8" align="center">VRAM Address (15:8)</td>
</tr>
<tr>
<td>$02</td>
<td>ADDRx_H (x=ADDRSEL)</td>
<td colspan="4" align="center">Address Increment</td>
<td colspan="1" align="center">DECR</td>
<td colspan="2" align="center">-</td>
<td colspan="1" align="center">VRAM Address (16)</td>
</tr>
<tr>
<td>$03</td>
<td>DATA0</td>
<td colspan="8" align="center">VRAM Data port 0</td>
</tr>
<tr>
<td>$04</td>
<td>DATA1</td>
<td colspan="8" align="center">VRAM Data port 1</td>
</tr>
<tr>
<td>$05</td>
<td>CTRL</td>
<td colspan="1" align="center">Reset</td>
<td colspan="5" align="center">-</td>
<td colspan="1" align="center">DCSEL</td>
<td colspan="1" align="center">ADDRSEL</td>
</tr>
<tr>
<td>$06</td>
<td>IEN</td>
<td colspan="1" align="center">IRQ Line (8)</td>
<td colspan="1" align="center">Scan Line (8)</td>
<td colspan="2" align="center">-</td>
<td colspan="1" align="center">AFLOW</td>
<td colspan="1" align="center">SPRCOL</td>
<td colspan="1" align="center">LINE</td>
<td colspan="1" align="center">VSYNC</td>
</tr>
<tr>
<td>$07</td>
<td>ISR</td>
<td colspan="4" align="center">Sprite collissions</td>
<td colspan="1" align="center">AFLOW</td>
<td colspan="1" align="center">SPRCOL</td>
<td colspan="1" align="center">LINE</td>
<td colspan="1" align="center">VSYNC</td>
</tr>
<tr>
<td>$08</td>
<td>IRQLINE_L (Write only)</td>
<td colspan="8" align="center">IRQ line (7:0)</td>
</tr>
<tr>
<td>$08</td>
<td>SCANLINE_L (Read only)</td>
<td colspan="8" align="center">Scan line (7:0)</td>
</tr>
<tr>
<td>$09</td>
<td>DC_VIDEO (DCSEL=0)</td>
<td colspan="1" align="center">Current Field</td>
<td colspan="1" align="center">Sprites Enable</td>
<td colspan="1" align="center">Layer1 Enable</td>
<td colspan="1" align="center">Layer0 Enable</td>
<td colspan="1" align="center">-</td>
<td colspan="1" align="center">Chroma Disable</td>
<td colspan="2" align="center">Output Mode</td>
</tr>
<tr>
<td>$0A</td>
<td>DC_HSCALE (DCSEL=0)</td>
<td colspan="8" align="center">Active Display H-Scale</td>
</tr>
<tr>
<td>$0B</td>
<td>DC_VSCALE (DCSEL=0)</td>
<td colspan="8" align="center">Active Display V-Scale</td>
</tr>
<tr>
<td>$0C</td>
<td>DC_BORDER (DCSEL=0)</td>
<td colspan="8" align="center">Border Color</td>
</tr>
<tr>
<td>$09</td>
<td>DC_HSTART (DCSEL=1)</td>
<td colspan="8" align="center">Active Display H-Start (9:2)</td>
</tr>
<tr>
<td>$0A</td>
<td>DC_HSTOP (DCSEL=1)</td>
<td colspan="8" align="center">Active Display H-Stop (9:2)</td>
</tr>
<tr>
<td>$0B</td>
<td>DC_VSTART (DCSEL=1)</td>
<td colspan="8" align="center">Active Display V-Start (8:1)</td>
</tr>
<tr>
<td>$0C</td>
<td>DC_VSTOP (DCSEL=1)</td>
<td colspan="8" align="center">Active Display V-Stop (8:1)</td>
</tr>
<tr>
<td>$0D</td>
<td>L0_CONFIG</td>
<td colspan="2" align="center">Map Height</td>
<td colspan="2" align="center">Map Width</td>
<td colspan="1" align="center">T256C</td>
<td colspan="1" align="center">Bitmap Mode</td>
<td colspan="2" align="center">Color Depth</td>
</tr>
<tr>
<td>$0E</td>
<td>L0_MAPBASE</td>
<td colspan="8" align="center">Map Base Address (16:9)</td>
</tr>
<tr>
<td>$0F</td>
<td>L0_TILEBASE</td>
<td colspan="6" align="center">Tile Base Address (16:11)</td>
<td colspan="1" align="center">Tile Height</td>
<td colspan="1" align="center">Tile Width</td>
</tr>
<tr>
<td>$10</td>
<td>L0_HSCROLL_L</td>
<td colspan="8" align="center">H-Scroll (7:0)</td>
</tr>
<tr>
<td>$11</td>
<td>L0_HSCROLL_H</td>
<td colspan="4" align="center">-</td>
<td colspan="8" align="center">H-Scroll (11:8)</td>
</tr>
<tr>
<td>$12</td>
<td>L0_VSCROLL_L</td>
<td colspan="8" align="center">V-Scroll (7:0)</td>
</tr>
<tr>
<td>$13</td>
<td>L0_VSCROLL_H</td>
<td colspan="4" align="center">-</td>
<td colspan="8" align="center">V-Scroll (11:8)</td>
</tr>
<tr>
<td>$14</td>
<td>L1_CONFIG</td>
<td colspan="2" align="center">Map Height</td>
<td colspan="2" align="center">Map Width</td>
<td colspan="1" align="center">T256C</td>
<td colspan="1" align="center">Bitmap Mode</td>
<td colspan="2" align="center">Color Depth</td>
</tr>
<tr>
<td>$15</td>
<td>L1_MAPBASE</td>
<td colspan="8" align="center">Map Base Address (16:9)</td>
</tr>
<tr>
<td>$16</td>
<td>L1_TILEBASE</td>
<td colspan="6" align="center">Tile Base Address (16:11)</td>
<td colspan="1" align="center">Tile Height</td>
<td colspan="1" align="center">Tile Width</td>
</tr>
<tr>
<td>$17</td>
<td>L1_HSCROLL_L</td>
<td colspan="8" align="center">H-Scroll (7:0)</td>
</tr>
<tr>
<td>$18</td>
<td>L1_HSCROLL_H</td>
<td colspan="4" align="center">-</td>
<td colspan="8" align="center">H-Scroll (11:8)</td>
</tr>
<tr>
<td>$19</td>
<td>L1_VSCROLL_L</td>
<td colspan="8" align="center">V-Scroll (7:0)</td>
</tr>
<tr>
<td>$1A</td>
<td>L1_VSCROLL_H</td>
<td colspan="4" align="center">-</td>
<td colspan="8" align="center">V-Scroll (11:8)</td>
</tr>
<tr>
<td>$1B</td>
<td>AUDIO_CTRL</td>
<td colspan="1" align="center">FIFO Full / FIFO Reset</td>
<td colspan="1" align="center">FIFO Empty</td>
<td colspan="1" align="center">16-Bit</td>
<td colspan="1" align="center">Stereo</td>
<td colspan="4" align="center">PCM Volume</td>
</tr>
<tr>
<td>$1C</td>
<td>AUDIO_RATE</td>
<td colspan="8" align="center">PCM Sample Rate</td>
</tr>
<tr>
<td>$1D</td>
<td>AUDIO_DATA</td>
<td colspan="8" align="center">Audio FIFO data (write-only)</td>
</tr>
<tr>
<td>$1E</td>
<td>SPI_DATA</td>
<td colspan="8" align="center">Data</td>
</tr>
<tr>
<td>$1F</td>
<td>SPI_CTRL</td>
<td colspan="1" align="center">Busy</td>
<td colspan="4" align="center">-</td>
<td colspan="1" align="center">Auto-tx</td>
<td colspan="1" align="center">Slow clock</td>
<td colspan="1" align="center">Select</td>
</tr>
</table>
## 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 |

View File

@ -24,3 +24,5 @@ This enables the binary loader to be extremely simple, as the data to be read in
The final segment is special: its target address represents the entry point to the executable, and its length of data value is always `0x000000`. The loader can easily detect this to identify when loading is done and where to enter the program.
The Sentinel 65X SDK will be configured to produce PGZ format executables by default, with the option to instead export to a file suitable for writing to a ROM cartridge.
Note: The open-source 64Tass assembler is also capable of generating PGZ-format executables.