October 13, 2026
Now for the fun stuff. The sample screens below show how the addon board displays information with the new firmware.
A brief startup splash shows the firmware version.
The main screen shows DC and AC volts and amps together.
An adjustable screensaver prevents OLED burn-in.
The main screen shows DC volts and amps on the top line and AC volts and amps on the bottom. When a fault is latched, the affected reading flashes, and a dead sensor shows SENSOR in place of the DC voltage.
A new settings interface with additional screens has been provided. Pressing the button on the main screen takes you into the settings, short presses cycle through the available actions, and holding the button for a long press activates the action.
The actions are:
[+] increase the value
[-] decrease the value
[S] save the value on the current screen and moves to the next setting
[C] cancel out of the settings, keeping everything previously saved
Screen space and memory limits called for short indicators, which is also why [S] moves to the next screen instead of there being a dedicated [N] Next button.
The original firmware had three settings screens (overcurrent, overvoltage hold and voltage trip point). There are now seven, in the following order:
DC current limit: 0.5 to 2.0 A, default 1.2 A.
Fault recovery: AUTO or HOLD, default HOLD. It applies to over-voltage and over-current; a sensor fault always clears itself.
DC volt trip: 5.1 to 5.5 V, default 5.4 V. The 5.5 V position is labelled 5.5HW, meaning "leave it to the hardware limit".
DC under volt: 4.0 to 4.9 V, default 4.6 V. This only drives the LOW V warning.
DC calibration: 100 to 800 in steps of 10, default 400, which tunes the DC current reading.
AC calibration: 10 to 50, default 20, which tunes the AC voltage reading.
Screen saver: about 1, 5 or 10 minutes, or disabled. The screen always wakes while a fault is latched.
A practical gain is the two calibrations. In the original code both were fixed constants (the INA219 calibration value of 400 in ina219.c and the AC volts scale in main.c), so correcting a reading meant editing the source and reflashing. They can now be adjusted from the screen on the board itself.
If you are upgrading from the original firmware, these are the differences you will notice. The new fault handling is described under "Start-up and fault recovery" in Part 1.
Start-up is slower to connect. Once the microcontroller is running, the output stays off until the sensor has answered. The original connected the load immediately at boot.
The default over-voltage trip is 5.4 V, down from 5.5 V, and the range is 5.1 to 5.5 V.
Settings are validated. Out-of-range or blank EEPROM values fall back to defaults, which means a blank EEPROM gives HOLD mode.
Flashing wipes the EEPROM, because the EESAVE fuse is not programmed. Note down your settings first, or back up the EEPROM (command in the building section).
5V_SAFE is not protected when the MCU is unpowered. The microcontroller runs from the AC-derived rail. With no 9 V AC present the output control pin is not being driven, so only the hardware crowbar protects the line. The same is true for a few milliseconds around a reset. This is the same as the original firmware, because it comes from the hardware.
The addon's 5 V regulator has little headroom on the AC side. U7 (an MCP1703A-5002E/DB, rated for 16 V in normal operation and 18 V absolute maximum) is fed from the rectified 9 V AC rail. With my transformer that rail measured 15 V DC at idle, so it is only about 1 V from the 16 V limit, and there is little margin if your mains runs high or your supply puts out more than mine. This comes from the original design, not from the firmware. A future rework of the board should consider changes in this area, such as a regulator with a higher input rating (which may also need a larger output capacitor).
The button shares the AC sense pin. A reading under 100 counts is treated as a press, so a very low AC reading and a press look alike.
Faults are not saved across a reset. A power cycle clears a latched fault, and the board re-checks from scratch.
There is no settings lock. Anyone at the button can change the limits.
There is no read-only view of the settings. A short press on the main screen goes straight into the editor, where the original let you step through the settings without changing them. To leave without saving, move the cursor to C and long-press.
The DC calibration steps in tens. That is about 2.5% per step at the default setting. It is a user-interface choice, not a hardware limit, because the INA219's register can be adjusted in steps of two, about 0.5%. It is good enough for a 0.1 ohm shunt, but the shunt's own tolerance will usually be larger than that.
There is no menu calibration for AC current. Its scale is the constant ACCUR_SCALE_NUM in board.h, set from one comparison with a true-RMS meter. A different sensor variant needs a different number and a rebuild.
Flash is nearly full. The build uses 99.5% of the 8 KB (45 bytes free), so adding features means trimming code elsewhere.
Occasional stray pixels. A few pixels in the top line of the display can corrupt when the C64 is switched on or off, probably from a noise burst on the display bus. The firmware redraws the labels and the blank column every cycle, so it clears within moments and does not affect protection. I did not add the optional 100 nF capacitor across the OLED's supply pins, to keep the board close to stock and the header free for programming.
The displayed DC current read about 2% low on my unit against a series meter (the 0.1 ohm shunt and the INA219 each have a tolerance), so the 1.2 A over-current limit really tripped near 1.225 A. Component tolerances mean yours may differ by a few percent.
Under load, the displayed DC voltage sits below the voltage at the input terminals by at least the drop across the 0.1 ohm shunt, about 75 mV at 0.75 A. A later test with the C64 drawing about 0.73 A matched that: 5.27 V at the input, 5.2 V on the display and 75.2 mV across the shunt. In my earlier electronic-load test the gap was larger: 0.22 V at 0.75 A and 0.33 V at 1.1 A, and the display stayed within about 0.06 V of the voltage the C64 actually receives. In that test the display and input readings were logged in separate runs, and I did not repeat it, so I can't say whether the extra drop was real or an artifact of the separate runs. The firmware over-voltage trip uses the displayed reading, so under load it trips later than the setting suggests, by at least the shunt drop: at 5.4 V and 0.75 A the input would need to be about 5.475 V, just under the hardware cut-off of about 5.5 V. If the larger shortfall from the earlier test is real, the hardware cut-off acts first.
The board drops about 0.19 V from input to output with the C64 at the BASIC prompt (about 0.73 A): 5.275 V in and 5.09 V out. In my earlier electronic-load test, with a 5.0 V input, it dropped 0.23 V at 0.75 A, 0.34 V at 1.0 A and 0.39 V at 1.1 A. The difference at similar current may be because Q2 gets more gate drive at the higher input voltage, but I have not tested that. The two tests also disagree about how the display relates to the output: in the electronic-load test the display was within 0.06 V of the output, while in the C64 test the figures (5.2 V on the display, 5.09 V at the output, not measured at the same moment) suggest it reads about 0.1 V higher. I would treat the displayed voltage as approximate under load. If the earlier figures hold, a C64 on a 5.0 V supply would already be below 4.75 V by about 1 A, so if you add power-hungry cartridges, check the voltage at the C64 and set the supply a little above 5.0 V if needed.
The AC volts reading is peak-to-peak scaled as a sine and then smoothed, so at idle it read 11.94 to 12.02 V against 11.89 V on a true-RMS meter. It is for the display only.
The logic was first exercised off-target. The protection and recovery state machine was built on a PC with stubbed hardware and driven through simulated ticks: over-current, over-voltage, sensor loss and recovery, AUTO and HOLD behavior, the retry budget, and the guarded manual recovery.
On the bench, with a real board:
The screens and every setting were stepped through.
Over-voltage trips were tested with a bench supply, and the protection paths behaved as expected with the load.
Sensor disconnect was tested: the SENSOR fault latches, the output is cut, and the fault clears on its own when the sensor comes back.
The AUTO recovery mode and its retry limits were tested.
The C64 starts first time from an overnight cold start with the addon fitted, peaking at about 0.78 A.
The CKDIV8 guard was tested deliberately: the low fuse was set to 0x52 (clock divided by 8), the firmware was reflashed with -B 10, and on power-up the board stopped with CLOCK ERROR and the output off. The fuse was then restored to 0xD2.
The brown-out detector was enabled (high fuse 0xDD) and tested with a slow 9 V AC shutdown.
The full set of tests above passed on the fork firmware. On the bench I also measured the overvoltage cut-off timing (results in Part 1), switched the C64 off at a 5.4 V trip with no latched fault, watched the display repair itself after a glitch at switch-on, and compared the AC current with a true-RMS meter. The cut-off timing figures are in Part 1. They were measured before I added the smoothing on the AC volts reading, which doesn't touch the protection code; I then repeated an over-voltage trip, an over-current trip, a settings save and a C64 power cycle on the final build.
Over-voltage trips at settings of 5.1, 5.2, 5.3 and 5.4 V landed within 0.02 V of the setting on a meter, and the 5.5HW setting tripped at 5.484 V. In AUTO mode, with a 5.1 V trip, the fault cleared once I lowered the input to 4.98 V (after the 2 second minimum latch), and in HOLD mode it stayed latched.
Over-current was tested with an electronic load: 1.1 A ran without tripping and 1.3 A tripped quickly against the 1.2 A limit. AUTO retried three times and then latched, and HOLD latched on the first trip.
I switched the C64 off and on 35 times (20 with its own power switch, 10 with the 5 V supply and 5 quick cycles with about half a second off), then left it idle for ten minutes. There were no nuisance trips and the C64 reached BASIC every time. The display peaked at about 0.75 A at switch-on and settled at about 0.7 A.
Cutting the 5 V supply showed the SENSOR fault, which cleared by itself when the 5 V returned, in both HOLD and AUTO mode.
I compared the current and voltage readings with a series meter and an electronic load from 0.1 A to 1.1 A. The displayed current read about 2% low, and under load the displayed voltage read below the input terminals (see the known limitations).
Every settings screen saved its value and kept it across a power cycle.
Soak: the release build ran overnight with the C64 sitting at the BASIC prompt. No trips, no fault messages, no display problems, and the C64 was still at BASIC at the end.
The easiest route is the Makefile in the repo. If you build by hand, note that the size flags are required: without them the firmware does not fit in the ATtiny85's 8 KB.
avr-gcc -mmcu=attiny85 -DF_CPU=8000000UL -Os -std=gnu99 -Wall -Werror -Wstrict-prototypes -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -flto -mcall-prologues -ffunction-sections -fdata-sections -I. -Ilibs/tinusaur-ssd1306xled/ssd1306xled main.c ui.c ina219.c libs/tinusaur-ssd1306xled/ssd1306xled/ssd1306xled.c libs/tinusaur-ssd1306xled/ssd1306xled/num2str.c -o main.elf "-Wl,--gc-sections" -lm
avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock main.elf main.hex
avr-size main.elf
Run it from the src folder. The quotes around the linker option are for PowerShell; on Linux or macOS they do no harm. I tested exactly this command, and it produces the sizes below.
The v1.00 build comes to 8,147 bytes of flash (99.5%, only 45 bytes free) and 88 bytes of static RAM, which leaves around 424 bytes for the stack. Check yours with avr-size.
Set these once, before you rely on the firmware:
Low fuse 0xD2: 8 MHz internal oscillator, clock not divided by 8.
High fuse 0xDD: SPI programming enabled and the 2.7 V brown-out detector on. Use 0xDF if you want brown-out off.
Extended fuse 0xFF.
Be careful with the low fuse. A wrong clock-source value (0xDD there selects an external crystal, for example) stops the chip dead and blocks normal in-circuit programming. Recovery then needs a high-voltage programmer or an external clock fed to pin 2. I know this because I did it: I wrote the wrong value to the low fuse by accident, then desoldered the ATtiny85, soldered it to an adapter, and put it in a TL866II programmer. With the chip selected in XGPro, the fuse settings are on the Config tab, and I set the low fuse back to 0xD2 from there. If the chip is accidentally left at 1 MHz (CKDIV8 programmed), the firmware's own guard stops with CLOCK ERROR instead of running at the wrong speed.
The programmer is a USBtiny, with -B 5 for the bit clock (use -B 10 if the chip is running at 1 MHz). Back up the EEPROM first, because flashing erases it:
avrdude -p attiny85 -c usbtiny -P usb -B 5 -U eeprom:r:eeprom_backup.hex:i
Then run make install, which programs the flash and the fuses, or use your usual front end.
The board's ISP header is a different pitch from the usual 0.1 inch header (the original README says 2 mm). I didn't have a header that fit, so I connected the programmer to a mix of points instead. Unplug the display first, then take GND, VCC, SCK and SDA from the OLED header (SDA is the MOSI line and SCL is SCK on the ATtiny85), and take MISO and RST from the small-pitch pads of the ISP footprint. That is only two of the six ISP points, which made it easy to fit. The board was powered by the USBtiny itself through the VCC point. I'd also suggest disconnecting the board from the C64 and leaving the 9 V AC unplugged while you do this.
The C64 Saver 2 hardware and original firmware are bwack's work, and none of this would exist without it. The repository is released under the CERN Open Hardware License v1.2, and the fork stays under the same terms. The OLED driver is the tinusaur ssd1306xled library, which is MIT licensed.
• Original project: github.com/bwack/C64-Saver-bwack
• This fork, with source, Makefile and CHANGES.md: github.com/RetroRevivalCA/C64-Saver-bwack
• Prebuilt firmware: a ready-to-flash .hex file is attached to the release on the fork, so you don't need to install a toolchain. Set the fuses described above, then flash the hex. The SHA-256 of the hex is d4c6bb63944edea1eb422d865a583754a4e85759c022c8070d1e375d7e3799cd. Download it from the v1.00 release page, or directly as main.hex.
This is hobby firmware, provided as is, with no warranty. I tested it as described under "How it was tested", and I can't speak for any other board, supply or computer. You build, flash and connect it at your own risk. If you find a problem, please open an issue on the fork.