The ZX Spectrum Reverse Engineering and Clone Desgin Blog


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

< 42 of 68 >

The Sidewize Test

Jun 30, 2007

Sidewise is notoriously sensitive to floating bus and interrupt issues. These manifest themselves as jerky movement and flickering graphics.

I dug out Sidewize, typed LOAD "" on the Harlequin keyboard, pressed PLAY and waited.....

The game at least runs! However gameplay is flickery.

I've decided to resort to a little bit of reverse-engineering and find out exactly what Sidewize is doing with the floating bus:

9CF4    LD    BC, 40FFh
9CF7    LD    E, 40h
9CF9    LD    A,R
9CFb    IN    A,(C)
9CFD    CP    E
9CFE    JP    NZ, 9CF9h
9D01    RET

Sidewize polls port 0x40FF and not 0x00FF. This means there must be something significant about that port.. Wait a minute, the ULA in a real Spectrum doesn't get confused by that port address and think a memory access is occurring halting the CPU does it?

A quick check with floatspy on the Harlequin reading port 0x40FF returns the same results as for 0x00FF. However on a real spectrum, 0x40FF fails. Ports between 0x40nn and 0x7Fnn must be contended, and Sidewise is relying on this 'slow down' for the polling loop to execute at the correct speed.

I loaded Sidewise into Fuse and altered memory location 0x9CF6 from 40h to 00h. This made sidewise read from port 0x00FF instead (an uncontended port), and it flickered like mad - exactly as the Harlequin.

A quick websearch came up with Spectrum IO Contention, specifically the section that reads:

Port being accessed .... If this is in the range 0x4000 to 0x7fff, the ULA treats this as an attempted access to contended memory ...

I have no idea how I managed to miss that blinder of a fact, but it should be simple to rectify. Instead of using RAM16 as a wait stage trigger, I can instead use A14 + A15. This removes MREQ from the equation, and cause a wait state to be triggered whenever 0x4000 - 0x7FFF is present on the address bus.

If Aquaplane is reading from a port in the range 0x4000 0x7FFF during it's timing loop, then it will run faster on the Harlequin, and complete sooner. This is no doubt the cause of the border horizon being too high. I'll alter the WAIT generation to consider A14 and A15 directly, and give both Sidewize and Aquaplane another try.........