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.

Monday, 15 January 2024

Metcal MX500P soldering iron repair

I've been giving my soldering iron something of a flogging of late. It's a Metcal MX500P, one of the very finest irons ever to be made. It uses 13.56MHz RF to heat a teensy inductor right in the tip, with an incredibly ingenious temperature regulation system whereby a magnet in the tip, once it gets to temperature, hits it's Curie point and loses magnetism, changing the frequency the coil resonates at and thus making it get more or less hot with the applied 13.56 MHz. In any case, yesterday it simply stopped getting hot. I found an extremely good on-line analysis of the soldering iron here., and mention of dead driver transistors. in forums.

In any case, I opened it up and had a look, and there was a pretty obvious popped capacitor:

It's C4, a 330n 63V film cap that just does smoothing on a DC rail. Here it is after removal:

I replaced it with a 330n 100V one, and voila.

Saturday, 6 January 2024

FreeBee Premium

This one is the logical progression of the FreeBee, just as the Premium (aka alpha) was the logical progression to the Microbee.

Indeed, the whole objective of the Freebee design is to get to this. I've had this idea of a massive simplification of the microbee video hardware in my head for literally decades, with the idea of wrapping the screen data back to the same RAM to get character data. This worked a treat with the Freebee. Now let's go nuts and access the sama overworked RAM no less than four times for each character. First we get the screen data, then attribute data, then colour data for a given character, then we use the screen and attribute data to look up the relevant character data on the fourth and last access.

It's a lot more complicated than Freebee. There's a whopping 57 ICs crammed into the main board. However like Freebee, it's a whole computer that doesn't need a coreboard to function. This makes debugging so much easier, as I don't have to muck about with coreboard extenders. It's got 32K of general purpose RAM alongside the 32K of Video RAM, plus 64K of EPROM, so it can load it's character data up and boot into standard Microbee 5.22e basic without adding any other boards. Of course it's totally compatible with Microbee coreboards, as well as SuperPAK and the Compact Flash coreboard.

To route all this extra complexity, I had to go to 4 layers. This makes it more expensive than Freebee, but not ridiculously so. Still done with gorgeous rounded tracks so it looks like it was done in tape.

I've added the ability to run the CPU off either 6.75 or 13.5 MHz in turbo mode, so (hopefully) with the right CPU this'll be the fastest bee on the block. In order to make that work with the glacial speed of the 6545 though, I've had to add a pile of wait states on I/O access.

The need for a 74LS open collector part to scan the keyboard always annoyed me, so I've used a bog-basic CMOS '138 instead, and added some diodes so it can't source current.

The PIO and tape circuitry is totally unchanged from Freebee.

There's not a lot to say about the coreboard connectors. Note there's no sensing of ROMSEL from the coreboard - the boot code needs to figure out where to jump after finishing the boot routines. It's always 8000h except for the annoying 56K CP/M coreboard.

Here's the core of the design - the video memory. One 62256, one data bus transceiver, several sources of address (CPU, CRTC, screen+attribute)... The key is wrapping around to get the character data sorted out.

There's some glue to make the screen sequencing work, and to allow CPU access. As with Freebee, CPU access is denied until the screen is in retrace. As with Freebee, there's no stinkin' PLDs.

On a whim I added a sound chip. This was never really supported on the Microbee hardware, and can simply be left off the board.

Finally the CPU and memory. Much the same as Freebee. The machine boots in boot mode, and the character font is copied into character RAM before the boot ROM pages itself out of existance. There's some jumpers to enable mainboard RAM and mainboard ROM above 8000h, in case you're running without a coreboard.

Here's a pic showing build of the prototype. It went together quite nicely.

And first boot. There was a stuff-up necessitating a bodge wire where the video output latch was not enabled. Additionally composite output (shown on the left-hand monitor) is inverted. Nothing that can't be fixed with more bodge wires! My mind is totally blown that my video sequencing scheme worked first try.

I wrote a quick test program in basic to sequence through colours. This shows that the keyboard works (albeit using tweezers to short contacts for many keyswitches where I'm waiting on parts), it shows that the colour circuitry works, and by running inverse at the bottom is shows the PCG RAM works. So that pretty-much validates the whole video memory design.

Next step is to try loading a game from tape. Emu Joust won't cut it, as it's monochrome. Gotta be Kilopede.

After inverting the pixel data for composite output and playing with the resistors for composite video (I ended up with 330Ω for pixel data and 680Ω for intensity) I get a nice clear separation between normal and intensity on in composite:

There's a stuff-up on the prototype where i didn't connect the LV register to the video logic. This had the effect of disabling PCG over 2K. Connecting them up then caused basic 5.22e to display garbage, as the register isn't cleared on reset. I fixed that in the boot ROM, then connected a SuperPAK with 5.29e basic, which has support for premium graphics via hires2. Finally I ran the demo program from the premium basic manual:

The result is a rather cool display using all 16K of PCG. It's a premium bee!

It was agreed on MSPP that the definitive Premium test would be to run Quix-2.com. This required getting a Compact Flash coreboard running (thanks Brad!), and transferring the program from my mac using Telcom (and Serial-ii on the mac side), thus validating that my serial port works. Then we get to display a cool screensaver.

Meanwhile, the production version is pretty-much ready - just gotta do some QA. I've done a bit of placement optimisation - moving the power switch, adding a teeny speaker on the board, shrinking the big power cap...

Irritatingly, it looks like the Fremium board doesn't get on with super-fast video RAM any better than the standard FreeBee. This is with a 71256A25 - 25nsec cache RAM...

After a bit of poking and prodding, I found the culprit. /VWR was generated from /VF000 and /WR, but the address lines for the video ram are also dependent on /VF000, and they go through several gates before percolating to the actual RAM. The result of this is that the address lines don't settle until around 10ns after /VWR is asserted. With very fast video RAM this is enough time to occasionally latch data to the wrong address, with the result above.

The fix isn't as straightforward as just running the /VWR line through a couple of gates to slow it down, as this will just move the problem to the other end of the write cycle. Instead we use a flip-flop to delay the falling edge of /VWR by one dot clock (74ns), and use VF000 to deassert the /VWR line straight away (using an asynch set input to the flip-flop). The result is clean writes with fast 25ns video RAM, as well as our slow 85ns stuff.

And here are the design files.

Sunday, 24 December 2023

Making the Compact Flash Coreboard more accessible (and reliable!)

I really enjoyed the design exercise for the FreeBee main board, especially doing the whole thing without using any PLDs. It had me drawing Karnaugh maps and trying different methods of simplifying TTL logic, which I find really satisfying.

So over the Christmas break I figured I'd revisit an older project, the Compact Flash Coreboard. Last time I worked on this was back in 2016. It basically featured a compact flash socket, some RAM, ROM, Floppy controller, and three Atmel 44 pin CPLDs. The design of these CPLDs was an exercise in frustration, tracking down glitches everywhere due to the big difference in their speed compared to that of the Microbee that was running them. One of the key issues was that I convinced myself that in order to talk IDE, I needed to do 16 bit transfers, where this simply isn't the case. This greatly complicated the design.Recently however I've been reading of RCBUS designs, including a compact flash interface in just three TTL chips (see this work by Tadeusz Pycio) that corrects for timing differences between the Z80 (rd, wr, iorq) and 8086 (iord, iowr) bus, meaning it will work reliably with any smallish Flash card, not just a select few.

The board essentially replicates what my old rev 0.4 coreboard did, with up to 512K of RAM, up to 512K of EEPROM, a floppy disk controller, and the Compact Flash interface. It's the "I want to have the CP/M bee experience" equivalent of the SuperPAK coreboard.

By allowing for up to 512K of EEPROM, my hope is that the machine can run a ported version of ROMWBW, which is an unencumbered version of CP/M developed by the retrocomputing community.

I built a prototype in early 2024, fixed a couple of really obvious stuff-ups (F000 line not going back to mainboard connector, and floppy drive enables swapped) and was then able to boot both from CF and from floppy. It stalled there for a while, as I couldn't get my head around the software for creating Compact Flash images on my PC. As it turns out, my mac, which I use for dumping images to Compact Flash cards, lies about the CHS (Cylinder, Head, Sector) values for a CF card when I run fdisk. This doesn't matter for most things, but the BIOS we're using for the CF card is based on the early Microbee hard drive BIOS, which does it's disk addressing in CHS mode. In any case, Brad from MSPP to the rescue, he figured out the difficult software stuff and got a whole bag of CF cards to run. He also suggested pullups on the data lines, plus series resistors for the CF data lines as well as the IORD, IOWR, and CFSEL lines, to combat potential ground bounce issues from newer faster cards.

In any case, now the production version is ready to roll and there is huge interest. I have 35 orders already. So I'd better get the production release right!

So on to the description of how it works. Our BIOS expects a WD2793 floppy disk controller at IO location 40h, plus disk and side select latch at 48h, IDE drive at 60h, and bank select port at 50h. IC13, a 74HCT138, performs port decode into 8 port chunks, from P40h-47h, through to port 78h-7Fh.

Bank switching is performed to allow up to 512K of RAM and 512K of EPROM on the Microbee or FreeBee mainboards, in a way that works with the standard Microbee BIOS. This involves a write-only port at 50h, with the following bit assignments:

  • Bit 0: RAM bank bit 0
  • Bit 1: RAM bank bit 1
  • Bit 2: Video RAM disable. When reset video memory is given precedence in the map over all other memory.
  • Bit 3: ROM disable. When set RAM bank 0 appears in upper memory (8000h - FFFFh) and bit 1 is negated. When reset ROM bank zero appears in upper memory.
  • Bit 4: Video RAM location. When reset video RAM is at F000h to FFFFh. When set it is from 8000h to 8FFFh.
  • Bit 5: ROM bank select. When set we can use the four bank bits to select a ROM bank to appear in lower memory (0000h to 7FFFh) when ROM is enabled. When reset the RAM exists here. Note this leaves no RAM in the system except for Video RAM. This bit breaks compatibility with the bee bank scheme when set, but shouldn't matter as I've never seen it used.
  • Bit 6: RAM bank bit 2.
  • Bit 7: RAM bank bit 3.

    There's a bit of weirdness with the Microbee bank select that we have to account for as well. Essentially bank select bit 1 is exclusive ORed with ROM disable. I'm not completely sure why they did this, and it's really hard to figure out from the contradictory documentation. When the computer boots and the register is cleared, RAM bank 0 appears from 0000h to 7FFFh, ROM bank 0 from 8000h to EFFFh, and video memory from F000h to FFFFh. Setting bit 2 then sees RAM bank 2 from 0000h to 7FFFh, RAM bank 0 from 8000h to EFFFh, and video memory from F000h to FFFFh.

    The compact flash interface is composed of just two dedicated chips, IC26 and IC28. IC26B, a 74HCT32, creates a shortened IORD* pulse by delaying the start of RD* by one CPU clock. IC26A lengthens CFSEL* by a CPU clock. The two gates on IOWR* simply delay this signal by two gate delays.

    The compact flash and IDE interface exists from P60h to P68h. This maintains compatibility with the Microbee CF8 BIOS.

    I added pullups (RN1) and series resistors (RN2, RN3, R13, R16, R20) in order to minimise potential for ground bounce when using really fast CF cards, hopefully meaning the circuit will work with more (newer) cards. This hasn't been trialled yet, but can be removed by simply not installing RN1, and jumpering out all the series resistors (or substituting low value resistors.

    The reset circuit is straight from the standard SRAM coreboard. Note thet we are not asserting NMI instead of reset with jump latch, as they do for the Microbee DRAM coreboards. I believe this is done to ensure refresh is continued to the RAM. As we're not using DRAM, we don't need to do this. As with the SuperPAK board, some adjustment of D4 might be necessary depending on what supply voltage you run your bee on.

    The rest of the board is the Floppy Disk Interface. This is really only interesting if you have old floppy disks to read. There are a pile of changes from the "standard" microbee floppy interface. Firstly, The board should work (with some code changes) for either WD2793 or WD2797 FDC chips. This is done by not using the ENMF* input (WD2793) to do a divide by two on the clock. This is instead done separately using a flipflop.

    IC15 is a four bit latch at port 48h. Bit 0 selects the floppy drive (A or B). Bit 2 selects the side. Bit 3 is used to select double density (MFM encoding) on the FDC. Bit 4 (unused on the microbee normally) selects high density (8", 5.25" 1.2MB, or 3.5" 1.44MB) disks. When set it doubles the FDC clock, and selects a different set of precompensation trimpots, as well as doubling the pump frequency (by halving the capacitance on the pump pin. This is based on the FloppyIO board from MSPP.

    There's some jumpers for selecting Head Load Timeout delays. I've labelled them 3 (fast), 5 (medium) and 8 (glacial) to correspond to the varying delays that must be incorporated for various hardware.

    The last tidbit from the FDC sheet is the NMI logic. The microbee is not fast enough normally to keep up with the data rate from a high density drive. Tony Ellis did a lot of work to develop a faster FDC interface, and worked out that if you use the INTRQ output from the FDC to trigger an NMI and heavily optimise your code, you can _just_ keep up at 3.375 MHz.

    So IC20D, IC18A, and IC23B does that. When HD floppies are enabled and halt is active (ie the CPU is waiting for an interrupt), the INTRQ or DRQ output of the FDC is gated to NMI.

    The PCB design is a simple 269 x 107mm, two layer board. The Compact flash socket dictates 8 thou (0.2mm) clearance, but otherwise it's much the same as other FreeBee boards. I've taken a lot of care to get grounds low impedance, and added a 40mm IDE socket, so if you're not brave enough to solder on the 0.635mm pitch SMD Compact Flash socket, you can just buy a cheap eBay adapter and use thet.

    It's part of the FreeBee family, so has been treated to the same attention to detail as other boards from the family. Nice rounded tracks and a clean hand-done layout, with generous elliptical pads for all ICs making for ease of construction.

    It's a completely open source design. Design files are on my Google drive.

    Here's the prototype ready for smoke test...

    There is a process documented on the MSPP site for generating the CF images to work with this, as well as the BIOS ROM, in the "tech" repository, under Microbee/Software/Compact_Flash/IDE_CF_Adapter.

    Disk controller setup is as follows:

    Boot into monitor with ctrl-M (no CF card installed).

    Install a jumper across the TEST header (This has to be done after boot).

    In monitor type O 48 8. This will enable DDEN mode, but keep HDEN mode disabled.

    • Check the clock frequency (pin 24 IC19), it should be 1 MHz.
    • Adjust RV4 to make the pulse on the TG43 test point 500ns.
    • Adjust C23 to make the pulse on the DIRC test point 2µs.
    • Adjust RV2 to make the pulse on the WD test point 250ns.

    Now type O 48 18 in monitor. This enables HDEN mode, as well as DDEN mode.

    • Check the clock frequency (pin 24 IC19), it should be 2 MHz.
    • Adjust RV3 to make the pulse on the TG43 test point 250ns.
    • Check that the pulse length on DIRC is now 1µs.
    • Adjust RV1 to make the pulse on the WD test point 125ns.
  • Monday, 30 October 2023

    FreeBee - A Microbee Compatible Single Board Computer

    This one is perhaps a little more ambitious than most of my vintage comupting shenanigans. It's been rattling around my head for a good number of years, as a vague idea about how I could simplify the video hardware on a Microbee. It's had a few false starts - mainly because as soon as the design process starts I start adding things - Z180 processors, per-pixel colour, blah blah. Once I start designing PLDs in, I know it's not going to see the light of day, as I simply don't enjoy the PLD design process.

    So this time around I set myself some really strict rules. I wanted to design the least possible computer I could that's capable of running Emu Joust. Rules are:

    • All through-hole DIP.
    • Must be able to play Emu Joust.
    • Absolutely no PLDs. Really. Designing a PLD in is just a shorthand to saying "I couldn't bother doing that bit, I'll leave it for later". And the bloody things just raise the bar for everyone. So many products use a PLD simply to make them hard to copy.
    • Which brings me to the next bit. Open source.
    • A machine for validating my video memory scheme.
    • as much as possible built from easy to obtain, current production chips.

    The last point is a bit difficult, as the key component for running Microbee software is the R6545 CRT controller. This is the granddaddy of modern graphics processors. It doesn't actually touch the graphics information, but it contains a pile of highly configurable counters that generate all the addresses for working theough video memory and pushing the data out to a CRT.

    It's the "highly configurable" bit that's problematic. Other machines of a similar era, even those that used ASICs for video (like the Sinclair Spectrum) had counters to clock through video memory, but were's nearly as configurable as the 6545. This is why the Harlequin is able to do Spectrum video in TTL. No configurability. Anyway, yes, 6545's aren't in current production, but we'll just have to deal with that.

    So let's get this video memory scheme bedded down first. It's the core part of the desigh. The majority of the computer is the video display circuitry.

    The R6545, like it's very close relative the Motorola 6845, comes from the bad old days of computing when people were impressed by seeing characters on a screen. Nowadays computers have pixel-addressable screens, but back in the late seventies that was super- high-end. When you think of the amount of data that even the modest Microbee 512 x 256 screen resolution entails (16kB in glorious monochrome), and then imagine moving the whole screen up one line (like you would when you scroll) with an LDIR block copy command. This takes 21 clocks per byte, or a whopping 6.2µs at 3.375 MHz. Our screen takes 101ms to draw (much longer if we have to wait for retrace times to do our moving), and the CPU isn't doing _anything_ else during that time.

    So the whole character thing makes our lives simpler. If we base our display on ASCII, and split the display up into (say) 16 rows of 64 columns (like the Bee does) then we've only got 1kB of data to store (and move!) for the whole screen.

    The key to character based screens is a double memory access. The CRTC outputs a counter that points to the character position on the screen. Each character is made up of a number of rows, and the CRTC outputs a row address that indexes into a character ROM. The same people who made the CRT Controllers also sold ROMs with ASCII character data.

    Here's a diagram from the SY6545 application note showing the scheme:

    And here's what's in the character ROM. This little guy is the Motorola MCM66740, from the late seventies. If you've spent as long looking at Microbee screens as I have, this will be instantly recognisable. It's the 'bee font!

    When generating the display, the CRTC scans across the screen, outputting the relevant screen address for the characters being displayed. At the end of the line a horizontal sync pulse is output, and then the same thing happens for the next row in the same characters. Once all the rows for the characters in the first row are done, the screen address is updated for the second row, and the next lot of characters are clocked out.

    Now how do we get graphics capability without the massive increase in CPU load that comes from pixel addressable graphics? The Exidy sorcerer (and Microbee) made use of programmable characters. Essentially a RAM was added alongside the character ROM. The first 128 characters (standard ASCII) go to the ROM, and the upper 128 go to the RAM. Loading data in to the RAM is a bit laborious - you need another set of address multiplexers, and another data transceiver. In the classic Microbee there are six multiplexer chips, and two transceivers, plus the shift register for the video output.

    It gets a lot more complicated in later bees. They have an extra RAM for colour for each character, plus yet another for "attribute" which really just increases the number of characters we can have (from 256 to conceivably 64K), meaning enough memory to have an individual bit per pixel, at the expense of more memory and more data bus transceivers.

    So this is where we enter the scene. We're not interested in colour or attributes (yet), but we are interested in running Emu Joust, which required monochrome with 128 "Programmable Character Graphics" characters.

    It’s possible to simplify this a bit, if you don’t mind all characters being in RAM (which means you have to pre-load them at power up).The key to understanding how to do this is to examine the timing. In order to display 80 characters in the standard PAL horizontal rate of 15.625 kHz, we need to use a dot clock of 13.5 MHz, which gives us a character rate (each character being 8 pixels wide) of 1.6875 MHz (592ns). This is a long time. Even when the Bee was very first built in ’82, you could buy 6116 static RAMs with an access time of 200ns or better. So it’s entirely reasonable to look up the screen data, then use the result a second time to look the character data using the same physical RAM.

    Our budget ends up looking something like:

    • 9ns input mux + 200ns RAM + 22ns screen latch + 200ns RAM = 431ns.

    Whereas a normal Microbee does:

    • 9ns screen mux + 200ns screen RAM = 209ns, at the same time as
    • 9ns character mux + 200ns PCG RAM = 209ns, or
    • 9ns character mux + 450ns Character ROM = 459ns.

    It’s pretty clear the incredibly slow 2532 is letting the show down for everyone. If we can just get rid of it, we can make some real changes.

    Let's use just one 8K RAM for everything. At the start of a character cycle the screen address is presented to the RAM (gated using tri-state buffers). The RAM outputs the screen data. At the half-way point through the character, this data is latched, and wrapped around back to the RAM address lines (using a second tri-state buffer) along with the row address. The data from the RAM is now our video which may be latched into the shift register. CPU accesses to either screen or character use a third set of tri-state buffers for the address, and a transceiver for the data.

    Note that 8K is more than we ostensibly need for screen RAM (2K), Character RAM (2K), and PCG RAM (2K). Let's use the last 2K for a second "small" font, which will be useful for an 80 x 24 screen. Turns out the Motorola MCM6674 character ROM has just the font we need, which (surprising nobody) is exactly the same as the Microbee 80 column font. To keep our Microbee compatibility, we'll enable this little guy using the MA13 output from the 6545, so by changing screen start address from 0000h to 2000h, we select the small font.

    So here's our schematics for CRT controller, video memory, and video memory access control. There's some complexity, sure, but we can break it down a bit. The first sheet is the CRT controller, along with the video output circuitry and keyboard.

    Here IC9 is our CRT Controller. It generates Video Memory addresses (MA0-10 and RA0-3) for the video memory array. The keyboard makes use of a "light pen strobe" input on the CRTC. Some of the video memory addresses are decoded and passed through a keyboard array. If you press a key, as the addresses scan to the key column and row, this match is passed through to the CRTC, which dutifully latches the address and raises a status bit to tell the CPU a key has been pressed.

    The DE (Display Enable), HS (Horizontal Sync), VS (Vertical Sync) and Cursor outputs from the CRTC, along with the video bitstream from the momory page are are used to build the actual output to the CRT. HS and VS tell the CRT when to start a new row (HS) or screen (VS). Display enable is used to gate the video output, so we don't put rubbish in the margins, and cursor is a neat signal that can be used to invert the video for a programmable number of rows in a programmable character position. IC16 delays the cursor and display enable signals to line up nicely with the video stream, and IC26 and 37 do the gating and cursor inversion.

    Moving on to the video memory page, we have a few things to do. IC8 and 10 gate the CPU address to the video RAM (IC14) and IC21 gates the CPU data bus. This allows us to read and write to the video memory. IC13 and 13 gates the CRTC address to the memory for a screen access, and IC11 does similarly for the row addresses that are used during character access. IC17 allows us to feed the results of the screen lookup back to the RAM for characters, and IC15 serialises the final output to send to the screen. Gating for the CRTC is incredibly easy - it's just done on alternate phases of the character clock. When CCLK is low we do screen address, and when CCLK is high we do character.

    Note that people building FreeBee have reported garbage on the screen when using very fast modern SRAM for the video memory. Please use old, slow memory such as the Hitachi HM6264ALSP.

    Finally we have the glue (no PLDs!) that works out what video address to generate for the various possibilities of CRTC screen, CRTC character RAM big and little fonts), CRTC PCG, and CPU access for each of these. A couple of gates control read and write (essentially it's all read unless the CPU wants to do a write), and the last bit delays CPU access when the CPU tries to barge in while the CRTC is actively writing the screen, to ensure the CPU doesn't put garbage on the screen. This is reasonably straightforward - CPU accesses are latched in IC18, causing the CPU to be put into a wait state. Once we're in retrace, the wait is cleared and the CPU finishes doing it's thing.

    As I said at the beginning, the video circuitry is most of this computer, so you'll be glad to know there's not a lot more to describe.

    Here's the CPU and memory. By using a CMOS CPU there's no need for bus transceivers and buffers everywhere (saving a bunch of chips). The EPROM here started life as simply something to load up the fonts into video RAM on boot, but I ended up making it big enough to include Microbee Basic as well, plus added 32K of RAM, so as one board it does everything.

    The flip flop is there to enable the ROM at address 0 on reset. Once the boot sequnce is complete the ROM is able to page itself out, presenting RAM from 0000h to 7fffh, with the upper ROM from 8000h to efffh.

    Next we have some ports. A Z-80 PIO gives us some GPIO, plus bit-banged serial, a speaker, and cassette I/O. Port decoding is simply done with a 74HCT138 and 74HCT139, giving the following port map:

    • 00 to 03: PIO
    • 0B: Boot ROM and Character RAM enable port
    • 0C to 0F: CRTC
    • Plus a few others that aren't used on the board but may be linked to a coreboard, if that's plugged in.

    Lastly we have clock and reset. The clock is derived from a 13.5MHz crystal. This provides the dot clock for the video shift register. It's divided by 4 (3.375 MHz) for the CPU clock, and by 8 (1.6875MHz) for character clock. The last eighth of each character clock is used to load the shift register, so this is derived by just anding CLK/2, CLK/4 and CLK/8.

    Reset can come from two places - power up or reset switch. In each case it's just done by charging a capacitor and using a 74HC14 as a comparator.

    Layout is done in KiCad. 12 thou track and space with beautiful curved traces. It really looks the part.

    And after a bit of debugging, we finally have:

    As always, here's the design files: