I was really glad to know that finally there are some ULA replacement on modern comodity hardware. Congratulations to the winners!
Half a year ago my only working ZX81 started to show a strange behaviour, some missing pixels always in the same position and also the printed characters were shifted, as if a bit in the character address was not working. Well, I blamed it on the ULA that also started to get even hotter than usual and started to look for some way to fix the problem.
I stumbled upon some projects and among them this thread here, where people was starting to develop some solutions based on the great design by Alwin Henseler. All this CPLD world (and also the ZX81) was new for me, but this was a good reason to try to learn.
I designed a board based on a Xilinx XC9572XL and ordered the minimum batch. After some changes in the clock components managed to get a somewhat stable oscillation only to find out that it didn't work at all. Random behaviour with out-of-sync screens, still garbage screen and even some random characters here and there. Not as elegant as other designs I've seen here, but still...
I was astonished also to find out that disabling NMI generation (by closing the needed jumper) the thing worked! I got the sacred 'K' cursor and I was even able to type a little BASIC program and see it run with tears in my eyes.
So it seemed to me that I was near, but how mistaken I was. Since my broken ULA was still generating a crippled K cursor, I decided to tap in the analyzer to compare the relevant signals with the ULA and the CPLD plugged in.
The first thing I found was that my NMI pulse trains had 31 pulses whereas the ULA ones had 55 pulses. I read in the original project good documentation that the US/UK pin should be pulled-up. So I added a resistor (as you can see in the photo) and that fixed the problem. Anyway I just thought that this shouln't be causing a hung, only maybe some video sync issues.
The problem is that the NMI pulse generation under my CPLD replacement gets eventually disabled for whatever reason, to never be reenabled again. I can see the IOREQ/WR/A1/A1 combination that disables the NMI pulse as happens for each frame, but there is a point when it no longer gets reenabled. For some time I suspected that the Sync circuit could be the reason, because the NMI pulse has different voltage levels, and maybe the circuit (TR1 and friends) is very sensible to the NMI level (even though the relevant NMI level here is zero). I tried to buffer the NMI signal with a TTL buffer with the same results.
This is when I came back to this thread and found the great design from Andy (I love the CPLD disposition and how tiny the board is) I saw that the componentes are pretty the same, except for what I understand is a transistor to amplify the tape input level. But for the rest, no buffers whatsoever, capacitors for the voltage regulator, for the CPLD power lines, cristal polarization and that is all. So I thought that maybe there was still hope.
But I'm not able to figure out why the NMI gets disabled and never enabled again. Even if the NMI generation was not stable or the sync circuit was not generating the needed WAIT states, I would expect a bad video output (out of sync) but not what seems to be a hung of the computer. So I decided to come here and expose the case to the ZX81 experts, looking for some tips to continue with this project. Because currently I'm honestly out of ideas.
So, this is an analyzer capture with the original ULA:
always the same pattern. I understand the dense HALT enabled zones match the rendering of the screen, and the two contiguous NMI zones are the lower and upper blank screen lines (with the VSYNC in half).
With the CPLD is pretty the same, but it gets stopped suddenly (sorry I was not able to figure out how to use the same x-scale in the analyzer software, but the timing is pretty the same as in the ULA capture)
If we zoom into the zone where the NMI gets disabled to never be enabled again, my untrained eye cannot detect any problem (neither the other eye).
So, why could be that the NMI generation is stopped and never reenabled again? Don't hesitate to ask for further information, analyzer dumps or scope measurements.
I'm afraid this post is finally longer than expected. Congratulations and thanks a lot if you reached this point.