From 3ee2cc737cb96c7668cb5e6942e5a656549a518b Mon Sep 17 00:00:00 2001 From: Kyle Cardoza Date: Sun, 24 Mar 2024 00:37:53 -0400 Subject: [PATCH] Work on fleshing out sections --- Audio & Video.md | 67 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 64 insertions(+), 3 deletions(-) diff --git a/Audio & Video.md b/Audio & Video.md index 2e7faba..a451c90 100644 --- a/Audio & Video.md +++ b/Audio & Video.md @@ -5,7 +5,7 @@ include_toc: true # 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. +The VERA FPGA core, implemented on an [iCE40 FPGA](https://www.latticesemi.com/en/Products/FPGAandCPLD/iCE40UltraPlus), is used to generate all audio and video signals produced by Sentinel 65X. This core, developed for the [Commander X16](https://github.com/commanderx16) project by [Frank van den Hoef](https://github.com/fvdhoef/vera-module/tree/rev4), is licensed under the MIT license. It has been modified by [Brian Swetland](https://github.com/swetland/vera-module) for Sentinel 65X, including porting it to be built using the [Yosys open-source FPGA toolchain](https://github.com/YosysHQ/yosys). ## Video @@ -159,6 +159,67 @@ The `DC_Video` and `DC_HSTART` registers share the address `0x00DF09`; which one 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](#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_HSCALE` sets a fractional horizontal 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. +`DC_HSTOP` controls the last 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_VSCALE / DC_VSTART + +The `DC_VSCALE` and `DC_VSTART` registers share the address `0x00DF0B`; which one is accessed at that address is determined by the `DCSEL` flag bit in the [CTRL](#ctrl) register -- a `0` value in `DCSEL` will enable the `DC_VSCALE` register, and a `1` value the `DC_VSTART` register. + +`DC_VSCALE` sets a fractional vertical 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_VSTART` controls the first active row of the screen, relative to the 640x480 display area. The value is the top 8 bits of a 9-bit number, the low order bit of which is implied to be 0 -- that is, the value is an 8 bit number which will be multiplied by 2. + +### DC_BORDER / DC_VSTOP + +The `DC_BORDER` and `DC_VSTOP` registers share the address `0x00DF0B`; which one is accessed at that address is determined by the `DCSEL` flag bit in the [CTRL](#ctrl) register -- a `0` value in `DCSEL` will enable the `DC_BORDER` register, and a `1` value the `DC_VSTOP` register. + +`DC_BORDER` stores the 8-bit pallette index of the colour used to fill the "inactive" region of the screen, as determined by the `DC_HSTART`, `DC_HSTOP`, `DC_VSTART`, and `DC_VSTOP` registers. + +`DC_VSTOP` controls the last active row of the screen, relative to the 640x480 display area. The value is the top 8 bits of a 9-bit number, the low order bit of which is implied to be 0 -- that is, the value is an 8 bit number which will be multiplied by 2. + +### L0_CONFIG + +The `L0_CONFIG` register, located at `0x00DF0D`, controls the configuration of tile/bitmap layer 0. + +Bits 0-1 store the colour depth of the layer; that is, the number of bits used per pixel in the tile or bitmap data used to render the layer: + +| Value | Depth | +| :---: | :---: | +| 0 | 1 bpp | +| 1 | 2 bpp | +| 2 | 4 bpp | +| 3 | 8 bpp | + +Bit 2 sets the layer to use tiles mode when set to `0`; a value of `1` will set the layer to use bitmap mode. + +Bit 3, called `T256C`, is used with tiles modes to enable or disable 256-colour 1bpp mode. + +Bits 4-5 encode the tile map width, while bits 6-7 encode the tile map height, according to the values in the following table: + +| Value | Map Width / Height | +| :---: | :----------------: | +| 0 | 32 tiles | +| 1 | 64 tiles | +| 2 | 128 tiles | +| 3 | 256 tiles | + +### L0_MAPBASE + +The `L0_MAPBASE` register, located at `0x00DF0DE`, encodes the high 8 bits of the 17-bit address in VERA memory where the map data for layer 0 can be found; since the bottom 9 bits are implicitly `0`, this means the map data must always begin on a 512-byte alignment boundary. + +## 16-Bit Reads/Writes + +With appropriate configuration of registers, it is possible to perform sequential 16-bit reads and writes to VERA address space: + +- Set `ADDR0` to the lowest address to read or write in VERA memory, and clear `DECR0`. +- Set `ADDR1` to a value exactly one address higher than `ADDR0`, and clear `DECR1`. +- Set both `INCR0` and `INCR1` to a value of `0` or `2`. +- Set the CPU register to be used to read from or write to VERA memory to be 16 bits wide. +- Read or write to `DATA0` using a 16-bit load or store instruction. This will implicitly read `DATA1`. +- If `INCR0` and `INCR1` are both set to `0`, then the address will not increment at all; if they are set to `2`, then the address of both `DATA0` and `DATA1` will be incremented by `2` addresses. + +Such 16-bit reads and writes are almost twice as cycle-efficient as reading or writing in 8-bit increments, as the extra byte takes only a single extra CPU cycle. + +The SDK will provide a C function pair `vera_memcpy_read()` and `vera_memcpu_write()` handle bulk data transfers; it will use this mode of reading and writing without futher intervention by the programmer.