oscilloscope as a Logic Analyzer
Posted: Wed Aug 25, 2010 7:43 pm
This is a spin-off from ElEctric_EyE's topic here.
The goal is to determine whether your new, untested system is executing your loop at $C000.... or executing garbage at who-knows-where! To make things as simple as possible and eliminate extraneous variables, the loop is simply one instruction: JMP $C000 -- ie, jump to itself. The RESET vector goes straight here. Your loop should show the following pattern (assuming regular, periodic clocks and no Wait States etc):
What we expect on the data bus is $4C $00 $C0 (endless repetitions of your JMP $C000 instruction), with SYNC high on the $4C. Your scope shows you only 1 bit at a time, though -- not the entire byte. Luckily, it's no great trick to read the columns vertically, which shows, in time, what each line is doing, cycle by cycle. ie: d7 is 0 0 1. d6 is 1 0 1. d5 is 0 0 0. [etc] SYNC is 1 0 0.
One challenge is that, for example, d7 may appear as 0 0 1 or as 0 1 0 or as 1 0 0 -- which is really just the same pattern, but viewed from different perspectives, timing-wise. So, having a consistent timing reference is gonna cut through a lot of confusion, obviously.
A useful reference in this case is SYNC, which we expect to be true only on the opcode fetch: the "first" cycle of our loop. So, hook one probe on SYNC and leave it there. Set your scope to synchronize to that signal. Be sure you have a stable display. THEN use the OTHER probe to go poking around and checking individual signals against the chart! Because you have your reference, there's no confusion over which cycle is which. Having the reference (by using two channels) is what makes this powerful technique possible. I call it the poor man's Logic Analyzer.
Address lines tend to have cleaner signals than data lines, so maybe I should've mentioned them first. (Data lines usually have crap on them except near the end of each cycle -- so that is what you need to observe.) OK, here's my chart again but showing some address lines. The same "read the columns vertically" method applies:
I haven't shown all the address lines, but you get the idea I'm sure. What the address lines tell you is where the cpu is fetching code from. If it's not fetching from $C000 then it's executing garbage (which it will willingly do -- cpu's is dum) 
-- Jeff
The goal is to determine whether your new, untested system is executing your loop at $C000.... or executing garbage at who-knows-where! To make things as simple as possible and eliminate extraneous variables, the loop is simply one instruction: JMP $C000 -- ie, jump to itself. The RESET vector goes straight here. Your loop should show the following pattern (assuming regular, periodic clocks and no Wait States etc):
Code: Select all
d7 d6 d5 d4 d3 d2 d1 d0
$4C is binary: 0 1 0 0 1 1 0 0 [SYNC=1 for this cycle]
$00 is binary: 0 0 0 0 0 0 0 0 [SYNC=0 for this cycle]
$C0 is binary: 1 1 0 0 0 0 0 0 [SYNC=0 for this cycle]One challenge is that, for example, d7 may appear as 0 0 1 or as 0 1 0 or as 1 0 0 -- which is really just the same pattern, but viewed from different perspectives, timing-wise. So, having a consistent timing reference is gonna cut through a lot of confusion, obviously.
A useful reference in this case is SYNC, which we expect to be true only on the opcode fetch: the "first" cycle of our loop. So, hook one probe on SYNC and leave it there. Set your scope to synchronize to that signal. Be sure you have a stable display. THEN use the OTHER probe to go poking around and checking individual signals against the chart! Because you have your reference, there's no confusion over which cycle is which. Having the reference (by using two channels) is what makes this powerful technique possible. I call it the poor man's Logic Analyzer.
Address lines tend to have cleaner signals than data lines, so maybe I should've mentioned them first. (Data lines usually have crap on them except near the end of each cycle -- so that is what you need to observe.) OK, here's my chart again but showing some address lines. The same "read the columns vertically" method applies:
Code: Select all
A15...A2 A1 A0 d7 d6 d5 d4 d3 d2 d1 d0
$C000 holds the $4C: 1 0 0 0 0 1 0 0 1 1 0 0 [SYNC=1 for this cycle]
$C001 holds the $00: 1 0 0 1 0 0 0 0 0 0 0 0 [SYNC=0 for this cycle]
$C002 holds the $C0: 1 0 1 0 1 1 0 0 0 0 0 0 [SYNC=0 for this cycle]-- Jeff