6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat Nov 23, 2024 4:52 am

All times are UTC




Post new topic Reply to topic  [ 26 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Bootstrap Debugger
PostPosted: Mon Jul 23, 2018 7:40 am 
Offline

Joined: Mon May 21, 2018 8:09 pm
Posts: 1462
I was thinking of what I might try to build for my first effort with a real 65C02, and came up with a doozy of an idea. More on that later, in some other thread perhaps. But thinking about its design led me to the question of whether I could bootstrap it without a dedicated EEPROM programmer, given that it should be capable of reflashing its own EEPROMs. This could be a useful mini-project for other people too, hence this thread.

The essential features are:
- For attachment to a debug host such as a Raspberry Pi. Assume for now that both have the same logic voltages (3.3V LVCMOS).
- Halt the CPU with RDY, latch the address bus in shift registers, and read them out, along with the various bus control signals (particularly RW, SYNC, VPB - or VPA, VDA on an '816).
- On reads, fill another shift register with data for the CPU, replacing whatever the hardware provided.
- On writes, let the CPU's data go through to the hardware. This allows the CPU to be manipulated into loading a monitor into RAM and jumping there.
- Release the CPU to run normally. The monitor can then load data over a UART and perform the timing-critical steps for burning the EEPROM.

Optional bonus features might include:
- Allow debug host to observe data provided by hardware before optionally replacing it.
- Halt CPU with BE, and allow debug host to read/write arbitrary addresses.
- Physical debug panel to replace debug host, if you think using a Raspberry Pi is "cheating".

All this could be a daughterboard to be inserted between the CPU and the rest of the machine, if it isn't integrated into the design for some reason. In daughterboard form it could be reused in almost any 6502 project.

Now to work out all the gritty details...


Top
 Profile  
Reply with quote  
 Post subject: Re: Bootstrap Debugger
PostPosted: Mon Jul 23, 2018 9:01 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8544
Location: Southern California
For ideas on pre-loading RAM before releasing the processor, I think you'll like this topic:
viewtopic.php?f=4&t=4161

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
 Post subject: Re: Bootstrap Debugger
PostPosted: Mon Jul 23, 2018 9:35 am 
Offline

Joined: Mon May 21, 2018 8:09 pm
Posts: 1462
There's some pretty crazy talk in that thread! Single-stepping the CPU and reading the address bus should take away most of the guesswork and generally make it more robust - albeit with a higher part count. But it's a device that can be reused, if it's on a daughtercard. Sort of like a JTAG parasite.

It strikes me that most shift registers can effectively be wired up directly to an SPI controller, and the Raspberry Pi happens to expose one of those on its pin header. That should greatly simplify one part of the design. I'll need to insert a bidirectional bus transceiver to isolate the data bus correctly, unless I rely on being able to insert an extra condition into all the output-enables. Beyond that, I just have to work out the timing and synchronisation logic.


Top
 Profile  
Reply with quote  
 Post subject: Re: Bootstrap Debugger
PostPosted: Mon Jul 23, 2018 12:34 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3367
Location: Ontario, Canada
Chromatix wrote:
There's some pretty crazy talk in that thread!
My 3-wire scheme? Yeah, I can't blame you for wondering about an idea that's both complex and untested. But somebody succeeded in making a Z80 do it, so... well, you know -- it became a point of pride to see if 65xx could do it, too! :wink: Maybe it's time I pulled this idea off the back burner.

The bootstrap problem is a fun one to solve, and there are lots of solutions. Maybe you'll end up with a variation of the scheme in this thread -- a scheme which *is* tested. I'm not the only one to come up with this idea. Anyway, it's pretty neat. No connection to the address bus is required, only the data bus and a few control lines (clock, reset and output-enable).

-- Jeff

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Top
 Profile  
Reply with quote  
 Post subject: Re: Bootstrap Debugger
PostPosted: Mon Jul 23, 2018 4:58 pm 
Offline
User avatar

Joined: Wed Mar 01, 2017 8:54 pm
Posts: 660
Location: North-Germany
You may take a look at this approach.


Top
 Profile  
Reply with quote  
 Post subject: Re: Bootstrap Debugger
PostPosted: Mon Jul 23, 2018 6:58 pm 
Offline

Joined: Mon May 21, 2018 8:09 pm
Posts: 1462
Hmm, the idea of attaching only to the data bus and ignoring the addresses is valid for simply bootstrapping - but since I'm initially looking for read-only access to the address lines, it doesn't really cost much to include it, and makes it clearer to the user what's going on (potentially valuable for early hardware debugging).

The thornier problem is in synchronising the output of the shift register with the CPU clock, given that the debug host will be driving the SPI master clock. The WDC CPUs can be driven by pretty much any kind of clock, mind, but I'm hoping for a design that can also be used with older 6502s that might not be fully static. With an NMOS CPU in particular, the clock has to run continuously, though the CPU will obediently wait on RDY asserted *unless* it's a write cycle. But we can just let write cycles fall through to the hardware anyway.

One wrinkle is that most 6502s don't have VPB, only the '816 and the current WDC 65C02S. This makes it slightly harder to know when RESET or NMI actually take effect, if we can't assume VPB is valid. However, after NMI there'll be a sequence of stack writes followed by a pair of reads. If the reads are given zeroes, it'll result in a JMP $0000, and a further zero read will result in BRK, triggering further stack writes and vector reads. There'll also still be SYNC signals. That should be sufficient for the debug host to figure out what type of CPU it's dealing with, and to steer it to safe program addresses for injecting fake instructions.


Top
 Profile  
Reply with quote  
 Post subject: Re: Bootstrap Debugger
PostPosted: Tue Jul 24, 2018 4:56 pm 
Offline

Joined: Mon May 21, 2018 8:09 pm
Posts: 1462
Thinking further, if one happens to have a smart interrupt controller which can intercept VPB, it can be used to direct the NMI handler to a spare piece of address space, regardless of what the ROM contains. A debug device can then be inserted into that address space, and behave like a normal-ish memory as far as the CPU is concerned. It seems perfectly reasonable to me to use NMI as a manual debug switch.

The debug device could itself be a sparse 4-byte diode-logic ROM, containing the opcodes for LDY# ($A0), STY abs ($8C), and BRA *-5 ($80 $F9). Why LDY/STY instead of using A? Because the STY abs can easily be changed to a JMP abs ($4C) under manual control, permitting a return to normal mode without triggering RESET. The operands for LDY and STY/JMP can then be provided manually, and RDY can be manipulated to run the CPU slowly (say 500kHz) through the tiny program and halt on returning to the beginning.

To enter the address and data, it is enough to have a 4x4 keypad which alternately sets the high and low nybbles of an 8-bit flipflop, and two further keys which can transfer that byte to the high and low halves of a 16-bit counter, which is incremented when the BRA is executed. To switch over to JMP instead of STY, we could co-opt the same physical switch as was used to trigger NMI in the first place, giving it a clean "debug/normal" meaning.

So we now have a way to toggle in a bootloader, which can pull the rest of the code required to flash the ROM over a serial port. It's not quite the same as a true "front panel" interface, since it co-opts the CPU instead of accessing the memory directly, but it's close enough to be useful and should be reasonably straightforward to build.


Top
 Profile  
Reply with quote  
 Post subject: Re: Bootstrap Debugger
PostPosted: Wed Jul 25, 2018 9:39 am 
Offline

Joined: Mon May 21, 2018 8:09 pm
Posts: 1462
So, here's a first pass at my interrupt controller:

Eight /IRQs from various devices go to an 8-to-3 priority encoder, whose four outputs (/Q0-2 and /G) are latched in a quad D flipflop clocked by (/VPB & Phi2). The latter ensures that the low bits of the vector table address remain stable during the vector pull, since /VPB is valid at the same times addresses are, ie. it completely overlaps Phi2 at both ends. The latched /G goes to CPU /IRQ.

When /VPB is asserted low, A1 and A2 indicate which vector is being pulled - if both high, then it's IRQ, if A1 low then it's NMI, if A2 low then it's RESET. So I generate /IRQVP with (/VPB | (A1 ~& A2)), and /NMIVP with (/VPB | ~A2). The latter asserts on IRQ pulls as well as NMI.

My goal is to leave RESET alone, so that is still vectored through ROM, but to bring NMI down to the debug I/O window at $BFFx and IRQ down to a table at the top of zero-page. So A14' is (A14 & /NMIVP), and Ax' for x in {8..13, 15} is (Ax & /IRQVP). Then A1' is (A1 & (/IRQVP | /Q1)) from the quad D flipflop, and similarly for A2', A3'.

What's slightly nasty about this is that there's a 4-gate delay from A2 and A1 to A1' et al, and three gate delays to the other Ax'. It's not so easy to see how to get around that, though, and it probably doesn't matter since accesses incurring that path delay always go to the relatively fast 55ns SRAM, or to the debug port which will have a multi-cycle wait state.

An important property of this arrangement is that the actual IRQ vectors are in RAM, rather than in special registers that would be fiddly to wire up and to locate in the address map. I'm also keen to avoid using CPLDs because their static power figures are *terrible*, so the above amounts to six-and-bits-of-some-other 74HC chips.


Top
 Profile  
Reply with quote  
 Post subject: Re: Bootstrap Debugger
PostPosted: Thu Jul 26, 2018 3:51 am 
Offline

Joined: Mon May 21, 2018 8:09 pm
Posts: 1462
Making a nice, reusable front-panel interface is being significantly complicated by the virtual extinction of hex-to-7seg decoder ICs. There's a few of the old 7seg digits with built-in decoders on eBay, but the datasheets for those strongly imply that they require a 5V nominal supply, not 3.3V. By contrast, I can buy any number of different varieties of BCD decoders which either blank or produce unreadable trash from $A to $F codes, and which are therefore useless for this application, even though adding support for hex digits wouldn't impair their BCD functionality at all.

That might be the one thing I can justify using a PLD or two for on this project, since it'll be associated with power-hungry LEDs and can be removed (and put aside for the next project) once the boot ROM is stable. Or I might punt on it and use LEDs wired directly to the bits, or possibly 4-to-16 decoders wired to bargraph strips.

Meanwhile, I've got a notebook page covered liberally with more details of the control circuitry I'll need to correctly sequence /NMI with /RESET on power-up with the debug switch set, and to correctly implement wait-state signals without incurring a power drain when the CPU executes WAI and pulls RDY low itself - which is, of course, when you most want to *save* power in a battery-powered machine. The combination of these two functions uses a pair of JK flipflops and all of a quad Schmitt-triggered NAND chip.

The RDY problem is that when the CPU goes to sleep, it asserts RDY (which is normally an input) low, but at that moment none of the external devices will be triggering a wait-state, so the controlling gate will be driven high. There will therefore be a current through the resistor dividing the two. One can reduce this current by increasing the resistor value, but this risks being unable to bring RDY high promptly after an external wait-state, which could be a performance problem. With a relatively low value (say 1KΩ) the drive is prompt, but the current is up to 3.3mA, several orders of magnitude higher than any other quiescent device in the system.

So, my solution is to detect the CPU's negation of RDY (using an XOR gate), and feed a latched copy of it back to the driver gate. Any of the three wakeup sources (IRQ, NMI, Reset) will then cancel that feedback and allow the CPU to fetch the appropriate vector. As a bonus, this provides a way to possibly switch to a slower clock, later on, so that the system activity in sleep mode is closer to actual quiescence.

And can I just observe that whatever planet KiCAD comes from, it's not the same one as the Macintosh Human Interface Guidelines. I just can't seem to internalise how to use it effectively.


Attachments:
20180726_062335.jpg
20180726_062335.jpg [ 3 MiB | Viewed 2430 times ]
Top
 Profile  
Reply with quote  
 Post subject: Re: Bootstrap Debugger
PostPosted: Thu Jul 26, 2018 6:05 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8507
Location: Midwestern USA
Chromatix wrote:
The RDY problem is that when the CPU goes to sleep, it asserts RDY (which is normally an input) low, but at that moment none of the external devices will be triggering a wait-state, so the controlling gate will be driven high. There will therefore be a current through the resistor dividing the two. One can reduce this current by increasing the resistor value, but this risks being unable to bring RDY high promptly after an external wait-state, which could be a performance problem. With a relatively low value (say 1KΩ) the drive is prompt, but the current is up to 3.3mA, several orders of magnitude higher than any other quiescent device in the system.

So, my solution is to detect the CPU's negation of RDY (using an XOR gate), and feed a latched copy of it back to the driver gate. Any of the three wakeup sources (IRQ, NMI, Reset) will then cancel that feedback and allow the CPU to fetch the appropriate vector. As a bonus, this provides a way to possibly switch to a slower clock, later on, so that the system activity in sleep mode is closer to actual quiescence.

An alternative is to "isolate" RDY from whatever is driving it with a small signal Schottky diode. Connect the diode's anode to RDY and the cathode the controlling device. RDY must be pulled up to Vcc with a suitable resistor.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
 Post subject: Re: Bootstrap Debugger
PostPosted: Thu Jul 26, 2018 6:11 am 
Offline

Joined: Mon May 21, 2018 8:09 pm
Posts: 1462
Quote:
RDY must be pulled up to Vcc with a suitable resistor.

...which immediately reintroduces the original problem, when the CPU pulls RDY down.


Top
 Profile  
Reply with quote  
 Post subject: Re: Bootstrap Debugger
PostPosted: Thu Jul 26, 2018 9:40 pm 
Offline

Joined: Sat Dec 13, 2003 3:37 pm
Posts: 1004
I know this is a hobby forum, and folks do stuff for the sake of doing stuff.

But, really, isn't just a lot better to fight the details of getting a UART to work the first time, and then just use one of the many available monitors? Maybe add a "programmers button" (as we called it on the Macintosh) that can interrupt the CPU in to the monitor?

Then, all you need to do is get a raw UART to work (which is a reasonably well documented topic) to get basic I/O, and once that works, you upload a known working monitor.

How do you know the monitor it working? Because you used one that was already available, and you ported/bootstrapped it using a simulator before you burned anything in to ROM.

Just seems like a lot to have to go through putting all the stuff on the board.


Top
 Profile  
Reply with quote  
 Post subject: Re: Bootstrap Debugger
PostPosted: Thu Jul 26, 2018 10:00 pm 
Offline

Joined: Mon May 21, 2018 8:09 pm
Posts: 1462
Actually, the NMI redirection turns out to be a very small modification of the IRQ vector redirection I already wanted. Look at the way A14' is produced in a slightly different way from the other high address bits - that really is it.

Wait-states and power management will be needed anyway (because the EEPROMs won't run at 8MHz without help), and that accounts for almost all of the rest of the circuitry on that page - except for a DPST switch which functions as the "programmer's key" you mention, and interfaces with three Schmitt trigger gates that aren't needed for the reset circuit, but which come in the same package anyway so I might as well use 'em. Flipping the debug switch back to "normal" will have the side-effect of changing the faked-up STY instruction to a JMP, and releasing the wait-state holding the CPU for my input.

I plan for the toggle panel itself (not on the above page) to be a daughterboard that can be removed and reused to bring up later versions of similar machines, and mapped into part of a 1K region reserved for I/O. A tiny 16-byte region is enough to hold the NMI vector pointing to itself, and the 7-byte loop for toggling in a program. It might well be constructed on stripboard instead of a proper PCB. The advantage of doing it this way is that I don't need to buy a dedicated EEPROM programmer device just to get the UART running, since I can flash them in software in situ, and I can load the ROM images and flashing routine over the UART. Only the UART transfer routine has to be toggled in by hand.


Top
 Profile  
Reply with quote  
 Post subject: Re: Bootstrap Debugger
PostPosted: Fri Jul 27, 2018 3:45 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8507
Location: Midwestern USA
Chromatix wrote:
Quote:
RDY must be pulled up to Vcc with a suitable resistor.
...which immediately reintroduces the original problem, when the CPU pulls RDY down.

No it doesn't.

The pullup resistor's value is selected to allow the MPU to drive RDY low when a WAI instruction is executed. I use 3.3K in my POC units, which means RDY only has to sink 1.5mA to get itself to ground.

The use of the Schottky diode allows the MPU to sink RDY without loading the device at the other end of the "wire." When that device drives its output low, the diode will be forward biased and RDY will be pulled low.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
 Post subject: Re: Bootstrap Debugger
PostPosted: Fri Jul 27, 2018 4:38 am 
Offline

Joined: Mon May 21, 2018 8:09 pm
Posts: 1462
I understand that. But 1.5mA is still a thousand times more than the 65c02 itself is supposed to consume when quiescent. It doesn't actually matter whether that's going through a resistor pulled up at one end by a gate, or directly to Vcc - it's still passing 1.5mA. It's a small waste, but to me, still a waste if there's a straightforward way of avoiding it. Remember, I had an NC200 that would literally last for weeks on a set of C-size NiCads, with files held in SRAM which, therefore, couldn't simply be powered down.

By actively setting the gate low when the CPU is found to have pulled RDY low, and only setting it high again when an interrupt or reset occurs, that waste of power is avoided. The cost is a few more gates on the board, which consume much less power themselves.

I won't claim there aren't any errors in my hand-sketched diagram. I've actually found a couple today, in the reset/debug switch circuit. But I don't put in circuits without a good reason behind them.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 26 posts ]  Go to page 1, 2  Next

All times are UTC


Who is online

Users browsing this forum: Google [Bot] and 26 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: