What can you do with an RC2014 (+ BusRaider)? Part 1

To mark the culmination of a lot of work on the BusRaider (retro computer display and debug board), I’ve started a series of short(ish) posts to answer the question: “What can you do with an RC2014” (a question asked on the RC2014 forum). The twist though is that my answers make the assumption that you have a BusRaider too 🙂

This is the first post and concerns the use of BusRaider as a tool for assisting in the development of other RC2014 hardware. It makes use of the BusRaider’s ability to drive the RC2014 bus in “Bus Master” mode. This is generally used for grabbing the display contents (when emulating a retro computer that had a memory-mapped display) and for grabbing the RAM contents during debugging. But the capability also allows the BusRaider to access the bus for other purposes and I’m going to document this capability for use in developing add-on hardware for the RC2014.

Developing RC2014 Hardware

When developing a new piece of hardware for a target computer it is desirable to put the board through its paces using some test programs. Normally these would execute on the target processor and would exercise the logic on the board. BusRaider provides an alternative for some simple tests by allowing a script in a high-level language on a separate computer to exercise the board’s functions.

To demonstrate how this is done I’m using a variant of Spencer’s 512KRAM+512KROM board that I’m working on which has additional support for paging using the PAGE (RST2) line on the RC2014 PRO bus. This board isn’t yet released as the current version has known issues – which we are about to resolve using the BusRaider’s super-powers! I will publish all the details on the board when I have a working version. In normal use (if the PAGE line is inactive/pulled-up) the board should be a drop-in replacement for Spencer’s board  – BUT it isn’t working so here goes fixing it.

Firstly we need to establish how to communicate with the BusRaider. This is most simply done over WiFi and using the BusRaider REST API which is the same API that the BusRaider’s Web UI uses. Using this API can be as simple as typing the API command into a browser window. For instance, to disable the regular BusRaider bus control you could use the command directly in your browser’s address bar:

Where: busraiderapiaddr is the IP Address of your BusRaider (see the manual for details of getting the BusRaider onto WiFi and finding the IP Address).

This should elicit a response like this:

The important part here is the “err”:”ok” which indicates the command completed successfully. The additional information isn’t relevant right now but is explained later on.

Using the API from Python

Instead of typing each API command into a browser’s address bar it would be good to setup a script to do this for us. Python is a suitably simple scripting language and we can use the Requests module to allow Python to make http requests. To install requests just use:

It is best to use Python 3 and on some computers with both Python 2 and Python3 installed you can use pip3 in place of pip to ensure you use the right package manager.

I have added a number of useful API commands which we can use for this kind of hardware debugging:

  • rawBusControlOn / rawBusControlOff
  • rawBusWaitDisable / rawBusWaitClear
  • rawBusTake / rawBusRelease
  • rawBusClockEnable / rawBusClockDisable
  • rawBusSetAddress / rawBusSetData
  • rawBusSetLine
  • rawBusGetData

Using these commands allows reasonably complete control over the Z80 bus and allows exercising of hardware. An example is this:

Note that all the values used for address and data are hexadecimal values (without any prefix) and make sure you set your IP address for these examples to work.

What this does is to walk the bus through the following steps:

  1. Disable BusRaider’s managed control of the bus
  2. Disable wait states
  3. Take control of the bus (using BUSRQ)
  4. Set the address bus
  5. Set the data bus
  6. Sequence the MREQ and WR lines to write the value to memory

In addition information from the bus is returned too, the “pib” value in the JSON is the data read from the multiplexed bus on the BusRaider and the “raw” value is what the Pi read from all of its GPIO block 0 pins (which includes all of the external pins that we use – for details of which bit means what you would need to view the schematic).

A More Complex Example

In order to debug the 512K RAM / ROM with Paging card I set up the following script initially:

This script is similar to the previous example but instead writes the values 0x01 & 0x00 alternately to the IO address 0x70 (which sets and clears the PAGE_EN value in the 74HCT74 flip-flop chip). See the schematic for Spencer’s 512K RAM/ROM card here.

Looking on a Logic Analyzer while this script runs you can see the following:

Clearly we’re not breaking any speed records here! But there is a lot of debug information going on in the background so it will be faster than this when that’s disabled. But the important thing is that the PAGE_EN line (bottom trace) toggles as we expect and the timing on the IORQ and WR lines can also be seen.

There isn’t a problem with that part of the circuit so let’s keep looking.

Exercising More of the Circuit

Let’s now jump into a more extensive test where we set up a few pages in the RAM, write some data into each page, then go back and check the right stuff is where we put it:

The script is a little more structured but basically sets up values 0x21, 0x22, x023, x024 in the four 8 bit registers provided by the 74HC670 chips. It also writes data into memory in each of these banks and then reads back what should be the same data.

This generates the following output:

So not what I was expecting!

Logic Analyzer Output for more extensive test

I didn’t work out what to look at with the logic analyzer immediately and always rue the paucity of lines which can be monitored simultaneously (even with a 16 channel analyzer) but eventually I looked at the A14 and MA14 lines and noticed that they are the same. They shouldn’t be! So I traced this back to an error in my schematic where I had incorrectly applied the A14 (and A15) lines directly to the RAM and ROM chips instead of their MA14 (and MA15) counterparts.

A bit of hacking with an Olfa cutter and some wiring fixed that on the prototype board, so then I tried again…

Hurrah!

At this point I assumed the job was done so I plugged the RomWBW ROM and RAM back in and turned-on, fully expecting to see everything working fine, but no joy! Blank terminal output.

Bringing out the Big Guns

At this point I was a little stumped. I’d checked out the hardware to a reasonable degree and found that it operated as I expected. So failure to work with actual firmware must be down to something I hadn’t considered.

I thought about this for a bit and then decided to do a little more work on a feature of the BusRaider that I’ve mainly only used for testing of the BusRaider itself – so far. That is the ability to monitor every bus access the Z80 makes (and optionally compare it to an emulated Z80 running on the Pi to check it is doing everything correctly). Alan Cox (who wrote the aforementioned Z80 emulator and is active on the RC2014 forums) suggested some time ago that this functionality would be more useful to him than single-step debugging and I think I can now see why.

So I set about improving the functionality to the point that it would be useful for comparing the operation of the original board with the new one. The main challenge here wan’t getting the bus monitoring functionality working – that part was already done and quite extensively tested – but in getting a large amount of data out of the BusRaider quickly enough to be useful. The issue here is that the data grabbed from the Z80 bus is in the Pi Zero, and the Pi Zero is connected to the ESP32 via a 920Kbps serial link, then the ESP32 is connected over WiFi to a fourth processor on a desktop or similar.

I made a few attempts at this (which failed as the serial buffers became swamped and it was tough to get end-to-end flow control working over so many interfaces) before alighting on a mechanism which buffers up captured bus activity and then holds the Z80 in WAIT until some of the data has been removed from the buffers. With sufficiently big buffers (2000 Z80 instructions, 32K of serial transmit buffer on the Pi, 32K receive buffer on the ESP32) I have managed to get around 1800 bus accesses per second traced in this way. Certainly no record breaker and equivalent, perhaps, to clocking the Z80 at about 4KHz (so 1000 times slower than a ZX Spectrum!) – but there’s lots of room for improvement 🙂

To create a dump using the tracing API is a little more involved than the previous examples as the REST API isn’t really suitable for grabbing data about execution (although I guess it might be possible). Anyhow, the start of the code to do this is as follows (the full file is on GitHub in the examples/hardwareDebug folder):

And the output from running this on my 512K RAM/ROM with Paging board is as follows:

I collected a few hundred thousand lines in a log file only to find that the problem is visible after record 16 in the above. The instruction at record 14 is d3 79 which is OUT (79), A and after that every instruction fetch returns 00 NOP – so that doesn’t look too good! By comparison this is the trace from the working board:

No such problem here!

The Final Step

Having now a clear idea that the (or at least another) problem lies with the paging mechanism I took a closer look at the circuitry around the paging selection and realised that I’d juxtaposed the PAGE_WR and PGEN_WR lines. So in-fact I would have found this problem earlier if I’d done a comparison of the output from the first test program on the original board. It wouldn’t have worked! And I’d have realized (perhaps) that the register values were actually the wrong way around in that program.

If you are interested in extending any of this the bulk of the code used in the first part of the post is in the BusController.cpp file in the PiSw/BusController folder. The code for the tracer is in the file StepTracer.cpp in the PiSw/StepTracer folder. And, finally the example code used here is in the PiSw/examples/hardwareDebug folder.

All of this is on GitHub.

robWhat can you do with an RC2014 (+ BusRaider)? Part 1

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.