Houston, we have an image!
-
- Posts: 108
- Joined: Mon May 23, 2011 2:10 pm
- Location: A bit north of Cardiff, Wales.
- Contact:
Re: Houston, we have an image!
Hmmm...
I'd be interested to know when you are forcing a NOP onto the data bus.
I need to re-check my my scope findings, as I think I may have mis-interpreted when the NOP appears on a real ZX81 - I may just have been "seeing" a zero byte on the display at the same time. I'll check later and update the page. The NOP hold seems to cover all of T2 and half of T3, according to what I am seeing on the scope ( http://home.micros.users.btopenworld.co ... ePics.html ), but this can't be right. It is probably just covering the end of T2 and start of T3 - I will check.
The ZX80 timings are correct.
Grant
I'd be interested to know when you are forcing a NOP onto the data bus.
I need to re-check my my scope findings, as I think I may have mis-interpreted when the NOP appears on a real ZX81 - I may just have been "seeing" a zero byte on the display at the same time. I'll check later and update the page. The NOP hold seems to cover all of T2 and half of T3, according to what I am seeing on the scope ( http://home.micros.users.btopenworld.co ... ePics.html ), but this can't be right. It is probably just covering the end of T2 and start of T3 - I will check.
The ZX80 timings are correct.
Grant
Last edited by zx80nut on Fri Nov 11, 2011 9:05 am, edited 2 times in total.
Re: Houston, we have an image!
With the data bus at the cpu getting signals from everywhere + some small coincidental capacitance, it's really quite difficult to tell when things are happening...
I'll PM you tomorrow, don't don't wanna give the game away just yet
Andy
I'll PM you tomorrow, don't don't wanna give the game away just yet

Andy
what's that Smell.... smells like fresh flux and solder fumes...
Re: Houston, we have another image!
I think the trick is correct timing of the /RAMCS which is generated from the ULA. I am not sure but maybe /RAMCS is not generated when /M1 and /MREQ are low. It could be set low when /M1 low and A15 high which occurs about 150ns earlier (half T-state) and could help solve this problem.RetroTechie wrote: Tried grabbing bit 0 of the character code on falling edge of T2 (while /M1 and /MREQ are low) - close, but no cigar. Then the rising edge of T2 - again close, but no cigar. Then used 6.5 MHz signal in various ways to try & grab that bit halfway a CPU clock high, or CPU clock low period (yeah I'm aware ULA's clock output is inverted on its way to Z80). Some interesting results, but again no cigar.
Finally I routed (/M1 and /MREQ) signal through an external RC delay, and used that to clock D0 into a flipflop (temporarily using /RFSH to output grabbed data onto A3' pin). This did the job, but only within a very narrow range of RC: with C=180 pF, R needed to be in 680-850 Ohm range (dunno exact delay, it depends on the CPLD's I/O characteristics). Which confirms to me there's a very small time window to grab correct character code from the databus.
Anyway this could be a workaround.

- RetroTechie
- Posts: 379
- Joined: Tue Nov 01, 2011 12:16 am
- Location: Hengelo, NL
- Contact:
Re: Houston, we have another image!
If /RAMCS uses /MREQ (it does in my current setup, and I'd think most ZX81 clones do it like that), access time wouldn't start until shortly after falling edge T1. Rising edge T2 would then be around 90~100 ns in (?) which might be fine for a modern SRAM (half-used 32Kx8, 120 ns SRAM here) but too short for original ZX81 RAMs.
If Z80 indeed samples databus at rising edge T3, that would be too late to force NOPs. So falling edge of T2 would seem optimal point to me - half a clockcycle should be more than enough room to force datalines to 0. And of course it's possible ZX81 ULA uses its internal 6.5 MHz clock to pick a point 1/4 cycle before T3 or halfway T2 high period (that would be my guess looking at the scope pix? Too bad I don't have a scope to see for myself).
(and Grant's scope pix indeed suggest that ZX81 /ROMCS is somewhat off vs ZX80 /ROMCS).
For myself I think I'd pick falling edge of T2 - modern CPLDs & FPGAs have dedicated clock nets which allow latching data with practically 0 hold time, so you could sample the databus & start to force a NOP onto it at virtually same point in time. As far as accuracy vs. original ULA goes: matching scope pix are nice but I don't care much as long as net result is the same...
Oh btw I have Z84C0008 in this ZX81 which should have shorter delays between clock edges & things like /MREQ low, /RD low etc. Don't think it makes much difference here. And XC9572 is of the -15 speed grade.
If Z80 indeed samples databus at rising edge T3, that would be too late to force NOPs. So falling edge of T2 would seem optimal point to me - half a clockcycle should be more than enough room to force datalines to 0. And of course it's possible ZX81 ULA uses its internal 6.5 MHz clock to pick a point 1/4 cycle before T3 or halfway T2 high period (that would be my guess looking at the scope pix? Too bad I don't have a scope to see for myself).
Telling apart M1 cycles from INTACKs might be tricky (or not), anyway it wouldn't surprise me if ZX81 does something like this. I had a similar problem with /ROMCS - simply decoding A14 & /MREQ didn't work. Fixed that quick 'n dirty by putting a small capacitor on /ROMCS pin @ the ROM...PokeMon wrote:I am not sure but maybe /RAMCS is not generated when /M1 and /MREQ are low. It could be set low when /M1 low and A15 high which occurs about 150ns earlier (half T-state) and could help solve this problem.

For myself I think I'd pick falling edge of T2 - modern CPLDs & FPGAs have dedicated clock nets which allow latching data with practically 0 hold time, so you could sample the databus & start to force a NOP onto it at virtually same point in time. As far as accuracy vs. original ULA goes: matching scope pix are nice but I don't care much as long as net result is the same...

Oh btw I have Z84C0008 in this ZX81 which should have shorter delays between clock edges & things like /MREQ low, /RD low etc. Don't think it makes much difference here. And XC9572 is of the -15 speed grade.
-
- Posts: 108
- Joined: Mon May 23, 2011 2:10 pm
- Location: A bit north of Cardiff, Wales.
- Contact:
Re: Houston, we have an image!
Something quite interesting seems to be happening on a real ZX81 ULA...
The NOP is forced, but is actually released for a short time then applied again during the second half of T2.
The scope picture that I did had that display bit set at zero anyway, so the release is not very obvious, but it can be seen if you look closely (it rises slightly - a small hump in the "low" then drops again just before T3).
http://home.micros.users.btopenworld.co ... ePics.html
I can see it clearly when looking at a bit set to 1. It's definitely getting clamped, unclamped the re-clamped as I have checked the signal either side of the resistors.
That must be where the ZX81 ULA releases the bus, samples the data that is there, then clamps it down again for the CPU sampling.
I'll do a better pic so that you can see it clearer later today.
Grant
update... Yes, there is definitely a time during the period where I have shown the NOP active where it is briefly released. At this point, the RAM data is available on the bus and is likely to be sampled. The NOP is then re-applied to ensure the Z80 samples the NOP opcode at the start of T3.
Although only the latter part of the NOP force is needed (just before T3) it is probably double-applied due to limited decoding (similar way as the ZX80 double-samples the bus into the data latch - the first happens but doesn't do anything as the second one is the important one).
Once I post the pic, I'm sure you clever people will be able to work out the actual decoding that is in the real ULA
I'll post a detailed pic later today.
The NOP is forced, but is actually released for a short time then applied again during the second half of T2.
The scope picture that I did had that display bit set at zero anyway, so the release is not very obvious, but it can be seen if you look closely (it rises slightly - a small hump in the "low" then drops again just before T3).
http://home.micros.users.btopenworld.co ... ePics.html
I can see it clearly when looking at a bit set to 1. It's definitely getting clamped, unclamped the re-clamped as I have checked the signal either side of the resistors.
That must be where the ZX81 ULA releases the bus, samples the data that is there, then clamps it down again for the CPU sampling.
I'll do a better pic so that you can see it clearer later today.
Grant
update... Yes, there is definitely a time during the period where I have shown the NOP active where it is briefly released. At this point, the RAM data is available on the bus and is likely to be sampled. The NOP is then re-applied to ensure the Z80 samples the NOP opcode at the start of T3.
Although only the latter part of the NOP force is needed (just before T3) it is probably double-applied due to limited decoding (similar way as the ZX80 double-samples the bus into the data latch - the first happens but doesn't do anything as the second one is the important one).
Once I post the pic, I'm sure you clever people will be able to work out the actual decoding that is in the real ULA

I'll post a detailed pic later today.
Re: Houston, we have an image!
Dumb question, probably, but in my emulator (which is being structured so that many of the same considerations apply) I've completely ignored the clock and I have the relevant video stuff set up so that it is triggered on A15 high, M1 and D6 low. It then grabs whatever is on the data bus and starts forcing the NOP immediately after latching that. It continues until the A15/M1/D6 condition ends. So there's no assumption about RAM timing — just that the NOP can be forced in the period between the RAM loading the bus and the Z80 sampling it.
Is that a grossly unreasonable way to approach the problem?
Is that a grossly unreasonable way to approach the problem?
-
- Posts: 108
- Joined: Mon May 23, 2011 2:10 pm
- Location: A bit north of Cardiff, Wales.
- Contact:
Re: Houston, we have an image!
As promised above, here are scope pics of what really happens with the NOP aplication on the data bus from a real ZX81 ULA (scroll down the picture
)...
As you can see, during the NOP period, there is a short time when the bus is released. This period is presumably used to allow the ULA to sample the real data before it is clamped LOW for the CPU opcode read at the start of T3.
An updated picture of the ZX80/81 signals is updated on my page...
http://home.micros.users.btopenworld.co ... ePics.html
Please refresh your browser page to see latest (it will show "Last update: 11th November 2011" near the top)
The first NOP application (start of T2) is not needed, and I suspect this only happens due to limited decoding in the ULA.
The second NOP application (end of T2 / start of T3) is the important one.
Hopefully that should clear up how the ULA can read the data from the RAM.
Regards.
Grant
http://home.micros.users.btopenworld.com
http://home.micros.users.btopenworld.com/zx80/zx80.html
http://home.micros.users.btopenworld.co ... hines.html

As you can see, during the NOP period, there is a short time when the bus is released. This period is presumably used to allow the ULA to sample the real data before it is clamped LOW for the CPU opcode read at the start of T3.
An updated picture of the ZX80/81 signals is updated on my page...
http://home.micros.users.btopenworld.co ... ePics.html
Please refresh your browser page to see latest (it will show "Last update: 11th November 2011" near the top)
The first NOP application (start of T2) is not needed, and I suspect this only happens due to limited decoding in the ULA.
The second NOP application (end of T2 / start of T3) is the important one.
Hopefully that should clear up how the ULA can read the data from the RAM.
Regards.
Grant
http://home.micros.users.btopenworld.com
http://home.micros.users.btopenworld.com/zx80/zx80.html
http://home.micros.users.btopenworld.co ... hines.html
Re: Houston, we have an image!
<head spins>
- RetroTechie
- Posts: 379
- Joined: Tue Nov 01, 2011 12:16 am
- Location: Hengelo, NL
- Contact:
Re: Houston, we have an image!
No wonder I had so much trouble pinning down the exact moment to grab the data - this would be so much easier if original ULA is gone & you can determine yourself what happens on the bus, and when. Also these new scope pix seem to suggest that /RAMCS indeed uses /MREQ signal. Big thanks for digging out the scope again, Grant!
Oh btw in some places it may not be a matter of "ROM/RAM data re-appearing" but rather everything high-Z with pull-ups pulling datalines to +5V - notice the exact same slope angle in several places (like the voltage/time curve you get from an RC filter).
Doubt this would have been easy for the Sinclair folks at the time, which might explain the various ZX81 ULA versions in existence.
Semi-custom IC development is difficult undertaking...
Steadily progressing here - ULA's A3-A8' outputs disconnected now... next up: 0..7 line counter (I think)

Doubt this would have been easy for the Sinclair folks at the time, which might explain the various ZX81 ULA versions in existence.

No, just ignore the low-level timing. All you need to know is what condition causes DFILE execution (+forced NOP), that RAM output is grabbed by the ULA as character code (+invert bit), but Z80 sees a NOP, and then character code is used as partial ROM address (Grant's page below the scope pix explains this nicely) to obtain the bit pattern that's shifted out serially to the screen (and possibly inverted).Thommy wrote:Dumb question, probably, but in my emulator (which is being structured so that many of the same considerations apply) I've completely ignored the clock and I have the relevant video stuff set up so that it is triggered on A15 high, M1 and D6 low. It then grabs whatever is on the data bus and starts forcing the NOP immediately after latching that. It continues until the A15/M1/D6 condition ends. So there's no assumption about RAM timing — just that the NOP can be forced in the period between the RAM loading the bus and the Z80 sampling it.
Is that a grossly unreasonable way to approach the problem?
Steadily progressing here - ULA's A3-A8' outputs disconnected now... next up: 0..7 line counter (I think)
-
- Posts: 108
- Joined: Mon May 23, 2011 2:10 pm
- Location: A bit north of Cardiff, Wales.
- Contact:
Re: Houston, we have an image!
Hi Retrotechie.
Glad they were of use to you
The ROM/RAM data reappearing is actually the data reappearing - it's just that it's very difficult to get only the trace I want due to the lack of signals use to trigger the scope, so you are actually seeing some other signals superimposed on the pic that aren't relevant to the display NOP execution (ie. at the top and bottom of the screen where scanlines still occur but are not running the display routine). So, please ignore the R/C curve
Only the brightest of the traces are relevant to the NOP execution routine.
Ideally, I should trigger the scope only when the display lines are being processed, but I will need to add an LM1881 and some extra logic / delay to blank out the signals when the non-relevant parts of the screen are drawn - I'll probably do that when I get a bit of time, but hopefully the trace is clear enough for now.
Regards
Grant
Glad they were of use to you

The ROM/RAM data reappearing is actually the data reappearing - it's just that it's very difficult to get only the trace I want due to the lack of signals use to trigger the scope, so you are actually seeing some other signals superimposed on the pic that aren't relevant to the display NOP execution (ie. at the top and bottom of the screen where scanlines still occur but are not running the display routine). So, please ignore the R/C curve

Ideally, I should trigger the scope only when the display lines are being processed, but I will need to add an LM1881 and some extra logic / delay to blank out the signals when the non-relevant parts of the screen are drawn - I'll probably do that when I get a bit of time, but hopefully the trace is clear enough for now.
Regards
Grant