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.

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.

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.