Skip to content

Rootless Docker and home folder shenanigans

December 2, 2022

Docker is a powerful tool for managing and deploying applications, but it can sometimes be frustrating to work with. In this post, I want to share my experience with a recent issue I had with rootless Docker, and what I did to resolve it.

I was working on a project when I suddenly realized that a Dockerfile wouldn’t build on my regular desktop user account. Any command that I ran after the FROM command would just spit out “invalid argument”. I was confused, because I have multiple users on this machine running Docker and my main user was the only one with any issues.

I spent a long time comparing the output of the docker info command between different accounts. Eventually, I noticed that all the working ones were using the overlay2 filesystem, while the one that wasn’t working was using vfs. It didn’t take too long to realize that my main user is the only one with an encrypted $home directory, which meant that using it as the data directory for Docker was not possible.

To fix the issue, I created a ~/.config/docker/daemon.json file containing an entry for data-root that pointed to a directory outside of the encrypted $home. This allowed the overlay2 filesystem to be used again, and I was able to build the Dockerfile without any issues.

I’m not sure why this issue ever worked before, but it’s possible that it was because I was running Docker in a different way (e.g. without rootless mode). I searched online for solutions to this problem, but I didn’t find many helpful hints. In the end, I had to figure it out on my own.

In conclusion, working with Docker can be challenging at times, but with some perseverance and a willingness to experiment, you can overcome most issues. In my case, the solution was to use a different filesystem and to point to a non-encrypted data directory. I’m glad that I was able to figure it out, and I hope that my experience can help others who may be facing similar issues.


Did this post seem a bit out of character for me? Well, then you should go read the original Mastodon thread. This writeup comes courtesy of ChatGPT, asked to rewrite said thread into an essay.

The Atari Mega ST keyboard – finally exposed

July 26, 2021

When people talk about the Atari ST range of computers, most mean the common form factor of the times where the computer and keyboard were all one unit. This was true for most of Atari’s machines – but for a few exceptions. The Mega ST, the Mega STE and the TT went for a more “business look”, which apparently meant separation of computer and keyboard. The Mega ST computer has a fantastic “pizza box” style, while the Mega STE and TT share a common … something else.

Another difference than just the looks were the keyboards. While the regular form factor had “mushy keys” these three models were praised for the tactile feel. There were (and are even today!) after market mods you could buy where you replaced the rubber domes beneath the keys of a regular ST to get the “TT feel”.

But one keyboard stands out, even here. While there’s very little information available when searching, the Mega ST keyboard is different from all the others (besides the looks, where it again is leaps beyond the Mega STE/TT style keyboards). While the Mega STE and TT relied on higher quality rubber domes, the Mega ST made use of one of the very first mechanic switches on the market – the Cherry MX Black. This means there’s no mylar, no domes – and since Cherry has stayed compatible up until this very day you can still buy replacement switches for your 35 year old Mega ST keyboard.

I did not know this before yesterday. I only knew that I had two Mega STE keyboards and one Mega ST (they’re interchangeable – connecting with an RJ12 plug) and I really really wanted to use the Mega ST keyboard but it had severe intermittent connection issues. Pressing a key sometimes generated a key press, sometimes not. Some keys worked better than others, but mostly it was a hit’n’miss how many times you needed to press a key to get a reaction.

What’s a geek to do.

Keyboard without outer chassis

It took only a few minutes to get down to a thick black metal frame topside, and a circuit board on the other side. The key caps could just be lifted off, but even after having removed all screws from the metal frame it wouldn’t budge from the pcb. I was expecting to be able to separate them getting access to a mylar at this point, which I had intended to fill in with a specific carbon dust mylar pad refresher. After some headscratching, and too much force, I realised that these black switches were soldered to the PCB. At the same time tIn on the #atariscne IRC channel pointed me to a page my own searches hadn’t turned up – where Atarian Computing details how the Mega ST keyboard uses Cherry MX Black switches. He, like me, had heard rumors but found any actual available information lacking.

One Cherry MX Black removed from PCB

Alright. At this point I decided I could just as well dismantle everything, documenting what I did and if needed buy a new set of switches. Since I really didn’t know anything about Cherry switches, I found a good page describing the differences. Atari had used the Cherry Blacks according to spec, which means the Space bar has a slightly stiffer Dark Grey. We thus have 93+1 switches in total. I looked up where to get replacements online, and quickly found out that mostly the 3 pin color LED variant is sold today, while what the Mega ST keyboard has is the 2 pin variant. This might not be a problem, I assume I could just cut the extra leg, but that felt like a waste. I also want to point out that already from the start Cherry supported a “pass through” wire, or diode, to aid the routing of signals for the keyboard manufactures. Atari did not make use of this, but if you buy 4 pin switches you can just remove that wire/diode and you’re left with the exact 2 pin switch you want.

A row of switches desoldered from what turns out to be a very yucky keyboard
The ICs and passive components on the keyboard PCB

When you’ve spent time restoring old retro computers, you develop a keen eye for “things to fix” that might not at all be what you were looking for. Here we can see that there are two electrolytic capacitors (2.2µf 50V and 100µf 16V) on the keyboard PCB, and with a max shelf life in the tens of years, those should always be replaced. I did think to test after having done so if that made a difference to the intermittent connection issues, but no.

The ZD-915 desolder gun made quick work of the switches, and I divided what I had up in dishwasher-safe (max 40 degrees C) and non-dishwasher safe parts. The switches themselves I dismantled, blew out with compressed air, and jet-sprayed with IPA inside the connector and put it through its motions, hoping that that would clear out any possible dirt or organic residue on the metal blades.

Dishwasher full of keyboard parts and key caps.

After that all I had to do was to solder everything back up, including a patch for that one switch I forcefully pulled without desoldering first, and I was greeted by a perfectly working, “mint condition”, Mega ST keyboard. The only real mechanical keyboard Atari ever made for its 16/32 bit computers – and an absolute joy to type on.

Freshly cleaned Cherry switches mounted to the metal plate
PCB with everything soldered back together
The finished keyboard, except the outer case

Sizecoding & custom packing

July 11, 2021

Update 2021-07-14: Ben of The Overlanders commented on my Facebook post that there was yet another optimization possible on the depack-routine. I have edited the source listing below.

This weekend yet another instance of the very popular Atari ST retro computer happening Sommarhack took place. Due to Covid-19, this year as well as last have been online-only events though. I decided to participate in one of the competitions, the 256 byte intro. This is what’s called sizecoding today, the art of writing something worthy of being shown off, yet you have very little actual room available to do so. On the Atari ST, the limit of 256 bytes excludes the operating system header which is normally 32 bytes in size.

The Atari ST, being 68000 based, is of course a 16 bit computer. There are no instructions smaller than a multiple of 16 bit, 2 bytes. A lot of instructions will be 4, 6 or even 8 bytes long in a regular program. We thus know, already from the start, that our program will not consist of more than 128 low level CPU instructions.

I decided I wanted to display text, and additionally I wanted to use a custom font. In a competition like this you would normally use pre-existing primitives available from the operating system, since you would get those “for free” without using any of the space you have available. A custom font would simply look better, and since the point of the intro I wanted to make was to display an http link, looks would be everything.

The graphics artist in my old group, BlueSTar, had already made an 8×8 pixel font back in 2015 that we had used in two previous releases. It was the obvious choice to use here as well, and so I knew what I now had to work with. The link would need 30 characters, of which 21 would be unique. The normal use of a font like this is to keep it in a lookup table, and simply reference the character you want to print to the screen. However, even having shrunk the full character set down to only the 21 I needed, when I added a minimal printing routine I got way too close to the 256 byte limit. The other option would be to just store the 30 characters in a screen friendly format, which would make for a smaller print routine. Also, none of the characters I needed from the font used the 8th line, so in the end I had 30 times 7 bytes of pure graphics data.

210 bytes.

I wrote up, and optimized, the print routine, the setting of a proper palette and some interrupt to get some movement on the otherwise static content. All that came in at 58 bytes. 210+58=268. 12 bytes over the limit. There were no more optimizations available at this stage, so I needed to look into packing the data. This might sound obvious in a world of ubiquitous ZIP and RAR, but it’s not that simple. The depacker will also need to fit, so I needed to find a way to pack data while at the same time gaining more free space from that packing than the depacking code needed.

Luckily, the same reason for why line 8 was not used by any of these characters would come help me again. In the 8 by 8 pixel square available for each character, none of them used the first column – or the eighth bit of each byte. The reason for this is of course that you should be able to write these 8×8 squares to the screen and automatically get space between characters and lines for readability.

My first test consisted of using bit 8 to mean “0x00” (a byte consisting of all zeroes, no pixels set) follows, in addition to the character otherwise using the lower bits. This got me very close, but not enough. After a few iterations of this concept, I decided that it was time to do something a bit more advanced. I switched to writing a custom packer in Java, which borrowed some concepts from the very capable lz77 algorithm. There would of course not be any room for a custom dictionary, and with only 210 bytes of source data it’s not likely to find some large lengths of duplicate bytes.

I developed a packer that would search for duplicates of 2 and 3 byte blocks, in the first 64 bytes of the data. If the highest bit was set, it together with the next highest bit decided if the position pointed to by the low 6 bits should be copied as 2 or 3 bytes. It would of course prioritize three byte blocks before two byte blocks, and all in all it was able to pack the 210 bytes of source data down to 168. The depacker got to be a bit complicated though, since I needed to store the length-bits and loop on those. At this point, I was able to get the intro under the limit, but I had an awful color cycling as the only available “movement”.

Somewhat disappointed, I decided to focus on the size of the depacker. Removing the possibility of using two different lengths brought it down a lot – and also allowed me to use 7 bits for pointing back. The new packer would thus only look for duplications of 2 byte sequences, and it could use the whole first 128 bytes as dictionary. I also gave it a bit more intelligence in how it sorted the priority on what to select for packing. This gave me not only a saving on the depacker – the packer was now able to save 46 bytes in total on the data! Even more than the supposedly more capable version.

Here’s what the depacker looks like, in both 68000 assembler as well as machine code. As you can see, it’s 26 bytes in size (excluding the setup of video memory in A1 and source data in A0).

41FA 004A	lea _text(pc),a0
47D0    	lea (a0),a3
303C 00A3	move.w #_textend-_text-1,d0     ; our packed byte array length
1418    	move.b (a0)+,d2
0881 0007	bclr #7,d1
6708    	beq.s .notrep                   ; if <$80 then it's not a lookup value
12F3 1000	move.b (a3,d1.w),(a1)+
1233 1001	move.b 1(a3,d1.w),d1            ; saves a bra.s
6A08            bpl.s .notrep                   ; if positive then not a lookup value
12F3 2080       move.b $80(a3,d2.w),(a1)+       ; Offset to ignore high/negative bit
1433 2081       move.b $81(a3,d2.w),d2          ; -"- and saves a bra.s
12C2    	move.b d2,(a1)+
51C8 FFEC   	dbf	d0,.l1

The total saving is thus 210-(164+26) = 20 bytes, or 10%. Adding back the 58 bytes of other code, plus handling of a temporary depack space, ended up at 260 bytes.

Oh, wait. 260? That’s … 4 bytes too much. Now, I had already taken the time to create some better “movement” in the screen, doing split rasters from a random seed, and I really didn’t want to scale back on that again. So, the final trick used is borrowed from another code magician of the past – Gunstick of ULM. Last year he found a way to make the 32 byte operating system header 4 bytes smaller, and since the whole point of the demo scene is to cheat as much as possible without it being obvious, that’s how come the A Link Between Worlds entry by SYNC at Sommarhack 2021 came in at the expected 288 bytes executable size.

added 2021-07-14: Ben’s optimization removed 4 bytes and thus the entry would not have needed the header-hack. This is a great example of how, when sizecoding, every single trick in the book is used to shrink the code. Ben makes use of the fact that the high bit (bit 8) is also the negative bit in a byte. Instead of clearing the high bit and jumping on whether it was set or not, as my code did previously, it’s possible to jump directly on whether the previous move.b contained a negative or positive byte. Since we don’t clear the high bit, we then need to offset the following moves with 128 and 129 (same as -128 and -127) on our index. The depack code thus now stands at 22 bytes in size.

If there’s interest, I might clean up the packer and release as well. However, unless you have an extremely similar custom use case you’ll probably be better off using lz77 directly. I’ve heard rumours of such a depacker on the 68000 at just double the size of mine.

(Did I win? Of course not – in true SYNC spirit I only cared about the tech challenge. The other entries had COOL MOVING STUFF – and the winner even had sound! You really should go check them out.)

Stiga SD 98 ride-on lawnmower repair and mod

September 19, 2020

(Also includes how to seriously mess something up creating even bigger repair needs)

When we bought our property we also purchased a lot of the equipment the previous owner had acquired. An integral part of that is the lawnmower tractor – total size is close to two acres and most of that is covered with grass. It’s a Hurricane HTG 98 SD, which is a model also sold under many other brands. In Sweden the most known one would probably be Stiga SD 98, but in the UK it’s likely an MTD. It has a Briggs & Stratton 17.5HP engine and does a pretty good job, we use it also to transport things around, collect leaves and tidy up the driveway gravel.

A week ago it suddenly wouldn’t start. It’s been a bit finicky since we got it, but no matter what I tried it simply didn’t even engage the starter. This points to an electrical issue, right up my alley. Or so you would think. I have degrees in Mechanical Engineering and Software Engineering, but all the electronics stuff I blog about is all self taught.

I also looked forward to tearing it down. Like other ride-ons, it has a safety switch where the engine cuts out immediately when it doesn’t detect a driver in the seat. This is all good and well, I really understand why, but when you have a huge lawn there’s just no way you can walk around in preparation for mowing, getting rid of all small rocks, large twigs and the constantly falling pears and apples now during the autumn. I really need to be able to keep it running while quickly moving things out of the way.

Since I had a hunch that the reason it didn’t start was another one of the safety switches, I stripped it down and started to search for both where they originated, and where the mower made the decision to whether it was safe to engage the engine or not. Also, to figure out which one it was that was currently not enabling.

From experience, I knew that there were at least three safety signals that are all needed for the mower to start: Driver in the seat, gearbox in neutral and cutting blades not engaged.

I decided to work backwards. This component is found next to the starter. Red is always 12V, the starter gets GND from a place not pictured, and I figured the two white cables would go to 12V when the key was turned to ignition. They never were. However, I could clearly hear a clicking sound as the key was turned to pre-ignition, so next my attention was turned to what that could be. (This component, btw, is a rectifier. It supplies DC power from the AC power generated by the engine, used to charge the battery. I was way off on its purpose there).

This is a breakout coming from the ignition key. White is 12V when the key is turned to ignition, red and brown are powered when the key is switched to pre-ignition. My model doesn’t have front lights, but from that I learned I can add them as a future mod. In the background you can see the solenoid, which is the component that does the clicking. It’s a relay, taking 12V directly from the battery with a high capacity cable, allowing current to pass through when the purple wire is powered (black is GND).

And, indeed, the purple wire never went to VCC when the ignition key was turned. Since I had already seen that the white wire from the breakout did, I manually connected these together and verified that the starter engaged and the engine came to life. I now definitely knew that the issue was somewhere in when “white went purple”, which most likely was where the safety signals converged as well.

What do you know, that looks interesting. Beneath the steering wheel is a little black box with electronics. Opening it up, we can see some familiar colours:

Red and blue in opposite corners are VCC. The larger gauge purple (yes, they are different) goes to the solenoid, the smaller gauge purple is a combination of the gear box signal and the driver seat signal. Blue’s ignition key and grey comes from the cutting blades engager. Maybe I also mixed them up when trying to remember – sorry. The two takeaways for my purposes is that I could measure these and see that the problem was with the push button enabling the cutting blades and also that I only had a combined signal for two of the safety conditions. And there’s no way I would want to mod the tractor so that it could be started while in gear.

I removed the button, separated the connectors below, cleaned out any corrosion with electronics cleaning spray and put it back together. Now it was time to get to work on that driver’s seat safety switch I had in mind. I wanted to hide (we have kids) a little toggle switch somewhere so I could selectively have the function enabled or not. Interestingly, when searching for if someone had done this before, I only found videos from other tractors where this wire was easily spotted underneath the seat – but that isn’t the case here. It turns out, the detection is done underneath the bodywork, where the springs attach to the frame.

Alright, there’s the connector. VCC on one wire, and when the driver is seated it simply connects them together. Wiring up a switch here is easy, connect in parallell and short them together for the override function.

Uh oh.

That’s … not good. That’s the main drive belt from the engine to the gearbox. Somehow I had managed to catch this just in time before it broke completely – and with everything torn down already! I stopped thinking about the override switch and went to order a replacement belt.

*a few days later*

Ok. So, I had already changed the cutting deck belt some weeks earlier, so how hard could it be? The belt simply wraps around some pulleys and then …

… hmm. It needs to get to that top pulley. And there’s something in the way of that, so it seems I would need to move the lower pulley and that other thing out of the way first.

That ‘other thing’ is a PTO brake, I learned. When engaged it magnetically engages a brake on the drive shaft. Good stuff. I watched some more youtube videos and all I had to do was to remove the nut and it and the pulleys should slide down. Well, yeah. In the ideal world of Youtube. No matter how hard I pulled, even with careful use of a lever (so as not to bend the shaft) they were completely stuck.

This is where I would go down the wrong rabbit hole and seriously start messing things up. I blame lack of sleep, overwork, having three small kids and the phase of the moon.

It seemed possible to attack the shaft from the other end, so I opened up the engine cover and pulled the nut from the flywheel. My thinking here was that if I removed the flywheel, somehow that would aid me in just moving the shaft the centimeter or so needed to thread the drive belt around the guides. But just as the pulleys, the flywheel didn’t budge. And so I turned my attention to four screws on the side of the flywheel. Now, I’m of the mindset that most things you disassemble you can put together again, so I didn’t spend any time thinking about what they could be for – just that they might be the ones stopping my progress. One of the bolts came out easily, but the next three just immediately sheared. So I started drilling them out, which worked well for one of them but not the other.

At this point, I did notice that when I turned the flywheel, there was a noise I hadn’t heard before. Also, I started thinking about my knowledge of, and lack of knowledge of, flywheels.

I decided the stop messing with the flywheel, and instead see if there might be some youtube videos showing me how to pull pulleys. I had searched for how to replace a drive belt, of course, but none of them had this PTO brake and they all had it easy where they could just slide the belt either over the lower pulley, or their models had engine mounts that could be moved back and forth.

Some better search terminology and off to the hardware store to buy a three-armed puller. It took all of five minutes to then get the pulleys and PTO brake off. I had spent the better part of a day on this problem already, so I was filled with joy. Another five minutes and the belt was in place. Some quick connections and the battery temporarily in place and it was time to start the engine. I wasn’t too bothered with the two bolts I had removed from the flywheel, it seemed securely in place and I had also bought replacement bolts I could put back.

The starter engaged and I heard a big clonking sound and that was it. The positives: I had fixed the original problem, and I had a new drive belt. The negatives: The engine was dead.

Now I decided to freshen up my knowledge of flywheels. My teenage years as a souped-up thirteen-horsepower-moped gangsta all came back to me and I realized I had most likely loosened magnets on the inside of the flywheel, and they were now grinding down getting stuck. I had my finger on the button for a new 200 euro flywheel. Went to sleep.

The next morning I tried to use the puller to lift the flywheel, but that was a no-go. There are two threaded holes for some speciality equipment for this, but it wasn’t something I could find in my local stores and I was getting real tired of this tractor. I found some bush-fix suggestions where you levered some slight tension upwards and then whacked the shaft (protected by the nut) with the biggest hammer you have. Well, I have an enormous sledge hammer. Five whacks later, and the flywheel came off.

Positives: My restored knowledge about flywheels had lead me to the correct conclusion. Negatives: Those metal plates protecting the magnets were bent out of their original shape – and these rotate around fixed magnets at the tiniest of surface to surface gaps needing to be pretty perfect to work.

A lot of careful whacks and taps with a hammer later, and some drilling, I had managed to produce what actually looked pretty good. This picture was taken before I dremeled the bolts down to level though, but you get the idea.

I mounted everything back together and was greeted by a perfectly running engine. You should see the grin on my face. I had messed this up – badly – but managed to save it.

Alright, back to that safety switch.

This is where I decided to connect up my switch in parallel. If you inspect your SD 98 from the right side, you’ll see some wiring tubes coming from the rear to the middle. One of them has three wires: red, orange and gray. Red is VCC, orange is the seat safety and gray is the gearbox safety. That’s probably the easiest places to do this mod, not requiring any teardown of bodywork at all – but hey – I had already done it.

… and here’s how it looks, finally mounted in place. Easily reachable if you know where to look for it, and hopefully something the kids won’t figure out until they’re old enough to be trusted with it.

Oh, and the mower runs better than ever. I took the time to lubricate wherever suitable as I went along, and I cleaned out a lot of assorted junk from various places as well. I even think the motor sounds better, but that’s maybe wishful thinking.

-“Troed, you should have your own Youtube channel for all of this instead of blog posts!”

No thanks. I absolutely hate having to wade through someone waffling about when all I want is to quickly get to what the solution I searched for is. If you came here looking for how to mod the driver’s safety on a Stiga/HTG/MTD/etc – aren’t you glad you didn’t have to? :)

Hooked on hookes

August 31, 2020

Comparison image

Above you see two probes that came with my DSLogic Analyzer. You also see two EZ-Hook XKM-S probes bought from Digikey at 30 SEK each. The latter are vastly higher quality – and much easier to work with since you can place them closer together due to their thinner tips.

Highly recommended.

Converting DSLogic Basic to Plus

August 12, 2020
tags: ,

I bought a DSLogic Basic USB Logic Analyzer a few years back. It has worked perfectly fine for my use cases. Recently I’ve begun using a Ubuntu desktop more than my Macbook laptops in the workshop, and when it came to installing the DSView software I stumbled upon the weird fact that DreamSourceLab seem to consider their old products unsupported, and they cannot use any newer version than 0.99.

While figuring this out (no, it’s not spelled out anywhere I can see when downloading the software) I stumbled upon some forum threads detailing how the only difference between DSLogic Basic and DSLogic Plus is 256Mbit RAM and changed values in an EEPROM.


The RAM chip (MT48LC16M16A2P-6A) is $1.5 imported from China, or $10 from within Europe. I went with LittleDiode in the UK and had it in just a few days.


8 screws later.


Apply solder paste.


While using the hot air station to melt the paste, also remove the eeprom.


The previously modded TL866 works just fine to read out what was in my case an ST M24128.

Search and replace 0E 2A 21 00 for 0E 2A 20 00 (two places). Can be done directly in the MiniPro software. Write back the changed contents to the eeprom and put it back in.


Congratulations! You now have a DSLogic Plus.


Look at that massive capture buffer. I have absolutely no idea what I will ever need it for.

Oh, and no. The DSLogic Plus with this hardware revision isn’t supported by anything newer than v0.99 of the DSView software either – which was what I was hoping for. Oh well.

Wireless phone charger – Tesla

August 11, 2020

Love the Tesla Model 3. When I got it I thought the clever way to route a charger cable up from the front USB ports was nice, but after a while I got real tired of having to poke the phone onto the plug whenever I got in the car.

The Tesla M3 subreddit had a thread about adding Qi wireless phone charging to the front compartment, and there seemed to be no real competition to the product from TapTes. I’ve now had it installed for a few days and it really is completely seamless. Whenever I place the phone down in the car it charges, and the installation was relatively straight forward.

On my commute is a section of freeway that’s often backed up. I let Autopilot deal with that, while I go on working through the phone (of course hands-free, officer!). Topping it up whenever possible becomes a must.

Now I just need to find some way of wirelessly charging the Tesla itself.

Stock, with a third party 90 degree angled charger cable.

The new charger plate with its USB power cables fitting the stock holes down into the compartment.

Qi charger plate installed, still without the stock bottom slide cover.

I keep my car messy. It’s a vehicle, not a showroom. Anyway, this photo shows their Y-cable solution where you still have access to two front USB ports even though they also power the wireless charger. Also in this image is a Raspberry Pi Zero running the awesome teslausb sync-thingie.

I scratched my head for a while trying to use my iPhone to take a photo of my iPhone being wirelessly charged, but had to give up and use a Huawei. In reality this looks good.

PLCC 44 PROM programming with TL866

July 22, 2020
tags: ,

Even the retro world is moving away from the regular DIP packaging sometimes. The Atari Falcon, and third party ROM boards from Exxos, use the 27C4096 PROM in PLCC packaging to hold TOS (the operating system).

The TL866 with its DIP40 socket cannot obviously handle these, but a quick search shows us that there exists many adapter packages available to purchase that will sort out various types of popular socket formats. Including 44 pin PLCC.

However, the most common such adapter isn’t meant for PROMs, but for micro controllers (like the AT89C51 used for the example below). While the pin assignment is almost the same, for the critical purpose of programming the NC pins are swapped.


$ minipro -p AT27C4096@DIP40 -r test.bin
Found TL866A 03.2.86 (0x256)
Invalid Chip ID: expected 0x1E00F400, got 0xFFFFFFFF (unknown)
(use '-y' to continue anyway at your own risk)


If we want to program PROMs with this adapter, we need to perform a slight modification.


Comparing different PLCC44 pinouts


Simply, but carefully, bridge pins 12-13 and 33-34 on the PLCC adapter (not the DIP!) and off you go.


Pins bridged


$ minipro -p AT27C4096@DIP40 -w dualtos_swapped.img
Found TL866A 03.2.86 (0x256)

VPP=13.5V, VDD=6.5V, VCC=5V, Pulse=100us
Chip ID OK: 0x1E00F400
Writing Code... 77.79Sec OK
Reading Code... 5.58Sec OK
Verification OK


Happy programming.

TL866 firmware updater macOS support

September 28, 2019

I own a TL866CS IC programmer. Wonderful device – I truly recommend it (and I assume its successor is even better). It’s been known for many years that the company who made them had one hardware revision, and limited the CS revision compared to the A revision purely in firmware.

That limitation has of course been hacked for almost as long as the device has existed. Someone going by the name “radioman” detailed many years ago how the bootloader could be reflashed from CS version to A, after which the original software and firmware updates will see the device as the A model in all aspects. To get access to the in-circuit programming abilities, you additionally have to solder a header to the mainboard.

radioman’s software is open source, and exists for Linux (QT) and Windows (.NET/QT). People say it works great under parallells or VirtualBox for macOS users.

But that’s no fun, is it?

I spent the last week changing out libudev for macOS’ native IOKit library in the QT codebase. That’s the only change needed, since libusb has good macOS support. My macOS pull request has now also been accepted and merged into master by radioman.

Open source working as intended. And my TL866CS has become a TL866A.

Kokoon Relax headphones review

March 14, 2019

[this post has been updated, see additional edits being made at the bottom]

April 2018 I saw a Facebook ad for a pair of headphones that sounded like the perfect match for my needs. I’m a severe insomniac, and a frequent flier. I’ve had the same pair of Sony MDR-NC32NX in-ear noise canceling headphones for a decade, and I was looking for something new.

Yesterday they arrived. Now, this was originally a Kickstarter (and I have seen that not all backers have gotten theirs yet) but when I ordered they expected to ship them in July the same year. Delays happen.

Now, for the rest of this review. If you’re looking for the best sound quality, or the best noise cancelation, these are not the headphones for you. My circles tell me the Sony WH-1000XM3 would be what you’re looking for. If you’re however looking for an extremely slim profile with a focus on helping with relaxation and insomnia – keep reading.

After having unpacked them, and tried them on (wow – they’re heavy!) I charged them up and started to play around. Connecting them to my iPhone was no problem (they’re Bluetooth) and the Kokoon Relax app is nicely laid out for you to download calming soundscapes to have in the background. This worked well during the evening yesterday.

Later at night, I connected them to my Macbook Pro (again, wirelessly) when going to sleep. I listened to some tv-series and Youtube episodes, and then decided to try to go to sleep. No matter what audio source you’re listening to, they’re supposed to detect when you have fallen asleep and turn down the sound a few minutes after.

I’m a side sleeper, which Kokoon has this to say about:

Earbuds and bulky noise canceling headphones will make it difficult to sleep for side sleepers. By relocating the headphone electronics from the ear cups to the headband, we have been able to achieve the lowest possible profile, maintaining the natural shape and characteristics of the head in bed. Combining this with cushioning has enabled us to ensure the headphones are comfortable.

… yeah, no. I have the perfect pillows to support this (soft and deep) but there’s no way I can side sleep with these comfortably at home in my bed. That’s a bummer, because that was one of my hopes. However, I still need a pair of headphones for when I’m traveling, and I don’t always upgrade to business class so sit-sleeping is still a thing.

This morning (day of use #1) I was unable to connect the headphones to my phone when leaving in the morning. The battery had run flat, which I now realize is because while the headphones can detect that you take them off (and pause the audio) the ability to turn themselves off is still a feature in development. I then charged them at work, and tried again on the way home. I was still not able to connect – until I tried re-pairing them with the phone.

This caused me to believe that they can only be recognized by one device at a time – but this also turned out to be wrong. When back home, the audio kept disconnecting from the phone and at one point connected to the computer (where a Youtube video started playing automatically). So I had to turn off Bluetooth on the computer. But I still have had no luck this evening – the few times I’ve managed to connect the headphones to the phone I’ve had a few minutes at the most before they suddenly disconnect (and turn off – with a very unpleasant audible ‘pop’ in your ears) and I have problems connecting them back again.

I now tried to hard-reset (power+action buttons for some 10 seconds) them a second time but it seems the battery has run flat.

Conclusion after unpacking day and 1st day of use is: Wow, this is a very very unfinished product.

Day #2 to #4:

Alright, so I’ve learnt that whenever I want to switch between phone and computer use I need to press the action button for a few seconds and reconnect through the Bluetooth menu. That’s not extremely problematic, I can live with it. Besides that I’ve only had a single surprising issue where the headphones disconnected from the computer while I was watching a show. A press of the power button made them come back alive.

I’ve also made it a habit to charge them whenever possible since I believe they have issues when at near low charge, which I’m of the impression happens a lot quicker than I would’ve expected.

So what now? The only thing I’m currently using them for is as a pair of regular Bluetooth headphones. I can’t side sleep with them, the EEG stuff seems unfinished (I know the app claims I fell asleep once when I listened to music, which I decidedly did not) and the ANR (Automatic Noise Reduction) is barely noticeable and I’m even unsure if it’s active. In this case I compare to my old Sonys which were truly awesome at it, but also a lot more noticeable (“pressure” on the eardrums).

Additionally, they make my outer ears hurt after a while, which the headphones I use when playing Playstation VR or my precious “office headphones” didn’t. Not sure why this is yet.

Day #5 to #9:

Regular usage as Bluetooth headphones has worked fine these days, although that’s not really what I bought them for. Just now I’m unable to get them to work though, which I think is connected to having taken them off allowing the automatic music-pause to kick in. After that they’re “dead”. Can’t turn them on, can’t reconnect them to something else, charging doesn’t make a difference, even the hard-reset button combination seems to do nothing.

Will try charging them for many hours, followed by trying to deplete them completely, and see what happens. Since I’m not a Kickstarter customer I do have consumer protection to use if necessary.

Day #10 and #11:

Continuing from above, after they had stopped responding, charging didn’t work. The green led blinked as if they were charging, but after many hours it still hadn’t turned solid green indicating they were fully charge. I tried to see if anything had changed as to responding to any button presses, which it hadn’t, and then let battery run out flat instead.

That worked fine – the next day I could charge them and they went solid green in the expected timeframe. However, they’re still not responding to any keypresses (power on, hard reset by pressing both buttons for an extended amount of time etc) and there’s no LED activity whatsoever.

My conclusion is that they’re bricked. I will now contact Kokoon to let them know these headphones are going back and I expect a full refund. This will be fun.

April 10th

Final update: I today received the refund for the headphones, and I want to credit Kokoon for being swift about it. They initially wanted to send out a replacement but I simple wrote back that I wasn’t a Kickstarter backer but a regular customer, and the headphones didn’t match the spec I had been told when ordering them (besides being completely dead after 9 days).

I bought the Sony WH-1000XM3 instead a while back and they’re absolutely amazing.