Time for a Mk1.1?

Posted on Fri 01 May 2026 in MUPS16

Over the last few years I've run into a fair few issues with the existing design and build. Some are just the expected issues that crop up when you let an inexperienced code monkey loose on hardware, but others are a bit more architectural. So, I've decided I think it's time to build a Mk1.1 version, building on what I've learned. I am going to have to be very careful not to let feature creep slip in here, and restrict myself to just fixing the issues with the existing machine, and not try to slip in pipelining, or code caching, or any other tasty redesigns.

The main changes I'm thinking of are:

  • all boards should be four layer, and clock signals in particular should be more carefully routed so they don't have long runs immediately next to data lines, for example;
  • standardised size and shape of boards, so I can more easily test them. After a bit of playing with pieces of paper, I think I've settled on a 'full-size' board being 15×7.5cm, and a half size being 7.5×7.5cm;
  • converting the register board to a RAM-based register file (partly because it's so big otherwise, and partly because I can't face the thought of soldering 550-odd components again);
  • allowing some use of (mostly period-appropriate) PLDs. Mainly this is because they remove a lot of the drudgery out of PCB design. I've already built all these boards before, and I don't really think I'm learning anything by doing it again, so if I can replace half-a-dozen components with an ATF22V10 or similar, that seems worth doing. The alternative is that I'd probably just not start on this;
  • cleaning up the startup SPI copy, by dropping the support for dual ROM chips on the memory board (which means dropping the ROM capacity from 128KB to 64KB, but that's acceptable), and making it easier to test. Dropping the dual ROM setup means that we no longer need the odd setup where the reset board increments all addresses by two during startup, forcing the control board to cross-wire itself to drop it back to incrementing every byte. I can also then connect the ROM chip to SPI_MISO and read its content via the backplane. With a dual ROM setup I had to have a separate dedicated circuit to multiplex the two ROM outputs onto one MISO line.

As well as the physical changes above, I want to make a couple of minor architectural changes:

  • removing the Zero register, and making R0 just a normal, general-purpose register. I added this right at the beginning, originally because that's what a lot of RISC CPUs do. It did slightly simplify some code, but as I've written more, and made a lot more progress on porting a couple of compilers to this architecture, the lack of general-purpose registers is far more painful than the occasional extra instruction to zero out a GPR;
  • removing the PTRE and PTRI instructions, which read data on page table entries and the current index respectively from the MMU. I never actually used these in any code I wrote, and they add four bus drivers to the MMU. Removing them makes it a much less crowded board at 15×7.5cm.
  • moving the ROM physical address to 0x000000, instead of 0x800000. This is just much cleaner all around, and I don't know why I didn't do it the first time around. It means that on boot the MMU doesn't need to force the top bit to 1 when BOOTDONE isn't set, and (more importantly) I don't need an entirely separate pair of RAM chips to hold the ROM contents (I can just copy them into the bottom 64K of the first pair). I lose 64K of RAM space, but out of 2MB that's perfectly acceptable.