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.

Saturday, 28 December 2024

Freebee Fremium Production Release

I've spent a week or so of my holidays getting the Freebee Fremium design ready to go out. I am hoping that the changes I've made to speed up video RAM access work without a further respin, so have done all the little clean-up bits that one does in moving from prototype to production. Most of the changes are subtle, intended to improve buildability, such as:

  • Adding part descriptiors under all the ICs, and in lovely inverse font too.
  • Moving the two keyboard scanning ICs up just a little, to give a bit more gap to the keyboard stabilisation bar.
  • Cleaning up the designators for the jumpers, so they're from A-Y across the board, making them a lot easier to find.
  • Integrating a tiny speaker on the PCB.
  • Adding a QR code with a link to the design files.
  • Rationalising the number of decoupling capacitors, plus moving 100nF ones to spots where they'll do the most good.

In terms of actual changes to the way the machine works, we have:

  • The improvements to CPU video access, as discussed previously.
  • Bringing the BSTB and BRDY signals from the PIO out to the GPIO connector in addition to the ASTB and ARDY signals plus port A0-A7. This subtle change allows using the GPIO connector as a high-speed synchronous bidirectional port, using PIO mode 2. I've got this idea for plugging things (generally involving an Arduino Nano) into the GPIO port that allows such things as super fast USB comms with a computer, SD card interface, etc etc. However as the Arduino Nano is sure to be obsoleted in about five minutes and become impossible to get, I don't want to design that onto the main board.
  • Allowing the machine to invert VSYNC, by simply changing the video starting address in the CRTC (much as is done for small fonts). This gives us the ability to pretend our video is EGA rather than CGA. Without changing our dot clock to 16.257 MHz we can't make full EGA resolution, but we do (I think!) have enough video speed at 13.5 MHz to do a 466 x 350 (58 x 25 characters with an 8 x 14 font). This is actually kinda special, as this means the pixels are pretty close to square.
  • A caps lock LED. I just connected this to LV6, an unused port bit.

There's also a couple of small mechanical changes, mainly around pushing the DIN connector back a few millimetres to get it in line with the D connectors. This necessitated making the PCB a bit bigger, and adding small notches to clear the tabs either side of the DIN connector on the Microbee case. I suspect that Applied Tech originally planned to do just this, but the cost of putting the notches in to the PCB put a kaibosh on that, and instead they just moved the DIN connector back into the case a bit.

A couple of screen grabs of the 3D model:

And the schematic pages:

Design files are on my google drive.

Here's the first one mostly assembled. I've had to steal a few ICs from the prototype, and have made a Digikey order for replacements. Mouser didn't have the 9 pin video connector in stock, so hence Digikey. I've decided to go with Gateron brown keyswitches, as whilst the Cherry MX blue ones feel divine to type with, they're shockingly noisy, meaning I can't play with it late at night. Now that I'm writing software for it I need to be able to use it in the wee hours. The brown ones still have a tactile feel, but without the click noise. I'm resisting the (strong) urge to rip other things apart to harvest parts to complete this.

And complete. There are two issues with the board, requiring three bodge wires to make it work. The first is a rookie mistake. Doubling the video RAM access rate means that the eighth slot is now CPU, not character. So using a simple 3 input NAND gate on the clocks to generate a low pulse for load means that it occurs after the character read. We must load the shift register on the /CHCK (seventh) instead. So cut the /LOAD net source (IC46 pin 12) and instead use /CHCK (IC4 pin 9) to drive the /LOAD net.

Additionally, the phase of the dot clock is incorrect relative to load. This didn't matter for the lower speed access, as the character read was enabled in the cycle prior to needing it. Now we've only got one cycle, and need that whole cycle to allow for address setup and read to propogate through the video RAM. By inverting dotclk for the shift register the rising edge of dotclk is now coincident with the end of the /CHCK pulse, giving us ample time for the video read.

And running at an unprecedented 13.5 MHz, using a 20 MHz Z-80, doing video writes and everything.

Saturday, 21 December 2024

Getting Freebee Premium to run at 13.5 MHz

Late model Microbees generally run at a 3.375 MHz CPU clock. The Peter Broughton 512K OS included a scheme for doubling that to 6.75 MHz, which was generally problematic. I really want Freebee to run at either 3.375 or 13.5 MHz - ie a full four times the original speed - selectable by software. On the prototype I was cowardly and included a jumper so that the fast speed could be jumpered to either 6.75 or 13.5 MHz.

Turns out the jumper was a good idea, as I simply can't get video CPU read and writes to work reliably at 13.5 MHz. Everything else works a treat (for example talking to the CRTC and the PIO, plus normal memory reads and writes). Additionally my video arbitration logic stops CPU access until the retrace period, so often there are whopping great 60usec long access times.

I've been working on a scheme for more rapidly swapping from CRTC access to CPU access for the video RAM. It involves doubling the RAM access speed (again!), and inserting a CPU access in between each video access, so screen, cpu, attribute, cpu, colour, cpu, character, cpu etc.

Life is complicated with the Z80 because unlike a 6800 it does accesses across multiple clock cycles. Morover, the accesses are wildly different for opcode fetch and other reads, incuding a requirement that the data is valid on the rising edge of the CPU clock for opcode fetch and falling edge of the clock for data fetch. Go figure.

So here's the scheme I'll be prototyping to make that work. It involves separating reads and writes out. Writes are just done via a straightforward buffer to isolate the CPU data bus and the video RAM data bus, but for reads, we use a register to hold the data from the memory, clocked at the end of the (short) access cycle, and present that data to the CPU data bus for as long as it needs it.

The flip-flops that hold the CPU in wait until the retrace period are gone, and replaced with a straightforward 1 clock wait state generator. This is needed to make the CPU wait long enough for data at 13.5 MHz.

Now to design this into a new PCB. I've ditched a component in the old wait state generator, but added one in the data bus flip-flop, so it should be even in terms of component count.

Saturday, 14 December 2024

Freebee Pi

Just musing for now, but how cool would it be to make a simple board with a Freebee keyboard, space for a floppy controller, normal bee serial and parallel ports, plus power etc., and then just whack a Raspberry pi zero on it to do all the compute magic. Really easy, quick, and cheap to build, and gives the hardware bee experience but using an emulation in the Pi, so it just plugs into any old HDMI display.

And showing how I randomly change directions in stuff like this. I bought a very cool Keychron keyboard recently, ironically with the intention of having soimething I could steal keyswitches from, as it's keyswitches are socketed. It's a cool keyboard (I'm actually using it now). But as well as the socketed keyswitches it does really nice bluetooth, so I can use it anywhere. Of course I pulled it apart and it's got an little processor that does the work with a bluetooth module.

This leads to some inevitable interwebs research, and I found that there's whole libraries of HID (keyboard) stuff that's completely open source. And Adafruit do a phenominally awesome ESP32 "Feather" module that has integrated USBC and Bluetooth, that has all the brains I need. Further wandering around the Adafruits website showed me the Adafruit floppy wing that does a whole floppy interface WITHOUT NEEDING A FLOPPY CONTROLLER! (Please excuse the shouting).

But once I've spliced the floppy interface onto the feather, I haven't got enough GPIO left for my keyboard... What to do? A bit more searching shows the incredibly well supported MCP23S17 16 bit SPI IO expander, which is like a Z80 PIO but with an SPI interface to the processor.

So now the whole direction of the project has changed. What if rather than just doing a Microbee clone in a Raspberry PI, we instead do a PC/Mac/Linux/Whatever peripheral, that can connect via USB or Bluetooth, that gives the host access to Microbee floppies (ala uBeedisk), a Microbee format keyboard, Microbee tape I/O, Microbee compatible serial connector, and even the 15 way GPIO port. Just plug it in (or pair it and get the power from a normal Microbee plug pack), and play. You can use it as a keyboard (I'm that perverse) or run a uBee512 and use it as the keyboard for your emulator...

This is what the board is looking like so far. There was a bit of extra space so I added a second feather device. This can be an OLED display, or sound interface, or really whatever you want. I've tried to limit the use of GPIO as much as possible (using the SPI expanders) so that most of the GPIO pins are free for use by the feather.

Friday, 15 November 2024

Writing an unencumbered boot and monitor ROM for Freebee

One of the more irritating features of working with Microbee stuff is that much of the software is copyright, so I can't distribute it with Freebee unless I get the permission of the copyright holder.

Even worse, much of the recently developed software has been built on disassembled versions of copyright software, so also can't be distributed.

The solution to this is to just go back to first principles and write stuff from scratch. In principle it should be possible to write a CP/M boot ROM and a basic ROM that's compatible but doesn't share the code, in much the same way as with PC clone BIOS ROMs.

This is a big job, but like eating an elephant the trick is to do it one bite at a time and just write code that can be useful. I'm not a programmer, so this is also a learning experience for me.

So let's start with my boot ROM, which until recently just loaded fonts and then dropped into (proprietary) basic. A monitor is a super useful tool in ot's own right for debugging, but as well as that it needs routines for keyboard input, screen output, tape IO, serial IO, etc., which can potentially be repurposed for more ambitious works.

After a week or so of work I have a couple of cool things happening. Firstly a splash screen and boot menu:

And secondly the beginnings of my monitor.

A little more work has a routine that when given an address, displays 32 bytes before and 224 bytes after the address, for a total of 256 bytes. You can move around the memory using the up (back 16 bytes), down (forward 16 bytes), left (back one byte) and right (forward one byte) keys. You can also enter an address using E XXXX where the address is a 4 digit hex number, and the display jumps to that.

I need to generalise input, as the whole checking every keystroke thing is getting bloody tedious. I think a routine to allow entry of a line of text, terminated with a CR character would be just what the doctor ordered. Then I need to parse the text input to determine what to do, and figure out what commands I want the monitor to recognise.

I also need to keep track of what memory is banked in where. There's plenty of space in the bottom right of the screen where I could display current PCG bank, status of boot bit, status or ROMRD bit, status of colouren bit... Then of course I need commands to actually change these, plus (in the case of the boot bit) a way to survive that, as the ROM that's being used for the monitor gets paged out of existance when I deassert boot. Perhaps I could LDIR a short routine to video RAM to do the bank swap, pull the data needed from RAM, and swap back.

Also using PCG bank zero for my scratch and stack isn't so great. Perhaps I could move these to PCG bank 15.

This is seriously good fun though. I'm learning so much about Z80 assembler doing this.

The absence of an up arrow character in the motorola font ROM prompted me to create a new one, including an up arrow plus lots of other stuff from the IBM CGA font ROM, and bold font. It looks so cool. My monitor code now allows me to show the contents of any address, go (call) code at a given address, and has a really advanced edit function where I can edit any memory, move around with arrow keys, and even do relative jumps based on the memory location. And thanks to the bold font it looks really cool.

I've also worked out that my Dell 2001FP accepts the CGA signals without upscaling - all I need is a few resistors to get the levels right. Compare the picture above to previous ones - it's so clear!

I've added code so that I can set the various bank variables (believe it or not there are ten of them!) so that I can show and edit the appropriate bits of memory. The bank variables don't evvect operation of the monitor - it operates in boot mode with pcg 7 most of the time so it has somewhere to store it's stack, but a lot of the time we'll want to view and edit memory that's not shown in these modes. In this case, the edit and display routine will chack where in memory we're working, then set the relevant bank so that we see what we want. Assuming that isn't boot/pcg7, we'll have to be really careful to ensure we don't accidentally pull the code out from under us, so I envisage some copying of code to video ram for execution when we're out of boot mode. For now we're just able to edit the variables using "bank whatever xx".

I've also written a help screen, which can be accessed by typing help. This screen uses as much EPROM as the whole monitor!

Friday, 25 October 2024

Preparing for the Perth MUG meetup.

So I've got some leave, and asked on MSPP if anyone was keen for a Perth Microbee Users Group (MUG) meeting. I have an ulterior motive. I never did get my compact flash coreboard working, as the software build side leaves me flummoxed. In my defence, it appears that my Mac lies about the geometry of compact flash cards.

Now people are going to come to my house. This is just the incentive to get going again on the Freebee Fremium prototype so I have something to show, and (much scarier) to tidy up my sewing room.

The sewing room comes up quite nicely. It didn't hurt that I did a purge on eBay recently (scoring nearly $2K!) giving me some much needed space for new projects.

Here's a photo of the whole FreeBee family. It's a sneak preview of what I'll be showing off at the meeting. I've got free open source versions of both disk/CF and ROM based coreboards, plus both standard and premium mainboards. The premium mainboard is able to go at four times the speed of a microbee, and runs everything I can throw at it.

Tuesday, 16 January 2024

EmuROM - An Open Hardware ROM emulator

Back in the nineties I spent a couple of years doing embedded system design, plus developing ISA and EISA cards. We had some cool tools for working on embedded machines, one of which was a ROM emulator. It was a plastic box with a ribbon cable hanging out one end, and a PC parallel port on the other. You could remove the ROM from a target system and plug it in, and load the ROM image into RAM inside the device under control of your PC. It made messing about with ROMs really straightforward.

Anyway, I'm messing about with ROMs now, and find the whole remove-erase-program-reinsert thing tedious, especially when my EPROM programmer only works on my old XP machine, which due to it's fragility isn't networked, which in turn means all my code has to be stuck on a USB stick to transfer to the programmer.

So I went looking online for ROM emulators. I found almost the perfect device, by John Tsiombikas. A straightforward board with a little Atmel microcontroller loading a RAM chip with data, which in turn is gated to the host machine using some tri-state buffers. Even better, John has released the whole lot under a Free Hardware and Free Software licence, allowing anyone to take his design work and play with it as they wish, as long as they in turn release their work under the same licence. And it's in KiCad!

Works for me! I took John's board and started by dropping support for 24 pin ROMs. If I ever need to emulate 2732's etc, I can aways do another board. As it's so tiny and I wanted to ensure good signal integrity on the host machine, I did away with the ribbon cable and mounted it via a 90 degree header and adapter board directly to the machine. I did a little work on the layout to reduce the size of the thing and neaten it up, including hiding the host tri-states under the RAM, which is socketed.

In any case, all the design files are on my google drive. I haven't yet updated the software, but am envisaging extending the firmware a bit so that no software is needed on the controlling PC aside from a simple terminal program, with EPROM code downloaded via X-modem, and perhaps even a simple monitor program. I do most of my work on a Mac, and like to use existing software (like serial-ii) as much as possible.

Here are the files.