Wilf Ritger's "Why Wait?" ZX81 Mod

Discussions about Sinclair ZX80 and ZX81 Hardware
Post Reply
User avatar
Flatulentia
Posts: 93
Joined: Sun May 14, 2023 3:58 pm
Location: Cambridgeshire, UK

Wilf Ritger's "Why Wait?" ZX81 Mod

Post by Flatulentia »

I noticed when idly searching the OuterWebz a little earlier that Wilf's "Why Wait?" mod is now hard to find so, for posteriorities sake, I'd like to reproduce the body of text and accompanying images here...


IMPROVED ZX81 WAIT CIRCUIT Rev 2

07/2005 - wilf rigter



Ever wondered about the purpose of TR1 in the ZX81 schematic?

TR1 together with some passive parts are connected to the CPU WAIT, NMI and HALT lines and generates WAIT states when a NMI pulse occurs.

Ok, but why generate WAIT states? The short answer is to synchronize the CPU to VIDEO timing. Still interested? Then read on to understand exactly why and how this circuit works and how, with a small hardware mod, we finally correct a bug to let us execute slow mode user programs 10% faster (about a quarter century too late).

First note that this TR1 circuit is not needed for FAST mode video, which is entirely generated in software with an overall fixed execution time.

In the SLOW mode, the video display is interleaved with user program execution during blank lines at the top and bottom of the screen. The NMI generator is used to periodically interrupt the user program to determine if it is time to service the video. The CPU response to the NMI pulse can have a latency (and jitter) of up to 23 clock cycles depending on which opcode is interrupted. During user program execution, this jitter does not affect video timing of the blank lines which is controlled by the horizontal sync pulses generated by the NMI hardware in the ULA.

When the time comes to generate the video characters on the screen or generate the vertical sync pulse then this NMI response jitter must be eliminated.

This is done when the NMI routine jumps to the NMI CONT routine, executes the HALT at address 0079 and then waits for one more NMI pulse to exit the HALT state.

Code: Select all

NMI CONTINUED SUBROUTINE
                   
006F EX AF,AF'      ;retrieve main register AF
0070 PUSH AF        ;now save all application 
0071 PUSH BC        ;program registers
0072 PUSH DE
0073 PUSH HL
0074 LD HL,(DFILE)  ;needed only if IX=0281 and
0077 SET 7,H        ;if DFILE is executed
0079 HALT           ;CPU T state/video synchronization 
007A OUT FD,A       ;turn off NMI generator
007C JP (IX)        ;to VIDEO-1 or VIDEO-2
However there is a problem: while halted, the HALT opcode executes NOPs every 4 clock cycles (T1-T4) and it can be at any clock cycle when NMI arrives but does not respond to NMI until the rising edge of the T4 state. This means HALT itself has a latency of up to 4 clock cycles before it exits the HALT state at T4 in response to the NMI pulse.

So what is so important about 4 clock cycle jitter?

The problem is that ZX81 SLOW mode video is displayed by executing NOP instructions. The execution time of a NOP is 4 clock cycles which is the time it takes to clock out 1 byte of pixel data but the loading of that byte into the video register must occur on a specific edge of 1 of those 4 clock cycles to avoid jitter of the video display screen. Since this part of the video is under real time CPU control, the CPU must be internally synchronized to one edge of a specific clock cycle at the rising edge of NMI to ensure that each displayed video frame starts in exactly the same place on the screen.

To do this the TR1 circuit was added that acts like an OR gate with an active low WAIT output at the collector of TR1 when NMI is low and HALT is high.

Why Wait 1.gif
Why Wait 1.gif (3.92 KiB) Viewed 1206 times

The WAIT state is asserted after the HALT line goes high when NMI forces the HALT exit, and inserts WAIT state betweens T2 and T3 of the M1 cycle of the NMI response (RST to 0066) for the duration of the NMI pulse. Then on the rising edge of NMI, the WAIT signal is removed and the CPU is precisely
synchronized with the start of T3 on the rising edge of the NMI pulse eliminating all video jitter.

While the original WAIT circuit solves one problem it comes at a price: The WAIT line is also asserted by every NMI pulse during blank line user program execution and this reduces available CPU time by 10 %!

An improved WAIT circuit adds just one 10K resistor (R35) and PNP transistor (TR3) circuit to correct this problem and increases SLOW mode program speed by 10%. TR1 and TR3 form a LATCH, which is SET on the rising edge of HALT and RESET when the NMI pulse goes high again.

Why Wait 2.gif
Why Wait 2.gif (4.92 KiB) Viewed 1206 times

The new WAIT circuit only generates WAIT states when synchronizing the CPU with NMI after the exit of HALT at address 0079. Since that occurs just
twice during each ZX81 video screen display there is no time wasted in generating unnecessary WAIT states during user program execution.

With a few tools and modest soldering skills, installing this mod is a simple and painless procedure which took me 10 minutes to complete. The lead of R1 to Z80 pin 18 is first unsoldered from the PCB pad and then soldered to Ground. Then TR3 and R35 are soldered to the original WAIT circuit as shown here:

Why Wait 3.jpg

So with a few hints and few pennies worth of parts, the ZX81 could have been running on all cylinders. We can only imaging the millions of MIPS wasted by the old WAIT circuit. The question is now whose head(s) should roll?

enjoy

wilf
ZX81 with ZiLOG Z84 CMOS Z80, 32KB battery-backed Toshiba 55257 SRAM with charge status LED, Wilf's "Why Wait?" mod and switch-mode 5V regulator. 50/60Hz mode switch, composite video output with Zigg's back porch mod and 1080p60 HDMI output.
Post Reply