Saturday, 15 March 2025

A second stab at a ROM Emulator, using a Teensy 4.0

After assembling the ROM Emulator using an ATMega and some RAM, I had issues getting it going. I could connect to the emulator using a terminal, and could change bytes on the ROM, but the software to download an image didn't work.

I put it to one side and did other stuff - notably getting MCLZ8 running on Freebee. I found the process of working within the Arduino IDE to control MCLZ8 as a debugger extremely enjoyable. I implemented commands to examine and change memory, do port I/O, examine and change the Z80 registers, start and stop the machine, and even do breakpoints. Many of the good stuff from NICE, running in a Teensy plugged into Freebee.

So then I saw that Microcore Labs also had an EPROM emulator, running in a Teensy 4. Unlike the ATMega EPROM emulator, we're not dependent on some code running on the host to transfer a file to the emulator. We just convert a binary file to a C array, paste it into the code for the emulator under the Arduino IDE, and hit the compile and upload button.

So I knocked out a better interposer board to go under the Teensy based on the Microcore Labs one, and had a play.

Great news is it all works! I can run an emulated Z80 on Freebee with emulated ROM as well.

There are, however, a couple of points. Firstly I had to overclock the Teensy 4.0 to 900 MHz or better to get it to run reliably with the emulated Z80. Note this is probably due to me fiddling with the Z80 emulation to get _that_ to run at 3.375 HHz reliably. I skip a wait for rising clock on the opcode fetch, as the Teensy was often not making it, meaning the teensy was very slow. By doing that though I suspect I occasionally get very fast opcode fetches, which the relatively slow emulated ROM can't reliably make. Oh well, overclock the hell out of it to make it work.

Second point is that the Arduino IDE doesn't like to simultaneously talk to multiple Teensys. This doesn't seem to affect the code upload - just select the Teensy appropriately, but it does affect console. I need console to drive my debugger. I found a cool tool - TYCommander, which gives me a console independently of the Arduino IDE which lets me control the emulated Z80 while the emulated ROM is also plugged in.

Links:

Wednesday, 26 February 2025

Keep it simple, stupid! A straightforward boot ROM for Freebee

I've been inflicting my buggy boot code with monitor etc on people, which is making their experiences in building Freebee more difficult. It's exacerbated by not distributing basic with the code, as that's copyright Microbee. I had one person wondering why it didn't do anything when he powered it up. After some faffing around, I asked "so did you patch basic in?" and it turned out he hadn't done that.

So I've generated a much simpler ROM that just copies the fonts in, then checks for the presence of basic (just looks for a C3h at 8000h). If it doesn't find that, it displays a helpful message as follows:

I shall put the new code, with a binary (not including basic!) in with the other design files.

Saturday, 1 February 2025

MCLZ8 on Freebee

So it turns out you can emulate a Z80 using a Teensy 4.1. Better yet, with the aid of a few voltage translators on a little interposer board, you can plug the teensy into your Z80 machine and run using the teensy as the processor.

This is kinda huge - the sky's the limit for the debug ability that comes from being able to interrogate everything that's happening at processor level over a dead-basic USB connection.

Luckily, Freebee doesn't need no stinkin' coreboard to run as a basic 32K bee, so the rather tall Teensy + interposer board is no impediment. However the interposer board as layed out on the Microcore Labs website was a bit bulky, so I redid it so it fits neatly under the Teensy. This means a third board is also needed to get back to the normal 0.6" pin pitch for the Z80. I guess I could have used an SMD connector for both Teensy and Z80 socket, but it's easier with through-hole here.

Then we download the MCLZ8 firmware, install the Arduino IDE + Teensy loader, compile the source, and upload the code to the Teensy. And just like that, we have a Z80 hardware emulator in software.

Thursday, 2 January 2025

An STD Bus Video Card that does CGA and EGA resolutions

With the latest release of Freebee Fremium, I added circuitry to invert VSYNC. This is useful to convince a multisync monitor (or upscaler) that you're doing EGA timing (16.67ms vsync, 45.76 µs hsync) with 350 vertical lines. On Freebee I can't just up and change dot clock to do full EGA resolution though, as the one crystal is used for both CRTC and CPU timing, and swapping the CPU to a different crystal is likely to hit it with a very short clock and crash it.

Independently, my brother Doug (yes, the madness runs in the family) has been working hard on STD bus cards. He's created a design for a Z180 CPU card, which even runs ROMWBW (hey Doug, send me a link to a blurb on your CPU card). I reckon it'd be a lot of fun to combine the two - graphics and STD bus. It's sort of reverting to the microbee roots, where it was a collection of S100 cards, but this time STD bus (as it's smaller) and still plenty big to put what we want on the cards.

My idea is for a simple three slot STD bus backplane, housed in a small Hammond enclosure (like the one for my floppy drive that I show in various places on my blog). One slot would be for a video card, one for a CPU + menory, and the last slot for other I/O (floppy disk etc). I'm getting away from the strict microbee compatibility, but who cares. In my mind as long as I can run CP/M and patch other microbee code to make it work, that's good enough.

So on to this design. It's a refactoring of my current Freebee Fremium video hardware, but I've added the ability to swap dot clocks between 13.5 MHz (or 14.31818 MHz if you have no interest in microbee stuff) for CGA, and 16.257 MHz for EGA. I've rolled all the various kludge bank selects (colour, char ROM etc.) into one port, and changed the port addressing such that the whole lot sits in four contiguous port addresses, then used a '688 to allow the card to sit anywhere in port space.

Addressing with STD bus is a bit harder. STD bus was developed when 64K was huge, like S100. The developers came up with a signal, MEMEX, that allows for expansion beyond 64K, but were pretty unimaginative as to how that's used. They envisaged it driven from a port bit on the CPU card to select a different 64K bank. The video card needs 4K of address space from F000-FFFF, and does a lot of bank switching in this spot to allow access to all the various memory in it's 32K RAM, so would work with that.

Alas more modern STD bus CPU cards generally have memory on board, and often large amounts, like 512K. They do their own bank switching on the card, and ignore MEMEX. After all, why would you need off-card memory when you've got 512K on the CPU card. This holds true until you want to build a video controller, you numpties. So the MEMEX line is problematic. I drive MEMEX either high or low (jumper selectable) when the video RAM is banked in to allow a memory card to deselect it's own RAM. I also allow MEMEX to be used as an input to my card (another jumper), and only enable the RAM if MEMEX is high in this case. If your card doesn't respect MEMEX than you'll need to make some changes before you can use this.

I knocked the board layout over in a couple of days of design frenzy. My productivity with Kicad always amazes me. It's such a wonderful PCB tool. Granted, much of the grunt-work was already done by copying and pasting from the Freebee design, but still.

It was a bit of a squeeze though. STD bus cards are 6.5" long and 4.5" wide, but once you respect the edge connector and card guide allowances, you've actually got about 6" by 4.2" to work with. I squeezed some 43 ICs into this space. Along the way I had to drop spacing between rows to 0.15", and revert to modern round pads. I also went with (sacre bleau!) surface mount decoupling caps (and resistors), so it's got a bit of a late eighties feel to it. So no rounded tracks either. I actually briefly toyed with six layers to get the thing to route, but eventually got it down to four. The difference in price from four to six layers is a factor of two, so it's sensible to stick to four if at all possible.

And schematics:

Design files are on my Google Drive.