Another "Retro-New" system - Cerberus 2080: Z80 and 65C02 + VGA on the same board

Just seen this project:

Cerberus 2080

and offered to port a BASIC to the 65C02 side of it… No guesses for which BASIC - although it won’t be porting the BASIC as such, more porting my OS that is needed to support my BASIC of choice…

It’s an interesting design - retro for using the 65C02 and Z80, but modern in a sense in that it uses 3 x 5v CPLDs for the glue and video circuitry. Video is 2KB for a 40x30 resolution character based display (with another 2KB to store the font data). this video memory is dual-ported so removes any clock issues between the 65C02 or Z80 and the VGA output.

There is also a “master controller” which is an Atmega328p (same MCU as Arudino).

So it’s a very interesting mix of old + new in one mini-ATX sized board.



Interesting indeed! I note they’ve chosen to design the CPLD in logic gates rather than an HDL, for some extra authenticity.

The dual-cpu thing is an either-or, although the monitor lets you switch from one to the other seamlessly. Which leads to the challenge of writing a program which is valid for both CPUs…

I’m glad to see that it boots into 6502 mode though!


… But a binary that might run on both, unchanged? That would be a real challenge! Of-course, having BBC Basic on both CPUs will be nice, but I don’t know if the 6502 and Z80 version share the same binary format.

Anyway, both can run at either 4 or 8Mhz, so compare and contrast 'till the cows come home…


I think you’d only need a few bytes which were valid for both, which manage to branch different ways, then cpu-specific code can jump to a clean copy of cpu-specific application. (An auto-detecting fat binary)

I think we know that a Z80 (of the original type) needs 3 or 4 clocks per memory access, compared to 1 for the 6502, and so even at 8MHz the Z80 would be expected to run slower than the 6502 at 4MHz. Only a pi program can tell us the answer… [or any other benchmark]

1 Like

Note that a Z80 will start executing code at $0000, while a 6502 will startup by jumping to the address pointed to in $FFFC, $FFFD.

This is an uncomfortable combination, because a Z80 computer would ideally have ROM at $0000, while a 6502 only operates efficiently if zero page is RAM.

This friction could be solved in a number of ways, like banking or starting up in 6502 mode. With RAM in zero page, the 6502 code might copy some ROM into zero page before switching to Z80 mode.

1 Like

I’m glad to see that it boots into 6502 mode though!

I like you, Ed, so I’ll forgive that :slight_smile:

Who am I kidding? I like 'em all. If you can flip between them quickly it’d be very interesting to see what the fastest 6502 + Z-80 programs would look like.

Lot of different ways to have a common code sequence that can distinguish between Z-80 and 6502. Here’s one that is fairly compact and flexible:

18 05 00 4C xx xx 00

For Z-80 it’s just a “JR +5” so the Z-80 code can begin at byte 7. In 6502 it’s CLC, ORA 0, JMP xxxx so put the 6502 code at xxxx.

No doubt there’s some better sequence. If the address of a jump is know it is quite possible to select it carefully so the one processor executes it safely. For example, JMP on the 6502 is $4C which is “LD C,H” on the Z-80. A 6502 JMP $4040 would be seen as “LD C,H; LD B,B; LD B,B” on the Z-80.

$00 almost works but you need to set up the 6502 BRK vector ahead of time.


The “BIOS” in the host MCU (ATmega 328p) in this system manually pokes the boot vectors (6502)/$0 JMP (z80) to force code to start at the same location ($0202) in both CPUs. (There is no ROM)

This is a bit weird for most systems but it seems to be what the designer wanted.

However I will be looking at the code in the host MCU and I know that the chap doing the Z80 side of it also wants to make some changes to it, so something could be done, if needed.

Once one CPU (Z80 or 6502) is running there is no way for that CPU to switch to the other CPU - yet. It seems possible, but the interface to the host MCU is changeable so it may be possible. Who knows.

Overall, it’s an interesting system - aimed at education - sort of nice to have both CPUs on the same board so who knows what happens. My suspicion is that like a lot of projects like this it will depend entirely on the uptake - if a nice active community springs up (like e.g. Gigatron), then who knows what will happen in the future.


1 Like

Interesting. I’ll admit that the only CPU switching system I’m familiar with is the Commodore 128, and I actually haven’t ever tried out the Z80 on my system even once.

1 Like

Very nice!

Edit: a fat binary could load (or relocate) the z80 application at the bottom of user memory (with the workspace above) and the 6502 at the top of user memory (with the workspace below.) Or, as I mention relocating, the two application could be just one after the other, with the later one block-moving itself down to 202 if it’s the active one. And then, in both case, the workspace would be immediately above the application.

(Acorn’s Beeb can take a z80 as a second processor, but there’s no memory sharing so it’s rather a different animal. The C128’s Z80 does, I think, have full access to very nearly all the same resources as the 6502 - lots of detail here. I think the two CPUs are mutually exclusive, though. And, only the 6502 can flash the caps lock LED…)

1 Like

The Microsoft Softcard (and clones) for the Apple II also puts the 6502 and Z80 on the same bus. Indeed, due to the fact that early NMOS 6502 processors are not fully static, it periodically yields a few cycles to the 6502. Since the Apple II doesn’t require DRAM refresh, it uses the built-in Z80 refresh timer for this.

The Softcard handles the layout differences between the two processors by simply inserting some discrete logic and crossed wires to remap memory. It was designed for CP/M, and portable CP/M programs require more or less contiguous usable memory from address 0 to the end of available RAM.

Programs using the softcard can switch back and forth from the 6502 (indeed, the 6502 continues to handle things like disk access), but I’m not sure this was ever used much in practice. Since the RAM is shared, it’s more or less a pass-the-baton situation.


Crossing or inverting an address line or two was the first strategy that flashed into my mind as well …

1 Like