Skip to content

Ed's Diary 2016 05 04

BigEd edited this page Jun 7, 2016 · 3 revisions

2016-05-04 Wednesday afternoon

A few notes on today's adventure: Ed and Dave B at Dave's

[Detour while we had a look at the HP logic analyser with PA-Risc unix inside and the 6502 disassembler it has with the million clocks of history]

We were aiming to write some interrupt handling code which fires on nTUBE, and reads from or writes to the Beeb's databus. Dave had already written and built an empty framework to initialise the Pi and the I/Os and accept falling edge interrupts.

We hooked up a Tube Silencer to Dave's Model B Pi. We have just enough I/O pins on the short Pi connector for our purposes.

We decided that the interrupt handler should do the absolute minimum work, so no FIFO work or interrupt work: just set a bit to tell the emulator that the Tube needs attention. The normal emulator loop already polls for interrupts every N instructions - now it must also check to see if the Tube needs to be emulated.

We can also have an overrun bit, in case the interrupt fires again without the emulator having serviced the Tube emulation.

But we haven't implemented any of that.

First we need the Pi to deal with the bus, and quickly enough.

Initially it turned out our code was much too slow. In two places it spins to check the state of the clock, but that was pushing the whole interrupt service out to two and a half clocks.

Turns out the first spin is not needed - we were waiting until phi2 to start driving, but in fact the level converters in the tube silencer will already be driving the beeb or driving us - they are controlled by RnW. So we can switch the direction of the databus at the Pi end as soon as we're ready - after we've set up the data value itself.

The data value we're using is from a short table of constants - not from the emulator or from a FIFO model. Indeed the emulator isn't running yet.

We tried to use a cycle counter to see how long things were taking but it seems always to read zero.

So we unhooked the nRST and used that as an output: raise it at the beginning of the irq service and lower it at some interesting point, then measure the pulse width to see how long that section takes. (That measurement includes the overhead of the writes to the I/O subsystem, or half of them.)

It turns out the Pi loading from the I/O subsystems is rather expensive - storing somewhat less. So if we can avoid read-modify-write approaches by instead just writing, that's much better.

And it looks like we just got there at 19:25.

We get the code down to 200ns from entry to the interrupt to having switched the write drivers. Including the overhead of the nRST instrumentation.

We can use the scope to see how the outputs change relative to nTUBE. And so in fact we don't need the telltale, which is slowing us down a tad.

It turns out we are driving the databus (for a 6502 read) at nTUBE+280 which is about Phi2+380 - around half way through Phi2. And indeed the Beeb can happily read our values (our fake values)

We gain 15ns by removing the telltale toggle on nRST, which was only debug assistance.

We can even boot the Beeb with DFS enabled if we return FE from a read of FEE0.

second session after food:

by 21:25 we think we have the irq handler done, apart from some finessing

and we have the C code emulating a simple register file, in theory.

but we've just noticed that Basic accesses which will use an indirect addressing mode will do a dummy read before write - and that means we might only get one edge. Which means we'll handle the dummy read, and never get a chance to handle the dummy write. Same problem with an indexed addressing mode - dummy reads before writes, or dummy reads before reads, will not work properly.

The tube OS will always use absolute addressing so we shouldn't see a problem there.

Perhaps we can use the next half-cycle after the completion of a read to check that there isn't a follow-on?

  • first access (or two) doesn't seem to read the right value
  • the writes don't seem to be working
  • we're not handling back-to-back accesses which come from dummy reads
  • not sure about RMW instructions either

at 21:44 the reg file is working! Turns out volatile C array is needed.

So now we have a regfile and the interrupt handling is done - we need a FIFO emulation in C.​

Back to Development Diary