Blondihacks Sun, 20 Jun 2021 23:14:02 +0000 en-US hourly 1 Blondihacks 32 32 Mockingboard 4c+ Sun, 20 Jun 2021 23:14:02 +0000 read more]]> Because Interrupts Are Hard.

The Apple II was (well, still is) a computer devoid of interrupts. I think most modern software engineers probably under-appreciate the implications of that. Folks skilled in writing main loops for games or graphics will at least be familiar with the evolution of main loops in games, so let’s start there.

Back in the old days, games had a “main loop” within which you serviced each activity required by the game- rendering graphics, updating physics and collision detection, processing inputs, starting audio sequences, etc. Each trip through this loop is generally considered a “frame”. On many very early platforms, this loop simply ran as fast as it could, because it was always going to be slower than you wish it would be. The second step in the evolution came with vertical blanking synchronization. Interestingly, even the concept of “vertical blanking” is becoming archaic knowledge because it’s much more of an abstract concept on modern LCD displays. In fact, under the hood they generally fake the concept because many old layers of software are still expecting it. However, they’re capable of essentially displaying continuously and updating any given pixel as needed. This is a slight oversimplification, because in reality pixels are still updated sequentially through shift registers and the like, mainly to save on circuitry. However it happens so fast as to be effectively instantaneous to software.

In the old days of cathode ray tube displays, however, vertical blanking was far from an abstract concept supported only to coddle dated software layers. It was an immutable physical property of the video device. As the electron gun scans across each row of pixels to “draw” it on the glowing phosphors, it reaches the bottom and must shoot back up to the top in order to do it again for the next frame. This is the “vertical blank”, so named because the screen is not updating during that time. In fact, the screen would go black during this time if not for the glowing phosphors buying us a little time. There’s also a much smaller horizontal blank during which the electron gun is shooting back to the start of each row. Some early computers leveraged this as well, but for this conversation the vertical blank is all we care about.

That was a lot of context just to get to the point that second-generation main loops in games are synchronized to the vertical blank. At the end of each trip through the loop, they pause and wait for a vertical blank to come up. The idea is that each loop starts when the gun starts heading back up to the top. If you can do all your processing and rendering during this vertical blank (no easy feat on early computers) then you can achieve a frame rate equivalent to the refresh rate of the screen (~60fps in North America), all with flawless animation. There are two ways that this vertical blank synchronization can be done. Earlier games did it by polling. There would be some flag set in the video hardware that went high when the vertical blank starts. So you would check that flag at the end of your loop. If it’s high, you’ve missed the start of this window, so you wait for it to go low, then high again. If it’s already low, you wait for it to go high. If you don’t manage to do all your screen updates during the vertical blank, the game will experience a lower frame rate, and also possibly artifacts, such as “tearing”. If you update the position of a draw element (such as an enemy sprite) just as the electron gun is passing through it, half of that element will be the old state and half will be the new, making it look like the object is horizontally torn in half and shifted. Clever game engines can avoid tearing while still taking longer than one vertical blank by updating things lower on the screen later, or by staggering updates and accepting 30 or 20fps instead.

Polling the vertical blank is fine as far as it goes, but the gold standard is interrupts. In more modern game engines, the rendering state is double-buffered and updated entirely from code that is triggered by an interrupt on the vertical blank generated by the video hardware. If you’re not familiar with interrupts in general, they are rather like a proto-form of threading. It’s a little piece of code that can be jumped into at any moment (asynchronously triggered by hardware) to do some work before handing control back to the main code. Interrupt programming used to be the only exposure most engineers had to concurrent programming (and the associated nightmarish bugs) but modern software engineers are generally comfortable with threading so should not be bothered by interrupt code. That is, assuming they paid attention in computer science classes and aren’t just relying on all the ways modern programming languages hide the complexities of threading.

Fully modern game engines take this idea all the way, and the graphics subsystem of a game is running entirely on a separate thread (even on a separate CPU hardware core which talks to one or more dedicated GPUs) controlled by the vertical blank (or a fake one generated by the video driver because ha ha LCDs aren’t real).

I’ve given you this trip down video memory lane because it’s easier to visualize the importance of interrupts and what life is like without them in the world of graphics. But we’re here to talk about sound. You see, sound actually has all the same challenges as video, but doesn’t get nearly the same love. And, it turns out, it’s much much more difficult to do audio in a game engine without interrupts. Which brings us back to the Apple II. The Apple II was (and is) well known for having lousy sound. It has a single-bit speaker much like later PCs did, however the Apple II has no interrupts. This is a critical difference, because it doesn’t just mean the audio is low-fidelity like the PC Speaker. It means that maintaining that audio has to be done manually in the game loop while it’s trying to do everything else. Furthermore, audio has no glowing phosphors to buy us time or fake our way through it. If we lose time and fail to tick that speaker at exactly the right pace, the audio drops in pitch, breaks up, or sounds poor. So think about what an Apple II game engine is trying to do. Every trip through the game loop, it has to update graphics, physics, collision, input, etc, but also tick the speaker. The frequency and complexity of sound is now tied to the frequency of your game loop. What happens if a player presses the jump key? The code path through the main loop changes and the code takes longer to execute. That would mess up the timing of ticking that speaker. This is basically an impossible situation, which is why virtually no Apple II games play music during gameplay. They often played music on title screens, or high score screens when nothing graphical or input-related was happening, but playing music while also running the extremely variable main game loop is almost impossible. I’m not certain off the top of my head if any games did it. I have a vague memory that one or two might have pulled it off, and if so they should be held in the highest regard now that you have some appreciation for how difficult this is. Even basic sound effects on the Apple II are hard. If you detect a collision and want to play a “thump” sound, you have to stop your game loop to do it. You can see this in many Apple II games- the animation pauses for a split second when a sound plays. Sound effects are kept short to minimize this effect. Simple sounds are a little easier to compute and can be played over multiple frames, so quite a few games do manage this. But again, it is difficult.

All of that context is to make you appreciate the value of sound add-on cards for the Apple II. They don’t just bring musical voices and synthesizer chips like on other computers of the day known for their quality sound. These cards brought their interrupts with them, freeing the programmer from trying to time audio playback amidst the main loop. You can start a frequency playing on one of these cards, then come back to it a few frames later and make an alteration as needed. This is incredibly powerful on a machine with no interrupts.

It’s perhaps a mystery then why sound cards like the Mockingboard and Phasor weren’t more popular. I suppose they had the chicken-and-egg problem that all add-on hardware has. The games don’t support it, so people don’t buy it. Nobody buys it, so the games don’t support it. The only way to break that cycle is aggressive developer partnerships, like SoundBlaster did in 1990s PC games. If you incentivize game companies to support your hardware, people will buy said hardware because the software already exists. Then your hardware becomes a standard and a virtuous cycle begins. In the Apple II days, hardware accessory companies hadn’t really figured that out yet, so we have great cards like the Mockingboard that are not well supported. That said, the games that really leaned into Mockingboard support (such as the Ultima series) really are outstanding with the card installed.

For the vast majority of the Apple //c’s life, it was mostly left out of Mockingboard support, because it didn’t have slots. There was a special “//c” version of the Mockingboard that was a box which plugged into a serial port. However, it required dedicated code to use, so now we’re talking about a niche of a niche hardware product that nobody supported. In the modern era however, we have incredibly powerful tools to do things like, say, make a board that parasitically intercepts all signals in and out of the CPU, and makes the computer think it has a Mockingboard in it, then emulating that board as though it existed to play sound. That’s what the Mockingboard 4c (by the amazing Ian Kim) is. It sits between the CPU and the motherboard, and makes the Apple II think it has a Mockingboard installed in a slot that doesn’t exist. This works because the Apple //c, internally, does think it has slots. The ROM code behaves as though slots are there, and the built-in features like the floppy drive and serial ports are treated as cards permanently installed in slots. This was a design simplification to portable-ize the II platform for the C, and modern devices like this can still take advantage.

Today I received my Mockingboard 4c+, which is Ian Kim’s latest product. It’s a Mockingboard clone that fits inside the Apple //c Plus, which happens to be my current daily driver Apple II. So let’s install it!


Here’s how the package arrived, all the way from South Korea. Perfectly packaged!


It’s a deceptively simple board, hiding a programmable logic device (I suspect CPLD, but might be an FPGA) and two large DIPs. The large DIPs are the original Yamaha AY-3-8910 sound chips used on the Mockingboard. These are genuine vintage chips that Ian is managing to source from somewhere, which will ultimately limit supply of these clone boards. Certainly those chips could be emulated in an FPGA, but it’s cool that he has the originals on there for authentic sound. The cat was a free optional add-on that I picked up locally.


You’ll note that the kit comes with two little speakers. This is an authentic oddity of the original Mockingboard- they did not pipe sound through the Apple II’s built in speaker. This is in line with later sound cards for PCs as well. SoundBlasters and the like had external speaker outputs that you had to connect. Only much later did computers manage to integrate add-on sound hardware such that it all came through a single audio output source (then on to your choice of internal speakers, headphone jacks, and line-outs).


You can see that the board is actually quite large relative to the machine that is going inside of.


Apple //c computers actually do have a large (by modern standards) amount of free space inside them. This is partly because of miniaturization limits of the day (the floppy drive and power supply need a lot of vertical height), and partly because there are some intended internal expansion options for the machine. There are two small “expansion ports” inside the //c Plus. They are not slots, exactly. One is for an internal modem, with pins dedicated to that task. I’ve never seen an internal modem product for this machine, but if they existed, I’d like to know! Drop a comment below. The other slot is more general purpose, containing many (but not all) of the signals found on a standard Apple II slot. There are quite a few products that used this for internal RAM disks and such. Applied Engineering did many very clever internal peripherals for the //c line, some of which used these connectors, and some which did tricks more in the vain of what the modern Mockingboard 4c+ is doing.


We start by removing all the screws around the periphery, on the underside of the machine.


Then the machine is flipped over and the top lifted off. This is the trickiest part, as some //c machines have a tendency to break tabs in this moment. On my machine, the secret is to push the top towards you from the back, then lift the front upwards. Finally, disengage the back, where the plastic meets the ports.



Next, disconnect the keyboard by carefully pulling straight up on this connector.


The keyboard can now be lifted off, revealing the motherboard underneath! This was a marvel of high density systems integration at the time, with entire Apple II subsystems being combined onto single VLSI chips to save space and power.


Our quarry- the 65C02 CPU.


There’s something really clever and magical about expansion boards like this that replace or intercept the entire CPU. Because modern electronics are so much faster and smaller than the 1980s stuff they are talking to, we can do all manner of crazy computing in between the comparatively glacial clock pulses of these old CPUs. We can build and dismantle worlds in the time it takes for that old CPU to go from a high pulse to a low on its pokey clock. That horsepower gap means that we can insert ourselves between the CPU and the outside world, and make it do just about anything. Like, say, think it has a sound board that doesn’t exist sitting in a slot that doesn’t exist.



That trick does, however, mean we have to get that CPU out. This can be non-trivial, since it probably hasn’t moved for 30 years.

The secret to getting old socketed chips out without damaging anything is patience. You have to find a way to get a tiny screwdriver or pick between the chip and the socket. Anywhere you can get a beachhead. Then work that part of the chip upwards a tiny amount, prying only between the socket and body of the chip. Once you get a little movement, move to an area opposite that on the chip and do the same until you get another tiny amount of movement. Go back and forth making tiny moves until you work the chip straight up and out.


Getting the first little bit of movement is the most difficult. Once you break that 30 year old seal of microscopic corrosion bonding things together, it’ll start to come up fairly easily.


Make sure you aren’t prying against other components or applying forces to anything except the chip against the chip socket. A twisting motion is usually best once you get a tiny bit of the screwdriver blade between the chip and socket.


Often a pick is the best way to start. There are little dimples in the top of the socket where a pick can go to get that upward motion started on the chip.


Patience yields results! The CPU is liberated, and no pins are bent.


The CPU is then carefully pressed into the Mockingboard. Carefully line up all the pins on the socket before pressing down on it. If you bend a pin at this stage, it may break when you straighten it. That will likely send you to eBay to find a replacement 65C02.


Next, the Mockingboard is inserted into the CPU socket. Note the rows of machine pins on the underside of the Mockingboard which fit into the CPU socket just as the CPU would.


Be mindful of the power harness on the floppy drive. I found it to be very close to the CPLD here, and it could easily be pinched during installation.


There’s the board, in its new home! We’re only halfway there, though. We have some wiring to attend to.


One of the tricks to a sound board is controlling volume. If you have your own external speakers (not using the built-in one) how do you control the output audio volume? SoundBlasters and the like did this by having their own separate volume control, or expecting you to use the Line Out to your own amplifier. The Mockingboard doesn’t have that luxury since we have no audio Line Out here. Instead, volume is controlled by two potentiometers on the board itself (the little blue squares shown above). This is a set-it-and-forget-it situation, which is fine because most Apple IIs don’t have volume control at all. They BEEP at a particular volume, and you take it or leave it. However, the Mockingboard 4c+ has one more trick up its sleeve. It has an option to piggyback on the system volume control that the Apple //c Plus does happen to have. To do this, you’ll need to warm up the soldering iron. Don’t panic though, it’s the easiest soldering job you’ll ever do, and easily reversed if desired.


The board comes with this little black wire, which you are instructed to solder on to the right-hand leg of resistor R50. The instructions make it very clear where this is. I’m using blue tape to hold the wire in position for this.


The wire is pre-tinned, so this could not be easier. Put a small dot of solder on the tip of your hot iron, then touch that to the leg of the resistor while the tinned wire is held against it with tape. In an instant it is connected. To reverse it later, touch the hot end of the iron to the end of the wire with gentle tension on the wire, and it will pop free again.


That black wire is then connected to the board with the supplied plug.


I opted to route the wire down between the chips for vertical clearance. I don’t think this was necessary, but I wasn’t sure how much space the board would need above it, and the black wire is plenty long enough to do this.


The final step are the speakers. It comes with two, since the Mockingboard is stereo. These are mounted inside the case of the Apple //c Plus, which makes everything seamless. This has the added benefit of disguising the secondary source of the sound, since the system’s built-in speaker is in the same area. The two sources effectively get mixed in the air after production.


Micro-speaker technology has come a long way, and these little guys sound better than the much larger factory one in the middle.


The speakers plug in to the board and are mounted in the corners, to spread the stereo field as much as possible. This is surprisingly effective. You can definitely hear the field separation when seated in front of the machine. These corners at the front also have grills built in, since this is a factory air vent all along the front. Thanks, Apple!

The speakers have a self-adhesive ring on them, but it’s quite clear this will not be sufficient to hold them well. In recognition of this, the instructions recommend an additional form of gluing, such as epoxy or hot glue. I opted for hot glue because this is easy to do, and easily reversed if you want to remove the speakers later. Hot glue sticks well to plastic, but not permanently so. Epoxy would be very permanent indeed.



The only trick here is being careful not to get any hot glue on the speaker elements themselves. That would of course interfere with their sound production. Only a tiny amount of glue is needed. Too much and it will ooze through the vent slots and make a mess. Hot glue can easily be cleaned up and trimmed before it’s fully hard, as needed.


After this it’s time for a test! I did one (or six), of course, but I’ll save that for the end. Let’s skip ahead to reassembling the machine, because here I encountered my first and only hiccup. The keyboard would not sit flat on its mounting posts. The Mockingboard 4c+ underneath it was sticking up a tiny hair too high. I could have bolted the keyboard back down as-is, but I didn’t want it to be stressed that way.


Space is tight in there. A little… too.. tight. The solder pads on the underside of the keyboard are resting on the chips of the Mockingboard, keeping the former from seating properly.


I verified everything was well seated. I did notice that the Yamaha chips that come preinstalled on the board were not themselves 100% seated in their sockets. They were 99.9% seated, but sticking up a tiny hair. I gave them a little push, but got no movement and didn’t want to force the issue. Instead, I increased clearance on the keyboard.


The factory soldering job on the key switches left quite long tails on these pins. These are what are resting on the Yamaha chips underneath. I simply cut them all flush to their solder blobs in the area above the sound card, and this resolved the issue.


Okay, here’s the moment you’re waiting for. Quiet on set! Sound check!


Forgive the BlairWitchCam there, but I was too excited to go get the tripod. It works incredibly well in Ultima V, which is itself a tour-de-force of Mockingboard audio. In the video you’ll see me configure Ultima for a Mockingboard C in slot 4. The “C” there is the Mockingboard model number. That was the most common one, and is what the Mockingboard 4C+ emulates. The C in the modern products’ name is for “Apple //c” (and now Plus). It’s a little confusing, I know. The card emulates itself being in slot 4 because that was by far the most common place that Apple II users put it. Most software lets you configure this, but if not, it will likely still work since software tended to assume slot 4. Now how about that system volume control modification. Does it work?



It does! Amazing! How about that effect I talked about with mixing music and system audio “in the air” as it were? Ultima V shows that off as well:


The “babbling brook” sound effects play at the same time as the music. The former is Apple II speaker, and the latter is Mockingboard, but it all works together perfectly.

To really show off any sound board though, you need a tracker. Trackers are a uniquely-80s (and 90s) form of electronic music production that borrows heavily from MIDI, but tailored to the limits of early computers. I believe the Amiga (or possibly the C64) pioneered them, but now anything with a sound card will play them. Depending on your hardware, there will be some dedicated sub-genre of trackers just for you. Amigas have their MOD files (which PC SoundBlaster people later adopted as well) and so forth. Is there something like this that our humble little Mockingboard can do? Thanks to awesome modern Apple II programmer Deater, the answer is yes. He has written a Mockingboard tracker (among many other things) that plays ZX Spectrum music, which used a tracker format called PT3. The results are spectacular:



The phone-recorded audio doesn’t do this stuff justice- it really sounds great in person.

Okay, amidst all this success, are there any flaws? I will say there is one. The Mockingboard 4c+ does seem to pick up interference. It seems to be coming from the power supply, perhaps. There is occasionally high-pitched and very soft noises coming from the speakers. Twiddling the volume slider a little often silences it, and the effect is less at lower volume levels. It is manageable, but it does seem like something on the board might need a little more shielding or termination to insulate from this signal noise. Overall though, I’m super happy with this new toy. As I said, not a lot of software supports it, but modern Apple II games do, and I’m looking to playing with Deater’s excellent Mockingboard library to write my own stuff.

As of this writing, the 4c+ board is not yet on general sale (I got an early review board) but watch Ian Kim’s site for updates. If you have a regular Apple //c, he has one for you that you can buy right now!


]]> 5
Johnny – CPU Board Repair Wed, 27 May 2020 20:05:13 +0000 read more]]> The cost of procrastination.


If you’re a regular reader of this blog, one thing you know is that I’ve been having chronic problems with the Start button on my 1995 Williams’ pinball machine, Johnny Mnemonic. If you’re new to the blog you may be shocked to know that (a) I own a pinball machine and (b) that anyone bothered to make a pinball machine about that terrible movie. Yes, it was a terrible movie, but the pinball rendition of it happens to be fantastic, and since I’m the biggest William Gibson nerd that ever lived, the purchase of it was pretty much a no-brainer for me. I’ve owned this monstrosity for several years now, and if you’re considering buying one of these things, I have two pieces of advice for you. First, they are a lot bigger than you think they are. Most of us have only ever seen pinball machines in commercial spaces: bars, arcades, movie theaters, etc. Those are large spaces and large machinery does not look large in them. Large machinery does look very large in your home. In fact, you should check your interior ceiling height to make sure it will even fit. In some lower-ceilinged rooms, it may not. The second piece of advice is that you need to understand that you are not buying a toy, you are buying a hobby. You are buying a perpetual project. Unless you buy a brand new $9000 machine from Stern or the new boutique makers, you’re buying a 30+ year-old electro-mechanical monster that was only meant to last a few years. That means there is constantly something needing fixing on them. They are very much like owning a classic car. You have to enjoy working on them, or you will not enjoy owning them. All that said, the great thing about pinball machines is that they are commercial coin-op machinery. These are not consumer-grade appliances. They are built like gorram tanks, and they are built to be maintained. We’re so accustomed to disposable things these days that it can be easy to forget what something built for maintenance looks like. I talk about this every time I write about Johnny, because it is still one my favorite things about these machines. Every single transistor is meticulously documented, and you can pretty much rebuild the entire machine with a screwdriver and a couple of wrenches. They were built to be maintained by cranky old operators driving around in their vans emptying quarters into a pail and cursing out the teenagers that kicked the coin door again. They are also built assuming teenagers are going to kick the coin doors. They weigh many hundreds of pounds (close to 1000 in some cases) and can take a remarkable amount of abuse. They are also built to fail gracefully. If a particular mechanism ceases to function, the software can route around it and keep the game operational (and earning quarters) until the operator could get to it for repairs. Almost any part on this machine can fail, but the game remains playable. Almost any part. You know what one part is really important? The Start button. Guess which part my game has chronic problems with. Well, you don’t have to guess, because I told you in the first sentence. Literally the first sentence. Keep up Quinn, geez.


Note the dejected finger press in the lower left. Yes, once again, Johnny’s start button has become decorative (and rendered the entire machine decorative as a result).


If you look back on my Johnny series, you’ll see multiple repairs of the start button circuit. You’ll also notice a theme- I’m constantly doing the minimum that I feel like I can get away with to get the game operational again. That’s not generally my style, but for some reason I keep doing it in this case. I’m about to (probably) do that again, but we’ll get there.

The good news is that I didn’t even have to diagnose anything. I’m normally strongly opposed to starting a repair before doing diagnosis to confirm the problem empirically, and most Johnny posts start with a long section about that. In this case, I have fixed this damn button so many times that I knew exactly what was wrong. To be more precise, I knew exactly what was wrong because deep down I have always known and I have been procrastinating on the correct fix. As you may have read in previous posts in this series, I have traced all the wiring, checked matrix diodes, and all other sources of malfunction between the start button and the CPU board (where the start signal ultimate leads). All are fine. The problem is, and always was, at the connector. Let’s look at why.


The trans-light (called a back-glass on older machines where it is actually glass) is unlocked and then lifts up and out. This photo is mainly so you can see the flawless cartoon rendering of Ice-T, and the bad guy in the upper right who really looks a lot like Gilbert Godfried. Once you see that, you cannot unsee it, and you’re welcome.


The next step is to call in the supervisor and get her opinion.


Sprocket H.G. Shopcat feels strongly that the problem is in there somewhere, and she’s not wrong.


There you are, CPU board J212, my old nemesis.


My finger is on the problematic connector. Right off the bat, you can see that it’s a newer style than the others. This is a Molex crimped-pin connector, and the others are all IDCs (insulation displacement connectors). That’s because I replaced this connector previously. The reason this connector is so problematic is also visible in the above photo. See all that nasty staining on the metal bracket in the lower left? That is battery corrosion. In an amazingly poor moment of design, the backup battery for the game is factory mounted double-decker on the CPU board, using plastic standoffs. You can see two them, left of my finger there. That places the batteries directly above connector J212. Guess what batteries do sometimes? They leak. At some point in this machine’s history, batteries have leaked alkaline goo on to that connector, causing corrosion and the subsequent unreliability that I have been living with ever since. When I got the machine, everything looked okay and things were working. The batteries in it at the time were in good shape. Nevertheless, the first thing I did was relocate the battery pack to the side, as you can see in the above photo. That way, if they leak, they can’t hurt anything. I also replace them annually, but in case I ever forget, I’m protected.

It’s maddening that the batteries were not only factory-mounted in a place where they can cause damage, but they are literally mounted over the one connector that paralyzes the game if it becomes unreliable. Amazing. In any case, a couple of years ago I had replaced that connector, because the corrosion was apparent on it. That made the start button reliable again for a couple of years. Recently, it has been acting up again, but I have been able to keep it working by periodically cleaning the pins on that connector. The thing about battery corrosion though, is that it’s like circuit board cancer. It gets into solder joints and on traces, and it will slowly spread. It can be virtually impossible to get rid of once it gets into certain places. In some extreme cases, I have seen retro computing enthusiasts cut away sections of circuitboard and stitch-in new pieces to get rid of corroded areas. In a multi-layer board, if the corrosion gets into the inner traces, this may be the only option. If you have any old electronics you care about, do me a favor and remove the dang batteries. More than a few beautiful old computers, arcade games, and pinball machines have been ruined by this.

In my case, since the connector was new and the problem was worsening again, I knew it was time to look at the male side of the connector, on the CPU board itself. It’s a bit of a job, which is why I have been procrastinating on digging into it. I could procrastinate no longer, because my old tricks of cleaning pins and reseating that connector were no longer working. Johnny was quite dead this time.


Don’t panic.


Luckily, I never removed that sticker. Thus, my warranty is intact. I called up Williams to have them do this repair, but there was no answer. They must be at lunch. Let’s do this ourselves instead of waiting until they get back.


The first job is to get that board out of there. There are a lot of connections on it that need to be carefully removed. Most of them have probably not moved since they were installed 25 years ago, so they may be quite stuck. The easiest way to remove them is to grab the wiring and yank really hard. Kidding! Kidding! Don’t do that, of course. Some care with thin bladed screwdrivers, picks, and gripping the connector’s body with small pliers is sufficient to ease them all off. You have to be mindful not to bend pins, so you have to work them side to side carefully such that they come straight off. If you bend pins on the connectors, you can straighten them again…. usually. If the metal is old and brittle, or has been flexed before, perhaps this is the time it snaps. You pays your money and you takes your chances.

There was a day when I would have meticulously labeled all those harnesses before removing anything. Experience has taught me that, when removing a single board like this, that really isn’t necessary. Those harnesses have been sitting in those positions for so long that they hardly even move when you disconnect them. It’s really easy to see where they all go back on. Even orientation is obvious because of the “set” that the wiring takes, but if a connector isn’t keyed, then it doesn’t hurt to mark one end of it. Most of them are keyed, though. Again, the machine is designed for maintenance.


I love features like this.


Speaking of designing for maintenance, note that the PCB is held in place by screws, but they are key-holed, not just simple through-holes. This means you can loosen the screws and simply slide the board up to remove it. Why is that a big deal? They are mounted vertically in the back box of the machine, and below them is a gaping hole into the huge underbelly of the machine (itself filled with high voltage stuff). Dropping a screw in this situation would be supremely annoying at best, and fatal to the machine at worst. The simple design choice of key-holing the mounting spots removes all those issues in one swoop. It makes removing and reinstalling the boards quick, easy, and low risk. See? Design for maintenance. It’s the little things.


Success! We’ve got the board out. Notice how all the wiring harnesses are literally hovering in space above the exact place where they were installed. 25 years of being in the same place will do that to a wiring harness.


Okay, let’s get this board over to the electronics bench and take a look.


The top-left-most brown pin header is J212, the one we are interested in. There’s definitely corrosion on it, but it’s not the worst I’ve seen. Unfortunately, as you can see, I managed to bend a couple of pins on other connectors (despite all my preaching about proper connector removal). It happens to all of us. Luck was with me, though, and they all straightened easily.


The top is about what I expected. Some corrosion on those pins, but debatably not enough to interfere with function. Let’s take a look underneath.


Circled in purple is J212. I’ve circled another area of interest in blue.


The underside of J212 actually looks fine. The joints all look okay and no corrosion is visible. There’s another area below it (in blue) that is showing some pretty lousy solder joints though. These look factory, and frankly there’s a whole bunch of these connector pins where the solder is a little light. As you probably know, a pin soldered to a pad should have a nice fillet of solder around it, like a little volcano. A whole bunch of these are flat- there’s barely solder bridging the pin to the pad. I don’t know if these were wave-soldered or done by hand. Knowing a bit about pinball factories, especially from back then, “by hand” is a likely answer. They built everything on these machines by hand, and largely still do. Check out online factory tour videos of Stern some time- it’s very much still a by-hand business. But then, look at most Chinese factories- a lot more of our products are still “hand-made” than we think. We don’t think of them as such if they are made on an assembly line by people in other countries, but an iPhone or your microwave or whatever are all still mostly made by hand. Even the circuit boards themselves. Sure, pick-and-place machines and ovens do most of the SMD work, but a lot of it is still drag-soldered by hand, as are all the through-hole components (unless the entire board is through-hole and can be wave-soldered).

Okay, I got side-tracked there. The solder joints look okay, but I think it’s well worth pulling J212 anyway. Time for some desoldering of very old components, which takes a bit of finesse. The first step, ironically, is to add solder.


Whoops! I have my super fine point on the iron. Before we can even get started, I need too swap that out. A common beginner belief as you want the smallest solder tip you can get. This makes a kind of intuitive sense, because you don’t want to touch areas other than where you are working. However, smaller solder tips transfer heat much less efficiently, which makes heat control more difficult, and thus makes it more difficult to do what you want. I was doing some special-case SMD work, which is why I have that on there. Most of the time, however, what you want is…


The classic chisel tip. This tip built an entire computer, has done plenty of 0.5mm-pitch SMD work, and has never let me down. Sure, sometimes you’ll touch adjacent pins with it, but that almost never matters. With more mass you get more efficient transfer, so you can get in and out quicker with less risk to components and better control of your heat.


Heat management is particularly important when working on vintage boards, because FR4 circuit board material is a lamination of fiberglass, copper, and epoxy. Epoxy is destroyed by heat, and the older it is, the more sensitive it is. If you overheat an area of the board, the epoxy in the substrate lets go and you’ll lift pads off the board or delaminate the area. New boards can take a lot of heat, but on a vintage one you need to get in, do your business, and get out.


I start by “reflowing” the solder joints to be removed. You simply heat them and add more fresh solder to the old.


Old solder doesn’t liquify or flow well, so adding new fresh solder smooths the rest of the process. We’re about to get out the big gun (sorta literally), and it doesn’t work well on old, brittle solder.


The big gun. This is my Hakko 808 vacuum desolder gun. It’s basically a magic wand that makes solder not a thing. These are pretty expensive to buy, but this was an obsolete model that I got in a group buy on some web forum with a bunch of other folks. I’ve used the heck out of it for a decade, and it’s still trucking along.


The Hakko is without a shadow of a doubt the most effective and most pleasant way to get solder off a board. There is a bit of technique to it, though. There is a minimum amount of solder required to be there, so it helps to blob on a bunch. It’ll suck up a huge blob with zero effort, but it won’t touch a thin film. You also have to learn to be patient with the vacuum. Give the heat a moment to do its thing. The top rookie move with this tool is to get trigger happy with the vacuum. That makes the situation worse because it sucks up part of the solder, leaving- you guessed it- a thin film. Now you’re stuck. It’ll seem like the tool is ineffective because of this technical error. Put a big blob of solder on there, get the hot end of the gun in place, give it a second or two to really liquify the whole area, then the briefest touch on that trigger and magic happens.


The first pin desoldered with the Hakko- it’s like there was never solder on it at all. This thing is magical with proper technique.


Most of the time, after hitting all pins with the gun, the part will simply fall off the board. If it doesn’t, I’ll give each pin a little wiggle with a screwdriver or pick to make sure it can move. If it doesn’t, there’s a solder film down in the hole somewhere holding it. The urge will be strong to force it at this point, but don’t! You’re likely to tear a pad off the board, and then you’ve quadrupled the challenge of your repair. This is especially true of a 25-year-old board like this. As I said earlier, the epoxy in the FR4 is old and brittle, and the pads can fall off the board if you look at them funny. If you get a pin that won’t wiggle, add more solder back on to it and hit it with the gun again.


A little love-wiggle is all that is needed to check for hidden films holding the pin in place.


Alright then, with the connector loose, let’s get a look underneath!


In the words of George Takei, oooh MY. In the words of my father, well there’s your problem right there.


I knew there would be corrosion in there, but I wasn’t expecting it to be quite that bad. Well, that’s good news in a way, because we know where to focus our repair efforts. The first step is to neutralize that corrosion. As I said earlier, battery corrosion is like cancer, and you have to stop the reaction or it will continue to eat away at the traces and inner layers of the board. A good tool for this is vinegar. A lot of people refer to this corrosion as “battery acid damage” and you even see people try to neutralize it with baking soda. I guess this is a failure of our education system, because the batteries say right on them: ALKALINE. They are basic. This is base corrosion, not acid. I suppose people think batteries are all acidic because car batteries are, and that’s a big part of peoples’ life experience with batteries? I don’t know how we, as a culture, got the wrong message on this. Anyway, you want an acid for this job, and if you’re not in a hurry, a mild one is nice. Vinegar works, albeit slowly, or something like CLR or Bar Keeper’s Friend work if you’re in a bigger hurry. The latter is oxalic acid and comes in powder form. Mix up a solution and you’re good to go. It’s amazing on calcium build-up on shower doors and such as well (hard water deposits are basic, but too tough for vinegar). I wouldn’t use anything stronger than home cleaning supplies on a circuit board that you care about. You could create all manner of new problems if you get in there with brazer’s pickling acid or sulfuric acid from pool chemicals, or even worse something like hydrochloric or nitric acid (all of which I have lying around because my shop is a wonderland of bad ideas).

By the by, a lot of people put circuit boards in the dishwasher to clean them. Yes, this really is a thing. Pinball and retrocomputing people do it a lot. I have never done it myself, but it appears to be fine. However, if you’re thinking that will clean this corrosion off the pads, you’d be wrong. Why? Because detergents are- you guessed it- basic. Most food is acidic, so if you want a soap to be good at cleaning it away, make it basic. This is also why toothpaste is basic. A little junior high school chemistry gets you a long way in this world. Probably the stuff after junior high too, but I dunno. I stopped listening shortly thereafter. I’m sure it was all great.


I set up a tub with some vinegar, and dunked the board. I soaked it for probably three hours.


After soaking for a few hours, it was time to clean up the mess. The vinegar reacts with the corrosion and leaves a precipitate on the pads (not sure what it is, I ain’t no chemist) that we need to clean off so that solder can once again be used. Anything to be soldered must be clean!


Out of the acid, the pads now look like this. You can see the silver of the tinned pads showing through, but also reaction products that are the black crud and the pinkish copper.


To clean up the pads, I used a combination of scotch-brite, brass wool, and some careful scraping with an X-Acto knife. I do a final cleaning with alcohol and cotton swabs. Once this is done, you can re-tin the pads with fresh solder. I also use a generous amount of liquid flux while retinning the pads, because it has an excellent cleaning action that will get any remaining fine residue off there.


Here are the pads, after cleaning and retinning. They aren’t brand new, but a far sight better than they were. These should serve just fine.


Now I needed to deal with that connector. The pins had a fair amount of corrosion on them, and I was concerned that if I reinstall that connector, the corrosion will simply spread again. I needed to replace it. By a stroke of luck, I had that exact style of connector in my junk pile, except it was two pins too short (of course). However, I had two of them! I hacked one up and made the connector I needed from the pieces.


Top: The corroded original connector. I soaked this in the acid as well, which is why the pins are black and pink (just like the pads were). I thought I might reuse this if it cleaned up well enough, but since I was able to bodge together a replacement (bottom) I needn’t bother. The top one went in the bin, never to bother another PCB again.


If you’re wondering why there is a pin missing in the original connector, that’s a key. I clipped the same pin on my replacement connector. Now the best part- reassembly!


It was a simple matter to solder in my new connector. I also reflowed and added solder to all the suspect pins on other connectors in this area. Maybe this was a dreaded Friday Afternoon board, because it sure seemed hastily assembled in places.



All back together, like it never happened! This photo is also a great view of the white plastic standoffs that originally held the battery pack. You can see why J212 took one for the team when the batteries leaked.


Looking good so far. Time to put it back in Johnny!


As I said earlier, reassembly is very easy because the connectors basically float right above where you removed them. It’s almost impossible to do this wrong. Furthermore, the harnesses are all exactly the right length for their location, so if you try to do it wrong, the wiring will not reach, or will bunch up.


Okay, moment of truth time, did I fix it? Time to power up.


Oh, poop. This is not something I anticipated.


You know, I really should have realized what was going to happen when I disconnected the batteries and pulled the CPU board. Of course that would mean I’d lose all the settings. More importantly though, I lost all my high scores. Had I thought about this, I would have left the battery pack connected to the board throughout the repair and it would have likely retained everything. I’ll be honest, I was genuinely a bit sad about this. You see, I had one very special score in there. Modern-era pinball machines like this have something called a Wizard Mode. It is so named because the The Who pinball machine was the first to do it, and it was named for Tommy The Pinball Wizard (of course). A Wizard Mode is like a final “mission” in a video game. After you complete all the tasks on the playfield, you get access to this special mode. It’s how you “solve” the game, basically. Johnny Mnemonic’s Wizard Mode is particularly epic, and is one of the main reasons I love the game. It’s called Power Down. When you start this mode, the game actually physically starts powering itself down in sections. For real. You have to hit certain shots repeatedly to keep the “battery” charged and keep playfield sections from shutting off. If you lose an area, then the pop bumpers go dead, it gets dark so you can’t see what you’re doing in that area, gates that you need get stuck closed, etc. It’s an incredible fourth-wall-busting experience the likes of which is rare in pinball. Why am I telling you all this? Because I have reached and completed Power Down exactly once. It is difficult and I’m frankly not that good at pinball. I was so proud of that score that it was my avatar photo on Facebook (back before it was evil and I was still on it). You can see that score in the first photo in this article. Why? Because I waited for the attract mode to show the score before taking the photo so you would see it. That score was the greatest moment of my pinball playing life. And it’s gone.

It’s okay- I did it once, so I can do it again. It’s a bummer, though.

On a lighter note, the game wouldn’t start yet, because it demanded that I set the clock. Why is that funny? Because I have owned this machine for almost 10 years and I literally had no idea it had a clock in it. I’ve never pulled the batteries before, and it doesn’t show the time in the game anywhere. Why does it have a clock? I suppose because the game has internal financial bookkeeping intended to be used by operators. I suppose it date-stamps that data, I’m not sure. It’s a whole region of the menus I’ve never really ventured into because it’s really dry and when you’re doing that you are not playing pinball. Digging through financial menus on a 4-line screen is a lot less fun than playing pinball, I can tell you. In any case, it won’t boot until you set the clock.


It’s also funny that the lowest supported year value is 1989. That’s the year this Williams board set came out. Johnny Mnemonic is from 1995, but it uses the WPC89 board set (the last to do so, I believe), which came out in 1989. Luckily it didn’t mind going all the way up to 2020. No Y2K problem here!


I had no idea how to even set the clock. It was buried waaaay deep in menus that I didn’t know were there.


To set the clock, I legitimately had to dig out this thing- the operations manual.



Now we get to the real moment of truth! I set it to free play (it defaults back to quarter play and I don’t even have coin mechanisms in this machine) and pushed the start button.




NOTHING. That’s right, the start button still didn’t work.


Well. That’s disappointing. However, I was still extremely certain that the corrosion on that connector was the problem and I was very confident in my repair. So, I wiggled the connector a bit.


WOOSH. The start button commenced functioning and the game roared into life.


To quote the Buffy The Vampire Slayer musical, “The battle’s done, and we… kind of won?”. The start button now works, and appears to work reliably. However, it didn’t until I jiggled the connector a bit. That’s a trifle worrisome. It may be that there is corrosion inside that connector, picked up from the pins. Ideally, I should repin that connector to be sure. However, remember how I said that the harnesses in these machines are all exactly the right length? That’s no joke. I re-pinned that connector once before, and you lose some wire length every time you do that. There was barely enough wire to do it once. To do it again, I would have to splice all those wires and make a big mess of the harness. Is this more procrastination on my part? Perhaps. Or perhaps you have to draw the line somewhere. I’d already spent the better part of a day on this repair, and maybe the connector is fine. Maybe there was grit or some leftover flux in there. I’m going to leave it be, and if it gives me trouble again, I’ll have plenty of chance to catch it before the corrosion spreads back down into that connector. At least… I hope so.




Anyways, that replacement Power Down score ain’t gonna earn itself. Gotta go play.


Most importantly, the supervisor approved the repair.
]]> 27
Veronica – F18A Font Mon, 09 Sep 2019 00:11:55 +0000 read more]]> Shuffling bits for fun and profit(?)


Last time, we got the F18A physically repaired and running off Veronica’s power supply. Things seemed to be working okay, and I could copy bytes into registers, but my VRAM block copier was not yet working. You may also recall that I threatened to buy a ZIF socket for the F18A so that I could easily remove it each time I flash Veronica’s ROM, on the off chance that was contributing to the repeated frying of the F18A’s bus transceiver. I’m happy to say I made good on that threat. If you’re not familiar, a Zero Insertion Force (ZIF) socket is a lever-action device that clamps down on the leads of a chip, and allows you to insert and remove it quickly as much as you want, with no damage to the chip. They are commonly used in (E)PROM burners and such, but are useful in a case like this as well.


Let this be a warning to the rest of you. If I say I’m going to put you in a ZIF socket, watch out. I’LL DO IT.


I’m pleased to say that since the last post, I’ve flashed Veronica’s ROM hundreds of times, and some combination of better power filtering and removing the F18A during each flash seems to be working. I’ve had no more bus transceiver failures since those first two. Huzzah for persistence! If nothing else, I’m a stubborn old heifer, let it be said.

One of the annoying things about ZIF sockets is that the leads on the underside of them are not standard DIP leads, so they don’t seat properly in breadboards. I did manage to find some machined-pin headers that fit in the ZIF socket and also the breadboard, so that’s why there’s a stack of connectors in the photo above.

With the hardware seemingly well sorted, I could get back to my software. Recall that I felt my VRAM block copier wasn’t working, despite my rigorous on-paper vetting of the code. However, this is one of those situations where it’s hard to say what’s actually broken. There are a lot of moving parts here- my block copier, all the various indirection tables in the F18A, the frame buffer, and so on. Any one of those things being incorrect would cause the whole system to fail. As usual, this debugging task boils down to trying to find a way to isolate pieces of this system to verify independently.

Last time I had established that the F18A starts up with all the lookup tables for sprites, colors, VRAM, etc in pretty predictable default places. Recall, for example, that I was able to modify the built in font by poking at pixels in the $800 area of VRAM (which is where the V9918’s documentation suggests locating the sprite table).

My goal is to use my VRAM block copier to move a font from Veronica’s system RAM into VRAM. This means copying 2048 bytes from RAM (or ROM, really) to $800 in the F18A’s VRAM. A V9918 font is 8 bytes per character (6 bits wide with two unused per byte) and 256 characters for a total of 2k. I created a dummy font with a single hand-drawn ‘A’. I started with an “all up” test- using the block routine to copy that character to every position in the font (aka sprite) buffer in VRAM. If this works, the screen should turn to solid As, because any character value that happens to be in the frame buffer will render as an A.


Well, that almost sorta worked! I got my ‘A’, but I also got a bunch of garbage sprayed around. What’s happening there?


I found that it didn’t seem to be quite working. Looks like a bunch of garbage got sprayed into other areas of VRAM when I did that. When debugging a memory move operation, it’s generally best to start with first principles. The edge cases are where things generally break, so test copying one byte, then one row of bytes, then two rows, etc. Each of those will exercise a new loop or branch in the block copier and help isolate the problem.

To do that kind of testing, I needed to set up an environment where I could see if it was working. The simplest case is to copy a few bytes from the upper left of my font to the upper left of the F18A font area, so I set up a test whereby I could see if that was working.

I knew from past experience that character 0 was a blank, and that the frame buffer was initialized with that. So modifying character zero in the font should be visible as filling the screen with things. I tried that to copy a letter A pattern from my font to character zero. This would be a much smaller memory move, and thus a much simpler code path in the block copier.


Okay, now we’re getting somewhere. I’ve successfully replaced the blank 0 character with an A, but I’m still getting extra junk there. Looks like pieces of the built-in character set are coming along for the ride.


I played around with this for a while, and I suddenly realized what was wrong. I wish I could say it was a careful scientific process of eliminating variables, but sometimes debugging is just a flash of inspiration. I realized that my block copier was relying on the source data being aligned to a 256-byte boundary. This radically simplifies the code, so it’s a nice requirement to impose. My test font was not aligned to anything. In fact I even commented in the block copier that the source must be page-aligned (a “page” in 6502-speak is a 256-byte block) and then promptly forgot about my own constraint. It always pays to RTFM, especially when you wrote TFM.

As I was getting ready to test a more complex code path in my block copier to modify more of that font, it occurred to me that I could test my copier just by placing text on the screen. Why not write a test function that uses the block copier to place characters at the top left?

Since I have the ability to write a single byte to VRAM (we got that code working last time) I used that code to place a row of 10 characters in the upper left, numbered 0-9. Then I can overwrite characters 0-9 in the font with my block copier, and I should see the text change. Let’s start there to validate that this test idea will work.


Here’s the setup for my test. Characters 0-9 already exist in the built-in F18A font, and they are some DOS-like graphical characters. This is great news. If those characters had been blank, this test would be trickier.


Since I know I can create success, if it fails with the block copier, I’ll be able to work backwards to find out why. Thus, I set up a test where my block copier would copy a long string to the upper left of the frame buffer.


Result! With the alignment of the source data fixed, the block copier seems to be working perfectly. The block copier is copying the values 0-112 to the top of the frame buffer. Why 112? Because that’s when I got bored of typing numbers in the ROM source code.


Here’s the test string copier:


In case it’s helpful, here’s that block copier again (see below). Those PARAM values and such are all just zero page locations. Using the zero page for parameter passing is a common pattern on the 6502, because traditional stack frames are kind of a pain on this chip. The concept of function stack frames came in with compilers, and later chips created dedicated opcodes for managing them. It’s a lot more work to manage local variables and recursion with the 6502 instruction set using a compiler-oriented stack frame pattern. Hence using the zero page and other tricks like self-modifying code, or placing parameter blocks inline in the code. Contrast that with something like the 68000, which has a huge instruction set, and many opcodes dedicated to handling stack frames. It’s such a joy that you can transcribe C into assembly for that chip by hand quite easily. I know this because for an assignment in an assembly class, I wanted to write a wireframe 3D renderer (with viewport clipping and multiple windows because I’m insane). That’s straightforward(ish) in C, but a huge pain in the ass in assembly. So I wrote it in C and “compiled” the code by hand into 68000 assembly. It worked great, and considering the assignment was actually to write a simple 2D blitter, let’s just say I got an A. The time I spent on that caused me to get a B- in calculus, but hey, we all make our choices. Anyways, the 680×0 architecture was the height of CISC thinking in CPUs, and the 6502 was the beginnings of RISC thinking. The latter would turn out to rule the world in the end, so it turns out Chuck Peddle was right all along.



So after all that, it turns out that the VRAM block copier that I wrote on an airplane four months ago actually worked perfectly all along. The only thing wrong was how I was using it!

Next I set out to write my font loader routine. I went back to using the block copier to copy the same A into every character position (except 0 this time). This should look like my previous text screens, except everything will be an A.


Result! So far so good.


Now, at this point I only had an ‘A’ because I hand-encoded that character in my font data in ROM. I needed a complete font. The F18A does have a built-in font (you saw pieces of it earlier, and it’s used to render the splash screen). However, I want to make my own because I want to learn how to manipulate every aspect of this device for my own purposes. It’s also just a good excuse to make the chip do things.

For giggles, I want a specific font in my F18A- the Apple II font. Everyone who grew up with early home computing probably has a nostalgic fondness for the typeface of the computer of their youth. I have, for example, often seen tributes to the serifed vomit that was the IBM PC text mode font. Some people like typographical abortions, and I don’t judge them for that. My personal jam is the font from the Apple II, which came in 40 column and 80 column flavors.

I considered digging through the various Apple II emulators that I have to find the contents of the character ROM, then massaging that into a useful form. However, it was quicker to ask around amongst the awesome Apple II folks on the KansasFest mailing list. Within an hour, they had provided all sorts of related data in various forms. I grabbed a version of the 40 column font in a format close to what I needed, and got to work.

My font needs to live in Veronica’s ROM, so that it can be copied into the F18A at startup. This isn’t particularly efficient, but it’s what we have to work with. To get it in Veronica’s ROM, it needs to live in my ROM source code as a long series of .byte statements. That’s the ca65 assembler syntax for declaring static data in the binary. By amazing stroke of luck, the Apple II font is already a good fit for what the F18A wants- 6 bits wide by 8 lines high, stored as 8 bytes per character. In principle, I should be able to paste-and-go. I started by doing this, and ended up with something along the lines of:


You’ll note that I actually remembered to 256-byte align the data this time! I have sections commented out in this screenshot. You’ll see why in a moment. The entire font is 2048 bytes, though.


With the entire Apple II font tucked away in my ROM image, I was quite chuffed to give it a try. However, this new ROM image wouldn’t even boot. That seemed odd, but it didn’t take much poking around to figure out why. One of the nice features of ca65 (and probably most assemblers) is the ability to output what’s called a “list” file. This is basically the entire object code of your program, mapped into where it will actually go in memory, interleaved with the source code that generated said object code. If your object code will be going through a dynamic linker or is relocatable code, the addresses may not mean much- they’ll still be correct, but relative to $0000 or other dynamic load location. In my case, there’s no linker here. The origin of the code is set to where the image is stored in ROM (at $F000 in the 6502s memory space) so the List file is a very powerful tool indeed. I can see exactly where every byte of my program is going to end up when it is mapped into ROM. In this case, the bad news is at the end of my List file:


Notice the three byte addresses on the left. That’s because we have exceeded $FFFF


I suppose I should have seen this coming, but this font is 2k in size, and Veronica’s entire ROM is only 4k. With Veronica’s old video system, the font was stored in the program EEPROM space of the AVR microcontroller generating the video, so I didn’t have to use precious system ROM for it. The F18A does have its own resident default font, but I really wanted to get my own loaded in there, for the reasons already discussed. Ultimately, what I need is a form of volatile mass storage from which large data like font files can be loaded. Computers in the 1980s often handled this problem with dedicated character ROMs that could be mapped in when needed, so they didn’t occupy valuable system address space. However you go to war with the army you have, and right now I have a 4k ROM and need to load a font from it.

The first thing I did was get rid of all the cruft that I could. I had, for example, an entire Pong game in ROM, as you may recall. That doesn’t need to be there. A few other blobs of test code and such were expunged. It was still not enough. That’s when I realized that I really don’t need an entire 256 character font in ROM. The goal is to get my ROM monitor up and running on the F18A, and I can make do with a “bootstrap” font of just a few characters to manage that. I stripped the Apple II font down to just the capital alphabet. I’ll add a couple of useful punctuation marks and numbers later as well.


That’s how I landed on this little blob here. Everything from A through Z! And…uh… nothing else.


The basic alphabet is 208 bytes, and that we can swing.


Aaaaaaand… it fits!


I did one other little trick. Instead of loading my 208 byte alphabet at the top of the sprite table (which the V9918 uses for rendering text characters), I loaded it at an offset of 520 bytes from the start of the sprite table. That put my ‘A’ in the same place as it would be if I had loaded an entire font. That saves me having to write any kind of messy character remapping code. The F18A can do lookups on the ASCII values just as it always would, and nobody is the wiser that I only loaded 26 characters.

Okay, time for another test run. We still have that code printing the alphabet on the first line at boot, so let’s see how that looks…


Okay, not bad! We can work with this.


There’s a couple of interesting things happening here. First, there’s a vertical bar on the left edge of each character. This is because the Apple II has an annoying habit of setting the high bit on everything text related. Due to an idiosyncrasy of the video rendering hardware, Steve Wozniak was able to save a few gates by having all text characters be high-bit-set. This messes you up when programming assembly on the Apple II as well, because ASCII characters in memory may or may not have the high bit set, depending on where they came from and where they are going. The Woz was all about reducing chip count, and wasn’t too worried about the torturous effects on programmers of the system (see: Apple II Double Hi-Res Graphics, if you think your programming job is hard).

The other artifact we have there is the characters are all chopped off on the right edge. This is because while the Apple II and F18A are both expecting six bit characters in an eight bit byte, the Apple puts the unused bits on the left, while the F18A (from the V9918) expects them to be on the right.

We can solve all these problems by bit-shifting all this font data left twice. I could do that in code when the font is loaded, but it’s silly to do a static transformation on data at runtime. It’s way better to fix the data. I could fix my 208 bytes by hand, however I want to eventually use this entire font, so I should fix all of it. That would be immensely tedious by hand, so I’m going to bang out a little Python script to do it. Tools are power, and in computing, programming languages are your tools. The more of them you know, the more likely it is you will have the right one to apply to a quick and dirty problem like this.

Here’s the python script I came up with. It reads the font from standard input in the ca65 format (with the .byte parts and all that) and outputs a new blob to standard output in the same format, but with all the hex values bit-shifted left twice.


Standard I/O streams in Un*x operating systems are incredibly powerful tools, and it behooves you to use them whenever possible. That saved me writing any sort of file handling code, I didn’t have to parse command line arguments to get filenames, and now this tool can be chained together with other tools. This was the vision of Unix from the very beginning, and it is as powerful today as it was 60 years ago. You may not think of Python as being a good I/O piping language, but it does just fine! The syntax to invoke it is a little esoteric compared to something written in C or a shell scripting language, but it works just fine:

cat Apple2BootFont.txt | ./

One of the tricks to making this easier is proper use of the shebang at the top of the python program. Any text-based scripting-language program can be executed as if it was a native binary if you put a blob at the top with the magic prefix #! (hence she-bang) which tells the shell executor which program to run the script against. In my example above, it’s specifying Python 3 in the weird place Mac OS insists on installing it. One caveat with shebangs is that they can reduce the cross-platform support of your script, because different OSes put standard tools in different places. Not even different variants of Linux can agree on whether tools like python belong in /usr/bin or /usr/local/bin or /var/bin or whatever. Forget about Mac and Windows, who couldn’t even agree on a file path separator. However there is a POSIX-standard cross-platform(ish) version of the shebang that helps quite a bit:

#!/usr/bin/env python3

This can work quite well, even between Mac and Windows (we do this a lot at my day job). The POSIX standard doesn’t actually specify where env is supposed to be, but most Un*x variants seem to agree on /usr/bin and foreign OS shells seem to have agreed to see that format of shebang and interpret it as “go find where I put a tool called python3 by whatever means I normally use for that”. It mostly works sometimes.

I didn’t do that in my Python script because, well, I’m lazy and I copy-pasted that script framework from another one on my machine. And so the bad habits become immortal. History may judge me, but my script worked, goddamit.

Okay, so after all that, how’d we do?




Huzzah! This is a great result. We now have the ability to load a font into the F18A, my VRAM block copier is known to be working, and we’ve got all the indirection tables for sprites, frame buffers, color tables, etc, sorted out. I think this is a great place to stop for now, but I think next up is to start connecting the plumbing between the F18A’s rendering and Veronica’s API for the ROM monitor. Stay tuned for all the hot 6502 on FPGA action.


]]> 10
Veronica – F18A Baby Steps Tue, 30 Jul 2019 00:50:55 +0000 read more]]> One step back, two steps forward.


If you’ve been following this Put-An-F18A-In-Veronica drama, you know that we had some very light early successes, followed by an emotional rollercoaster of tragic failures and heroic repairs (for certain values of “heroic”).

It is high on my priority list to never repair that transceiver again, so it would behoove me to figure out what is causing that thing to burn out repeatedly. Normally at this stage I would start a long, possibly patronizing diatribe about how to debug things by starting at one end of the chain and working your way down, challenging assumptions at each stage. However, when your failure mode is “thing blows up and you have to play roulette with a soldering iron to maybe get it unblowed up” that scientifically rigorous approach loses a lot of appeal. Situations like this are where it is sometimes okay to take more of a shotgun approach to problem-solving. That is, fix everything you think might be contributing to the problem and hope you found the cause. This can lead to some superstitious behavior, as we’ll see, but it’s a decent enough place to start.

Many of my kind commenters had suggestions on previous posts for possible causes of the problem, and I took all those to heart. The most common hypothesis among myself and others is the quality of my power rails. I’ve been lazy on this F18A project by using my bench supply to power the breadboard directly. This started because I wasn’t certain if Veronica’s built-in power supply had enough current capacity to power the computer and the new F18A experiments on the breadboard. I also like using the bench supply because it gives you some warning if you have a short, in the form of a spike in current consumption on the built-in ammeter. However, that ammeter trick didn’t save me either of the times that the transceiver went quietly into that good night, so perhaps said trick is less helpful with modern components. Big old 5V TTL stuff can take an over-current condition for several seconds, so you have time to see the problem on an ammeter and shut things down. That said, I don’t know that it was any form of short causing this problem in any case. At the end of the day, I don’t for sure, but cleaning up my power can’t hurt and seems like it should have a good shot at helping.

Now that I have some experience with the F18A, I know that it draws around 200mA, and I’m comfortable Veronica’s 7805-based power supply can handle that just fine. Veronica’s supply has good filtering on it, and the backplane has the power rails on it, so it’s a simple matter to route power to the breadboard from there (instead of the other way around, as I was doing).

It doesn’t look like much, but those red and black wires running from the backplane harness to the breadboard’s power rails may be the most significant thing I’ve done so far on this F18A project.


The next thing I decided to do was eliminate possible sources of noise. I doubt noise would fry anything, but while we’re in the mode of cleaning up my bad habits, why not? I had two main sources of noise here- floating TTL inputs, and lack of decoupling capacitors on any of the chips. I generally don’t bother with that stuff while on the breadboard, because you can generally get away without tying up those loose ends. It’s important to decouple power at each chip and floating TTL is a definite no-no for robust final designs, but for screwing around on the breadboard it’s not generally a problem. However, we’re shotgunning here, so brace for splash damage.


A liberal sprinkling of 100nF decoupling caps on the power rails near each chip, all unused TTL inputs pulled high, and you’d almost think I know what I’m doing.


I also took this opportunity to verify every single connection on the board. It’s possible I had some lingering short I didn’t know about. Furthermore, Sprocket H.G. Shopcat really really loves poking around on my electronics bench, and she has a tendency to mess around with my breadboards. Sure enough, she had pulled a couple of wires out. Electronics prototyping with a cat in the house is like playing on Advanced Mode. You think you’re good at this stuff? Well how about if a malevolent entity randomly yanks on things when you’re not looking! Now how good are you, hotshot?

The final effort I’ll be undertaking is removing the F18A any time I need to flash Veronica’s EEPROM. I know from experience that Veronica’s on-board EEPROM programmer (driven by an AVR programming header) tends to drive the system bus pretty hard. Current consumption goes up 20mA during programming, so something on the bus is insufficiently isolated. It’s never caused a problem for Veronica herself, but I’m taking no more chances with the F18A. This will result in a time-consuming and possibly pointless superstition of removing and replacing the device on the breadboard a lot, but I need that peace of mind right now (I could use a piece of mind also, for that matter).

After all that work, no news would be good news. I should see my old test code turning the border white at startup.

White border! We’re back in business.


Now, that last concession about pulling the F18A off the board on every EEPROM flash is not a light one. When doing low-level programming without a lot of sophisticated tools like this, you tend to iterate a lot. Like, really a lot. Iteration is one of the most powerful forms of debugging in the absence of high level tools like simulators and steppers. You make a tiny change, see what effect it had, form a hypothesis, make another tiny change to test that hypothesis, and so on. Pulling a device on and off the board on every iteration is going to slow me down a lot, and I’m also concerned about the wear on the device and breadboard. I’ve ordered a 40-pin ZIF socket, and I’m going to install that on my breadboard to make this easier. Until it arrives, we’ll press on. Slow iteration time has one advantage- it forces you to spend more time thinking about your code before hitting Build And Run. I’m reminded of my early days in C programming. I first learned C during a time when the best computer I had access to was an Apple IIgs. Compiling a project of any decent size on that machine took around 20 mins (on a 2.8MHz 65816). With a 20-minute build time, you learn to spend more time running code in your head before testing it out, and you don’t make changes lightly. Oh, and that build time doesn’t count the additional 10 minutes it takes to get back to where you were if your code crashes, because crashes on 1980s computers bring everything down. That means reboot, restart the OS, reload your editor, load your code, and then start to debug. Kids today- you don’t know!

Tapping into my old IIgs roots, I did a lot of simulating code on paper at this stage of the project. That’s pretty easy with 6502 assembly. You can run through a block of code, noting what’s in each register and relevant memory location as you go. Every bug you catch this way saves you an iteration, and potentially a lot of time in a situation like mine. In this case, it also saves wear-and-tear on the F18A headers (which are not designed for hundreds of insertion cycles).

Speaking of code, let’s look at some. Now that the hardware is working again, I can start building up some first principles of the new F18A-based graphics engine for Veronica.

There are two types of memory writing on the F18A (and 9918A on which it is based)- registers and VRAM. Writing to registers is easy. We demonstrated that right away by changing the border color. I decided to formalize that a bit with a macro:


; Write to an F18A register. High 5 bits of regNum must be 10000
.macro F18AREGW regNum,dataByte
	lda		#dataByte
	sta		F18AREG1
	lda		#regNum
	sta		F18AREG1


If that syntax is unfamiliar to you, recall that Veronica’s tool chain for ROM code development is based on ca65, the assembler that underpins the excellent cc65 package. Unfortunately cc65 is no longer maintained, but there’s nothing platform specific in it, so it still works great for me, even six years after it was orphaned.

The second type of memory writing we need to handle is VRAM writes. Recall that the 9918A has a very narrow pipe to the CPU. There’s no shared memory, only an 8-bit virtual register that you can write to. There are effectively two registers, because of the unusual MODE bit, as we’ve discussed previously. Writing to a location in VRAM consists of pushing the two bytes of the address into one register, then pushing your data byte into the other register. This puts in the device into a special “VRAM writing mode”. All subsequent pushes to the register are treated as additional data bytes, and the address in VRAM is auto-incremented on each write. Any subsequent write to the “first” register will break the device out of this mode and you can go back to writing to the internal registers if you wish. It’s all a bit confusing, I know. The price we pay for a very easy hardware interface is a slightly awkward software interface. As it has always been, so it shall always be. The 9918A also has some special rules about the values of high bits on the things you are writing that help it keep track of whether you’re trying to start a new block with an address byte pair, or appending to a previous block with new data bytes.

I sat down to write a VRAM block writer, and since I needed to minimize iteration time, I was going to need to simulate it at length on paper. I ended up writing it on an airplane, thousands of miles from Veronica’s hardware. Now that’s a great way to test your assembly programming mettle. Can you code something away from the hardware entirely, and have it work the first time? Spoiler: no, I can’t. Here’s the code I wrote on the plane, anyway:


; graphicsVramWriteBlock
; PARAM1 : Destination VRAM address in F18A, high 2 bits must be 01
; PARAM2 : Source address in main RAM, must be page-aligned
; PARAM3 : Number of bytes to copy
; Write data to F18A's VRAM
; Trashes PARAM2

	; Set up F18A address register
	lda PARAM1_L
	sta F18AREG1
	lda PARAM1_H
	sta F18AREG1

	ldy #0
	ldx PARAM3_H

	lda (PARAM2_L),y
	sta F18AREG0
	cpy PARAM3_L
	beq graphicsVramWriteBlockLoopLowDone

	cpy #0
	bne graphicsVramWriteBlockLoop

	; Finished 256 byte page, so wrap to next one
	inc PARAM2_H	; Advance source pointer in RAM to next page
	jmp graphicsVramWriteBlockLoop

	; Low byte of counter matched
	cpx #0		; If high counter is finished, so are we
	bne graphicsVramWriteBlockLoopCont



The basic idea is that the input block is required to be page-aligned (that’s 256-byte-aligned in 6502-speak) which makes the code much easier to write. I simulated this case on paper using every edge case I could think of (partial blocks less than one page, partial blocks more than one page, exactly-one-page blocks, blocks that are even multiples of pages, etc) and it seemed to do the right thing (write thing?) in all cases. I was pretty confident as I deplaned that it should work.

Before we can test it, however, we need to get the F18A into a known state. I decided to start with text mode, since I’m driving towards rewriting Veronica’s ROM monitor for this new graphics system.


; graphicsModeText
; Begins text rendering mode

	F18AREGW $80,%00000000	; Set M3 to 0 (dumb, but necessary)
	F18AREGW $81,%01010000	; Select Text mode (with M1,M2)
	F18AREGW $87,$f0		    ; Set white on black text color



The rendering mode on the 9918A is set with three bits. Inexplicably, two of those bits live in one register, and one bit lives in another register. Things must have been tight on the chip, and they were jamming stuff in wherever they could. Anyways, that’s why you see all the weird gymnastics in that code, just to enable text mode. That code gave me this:

The screen clearly changed modes, so that’s a good sign. I had also set the frame buffer to $0000 in VRAM (not shown in that code), so in theory we’re seeing uninitialized memory here.


For giggles, I decided to give my VRAM block writer a try and use it to load some font data (which should those garbage blocks to recognizable characters). The screen did this:

It’s garbage, but something happened.


So, it doesn’t seem like my VRAM block writer is working, despite what Deplaning Quinn thought. Next I tried pointing the frame buffer to $0800, which is a default place that the manual suggests using for various things.


Now this is super interesting. We can see what looks like a distorted character set. I think I need to take a step back, though. There are too many variables changing at once here.


Now we get to a tricky place. The 9918A’s renderer uses a whole series of data structures that are indirections for various things. This is very desirable in a 2D renderer, because indirection means things can be very dynamic. For example, rather than hardcoding a font in ROM as many 1980s computers did, the chip has a lookup table that holds the font characters, and to place a character on the screen, you place a pointer into that table in the frame buffer. Similarly, the character definitions are not pixel matrices, but rather matrices of pointers into the color table. All these tables themselves are also specified by pointers into VRAM, so you can move them around, or switch quickly between them at will. Even the frame buffer itself is a pointer, so it’s trivial to double-buffer, or even triple buffer (VRAM space permitting). Vertical scrolling is also straightforward, just by moving the frame buffer pointer. The only real downside to all this indirection is that it means a lot of moving parts all have to be configured perfectly, or nothing works. That’s a problem for the intrepid bare-metal ROM programmer, who doesn’t even know if she can write to VRAM correctly yet. How do we set up all these tables and pointers to other tables if we can’t trust our code? If it doesn’t work on the first try (which it won’t) how do we debug this? In a situation like this, you have to find a baby step. One thing you can do that will have a predictable outcome. I struggled with this for a while, before it hit me- the F18A’s title screen has text on it, so that text is coming from a font defined somewhere. If I can deduce where, I should be able to modify the characters used in that font and verify my VRAM writes are working. That’s a baby step!

While you can theoretically put all these tables anywhere you want in VRAM, the 9918A’s technical manual does have some examples that seem to be reasonable defaults. I took a guess that the F18A might be using them. I tried enabling text mode without setting the location of the text buffer, or the character font. They would remain at their defaults. If I understand how the F18A title screen works, the screen should remain unchanged, and I can then try modifying a character in the font.

Ah, now that is interesting! We’ve learned two things here.


Notice that the title screen was still there, but the characters all look clipped. This is because the text mode uses 6×8 characters, but the basic graphics mode uses 8×8 tiles. So the title screen is actually a graphics screen, not a text screen. Now recall earlier when I pointed the frame buffer at $800, I saw what looked like a character set. This character set, in fact. Perhaps I can write a single byte to VRAM at $800, and modify the top line of the 0th character. I decided it would be a good idea to write a helper function to write a single byte to VRAM, instead of the complex block one above.


; graphicsVramWriteByte
; PARAM1 : Destination VRAM address in F18A, high 2 bits must be 01
; X : Byte to write
; Write a single byte to F18A's VRAM

	; Set up F18A address register
	lda PARAM1_L
	sta F18AREG1
	lda PARAM1_H
	sta F18AREG1

	; Write the byte
	stx F18AREG0



Using that, I can now try this little hack:


.macro CALL16	subroutine,param16
	lda		#<param16
	sta		PARAM1_L
	lda		#>param16
	sta		PARAM1_H
	jsr		subroutine

  ldx #$fc
  CALL16 graphicsVramWriteByte,$0800



The screen now did this:


WHOA. Now we’re getting somewhere.


Clearly I succeeded in setting the top row of pixels in the 0th character to 1s. Also, by dumb luck, the background of the title screen was made up of character 0. There was no guarantee that would be the case, although it was likely because programmers love zeroes.

If I’m right about my write, then I should be able to make little rectangles by doing this:


  ldx #$fc
  CALL16 graphicsVramWriteByte,$0800
	ldx #$84
	CALL16 graphicsVramWriteByte,$0801
	ldx #$84
	CALL16 graphicsVramWriteByte,$0802
	ldx #$84
	CALL16 graphicsVramWriteByte,$0803
	ldx #$fc
	CALL16 graphicsVramWriteByte,$0804


What effect did that have?




That was a substantial victory! It proves that I can write a byte to VRAM on the F18A, which is a huge milestone. I still have to debug my block writer, and get the whole network of indirection tables up and running, but now it seems like I can trust the basics, and my hardware all seems to be working correctly. I can also state that I have spent a whole day iterating on this software and didn’t blow up the bus transceiver on my F18A. That’s a great sign that perhaps one of the changes I made was effective.

If you decide to go down a rabbit hole with the 9918A’s documentation (which you can find on note that they use weird names for all the concepts we’ve been discussing. The frame buffer is a “name table”. The sprite/character bitmaps are a “pattern generator” and so on. It can be hard-going understanding the concepts with these weird terms, but it’s important to remember the historical context here. In the early days of graphics hardware, nobody had agreed yet on what all this stuff should be called. Every designer had their own set of vaguely similar abstractions for how to represent the data structures needed in a 2D tile rendering engine. Arguably Texas Instruments chose the weirdest possible names, and inexplicably numbered their bits and busses backwards (0 is the most significant bit in all cases). I’ll tend to use more modern and accepted terms for these concepts in my posts, but if you read the docs, be prepared to see a frame buffer referred to as a “name table”.

Anyway, I think this is a great victory to end on for now. Assuming the finicky bus transceiver continues to hold up, I’ll continue pressing forward with the software layers needed to bring up this device. Stay tuned for that!

And hey- if you’re enjoying this series, maybe buy me a beer once a month over on Patreon. The patrons of Blondihacks are what is keeping this whole enterprise going. Thanks to all of you who already support me!




]]> 9
Veronica – Transceiver Strikes Back Sun, 14 Jul 2019 18:33:48 +0000 read more]]> THIS IS FINE.


After the incredible success of our last bit of work on Veronica’s F18A, I was very excited to get started on the software to talk to this thing. My ultimate goal is to have the F18A replace Veronica’s original GPU, and that means rewriting the core ROM routines for text, sprites, scrolling, and so forth.

Before I can do any of that, however, I need access to the MODE bit on the F18A. I have previously been ignoring that signal, because it isn’t necessary for my basic test of changing the border color. For more complex interactions, I need the ability to toggle the MODE bit from software. In the V9918A documentation, the recommended way to handle the MODE bit is to simply tie it to the least-significant address line. This is quite an elegant solution, because it means you now have two memory addresses mapped to the device, and writing to one is the same as the other, except a different value of MODE will be present. No need to write special code to manage that bit, nor is any fancy address decoding needed. The only catch is that you need an even and odd memory address next to each other that only differ by one bit, and I don’t actually have that. Recall that I mapped the device to $EFFE, to be right next to my original GPU’s $EFFF location. The simple solution was to move the F18A one byte down in memory so it will occupy $EFFC and $EFFD. I quickly rewired the address decoder to do this. Then I routed the MODE bit to A0 on my bus. I also tied the low bit of my address decoding comparator high so that both the addresses would match for reads and writes.

The pliers are showing address line A0 coming from Veronica, and routed under the F18A’s PCB to the MODE pin. So far so good.


After these changes, I wanted to test to make sure my border color still turns white. I updated the ROM code to reference the new location, burned it to the EEPROM, rebooted Veronica, and…


Um…. what.


My border color is now… cyan. This is strange. Perhaps the addition of the MODE bit has done something to the timing of my address decoding, so I tied MODE high again to go back to the previous arrangement. Same problem.

This cyan color is (I believe) $7 in the V9918A’s palette. Let’s try another color and see what happens. I changed the code to set the border to dark red ($6 in the palette). This gave me…

That might be dark red, but it doesn’t seem very dark. There are two other reds (Medium, $8 and Light, $9), and this really seems like one of those.


To summarize, if I ask for color $F, I get $7. If I ask for $6, I either get $6, $8, or $9. It’s hard to say. The thing is, I’ve seen this type of problem before. This seems a lot like a stuck bit in the bus transceiver. There’s that sinking feeling of impending doom again.

I re-did the test that I knew I needed to do, but I was dreading the results. I hard-wired the F18A to be deselected, which should tri-state the entire data bus. All the pins were tri-stated… except one. I checked for shorts or solder bridges on that pin, and there were none. It seems that I have somehow burned out this bus transceiver again.

As you can imagine, that was pretty demoralizing. I genuinely considered abandoning the whole project at this point. In fact, I did abandon it for a good day or so. However, here’s the thing. I had replaced that bus transceiver once before, so I felt like I could probably do it again. Plus, I now had all the supplies already. If anything it should be easier this time, right? I also happen to know where I can borrow a binocular microscope, which would make this a lot easier than the combination of macro camera lens and adult language that I used last time.

I won’t go through all the steps in the repair, since I covered that last time. This will mostly be about the new things I learned attempting this a second time.

First and foremost is vision. I learned that head-mounted loupes and visors are really not enough for this job. I also learned that a macro lens on a camera works in a pinch, but doesn’t give you much working space (and your lens will take some heat from the soldering iron, like it or not). In principle, the ideal tool for seeing this job is one of these:


This is quite a beast. It weighs about fifty pounds. I know this because while carrying it into the lab, the base fell off and ruined a section of my floor. That was a great day except for the part where a microscope base ruined my expensive flooring. I guess I’m lucky it didn’t land closer to me, or they’d be calling be Old Quinn Nine Toes.


All the biologists will probably roll their eyes at this next part, but I learned that there is some skill in using this instrument. It’s not a magic “now I can see tiny stuff” box. Getting the eye pieces adjusted perfectly so that you genuinely have depth perception is tricky. It’s easy to think you have, but then you close one eye and realize that eye wasn’t doing anything. Then, once you get it, you have to learn to work without moving your head. If you move your head even a little, you lose your place. Your field of view is a small circular area, and any slight head motion can cause that circle to disappear.

Also, despite being advertised as for use with electronics, this microscope was a bit too powerful. It was okay on the lowest power setting (20x), but it went all the way up to something like 90x. Much more than is useful for this type of job, because your field of view gets too small to work within. You need to be able to maneuver the part a bit under the lens, and if the field of view is too small, any slight motion causes it to disappear from view, and you’ll struggle to “find” it again. That’s another element of skill in using this thing- figuring out how to find your work under the lens. Until you get the focus, distance, and position just right, you’ll mostly see nothing. You do get better at “sensing” where the lens is looking, but it takes practice. After an hour I started to get the hang of it, and it did do the job I needed, but I’m pretty glad I didn’t drop the kind of money that these things cost (although dropping the money would have been much kinder to my floor). It was “good”, but it wasn’t transformative for my work on small parts, and they want transformative money for these things.

The other thing that wasn’t clear to a microscope rookie like me is how much light these things need. I suppose that’s obvious to any photography buff or Generally Smart Person™, but glass eats light, and when you have a lot of glass, you need a lot of light. A ‘scope like this that is for working on a bench doesn’t have an under-light, so you need to point light at your work from the sides. The more you can muster, the better. I pointed my most blinding daylight CFL bulb at the board, as close as I could safely get it, and I was rewarded with a view that was workable, if a bit dim for my taste. You’ll also get crazy shadows and other visual artifacts caused by imperfect lighting from different sides, so effort here to get lighting bright and even is worthwhile.

For a sense of the process of using one of these, here’s a mostly pointless video clip of me fixing some solder bridges with it. The soldering iron tip I’m using is the skinniest one Weller makes, the PTS7. It’s basically a sewing needle at the end. I’m using it to break solder bridges between pins in this clip. I found it helpful to use two hands on the iron, for additional stability. At 20x magnification, my 45yo hands are at the edge of being steady enough for this work:



After buckling up and buckling down, I was able to once again remove this transceiver with ChipQuik.


As before, with a metric gallon of flux and plenty of ChipQuik, the chip slid off the board with minimal drama.


I didn’t do as well at cleaning up the pads this time. There’s more ChipQuik remaining there than I would like.


The cleanup step didn’t go quite as well this time, perhaps because I was more paranoid about heat. The only effective way I have found to clean the last traces of ChipQuik off the board is old-fashioned desoldering braid, and the challenge with that stuff is heat control. The braid always seems to need a ton of heat, and it’s easy to go overboard. I was trying to be conservative here with the heat because, as you can see in that photo, I’ve already lost a pad from the previous repair. Fortunately that pad wasn’t in use. That’s not just luck, interestingly- because there are no traces attached, it isn’t capable of sinking as much heat, so the excess goes directly in the FR-4 underneath, cooking the epoxy. Cook the epoxy, and up comes the pad. The real evil here is that heat damage to a PCB is cumulative. It doesn’t “heal” after you cool it off. If you’ve overheated it, you’ve started to damage the laminating glue, and that damage accumulates over time. This means you effectively get a fixed number of heat cycles, but there’s no way to know what that number is. It’s down to how skilled you are at getting the solder work done while remaining below the tolerance of the board to absorb heat. These margins are thinner than we’d like, since this stuff is meant to be built once by robots and never touched again. It’s not easy being a human in a robot’s world.

Undeterred, I proceeded to tack the corners of the new chip down, as before. For some reason I had a lot more difficulty getting the corners to stick without the chip moving. I think this is due to the pads not being as clean. If the pads are clean and smooth, the chip sits nicely and you have fine control over its position. If the pads are rough with tiny lumps of solder, it’s like trying to slide a crate around on gravel. The chip gets stuck in certain positions, and then pops out unexpectedly when you try to nudge it where you want.


With some perseverance, I did get the new chip tacked down, as before.


You may recall from last time that I way over-did the “drag soldering”, and made myself quite a desoldering project to clean it all up. This time I tried to be much more conservative, and I think it went better.

My latest attempt at drag soldering resulted in a couple of bridges, but much better than last time. At one point I was actually quite good at this. Maybe I killed those motor neurons with too much therapy whiskey.


So, things seem to be going quite well, right? Almost done already? Well, I had a new problem that didn’t afflict me last time. I learned that too much heat and/or pressure in one area can cause the pins to become crooked within the package itself. It seems to be a combination of the pin bending and the plastic holding it in place becoming soft. Amazingly none of the bond wires inside the package that connect the pins to the die seem to have failed during this exercise. As least, not as far as I can tell so far. This was still a difficult problem to deal with, though.

In the fifth pin from the right, you can see the problem. The pin somehow got bend sideways and joined with the adjacent pin and pad.


This is tricky to fix. The first thing I tried was pushing the hot iron in between the overlapping pins. This tended to just push the formerly-good pin next to it away from the bent one, and now you have two problems.

What did work okay was applying very gentle lateral pressure to the bent pin with an X-Acto blade, then heating the area with the iron. Once the solder softened, the bent pin would slide back into place. This was a very difficult two-handed operation, and the hands-free nature and generous working volume of the binocular microscope was helpful here. This would have been a much more difficult fix with my old macro-camera-lens method, because you need room between the lens and the work to get multiple tools and your digital sausages in there.

After the pin straightening, there was also often a solder bridge to the adjacent pad, because you never get the pin exactly straight again, and these pads are very close together. Furthermore, the situation is rather like a row of compact parking spaces. If one person is a little off, that error accumulates until some poor mope at the end has to climb out her sunroof or pay for the valet (who will park in the same space anyway, climb out the sunroof, and then charge you for it). The X-Acto blade was very useful for breaking these pad-to-pad solder bridges around bent pins.

Here’s the aftermath of a couple of repair attempts. I did finally manage to mostly unbend the three pins that I bent trying to fix the first bent pin, and then electrically isolate them from each other. Careful use of the knife between pads was the key there. It’s not pretty, but it is electrically sound.


Okay, after nearly as much sweat and drama as last time, we were once again ready for a test. If it worked, the border should once again turn white at startup.

Um… yay?


Well, this kinda worked. The border turned white, but there are a lot of weird lines through the image. It looks like scan-lines on an old CRT. I wondered if perhaps I still had a slight whisker short somewhere that was creating noise, or if I had damaged some other part of the board. I did a thorough inspection of my repair, leaving no angle or position unchecked. I found nothing wrong.

The human brain is a very strange thing. While I was spending twenty minutes intensely focused on the world inside the microscope, some distant fuzzy memory suddenly emerged. I have no idea how this information surfaced, but it did. When I bought this device several years ago, I recalled one of the features it offered was a retro “scan-line rendering” mode so that it would look like an old CRT. I have not read that anywhere in documentation since. That information literally gurgled up from my memory of reading the original promos for this device when I bought it in 2012. Could that be what I’m seeing? The “CRT” feature?

That’s when I realized I had forgotten to reinstall the jumper blocks near the transceiver. I removed them because they were in the way for my repair, and I was likely to melt them with the side of the iron. So I reinstalled the blocks, crossed my fingers, and…



Once again, this device seems to be functioning normally (at least as far as my simple software can ascertain thus far). The data bus is behaving itself again, so all seems well.

Now the real mystery begins, however- WHY does this board keep frying itself? I really don’t want to fix this a third time, so I’ll be having a good long think about this situation before proceeding. I’ll probably get better power in here. I’ll add a filtered 5V source to the breadboard, instead of running the bench supply directly to it as I have been lazily doing. I honestly don’t know how good the power out of my inexpensive bench supply is. I also suspect that my on-board EEPROM programmer has a tendency to spike the data bus. It has never harmed Veronica, but I do notice a relatively high-current (30mA maybe) bus contention situation during EEPROM writing. That device is not totally isolated from the bus as it should be, so things get a little cray cray on the backplane during programming. I will try disconnecting the F18A completely when programming. What else can I do? opto-isolators on every pin? That seems crazy, but if this thing dies again, I think this project is done. Even my burning desire to repair can be turned into a burning desire to kill the earth when pushed too far. Suggestions welcome.

In the meantime, I can hopefully get back to finishing up the control signals, and writing software for this thing. You know- the thing that I set out to do in the first place for this post.







]]> 20
Veronica – Transceiver Repair Sun, 30 Jun 2019 19:37:58 +0000 read more]]> Do not go gentle into that good night.


Just when things were starting to go really well on the Put An F18A In Veronica plan, well, I fried an irreplaceable device. Yes, if you’re following along, you know that last time I somehow managed to cook the bus transceiver on the F18A, rendering the entire board unusable. I’m still not sure exactly when it happened, or what I did, but what’s important is how to move forward. A replacement F18A cannot be bought, so we must find another way. Sure, I could throw up my hands and declare defeat, but that’s not the Blondihacks way. No, the Blondihacks way is to somehow use my clumsy meathooks and 45-year-old eyes to repair this tiny device made by robots.

Now, I have some experience with soldering small surface-mount devices. I built a run of my Apple II ROM Tool, which dumps ROMs and burns EEPROMs for 1980s computers. That board used a particular Atmel microcontroller that only came in a challenging 0.5mm pitch SMT package. I needed that particular one because it has the built-in USB Host support, so that I could write a command line tool on my modern laptop to talk to it. In doing so, I got plenty of experience with the “drag soldering” method of installing these chips. Basically, you just put some solder on the iron, and drag it across the pins. The solder mostly only goes on the pins, because solder only sticks to hot metal things. You’ll get a bridge between pins here or there, but those are readily cleaned up. In general, it’s not as hard as it seems like it would be. However, in the case of building those boards, I was working with the easiest possible scenario. The PCBs were brand new ones produced by OSHPark, so they were spotlessly clean and extremely well made. The chip I was installing was inexpensive, and I had spare PCBs, so there was no pressure. If I messed one up (and I often did), I could simply toss both parts and try again. Furthermore, because it was a brand new board I was building from scratch, I could install the tricky chip first so no other components were in the way. Overall, it was tricky, but not brutal.

This repair would be a whole new level for my rookie SMD rework skills. In this case, I have an old dirty board with a ton of other parts on it. I have no idea how high quality the FR-4 (PCB substrate) is, or how good the pads are. I also pretty much only get one shot at this. Certain mistakes, such as lifting a pad or overheating other components, could be fatal. I have exactly one of this device and absolutely cannot get another one. This is a different ballgame of stakes than I have had before on SMDs!

However, that’s the completely wrong mindset with which to go into this. The way to think about it is simply, “it’s broken now so I have nothing left to lose”. That mindset makes every outcome a positive one. I’ll learn something about SMD work, I’ll get to try some new tools and techniques, I’ll level up my soldering game, and who knows- there’s a remote chance I might even fix it. If everything goes completely pear-shaped and I’m left with a device I can’t use, well guess what- that’s where I am now. With the right mindset, failure is only a lateral move. If I had figured that out in my 20s, I’d be a lot further in life right now.

Okay kids, buckle up. I’m gonna replace the bus transceiver on my F18A.

After gathering myself into the appropriate mindset, I set about acquiring the tools to do this job. The ideal would probably be a hot air rework station and a binocular microscope, but those things are expensive and it’s not clear I can justify them for long term utility.

My main concern in this repair was removing the old device. To desolder a chip, you have to get all of its pins free of their pads at the same time. With an older through-hole chip, this is pretty easy to do with a desoldering gun. Simply sucking the solder off each pin is generally enough to loosen the chip enough for removal. Furthermore, you’re lifting the chip up, and the solder pads are under the board, so there’s minimal risk of pulling the pads off the board. Lastly, the chip itself is stronger than the solder, so if you have some straggler solder bridges, you can generally break them free. If all else fails, you can go in and cut all the pins and then soften the solder on each pin one by one to drop them out.

For surface-mount chips, all those advantages are gone. The pins are weaker than the solder holding them, so they can easily break if any force is used. The solder separation must be clean and total. The pins are too small to cut so you must somehow free all pins simultaneously. The solder pads are tiny and on the top side of the board, so if you accidentally apply any upward force, you will rip them off. That means the chip must not be pulled on at all. Finally, you have to somehow do all this with minimal heat, or you will lift the tiny solder pads off the board due to microscopic damage to the epoxy in the PCB. All of this is a tall order, and I wasn’t sure how to go about it.

However, my helpful Patrons put me on to a wonderful product designed for this purpose- Chip Quik. It’s a lot like solder (and looks like solder), but it has a very low melting point. It’s not designed to hold parts together. In fact, it dries brittle so it’s critical to remove it all before you’re done. However, it mixes with regular solder and keeps it molten for a really long time. It’s like using salt to melt ice on winter roads. By lowering the melting point of the ice, you not only make it liquid, but you keep new ice from forming in that area. This is what Chip Quik does.

To use it, you slather it on all the pins of the chip, and gradually heat it all up evenly. It melts all the solder and keeps it melted, until eventually the chip simply slides loose like magic. Then you clean up the Chip Quik and put the new chip on. Let’s get to it!

I am by no means an expert at this, but I’ll share what I’ve learned. I know that people do SMT work by hand all the time and this is hardly amazing, but for me this was a big deal. It was something I might not have thought I could do, so bear with me as I indulge in some hyperbole now and again.

There are three keys to success in this process- cleanliness, cleanliness, and cats. No, I mean cleanliness. The joke was that all three things are the same thing and that thing is cleanliness. I really like cats and got distracted for a moment there.

Our weapons in the battle for cleanliness are isopropyl alcohol and liquid flux. You pretty much can’t use too much of either. I did a whole bunch of practice with this technique by grabbing every PCB in my scrap bin that had an SMT chip on it and removing it. By doing that, I learned that pretty much all problems you encounter with this process can be solved by more flux. I was soaking the board constantly and the more I used, the better things worked.

Step one, however, is to get the surface dirt off the pins in question. This board has been sitting around for years, and it has crud on it. I went to town with isopropyl alcohol and cotton swabs until the pins on the chip to be removed were spotless and the cotton swabs came away clean.

Next, I soaked the whole area in liquid flux. I found it helpful to burn off this initial soaking with the soldering iron, then soak it some more. Burning off the flux activates the cleaning action, and applying more will get the Chip Quik to flow.

If the Chip Quik balls up or sticks to the iron but not the chip, you need more flux. Once you have enough, the Chip Quik will flow into the pins just like solder would. Move the iron around a lot and build up the heat gradually. It’s very easy to lift a pad with too much heat, and then this repair gets a hundred times harder. I had my iron set at 550°F, lower than the 650° I normally use for soldering. That helped me control the heat better. I also used the finest-point tip I could buy, because a smaller tip also helps control heat (and came in very handy later).

Practice really helps, and I’m glad I spent time pulling every surface mount device off every board in my junk pile before trying the real thing. I made mistakes and learned things with every attempt.


Here’s the bus transceiver removed, with the ChipQuik still hanging out. In the background, you can see all the practice devices that I removed from scrap boards.

Once the device is removed, the next challenge is cleaning up the Chip Quik. It cools at very low temperature and the solid form is brittle, so you don’t want it mixed with your solder. It won’t do a good job of holding parts. All standard desoldering tools work perfectly well with it. I got the worst of it off with my Hakko desoldering gun, which was a big help. I did final cleanup on the pads with desoldering braid. For this step, flux is again a good idea. I soak the braid in flux, and I also apply solder to the iron on the back of the braid, so that the heat conducts from the iron into the braid efficiently. The trick with that stuff is that the braid has to melt the solder, not the iron. Also it’s critical to keep it moving or the heat will damage the epoxy in the PCB and the pads will lift off. I did this in one of my practice runs, so that was a good lesson.

Of course, you won’t get every molecule of Chip Quik off, but the pads should look clean and “tinned” when you’re done. Check for bridges, as well. You don’t want to start behind the 8-ball on solder bridges once it comes time to put the new chip on.

After the desoldering gun, lots of flux, and some swipes with desoldering braid, our pads look good as new.

At this point, cleaning with isopropyl alcohol again is a very good idea. Again, you can’t clean too much. Clean, clean, clean.

Under the macro lens, you can see I’ve still got some cleaning to do here. There are little balls of Chip Quik scattered about, and a solder bridge or two between pads.

If you get a bridge between two pads, a quick swipe between them with the fine-pointed soldering iron will generally take care of them. Solder doesn’t stick to PCBs, only to hot metal. All you have to do is give it somewhere better to go. That’s often safer than going in with the braid again and risking overheating the pads. Again, these pads are very small, so it doesn’t take a lot of heat to damage the epoxy in the FR-4 below them enough to lift them off.

The macro lens attachment on my cellphone was very useful for inspecting up close and making sure there were no shorts or other issues to clean up.

Once the pads were as clean as I could get them without going crazy with the heat, it was time for the new part. It’s important at this point to clean up the soldering iron as well, because you don’t want the Chip Quik mixing with your solder any more than you can help it. It will weaken the normal solder. Cleaning the iron with your brass wool and re-tinning three times is said to do the trick, and that worked for me as well.

One nice thing about working with modern parts is that you can, well, just buy them. I’m used to working on retro projects and old computer hardware that rely on weird old DIP chips that haven’t been produced for 25 years. Sometimes places like Jameco carry them, but often I have to buy on eBay, wait for weeks, and cross my fingers that the chip is still working. Common TTL DIP chips can still be found new, but they tend to be a bit expensive because only hobbyists bother with them anymore. Enter the modern SMD component.

These brand new bus transceivers were 87 cents and arrived on my doorstep in one day. Behold modern components.

I’ll be throwing around a bunch more hyperbole now about how small this stuff is, but take it with a grain of salt. People work with SMT devices by hand all the time, and I am not special for doing so. There are entire categories of tools devoted to this area. Binocular microscopes, hot air rework stations, solder paste, stencils, etc, all exist. It’s a thing people do every day. That said, this was a very big deal for me, because I don’t have a lot of experience doing this, I don’t have any tools appropriate to doing this, and I had serious doubts in my ability to achieve this. However, I’m halfway through the job now, so it’s no time to get weak in the knees.

The first step for the new part is pretty easy- we need to position the chip and tack down opposite corners so it doesn’t move. Like everything else in this process, strong magnification helps a lot. My 10x head-mounted loupe was sufficient for now, but I would make heavy use of the macro lens on my camera later.

Once again, lots of flux at every point in the process helps. The funny thing about SMT work is that you basically have to unlearn all the good soldering habits you had. For example, the cardinal rule of soldering is that the work must melt the solder, not the iron. Beginners make the mistake of trying to “apply” solder with the iron like a glue stick. Well, with SMT devices, that’s actually what works the best. For tacking down the corners, what works well is putting a small blob of solder on the iron, and touching that blob to the pins you want. Holding the chip aligned with the pads while doing this can be a bit tricky, but light downward pressure on the top with tweezers seems to work well.

I tacked-down the chip by touching pins 24 and 48 with a little blob of solder.

With the corners tacked down, it’s now time for the main event- soldering the rest of the pins. There are various techniques for this, but I opted for the “drag soldering” method. Again, in violation of all previously-held good habits of soldering, this is simply putting a blob on the iron and dragging it over the pins. Because the pads and pins are clean and fluxed (right?) and the traces are covered with solder mask, the solder really only wants to be on the pins and pads anyway. If you use too much solder, you will get some bridges between. If you use a lot too much solder, you will get a lot of bridges between pins. Guess what I did.

This is a lot too much solder.

As you can see, I pretty much bridged every pin. Amateur hour, indeed. Especially when you consider that I have done this a lot before. It’s been a while though, and clearly I am rusty. However, don’t panic! We can fix this.

Cleaning up the bridges was a long process because of how poorly I did this step, but a combination of techniques got it done. If you’re good at drag-soldering, you’ll typically get one or two bridges at most. Often none.

For the really big blobs, I used my Hakko 808 desoldering gun. This is a sledgehammer as SMT instruments go, but luckily you only have to get it vaguely in the correct area to suck up the excess. The nice thing about SMDs is that very little solder is actually needed on each pin. So little that the desoldering gun will not likely be able to remove too much. Desoldering guns always leave a film behind, and that film is all that an SMD needs.

The second technique used is desolder wick. For areas that are too small for the desoldering gun, but there’s still a pretty substantial blob or bridge, desolder wick gets it done. I find it helpful to dunk this stuff in flux, and apply a blob of solder to the iron. Solder conducts heat way better than metal-on-metal, so having a blob of solder between the braid and the iron on the back really helps. It’s also important to keep the braid moving. Leaving it one place, it’s easy to overheat the pin or pad.

Once you’re down to the really small bridges, then it’s time for the “dry iron” technique. This gets the whiskers between pads, and importantly, the bridges across the backs of the pins that can be really nefarious. The trick here is simply to give your iron a good cleaning in the brass wool so that there’s no appreciable solder on the tip. For bridges between pads, simply swipe the crack between the pads, back to front to clear the bridge. For those nasty bridges across the backs of pins, stick the point of the iron straight in between the pins. The finest point tips from Weller are fine enough to do this. Melting the bridge will break it, sending the solder to the pins on either side, or on to the iron. Either way, you win and evil loses. The trick to this is that your iron has to be perfectly parallel to the pins. If it isn’t, it’ll seem like you can’t reach back in far enough. Trust me, you can with the correct angle. When doing the dry iron technique, clean the iron after every single bridge that you fix. If you don’t, solder will accumulate on the iron and you’ll make bridges worse when you touch them.

It won’t win any beauty contests, but here we after clearing all the bridges.


Bridge clearing went well, but I did mess up one part of this repair, unfortunately.

Well… that’s not awesome.


Pins 7, 8, and 9 are kind of a mess. I lifted the pad on pin 8, the pin got bent, and all three pins are bridged. Is this catastrophic? Not at all. A quick look at my photos from the PCB under the chip shows that none of those pins are actually in use. From the datasheet for the chip, we see that one of the pins is Vcc and the other two are inputs. So all I have done is tied two unused inputs high that were previously floating. This seems entirely harmless, and the best course of action seems to be to let sleeping dogs lie here. If I get aggressive about trying to repair that, I could do more damage.

As mentioned, I’m too cheap (as of this writing) to invest in a binocular microscope. However, I did make extensive use of the macro lens attachment that I happen to have for my phone. You can buy these things online for any brand of phone, and it was a surprisingly effective way to tackle this problem. The main challenge is that the focal length of a macro lens for a camera is much shorter than a microscope designed for soldering work, so you only have about an inch of space between the lens and the PCB to work in. You can do it, though, and it pretty much enabled this repair. I have a head-mounted magnification visor (the standard cheap one we all have), but it tops out at 10x and the lenses are not very good. It really wasn’t sufficient to see what I was doing here. I used the macro lens two different ways that both worked. I held the phone suspended over the work with a helping hands device, and I also just held it in my left hand while soldering with the right. That latter approach doesn’t seem like it would work, but it actually did. The trick is to find an angle where the camera can see what you need, but you can still get the iron in underneath it.

I put a few battle scars on the plastic part of the lens while doing this work. Space is tight and the iron kissed it more than a few times.


At this point, it seemed like maybe everything should work. I had inspected the chip to the best of my ability, and all my solder joints looked good. If I actually repaired it, I should be able to power up the device, and Veronica’s boot sequence will turn the border white (I added that code to the ROM startup for easy testing).

First test after my repair, and… nope. Border is still green.


Not discouraged, I got out the logic probe and tested the data bus again. With the F18A deselected, the data bus should all be tri-stated, which sounds like a confused low buzzing on the logic probe. I found that a couple of pins were still being driven low. That was the symptom that prompted this entire repair in the first place, so it could be rather discouraging. But wait, this could also be a solder bridge, so I took a harder look at the affected pins.

It was basically impossible to get the focus right, but if you look very closely, the three pins on the right are bridged on their back sides, under the chip.


One of those pins is ground, and the other two are data bus pins, so this could certainly explain them being driven low. Using the dry iron technique, I was able to poke straight in there and clear those two bridges. This also taught me another camera angle to use for my inspections. On parts this small, camera angle matters a lot. If you don’t inspect every joint from every angle, you can easily miss something like this. I needed to view the gap between the pins from straight-on at board level to see those bridges. I then inspected all the other pins from this newly-discovered camera angle, but the others were all okay.

After all that, it was time to power it up again. How’d we do? If it worked, then the border will turn white a few seconds after boot:



I gotta say, seeing that border turn white was one of the greatest moments in Veronica’s history. This is a project with some very hard-won victories in it (*cough*5yearsToBuildAGPU*cough*), but this was definitely one of the best. The amount of self-doubt I had for this repair was immense. I honestly didn’t really believe I could replace that bus transceiver successfully. This class of SMT rework is well above my pay grade and it’s a next-level accomplishment for me. I won’t lie- there was shouting, arm pumping, and dancing inside Dunki Freehold when that border turned white.

More challenges await, but we’ll leave things here on a high note. Veronica’s new graphics system may well have been clawed back from the abyss of certain infinite doom. Also Chip Quik is pretty nifty.

]]> 20
Elliptical – Rear Subframe Replacement Sat, 01 Jun 2019 20:31:19 +0000 read more]]> Testing the limits of my desire to repair.


What’s this? Is that my elliptical machine on the operating table again? How can this be? The previous repair seemed quite final. Well, I was doing my daily cheeseburger removal ritual the other day, when the machine suddenly developed a distinct starboard list.


One of the many reasons I love this hydraulic cart. It makes working on something like this very pleasant.


If you look under the rear of the machine, you’ll see the long rear “foot” is attached with a shorter section of tubing that is squished on the bottom. I’m calling that “squished” piece the “rear subframe”. It joins the main frame of the machine to the rear foot piece. Well, let’s take a closer look at that subframe. I’ve repaired that part before, when it developed a crack. I figured perhaps my weld let go (I’m a lousy weldor).


Wow! Well, the good news is my weld actually held fine! The bad news is, this part cracked in one, two, three new places. How about the other side?


Double wow! Again, my weld held, but here we have one, two, three, four, five, six new cracks.


Not all show up in the photo, but counting all the hairline fractures I see, there appear to be nine cracks in this part! Amazing it’s still in one piece at all! I’m fascinated by mechanical failure, and this is a great example of it. While using the machine, your weight naturally shifts back and forth, creating constantly moving stresses inside the steel. It’s amazing how this can manifest (over the course of years) into such catastrophic failure.

Well, it was immediately clear that no mere patch job was going to get it done this time. That whole part needs to go. Unfortunately, that part is welded to the main frame of the bike, so this repair won’t be a walk in the park.

First things first, we need some access to it. Let’s see how close we can get.


This top dust cover is screwed to the subframe, so that obviously has to go. Side note- I never see non-car people using magnetic trays. If you like to build stuff, get yourself some magnetic trays! They’re fantastic for working on cars, because you can stick them upside down when you’re underneath, and they hold hardware and tools right above your face, where you usually want them (car people are weird). They’re great for jobs like this too, though!


Of course, nothing is that easy- the front edge of the dust cover disappears under two other plastic panels on the front.


These front panels have to come off, or at least be loosened.


Some of the screws holding those front panels on were insanely tight. Clearly installed with extreme prejudice via some demonic pneumatic tool on the assembly line. Not stripping them upon removal will be a challenge.


Here’s a pro-tip. Screwdrivers give you basically zero leverage, so when trying to keep from stripping a screw, you use most of your muscle holding the tool in place, and don’t have enough left over to twist. Or, if you try to twist hard, you don’t have enough pressure, and the screwdriver cams out and strips the screw. By using a bit driver on a socket wrench, you get huge leverage, so you can use all your force holding the bit in to keep it from stripping.


With all the plastic covers out of the way, we can turn our attention to the large foot at the back. It attaches to the subframe with some dome-head bolts.


Allen bits for your socket wrench are a great investment. Once you’ve used these, you’ll never mess with those fiddly little L-shaped Allen wrenches again.


With the foot free, we can see that it’s actually in perfect condition (except for some flash rust and Miscellaneous Mystery Crud™.


With all the pieces apart, we can see some interesting differences. The foot is fairly heavy wall tubing, but the subframe is about half as thick. Amazingly, the main frame (to which the subframe is welded) is even thinner. It’s like tissue paper. It’s some sort of monomolecular graphene form of steel that probably should win a Nobel Prize for manufacturing efficiency. Luckily the main frame is showing no signs of wear, and the foot is perfectly well made, so it’s also fine. It seems the subframe is the only place where they cut the specs a little too close to the line.



Here’s another look at the subframe, and you can see all the amazing cracks in it. One of the cracks starts right next to my previous weld repair on this part, so no doubt the weld created a stress concentration point. You can also see that both mounting bosses for the bolts are cracked almost all the way around. The bolts are strictly decorative at this point.


In case you’re wondering, the subframe tube is supposed to have that squished shape. It’s a cheap way to join two pieces of tubing together in a way that is better supported. Two cylinders only touch on a single line, so there would be a lot more stress on the areas around the bolts if one tube wasn’t squished like this. They can also get away with thinner material by employing this shape.


While I was in there, I found this random piece of… something… rattling around in the mechanism. Extra resistance training!


Now we get into the meat of this repair, though. The subframe is welded to the frame, so we gotta cut it out of there. I decided to start by carving off the drumsticks with the portable bandsaw. This will give me much better access to the main welds.


I was able to lop off the ends of the subframe with the bandsaw, and we get our first look at the main frame underneath.


As I was cutting, the subframe started disintegrating before my eyes, as though it knew deep down that it was a thing that is no longer of this world, clinging to life only but for the grace of the slow pace of entropy. Perhaps it hoped to see the Heat Death, but it knew it probably wouldn’t.


Said another way, this thing was foooooooooooooooooorked up.


With the big chunks out of the way, we now need to separate it from the main frame, which means cutting those welds somehow. I could access some of the welds with the angle grinder. I keep small mostly worn-out zip discs around for jobs like this, when you need to get in tight. I couldn’t get in all the way though, and I really wanted to avoid disturbing the factory welds of the two main square tubes to each other. The factory welds are better than my farmer-weld replacements would be.


For the tightest spot, I was able to cut lateral kerfs in there, then crack the pieces loose with a cold chisel.


With the chunks free, I was able to clean up the area in preparation for welding in a new part. I ended up with a hole that was a different shape than what the original part fit into, but we can work with that.


Everything is all cleaned up for welding, and the factory welds are intact. So far so good!


I also took time to remove anything nearby that might be damaged by the welding. There were electrical somethings zip-tied to the tubing inside the machine, which I could reach with a large forceps. One of the many advantages of growing up with a family full of veterinarians is that I learned the shop value of surgical tools. If you don’t own a full range of forceps, drop what you’re doing and buy some right now.


There is also this thing attached to the tubing, which looks to me like a hall effect sensor. I suspect it is related to the calorie burn calculator in the computer, which estimates how much work you’re doing based on the RPM you achieve and the resistance setting. I marked the location of it with sharpie and removed it to protect it from welding heat.


Now I needed to figure out what to replace that subframe with. At first I tried some round tubing. I have some really heavy wall stuff left over from the front foot repair, and it’s a decent match diameter-wise for the factory part. I tried to squish it the same way the factory part was by heating it to plastic temperature along one edge, and pressing a round part down into it. At least, that was the plan. Even with the acetylene torch, however, I couldn’t get enough heat into it. Tubing has a lot of surface area, and it reached an air-cooling equilibrium that was too low. After burning through a lot of torch fuel, I decided a forge would be needed for this idea. In any case, because the opening I made in removing the old part is not round, a round replacement part wasn’t a good match. After fooling around with some scraps from the junk pile, I found that a piece of 2″ heavy-wall square tubing was actually a really good fit for the opening in the frame. It would mean the joint to the foot was flat-surface-on-cylinder, which is again a single line. However, all this means is that the bolt areas around the foot will be a bit more stressed, and the foot is easy to remove and repair/replace if needed. The new subframe would be so beefy that it will definitely not fail due to this interface. I now had a plan!


This is a scrap of tubing left over from Furiosa’s Workbench. It was time for the big guns.


Tubing this heavy shrugs off the portable bandsaw with the shrill cry of a thousand banshees, so I had to bust out the horizontal bandsaw. I maintain these crappy import horizontal bandsaws are a good bargain once you tune them and put a proper blade on them. It doesn’t break a sweat on this heavy tubing.

With the tubing cut, it was time to see what I could do about fitting it up.


It seems like this plan is crazy enough to work. I can get it aligned pretty well with enough magnets and fiddling with squares. The gaps to the main frame are more than I’d like in a couple of spots, but I can bridge them with some weld build-up. I had reached the point where I didn’t want to grind away any more of the main frame to get a flat interface, so I needed to work with what I have.


The next task was to get the welder set up for this job. It was going to be tricky, because I’m welding very heavy-wall tubing to very thin wall stuff. The settings to get really good penetration on the square tubing would blow through the thin-wall stuff like a twister through a trailer park.

I opted to set the welder up for the low side of what the thick stuff wants (just enough to get decent penetration), and focus on heat control. My plan was to basically lay the bead on the heavy stuff, while just sorta “washing” the weld puddle up on to the thin stuff as I go. I figured I had better practice this first.


I used a scrap of the old subframe to stand in for the thin stuff, although it’s actually a little thicker than the main frame. It was a chance to test my heat control technique, and I’m pleased to say this worked very well. I got good penetration on both parts, and nothing blew out.


Okay, so the welder is now set up right, but getting the weldor set up right is a different can of worms. Unfortunately, all the actual welds are in tricky places. None are flat, and access is not good anywhere. By rolling the exercise machine around on the floor, I was able to avoid any upside-down welding, but I did have to do some vertical. Keeping away from the plastic parts really limited where I could get good angles, but I did the best I could.

Results were mixed. Some of the beads turned out sorta okay, and others are complete rubbish, but they did all achieve good penetration. I’m confident they will hold, but they will not win any beauty contests.


Down here in the tight spots behind the resistance wheel (which is plastic), access was tough. I actually got a half decent bead in here, if you squint just right.


This is probably the best one of the lot. It was the last one, of course. Shockingly, you get better at the job as you go.


Ironically, the one with the best access is the worst. This one is facing up, and there’s plenty of space to work. There no excuse for this, except that I’m a half-assed weldor. But hey, it’ll hold.


Next we need to find a way to mount the foot to our new subframe. The easiest thing seemed to be to re-use the old mounting bolts. On the factory subframe, they used that technique where the holes are punched, and then the flashing left behind from that is threaded to take the bolt. This is a very inexpensive way to thread a fastener into thin-wall material. In my replacement, however, the material itself is thick enough to take threads, so I can simply drill and tap it directly.


I marked the center line of the part, and laid out where the holes need to be.


The next step was to figure out what the factory hardware is. Since it was made overseas and it isn’t 1978, you can bet it will be metric. I grabbed that thread gauge first.


Yep, we have ourselves an M8-1.25. Luckily, I have that tap.


It was at this point that I realized I should have made these holes before welding the part in place. This would have been way easier to do on the drill press. That’s what I get for not actually having a plan. Instead, I had to drill them by hand and do my best to get them straight.


Getting these straight is quite important, because any error here will be magnified a lot at the long ends of the foot.


Taaaapy tap tap


Now for a quick test fit of the bolts…


Those aren’t crooked, they are “artisan”. People pay big money for that now!


Okay, moment of truth! Let’s do a test fit and see how she goes.


Result! That seems like it’s going to work just fine. Recognize that white Delrin roller? I made those a while back.


There’s one little detail to be aware of here. The overall height of the back of the machine was being established by the thickness of that factory “squished tube” subframe. My new part isn’t exactly the same cross-section, when measuring mating-surface to mating-surface between the foot and the main frame. However, I think it will be close enough that you can’t feel it on the machine.


You can see that my new subframe is a wee-bit taller than the old one, so the machine is technically pointed slightly downhill now. However, this is 3/16″ of error over 4′ of machine length, so I doubt it will be noticeable. The whole machine sits on a soft rubber mat that probably introduces more error than this anyway.


Okay, let’s get this thing back on its feet and see if it’s going to work.


Looking good! The far leg has some daylight under it, but I assumed this was just a low spot in my concrete floor. Spoiler: it wasn’t.


Now for some paint, and reassembly!


A bunch of masking and spraying later, and we’re looking good.


Back in one piece. This seems crazy enough to work!


I’ve used that same white spray paint for all my repairs on this machine, and of course it doesn’t match the almond factory color. I like that you can see the history of all my repairs at a glance. It’s like software source control, but for madness.

“But wait,” you might be thinking, “What about the rear of the dust cover that bolted to the round subframe part?”. If you thought that, you’re a lot smarter than me, because that didn’t occur to me until the moment I tried to reinstall it.


Wait…. um….. hmpf.


The mounting bolts for that plastic part are required to be at a funny angle, which was fine when the tubing was round. On this square stuff, not so much. I took a shot at drilling and tapping angled holes in the square tubing, but the angle was impossible to do. There was no way to get that drill started.

Need to attach something weird to something else weird with no fasteners? Zip ties.


Installed. All that’s left to do is dust off my hands and walk casually away from the explosion without looking back.


Feeling pretty chuffed with myself, it was time to put the machine back in its spot.


It was at this point that I realized it was not the floor’s fault that the rear foot wasn’t sitting flat. Much as we hope every time, it’s never the floor’s fault.


Even sitting on the rubber mat, the machine had a distinct front-left-to-rear-right rock to it. Luckily, an easy fix was at hand. I just needed to shim one side of the rear foot down a bit with a washer on one of the mounting bolts.


Sprocket was instrumental in supervising this portion of the repair.


Yes, I have a Snap-On tool fetish, and no it isn’t rational. In my defense, I’ve never paid more than 35% of retail for one. I have my ways (okay, one way, and it’s eBay). Sprocket certainly agrees with my taste in tools.


You can just barely make it out in this photo, I think. The right side of the new subframe sits a little higher because I added a washer in there. That lowered the right end of the foot to level out the machine. It worked perfectly!


Oh, and, in case you were wondering, those crooked bolts did show themselves in the end.


Um… yah… that there foot has got a little… list… to ‘er. Sorry, I mean, it’s “artisan”.


After all that, is the machine actually fixed? In a word and three letters, “OMG yes”. I didn’t realize until now how wobbly that machine really was. I was used to it, and the stress fractures in that part have formed gradually over time. The whole machine was jello, but I was accustomed to the feel of it. Now, it feels completely rock solid, like standing on, well, rocks. The whole machine is amazingly quiet and smooth now as well. Not nearly the squeaky rattle trap it usually is. Who’d have thought that the rigidity of the frame could make such a difference in how the entire machine functions. I always learn something in these repairs, and this time I gained a whole new appreciation for how steel structures live, breath, and ultimately fail.

What’s next for this machine, you might wonder? Honestly, the next most likely failure point is the main frame, around where I welded in the new part. That’s the next potential weak link in that chain. When that fails, it’s highly likely to be not worth trying to repair. I’d pretty much have to rebuild the whole machine from scratch to fix that. Surely that would be a bridge too far to keep this thing going? I should know by now never to make statements like that around here.









]]> 19
Veronica – F18A Control Signals Wed, 22 May 2019 03:56:14 +0000 read more]]> It was the best of times, it was the worst of times.

With our recent success in remembering how to do address decoding, it was time to look at the control signals. The V9918A has three basic ones- /CSR, /CSW, and MODE. The first two are active low signals for reading from and writing to the device. The MODE signal is weird, and we’ll get to that in a bit. The device’s interface to the outside world is an abstraction of a lot of internals, including a large array of registers and a secret stash of video RAM (external on the V9918A, internal on the F18A). What’s interesting to me about this is that it’s the exact same interfacing paradigm that I used in my home-brew GPU for Veronica. That seems to suggest that it wasn’t a terrible approach for me to take after all. Even a blind squirrel finds a nut sometimes.

I spent some quality time with the technical manual for the V9918A (it’s actually a great read) and I narrowed down what I felt would be the simplest use-case to achieve: changing the border color of the screen. This is done by writing one byte to register 7 in the 9918, which is the smallest operation you can do that will have some obvious effect.

Writing to a register consists of two byte-writes. Recall that the V9918 sits on the data bus and acts like a single byte that you can memory-map (which we did last time).

This clip from the V9918 technical manual explains how to write to a register.

You start by writing your data byte, then sending another byte to tell the 9918 what to do with it. This seems backwards, but it’s how they did it. It’s “Noun, Verb” instead of the more expected “Verb, Noun”. Note the MODE column in that chart. Some of the more complex operations (such as reading or writing blocks of VRAM) require manipulating that MODE bit. Part of the reason I chose this simple register write as a test is that the MODE bit can be tied high and I don’t have to worry about hooking it up. Truth be told, the manual recommends simply connecting MODE to the least significant bit address line, which effectively maps two memory bytes to the V9918. That’s a nice elegant way to generate that control signal, and is likely what I will do as well when the time comes.

Looking at the register descriptions, we find number seven is the interesting one for our test:

This register holds two colors- one for text and one for the main backdrop (which is also the “border” color, always visible).

The colors are specified from a fixed palette, which is kind of an interesting restriction (though not uncommon for 8-bit machines, 16-bit-era machines universally did away with this).

These are the 16 colors we have to work with. I hope they’re nice!

Given all that information, it seems that if we write the sequence $FF $87 to the device, it should set the border color to white (and also the text color, but that’s fine- it simplifies our test to send all high bits for the first data byte).

Next we need to provide the primary control signal to the F18A, which is /CSW (memory write, active low). The weird thing about the 9918’s design is that it has separate Read and Write control signals, and the device is de-selected when both are inactive. A typical 6502 accessory has a R/W line and an /Enable line to match the single R/W signal provided by the CPU. To do this translation, I’ll use a simple OR gate with the R/W line and my address decode. Both are active low, so an OR behaves as an AND gate. In other words, when the address is decoded and the CPU tries to write, wake up the F18A and put it on the data bus. Simple as that. We’ll need to do additional signal fiddling for the read signal, but reading data back from the V9918A is a more advanced function that we can do without for the moment. The main purpose for reading would be to get the status register, which contains (among other things) the sprite collision flag. We’ll need it eventually, but for now writing is enough.

Here’s my oh-so-sophisticated control signal generator so far. A single 74HC32 quad OR gate. Note that you shouldn’t have floating inputs on TTL chips as I’m doing here. It’s fine for this little test, but you must tie them all high in the final design or you will get noise in your circuit.

Now in principle, with the F18A sitting on the data bus, and my address decoding working, I should just have to write those values ($FF,$87) to $DFFE and it should work. I have an interesting tool for doing that- my ROM monitor.

Using the “write” command in my monitor, I tried setting the values. Nothing seemed to happen on the F18A. I put my logic probe on the address decoder, and did the write command again. No blip. That suggests the data is not going to the correct address, or the write isn’t happening at all.

I decided I had better do a quick sanity-check on my ROM commands.

Here, I wrote $ABAB to address $2000, and that seemed to work. The $42s are the aftermath of the RAM check sequence, so I know that my writes succeeded.

The ROM tool seemed to be working, but my address decoder was not firing. When all else fails in debugging, start questioning every assumption. I’m verifying the ROM write tool works by doing what? Using the ROM read tool. Maybe both are broken? I wrote a special function in ROM that just spams the $DFFE address with a value and uploaded that code. My address decoder fired like crazy. So, it seems my ROM routines aren’t behaving correctly in some mysterious way. You may recall I had similar issues with the ROM commands last time. Rather than spending a lot of time debugging that, I decided to stay focused on getting the F18A to respond to my data. I changed my “memory spam” routine to send the $FF,$87 sequence to $DFFE. My address decoder blipped, which was certainly encouraging. Did anything happen on the F18A? Nope.

Time for the logic analyzer again. The logic analyzer revealed that on the falling edge of the /CSW (memory write) pulse that I’m giving the F18A, the data bus is not set up yet. At that moment, the second half of the $DFFE address is still there (from when it was reading my program). It’s been so long since I did low-level 6502 stuff that I forgot the cardinal rule of the 6502 data bus- there’s a two phase clock, and all the good data stuff happens in the second phase.

Time to dig out the probes again…

I figured I could improve this situation by ORing my /CSW signal with the inverse of the clock. Since both will be active low, the OR will act as an AND, thus sending /CSW only when the address has been decoded, and when the clock is in the second half of its cycle.

Here you can see the problem.  D8 is my /CSW signal to the F18A, and when it goes low, the data bus is still setting itself up. Where the white cursor line is (the second half of the clock cycle) is where I need that /CSW to be. That’s when the $FF is on the data bus.

I threw a 74HC04 inverter on the breadboard to invert my clock, and used another OR gate to include it in the /CSW signal. Seasoned 6502 people are yelling at their RSS readers right now because you should never need to invert the clock on a 6502. It provides two clock outputs (ɸ1 and ɸ2) specifically for this purpose. Most things use ɸ2, but in cases such as this when you really need the other phase, ɸ1 gives it to you. However, I didn’t actually put ɸ1 on Veronica’s backplane, because it is so rarely needed. I have literally never needed it in any of the other devices. So here I am, putting an inverter on ɸ2 like a chump. However, the logic analyzer did show the data on the bus was now correct when /CSW goes low. That’s encouraging.

At this point, I absentmindedly moved my VGA cable over to the F18A. I only have one monitor on my lab bench, so I quickly got into the habit of shifting the plug back and forth between Veronica and the F18A while I worked. I was literally just muscle memory by this point. This time, however…


It worked!!! Those two bytes made it over the F18A and changed the border to white, frankly while I was still fiddling with the clock inverter. This was a huge moment! I think I immediately jumped on Patreon Lens and Instagram to share this news because I was so excited.

It was time to start formalizing some of my interface signals, and it was around this time that I finally realized I’ve been using the wrong memory address all this time. I was supposed to be decoding $EFFE, which is in Veronica’s hardware page, not $DFFE, which is just a general memory address. I rearranged the constant values on my 74HC688s and double-checked that the F18A was still responding to my control bytes. It wasn’t.

Suddenly nothing was working any more. I had that one moment of pure victory, then touched one minor thing, and I lost it. I reverified everything in the address decoding and the code spamming bytes and yada yada, but the F18A wasn’t responding. I also noticed that current draw had gone up about 50mA, and Veronica herself had become unstable while the F18A was connected.

Instability and slightly higher current consumption are usually a sign of bus contention, so I probed the F18A while it was deselected. The news was… strange.

With the F18A deselected, all pins on its data bus are tri-stated as you would expect… except two.

That was really odd, but it seemed as though the F18A was still driving the bus even when deselected. At the time it didn’t click for me that this was new behavior. I thought maybe it was always like that and I hadn’t noticed. Perhaps it just doesn’t play nice on the data bus, and I need to isolate it better. I busted out a chip designed for exactly this- a 74HC645 bus transceiver. It allows two-way communication between two devices, while allowing you to completely isolate them when needed.

Here’s the bus transceiver, inserted between Veronica’s data bus and the F18A. The /Enable signal on this guy is connected to the F18A address decode.

However, it still wasn’t working. Time for the logic analyzer again.

This all seems okay, but… maybe the timing isn’t right?

The signals seemed okay, and were the same as when it was working before. However, truth be told, you can see in that timing data that the falling edge of /CSW is a bit close to the data bus’ setup. Maybe too close? Am I violating the the timing requirements of the V9918A? That one time it worked might have been lucky?

A quick trip to the dark bowels of the V9918A datasheet was in order. When one resorts to reading timing diagrams, it’s seldom a harbinger of glad tidings.

Here’s the timing diagram for a CPU write to the 9918’s data bus.

The documentation doesn’t say if the data is actually latched on the falling or rising edge of the /CSW signal, annoyingly. The falling edge would be typical, but that timing diagram strongly suggests it’s the rising edge doing the work. If true, that’s really inconvenient for us, because on the 6502, by the time we get to the next rising clock edge, the data bus won’t be valid anymore. The previous rising edge is too soon. Furthermore, the diagram states that the setup time on the data bus (tsu(D-WH)) is 100ns, and hold time (th(WH-D)) is 20ns. If I read that correctly, we somehow have to get the data bus to sit stable for 120ns on either side of the rising edge of /CSW. That means shifting /CSW forward by one quarter of a clock cycle (half a phase). That’s a super annoying thing to try and do in digital logic design. I’m guessing the chip behaves this way because it suits the TMS9900 CPU for which it was really designed. The 6502 does not like doing things the way this chip seems to want them.

Shifting a pulse forward in time 100ns is not easy, but there are ways. The cheap and dirty way is to put a bunch of dummy gates in the way. Buffers, pairs of inverters, OR/AND gates with the inputs tied together, etc. The challenge is that you need a lot of them to get a shift that big. If the discrepancy was 10ns, we might get away with this. 100ns is quite another story. One hundred nanoseconds is an eternity in digital logic, even at 1MHz. There is also the digital design scoundrel’s tool of last resort- the silicon delay line. This is a specialty chip that takes a pulse in, and gives you multiple output taps that space that pulse out by varying degrees. They are the goto of hardware design. They can solve your problem in a pinch, but if you need it, your whole approach is probably wrong. I also considered more complex setups like latching the data in my own external buffer, and handing it over the 9918 asynchronously. Before I went down any of these rabbit holes though, I wanted to have some evidence that a timing violation was actually my problem here.

I started by wiring up a whole bunch of my slowest inverters in series. I was able to buy about 50ns of propagation delay this way, which should make some difference.

You can see here that with my inverter shenanigans, I was able to shift the /CSW forward enough that I’m no longer, in theory, violating the timing requirements. Assuming I’m interpreting that chart correctly and that I’m correct in my guess that the rising edge is what it cares about.

According to the scope, my data bus has definitely settled well before the rising edge now, so both the $FF and $87 bytes should be getting in. However, I still had no action from the F18A. It refused to change the border color the way it once had. It was around this time that I started noticing a new problem. I was getting noise on the data bus between my bus transceiver and the F18A. You can see it on line D4 in that photo of the logic analyzer above. To verify this noise wasn’t coming from Veronica, I even disconnected her data bus and drove the F18A directly with my hex input tool.

I verified the data on the F18A side of the transceiver wasn’t right by driving that slave bus directly from my hex input device. Even this direct drive wasn’t resulting in the right values.

Despite putting $FF on the main data bus, for example, the F18A side of the transceiver would show $FB. Instead of $87, it would show $83. What pattern do you see there? Let’s look at the binary.

$FF = 11111111
$FB = 11111011
$87 = 10000111
$83 = 10000011

See it? Bit 2 is zero in both errors, when it should be 1. Something is driving that data line low. Remember the noise I was seeing on the F18A that prompted me to put the bus transceiver in? That wasn’t the chip being ornery. It was permanently driving those pins. A growing sense of dread started to form in the back of my mind. I started probing pins on the F18A, with no power applied.

These two pins on the data bus are shorted together. Poopknuckles.

Looking closely at the board, those pins both feed directly into that nearby chip, which is an LCX16245 16-bit bus transceiver. Basically a modern version of the little 74HC645’s that Veronica uses.

Pins being driven to arbitrary values, you say? Pins shorted together with no power applied, you say? You know what those are symptoms of? A fried bus transceiver. It seems at some point during my experiments, I fried that chip. I was gutted. There were no two ways about it, though. At this point I have multiple lines of evidence clearly pointing to that chip being fried.

I had to walk away from the project for a while, at this point. The F18A is unobtainium now, so getting a new one is off the table. I was at a loss, but then my Patreon Patrons to the rescue! I was posting a lot of live updates to my Patreon Lens (available to Distinguished Patrons and above) and when this problem came up, people jumped in with a suggestion. They pointed me to tools and techniques for replacing fine pitch SMD chips without a lot of fancy tools. I tried my hand at this, so stay tuned to see how this went!


]]> 2
Veronica – F18A Address Decoding Tue, 14 May 2019 21:54:04 +0000 read more]]> Bridging The Gap


As you probably know if you’re the kind of person who follows this blog, the 6502 CPU (the 1970s chip around which Veronica is based) talks to the outside world entirely via memory mapping. Contrast this with, say, modern microcontrollers which have a set of general purpose input/output pins, and a special instruction (or twenty) to talk to those pins. On the 6502, all it has are address lines and data lines. It’s up to you, the computer designer, to hang things on those buses that can play nice and communicate with the outside world. The technique we use for doing this is called address decoding. Basically, each peripheral that the CPU needs to talk to is attached to the address and data buses. All of them, at the same time. How do we prevent them from interfering with each other? Well, every peripheral has to have an “enable” signal of some sort, and it’s up to all of them to play nice and not use the bus when they aren’t supposed to. This is called bus contention, and it generally creates noise on the bus which causes malfunctions in software and other chaos. What address decoding does, then, is listen on the bus for a specific memory address (or range of addresses) that have been assigned to that peripheral device. When those addresses are heard, we know it’s our turn, and we can jump on the data bus and start using it. The address bus is read-only, so everyone can listen to it at the same time. The data bus is read/write, so everyone has to take their turn.

How do you decide which range of memory addresses to assign to which devices, then? Well, that’s the job of the computer designer in a 6502-based system, and it’s a combination of convenience and compromises on space. Memory-mapped I/O is really really elegant, but the downside to it is that it actually takes away RAM from the system. If you have a specific byte in the address space assigned to your device, that same byte in RAM is now invisible to the CPU and can never be used. There are tricks like bank swapping and memory overlays that can recover some of these losses, but you’ll never get the full 64k of RAM to which your 6502 is entitled unless you have zero devices on your bus (and thus your computer is an exercise in navel-gazing as it can do no useful work).

How do you decide how many addresses to assign to a device? This depends on what the device needs. Something like a keyboard might need a couple of bytes for transmit and receive buffers. Something like a floppy drive might need a 1k chunk for read/write buffers and control signals. System ROM (what the kids today call BIOS) often takes up large chunks as well. ROM is a memory-mapped peripheral just like any other.

Ranges of memory addresses are generally assigned as dictated by convenience of address decoding logic. If you’ve ever wondered why the memory maps of old computers are crazy, with random chunks taken out of the middle of RAM all over the place, this is why.  If you’re willing to live with a fragmented memory map, your address decoding gets orders of magnitude simpler. For example, to reserve a 4k chunk, all you need is a 4-input AND gate and some inverters attached to the top four bits of the address bus. That will match exactly one 4k chunk (say $C000 or $8000) of memory. This is generally how big stuff like ROM is done. Generally speaking, the more “surgical” your address decoding needs to be, the more complex the address decoding logic gets. Forget trying to match 7 bytes at $C067 and 4 bytes at $D142 in your device. Your address decoding logic will use more chips than the rest of the machine combined.

Flashing back to my original graphics hardware for Veronica, I did something rather unusual for a 6502. I hung the entire graphics system on a single byte in the memory-mapped I/O. Everything was done with a special “command language” consisting of command bytes and data bytes sent serially into the GPU. The idea was that data transfer doesn’t have to be fast, because the actual job of rendering and managing the graphics is entirely separate from the CPU. This also made interfacing much simpler, since I didn’t have to come up with a clever means of sharing system RAM with the video circuitry (a very hard problem in early computer designs). This model of “command bytes” is more typical of non-6502 systems, like modern microcontrollers that tend to use I2C (or similar) to talk to peripherals.

That brings us to the F18A, which works the same as the V9918A upon which it is based. Interestingly, the V9918A also works by communicating through a single byte-wide channel, along with a couple of signals to control mode and read/write. It behaves much like a latch or shift register chip rather than a full-fledged GPU. This is because it was designed for the TI-99/4A, which is designed to have an external graphics processor doing all the heavy lifting. The V9918A and the 6502 make somewhat odd bedfellows, but it does make interfacing very easy. I only need to memory map a single byte in memory, like I did with my own GPU. So let’s get to it!

To the big box of chips!


I love my big box o’ chips very much. The solutions to all digital problems lie somewhere in here.


My weapon of choice for this address decoding job is the 74HC688. This chip is an 8-bit comparator. It takes in two 8-bit values, and tells you if they are the same. It has an “enable” signal, and an output signal, which can be daisy chained together to match larger values. In my case, I want to match one 16-bit memory address, since I only need one byte of memory to map the F18A. Two 74HC688s will get the job done.

My original GPU’s one byte access point was mapped to address $dfff [This is actually incorrect, and caused me to make several subsequent errors. Stay tuned- Ed.]. I decided not to reuse that so I can operate both sets of video hardware at the same time. That will be very helpful for debugging, since I can use my old video to create tools for bootstrapping the new one. To that end, I opted to map the F18A to $dffe.


It’s been a while since we had a nice breadboard shot here on Blondihacks!


In that photo, you can see I’m bringing the address lines (yellow) in to one “side” of each comparator, and the other sides are tied to a “constant” value created by tying pins to 5V and Ground as needed. One annoying thing about the ‘688 is that the bit values being compared are interleaved on the chip. Bits from each value are side by side, instead of being grouped by value. This is no doubt for convenience on the die, because this device is really just an 8-input NAND gate (likely created with a cascade of two-input NANDs internally). The topography on the die is vastly simpler if the bits are grouped by position instead of value.

The next step was to find a way to test this. In principle I can connect the decoder to my address bus, but then what? How do I know if it works? Well, because Veronica is already a working computer, I have a secret weapon in that fight- the ROM monitor. This is a low-level command line tool that can be used to do some basic memory manipulation directly on the machine. Also, because of my microcontroller-based ROM emulation, it’s very easy to flash new code to experiment with. However, before I can do any of that, I need to refresh my memory on working with Veronica’s ROM code.

It has been so long since I did any of this that I have completely forgotten how Veronica’s tool chain works. Luckily, I documented it- right here on this blog. I’ve often said that this blog is not just for your entertainment (though I hope it does serve such a role). It’s also my own technical notebook. Now more than ever, because I need to re-learn vast sections of this computer and the tool chain associated with it. After reviewing many of my old blog posts, I wanted to see if I can successfully modify the ROM code. An easy way to do that was to change some text that it displays at startup.


Blam! What was a RAM check is now a BLAM check, proving my tool chain still works, and I have successfully re-learned how to use it.


My documentation isn’t perfect though. I had a rather silly problem next- how do I connect to the address bus on Veronica? More specifically, which end is which? I had documented which bus lines are the address in my schematics, but not actually which pin was which. The signals are named in Eagle of course, and I have those files, but my version of Eagle is so old that it won’t launch on my current Mac OS anymore. I had to trace the signals from the A0 pin on the 6502 CPU down to the bus to see where it landed. This is the risk in relying on proprietary file formats for documentation. It’s very easy to lose the ability to read them.


A logic probe can also tell you which end of a bus is which, because the pulses will be higher-pitched on the less-significant bits. They change more frequently, so the pulses are faster, making the probe sing higher. This is not a 100% reliable method, but can often be a clue.


The next thing I wanted to do was arrange Veronica to run off my bench supply, not her own internal power supply. In my earlier tests, I learned that the F18A is going to be drawing around 230mA, and Veronica draws about 170-200mA on her own. So now we’re flirting with half an amp, and Veronica’s “power supply” is really just a linear regulator and a couple of filter capacitors. It’s not up to a whole lot of demand.


Luckily, Veronica is built for this sort of thing. It’s a simple matter to disconnect the backplane’s power input and run it through my breadboard instead. The breadboard gets juice from the bench supply, and Bob’s your uncle.


At this point, in principle, I can use my existing ROM “write” function to put a value on the address bus, and trigger my address decoder. However, it didn’t seem to be working. I held the logic probe on the decoder’s output (which is active low) and tried to make it blip by modifying memory in the monitor. The probe was pinned high, no matter what I did. However, while experimenting, I did notice something odd- if I held the probe on the address decoder while the machine boots, it does blip at one point. Why? The RAM diagnostic! At boot, Veronica cycles through almost all of memory, writing and reading back bit values to make sure everything is okay. One of these trips the comparator and blips the logic probe.


Aha! Booting the machine trips my address decoder. So why can’t I trip it with my ROM tools?


Perhaps the ROM tools aren’t working because my comparator is detecting the wrong address. The RAM check is so fast that I can’t tell which address is tripping it, just that one of them is. At this point I busted out a tool that I built for a very early point in Veronica’s development- my hexadecimal input device.


Result! I verified with this device that the value that should trip the comparator ($DFFE) does in fact do so! This device is crazy useful- it allows you to drive a bus with any 8-24 bit value that you want, for situations just like this. Build one yourself!


Okay, the comparator is correct, so the failure must be somewhere upstream, like how the ROM code is driving the bus. In the old Veronica days, I’d have started writing elaborate process-of-elimination test cases for my ROM code to deduce what the hardware downstream was all doing. Maybe I’m getting impatient in my old age, because this time around I went straight for the logic analyzer.


Yup- when the breadboard looks like this, things are not going well.


The logic analyzer makes fools of us all in pretty short order, and this was no exception. I know that the comparator gets a match on boot, so I set up the logic analyzer to trigger on the output of the comparator while tracking the address lines on the bus. Let’s see what value it sees when it fires.


Well well, would you look at that. In fact, the comparator is triggering at $DFFE, just like it should. My analyzer is only 16 bits wide, so I tested one byte at a time, since I needed an extra bit for the trigger (shown here on D8)


At this point it was certain that a bug in my ROM code was the problem, because this boot-and-analyze test has eliminated all the hardware between my comparator and the actual code running in ROM. Rather than spending a lot of time fussing with the ROM code trying to debug it, I opted to write a simple line of code that would spam the memory address in question ($DFFE). It doesn’t matter whether I read or write, because the only goal is to get that address on the address bus for a substantial portion of time so that the logic probe can see it. That code is extremely sophisticated, as you’ll see:

spam: lda $dffe
      jmp spam


That was a 6502 assembly joke, in case you missed it. This is definitely not sophisticated. The good news is, that worked! My address decoder is working, and I will be able to talk to the F18A by writing data to $dffe. Now we can move on to the rest of the interfacing job.

But wait- there’s just one more thing. Remember the blobbed solder joints that I was concerned about and ultimately decided to ignore? Well, while messing around with the addressing decoding, after a reset, the F18A suddenly started drawing half an amp and got very hot. I yanked the power as quickly as I could, and luckily it seems to be okay. This made me wonder if I had tripped some internal feature in the chip that was using those shorted pins. I figured it was time to bite the bullet and try to fix them.


I started by investing in a set of very very fine pointed tips for my trusty Weller iron. These things are great for fine work like this.


I struggled for a while with my head-mounted magnifier on maximum (about 10x, I think), but my 44yo eyes were not up to this job. To fix solder joints on a 0.5mm pitch SMT part, the ideal tool is a binocular microscope. I dunno if you’ve priced those out lately, but they’re a bit on the spendy side. I’m also cheap, so I looked for another way. Luckily, I found one. While struggling with the magnifier, I found myself wishing I could see as well as in the macro photo I posted earlier.


Gosh, I sure wish I could see this well. WAIT A MINUTE….


Then it hit me- why not just use the macro lens to do this in realtime?


I set up an old cellphone hovering over the work, with the macro-lens attachment that I use to take those magnified photos. Sure enough, I was able to work under this with the fine pointed iron and clean up the joints!


I was shocked at how well this worked. The main downside was that the focal length of a macro lens is very short, which means the lens has to be physically very close to the work. That means it’s a bit tricky to get the tools in between the lens and the work. However, you can do it, and I got the job done.

After all that, did I fix the problem? Well…


It turns out there was no problem. I cleaned up the excess solder on the joints, and found that there’s a hidden trace connecting them anyway. There was no unintentional short in the first place.


If you look closely in that photo, you can just make out little rectangles on the board connecting the pins. There’s a trace there, so these pins are supposed to be joined. That means I don’t actually know what caused my brief short that turned the FPGA into a toaster oven for ants, but luckily it survived, and the problem has not happened again. Maybe it was a temporary problem on my breadboard, I’m not sure. I’m keeping an eye on it, and I don’t leave it plugged in for long, just in case. I only have one of these and they’re hard to get now, so I need to take care of it [ominous foreshadowing- Ed.].

Okay, with the address decoding sorted, the next job is to get the other control signals sorted out. The F18A (really the V9918A) has some odd ones, so we’ll need to figure out how to generate them. Stay tuned!




]]> 15
Swiveling Tripod Adapter Sun, 28 Apr 2019 21:38:49 +0000 read more]]> Making improvements to a tool we built


A while back, I built a couple of smartphone mounts for tripods, based on a design that came to me in a whiskey haze. That design worked very well at the main thing it was designed to do- hold a cellphone. However, in practice it has one decided weakness. Any time you attach a camera to something, you need to consider how the camera will be aimed. In my case, the thought was that the NOGA arm will be doing all the pointing, so the camera mount can be static. In practice, that didn’t work very well because the weight of the camera tends to loosen the threaded attachment point, and it’s often inconvenient to have to loosen the entire NOGA arm to rotate the camera.

If you’re not familiar with NOGA arms (or the copies thereof), they are a three-jointed arm with a single knob at the “elbow”. You can loosen the knob, arrange all three joints anywhere in space that you want, and then make the whole arm rigid in that position by tightening that single knob. They are pretty magical. Internally, they work in one of two ways. Some models have cables that run through the joints away from the elbow, and the knob acts as a sort of “winch” to tighten both of them at once, locking all the joints in position. There’s another approach whereby the whole arm is filled with fluid, and tightening the knob eliminates all air space from inside the tube/joint system, effectively locking everything up hydraulically. Both approaches work well. NOGA arms are used in machining, photography, and various other applications. In machining, they are typically attached to a magnetic base, but you also see them bolted to other equipment, or clamped to things.

Here’s an example of how “version 1” of my camera mount worked when attached to a large NOGA arm:


Pretty cool, right? With a NOGA arm and my Smartphone Holder, you can slap a camera anywhere. There are steel plates screwed to the walls and ceilings around my shop, and the magnetic base allows quick and easy camera positioning.


However, here’s the problem:

In a position like this, the phone won’t hold that angle for long. It will swing downward on its own mounting screw.


The problem is that the smartphone holder is effectively a long lever that gives the weight of the phone a lot of advantage over the mounting screw. No matter how tight you make it, it will always tend to unscrew itself any time the phone is held in a position where gravity would pull it to the left (lefty loosey).

A jam nut in there might help, but the other problem with this setup is that setting the camera angle is a bit inconvenient, as I mentioned before. It’s also worth noting that standard tripod threads are ¼-20, while the large NOGA arm end-effector has an M6 thread in it. These are obviously incompatible. I had “solved” that temporarily by re-cutting the threads to ¼-20 on half of an M6 bolt. Don’t do this, it’s dumb (though it did actually work).

What I’d really like is a way for the camera to be securely attached to the arm, but still be able to adjust it in space, while simultaneously adapting those mismatched threads to each other. Here’s what I came up with to do that.


As is tradition, I modeled this idea in Fusion 360 first. I’ll share this model and the engineering drawings for the part on my Patron feed, if anyone wants it.


This adapter consists of an M6-threaded rod that goes into the NOGA arm (and can be jam-nutted or Loctited as desired). This is shown in pink in the model. The other end is a smooth shaft with a channel in it. That channel holds O-rings for friction. A knurled knob (shown in yellow) fits over that shaft and is secured with setscrews. The knurled knob acts as the jam against the smartphone holder, while the smooth shaft inside allows the whole assembly to be rotated freely. The friction of the O-rings (with tension set by the setscrews) holds the phone in any orientation. The back of the knurled knob is threaded ¼-20 for fitting into any camera mount (in this case, my smartphone holder).

Okay, so that seems sane enough to work. Let’s give it a go. I’ll start by making the shaft that goes into the NOGA arm.


I turned the shaft down from some 360 brass, because I like this material a lot. 360 brass is an alloy with a tiny amount of lead in it, which makes it nicer to machine. It’s similar to 12L14 steel in this regard.


While I’m using brass, anything would work- steel, aluminum, headcheese, whatever you have. Well, headcheese would go rancid pretty quickly, so maybe don’t use that. Also, while I haven’t done a finite element analysis on it as of yet, I suspect headcheese would present some structural integrity challenges. Your mileage may vary.


Here’s one of my favorite quick layout tricks for machining. With the lathe spinning slowly (say, less than 100 rpm), apply layout fluid (or Sharpie) to the part. Then set your caliper to the desired length. Hook one end over the end of the part, and scribe with the other end. For this to work, the end of the part must be faced. Technically you get a teeny amount of cosine error doing this, because the caliper is at a slight angle. In practice it is such a small amount that it hardly matters.


Next we need to make that little groove that holds the O-rings.


The width of the groove is pretty arbitrary, so I made it arbitrarily the width of this parting tool. A simple plunge and the feature is formed.


The shaft was turned to the diameter needed by the smooth part of the shaft, but now we need to make the M6 thread. The major diameter of an M6 thread is 236 thou (6mm, shockingly), so we need to turn down that area a smidge further before cutting the threads.


To shave a lamb’s tail hair off the threaded area, I snuck in there with a long inside-shoulder turning tool. It needed to be long because the tailstock is in the way, but this cut is light, so rigidity won’t be a problem. The tool is sharp-pointed, which will result in a poor surface finish, but it’s going to be threaded anyway.


Next up is making the M6 thread. I would normally do this with a threading die in my shop-made tail-stock die holder. However, that die holder is for round dies, and the only M6 thread die I have is the hexagonal style. Fun fact- most online sources will swear that all hexagonal dies are for thread-chasing (repair), not thread cutting. This is not true. There are genuine thread-cutting dies in the hexagonal form factor. Generally thread cutting dies are round, yes, but it goes to show that most things you read on the internet are wrong. Including everything I say, perhaps. In any case, this is a good excuse to show a method of cutting threads on the lathe that doesn’t require a fancy tool. You can do it with almost any die wrench.


For this trick, install the die in the die wrench, then find something to center and support the back of it. In this case the wrench has a big hole in the back, so I stuck the live center in there. If that won’t work, you can also apply pressure with the end of tailstock quill directly. That will keep things straight if the back of your die wrench is flat.


The trick here is to put a little chunk of wood down on the ways to protect it, then allow the die wrench’s handle to rest on that. Then you can turn the lathe chuck by hand, and the threading operation will pull the die wrench forward with it, sliding along that chunk of wood. I cut all my threads this way before I made my tailstock die holder, and it works just fine. The trick with the block of wood keeps you from needing three hands for this.


With our threads cut, all that remains is to part it off.


Now we can turn our attention to the knurled knob. That part starts with a bigger chunk of brass.


After facing the end, I turn down the section that will form the socket for the spinning shaft. I do this with the “turning to a shoulder” technique I explained here on YouTube.


This technique is really satisfying to watch as that final face is formed, so make sure to check out the YouTube video. Watch the rest of my Lathe Skills series while you’re at it!


With the outer shape of the knob formed, the next task is to make the hole in the middle. We want this to be a nice slip fit over the shaft that we made earlier. When designing parts like this, you need to think about two things:

1) What tooling do you have? If you have a standard set of reamers, don’t design a feature with a 317 thou hole, because you won’t have a reamer in that size (or even a drill, for that matter). If the hole is large enough, you can use a boring operation to reach any desired size, but the hole has to be big enough to get a boring bar into. Turning can always be done to any diameter, so make your holes a standard size, and tailor the shafts that go in them to the type of fit you need (press, slip, free-running, etc). If you have over/under reamers, that makes life a lot easier. These are reamers that are 0.5 or 1 thou over (or under) their nominal size. They allow you to easily create light press fits or slip fits.

2) What is your order of operations? Holes in certain places can only be made certain ways. If the hole is coaxial with a round part, it’s likely you can ream or bore that hole as needed. If it’s a cross-hole, boring will require a very complicated setup with a faceplate, or expensive tooling like a boring head on a mill. It’s much easier if you can ream cross holes, so plan ahead for that and make your cross holes standard sizes.



Our hole will be reamed to final dimension, so we need to start by center-drilling.


The typical Machinist Way™ to drill a hole is to center-drill (insures concentricity), pilot drill (keeps tool pressure down and larger drills on-course), drill under-size (for reamer clearance) and finally ream to final dimension (for precision). Some of those steps can be skipped, depending on how precise the result needs to be. In our case, the hole is small, so we can skip pilot drilling, at least.


In this case, we’ll drill and ream. We’re going for a generous slip or free-running fit here, so our tolerances are generous. Anything from two to, say, five thousandths over will be fine.


A quick test fit of the shaft confirms that we’re good to go.


When planning order of operations, always think about the time invested in the part at critical points. If this hole had been 20 thou oversize somehow (machinist error) the part would be useless. However, we’re only on the second or third operation, so it’s not a lot of lost time. Try to arrange it so the most difficult and most critical steps are as early as possible in the order so you don’t lose much time if you have to scrap it.

Now we can flip the part and form the features on the other side of the knob. You’ll note that I’m flipping the part in the three jaw chuck here, which is a giant no-no for maintaining concentricity! Machinists are hurling invectives at their monitors right this very moment! How dare I disgrace precision this way! Okay, everyone take a deep breath. We must always consider whether maximum precision is necessary for any feature. If a tripod adapter that holds a cellphone and will never spin much at all is out-of-concentric by 5 thou due to flipping the part in a scroll chuck, I guarantee you the sun will still rise in the morning. Everyone take a deep breath and step away from the online machinist forums for a bit. Precision is almost always a tradeoff for time, and I dunno about you, but my time on this earth is the only truly valuable thing I have. If I can save some of it in a goofy side project like this, I surely will.


Real Machinists look away!


Once again, turning to a shoulder: Super Satisfying™.


All that’s left on this part now is to cut the ¼-20 threads for the tripod mount. Luckily for this I do have a standard round die, so I can use my tailstock die holder (which was super fun to make, by the way).


These threads are small and the material is brass, so this is a very easy job.


Next up is to apply knurling to the knob. It’s not that this knob will see much handling (you screw it into the phone holder once and pretty much never touch it again) but knurling looks nifty. It wouldn’t be a proper machinist project if something wasn’t knurled. Machinery’s Handbook (30th ed.) actually requires all parts to have something knurled. Yes, it’s true! Prove me wrong by reading the whole thing. I’ll wait.


Knurling close to the chuck is a very butt-clenching operation, because knurling wheels tend to wander around. I never like doing this, but for the good of you, fair blog readers, I take these bullets.


All we have left to do is make threaded cross holes for the set screws that hold this whole thing together. For that, I’m going over to the mill, and using one of my favorite toys: the collet block.


Collet blocks allow you to easily hold round parts very concentrically, and they can be indexed, which is very nice. In this case, it’s just an easy way to cross drill these two holes.


These set-screws are small (4-40, which is about ~2.8mm for Metric folks), so the tap is small too. Small taps means high risk of breaking them, but luckily this is just brass. A broken tap is always a sad moment, because they are so immensely hard that not much can remove them. You can’t drill them out with regular drills. Sometimes carbide drills work, if you have one the right size. In the worst cases, only Electrical Discharge Machining can save you. My $40,000 EDM machine is out for repair, so I’ll just tap carefully.


Taaapy tap tap…  Fun fact, it doesn’t matter which side you tap a hole from, so for a case like this, you can tap through both holes at once. That’s a bad idea unless you’re certain the holes are perfectly aligned, but we are certain of that, since we just drilled them.


Okay, we’re ready for some final assembly! I made the bold claim up front that this device holds the phone securely at any angle, so let’s recap how it actually does that. The answer is friction. That groove we cut in the central shaft holds some number of O-rings, which provide friction on the spinning mount. You can also tighten the setscrews as needed to set the tension. The set screws need to be in far enough to keep the knob from pulling off the shaft, but beyond that they set the amount of drag on the O-rings. You can also vary the number and thickness of the O-rings as needed for the weight they need to resist. Eventually these O-rings will wear out, but you can easily replace them by backing out the setscrews. The setscrews are not tightened all the way in, as they would lock up the shaft and crush the O-rings. Instead, they are adjusted as needed, then Loctited in place so they won’t back out. If you ever need to remove them, a little bit of heat is all that is needed to release the Loctite.


I experimented with thickness and quantity of O-rings until I found a combination that worked well for me.


Loctite is applied to the setscrews, which are then tightened in to where they are retaining the shaft inside the knob, and applying some pressure to the O-rings without crushing them.


I’ve been using this knob on my NOGA arm for quite a while now, and I can say it has been working quite well. I did need to Loctite the ¼-20 thread into the phone holder, because it would still unscrew itself over time as the phone was manipulated. A jam nut would also have worked here, but I like Loctite. It’s easy and it works. It remains to be seen how well the O-rings will hold up over time, but it’s been several months, and so far so good. While I designed this specifically for NOGA arms, you can easily change the thread on the shaft to allow you to mount a camera on anything you want. The power of this little guy is that you can thread in the camera mount without needing to rotate the other end, and it will hold the camera at any angle without any threads loosening.

That’s it for this project! Check out my YouTube channel to see lots of videos filmed with this very adapter!




]]> 2