Video system

A project log for Isetta TTL computer

Retro computer built from TTL, with 6502 and Z80 instruction set. Includes video, file, and sound system. No microprocessor.

roelhroelh 08/22/2023 at 18:510 Comments

The Isetta video system will now be described.


The generated signal is a VGA signal with a maximum resolution of 640 x 480 pixels.

The timing is: 
  25.175 master clock
  approx. 40nS per pixel (for 640 pixels/line)
  approx. 32uS scanline
A whole scanline has a width of 800 pixels (only 640 pixels used)
A whole frame has a height of 525 scanlines (480 scanlines used).
Exact values can be found here.

The isetta can work with maximum or reduced horizontal resolutions:

In the vertical direction, scanlines can be repeated (to keep the pixels almost square, also when a lower horizontal resolution is used), giving:

There are 64 colors (but the color can not be freely chosen for every pixel).


The Isetta processor runs with a cycle of 160nS (6.25 MHz). The video output is directly generated by the processor, so during every instruction, one or more pixels must be generated:

Isetta contains a hardware timer that triggers an interrupt at the beginning of every scanline. At the beginning of the visual part of the screen, this interrupt transfers control to the microcode that has the video instructions to give screen output. It can also initiate the generation of the frame sync pulse (the line sync pulse is generated by the hardware timer). If the interrupt is outside the visible area, the interrupt code will only increment the line counter, and return to the interrupted program almost immediately.

A video instruction will get a single byte from the RAM, and gets color information, pixel information, and sometimes control information (flags) from that byte.

The microinstruction fetches this byte from the indicated RAM location.
The RAM is normally addressed with the (PC++) mode (Of course this requires that the PC that was used in the Z80 or 6502 program was saved when the interrupt is entered).

The color information is 6 bits. The instruction can store the color in register T (foreground color) or in register A (background color).

Information about a pixel is only 1 bit. If that bit is 1, the color of the pixel comes from register A. If the bit is 0, the color comes from register T.

We now come to the basic byte formats that are used for the video system.

Byte format: -cccccc-

The 6 color bits 'cccccc' can be transferred to the T (Foreground, FG) or A (Background, BG) register.

Byte format: a------b

Two pixel bits 'ab' select the two pixels to be used in 320 pixels/line mode. These pixels are placed in the 4-bit 'pixel register' as 'bbaa'. The pixel register is loaded at every instruction, so the information is only available in the next cycle.

This format is the same as the 320 pixels/line format, but in this case the bits a and b simply have the same value.

Byte format for 4 pixels: --pppp-- 
Four pixel bits 'pppp' select four pixels to be used in the 640 pixels/line mode. These pixels are transferred to the DPH register, and the output of this register is connected to a multiplexer that selects the correct pixel to be displayed. The 'pppp' bits are in bit5, bit4, bit3 and bit2 of the byte. The pixel register is connected to other inputs of the same multiplexer.

Byte format for 2 pixels:  ab-----1

This 2-pixel byte must be loaded with a SHL (shift left) instruction, while shifting a '1' into bit0. That will put the bits in the 4-bit pixel register as '11ab'. The '11' section defines background color (in register A).

One of the bits in the microinstruction ( ctl_reg1 ) determines if the pixel information comes from the 4-bit pixel register  or from the four '--pppp--' values in the DPH register. This is done in the cycle that follows the instruction that loaded the byte.

Note that there can be combinations of bytes:


At the start of the visible area, the processor should set the 'blank' signal (in the output port) to zero. This enables the video output, and selects the A or T register on the operand bus, based upon the pixel value (while this selection is normally determined by the microinstruction). During video output, the microinstruction can select A on the operand bus to force the color to background.

At the start of a video line, a table will be accessed that has the relevant information for this line:

320-pixel/line Graphic mode

A normal 320-pixel/line can alternate between loading a new FG color and loading a new BG color. Every instruction will also provide the two 'bbaa' bits to the pixel register.

A <- (PC++) // load BG color and ab bits, display 'bbaa' in next cycle
T <- (PC++) // load FG color and ab bits, display 'bbaa' in next cycle
A <- (PC++)
T <- (PC++)
A <- (PC++)
T <- (PC++)

640-pixel/line 2-color graphic mode

A 640-pixel/line can be used for 2-color graphic output. The FG and BG colors must already be present in the A and T registers:

DPH <- (PC++) // provide four --pppp-- bits
DPH <- (PC++) // provide next four --pppp-- bits
DPH <- (PC++) // provide next four --pppp-- bits
DPH <- (PC++) // provide next four --pppp-- bits

40-char/line text mode

The 320-pixel/line graphic mode can also be used to display text. 

But it is also possible to use a character definition bitmap somewhere in memory. We spread the definition of a single row (6 pixels) over 3 memory banks. These locations also contain the foreground color of the character.

The first instruction places the character code in DPL. The DPH register is already set to the correct row of the character (done before the start of the line). The video data can be the same for each row in a character. If we start the video data at address 0x0400, the behaviour will be similar to the text mode of the Commodore 64: Write an ASCII value in the range 0x0400-0x7FF and the character will appear on the screen.

dpl <- (pc++)  // char code.  DPH is set at beginning of line. Suppress pixels(with A/T select)
T <- (dph/dpl,bank1)  // pixels/color accccccb  (color specified in bitmap)
T <- (dph/dpl,bank2)  // pixels/color accccccb 
T <- (dph/dpl,bank3)  // pixels/color accccccb

2-color 80-char/line text mode

We use essentially the graphic mode for this. The 640 pixel/line mode will probably be used with 400 or 480 lines per screen, so this will take a lot of memory (But we can use a memory bank outside the normal 64kB area).

There is way to reduce the memory usage when text is used, by providing 6 pixels in a byte, in the ab-pppp1 format. A first instruction will load the byte and display the '11ab' bits in the next cycle. The next instruction will display the 'pppp' bits in its next cycle.

So the character is 8 pixels wide, but the first two pixels are '1' (background).

DPH <- (PC++)   // load ab-pppp1 and display 11ab in next cycle
NOP             // display pppp in next cycle
DPH <- (PC++)   // load ab-pppp1 and display 11ab in next cycle
NOP             // display pppp in next cycle

Multicolor 80-char/line text mode

In this mode, the first instruction loads 2 pixels and a 5-bit color. The next instruction loads 4 pixels, together this are 6 pixels for the character. This repeats for the next characters. So every character can have a different color.

T <- shl(pc++)  // abccccc1, 2 pixels, shift, pixels 11ab, color ccccc1
DPH <- (pc++)   //  --pp pp--, load 4 pixels
T <- shl(pc++)
DPH <- (pc++)

[ Edit 230830 The definition of the byte formats, and the application section, have changed. This log was made up-to-date. ]