Locked room challenge -- bootstrapping a design and build
Posted: Mon Jul 31, 2023 1:28 am
I've set myself a challenge that might seem a bit silly to some, but helps me to learn and discover in a way that is fun to me...
Imagine that you are in a locked room (or on a nice Island or whatever you fancy), and you have a pile of chips and data sheets, wire and basic electronics-making supplies and equipment. Not in the room is there any preprogrammed non-volatile storage or already designed and built computer systems. Your goal is to incrementally build up a fully working 6502 computer with keyboard, video, storage and the ability to program it nicely, and maybe create some video games.
So here is where I am in this process: This has just gotten to the point where I can program in machine language. entering bytes into NVRAM using a hex keypad, and watch the CPU run, either using the LED address/data/control line visualization when single stepping the clock, or using an oscilloscope to look at the various lines when running up to 12.5875 MHz so far.
There is one module per wireless proto board. The first one I built is the clock/counter module in the upper left, with a crystal oscillator module starting a divide-by-two chain at 25.175 MHz. The second module is in the lower left, which turns hex keypad presses into keypress events. The third is in the lower right. That takes hex keypress events and turns them into a nonvolatile RAM byte editor. There is no hex-to-segment/font decoding yet, so the address and data values are displayed in binary for now. Finally, the programmed NVRAM can be moved to the upper right CPU module to be executed. The CPU module proper is the upper half, with the CPU, clock half-stepping circuit, address decoding and RAM control logic. The lower half has a bunch of LEDs to visualize the address, data, control and memory-mapped output latch (the latch is the chip just to the right of the LEDs).
My long-winded journal of the design and build process, with a number of tangents, is captured at http://cognigraph.com/6502. I'll put more at that web link as I go along and post here on the forum as well.
The key chips I'm using so far are:
Here are some details on each of the four prototype modules so far.
CLOCK MODULE
I started by using the 12-bit ripple counters tied to the 25.175MHz crystal oscillator module, but realized the ripple counters have nasty glitches in the count values if you use their outputs directly. While it is possible to do some sort of latching to fix this, that seemed overly complicated. Searching around, there is a sweet 74xx163 counter chip that deals with this latching nicely. I also played with using 74xx175 flip flops directly, maybe combined with some logic similar to what the 74xx163 has. This would have the advantage of providing normal and inverted outputs per clock counter bit.
My second build-out after the ripple counter demo was using straight 74F163’s clocked directly from the 25.175MHz clock. This worked when chaining together around six of them (4*6=24 bits count out of the 32 bits I was aiming for), then the seventh counter chip would not count. It turns out this was due to the chained propagation delays of the carry lookahead logic: it just could not manage that many chips in the chain at the high clock speed. So I placed a one-bit flip-flop counter using a 74F175 at the beginning to divide the fast video clock in two, to 12.5875MHz, and was able to chain eight 4-bit 74F163 counters off of that. With that fix, I think the clock module is adequate, and will supply the following interface lines: GND, +5v, clear input, 25.175MHz (640x480 VGA dot clock), 12.5875MHz (CPU clock), and count bits 0 to 31. Total lines used: 37. It turns out that the big soldered proto boards I have include 37 pins on the edge connector array. What luck!
The clock module counter has 32 bit, with cycles time going from 6.29375MHz in powers of two divisions:
Inputs: 10 consecutive clock lines (bits 6-15), ground and +5v
Outputs: positive-edge clock line, 4 data lines, for hexadecimal keypress events
The keypad is scanned 192 times per second. For each keypad row, four R-S latches are set initially, and selectively cleared should a key down be detected for the respective key in the row. Near the end of the per-row time slot, these R-S latches are copied/clocked-out to a set of four serial-in/parallel-out shift registers, and before the row increments, the shift registers are scanned one-at-a-time to look for key up-to-down (keypress) transitions. Each keypress event found generates a positive-going pulse on the output clock line, and the four associated data lines are the row and column bits appended together to form the hexadecimal value of the key being pressed.
NVRAM DATA ENTRY MODULE
Based on keypress events from the hexadecimal keypad module, the data entry module allows setting up a 16-bit address and 8 bit data value, visualized 1:1 as an LED per bit, and has a ‘write’ button to store the byte at the address. The NVRAM reads the byte at the selected address and visualizes this in a separate 1:1 LED display.
The data entry module is fully functional and tested on a cheap 32kB SRAM as of 2023-06-30. Next step: try getting the expensive NVRAM working. This will require delicate soldering to the proto adapter board, plus hardwiring the extra unused address lines.
By mid July 2023 the NVRAM editing was working. The first NVRAM module got borked, the data MSB stuck high, likely due to the difficulty of soldering the dang TSOP II chip to the DIP adapted board. My second try soldering a second NVRAM worked. The NVRAM indeed remembers the data I have written to it, despite power downs.
INITIAL 6502 MODULE
To start, I am making the 6502 setup run off or a manual half-cycle-step clock, with an S-R latch set high/low with respective pushbuttons. I’ve also added a reset pushbutton and lots of 1x10 LED arrays to visualize all the state, including address, data and clock/control/output lines. I’ll put in a simple clock/counting program in the NVRAM, add memory-mapped output to an 8-bit latch, and see how it goes.
[July 20 or so....] It worked! The memory-mapped output latch shows the count incrementing correctly during half-step execution, and the latch bits show the correct frequencies on the oscilloscope when running at various CPU clocks.
-----------------------
Okay, that is it for the moment. I have a lot more details to document on the work so far, but this gives you an outline. The timing diagram on the keypad scanning is fairly involved/tricky. The CPU/RAM/latch address decoding and control/timing logic is I'm sure well known here, but I should document that in case I'm doing something weird.
I'd love to hear what you all think or would like to know more about.
--Mark Duchaineau
Imagine that you are in a locked room (or on a nice Island or whatever you fancy), and you have a pile of chips and data sheets, wire and basic electronics-making supplies and equipment. Not in the room is there any preprogrammed non-volatile storage or already designed and built computer systems. Your goal is to incrementally build up a fully working 6502 computer with keyboard, video, storage and the ability to program it nicely, and maybe create some video games.
So here is where I am in this process: This has just gotten to the point where I can program in machine language. entering bytes into NVRAM using a hex keypad, and watch the CPU run, either using the LED address/data/control line visualization when single stepping the clock, or using an oscilloscope to look at the various lines when running up to 12.5875 MHz so far.
There is one module per wireless proto board. The first one I built is the clock/counter module in the upper left, with a crystal oscillator module starting a divide-by-two chain at 25.175 MHz. The second module is in the lower left, which turns hex keypad presses into keypress events. The third is in the lower right. That takes hex keypress events and turns them into a nonvolatile RAM byte editor. There is no hex-to-segment/font decoding yet, so the address and data values are displayed in binary for now. Finally, the programmed NVRAM can be moved to the upper right CPU module to be executed. The CPU module proper is the upper half, with the CPU, clock half-stepping circuit, address decoding and RAM control logic. The lower half has a bunch of LEDs to visualize the address, data, control and memory-mapped output latch (the latch is the chip just to the right of the LEDs).
My long-winded journal of the design and build process, with a number of tangents, is captured at http://cognigraph.com/6502. I'll put more at that web link as I go along and post here on the forum as well.
The key chips I'm using so far are:
- CPU: W65C02S PDIP
NVRAM: amazing CY14E116L-ZS25XI (acts like a static RAM, similar performance, but saves itself to a NV store on the same chip on power down)
Here are some details on each of the four prototype modules so far.
CLOCK MODULE
I started by using the 12-bit ripple counters tied to the 25.175MHz crystal oscillator module, but realized the ripple counters have nasty glitches in the count values if you use their outputs directly. While it is possible to do some sort of latching to fix this, that seemed overly complicated. Searching around, there is a sweet 74xx163 counter chip that deals with this latching nicely. I also played with using 74xx175 flip flops directly, maybe combined with some logic similar to what the 74xx163 has. This would have the advantage of providing normal and inverted outputs per clock counter bit.
My second build-out after the ripple counter demo was using straight 74F163’s clocked directly from the 25.175MHz clock. This worked when chaining together around six of them (4*6=24 bits count out of the 32 bits I was aiming for), then the seventh counter chip would not count. It turns out this was due to the chained propagation delays of the carry lookahead logic: it just could not manage that many chips in the chain at the high clock speed. So I placed a one-bit flip-flop counter using a 74F175 at the beginning to divide the fast video clock in two, to 12.5875MHz, and was able to chain eight 4-bit 74F163 counters off of that. With that fix, I think the clock module is adequate, and will supply the following interface lines: GND, +5v, clear input, 25.175MHz (640x480 VGA dot clock), 12.5875MHz (CPU clock), and count bits 0 to 31. Total lines used: 37. It turns out that the big soldered proto boards I have include 37 pins on the edge connector array. What luck!
The clock module counter has 32 bit, with cycles time going from 6.29375MHz in powers of two divisions:
- Bits 0-3:
6.29375mHz/158.9ns, 3.146875mHz/317.8ns, 1.5734375mHz/635.6ns, 786.71875kHz/1.271us
Bits 4-7:
393.359375kHz/2.542us, 196.6796875kHz/5.084us, 98.33984375kHz/10.169us, 49.169921875kHz/20.34us
Bits 8-11:
24.5849609375kHz/40.68us, 12.2924804688kHz/81.35us, 6.14624023438kHz/162.70us, 3.07312011719kHz/325.40us
Bits 12-15:
1.53656005859kHz/650.80us, 768.280029297Hz/1.30ms, 384.140014648Hz/2.60ms, 192.070007324Hz/5.21ms
Bits 16-19:
96.0350036621Hz/10.41ms, 48.0175018311Hz/20.83ms, 24.0087509155Hz/41.65ms, 12.0043754578Hz/83.30ms
Bits 20-23:
6.00218772888Hz/166.61ms, 3.00109386444Hz/333.2ms, 1.50054693222Hz/666.4ms, 0.75027346611Hz/1.333s
Bits 24-27:
2.666s, 5.33s, 10.66s, 21.33s
Bits 28-31:
42.65s, 85.30s, 170.60s, 341.2s
Inputs: 10 consecutive clock lines (bits 6-15), ground and +5v
Outputs: positive-edge clock line, 4 data lines, for hexadecimal keypress events
The keypad is scanned 192 times per second. For each keypad row, four R-S latches are set initially, and selectively cleared should a key down be detected for the respective key in the row. Near the end of the per-row time slot, these R-S latches are copied/clocked-out to a set of four serial-in/parallel-out shift registers, and before the row increments, the shift registers are scanned one-at-a-time to look for key up-to-down (keypress) transitions. Each keypress event found generates a positive-going pulse on the output clock line, and the four associated data lines are the row and column bits appended together to form the hexadecimal value of the key being pressed.
NVRAM DATA ENTRY MODULE
Based on keypress events from the hexadecimal keypad module, the data entry module allows setting up a 16-bit address and 8 bit data value, visualized 1:1 as an LED per bit, and has a ‘write’ button to store the byte at the address. The NVRAM reads the byte at the selected address and visualizes this in a separate 1:1 LED display.
The data entry module is fully functional and tested on a cheap 32kB SRAM as of 2023-06-30. Next step: try getting the expensive NVRAM working. This will require delicate soldering to the proto adapter board, plus hardwiring the extra unused address lines.
By mid July 2023 the NVRAM editing was working. The first NVRAM module got borked, the data MSB stuck high, likely due to the difficulty of soldering the dang TSOP II chip to the DIP adapted board. My second try soldering a second NVRAM worked. The NVRAM indeed remembers the data I have written to it, despite power downs.
INITIAL 6502 MODULE
To start, I am making the 6502 setup run off or a manual half-cycle-step clock, with an S-R latch set high/low with respective pushbuttons. I’ve also added a reset pushbutton and lots of 1x10 LED arrays to visualize all the state, including address, data and clock/control/output lines. I’ll put in a simple clock/counting program in the NVRAM, add memory-mapped output to an 8-bit latch, and see how it goes.
[July 20 or so....] It worked! The memory-mapped output latch shows the count incrementing correctly during half-step execution, and the latch bits show the correct frequencies on the oscilloscope when running at various CPU clocks.
-----------------------
Okay, that is it for the moment. I have a lot more details to document on the work so far, but this gives you an outline. The timing diagram on the keypad scanning is fairly involved/tricky. The CPU/RAM/latch address decoding and control/timing logic is I'm sure well known here, but I should document that in case I'm doing something weird.
I'd love to hear what you all think or would like to know more about.
--Mark Duchaineau