The ZX Spectrum Reverse Engineering and Clone Desgin Blog


A site dedicated to the reverse engineering of the ZX Spectrum and related projects.

< 38 of 68 >

Testing the Interrupts

Jun 29, 2007

Ramsofts floating bus and interrupt test program is supplied as a .TAP file, so I loaded this up into my Spectrum emulator Fuse, the Free Unix Spectrum Emulator, broke into it and saved it again into a TZX file. I could then use playtzx to replay it, as if from cassette, for the Harlequin to load.

Floatspy fills the first 8 lines of pixels with bytes 0 through 255, and the first row of attributes have values 64 through 95. It is these values that it reads from the bus by sampling it an exact number of T-states after the interrupt.

Once loaded, floatspy start by displaying the value read on the bus at T-state 14347 (the additional 11 due to the IN instruction). This should be the value zero - however Harlequin returns 255 (nothing on the bus). I increased the sample T-state until 0 was returned. This was at T-state 14374, a full 27 T-states later than expected - which for this extra time to have passed means that the Harlequin interrupt is occurring 27 T-states too early!

This probably accounts for Dark Stars border logo being too far to the left, but probably not Aquaplanes border horizon being too high, as that would require the interrupt to be very many T-states early!

Floatspy provides a test mode which scans a total of 224 x 8 T-states, one by one (the first eight lines), comparing the values read on the bus against the values returned by a real ZX Spectrum. Errors are displayed as they occur and a total error count given at the end of the test. Even though the Harlequin start T-state is too late, I wanted to see if the floating bus was otherwise accurate. In order to run this test, I had to edit floatspy and change the start T-state to be 14374. The following screenshot shows floatspy failing at read 2, where it was expecting 255 and got 67:

The timing of the interrupt is set by the onset of the VSyncEn and following that, the low to high transition of the horizontal reset Hrst. Something must be wrong here.

I also noticed that when left displaying a particular floating bus value, floatspy intermittently picked up another value for a moment, clear evidence that the interrupt must be unstable.

When Hrst is issued the horizontal counter resets, HC8 would be high at this point and drop to a low state. Instead of using Hrst, I wired up HC8 through a spare inverter so that it went from low to high, and used that to clock the interrupt flip-flop.

Running floatspy again gave a starting T-state of 16346 - this time one T-state too late! The test program also returned bus errors when running from this new start T-state.

The difference in T-states is really quite strange given that Hrst is the signal that causes HC8 to go low, and since they're synchronised it shouldn't matter which is used to clock the interrupt flip-flop! According to the 74HC161 data sheet, HC8 will go low a maximum of 19ns after HC is reset by Hrst, so there shouldn't be a difference.

A few thoughts on what may cause this discrepancy:

  1. Late sampling of INT
  2. The timing of HC8 and HSyncEn not as expected
  3. Hrst unstable, or not long enough to clock the interrupt flip-flop reliably
  4. HC not responding to Hrst reliably
  5. Port contention is not correct

I doubt the first option (late sampling) is correct as this would show the same timing regardless of HC8 or Hrst clocking the flip-flop.

We find that the interrupt timing is very much nearer the expected 14336+11 when HC8 is clocking the interrupt flip flop. If we assume for the moment that it is synchronised with Hrst, then since HSyncEn goes low when HC8HBlank is true, and as this is well before Hrst or HC8 goes low, then point 2 above is false.

For the third option, a look at Hrst with the oscilloscope is required.

Interestingly a glitch is just about visible on the Hrst line shortly before the actual low reset pulse, but HC8 going low does correspond to this reset pulse as expected. Whether this glitch is the cause of the interrupt miss-timing will need to be seen, it certainly doesn't seem to worry the horizontal counter and cause it to reset early - careful measurement of the Hrst low pulse with the oscilloscope shows it to be consistent and stable, discounting point 4 above.

The 74HC161A used for HC was deliberately chosen as it is a synchronous counter and thus it's output should be glitch free. I must look at the derivation of Hrst and see if something there could be causing it.....