Blondihacks Fri, 03 Jan 2020 19:17:40 +0000 en-US hourly 1 Blondihacks 32 32 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:


Veronica – Transceiver Repair

Click here to view the video on YouTube.


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
Veronica – GPU Strikes Back Sun, 14 Apr 2019 19:01:43 +0000 read more]]> Time for our girl to learn some new tricks.


If you were to ask me what questions I get asked the most in my life, the list might look something like this:

1) Who the hell are you?
2) Wait, you like computers?
3) Wait, you like machine shops?
4) Wait, you like race cars?
5) Can I hold your cat? She looks very soft.
6) How did you get in here? I’m calling the police
7) No seriously, who the hell are you?
8) Can you do more projects with Veronica?
9) Can you hold my beer?
10) For reals, who are you and how did you get in here?

As you can see, Veronica makes the top ten. If you’re new around here (and if my analytics are to be believed, a lot of you are), let’s recap.

You see, way back in 2011, when CDs were maybe(?) still a thing and Blackberries still thought maybe they could make a go of it, I decided to build a computer. Usually when I tell people I built a computer, they think I went and bought a power supply and an ATX motherboard and some silly neon lights and whatever else the kids do to play Crysis these days. Then I have to explain that, no, I mean I built a computer. You know, like Steve Wozniak. The next question is, “Who the hell is Steve Wozniak” because all of my co-workers are under 30 and Steve Jobs did a lot of rewriting of history before he donned his last black turtleneck.

Anyway, more to the point- I was inspired by Steve The Smarter to build my own computer from TTL parts the same way he had done with the Apple II. I’ve always been a software person, and while I learned enough electrical engineering to be dangerous in school, I had not done much in the realm of actual computer design. I wanted to give it a shot. You can read the whole story here, if you need a refresher.

I wanted a computer in the vein of the 1980s home computer wars. For those of you who weren’t there, it was an amazing time. There were dozens of competing brands, each with a whole line of machines, all entirely mutually incompatible (often within the same brand). The world had not picked any standards to speak of, and it was a marketplace of (mostly bad) ideas. Among all the many things I did not know that I didn’t know about computer engineering, one major thing stood out. I had always thought of computers as basically a CPU with some RAM and I/O hanging off a bus. Good old Von Neumann, right? For 1980s computers, this made them really quite simple because TTL logic is basically digital lego, clock speeds are low, and buses are narrow. It should be easy to build such a computer! What I failed to appreciate is that any given 1980s computer was not a CPU and some RAM hanging off a bus. It was a crazy mad scientist method of generating video based on the fever dream of a hardware engineer who had spent a little too much time watching The Last Starfighter, and maybe not quite enough time reading reference circuits for the parts in her drawers. Every 1980s computer was an experiment in a new way to generate graphics, and everything else (CPU, RAM, etc) was an accessory to that effort. This is crucial to understand, and it’s something that nobody in the home-brew computer world ever seems to talk about. I mean sure, if you’re happy talking to your “computer” over a serial port and having it spit ASCII back at you at 300 baud, great. Go nuts. Personally, I like actual fun. And that means pixels.

It was with that pile of lies in my head that I plunged into a 5 year odyssey of attempting to build a GPU of my own design. Because I don’t know what I’m doing, it was largely implemented in software on an ATMega microcontroller, and could spit out passable VGA video while talking to a 6502 over an 8 bit bus. I succeeded in this dream, but juuuuust barely. While I achieved my stated goal of building a computer that you can sit down in front of and program itself with itself, the video always nagged at me. Don’t get me wrong- reverse engineering the VGA standard and bit-banging it out of a 20MHz microcontroller with 10MHz of I/O bandwidth using little more than a logic probe and a complete lack of good decision making skills is one of the finest things I’ve ever done. However, at the end of the day, it wasn’t a good way to do video. Yes, it renders text and a couple of sprites and even plays a decent game of pong, but the implementation was so clunky that I knew it was never going to achieve much more than that.

I had started down this road of designing my own GPU because I couldn’t find one suitable. There are vintage graphics chips still available, but all either output composite video (too old and limiting) or didn’t have video output at all. Often they would output something like 15KHz linearly clocked pixel data, and you were expected to build a video generator to hang off the back of it that generates all the analog waveforms needed to speak to a monitor. This approach made perfect sense when these chips were new, because there were few video standards to speak of back then. Most computers did some form of composite, but as the Apple II demonstrated, it’s possible to be officially “composite”, yet not display properly on most monitors. Other machines like the Apple IIgs technically have composite, but it looks like garbage. The machines renowned for their graphics (Amiga, Atari ST, Apple IIgs, etc) made up their own video standards because existing ones were crap. Many (again like the IIgs) used variations of arcade video, which had its own unofficial-but-defacto way of getting pixels onto a tube. The point of all this is that, as a video chip designer, it made perfect to stop short of generating actual video, because nobody in the 1980s agreed on what video signals we should have. We haven’t even talked about interlacing, resolutions, overscan, color depths, bit planes, VRAM layouts, etc. Those are all entirely other cans of worms that nobody agreed on. You think modern PC video is a wild west of different variations? Oh, honey.

Let’s get back on track here. Well, some time after I finished my own video solution, I stumbled across the thing I had always wanted for Veronica- a real, honest-to-goodness graphics processor that can talk to an 8-bit CPU, spits out VGA, and can be bought new today. It’s called the F18A, and it’s the brainchild of Matthew Hagerty.

As of this writing, the F18A is no longer available for purchase, but Matthew is working on a Mark 2 that supports HDMI(!). I bought mine many years ago when they were still available, because I’ve learned from the retro computing hobby to always buy cool things when people sell them. Projects like this are always labors of love, and when they stop being available (because the creator wants their life back) they will be gone forever. I bought the F18A while I could, and it has been sitting in my junk pile waiting for its time to shine. That time is now, and I want to use it to give Veronica all new video. Let’s do this.

The first step was to get Veronica back on the bench where she belongs. She has been serving as decoration in my living room for several years, and I had no idea if she would still power up.


Well well… look who it is.


I figured a visual inspection was in order, before applying power.


All the PCBs are right where I left them, and no mice have moved in. All good news. The glue failed on the foam that secures the PCBs to the hold-down bar.


Everything looked good inside. I pulled the board set out and looked everything over. I was quite expecting to see some corrosion, because the copper boards that I etched myself are all unprotected. There’s no sealing coat on them at all, and bare copper will corrode eventually. I still have all the gerber files and photo masks used to make these boards, so I can easily replace them if needed, but it’s nice to see they are still in new condition after eight years.


The boards are like new! I was really at the top of my PCB game when I made some of these boards. Those traces are sweet like candy.


I also checked the alignment of each board with its respective socket in the backplane. I’ve learned in previous adventures that some of my boards have slight size issues with the edge connector. This is due to small scaling errors that crept into some of my photo-etch masks that I printed on FedEx Office printers. Those printers all have a small scale factor to them (generally 1-5%) and you have to compensate for that. I’ve never figured out why those printers scale slightly, but it has been suggested that this is to defeat counterfeiting. That answer sounds a little too “neato” to be true. More likely it’s just that reproducing scale perfectly from software to file format to hardcopy is difficult and most printers don’t do it perfectly. Who knows. I can say that the printer in my office (an HP Lasersomethingsomething) does an amazing job on my mechanical drawings produced from Fusion 360. Those come out 1:1 with a precision that is within the thickness of the lines. In conclusion, printing is hard.

Everything checked out in my inspection, so there was nothing to do but turn it on!


Well, would you look at that. She booted right up, went through the RAM check sequence, and landed at the monitor. Just like the day I put her away.


The screen image is quite dim, and this is another problem Veronica has always had. The VGA signals produced are ostensibly within spec (as far as I can tell), but the image is dim. It certainly doesn’t help that this monitor is a piece of gou shi that I bought at a swap meet. It has many issues all its own. One of the many mistakes I made in Veronica’s video system was dialing in the timing precisely to suit this display. I naïvely assumed all VGA monitors should be broadly compatible, so if the image is good here, it will be good anywhere. It turns out this particular monitor has freakishly smaller overscan than average, and on most other VGA monitors I have tried, the left edge of Veronica’s video gets cut off. Fixing this horizontal alignment requires realigning the horizontal timing pulses relative to the vertical blank. If you followed along with the original development of Veronica’s video, then you know that fixing this would be obscenely difficult. Many many hours were spend counting clock cycles in every code path through the huge block of assembly language that is bit-banging the VGA (while also rendering fonts, sprites, etc). Any change requires recalculating a new set of codepaths that all line up with the desired new timing. It’s extremely nontrivial, I was lucky to get it working at all, and thus I live with the quirks.


A quick test of some ROM monitor commands (this one dumps contents of RAM) shows things are working well.


The screen dimness and alignment issues are two more reasons that I’m excited to try the F18A. I was in over my head with that video generation project, and while I did get it done, and could do it better next time, I’m frankly glad to have someone like Matthew come in and pinch-hit the next inning on this one. That’s all the sportsball metaphors I know, so I hope it was good for you.

Okay, let’s get to the object of my affection- the F18A itself. What is this thing?


It’s this.


The F18A is basically an FPGA re-implementation of the TMS9918A Video Display Controller, which was used in the TI-99/4A computer (c.1981) to generate graphics, text, and video. The 9918A VDC was later adopted as the standard for the MSX-compatible computers popular in Japan in the 1980s and 1990s. It can also be found in the ColecoVision, some arcade machines, and various other obscure 1980s home computers. The TMS9918A was such a great chip that it spawned a line of video generators, including the super amazing Yamaha V9938, which was the basis for the MSX2 platform. I’ll get angry comments for this, but the 9918A is roughly comparable to the Nintendo Entertainment Systems’ PPU graphics chip, while the V9938 is a decent analog to the Super Nintendo. I say that not to get into a specs argument about palette counts or sprite layers, but to give you a sense of the level of graphics technology that we’re talking about here- we’re talking 2D tile maps and sprites in the 8- and 16-bit fidelity range. This was hardware accelerated video in the 1980s, and it was great. It’s funny that we think of hardware accelerated graphics as an invention of the late 1990s (lookin’ at you, Voodoo), but what really happened is that (as with most things) PCs just took a really long time to join the party. That sound you just heard was three hundred Amiga users flipping their tables in disgust. That happened a lot in the 1990s, too.

Okay, I got off track again there, but back to the point. The F18A is a modern reimplementation of the 9918A, as I said. It is literally a drop-in replacement for that chip for any computer or arcade machine that used it. More than that, Matthew has actually improved the design in several key ways. The most obvious is that the board outputs VGA directly. The original chip primarily gave you digital RGB pixel data, and you were on your own to hang a video generator off the back of that. It did also output NTSC (and later PAL) composite video in the first version, but subsequent chips in the line dropped that. The other cool thing about the F18A is that it has its own VRAM onboard. This allows it to implement new video modes that the original 9918A didn’t have. The original TI-99/4A had 16k of dedicated VRAM (called VDP RAM), which limits how much more you can do. For our purposes, this built-in VRAM is amazing because it makes the board a completely self-contained graphics solution for home-brew computers. It’s so well self-contained that it only implements a handful of the original 40 pins on the 9981A. All it really needs is power and an 8-bit bus to the CPU. Matthew has also documented it extensively, and it’s quite easy to use (as graphics chips go). I was going to also say here that, being a modern implementation, a big advantage is that you can actually get it. The classic chips like the 9918A and V9938 do show up on eBay occasionally, but they are pretty unobtainium. Even if you get one, you still have to implement the video generator yourself, unless you use the older chips that output composite video straight from the chip and you have some way to display that. Video generators right are no picnic to get right (see: five years of my life I’ll never get back). All of this makes the F18A even better. Well, except that you actually can’t get them right now. He’s not currently selling any more of them, and while the Mark 2 (with HDMI!) is apparently still in development, there haven’t been any updates in several months. I don’t fault Matthew at all for the delays. A project like this is a very time consuming hobby, and we all have real lives to attend to. If the Mark 2 sees the light of day, it’ll happen when it happens, and buy it while you can.

Okay, back to my F18A, which I am super grateful to own. I have literally never tried to power it up or do anything with it. It was sitting on my junk pile in its original packaging for several years. I gave it a visual once-over to see how things look. Unfortunately, the news was not all good.


A close look under the macro lens revealed a potential problem. Do you see it?


Let’s zoom-and-enhance on that…


Rut roh. We have a full-on solder bridge between these three pins on the FPGA.


At this point I had a dilemma. Do I risk powering it up and frying something? Do I try to fix it? This is a VQ100 package with pins on a 0.5mm pitch. This is smaller stuff than I have ever soldered. After some thinking, I started by emailing Matthew to see if this would be a problem. Perhaps these pins are unused or are all grounds or something. There are traces on two of them, so they appeared to be in use, but you never know. Things happen in PCB layout. I didn’t get a reply from him (no worries, we’re all busy- I get it) so I took a shot at repairing it.

I started by verifying that there is an actual short here. Sure, it’s obvious in the macro photos, but my 40-something year-old eyes weren’t so sure.


Using fine wires as probes, I confirmed with the meter that these pins are definitely shorted.


From my previous adventures in hand soldering fine-pitch SMT stuff, I learned that you can usually just swipe over pins with the iron and the solder will glob up in the right places. It wants to be on the pins, and bridges like this are not a stable configuration for molten solder. Unfortunately, I didn’t have any luck this time. I don’t have a fine-pointed tip for my iron, so I was counting on heating the pins being enough to move the solder. It remained stubbornly in place, largely because the clunky chisel tip on my iron couldn’t get the heat to the right spot. I ordered some fine-point soldering tips, and in the meantime considered other options.

I took a couple of swipes at the solder bridges with a dental pick, hoping they were fragile. They were not, and the shorts remained. I didn’t want to get too aggressive with any of these repair measures, because remember that I don’t actually know if anything is wrong. I’m assuming these bridges are a problem, but I may in fact be “fixing” something that isn’t broken and making a mess.

As a final act of desperation, I grabbed the data sheet for this chip on the off chance the pins in question are unused, or all grounds or similar good news. The chip is a Xilinx Spartan 3E FPGA, specifically the S250 variant which has 250k gates and comes in the hobbyist-friendly VQ100 package. You might question how hobbyist friendly a 0.5mm pitch, 100-pin SMT package is, but considering the alternative is a 242-pin ball grid array, well, that VQ100 starts to look pretty damned good.


Here’s the relevant section of the data sheet. Our bridged pins are in the lower right. They are GPIO, and also programming pins. It’s unclear if shorting them is a problem or not.


The solder tips got delayed in shipping, so well, in the words of the great Adama, “Sometimes you gotta roll the hard six”. It was time to apply power and watch the show. Now, this isn’t totally reckless, for a few reasons. First, my power supply has an ammeter on it, so if there’s a bad short, I’ll see it in short order. Second, never underestimate the power of the finger test. If you suspect shorts, put your fingers on everything. Anything shorting will be hot, I guarantee it. The laws of physics are simple here- excess current must be dissipated, and that happens via heat. You might think that the components will destruct too quickly for the problem to be detected with such primitive measures, and sometimes that’s true. However, most of the time, the truth is these parts are tougher than people give them credit for. I’ve seen old TTL chips sit in a dead short for 20 seconds or so, and they were still fine when I finally noticed and corrected the problem. Modern chips are tougher still and tend to have safeguards in them for ham-fisted stunts like this. I’m not saying this is the best idea, but I am saying it is not the worst idea.

Power? Go, flight.

I applied ground and +5V, and held fingers on all the parts known to contain magic smoke. I kept a close eye on that ammeter as well.


Well, no smoke, and the chip drew a steady 140mA, which seems entirely reasonable. Anything over about 250mA would have felt like a problem for a device of this size and use-case, but at 140 I feel good there’s no dead short here.


No smoke and reasonable current draw! This is good news! Perhaps those IO pins are not in use, or perhaps they were only used for programming the device, and shorts don’t matter for normal use. It’s possible some internal function of the device isn’t working because of the shorts, but hey, those fine-point solder tips will get here someday.

Okay, time to take this to the next level. I don’t have the device hooked up to a computer, of course, but I reasoned that it might be designed to show something on the screen, even when dead-headed. Only one way to find out!


The device came with this ribbon cable that ends in a VGA plug.


I needed to figure out what the minimal configuration of inputs might be to make it do something. Remember that this device is a drop-in replacement for the TMS9918A, so that‘s the datasheet I have to go next! Luckily, Texas Instruments produced a very nice technical manual for this chip, of which good scans are pretty easy to find online. What’s interesting about the F18A is that it only implements a small fraction of the pins on the original chip. Basically just power, a couple of control signals, and the CPU data bus. This is because, as I mentioned earlier, it doesn’t use the TI-99’s outboard VRAM the way the 9918A did, and the device is not memory-mapped the way a 6502-targeted accessory would be. This all means it has surprisingly few pins. It does have a reset pin which is active low, so I tied that high.

I powered up the device with my monitor connected and got a black screen. However, the monitor did sync, so a VGA video signal was present. Could it be as simple as supplying a proper reset pulse? I briefly grounded the reset line, and…


WOW! Look at that!


Result! It’s producing amazing looking video with nothing but power and ground. Everything is green, but I’m not sure if that’s a bug or just how the splash screen is. All I need to do now is figure out how to interface Veronica to it, and write all the software. Wait… that’s not going to be easy… well, I’ve never been known for doing things that are easy, I guess. Why start now? Stay tuned, Veronica fans. Things are about to get nuts.





]]> 20
Johnny – More Button Repairs Sat, 30 Mar 2019 17:07:36 +0000 read more]]> Pinball machines have a lot of switches, and they fail a lot.


What’s this? Another Johnny repair article so soon? Well, like many complex electro/mechanical systems (cars, robots, robot pets, robot cars, pet robots, etc), pinball machines pout occasionally. It’s often triggered by extended neglect, as many things are slowly degrading all at once. However, sometimes problems are also triggered by, well… me. Allow me to explain.

While enjoying several celebratory games following the previous Johnny repair, it became apparent that the left rear flipper button was not functioning. If you’re not familiar with Williams Johnny Mnemonic (and why would you be familiar with a 1993 pinball machine about a terrible movie based on an okay short story by a brilliant author who created the genre of Cyberpunk), there are four flipper buttons, but only two flippers. The rear two flipper buttons are there to control the infamous cyberglove toy. This is a prop from the movie that is part of the interface to one’s cyberdeck, which is used to interface to The Matrix. Yes, in the 1980s, we were pretty sure the internet was going to be all VR and haptic controls. Web browsers would be deeply disappointing to teenage me, I can tell you. Anyway, the glove toy catches and holds the ball when you do certain things in the game. You then gain control of the arm (which is, to be fair, a goddam robot because pinball machines amazing) and can carry the ball across the play field to “The Matrix”. The Matrix (so-named long before a certain Canadian surfer chap donned a leather trench coat) is a grid of nine slots that can hold a ball. There are various complicated strategic reasons for choosing where to drop the ball, but the point is that the glove moves in four directions, hence the four flipper buttons.

Back to my main point- it became clear during play that we could not move the glove backwards, which means the right rear flipper button seemed to be dead. I had some time, so I tore into the problem.

Learning from previous mistakes, I started immediately with the switch diagnostic menu. Sure enough, it confirmed there was no response being received by the CPU from the problematic flipper button.


Amazingly, I may have finally found a camera angle from which it’s possible to take a decent photo of the Vacuum Fluorescent Display in a pinball machine. The screen is pretty much unreadable in every other photo I’ve taken of it, and you can probably see horrible things in the reflections. I mean, assuming I do horrible things behind the camera in my photos. But I definitely don’t. Nothing abnormal here. Hey fellow humans, how about that local sporting team!


For comparison, this is what happens when the right rear flipper button is pushed. The screen shows us that it recognizes that button, and where it is in the diode-controlled switch matrix. It also shows you the wire colors on each switch, because Williams was amazing. Not only are these machines built to be serviced, but they’re built to give you a decent shot at fixing it without any documentation handy.


At this point there was nothing left to do but crack open the machine once again and start poking around. Thankfully, I remembered to remove the balls this time.

An interesting thing about the rear flipper buttons on this machine is that they are leaf switches. That’s unusual on a machine from this period, when they had mostly gone entirely to microswitches. Purists say that leaf switches have a better feel, especially for flipper buttons, so you might say that’s the reason. However, the actual flipper buttons on this machine are two-stage optical sensors as part of the Williams Fliptronic II semi-analog flipper system. So why bother putting leaf switches on fake flipper buttons that are only used to control the glove? Your guess is as good as mine. I guess it does make them feel the same as the other flipper buttons, since the opticals don’t have the “clickiness” of a microswitch. Maybe I just answered my own question. Perhaps my guess was better than yours after all.

Anyway, back to the problem at hand. Leaf switches are exposed to the air, so they do tend to get dirty a lot. That could explain our malfunction here, so the first thing to try is cleaning it.


The oft-recommended way to clean these is with a business card. Light pressure on the contacts will buff them right up. Don’t use something like a file or emery paper, because you’ll remove the plating from the contacts, which is needed for best conductivity.


Plenty of crud did come off these contacts, so maybe it’s fixed?


It wasn’t fixed. Time to start looking at wiring. Expecting another marathon adventure, I got out the schematics, harness routing charts, multimet…. oh. Crap.




Indeed, following the harness back a bit, we immediately find that a wire has been ripped out of the connector. Unfortunately, I would later realize this was my fault. When I did the Start Button repair previously, I forgot to do one thing at the very end- put all the harnesses back in their retaining clips. I remembered this after the fact, and thought, “oh well, it’ll be fine. I’ll tidy up next time I’m back in there”. It turns out those clips aren’t just for tidiness. They keep some of the harnesses (like, say, the flipper buttons) clear of the runners on the underside of the playfield. When I closed the machine after that job, I probably snagged the harness and ripped it out. You don’t use those rear flipper buttons all that often, so it took a while to notice.


Here we can see the crimp on the Molex pin inside just couldn’t hold on. It tried so hard!


Now I had some choices to make. I am set up for re-pinning most types of pinball connectors, but not this kind (wouldn’t you know). I could order the connectors, the pins, and the (no doubt stupidly expensive) tool to make this type of connector, or I could do something else. I opted to do something else.

A person could simply cut that connector out and solder the wires back together, but that person would be a horrible monster that I would not have a beer with. That connector is there for a reason, and eliminating them always comes back to bite you later when you try to remove some unrelated component and that harness is in the way. You’ll find out the hard way why some 1995 grunge-rock-listening engineer put it there. No, we won’t eliminate the connector. Instead, we’ll make a substitute connector of sorts.


I cut out the connector with sufficient length on the wires that I _could_ reuse this someday. You never know. It goes on the junk pile, where Future Me will thank Current Me. Or estate-cleaning Kids Of Me will curse Current Me. One of those will happen.


Since it’s only two wires, I’m going to replace the connector with spades. The ideal thing would be those insulated spades as are often used in cars. I don’t have any of those on hand, but we can make them. Allow me to demonstrate.


Sprocket is pointing out that I could have just tested the leaf switch with the meter instead of cleaning it pointlessly. Never jump to a proposed solution until you have conclusively identified the problem! I should listen to her more.


Here are the connectors I’m going to use, along with the proper ratcheting crimping tool. For the love of Grace Hopper, do NOT use those plier-like things you get at the auto parts store. They will never give you a proper crimp. All they will give you is sore hands and connectors that are either too loose, or damaged from your desperate attempt to keep them from being too loose.


Properly crimped from the two-stage die on the tool. The upper crimp makes the connection to the wire, and the lower one grabs the insulation for strain relief.


Note the trick I used there- the wires are staggered in length. This is an old racer’s trick to help prevent shorts. Should the wrapping on the connector ever fail, this is still unlikely to short, because the two connectors aren’t aligned. It also makes harnesses smaller because you don’t have a big “ball” where all the connectors are. Now to insulate those connectors!

In a pinch, you can make insulated spade connectors with heat shrink tubing. The trick is get the length just right.


The heat shrink on the male end should cover the lower third of the spade, as shown. On the female end, it should cover the end.


With the heat shrink applied as shown in that photo, the rubber will push itself out of the way as you join the connectors, forming quite a decent seal. It’s not water tight, but it certainly won’t short on anything, and can still be separated at any time (unlike if you had heatshrinked the entire connection at once).


The connector is fully seated, and the heat shrink has squished itself into a good seal in the mating area.


Okay, with our field-expedient connector complete, how did we do?


Huzzah! Flipper action restored.


That’s all well and good, but one more thing was nagging me. While playing, I started getting brief flashes of the Interlock warning. It means the computer is losing the connection to the coin door interlock, and thinks the door is open. In response, it shuts off the high voltage circuits, such as the solenoids. However, the door isn’t actually open, and the problem is quite intermittent. This happened once before, but the problem at that time was the corroded connector on the CPU board (same as the Start Button problem last time). I felt pretty good that the CPU connector wasn’t the problem this time, because I had just cleaned it quite thoroughly. Seems like something else is afoot here. Maybe this time it really is the switch?


It’s not pleasant to see this warning flash during gameplay! Tell me Johnny, why do you think your door is open, when it is not?!


The coin door has two interlock switches on it. The lower one is the “main” one that the CPU is watching for.


I did check this switch using the diagnostic menu, and it seems okay. The problem is intermittent, which suggests corrosion somewhere. Let’s get a look at that switch.


This is the switch. It’s a low-current logic-level switch, despite the impressive 125VAC rating.


The Shop Supervisor and Chief Engineer says this switch seems okay, but we’d better take a closer look.


The contacts on the switch are plenty corroded, so this could be our problem. I wasn’t able to reproduce the issue with the multimeter, but intermittent switch problems can be hard to diagnose this way. If your first instinct was to take that switch apart and see how it works, well, you’ve come to the right blog. Welcome to your people.


These big Cherry switches are great because you can actually service them! They separate easily with these little clips.


Here’s a look at the mechanism. The button nudges that brass lever sideways, which causes it to over-center and throw the moving contact upwards, closing the circuit. The over-centering is what gives it that great “click”.


Here are all the contacts, and they are a mixed bag. Some look okay, some are definitely corroded.


I cleaned up all the contacts with some scotchbrite and alcohol. Contrary to my usual advice of not invoking solutions until you’re sure of the problem, in this case the problem won’t reproduce on the bench, so I don’t have much choice. I’m also lazy and this blog post is already getting too long.


Things really do look a lot better after cleaning. There was more corrosion in there than it first appeared.


Since I had the alcohol out, I cleaned the outside as well. This might make me insane. But look how nice it looks!


Well, I’m pleased to say that after reassembly, the problem seemed to go away! It did seem to be corrosion somewhere in that system of connectors and contacts. Cleaning the insides of the switch was probably unnecessary, but it was fun.


After its successful surgery, our healthy switch snaps back into this bracket. Now… about that switch above it…


There was just one more thing. The last time I had this area apart, I remarked on that other interlock switch that sits above this one. Once again, I wondered what the heck that is. It isn’t mentioned on any schematics, parts lists, or assembly diagrams in the manual. Yet it has four Very Important™ looking connections on it. What is this switch doing? I needed to know. I checked the switch diagnostic menu, and this switch doesn’t register. So it’s a standalone, not plumbed through the CPU. Time to trace some wires.


Our mystery second interlock has four connections on it, and the four wires form a harness. Presumably it goes to the coin door interface board, like everything else in this area.




Oh ho ho! No, it bypasses the interface door and heads back into the bowels of the machine. Interestingly, the four wires in the harness are duplicate colors. That’s very unusual.


The harness disappears inside one of the conduits that runs up into the backbox.


Here’s our culprit on the other side of the conduit. It winds its way over to the right side of the backbox…


…and lands here. Connector J102 on the Power Driver Board. To the schematics!


While the service manual makes NO mention of this switch anywhere, it does show connector J102.


Okay, now we’re getting somewhere. Apparently there is 16VAC coming from a secondary tap on the main transformer.


One of the interesting things about this era of pinball machines is that they use a lot of weird power. The newest pinball machines from the likes of Stern and Jersey Jack are actually simpler in this regard, because they use low-power DC LEDs, low power LCD displays, and digital logic for everything except coils. These older machines have 5VDC for TTL logic, 70VDC for coils, three separate high AC voltages for the vacuum fluorescent display, 4VAC for incandescent bulbs, and so on. What I don’t know is what it uses 16VAC for. That’s a bit of a mystery, but for some reason they felt the need to interlock it. Perhaps late in development of the machine someone decided 16VAC was enough to hurt someone, so it ought to be interlocked. The manuals were already being printed, so it was too late to document it? In any case, it appears 16VAC comes from a secondary tap on the transformer, runs up to the Power Driver Board, then runs all the way out to the coin door and back to be interlocked before use by the board. Maybe someday I’ll know the “why” on this one, but I don’t have full schematics for the Williams WPC-S Power Driver Board handy. Figuring that out will have to be a project for another day.


]]> 9