Technics KN5000 homebrew development

Roughly 25 years ago my parents bought me a Technics KN5000 music keyboard. It was considered “top of line” professional equipment by then (in Brazil at least, back in 1996). Technics only made a few more keyboard models after this one, the KN6000 and the KN7000 (and I think I heard of a KN6500 but I am not sure) and then discontinued their music keyboards product line.

Ten years later (roughly 15 years ago) I started getting interested in writing custom homebrew software to run on this device. But even though I was already doing some software reverse engineering on MS-DOS games like Pinball Fantasies, I still felt that I did not have enough skills to tackle the challenge of deciphering the KN5000 secrets.

Many times during these past decades I have revisited this challenge. These past couple weeks though, and specially yesterday, I was able to reach a major milestone!

I have finally been able to understand the data format of the firmware update floppy disk image for the kn5000. And based on that discovery I wrote a python script that decompresses the data, which I hosted here:

In retrospect, the compression scheme is not that much complicated. But it took me a while to figure it out. And I feel great that now I can decompress the data!

By using binxelview I was able then to spot many graphics assets on the decompressed firmware data.

Here’s the “Technics” logo from the boot splash screen:


Here are some accordion icons used on the user interface:

And the drawbars for volume adjustments on the many “pipes” of hammond-like organs:


I have a sketch of a skeleton MAME driver for this kn5000 music keyboard, but it is way far from working state.

Please let me know if any of you would be interested in talking about this device. I would love to share more insights.

I’ve got 3 of these keyboards, by the way. Two of them working nicely, the third one is broken, but I may someday spend a couple hundred bucks buying a new motherboard for it…

Oh! and I forgot to mention that the firmware update is performed by loading a “system” floppy disk, which is the thing I’m unpacking to extract the firmware.

A friend (Ricardo Bittencourt, a.k.a. RicBit) told me it would be “something similar to LZ77, LZ78 or LZW” but I was unfamiliar with these algorithms. So I read a bit about them and then continued investigating. In the end, the actual algorithm is (in my opinion) sort of custom, but uses some of those concepts

I may be wrong, though. I am really not used to working with data compression so this is very very new to me.

A friend on the MAMEDev community told me tonight:
“That compression looks like lzss, if you want to put a name to it. It’s very commonly used in Japan at least”

NEXT STEPS:

I want to load the decompressed data into my MAME driver so that I can start looking at some disassembly on the interactive debugger and then grasp some more details of the hardware (such as the undocumented protocol for configuring the video controller chip for that very cool 320x240x8bpp LCD display).

The service manual describes the program ROM as a couple of flashroms totaling 2Mbytes interlaced as even/odd ROMs and a 16-bit data bus.

The packed firmware update file is 1.1MByte. After being decompressed, it results in 2.2MBytes, which is more than the 2MBytes for the program ROMs.

There are some headers, but not enough to spend all those extra ~200k bytes. My current challenge is to understand which portion of that decompressed data is indeed meant to be stored in the program ROMs.

(and also what’s the meaning of the rest of the data in that file)

1 Curtida

I found an LZSS implementation on the PyPI repository and replaced most of my python code by a simple invocation of this module’s decompression method. I also used it to make a compressor for the raw data.

The only thing that remained from my original code was the handling of those 11 bytes in the reader. All the rest is simply delegated to the library.

I also wrote a BinxelEdit class (the name is obviously referencing the BinxelView program) that can load an image such as a PNG file and save it to a binary file using the pixel encoding defined by the same parameters one can see on BinxelEdit. That way, it becomes much simpler to find graphics assets and then write patches.

On a kn5000_patch.py script I now perform loading of the original file, decompression of its contents, then a patching step where I replace a few graphics elements such as the “Technics” logo on the boot splash screen, and then a final step in which the data is re-compressed.

The resulting file is loaded to a floppy and installed on the keyboards.

As you can see here, it works :smiley: :

Lots of things happened but I did not yet report them here. I’ll do so later. But for now I’d like to mention that a port of GNU binutils for the TLCS900 architecture is being developed here:

And also the MAME driver for kn5000 is being developed here: