I've come across a couple of projects that manage to get VGA working with the Z80 and similar CPUs:

  • Veronica (6502 CPU, VGA signal generation by AVR)
  • ZC160 (Z80 CPU, VGA signal generation by GAL)
  • c-Z80 (Z80 CPU, VGA signal generation by AVR)
  • and many others by searching for "VGA + cpuName"

What I can't seem to understand is how the various adapters talk with the CPU. If we assume that VGA signal generation is a solved problem handled by a black box, how do you connect this black box to the CPU?

Does one use the INT and/or IOREQ pins? The databus? Is most of the talking through assembly code using the IN and OUT commands?

  • 1
    There are multiple ways in which it can be done (I can think of at least 4 approaches that could be used that are different in critical ways), and the projects you list approach the problem in different ways. Perhaps if you focus on just one of them, the question might be easier to answer? (note that a 6502 doesn't have an equivalent of the Z80's IN/OUT commands, so clearly that's not how it works for at least one of your examples)
    – Jules
    Commented Jul 1, 2018 at 21:13
  • (I'd personally suggest that ZC160 is by far the more interesting of the projects, but that could just be my personal perspective)
    – Jules
    Commented Jul 1, 2018 at 21:19
  • @Jules I agree, the virual address structure of the c-Z80 is a clever design implementing a compact high level interface in a compact and fast fast way using the capabilities of a certain Z80 instruction. It reduces the classic charout routine to a single Z80 instruction.
    – Raffzahn
    Commented Jul 1, 2018 at 21:48
  • A Commodore 64 with an Individual Computer's Turbo Chameleon Cartridge outputs VGA by providing VIC-II hardware emulation running alongside the actual VIC-II. The CPU/software never sees any difference.
    – Brian H
    Commented Jul 1, 2018 at 22:26
  • You don't even need a CPU. Ben Eater put out some videos in 2019 on how to output VGA using just discrete logic and breadboards: eater.net/vga Commented Apr 16, 2020 at 5:34

4 Answers 4


Preface: The question sounds as if you're missing a basic understanding of interfacing and communication between different chips/systems. At the core it can't be answered without a whole course in digital electronics 101. So I can only try to give some hints to understand the various concepts presented.

I've come across a couple of projects that manage to get VGA working with the Z80 and similar CPUs [...] and many others by searching for "VGA + cpuName"

To start with (*1), the term VGA is very loosely used here in describing something with a resolution between 2000 and 500 lines at a line rate of (or near) 31.5 kHz with a horizontal resolution between ~300 and 700 pixels. So roughly what can be displayed on a VGA screen

None of the projects mentioned is using a 'real' VGA as the title of your question may imply. Even more, the term VGA is by no means meant to describe the interface toward the CPU or display capabilities as of a genuine VGA - and especially not tied to the 640x480 resolution that usually is assumed when speaking of a VGA.

What I can't seem to understand is how the various adapters talk with the CPU.

Like always via a fitting interface. Your three examples use different techniques:

  • A 'real' memory interface on the ZC160, where real RAM is filled by the CPU and outputted via some memory to screen interface

  • A 'virtual' memory interface on the c-Z80, where circuitry is mapped into I/O space to take address bus information as text coordinates and data bus content as characters to be displayed. How this is done is hidden within the 'VGA' controller, read the AVR.

  • A single write-only port on the Veronica to send commands to the AVR, which again manages everything on its own - just this time with some external memory to store high resolution graphics (*2)

It is easy to think of many more interfaces, not least IBM's own VGA with I/O registers and memory planes - which again can be handled via a quite varying style of interfaces. After all, that's what a system designer does: inventing interfaces between chips to get the job done.

Does one use the INT and/or IOREQ pins?

None of these, but again, it can be done if it fits the design.

The databus?

Might be reasonable for most, but the c-Z80 already shows that the address bus can be used as well - or even instead.

Is most of the talking through assembly code using the IN and OUT commands?

If the video interface is located in I/O address space then it will be IN and OUT instructions (if that CPU has some, that is). If it's in memory address space, then it will rather be a series of store (and maybe load) instructions. Whatever fits the interface.

Bottom line: There is no general description how all thinkable video interfaces work. You need to look at each and figure it out - and then decide if it's the right one for you.

After all, coming up with a clever solution to handle VGA-like output on a rather restricted 8-bit system is the real fun about designing such a system - that's what tickles the engineer sense of a hardware nerd.

*1 - To really start with, a 6502 isn't anything similar to a Z80 - they both define opposite ways to build a 8 Bit CPU - especially bus wise, as the Z80 follows Intel's design, while the 6502 features a Motorola bus.

*2 - The AVR on the c-Z80 only does a character-based 40x33 display.

  • 4
    "To start with (*1), the term VGA is very loosly used here" .... I think it's being used in the sense of being compatible with the electrical interface used by the original IBM VGA card to talk to a monitor, i.e. component analogue video with a bandwith of roughly 25MHz and standard TV-like sync pulses on separate lines.
    – Jules
    Commented Jul 1, 2018 at 22:25
  • 4
    My point, isn't it?
    – Raffzahn
    Commented Jul 1, 2018 at 22:34

The Veronica uses an 8-bit memory mapped port to send commands from 6502 CPU to the AVR that generates VGA output. Commands can only be sent during the blanking periods and the port ca be read by the 6502 CPU to find out when that is.

The ZC160 uses a second Z80 in combination with custom programmed GALs to generate the VGA output. A comment says that it was planned for the main Z80 to communicate to this second Z80 through an shared 8K memory region, but the blog was never updated to indicate whether this was actually implemented. The shared 8K region would also be only available during blanking periods and the main CPU would be sent an NMI when this occurs.

The c-Z80 uses large range of I/O mapped ports to send commands to the ATMega. Each port represents a different 40x33 text character cell. Writing an ASCII character value using an OUT instruction to one of these ports displays that character at the corresponding screen position. The c-Z80 VGA adapter can only process these writes during blanking intervals and so the Z80 CPU's /WAIT signal is used to prevent it from writing anything else until it ready again.

Interestingly none of these VGA implementations use the same shared memory frame buffer solution most classic 8-bit retrocomputers used, or for that matter that modern video cards use.

  • 1
    Of course not, address space is a premium on 8 bit system, and modern frame buffers are way larger than a classic Apple IIs 8 KiB. A great playfied for innovative solutions.
    – Raffzahn
    Commented Jul 1, 2018 at 21:50
  • 1
    @Raffzahn - indeed. 640x480 with anything more than trivial colour is way too large to fit in an 8-bit system without playing around with banked memory, or similar. At least, it is if using it with a standard framebuffer. One approach (reminiscent of the later 8-bit Ataris) would be to have a list of display regions with different types of memory organisation -- so the display system processes a block of descriptors that say this section of memory has colour graphics, this section is 2-colour, this section is text-only, and so on. Much more complicated than any of these systems, though...
    – Jules
    Commented Jul 1, 2018 at 22:16
  • Well, yes, but that requires a lot of 'intelligent' hardware. I'd just go a palette aproach. With 64 KiB it's possible to do 640x400 in 4 coulours, wich isn't bad - and it allows further to use the remaining RAM to store for each line an index to allow a different set of colours per line. This already good for quite impressive graphics. Going down to 320x400 might allow 16 colours or 4 colours but different palettes for every 4 pixels in a row. both modes aren't realy hard to build and should allow impressive pictures using the right encoding that is :))
    – Raffzahn
    Commented Jul 1, 2018 at 22:27
  • A high-resolution RGB display could, with a reasonable amount of hardware, be mapped into 256 bytes of address space in a way that would allow more efficient access from a 6502 than would be possible using simple linear address space. Use one group of 64 bytes for address and control registers, one for accessing 64 red values, one for blue, and one for 64 green. The basic principle would be that code writes 4 bytes with either XY or YX values and sets a mode control bit to indicate which it's using. The upper 192 bytes of address space would then access RGB values from a 64-pixel...
    – supercat
    Commented Jul 2, 2018 at 17:00
  • ...horizontal or vertical stripe starting at the specified coordinate. Using a bit more address space could allow things to work smoothly in even more usage cases (e.g. expand the "window" to 256 bytes rather than 64, or add a 256x8x3 palette RAM and have a region where writes set R, G, and B simultaneously to one of 256 colors). Having a large linear address space is often not as helpful as being able to set a base pointer and then use shorter indexed addressing.
    – supercat
    Commented Jul 2, 2018 at 17:04

The Amstrad PCW16 has a display that's VGA-compatible at a hardware level. The built-in mono monitor shows the green channel; there's also silkscreening on the circuit board for a DE15 VGA connector. At least one hobbyist has populated it so it's known to work.

From the Z80's point of view, there's a table of 480 words at a fixed address (0x3C00 in RAM bank 3) giving, for each line, its start address and colour depth: mono 640 pixels, 4-colour 320 pixels or 16-colour 160 pixels.


This videos show general idea how build VGA graphics card for bread board computer "World's worst video card":

Should work for any micropocessor.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .