3

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?

  • 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 Jul 1 '18 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 Jul 1 '18 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 Jul 1 '18 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 Jul 1 '18 at 22:26
7

Preface: The question sounds as if you're missing a basic understanding for 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 loosly 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 resulation between ~300 and 700 pixels. So roughly what can ge 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 ment to describe interface toward teh 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 fiting interface. Your three examples use different techniques:

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

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

  • A single write only port ont the Veronica to send commands to the AVR, which again manages everythin 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 at least the one of IBMs VGA with I/O registers and memory planes - which again can be handles 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 rasonable for most, but the c-Z80 already shows that the address buss 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 wil lbe IN and OUT instructions (if that CPU got 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 for you.

After all, coming up with a clever solution to handle VGA-alike 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 realy start with, a 6502 isn't anithing similar than a Z80 - they both define oposite ways to build a 8 Bit CPU - especially bus wise, as the Z80 follows Intels design, thilw the 6502 features a Motorola bus.

*2 - The AVR on the c-Z80 does only 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 Jul 1 '18 at 22:25
  • 3
    My point, isn't it? – Raffzahn Jul 1 '18 at 22:34
3

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 Jul 1 '18 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 Jul 1 '18 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 Jul 1 '18 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 Jul 2 '18 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 Jul 2 '18 at 17:04
-1

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.