Building a simple CNC microscope (part 1)

Simple != cheap. Just FYI.

Since I've been really enjoying reverse-engineering the Unisonic 21 CPU chip, I've resolved to get into decapping, photographing, reverse-engineering and archiving dies of older 1970s and 1980s chips. I went to a bunch of surplus stores here in the Bay Area to pick up boards and individual chips in the [5400 and 7400] logic family. Primarily [Excess Solutions] and to a lesser extent [Weird Stuff Warehouse], while [Halted] wasn't a very good source (and their chips are all behind the counter WTF).

These are very simple logic chips. Perhaps the most complicated is the ['181 4-bit ALU]. But, they're simple enough to level up on TTL with, and there are many variations and manufacturers of the same chip to compare.

Following in [John McMaster's footsteps], I hit the eBay to find a metallurgical microscope, a motorized XY stage, and a 20x planar apochromatic objective with long working distance.

For the metallurgical microscope, I found this awesome [Olympus BH2 microscope] (US $1600 shipped) (photo to come later). It is bolted to an optical breadboard, came with four objectives plus an objective adapter thing, and a bunch of other measurement things that I didn't really need. But it is awesome because I can add whatever I need to the base.

The BH2 is also infinity-corrected, meaning that you can use infinity-corrected objectives with it, which are plentiful. The microscopes that aren't infinity-corrected have a fixed tube length, and you need to use the same tube-length designated objectives. That is really limiting. See [this Olympus article] about objectives for some useful information about what tube length is, and [this article] for other objective terminology.

At first, I found what seemed like the perfect XY stage. It was actually an XYZ stage made by Newport Klinger Micro-Controle. It uses variable reluctance stepper motors, which sucks because they are noisy and controllers are hard to come by. And when I got it, it turned out to be a YZ stage because the X axis was broken, and taking it apart is proving unreasonably difficult.

So I gave that up as a bad job, and searched for more motorized XY stages, and found this awesome thing, called "MMT 80x80 XY axis Motorized Stage Cross Roller Precision VEXTA PK544-NB MRS-I-10" in the listing (US $400 shipped from Korea). It was apparently pulled from equipment.

A bit of digging showed that it used [Oriental Motor PK-544] 5-phase stepper motors with some optical limit switches, and the recommended drivers were Oriental Motor Vexta DFC1507 modules which I found at a local place (US $140 each). And there's very clear [documentation] for it!

So I ordered all that stuff and mechanically, at least, the stage works fantastically. It has lots of holes in it for breadboarding. Very customizable, and the step size seems nice and small.

I already had a [BeagleBone Black] which I wanted to use because it has [MachineKit] available for it, basically a CNC controller, and that uses the BBB's PRUs (Programmable Real-time Units) meaning that it's far less likely to stutter since the control signals are offloaded to a dedicated processor. All I really needed was pulse output (and later, limit switch input), so I chose the simplest configuration I could find,  CRAMPS. This refers to a hardware driver, but I didn't need one because I already had a driver, the Vexta units.

The only problem was that the Vexta units take a CW/CCW pulse while the PRU configurations in MachineKit can only output STEP/DIR pulses. The CW/CCW or UP/DOWN config is [not implemented], but there's [a placeholder] for it, as if I don't have enough projects :( .

So I doodled for a little while and rooted around in my surplus chip box and came up with a 74352 which could be configured to convert two STEP/DIR pairs into two CW/CCW pairs. (schematic to come).

Finally, I needed the objective. Apparently Mitutoyo is the best, and you really want an objective that is not likely to screw you over. Something plano (so no distortion around the edges) and apochromatic (so no to little chromatic distortion) and long working depth (because I'll want to image dies that are still in their packages, so at least 2mm). Also infinity-corrected. The Mitutoyo MPLAN APO 20x is perfect, but you [really don't want to buy one new] if you don't have to (eBay, US $800 shipped from Korea). Get one with a money-back return policy.

It's pretty huge, and luckily I had that objective adapter thing. That's why infinity-correction is important. I could whack that adapter in there and it wouldn't matter much how long it was, since the rays inside are parallel.

Next, I need to put everything together and put a camera on it. But first, a test image. This was not taken with the 20x objective. It is a 74245 die. The reticle in the photo is from the eyepiece.

Total so far: US $3080. As I said, it's not cheap.

Unisonic 21: Another driver circuit, more simulations in LTSpice

Tracing out the circuit section after the clock generator, I found some really large capacitors:

Next to each capacitor I've put their size in squares. C3 is familiar, being part of a bootstrap load. But what are huge capacitors C1 and C2 for? And why is there an extra capacitor C4 just hanging out across Q15?

Searching through the Rockwell patents, I found patent [US3480796], "MOS Transistor Driver Using a Control Signal". The reference at the beginning of the patent to a filing called "MOS Driver Using Capacitive Feedback" is, in fact, patent [US3506851] which I mentioned back in [part 2], and explored in the [bootstrap load simulation post].

In that simulation, we saw that the output voltage decayed, and it was worse with a really small capacitor in the bootstrap load. This patent is supposed to overcome that decay problem.

Figure 1 from patent US3480796.

Figure 1 from patent US3480796.

The input stage shown is an inverter. The original signal (8 in the diagram) drives the high-side transistor (5) while the inverted signal (4) drives the low-side transistor (1). There's an extra capacitor (C) and signal (17) which we need to explore. C1 in the diagram represents "the parasitic capacitance of the device", which for now I'll take to mean the gate capacitance of transistor 1.

I've redrawn this circuit, without the extra capacitor, in LTSpice. I've also flipped it so that the supply voltage is positive. Finally, the W/L of the transistors in the inverter are set as in the previous post, and the output transistors' W/L are set to 16/1 since they are supposed to be driver transistors.

Looking at G- (the red trace), we see that it goes from 1.5v to 14v as expected for a circuit without a bootstrap load. The output trace (blue) goes from 4.8v to 14.6v. That weak zero-level (4.8v) is due to the weak zero-level of the non-bootstrap load (1.5v). The weak zero-level is also what would happen if M9 were replaced with a bootstrap load with a very small capacitor, although there would be a brief period with a "good" output before the output decayed.

The patent describes adding a large capacitor at G-, fed by a signal Φ (VPH in the below schematic).

When the low-side transistor M1 is turned on (by G- going low, meaning IN is high), VPH goes high. This charges up the capacitor to VPLUS minus the threshold voltage (14.6-1.5, or 13.1v). Once the capacitor is charged up, VPH goes low, and because capacitors resist changes in voltage, this drives G- very negative, to -13.1v. And, like in the bootstrap load, this turns M1 on very strongly. The larger C1 is, the longer it will take for the output to decay.

In the simulation trace below, V(n001) is the PH signal. I've set it to be on for 0.1 msec.

We can see that after 0.1 msec, G- is driven very negative, which has the effect of turning M1 on strongly, which will let the output be driven strongly to 0v. We can also see that G- is decaying.

This circuit has the same effect as a bootstrap load, except that the capacitor is controlled by an external signal rather than the input signal. Why is this important?

For one, these output transistors are large and meant to drive heavy loads. Replacing the 100k output resistor with 10k barely changes the output voltage, but the bootstrap load cannot handle this output.

At 10k load, the bootstrap load can only drive the output down to about 5.4v.

At 10k load, the bootstrap load can only drive the output down to about 5.4v.

When the output transistors M1 and M3 are large, the increased drive can bring the output to about 0.6v on the low side, but only to around 11v on the high side.

When the output transistors M1 and M3 are large, the increased drive can bring the output to about 0.6v on the low side, but only to around 11v on the high side.

Also, large transistors come with large gate capacitances, which effectively adds more load.

So, that's the purpose of those large capacitors in the Unisonic 21 circuit. We can see that the signal marked PH is the external signal for capacitor C1 which helps drive Q2 low. Q9 and Q10 form a NAND gate. The /A signal is one input to that gate, while the other signal is an inverted delayed version of /A, courtesy Q14 and C4. The result is a pulse, which is just what is needed to drive the large capacitor.

Equivalent circuit.

Equivalent circuit.

What is also important is that for logical simulation purposes, this circuit has no effect. It is purely there to improve the drive characteristics of the output, and if the output is idealized, this circuit disappears.

Chip Decapping Adventure #1

I decided to start my adventures decapping chips with a very low-impact method that's been talked about: decapping with rosin. Rosin is the solid form of resin. Rosin can be most often gathered from eBay under the name Colophony, where it goes for not very much per pound.

A pound of rosin from eBay for USD 9.00, plus 7.00 shipping.

A pound of rosin from eBay for USD 9.00, plus 7.00 shipping.

Next I bought this stuff:

  • Steinel type 3482 temperature-controlled heat gun (eBay, USD 149 plus 5 shipping
  • 10-pack borosilicate test tubes, 18mm diam x 150mm long (eBay, USD 10)
  • Acetone 99.5%, 950ml (Duda Diesel, USD 8 plus 9 shipping)
  • Safety wash bottle, 1000ml, Karter Scientific #217H1 (eBay, USD 12)
  • Test tube clamp, 45mm, Eisco Labs #CH0688A (eBay, USD 12.50)
  • Ultrasonic heater/cleaner, 2L, unbranded Chinese manufacture (eBay, USD 55 plus 5 shipping)

Also a stand which a friend welded together, that could hold the test tube clamp. And finally, I already had a Fluke 87V multimeter with type K thermocouple.



Next, I stuck the thermocouple in the test tube and aimed the heat gun at it. The temperature in the air in the test tube was always below the temperature reading on the heat gun, and the higher the temperature setting, the more the deviation.

I took a chip, a 74S10 (a triple three-input TTL NAND gate, manufactured the 14th week of 1980) that I had many of, and, with a Dremel and a cut-off wheel, slowly whisked off very thin layers of epoxy off the back of the chip until the back end of the die carrier became visible. This allowed me to cut off the non-die portions of the package.

I've splayed out the pins so that the chip could be held in a vise while being Dremelled.

I've splayed out the pins so that the chip could be held in a vise while being Dremelled.

Next, I placed three crystals of rosin in the tube, put the nozzle of the heat gun almost against it, and started it up. I put the thermocouple touching the glass, where the nozzle was aimed. The thermocouple registered 175 deg F [80 C] when the crystals started to melt -- the heat gun was set to 230 F [110 C] at this point. At 240 F [115 C] on the thermocouple (280 F [140 C] on the heat gun) the crystals were thoroughly melted into a brown-yellow viscous liquid. At higher temperatures, the rosin became thoroughly liquid.

I made a little basket out of ordinary metal window mesh. I put the chip in, and lowered it into the liquid. I also decided to put the thermocouple in as well. At a measured temperature of 373 F [190 C] (550 F [290 C] on the heat gun) a few small bubbles started to stream from the chip. I left it there for 30 minutes, then increased the temperature to measure 399 F [205 C], and left it there for another 30 minutes.

Then I removed the chip with basket, placed it in another test tube, let it cool a bit, put some acetone in to cover the chip, and placed it in the ultrasonic cleaner filled with distilled water, for five minutes.

After this, the chip was clean, but there was no evidence of the epoxy being affected. Even the lettering was still intact.

I reheated the rosin, put the chip and basket back in, and raised the temperature to measure 447 F [230 C] (600 F [315 C] on the heat gun). I saw what appeared to be silvery metallic dust circulating in the liquid. I increased the temperature to 570 F [300 C] (800 F [425 C] on the heat gun). At this point the rosin liquid was boiling, but not vigorously. I left it for 60 minutes, then removed and cleaned in acetone and ultrasonic as above.

I found that the chip had cracked along a line apparently just above the die, so I removed the epoxy half and put the chip back in the basket. I had also noticed that the thermocouple read hotter near the top of the liquid (for example, 625 F [330 C] at the top but 560 F [295 C] at the bottom of the test tube) so I affixed the thermocouple so it was measuring the top of the liquid.

The piece on the right contains the die.

The piece on the right contains the die.

This time I set the measured temperature at 650 F [345 C] (900 F [480 C] on the heat gun) and left it in for 15 minutes. At this point the color of the liquid was brown-black. I removed the chip and cleaned again.

This time, I found that I could just pick the package apart.

The remains after removing the die. The square metal piece is not the metalization ring mentioned below, but rather was surrounding the die.

The remains after removing the die. The square metal piece is not the metalization ring mentioned below, but rather was surrounding the die.

The die was separated, but had cracked in one corner. There was also epoxy in the middle. I believe the metalization layer seems partially gone. it looks like copper-colored metalization is covering silver-colored metalization. The die itself appears black. I've most often seen a ring of metalization around the outside of the die, but it seems that while the ring is there, the metalization is not. I fear the metalization has been partially removed.

Die photo taken with AmScope SM-4TZ-144A at around 90x magnification, the highest I can go.

Die photo taken with AmScope SM-4TZ-144A at around 90x magnification, the highest I can go.

It is possible that the multiple heat-cool cycles cracked the die. Or, it could have been due to the high temperatures (up to 650 F [345 C]).

Next, I am waiting for an AmScope ME300TZB-2L-10M metallurgical microscope which should be able to take much higher-resolution images. I'm going to try this technique again with another 74S10, except this time set the temperature right up to the final setting, and leave it there for maybe an hour or two.

I've also ordered some sulfuric acid from Duda Diesel to try the hot sulfuric acid technique. When I was walking around Harbor Freight today, I noticed they had an abrasives blast cabinet that I could probably repurpose into a fume box.

The awful Harbor Freight blast cabinet that apparently is extraordinarily leaky.

The awful Harbor Freight blast cabinet that apparently is extraordinarily leaky.

Just seal it all up, replace the gloves with acid-resistant ones, add a filtered air outlet to attach a fume fan to (which I have courtesy my laser cutter). Hopefully that should eliminate the change of getting hydrogen sulfide smell all over the place.

Unisonic 21 single PMOS simulation in LTSpice

I used [LTSpice] to simulate the output circuit I previously measured and characterized.

Seems to work as expected. The primary assumption is that the gate is at ground. Honestly this doesn't prove a whole lot, just that the math behind best-fit worked. But it does serve as a base for more simulations, since I wanted to be sure I had the SPICE parameters correct for the PMOS.

Note that the substrate is connected to V1 rather than the "source" of the transistor. This will be true of all transistors in any simulation.

Here's a simulation of an inverter with a simple active load.

The output only rises to 12v because of the load of the output resistor in parallel with the resistance of the active load. I set the W/L of the upper transistor to 4/1 and the active load to 1/4, otherwise the upper transistor would not be strong enough to pull the output up away from the load transistor.

If we remove the output resistor entirely, we see that the active load cannot, in fact, drive the output to ground.

Here I will change the threshold from -7.3v to -1.5v. I really don't think the threshold is so large.

We see that the output is 1.5v when it should be 0v. It is, in fact, one threshold above ground.

Now, let's put together a bootstrap load circuit, as described in patent US3506851. First, without any capacitor. I have set M3 to 1/1.

As described in the patent, the output is off by two thresholds, at 3v. That's expected: you lose a threshold every time you add a transistor pulling to ground.

Now, let's add a capacitor. I've chose 0.01pF.

Look, the output went to ground! The reason is that when the output is high, the capacitor is charged up, and when the output voltage drops, the other end of the capacitor has to drop the same amount, since the capacitor does not want to change the voltage across itself.

This makes the gate on M3 go more negative, turning it on more strongly. Let's look at the gate voltage on M3.

See, it went very negative! It also slowly loses its charge because it will leak through the non-infinite resistance of M2.

Adding a load resistor to VPLUS makes the advantage even more stark:

The circuit without the bootstrap load is only capable of driving the output down to about 6.5v. The circuit with the bootstrap drives it below 1v.

The capacitor does have to be large enough that it doesn't leak all its charge away. Here's an example at 0.001pF.

By the way, this circuit doesn't work at all if the threshold goes back to -7.3v. That's why I think the threshold is wrong.

Anyway, that's the bootstrap load. It is used extensively in the CPU.

Reverse-engineering the 1977 Unisonic 21 calculator/game (part 3)

The three signals from the oscillator section, A, B, and C, feed into a clock phase generator section. The three signals are converted into four. Here's the logical diagram:

So how was I able to get the timing of each phase? It turns out that pin 1, not connected on the PCB, is the B_XNOR_C signal. I measured that in relation to the A signal on pin 2, and so all clock phase periods are known.

Annotated clock phase generator section.

Annotated clock phase generator section.

Polygonized. Yellow is metal, black is a contact to diffusion, red is diffusion powered by the high voltage (logical 1, VSS), blue is diffusion powered by the low voltage (logical 0, VDD), green is other diffusion, and pink is oxide. Areas that look gray are actually blue plus yellow.

Polygonized. Yellow is metal, black is a contact to diffusion, red is diffusion powered by the high voltage (logical 1, VSS), blue is diffusion powered by the low voltage (logical 0, VDD), green is other diffusion, and pink is oxide. Areas that look gray are actually blue plus yellow.

Four gates in 25 transistors. See the [PDF] and KiCad schematics at the [Unisonic21 GitHub project].

Now there are two sections on the progress map!

Reverse-engineering the 1977 Unisonic 21 calculator/game (part 2.5)

I found a 1969 Rockwell patent [US3591836], "Field Effect Conditionally Switched Capacitor" which explains a lot about the fabrication of a capacitor, and also gives a nice detailed view of a contact.

Figure 1 shows that there are several thicknesses of insulator, and the capacitor is formed by using a much thinner layer than usual. The capacitor described is effectively unidirectional, but if the diffusion were extended all the way underneath the top metal plate, it would be an ordinary capacitor like the kinds we see on the chip. The depression formed in the metal by the very thin insulation section is visible in the image:





Next, I want to summarize my progress by showing the sections of the die I've mapped out and turned into schematics. The ROM and registers are obvious in the image, but since I haven't turned those into schematics, I'm not counting them as done.

Reverse-engineering the 1977 Unisonic 21 calculator/game (part 2)

First, corrections! It turns out that the things without the oxide layer that I thought were resistors were actually also capacitors. Also, there are PMOS transistors with thin, long gates that act as resistors. The gate is also connected to a constant voltage.

A capacitor.

A capacitor.

A resistor.

A resistor.

Finding which bond pad corresponded to which pin was a bit of a puzzle. The QIP package has 42 pins, of which only 31 are connected on the circuit board. The die, however, has 37 bond pads.

Three bond pads on the right side of the die.

Three bond pads on the right side of the die.

There is one round bond pad, and all the rest are square. The bond bad shown in the lower right of the image has a triangle attached to it. It is also electrically connected via the metal layer to another square bond pad also with a triangle.

The [patent] shows a block representing the chip  connections to the PCB, and shows the connections in almost, but not quite, the same order as the pins on the chip.

Block diagram of processor from US patent 4339134.

Block diagram of processor from US patent 4339134.

It was enough order, though, and that, combined with tracing out the PCB and measuring signals, meant I was able to determine which pin was what. That allowed me to determine also which pin was which on the die. The round pin is, in fact, pin 1, not connected on the PCB. The square pin below it with the triangle is pin 42, which is VSS, which is also not connected on the PCB. It is electrically connected to pin 14, however, which is connected on the PCB, and does indeed go to ground.

Also helping were the fat output transistors for output pins. The ones without those transistors were clearly inputs such as PO, DIN1, and so on.

Bond pads that were missing were pins 3, 4, 12, 13, 16, none of which are connected on the PCB, except for pin 16 which is connected to ground.

With all pins identified, I could move on to looking for the block labeled "Osc and clock generator". This had pin VC going to it. I traced this out on the chip, and found the oscillator part to be three inverters connected in a ring, with an RC pair between each stage.

(See the [PDF version] on GitHub)

A few things that will look odd about this schematic. First, I label the positive voltage as +12v, and use the ground symbol for 0v. In fact, the actual circuit has the positive voltage (VDD) as 0v and the negative voltage (VSS) as -14.6v. Which really makes me crazy because everything is backwards from all of my circuit experience!

I also have a problem with telling drain from source. Luckily in these integrated circuits that differentiation is not present because with the body "terminal" connected to substrate, the MOSFET is a symmetrical device. There is no drain or source, only electrodes.

So anyway I just labelled VDD as positive and at the top, and VSS as ground and at the bottom. Also I set VDD to a familiar voltage.

Ignoring the timing, we have this diagram:

This results in a six-phase signal.

These signals feed into more logic which appears to be clock generating logic. I'll describe in the next post. But the interesting thing is that pin 2 is signal A!

I measured that signal and found it to have a high time (i.e. zero volts, which I'm calling logical 1) of 5.9 usec, and a low time (i.e. -14.6 volts, which I'm calling logical 0) of 6.6 usec for a total period of 12.5 usec (80 kHz).

Clearly all phases are not equal in time, because then the high time should be 6.25 usec and the low time also 6.25 usec. And this makes sense, given the different sizes of the resistors and capacitors in the inverter ring.

Further, I found a Rockwell patent filed in 1970, [US3641370], "Multiple-Phase Clock Signal Generator Using Frequency-Related and Phase-Separated Signals" showing a five-inverter version of this circuit. It also shows the VC signal (not by that name) controlling the resistances.

That patent, and also the 1966 patent [US3506851], "Field Effect Transistor Driver Using Capacitor Feedback" shows the pair of load transistors with the capacitor. The capacitor serves to drive the gate of the top transistor lower than the most negative voltage to really turn it on when it has to.

Thanks go to Ken Shirriff for pointing out that this circuit (which I traced but couldn't figure out) was likely a bootstrap load, also [used in the 4004 NMOS CPU] with the capacitor in a different location.

One minor aside: I tried to characterize the transistors by hooking up a resistor to pin 2 (the A signal) to get a current/voltage relationship.

By varying the resistance and measuring the voltage across it with my oscilloscope (not the most precision device), I could get an idea of what the current through the FET and the voltage across it were. By measuring several points, I could fit it to the MOSFET equation.

I validated that I was using the correct equation (linear or saturated) by checking those conditions were met. I knew W/L from looking at the die photo, in this case W/L was 12.

In the end, I came up with values of μpCox = 0.018 mA/V2, λ = 0.0527 V-1, and, oddly, Vsg - |VT| = 7.29 V which is almost exactly half the supply voltage. Since the "source" is also connected to the substrate, and is at +14.6v, and assuming that the gate is maximally driven at 0v, we see that VT would be -7.31 V, which seems a bit high to me. But it is still tempting to think that the engineers manipulated the doping to make the threshold exactly halfway between the two supplies.

Using these numbers, if I were to short the output to ground and calculate the current, it would be 10.2 mA. With Vsd of 14.6 V, that makes Rsd(on) 1.43 kΩ. Clearly not a MOSFET I'm used to, which has on resistances on the order of an ohm or less.

Anyway, I have no idea how realistic those numbers are.

In the next post, I'll show the next block, which seems to be clock phase generation logic.

Reverse-engineering the 1977 Unisonic 21 calculator/game (part 1)

My Unisonic 21 (S/N 026255) in game mode.

My Unisonic 21 (S/N 026255) in game mode.

My Dad bought this [Unisonic] 21 calculator/game in 1977, when I was eight years old. It is a four-function calculator that could also play [Blackjack ("Twenty-One")]. I played with it incessantly, and was able to intuit most of the rules of Blackjack from it.

Perhaps more infamously, the Unisonic 21 was marketed as "signed by [Jimmy the Greek]", a sports commentator and bookie who was not a nice guy.

Anyway, the inside contains a single 42-pin [QIL] chip labeled A4821. This is a mask-ROM [PPS-4] Rockwell CPU, a 4-bit PMOS processor. [Datasheet]

The insides. In the center is the A4821, date code 48th week of 1977. The VFD is toward the right, and the round-looking thing next to it is actually a DC-to-DC converter to provide -14.5v to the chip, and -31v to the VFD. The PCB on the left is the keyboard.

The insides. In the center is the A4821, date code 48th week of 1977. The VFD is toward the right, and the round-looking thing next to it is actually a DC-to-DC converter to provide -14.5v to the chip, and -31v to the VFD. The PCB on the left is the keyboard.

The system was patented in 1977 in [US4339134]. Interestingly, the patent contains the entire assembly language listing and flowchart for the program.

Since I'd been fairly successful in identifying various CMOS circuits in the [HCF4056 reverse engineering], I thought I'd attempt a more primitive but more complex chip, and what better target than the one in my favorite handheld game from the 70's.

I sent three of the A4821 chips (these games are cheap on eBay) to [Zeptobars] for decapping. I also visited John McMaster at [siliconpr0n] to learn about decapping first-hand, and we also decapped the A4821. I'm really interested in comparing the two results!

I'm still working on this, it will take quite a long time. But I've identified various bits, and this will serve as a sort of visual orientation guide to the chip.

I find it interesting that on the web there are plenty of side views of VLSI components, but virtually none of top views from actual dies.

This one is the easiest to identify, the metal layer.

Metal wire.

Metal wire.

This next example is a diffusion wire. I think the outline is caused by the material used to mask off the part of the chip that did not receive diffusion. In any case, it's very convenient.

P-type diffusion.

P-type diffusion.

The next example shows a contact or via between metal and diffusion. The diffusion ends in a square, as does the metal. There is a bold inner outline, and then you can barely see a very thin outline inside of that. The thin outline indicates that the metal goes into the diffusion, forming a contact. I have no idea at this point what the bold outer outline is. Maybe it's just metal, meaning that the contacts were formed in a step prior to the metal wire layer. The side view shows my hypothesis.



Transistors kind of look like bandages. The thin outline of the rectangle going vertically is a layer of oxide. It touches metal on the top in the side view, and straddles diffusion on the bottom in the side view.

PMOS transistor.

PMOS transistor.

A capacitor is formed between diffusion and metal with the oxide insulator between. You can see the oxide come in from the upper right, and basically surround the diffusion area of the capacitor. What makes this different from a transistor is that the oxide doesn't straddle a continuing section of diffusion. The diffusion sort of dead-ends.



Most of these things have their metal layer connected to VDD (-14.5v). They have no oxide, so they are not capacitors. I think they are resistors. The inner bold outline must be some kind of resistive material.



In the die marking, it's interesting that there are two underlines after A48. This must mean that the masks were standard, and only the ROM section of the mask was changed. The A48 part and the dot after the number appears to be diffusion with metal on top. The underlines are metal only, while the 21 part is diffusion only.

I'm not sure what AFFEIO means or stands for, but it seems that the A is diffusion, the first F is oxide, the I is metal. The other three are unknown. Perhaps one is the resistive material.

Die marking and tests.

Die marking and tests.

Some other test patterns:

Reverse engineering an HCF4056 BCD-to-7 segment decoder/driver chip from its die photo

TL;DR: [GitHub project] with PDF schematic, datasheet, and KiCad schematic.

I was inspired by Ken Shirriff's 2016 Hackaday Superconference talk [video] [Hackaday write-up] to try to reverse engineer a chip from its die photo. Ken recommended going to Zeptobars, downloading a die image, and diving right in, so I did.

I chose a digital chip that wasn't too complicated, and a BCD-to-7 segment decoder seemed ideal, and the [datasheet] already gives the pinout and function, so I wouldn't have to start from zero.

To give you an idea of what it was like when I started, here's a low-resolution image of the die (high resolution at the above Zeptobars link):

Here's a small part of it.

What is that? The shiny stuff on the top is metal, but what are these different colors? I had no idea what I was looking at.

I stared at a pin:

Why's it blue when all the other pins are purple? What's that track running around the outside of the chip? What's that line going around it? If this is a ground, why isn't there a huge metal network coming from it?

Clearly I knew nothing.

Searching the web for VLSI tutorials didn't give me any good starting point. I just couldn't connect the textbook diagrams to what I was seeing:

From the Silicon Pr0n wiki entry on MOSFETs.

From the Silicon Pr0n wiki entry on MOSFETs.

I finally stumbled upon Silicon Pr0n's wiki site, which had a good, if terse and disheartening "fixme", [tutorial]. I started with the pinout section, which said that pin 1 usually had a different shape from the other pins.

Pin 1! It had a different shape from all the other pins!

Pinout from the datasheet.

Pinout from the datasheet.

So since the pins on the die have to go in the same direction as the pins on the package, I could identify the pin above it with those huge metal wings as VDD.

Excellent! Now, the datasheet showed an input equivalent circuit:

And here was an input:

I got stuck again. There's a metal contact in the middle upper part, but what's that rectangle it contacts? Why's there another small rectangle inside the larger one? And there's a kind of pinkish rectangle around the contact in the upper right, what's that all about?

I checked the tutorial again, which didn't really help. The [section on I/O] did talk about diodes on the inputs, but the image I was looking at looked nothing like the image in the tutorial.

Further on in the tutorial, it said that any pin with a pad going right to a fat transistor, but not connected to its gate, is probably an output.

Great! There's a fat transistor, two of them, both connected to the pad. A transistor, specifically a MOSFET, has its terminals connected to source and drain, and the middle terminal between them is the gate. This one has each fat transistor kind of made up of two transistors paralleled. The middle contact is the output, the inverted U-shape is the gate, and the outsides must be connected to power!

Indeed, the bottom transistor's rightmost metal bit connects to the ring around the outside of the transistor, which is also connected to the VDD pin. So this had to be a PMOS transistor. That would make the other one an NMOS transistor, forming the typical inverter-driver.

CMOS inverter, from Wikipedia.

CMOS inverter, from Wikipedia.

Then I tried to trace the gate back further. The only connection it made was to this structure:

And I remembered that wires in chips are not only metal, but can also be polysilicon or diffusion. Polysilicon and diffusion can also be used as resistors. Here's another output gate wire connection:

You can actually see a thin line going underneath the metal, where the rectangular area ends. Since this was much smaller than the other one, I felt pretty confident that this was just a wire, and any resistance it had was not important.

So okay, if this was a wire, let's trace it back even further.

There's another wire thing, but the gate of the driver (the metal contact on the bottom) goes right through the middle of two structures. Those must also be transistors. The top one has two gates that don't connect, while the bottom one seems to have a gate on the right and maybe a gate on the left? But the structure seems to just end at that point, so where's the corresponding other terminal?

I couldn't make any progress, so I switched back to an input.

Ignoring the fact that I couldn't figure out the diodes, I treated the input structure as a wire and moved on. This goes into two fat transistors. Clue 1 was that one of the terminals on the top one went to VDD, so that must be PMOS. Clue 2 is that PMOS transistors are usually bigger than NMOS for the same driving capacity, and this is certainly bigger than its friend on the bottom.

That meant the bottom NMOS would be connected somehow to ground. Sure enough, I traced the contact on the left of the NMOS all the way across the chip to the VSS pin.

The path jumped across this wire-jumper-looking thing and then right to the pin.

So I had identified an inverter-driver connected to an input, pin 1, which was the STROBE input. But from there the trace went all over the chip. Instead, I concentrated on pin 2, a BCD input.

I stared at this for hours. I couldn't make any sense out of it. Why did it look like the little transistors on the left had their rightmost terminals not connected to anything? Why did the bottom middle and top right transistors have gates on the end?

It occurred to me to look at the datasheet's block diagram. Of course, the datasheet didn't help with its input equivalent circuit, but I was out of ideas and the web wasn't yielding any more information.

Block diagram from the datasheet.

Block diagram from the datasheet.

So the inputs all had to go to a latch, latched by the strobe line. I looked online for example CMOS D-latches, and I found this:

Hmm, not a lot of help there. Then I came up with a hypothesis. Maybe the line going horizontally through the transistors was a wire. And maybe the slight overlap of the top transistors' unconnected metal actually connected to that wire. And maybe that wire connected up to VSS.

That would make the top transistors NMOS, and the bottom complementary transistors PMOS.

The next leap of faith was that the gates floating there on the ends of the transistor were really not on the ends of the transistor, but the transistor kept going. When I drew out the connections thus made, I had this:

Then I rearranged to make things look nice. This took a couple of tries.


This looked almost exactly like the D-latch, except that the input wasn't inverted first. That also fixed the connection I couldn't make out. It also meant that I now knew what OUT1 and OUT2 were: OUT1 is the input, and OUT2 is the inverted input.

With that done, it just took a few more hours (okay, a few more days) to work out the rest of the circuit and create the [schematic].

I still have open questions:

  • Where are the input diodes?
  • What exactly are the non-metallic wires made of?
  • How could I have found that missing connection in the input latch from the die?
  • How are the connections from the transistors to VCC made?
  • What are those purple patches under the contacts on the wires?
  • Why are VSS and VEE blue and the rest of the pins purple?
  • How do the transistors that appear to have gates at their end actually connect to each other?

My next project is going to involve sending some [Unisonic 21 calculator/game] CPU ICs to Zeptobars for decapping and photographing, and then reverse engineering that. These chips are from 1978, so they might be CMOS.

Monroe Calculating Machine Company at the Internet Archive

I've recently come into a large cache of original documents from the Monroe Calculating Machine Company, spanning from 1919 to the 1970s. Most of these are Machine Service Bulletins, which were sent out approximately weekly to Monroe field offices around the country. These MSBs ran the gamut from one-pagers describing how to fix something, to 100-page manuals showing in detail how to disassemble, reassemble, and adjust an entire model of calculator.

There are also some course books, instruction manuals, ads, a newsletter or two, reference cards.

I've scanned all of these, and placed them on the Internet Archive for anyone to read!

Of particular interest are:

  • The 1919 instruction book for the Monroe Calculating Machine [link]. The machine depicted is a model D, but 1919 would put it in the model G era.
  • Machine Service Bulletin 34 [link], a full disassembly, assembly, and adjustment guide to the K-0 and KA-0 calculators.
  • Machine Service Bulletin 40 [link], a full disassembly, assembly, and adjustment guide to the K-1AA and K-2AA calculators.
  • Machine Service Bulletin 45 [link], showing what a bad day they were having.
  • Machine Service Bulletin 95C [link], illustrated parts guide for various L and LA calculators with prices for each part.
  • Machine Service Bulletin 116 [link] (with its supplement 116A [link]), a full disassembly, assembly, and adjustment guide to the MA-213 calculator.
  • Book 1 in the Service Training Course [link].

Enjoy! And if you have any Monroe publications that aren't in the Archive, please let me know, I'd like to add them.

Elektronika MS-1103 (Электроника МС-1103) Manual

Probably because of my RPN Nixie calculator project, I got interested in Soviet-era calculators. There are some MC-1103 calculators on eBay, so I bought two. The first one came without a manual, so I decided to open it and reverse-engineer it.

As you can see, it works. Interestingly, it truncated pi. If it rounded, it should end in a 3. I plugged it in to a 110-to-220 converter. However, US AC voltage is 120 which means that I actually get 240 VAC out. This would result in increased AC voltages inside, but the DC voltages should not be affected if they were regulated.

The above image shows the power supply removed from the case. There's a big transformer on right, and what appears to be four series pass transistors. Each such section also had a multi-turn potentiometer, presumably for fine adjust of voltage, and a chip. There were actually two types of chips: кпен2г (KPEN2G) and кп142ен1г (KP142EN1G).

From cpu-ukraine's article on Soviet chip identification, I learned that Soviet chips were all marked in a nation-wide standardized way. KP meant commercial use, plastic package. 142 was the chip family, EN was the type, and 1G was the model.

I also learned, by piecing together statements on various forums and Russian chip resellers that KPEN2G was shorthand for KP142EN2G (so they are the same chip, different models), that they were linear adjustable voltage regulators, that 1 meant Vin max 20v, Vout 3-12v and 2 meant Vin max 40v, Vout 12-30v, and G meant 0.2% regulation. I also found that they were equivalent to the LM723 regulator, but with a different pinout.

The pass transistors were КТ817А and КТ817Б (KT817B). These are NPN power transistors, A meaning 25v max and B meaning 45v max, and they were equivalent to the BD175 transistor.

Putting all this together, I was able to draw a schematic. The power supply provides regulated 5v, 15v, -15v, and -27v.

Anyway, as I was poking around with my multimeter with the power on, I heard a hissing sound and quickly cut the power. One of the capacitors had sprung a leak! Further investigation showed that it had taken its voltage regulator and series pass transistor with it. Maybe I shorted something? In any case, I had to replace these, and I used an LM317, a three-terminal adjustable voltage regulator which combined the chip and the pass transistor.

After a really messy install, the power supply worked again.

Then I got the second calculator, and it came with a manual. And the manual included schematics. Aside from the missing connection between the transformer's terminal 12 and the other end of the VD21, I got most of it right.

Anyway, here's the scan of the user manual I put up on the Internet Archive. Enjoy!

Raise3D N2: Vibrations (and solution)

Suddenly, a new feature appears :( The y-axis is nice and smooth but the x-axis is vibrating when it moves. It vibrates so hard that it seems to lose steps. Here's a print where the next layer is shifted over to the left a bit.

Sent these to Raise3D. Let's see if there are some adjustments I can make to get rid of the vibration.

Update: After a day of working with Raise3D, no progress with anything we tried. Everything seems good, nothing loose, broken, wobbly, shaky, or out of alignment except one of the screws on one of the bushings is stripped and wouldn't tighten. Replaced, still no good. 

Thinking back, when my friend helped me set this printer up, and we tried the first print, he did notice a vibration in the x-axis, but I didn't pay attention because the print seemed to be going okay. I thought maybe it was normal. Clearly not.

The next day, I got some grease. Not SuperLube (PTFE grease), which is THE grease to have, but unfortunately because it's so good, nobody stocks it.

Instead I got some silicone grease. It seems thick, but in any case I liberally coated the rods and packed the bearings where they meet the rods, and... no vibrations!  The printer is really quiet now.

Trying a small print now, and will follow up with a larger 15-hour job to see how this stuff holds up. Will also replace this grease with SuperLube once I get it in.

About 14 hours in.... This is the Vanderbilt mansion [Thingiverse 10485], model scaled to 50%, 0.15 mm layer height, 10% infill.

About 14 hours in.... This is the Vanderbilt mansion [Thingiverse 10485], model scaled to 50%, 0.15 mm layer height, 10% infill.

Raise3D N2: second impression

The next print failed.

I started this up before I went to bed, and in the morning I found the head merrily moving around a few inches above the prints. What probably happened is what Raise3D suggested previously when I said that the purge cycle didn't purge anything: the "third-party" filament clearly was not being fed.

I looked closer at the feed point.

Now, this image was from after I unloaded the filament, cut off the faulty bit, and was about to load it back in. Here's the faulty bit:

There are a few features to note here. First, on the right, we have the toothmarks from the feeder gear. This is normal. Then, we have a circular depression where the feeder gear ground into the filament. This is not normal, and is what happens when the filament gets stuck. Finally, on the left side you can see a bend in the filament. Also, the filament has changed  from semitransparent white to opaque white. This is the result of the filament being bent.

For example:

Bending the filament like this produced the exact same result. Now, here's a look at the whole feed path.

Note that there is nothing preventing the filament from being bent around that sharp radius. The printer is relying on the roll of filament being easy to move as the head moves around, and I am not convinced that is true for a 1kg roll of 1.75mm ABS. I used LD Product's brand of natural ABS.

My Ultimaker2 has a tube that runs all the way from the feeder gear in the back up to the extruder. No sharp radius possible. I don't know if the method Raise3D is using is new or not, but I'm a little suspicious.

At this point I am not ready to blame the printer. It could be the filament. I have some Toy Builder Labs 1.75mm ABS filament coming. Raise3D only sells PLA filament, not ABS. So can the printer handle ABS? It's supposed to. Raise3D has also acquired Toy Builder Labs, so I can only hope that the filament Toybuilder sells will (eventually) be compatible with the printer.

While I'm waiting for the Toy Builder Labs filament to come in, I'm going to redo the print using the PLA filament that came with the printer.

Now, when I removed the ABS roll, I found that the filament had come off the roll and was wound around the filament holder. That would absolutely cause an increase in drag.

This is fairly typical. Sometimes filament comes off the roll, and then you're in trouble. The solution is to add a plate which holds the filament on the roll.

I'm going to see if the same problem happens with the PLA. It might not because PLA is not as stiff as ABS and may not come off the roll. After that print, I'm going to print up a plate out of PLA which will fit behind the roll and hopefully help this situation.

I haven't lost hope!

Raise3D N2: first impressions

Got my Raise3D N2 today. The good news is, it worked right out of the box. A few standouts were that I didn't have to level the bed, the touch screen is awesome, and the whole thing looks great. It's also very very quiet.

51 kg of fun

51 kg of fun

All the things in the box

All the things in the box

All the things inside the thing in the box, except for the drill which is shown for size.

All the things inside the thing in the box, except for the drill which is shown for size.

Set up and almost ready to go

Set up and almost ready to go

However, there are a few things that need fixing. Some are pretty minor. Some are major. I emailed Raise3D all of these, and they got back to me within half an hour! In no particular order (Raise3D's response in italics):

1. The quick-start guide (section C step 3) says to unscrew the 2 nuts holding the Z-axis in place. I'd use the word clamps instead of nuts. Also I'd say to unscrew the 2 screws on each of the two clamps holding the Z-axis in place. It's just clearer that way.

2. The quick-start guide (section G step 4) says that the USB storage included with the printer comes loaded with already sliced models. It did not.

3. Sorry, there's Chinglish in the software, which is sad because the printer looks so good. If you make these changes, it will look much better:

[Note: Chinglish really bothers me. It's not hard to find a native speaker of English that knows Chinese. Or heck, even a native speaker of English that doesn't know Chinese, who can do a second pass on the wording like I just did. I don't think there's any excuse for manuals not to be in good, grammatical English.]

a. "Task Finished! Please take the models off from the bed." -> "Task finished! Please take the models off the bed." (don't capitalize the "f" in "finished", and use "off" instead of "off from").

b. Under the extruder loading screen: "When the extruder gear started rotating, feed the filament into right extruder;" -> "When the extruder gear starts rotating, feed the filament into right extruder." (started -> starting, don't use a semicolon at the end of the sentence; use a period. There's a reason for the semicolon and separating list items isn't it :)  ).

c. Also under the extruder loading screen: "When hot end reached target temperature, press "Load" button to next operation." -> "When hot end reaches target temperature, press "Load" button to continue." (reached -> reaches, and you need a verb after "to")

yes, we will change that for the next update.

4. The BuildTak has bubbles in it. This is very very bad, since the part will not be flat.

We have complained about that to BuildTak a lot also. For now, please use a needle to poke each bubble to release the air and flat it.

5. Under Utilities, the strange symbol in the upper left (which I now recognize as a stepper motor) disables the motors. But there doesn't seem to be a way to re-enable the motors. Pressing that button again just goes right back to saying it disabled the motors.

It is just a one motion button--to disable the motors so that you can push the extruder around. As soon as you use the touchscreen to move the extruder, it will go back on(enable).

6. When I pressed the disable motor button, cancelled the dialog, pressed it again, cancelled the dialog, and did it a few more times, eventually the response became slow and then the touch screen did not respond to touches any more. It did eventually go back to the home screen, and I saw the temperature monitors were still working, but the touch screen remained unresponsive. The only solution was to turn off the printer and turn it on again.

That is an issue we are working on right now. Also do not hold the button for too long otherwise it may freeze and you have to turn it off and on again.

7. Speaking of turning the printer off, the power switch is located in a very inconvenient place. The thing is nearly 60 cm deep, and it's hard to reach around to get to the switch. I suggest that the next iteration have the switch on the front or on the side near the front.

Ya, we noticed this also. We will think about this and figure out a better way.

8. No ground. The power cable that comes with the printer is two-prong with some kind of small green wire hanging off it. This is very very bad. Power cables should use all three prongs, and the case should be grounded using the ground wire. This is a shock hazard and you could be barred from importing this printer into the US unless you ground the machine properly.

[Note to all: I admit I'm probably wrong about this thing being barred from the US for not being grounded. Still, it's a good idea, no?]

We will switch to a standard 3-prong plug.

9. The purge cycle at the start of a print worked fine, but then the purged stuff didn't get wiped off onto the BuildTak. It actually was being dragged around during the print. I had to reach in there and pull it out.

Sometimes it wipes and sometimes it does not. We will think about a way to solve this.

10. After the print is done, the bed does not move down to the bottom. I have to manually move it. But moving it seems to be difficult: I went to Utilities and hit the Z-down button. It moves at most 10mm at a time, and it doesn't move continuously. I have no idea how I'm supposed to move the bed down. On the other printers I've used, the bed moves all the way down after the print is done so you can remove the print easily.

Ya, we are thinking about the Z movement. We might add a button to tell Z axis to move the bottom instead of 10mm a step.

11. When stopping a print, the print should stop immediately and the heaters should turn off. I found that if I wanted to cancel a print just after I started a print, the "Stopping print" message came up, and then did nothing. The nozzle and bed seemed to continue to heat up. I would expect that stopping the print would completely stop the process.

That is a Marlin thing. It has to heat up to desired Temperature before it can stop. We will think about a way to get around this.

12. When heating up, the nozzle temp gauge goes up but the bed temp gauge stays at "25/0" until the nozzle temp turns green, then the bed temp suddenly changes to "75/100". It's like the bed is heating up, but the gauge does not show its temp until the nozzle has completed heating up.

Again, this is also a Marlin thing. We have already fixed this. Please update the firmware and it should be fine. You can find it on our website under download.

13. When I started my second print, the nozzle and bed heated up, then the bed calibrated itself, then the purge cycle began, but nothing came out. Then the print started, and still nothing came out. I verified that the feeder gears were turning. It looks like the purge cycle isn't purging enough to fully load the extruder.

It seems that the filament is stripped due to gear teeth grinding. You can take off the cover and check whether the filament is actually going in or not. If the filament is not going in, then you need to unload the filament and re-load it again. Also using 3rd party filament may cause clogging issue.

A little tip is to always load a little bit filament before printing. If there is something wrong, you can spot it sooner.

Right now I have the printer printing a 17 hour job as a kind of torture test. We'll see how it goes, but from Raise3D's responsiveness so far, and the quality of the one print I finished, after all the usual initial bugs are worked out, this looks like it will be an excellent printer!

Cleaning a TRS-80 model III keyboard

I have a TRS-80 model III.

It has a keyboard. It doesn't work so well. Some keys don't work, others are flaky.

So I opened it up and popped the keycaps off.

I removed the keyboard assembly. It's an Alps 12KE010C.

Well, that explains some of the keys not working at all. The only thing protecting the keyboard PCB from the plastic post in the base of the computer is... nothing. Oh Radio Shack. Were you already beginning the long slow slide into oblivion?

Still doesn't explain flaky keys. So I desoldered a key, since that's the only way to get them out.

I measured the resistance when pressing the key.

160kohms?! That's just wrong! Let's open this thing up. It's easy: you just pry on these tabs with your fingernails and they just pop apart.

The inside of the bottom contains the contacts.

Those little dimples are supposed to press into the rubber conductive material inside the dome. And press they did. I suspect these keys weren't meant to stand up to much use. 640k keypresses ought to be enough for anyone.

Lacking true contact cleaner, I just scratched up the contacts and dimples with a screwdriver to maybe get rid of oxidation. I also rotated the dome 90 degrees so the dimples can press into fresh rubber. I put the key together and...

87 ohms! That's more like it.

63 more keys to go :(

Driving Nixie tubes with a MAX6922 VFD driver

The MAX6922 is a driver for VFDs. It takes standard 3.3v or 5v logic inputs via something close to SPI, and controls 32 separate outputs. Each output can be pulled low, sinking 15mA, or pulled high to a separate high voltage supply (up to 76 VDC), sourcing 45mA.

You can also daisy chain the drivers to add as many outputs as you want.

It's alive! Pro Trinket on left, transistors "stored" on the breadboard, MAX6922 on SchmartBoard PLCC adapter.

It's alive! Pro Trinket on left, transistors "stored" on the breadboard, MAX6922 on SchmartBoard PLCC adapter.

It seems like a powerful enough chip to replace the standard 74141/K155ID1 chips, with a more convenient input as well. Here's a circuit I put together showing the MAX6922 driving three IN-12B tubes. I left out the decimal points, since they would require 33 outputs, not 32. Since the drivers can be daisy chained, this wouldn't be a limitation.

Is it worth it? You can get them at Digikey, quantity 1, for USD 7.45 each, with price breaks at 10, 25, and so on, with a bit of shipping. For the same circuitry, you'd need three K155ID1s (about USD 1.50 each, plus shipping from Ukraine, Russia, or some other former Soviet Bloc country). So that would ordinarily deal the K155ID1 a win, but then, do you want to drive that decimal point? You need more parts. Do you not want to use up pins on your microcontroller? Then you need a GPIO expander running on I2C or SPI. Do you want the driver within the next few days? Then you probably shouldn't get a K155ID1.

I'm not going to argue about availability. There are probably a bazillion K155ID1s still out there, and likely MAX6922s will never be produced in such quantities. Nevertheless, the MAX6922 is worth a hard look if you need to drive a few Nixies.


Project: Nixie tube calculator, Part 3

CORDIC, or Coordinate Rotation Digital Computer, is a venerable algorithm used by calculators to calculate trigonometric and logarithmic functions and their inverses: sin, cos, tan, sinh, cosh, tanh, ln, exp.

Rather than give an explanation here, I know of no better explanation than that given by Richard Parris.

The CORDIC algorithm uses some number of constants, and then successive additions or subtractions and shifts, followed by one multiplication at the end to give the answer. Since it consists of two of the simplest possible mathematical operations, it is fast enough and simple enough to be implemented by quite limited processors.

Now, since my calculator is meant to be able to represent the magnitude of any number up to 10100 to an accuracy of 10-100, I decided to use 200 digits (or so) to represent any number using the 100.100 format, or 100 digits for the integer part, and 100 digits for the fractional part.

This meant that I needed all the CORDIC constants, to at least 200 digits, in this format. I wrote a Mathematica notebook which does this for me, which you can see in PDF format.

Project: Nixie tube RPN calculator, part 2

If I go to my HP48 calculator (or the Android or iOS versions thereof) and enter 1 3 ÷, the answer you'll get is .333333333333, 12 digits. Now, if I enter 3 x I get .999999999999. And this is correct, since the calculator makes the assumption that all digits past the displayed answer are 0.

If, however, I do this with 32-bit floating point calculations, we see that the closest floating point representation of 1/3 is 0.3333333432674407958984375 (exactly). How should that be displayed? If I display it as 0.3333333 then I'm lying, because the closest representation of that is actually 0.333333313465118408203125. But if I display it as 0.33333334 then I'm inaccurate because there is no way that is 1/3.

Two things come to mind.

  1. Floating point is hard.
  2. Floating point is ridiculous for a calculator.

So really, we should be using multiple-precision decimal arithmetic, but even that has problems. To solve the 1 3 ÷ 3 x problem, we could add one guard digit and round, which means .999999999999(9) will be displayed as 1. Even so, there will always be errors, sometimes fatal ones. There is a whole field around this issue.

But this is a calculator. We can provide an answer and assume that the human knows what context their calculation has, so even if they use the HP48 and see .999999999999, they'll know when this is 1 and when it is not 1.

If, however, we want to use scientific notation, then no matter how many digits of precision we use, we run into all the floating point problems again because N digits of precision plus an exponent is the definition of floating point.

Maybe we shouldn't let the point float? What if we want to be able to represent all numbers between 1x102 (100) and 1x10-2 (0.01) to an accuracy of 1x10-2? Then we need 4 digits. If our 4-digit representation is ABCD, then the actual number represented is ABCDx10-2, always. If ABCD = 0001 the number is 1x10-2 (0.01). and if ABCD = 9999 then the number is 99.99, or 1x102 - 1x10-2 (close enough, there's always going to be that upper bound missing). The exponent never changes, which means the point does not float. Add a sign bit and you've got arithmetic.

So where do we find a multiple-precision library? The Gnu Multiple Precision library (GMP) holds out some hope. Let's play with it for a bit.

Let's try 1+2:

#include <gmp.h>

int main() {
    mpz_t x, y, z;


    mpz_set_ui(x, 1);
    mpz_set_ui(y, 2);
    mpz_add(z, x, y);

    gmp_printf("%Zd\n", z);

This will simply print 3. So far, so good. But when we use mpz_tdiv_q instead of mpz_add, the answer is zero because 1/2 with the result rounded to an integer towards zero is zero.

This is where our assumed exponent comes in. When we divide Xx10-2 by Yx10-2 we get [X/Y]x100 because mantissas divide while exponents subtract. I use [X/Y] to indicate the integer result of X/Y rounded towards zero. But we want an answer that is a multiple of 10-2. The only way to do this is add more precision to the numerator: Xx102 x10-2. Now we get the correct answer, [X x102/Y] x10-2.

#include <gmp.h>

int main() {
    mpz_t x, y, z;

    mpz_set_ui(x, 10000);
    mpz_set_ui(y, 200);
    mpz_tdiv_q(z, x, y);

    mpz_t intPart, fracPart;
    mpz_t hundred;

    mpz_init_set_ui(hundred, 100);

    mpz_tdiv_qr(intPart, fracPart, z, hundred);

    gmp_printf("%Zd x 10^-2\n", z);
    gmp_printf("%Zd.%02Zd\n", intPart, fracPart);

The output of this program is:

50 x 10^-2

And that is correct. For multiplication, we will end up with twice as many digits as we need, so we just round off.

So much for the four functions. What about exponentiation and roots? Trigonometric functions? For that we'll need the incredible magical CORDIC algorithm, which I'll talk about in part 3.

Project: Nixie tube RPN calculator

Nixie tubes are neat. They're nostalgic, and not too hard to get working. Russia still has bazillions of them.

Here's an actual calculator that was sold, for money, made with Nixie tubes:

The 1972 Casio model AS-C. Image copyright Nigel Tout of

The 1972 Casio model AS-C. Image copyright Nigel Tout of

Everyone's making clocks with them.

Nixie clock built by (and image copyright) Tomasz Watorowski, 2014.

Nixie clock built by (and image copyright) Tomasz Watorowski, 2014.

Some are rethinking calculators with them.

Nixie calculator project (and image copyright) Spike Tsasmali, 2010.

Nixie calculator project (and image copyright) Spike Tsasmali, 2010.

So I thought it would be fun to go bigger, and interactive, but not too crazy. So that's where the Reverse Polish Notation Nixie calculator comes in. Like the venerable HP-48, it should have four visible stack levels. I would use IN-12B tubes, since they are top-read and have a decimal separator: a comma, which makes it compatible with most of South America, Europe and Asia.

Reverse Polish Notation

Polish Notation was invented by the Polish logician Jan Łukasiewicz in 1924. He was stuck in Poland under German occupation during World War II, and after the war he emigrated to Ireland. It wasn't until 1954 that Reverse Polish Notation came into being, but it wasn't used in calculators and computers until the early 1960s. RPN was certainly inspired by Łukasiewicz's work.

Alternate History

In my alternate history, Łukasiewicz did not leave Poland after the war. He was deported from Poland to the USSR as part of Operation Osoaviakhim to work on mathematics and help other captured scientists. However, the Soviets quickly realized the utility of Polish Notation, except reversed, in calculations, and by the 1950s were building large RPN desk-calculators with Nixie tube displays.


Here are the features I want to support:

  • 4-level stack display
  • scientific notation
  • IEEE 754 double-precision floating point (binary64, which is 15-17 decimals of precision)
  • Functions 10x , e x , log 10 , ln
  • Functions x 2 , x y , √x, y √x
  • Trigonometric functions (arc) sin, cos, tan (h)
  • π, e
  • Stack operations drop, dup, swap, rot3
  • Auxilliary memory store and recall


I want to have enough digits on each stack level to display a double-precision number to 17 digits with 3 digits of exponent. To represent scientific notation, instead of the usual practice of using "E" or a space to separate the mantissa from the exponent, I'd use a light shining through a panel overlay between the 3rd and 4th digits, showing either " + "or " - ". So O.778+O43 would be 0.778x1043 . Negative numbers would also be represented by having a " - " panel light on the far left side.

The interesting thing about this representation is that numbers not needing an exponent, which are those having an exponent of 0, could either be displayed with that exponent ( +OOO ) or, probably better, by leaving off the exponent and leaving the last three digits blank. That would make exponentiated and non-exponentiated numbers line up.

Infinity could be represented by OO and NaN by lighting all the commas.


As for electronics, as I said above, I'd use IN-12B tubes. These require a supply of 170VDC. Russia also has bazillions of K155ID1 chips, which drive these tubes, except for the decimal separator, for which I'd just use a simple transistor driver. This driver chip is pin-for-pin compatible with (and sadly much more available than) the 74141. One could use any 4-to-16 decoder and couple it with some high-voltage tolerant circuitry, but then you'd have essentially built a K155ID1.

I'd run the whole thing off of (of course) an Arduino. Now, each stack level has 20 digits times 5 bits each (4 for the BCD digit, and 1 for the separator), plus at least three indicators (sign, exponent signs). That's 103 bits per level, times 4 levels is 412 bits.

Conveniently, there are chips which take I2C and can latch many outputs (or read many inputs). There are two nice ones:

Each can be programmed with a 7-bit address, so there is no cramped address space to deal with.

If I want to be modular, each stack level can be powered using three of the NXP chips, or two of the Cypress chips. The NXP chips seem more approachable to me.


I figure the keyboard will be a 4x8 matrix, which should be able to handle all the functions plus digits as long as I have a shift key. 

Keys without shift functions (18):

  • 0-9
  • .
  • SH (shift)
  • +, -, x, ÷
  • CHS (change sign)
  • EE (enter exponent)
  • HYP (hyperbolic, for trigonometric functions)

Keys with shift functions (12):

  • sin / asin
  • cos / acos
  • tan / atan
  • log / 10x
  • ln / ex
  • x2 / √x
  • xy / y√x
  • 1/x / x!
  • π / e
  • DROP / DUP
  • ROT2 / ROT3
  • STO / RCL

These 30 keys would be placed in a 4x8 matrix, not necessarily physically but electrically. Each row of eight keys would be read via I2C, with a full keyboard scan happening many times per second.