Back to README.md
In addition to being compatible with a genuine VIC-II, VIC-II Kawari adds a number of new features.
Extra registers are enabled through the activation port (0xd03f) by poking it with the PETSCII bytes "VIC2". This prevents existing software from unintentionally triggering extra registers. NOTE: If lock bit jumper #2 is removed, extra registers cannot be activated.
POKE 53311,ASC("V")
POKE 53311,ASC("I")
POKE 53311,ASC("C")
POKE 53311,ASC("2")
LDA #86 ; 'V'
STA $d03f
LDA #73 ; 'I'
STA $d03f
LDA #67 ; 'C'
STA $d03f
LDA #50 ; '2'
STA $d03f
Once activated, registers 0xd02f - 0xd03f become available and may be used to access VIC-II Kawari extra features. Extra regsters can be deactivated again by setting bit 8 of 0xd03f to 1.
REG | Name | Description |
---|---|---|
0xd02f | OP_1_HI/RESULT_HH | Math Operand 1 HI on write, Result 31-25 |
0xd030 | OP_1_LO/RESULT_HL | Math Operand 1 LO on write, Result 24-16 |
0xd031 | OP_2_HI/RESULT_LH | Math Operand 2 HI on write, Result 15-8 |
0xd032 | OP_2_LO/RESULT_LL | Math Operand 2 LO on write, Result 7-0 |
0xd033 | OPERATOR/OPERATOR_FLAGS | Math Operator on write, Operation Flags on read |
0xd034 | SPI_REG | SPI Programming Register / Status Register |
0xd035 | VIDEO_MEM_1_IDX | Video Memory Index Port A (RAM only) |
0xd036 | VIDEO_MEM_2_IDX | Video Memory Index Port B (RAM only) |
0xd037 | VIDEO_MODE1 | See below |
0xd038 | VIDEO_MODE2 | See below |
0xd039 | VIDEO_MEM_1_LO | Video Memory Addr Lo Port A |
0xd03a | VIDEO_MEM_1_HI | Video Memory Addr Hi Port A |
0xd03b | VIDEO_MEM_1_VAL | Video Memory Read/Write Value Port A |
0xd03c | VIDEO_MEM_2_LO | Video Memory Addr Lo Port B |
0xd03d | VIDEO_MEM_2_HI | Video Memory Addr Hi Port B |
0xd03e | VIDEO_MEM_2_VAL | Video Memory Read/Write Value Port B |
0xd03f | VIDEO_MEM_FLAGS | Video Memory Op Flags (see below) |
VIC-II Kawari has signed and unsigned multiply and divide operations which can eliminate expensive loops on the CPU and achieve the same result. All math operands are 16-bit.
OPERATOR | Value | Description |
---|---|---|
U_MULT | 0 | Unsigned multiply OP_1 * OP_2 |
U_DIV | 1 | Unsigned divide OP_1 / OP_2 |
S_MULT | 2 | Signed multiply OP_1 * OP_2 |
S_DIV | 3 | Signed divide OP_1 / OP_2 |
OPERATION | Result Format |
---|---|
U_MULT | 32-bit unsigned in RESULT_HH RESULT_HL RESULT_LH RESULT_LL |
U_DIV | 16-bit remainder in RESULT_HH RESULT_HL, 16-bit quotient in RESULT_LH RESULT_LL |
S_MULT | 32-bit signed in RESULT_HH RESULT_HL RESULT_LH RESULT_LL |
S_DIV | 16-bit remainder in RESULT_HH RESULT_HL, 16-bit quotient in RESULT_LH RESULT_LL |
OPERATOR_FLAGS | Description |
---|---|
1 | Div By Zero |
This register is used by config/flash programs to update the FPGA bitstream. The SPI register is not enabled unless it is first POKEd with the sequence 'S','P','I'.
On Write:
Bit | Bit 8=0 | Bit 8=1 |
---|---|---|
Bit 1 | Flash SPI Select Line | Bulk Flash Op |
Bit 2 | SPI Clock Line | Bulk Flash Op |
Bit 3 | SPI Data Out Line | Bulk Flash Op |
Bit 4 | EEPROM SPI Select Line | Bulk Flash Op |
Bit 5 | Unused | Bulk Flash Op |
Bit 6 | Unused | Bulk Flash Op |
Bit 7 | Unused | Bulk Flash Op |
Bit 8 | 0=Set SPI Lines, 1=Bulk SPI Operation |
Bulk Flash Op | Operation |
---|---|
0000001 | BULK WRITE |
0000010 | BULK READ |
24 bit Flash Address = { VIDEO_MEM_1_IDX, VIDEO_MEM_1_HI, VIDEO_MEM_1_LO }
16 bit VMEM Address = { VIDEO_MEM_2_HI, VIDEO_MEM_2_LO }
Bulk flash operations always operate on 16k pages.
On Read:
Bit | Bit 8=0 |
---|---|
Bit 1 | Spi Data In Line |
Bit 2 | Bulk Flash Operation Busy |
Bit 3 | Bulk Flash Operation Verify Error |
Bit 4 | SPI Lock Status |
Bit 5 | Extensions Lock Status |
Bit 6 | Persistence Lock Status |
Bit 7 | Unused |
Bit 8 | Unused |
Jumper | Name | Function |
---|---|---|
1 | SPI Lock | OPEN=ALLOW SPI PROGRAMMING, SHORT=DISALLOW SPI PROGRAMMING |
2 | Extensions Lock | OPEN=DISALLOW EXTENSIONS, SHORT=ALLOW EXTENSIONS |
3 | Persistence Lock | OPEN=DISALLOW PERSISTENCE, SHORT=ALLOW PERSISTENCE |
Pin 1 - SPI Lock must be OPEN for flash updates to work.
Pin 2 - Extensions Lock can be left OPEN to prevent any access to extra extensions. This effectively turns VIC-II Kawari into a normal 6567/6569 chip with no extra features accessible.
Pin 3 - Persistence Lock can be left OPEN to prevent overwriting existing saved settings (rasterlines, colors, hdmi/vga/settings, etc). (Chip model is exempt from this lock)
VIC-II Kawari adds 64k of video memory to the C64. This memory can be directly accessed by VIC-II Kawari for new graphics modes and indirectly by the 6510 CPU. The registers 0xd039-0xd03f are used to read/write from/to video memory. (This space can also be used to store code but it would have to be copied back to main memory to be executed by the CPU.)
VIDEO_MEM_FLAGS | Description |
---|---|
BIT 1,2 | PORT 1 FUNCTION 0=NONE 1=AUTO INC 2=AUTO DEC 3=DMA |
BIT 3,4 | PORT 2 FUNCTION 0=NONE 1=AUTO INC 2=AUTO DEC 3=DMA |
BIT 5 | Persist busy status flag (see below) |
BIT 6 | Extra 256 registers overlay at 0x0000 Enable/Disable |
BIT 7 | Persist Flag (see below) |
BIT 8 | Deactivate Extra Registers |
When BIT 7 is 1, changes to some registers (like color palette, composite luma, phase, amplitude, etc) will be persisted to the EEPROM and restored on reboot. Each register change must be written to the EEPROM which may not be able to keep up with many register changes back to back. To avoid lost changes, the 6502 should check BIT 5 and make sure it is 0 before attempting to set the next register. For boards that do not support persistence, BIT 7 has no function and BIT 5 is always 0. If BIT 7 is not enabled, BIT 5 can be ignored.
VIDEO_MODE1 | Description |
---|---|
BIT 3-1 | CHAR_PIXEL_BASE |
BIT 4 | HIRES ALLOW BADLINES ON LORES MODES (0=no, 1=yes) |
BIT 5 | HIRES ENABLE |
BIT 8-6 | HIRES MODE |
HIRES MODE | Description |
---|---|
000 | 80 Column Text |
010 | 320x200x16 |
011 | 640x200x4 |
100 | 160x200x16 |
VIDEO_MODE2 | Description |
---|---|
BIT 1-4 | MATRIX_BASE |
BIT 5-8 | COLOR_BASE |
For the 80 column text mode, each byte stores color information as well as display attributes.
BIT | Description |
---|---|
1-4 | 16 color index |
5 | blink (every 32 frames) |
6 | underscore |
7 | reverse video |
8 | alt char set |
This bit must be 1 for any of the hi-resolution modes to be visible. When enabled, bit 4 of VIDEO_MODE1 will determine whether badlines normally generated by the 40 column mode are enabled/disabled. When disabled, it is as though the DEN bit is set to 0.
These bit controls the hires video mode.
HIRES MODE | Description |
---|---|
000 | 80 Column Text 16 Colors (4K CharDef, 2K Matrix, 2K Color) |
100 | 160x200 Bitmap 16 Color (16K Bitmap, packed pixels, 2 pixels per byte) |
010 | 320x200 Bitmap 16 Color (32K Bitmap, packed pixels, 2 pixels per byte) |
011 | 640x200 Bitmap 4 Color (32K Bitmap, packed pixels, 4 pixels per byte) |
Base Pointer | Description | Range | Restrictions |
---|---|---|---|
CHAR_PIXEL_BASE | Points to a 4k block with character ROM data | XXXXX000-XXXXX111 | lower 32k only |
MATRIX_BASE | Points to a 2k block for 80x25 character matrix | XXXX0000-XXXX1111 | lower 32k only |
COLOR_BASE | Points to a 2k block for 80x25 color matrix | XXXX0000-XXXX1111 | lower 32k only |
This works much like 40 column text mode except matrix bytes are fetched on both HIGH and LO
PHI cycles giving 80 bytes per line:
VC (11 bit matrix counter, repeats for 8 rows)
RC (3 bit row counter : 0-7)
Color Fetch Addr (15): COLOR_BASE(4) | VC(11)
Matrix Fetch Addr (15): MATRIX_BASE(4) | VC(11)
Char Pixel Fetch Addr (15): CHAR_PIXEL_BASE(3) | CASE_BIT(1) | CHAR_NUM(8) | RC(3)
There are no 'badlines' in hires modes since the video memory is dual port and can be accessed by hires pixel sequencer and the CPU at the same time. However, yscroll will still trigger a reset of the row counter as it does in the legacy modes. (NOTE: Badlines for hires modes can be enabled/disabled. See BIT 4 of VIDEO_MODE1 register. If disabled, an additional 6% (approximately) worth of 6510 cycles / frame becomes available for the CPU.)
Base Pointer | Description | Range | Restrictions |
---|---|---|---|
CHAR_PIXEL_BASE | Unused | ||
MATRIX_BASE | Points to a 32k block 320x200 packed pixel data | XXXXXXX0-XXXXXXX1 | |
COLOR_BASE | Unused |
Two bytes are fetched each half cycle giving 160 bytes each line. But each pixel color is
defined by a nibble (16 colors) so we get 2 pixels per byte, or 320 pixels each line.
FVC (15 bit counter)
Pixel Fetch Addr (16) : MATRIX_BASE[0](1) | HVC
Base Pointer | Description | Range | Restrictions |
---|---|---|---|
CHAR_PIXEL_BASE | Unused | ||
MATRIX_BASE | Points to a 32k block 640x200 packed pixel data | XXXXXXX0-XXXXXXX1 | |
COLOR_BASE | Color bank | XXXXXX00-XXXXXX11 |
Two bytes are fetched each half cycle giving 160 bytes each line. But each pixel color is
defined by a 2 adjacent bits (4 colors), so we get 4 pixels per byte, or 640 pixels each line.
The bank of 4 colors within the available 16 are determined by the lower 2 bits of COLOR_BASE.
HVC (15 bit counter)
Pixel Fetch Addr (16) : MATRIX_BASE[0](1) | HVC
Base Pointer | Description | Range | Restrictions |
---|---|---|---|
CHAR_PIXEL_BASE | Unused | ||
MATRIX_BASE | Points to a 16k block 160x200 pixel data | XXXXXX00-XXXXXX11 | |
COLOR_BASE | Unused |
One byte is fetched each cycle giving 80 bytes each line. But each pixel color is
defined by a nibble (16 colors) so we get 2 pixels per byte, or 160 pixels each line.
byte is fetched each half cycle giving 80 bytes per line.
FVC (14 bit counter)
Pixel Fetch Addr (16): MATRIX_BASE[1:0](2) | FVC
LDA <ADDR
STA VIDEO_MEM_1_HI
LDA >ADDR
STA VIDEO_MEM_1_LO
LDA #1 ; Auto increment port 1
STA VIDEO_MEM_FLAGS
LDA #$55
STA VIDEO_MEM_A_VAL ; write $55 to video mem ADDR
Sequential writes will auto increment the address:
LDA #$56
STA VIDEO_MEM_A_VAL ; write $56 to ADDR+1
LDA #$57
STA VIDEO_MEM_A_VAL ; write $57 to ADDR+2
(...etc)
* video mem hi/lo pairs will wrap as expected
LDA <ADDR
STA VIDEO_MEM_1_HI
LDA >ADDR
STA VIDEO_MEM_1_LO
LDA #1 ; Auto increment port 1
STA VIDEO_MEM_FLAGS
LDA VIDEO_MEM_A_VAL ; read the value
Sequential reads will auto increment the address:
LDA VIDEO_MEM_A_VAL ; read from ADDR+1
LDA VIDEO_MEM_A_VAL ; read from ADDR+2
(...etc)
* video mem hi/lo pairs will wrap as expected
Here is an example of moving memory within video RAM using the CPU. (A much more efficient way using block copy is shown below).
LDA <SRC_ADDR
STA VIDEO_MEM_1_HI
LDA >SRC_ADDR
STA VIDEO_MEM_1_LO
LDA <DEST_ADDR
STA VIDEO_MEM_2_HI
LDA >DEST_ADDR
STA VIDEO_MEM_2_LO
LDA #5 ; Auto increment port 1 and 2
STA VIDEO_MEM_FLAGS
LDA VIDEO_MEM_A_VAL ; read from src
STA VIDEO_MEM_B_VAL ; write to dest
Sequential read/writes will auto increment/decrement the address as above.
Sometimes, it may be more convenient to use an index when porting code to use VIC-II Kawari extended video memory. This is useful if replacing indirect indexed addressing.
For example, the code:
LDY #20
LDA #00
STA $fc
LDA #04
STA $fd
LDA ($fc),y
Can be replaced with:
LDY #20
LDA #00
STA VIDEO_MEM_1_LO
LDA #04
STA VIDEO_MEM_1_HI
STY VIDEO_MEM_1_IDX
LDA VIDEO_MEM_1_VAL
NOTE: VIDEO_MEM_?_IDX only applies to RAM access, not the extended register overlay area between 0x00 - 0xff described below.
You can perform high speed copy/fill operations by setting the vmem port 1 and 2 functions to DMA. NOTE: Both port 1 and 2 must be configured for DMA.
Register | Meaning |
---|---|
VIDEO_MEM_1_LO | Dest Lo Byte |
VIDEO_MEM_1_HI | Dest Hi Byte |
VIDEO_MEM_2_LO | Src Lo Byte |
VIDEO_MEM_2_HI | Src Hi Byte |
VIDEO_MEM_1_IDX | Num Bytes Lo (Copy) |
VIDEO_MEM_2_IDX | Num Bytes Hi (Copy) |
VIDEO_MEM_1_VAL | Perform DMA Function (on write) |
VIDEO_MEM_2_VAL | Unused |
Perform DMA Function Value | Meaning |
---|---|
1 | Copy VMEM src to VMEM dest (start to end) |
2 | Copy VMEM src to VMEM dest (end to start) |
4 | Fill VMEM dest (See below) |
8 | Copy DRAM src* to VMEM dest |
16 | Copy VMEM src to DRAM dest* |
32 | Set Blit Src Info |
64 | Set Blit Dst Info & Execute |
128 | Unused |
* The upper 2 bits of all DRAM src/dest addresses are controlled by the CIA chip. That is, DRAM accesses for DMA transfers will point to the same 16k bank the CIA chip points the VIC to. The upper two bits of all DRAM addresses specified in the registers above are effectively ignored.
When extra registers are enabled, an additional IRQ control bit is available in 0xD01A and status bit in 0xD019 (firmware v1.16 or higher). Enabling the control bit 4 (value 16) will raise an interrupt with the CPU and the interrupt routine located at $314/$315 will be executed. Clear the interrupt by writing bit 4 (16) to the IRQST register as you would other types of interrupts.
This is an alternative method for detecting when the DMA operation is complete. It avoids polling which can waste CPU cycles that could used for other operations while the DMA transfer is in progress. The polling method is used in samples below. However, the IRQ method is more flexible as you are able to chain multiple DMA operations together with no wasted CPU cycles.
Register | Name | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|---|
D019 | IRQST | IRQ | IDMA | ILP | IMMC | IMBC | IRST | ||
D01A | IRQEN | EDMA | ELP | EMMC | EMBC | ERST |
LDA <SRC_ADDR
STA VIDEO_MEM_1_HI
LDA >SRC_ADDR
STA VIDEO_MEM_1_LO
LDA <DEST_ADDR
STA VIDEO_MEM_2_HI
LDA >DEST_ADDR
STA VIDEO_MEM_2_LO
LDA #15 ; Port 1 copy src, Port 2 copy dest
STA VIDEO_MEM_FLAGS
LDA #00
STA VIDEO_MEM_1_IDX
LDA #02
STA VIDEO_MEM_2_IDX ; 512 bytes
LDA #1
STA VIDEO_MEM_1_VAL ; Perform copy (start to end)
polldone
LDA VIDEO_MEM_2_IDX ; wait for done
bne polldone
- Copy is finished when VIDEO_MEM_1_IDX == 0 && VIDEO_MEM_2_IDX == 0
- These values do not change while copy is performed so just checking one value that started as not 0 for 0 is sufficient to indicate done.
- 8 bytes are moved each 6510 cycle.
- Max copy is 65535 bytes
NOTE: Since firmware 1.16, DMA copy operation can use the overlay regs as a destination (not a source). This is meant to quickly swap in palettes without having to use the CPU.
The following table estimates the number of bytes that can be moved if move operations are restricted to non-graphics raster lines. (NOTE: move can be invoked any time.)
Chip | Non visible gfx lines | Cycles / line | Bytes Copied / Frame |
---|---|---|---|
6569 | (312-200) = 112 | 63 | 63*112*8 = 56448 |
6567R8 | (262-200) = 62 | 65 | 65*62*8 = 32240 |
6567R56A | (261-200) = 61 | 64 | 64*61*8 = 31232 |
Register | Meaning |
---|---|
VIDEO_MEM_1_LO | Start Lo Byte |
VIDEO_MEM_1_HI | Start Hi Byte |
VIDEO_MEM_1_IDX | Num Bytes Lo |
VIDEO_MEM_2_IDX | Num Bytes Hi |
VIDEO_MEM_2_LO | Byte for fill |
VIDEO_MEM_2_HI | Unused |
VIDEO_MEM_1_VAL | 4 = Perform fill with byte stored in VIDEO_MEM_2_LO |
VIDEO_MEM_2_VAL | Unused |
LDA <DST_ADDR
STA VIDEO_MEM_1_HI
LDA >DST_ADDR
STA VIDEO_MEM_1_LO
LDA #15 ; Port 1 DMA, Port 2 DMA
STA VIDEO_MEM_FLAGS
LDA #00
STA VIDEO_MEM_1_IDX
LDA #02
STA VIDEO_MEM_2_IDX ; 512 bytes
LDA #ff ; Byte for fill
STA VIDEO_MEM_2_LO
LDA #4
STA VIDEO_MEM_1_VAL ; Perform fill
polldone
LDA VIDEO_MEM_2_IDX ; wait for done
bne polldone
- Fill is finished when VIDEO_MEM_1_IDX == 0 && VIDEO_MEM_2_IDX == 0
- These values do not change while copy is performed so just checking one value that started as not 0 for 0 is sufficient to indicate done.
- 32 bytes are filled each 6510 cycle.
- Max fill is 65535 bytes
The following table estimates the number of bytes that can be filled if fill operations are restricted to non-graphics raster lines. (NOTE: fill can be invoked any time.)
Chip | Non visible gfx lines | Cycles / line | Bytes Filled / Frame |
---|---|---|---|
6569 | (312-200) = 112 | 63 | 63*112*32 = 225792 |
6567R8 | (262-200) = 62 | 65 | 65*62*32 = 128960 |
6567R56A | (261-200) = 61 | 64 | 64*61*32 = 124928 |
LDA <VMEM_SRC_ADDR ; vmem src
STA VIDEO_MEM_1_HI
LDA >VMEM_SRC_ADDR
STA VIDEO_MEM_1_LO
LDA <DRAM_DST_ADDR ; dram dest
STA VIDEO_MEM_2_HI
LDA >DRAM_DST_ADDR
STA VIDEO_MEM_2_LO
LDA #0
STA VIDEO_MEM_1_IDX
LDA #4
STA VIDEO_MEM_2_IDX ; size 2k
LDA #15 ; Port 1 op DMA, Port 2 op DMA
STA VIDEO_MEM_FLAGS
LDA #8 ; Perform DMA op
STA VIDEO_MEM_FLAGS
polldone
LDA VIDEO_MEM_2_IDX ; wait for done
bne polldone
LDA <DRAM_SRC_ADDR ; dram src
STA VIDEO_MEM_1_HI
LDA >DRAM_SRC_ADDR
STA VIDEO_MEM_1_LO
LDA <VMEM_DST_ADDR ; vmem dest
STA VIDEO_MEM_2_HI
LDA >VMEM_DST_ADDR
STA VIDEO_MEM_2_LO
LDA #0
STA VIDEO_MEM_1_IDX
LDA #4
STA VIDEO_MEM_2_IDX ; size 2k
LDA #15 ; Port 1 op DMA, Port 2 op DMA
STA VIDEO_MEM_FLAGS
LDA #16 ; Perform DMA op
STA VIDEO_MEM_FLAGS
polldone
LDA VIDEO_MEM_2_IDX ; wait for done
bne polldone
- VIC-II Kawari uses idle graphics fetch cycles (as well as idle cycles) to perform DRAM to VMEM or VMEM to DRAM transfers. On raster lines less than 51 and greater than 250 (i.e when graphics fetches are in idle state), at least 40 bytes will be transfered each raster line. The actual number depends on the chip model since there are 2-4 additional idle cycles. When graphics fetches are not in idle state (i.e. usually in the visible gfx region) only 2-4 bytes are transfered each raster line. Rough calculations on the number of bytes that can be transfered per second are provided below.
Chip | Idle RL | Active RL | Bytes/Idle RL | Bytes/Active RL | Bytes / Frame |
---|---|---|---|---|---|
6569 | 50 + (312-250) = 112 | 200 | 42 | 2 | 5104 |
6567R8 | 50 + (262-250) = 62 | 200 | 44 | 4 | 3528 |
6567R56A | 50 + (261-250) = 61 | 200 | 43 | 3 | 3223 |
- If badlines are suppressed (i.e turn off the den bit), then all raster lines can transfer the maximum number of bytes and the transfer rate is much higher. By turning off the low-res VIC modes, transferring memory from DRAM to VMEM can be as high as 13k/Frame.
The blitter modifies graphics data in a region of video memory (dest) using data in another region of video memory (source) according to the specified operation (rasterOp). Video mem flags for both ports 1 & 2 functions must be set to DMA (3) for the blitter to execute. The blitter only operates on the extended video ram (VRAM), not DRAM.
The base pointer for the source and destination must be specified as well as the source and destination stride. The source and destination coordinates (x,y) of a rectangle (w,h) must also be specified. For both 320x200x16 and 640x200x4 resolutions, the stride is 160. However, you can keep an off-screen bitmap of any stride if needed. It is up to the caller to ensure the stride is sufficient to contain the width of the rectangle. Pixel depth is always determined by the current resolution in VIDEO_MODE1 (bits 6-7). The blitter only works with bitmap modes 160x200, 320x200 or 640x200. Using the blitter with other modes is undefined behavior. The caller may check 0xd03d == 0 to determine whether the blitter operation is complete. (or use IRQ in v1.16+, see below)
- Set the blitter source rectangle information
- Set the blitter destination rectangle information, raster operation + flags and execute
- Check 0xd03d == 0 for done (or use IRQ - v1.16+)
Register | Param | Description |
---|---|---|
0xd02f | Width Hi | The rectangle width hi byte (only lowest 2 bits are valid) |
0xd030 | Width Lo | The rectangle width lo byte |
0xd031 | Height Hi | The rectangle height hi byte (only lowest 2 bits are valid) |
0xd032 | Height Lo | The rectangle height lo byte |
0xd035 | Src Ptr Lo Byte | The base pointer to bitmap data (lo byte) |
0xd036 | Src Ptr Hi byte | The base pointer to bitmap data (hi byte) |
0xd039 | Src X Lo Byte | The x coordinate for the rectangle (lo byte) |
0xd03a | Src X Hi Byte | The x coordinate for the rectangle (hi byte) |
0xd03c | Src Y Lo Byte | The y coordinate for the rectangle |
0xd03d | Src Stride | The source bitmap stride |
0xd03b | Set | Set blitter src with value of 32 |
Register | Param | Description |
---|---|---|
0xd02f | Blit Flags | Flags and Raster operation (See below) |
0xd030 | Unused | |
0xd031 | Unused | |
0xd032 | Unused | |
0xd035 | Dst Ptr Lo Byte | The base pointer to bitmap data (lo byte) |
0xd036 | Dst Ptr Hi byte | The base pointer to bitmap data (hi byte) |
0xd039 | Dst X Lo Byte | The x coordinate for the rectangle (lo byte) |
0xd03a | Dst X Hi Byte | The x coordinate for the rectangle (hi byte) |
0xd03c | Dst Y Lo Byte | The y coordinate for the rectangle |
0xd03d | Dst Stride | The destination bitmap stride |
0xd03b | Set Reg | Set blitter dst and perform blit op with value of 64 |
8765 | 4 | 3 | 2 | 1 |
---|---|---|---|---|
index | transparency bit | raster operation |
If set, the transparency bit tells the blitter to consider any pixel with a color index specified by bits 8-5 as transparent. The raster operation is fixed to DST = SRC in that case. Note that in 640x400x4 mode, only bits 5&6 matter since ther are only 4 colors per pixel.
Value | Description |
---|---|
0 | DST = SRC |
1 | DST = SRC OR DST |
2 | DST = SRC AND DST |
3 | DST = SRC XOR DST |
4-7 | Unused |
There is no clipping of rectangles. The rectangles must be within the bounds of the bitmap region.
The estimated bandwidth of blitter operations is 4 pixels per 6510 cycle. The table below shows how many pixels / frame can be copied/movied if blitter operations are restricted to run outside visible graphics region.
Chip | Non visible gfx lines | Cycles / line | Pixels Moved / Frame |
---|---|---|---|
6569 | (312-200) = 112 | 63 | 63*112*4 = 28224 |
6567R8 | (262-200) = 62 | 65 | 65*62*4 = 16120 |
6567R56A | (261-200) = 61 | 64 | 64*61*4 = 15616 |
NOTE: You can invoke the blitter any time and you can likely get a slightly higher bandwidth by starting operations before the raster line reaches the last visible graphics line. However, care must be taken to avoid altering visible graphics region where the scanline currently is to avoid tearing.
When BIT 6 of the VIDEO_MEM_FLAGS register is set, the first 256 bytes of video RAM is mapped to extra registers for special VIC-II Kawari functions.
Location | Name | Since | Description | Capability Requirement | Can be saved? |
---|---|---|---|---|---|
0x00 - 0x03 | MAGIC BYTES | 1.4 | EEPROM Magic Bytes | N/A | Y |
0x04 | DISPLAY_FLAGS | 1.4 | See below | NONE | Y |
0x05 | EEPROM_BANK | 1.4 | EEPROM Bank | HAVE_EEPROM | N |
0x06 | DISPLAY_FLAGS2 | 1.12 | See below | HAVE_EEPROM | Y |
0x07 | CFG_VERSION | 1.12 | See below | HAVE_EEPROM | N |
0x1f | CHIP_MODEL | 1.4 | Chip Model Select (0=6567R8, 1=6569R3, 2=6567R56A, 3=6569R1) | NONE | Y |
0x20 - 0x3f | UNUSED | 1.4 | Unused | NONE | N/A |
0x40 - 0x7f | PAL_RGB | 1.4 | 4x16 array of RGBx (4th byte unused) | CONFIG_RGB | Y |
0x80 | BLACK_LEVEL | 1.4 | Composite black level (0-63) | CONFIG_COMPOSITE | Y |
0x81 | BURST_AMPLITUDE | 1.4 | Composite color burst amplitude (1-15, 0 = no color burst) | CONFIG_COMPOSITE | Y |
0x83 | VERSION | 1.4 | Version (high nibble major, low nibble minor) - Read Only | NONE | N/A |
0x85 | CURSOR_LO | 1.4 | Hires Cursor lo byte | HIRES_MODES | N/A |
0x86 | CURSOR_HI | 1.4 | Hires Cursor hi byte | HIRES_MODES | N/A |
0x87 | CAP_LO | 1.4 | Capability Bits lo byte (Read Only) | NONE | N/A |
0x88 | CAP_HI | 1.4 | Capability Bits hi byte (Read Only) | NONE | N/A |
0x89 | TIMING_CHANGE | 1.4 | HDMI/VGA Timing change signal - Bit 1 | CONFIG_TIMING | N |
0x8a - 0x8f | Reserved | 1.4 | Reserved | NONE | N/A |
0x90 - 0x9f | VARIANT_NAME | 1.4 | Variant Name | NONE | N/A |
0xa0 - 0xaf | LUMA_LEVELS | 1.4 | Composite luma levels for colors (0-63) | CONFIG_COMPOSITE | |
0xb0 - 0xbf | PHASE_VALUES | 1.4 | Composite phase values for colors (0-255 representing 0-359 degrees) | CONFIG_COMPOSITE | Y |
0xc0 - 0xcf | AMPL_VALUES | 1.4 | Composite amplitude values for colors (1-15, 0 = no modulation) | CONFIG_COMPOSITE | Y |
0xd0 | VGA_HBLANK | 1.4 | HDMI/VGA H blank start | CONFIG_TIMING | N |
0xd1 | VGA_FPORCH | 1.4 | HDMI/VGA H front porch | CONFIG_TIMING | N |
0xd2 | VGA_SPULSE | 1.4 | HDMI/VGA H sync pulse | CONFIG_TIMING | N |
0xd3 | VGA_BPORCH | 1.4 | HDMI/VGA H back porch | CONFIG_TIMING | N |
0xd4 | VGA_VBLANK | 1.4 | HDMI/VGA V blank start | CONFIG_TIMING | N |
0xd5 | VGA_FPORCH | 1.4 | HDMI/VGA V front porch | CONFIG_TIMING | N |
0xd6 | VGA_SPULSE | 1.4 | HDMI/VGA V sync pulse | CONFIG_TIMING | N |
0xd7 | VGA_BPORCH | 1.4 | HDMI/VGA V back porch | CONFIG_TIMING | N |
0xe0 - 0xff | UNUSED | Unused | NONE | N/A |
VIC-II Kawari has a configurable color palette. The 16 colors can be selected from a palette of 262144 colors by specifying three 6-bit RGB values. (The upper 2 bits in each byte are ignored). The RGB palette is located at 0x40 in the extended registers page.
Colors generated by the luma/chroma generator can be modified by changing registers 0xa0-0xaf (luma levels), 0xb0-0xbf (hue/phase angles) and 0xc0-0xcf (saturation/amplitude). Luma levels are 6 bit values (0-63). Phase angles are 0-255 (representing 0-359 degrees). Amplitudes are 4 bit values (0-15). (NOTE: Blanking levels below 8 may not be accepted by some TV's/monitors and any color luma value should be at or above the blanking level or the CRT may lose sync.)
Any register above 0x1f is a 'per-chip' register. If it is persisted to EEPROM, it will be persisted only for the chip specified in eeprom_bank. Any register 0x1f or less is a 'cross-chip' register and will be applied to all chip models at boot.
NOTE: The RGB based video timing registers are not available in unless the bitstream was generated with configurable timing. This feature was meant to test different values during development and was not meant as an end-user feature. These registers will likely be removed once the final timings are determined.
Blanking start values are absolute values compared to the native resolution.
VBLANK is compared to raster line (vertical) and HBLANK to xpos (horizontal) internal counters.
NTSC HBLANK and VBLANK can range from 0-255
PAL HBLANK start ranges from 0-255
PAL VBLANK start ranges from 256-511 (represented by 0-255)
For VGA, Front Porch, Sync Pulse Width and Back Porch are durations and are added cumulatively to blank start. (Hence, Visible End = Blank Start and Visible Start = Blank Start + Front Porch + Sync Pulse Width + Back Porch)
Care must be taken so that no value exceeds the resolution. For PAL, VBLANK + FPORCH + SPULSE + is expected to be less than 311 but BPORCH is expected to cross 311.
For composite output, color burst and sync pulses begin/end are hard coded to NTSC or PAL video standards and are relative to blank start.
DISPLAY_FLAGS | Function |
---|---|
Bit 1 | Raster lines visible(1) or invisible(0) for RGB/DVI modes |
Bit 2 | Use native y resolution for DVI/RGB modes rather than double (1=15khz, 0=31khz) |
Bit 3 | Use native x resolution for DVI/RGB modes rather than double (1=native, 0=doubled) |
Bit 4 | Enable CSYNC on HSYNC pin (VSYNC held low) |
Bit 5 | RGB VSync Polarity (0=active low, 1=active high) |
Bit 6 | RGB HSync Polarity (0=active low, 1=active high) |
Bit 7 | External switch state (0=not inverting saved chip, 1=inverting saved chip) |
Bit 8 | Enable/disable max luma on first pixel for each rasterline (composite out only) |
- Double x resolution is required for 80 column mode or any hires mode.
- If CSYNC is enabled, polarity is controlled by HSync Polarity
DISPLAY_FLAGS2 | Function |
---|---|
Bit 1 | NTSC 50 Enable/Disable |
Bit 2 | Unused |
Bit 3 | Lumacode Enable/Disable |
Bit 4 | Unused |
Bit 5 | Unused |
Bit 6 | Unused |
Bit 7 | Unused |
Bit 8 | Unused |
CAP_LO | Description |
---|---|
Bit 1 | Has analog RGB out |
Bit 2 | Has digital RGB out (DVI) |
Bit 3 | Has composite out (LUMA/CHROMA) |
Bit 4 | Has configurable RGB palette |
Bit 5 | Has configurable Luma/Chroma/Amplitude |
Bit 6 | Has configurable analog/digital RGB timing params |
Bit 7 | Has configuration persistance |
Bit 8 | Has hires modes available |
CAP_HI | Description |
---|---|
Bit 1-8 | Reserved |
The extra register overlay area 0x0090 - 0xd09f is used to identify the Kawari variant name. This is a max 16 byte null terminated PETSCII string. All forks should change this to something other than 'main' if they plan on releasing a bitstream. See FORKING.md
The extra registers described here should remain functional across all VIC-II Kawari variants. This way, the main branch configuration utility will be able to at least query the variant name and version on any variant (as well as change video standard or other common features between variants). Users will be able to at least identify what variant they are running even if they use the main branch config utility. Also, programs can run a simple check routine that will run on all variants and can display a user friendly message indicating the wrong variant is installed.
Bit | Description | Value |
---|---|---|
Bit 1 | LSB | 1 |
Bit 2 | 2 | |
Bit 3 | 4 | |
Bit 4 | 8 | |
Bit 5 | 16 | |
Bit 6 | 32 | |
Bit 7 | 64 | |
Bit 8 | MSB | 128 |