Keeping Contiki 1.x alive

Posted by pulkomandy on Sun May 7 20:30:24 2023  •  Comments (0)  • 

Contiki is a small operating system originally developed by Adam Dunkels. Version 1.x became famous on the internets after he ported it to the Commodore 64. The system came with a small GUI and ran reasonably well. It is written in C and uses a few nice tricks to run efficiently on low memory systems.

Contiki became "big and professional", well, mostly profesionnal, and in version 2.x, the GUI was mostly removed and the fun 8 and 16 bit machine ports all abandoned. Now it is useful for actual projects, running on small sensor boards and the like.

The best place to find info about the old Contiki version is the Hitmen demogroup page. I was a bit annoyed about the Amstrad CPC port description there: "runs slowly, does not look nice, and could probably be improved. But still worth a look". Certainly the CPC deserves better. And so I started hacking. That was in 2014.

The CPC port was initially developped by Kevin Thacker, who got it running, and kind of stopped there. It was indeed very slow, but the main cause was the implementation of the "clear rectangle" function as a loop putting space characters all over the display. But I went on and changed quite a few things to get it to look better, be faster, and saved several kilobytes of RAM (partially thanks to improvements in SDCC, and partially through rewriting more of the UI code with small assembler parts, adding missing "const" in various places, etc).

I also simplified the build quite a bit, in particular I had to rework the generation of symbol definition files that are used to link the loadable PRG files to the Contiki kernel. On the CPC port, these files are generated from the SDCC generated mapping files, now using some SED scripts to convert them to the appropriate format. I also made several adjustments to use newer SDCC versions over the years.

Later on, I also ported Contiki to the Bitbox console as well as the VTech V.Smile. The V.Smile port is still unfinished and waiting for the development of a proper toolchain for its unusual CPU, more on that later in another article.

Anyway, this brings us to today where I finally decided to update the port to use the latest version of SDCC. The SDCC compiler changed their calling convention in version 4.2 and finally added a way to pass parameters to functions using CPU registers. Before that, they were pushing parameters to the stack, and making that more complicated by insisting on pusing only 1 byte, when there are no instructions on the z80 to do so (PUSH and POP always work on 16 bit register pairs).

This, of course, requires all functions written in assemby to be updated. But before I got to that, I had to fix a patch to SDCC. One specificity of Contiki is its ability to load programs at arbitrary addresses in RAM to execute them. On a modern machine, this would be handled either by using the MMU to provide a fixed memory layout to the program, or by compiling the code as "position independent". But none of these are available on the Z80 CPU (well, you could, with a lot of custom hardware, but not on an Amstrad CPC at least). So, Contiki has to "relocate" executable, that means, after loading them into RAM, patch every address referenced in the code to adjust it for where the program was loaded. Fortunately there is some support for this in SDCC and Kevin provided a patch to generate a relocation table that lists the places that need to be patched in the final binary of each program.

I have kept this patch up to date with the current version of SDCC over the years, and version 4.2 needed a new change. It internally represents addresses as 24 bit instead of 16, I guess to allow support for banking. This resulted in corruption in the generated .hex files, and a bit of confusion until I managed to convince SDCC buildsystem to generate binaries with debug info for the linker, so I could look at what it was doing. It took a bit more guessing due to Haiku debugger not showing the value for global variables yet, but eventually I figured it out.

The next step was fixing a segmentation fault in the compiler. Fortunately, I could locate an existing bugreport with a fix, and apply the changes to my version of SDCC to avoid the problem.

And finally I could get to the part where I have to adjust all the assembler code to the new convention. Several of the functions could be simplified or even removed completely (when the calling convention matches that of the CPC firmware, it's possible to call directly into the firmware).

Converting the functions was not too hard, despite me making some stupid mistakes (don't pop something into a register if you need the value that's already in that register...) and having to fix another place where a function corrupted the IX register while SDCC didn't expect that (since it's the frame pointer, it assumes all functions preserve it, including ones written manually in assembler).

In the end, Contiki is now running fine with SDCC 4.2! I then tried to turn the optimization level (max-allocs-per-node) way up to 20 million and let things compile for a very long time. But this failed, the compiler generates instructions that the assembler doesn't accept because they are undocumented opcodes (that exist in the z80 implementation, but were not mentionned in the official documentation and removed from later CPUs like the z180).

So for now I have turned that back down, and I will test again in SDCC 4.3 where support for undocumented opcodes will be official and toggleable with a command line switch.

In the end, this new version of SDCC allowed to raise the free space in RAM with Contiki running from 24 to 26K, which is not bad at all! And there would be ways to free even more, by moving the Contiki Kernel to a ROM or using the RAM banks of the CPC to not have the code and the framebuffer share the same 64K space.

... so a few days later I did just this. It took some bug hunting and some not so clean tricks to get the file generated the way I wanted, but Contiki is now a ROM. Which means the free space is now 37K out of a 41K "heap", when the desktop and the "memstat" apps are both running. This is possible because the ROM uses the same memory space as the framebuffer, and so, suddenly there is 16K more of address space to use.

I think I could also implement a proper GUI driver that is not restricted to simulating a GUI from textmode. It could be made to look quite a bit nicer with a smaller font, and not being restricted to 8x8 pixels character blocks with only 2 colors for everything, and also make it use an overscan display instead of just 320x200. That would require moving the apps to memory bank so most of the main memory can be used for the display. But I already planned that when I started working on Contiki 10 years ago, and I have not started it since. And I think it's time to move on to other projects.

I still had two bugs to fix: during startup, there were some things written to the framebuffer that shouln't be there, meaning the linker somehow put non-const data in the ROM. And, the icons on the desktop are not loading. These two were related, it tuns out I had added a "const" to the icons to workaround a problem with the generation of the DSC files (these are files with just the icon data, used to quickly show the icon directory in Contiki). And so they were in the ROM, but adding an icon to the desktop actually writes some things in the icon data structure... So I made my hack a bit more complicated and now it's working fine.

While investigating this, I also found that the borders for some windows did not stop drawing where they should, and continued all the way to the bottom of the screen. I'm not sure if it was a compiler bug or a mistake in the code, but I have rewritten the code in a slightly different way and it's working fine now.

So, it is time for a new release of Contiki after 5 years of doing nothing, and two weekends of hacking!

Download Contiki 1.4 for Amstrad CPC. You will need to flash the ROM to any ROM slot, and put the DSK in your disk drive. Then type

to start the OS. Enjoy!

Get the sourcecode using Git if you'd like to help with this project or have your own fun experiments with it. I don't know when I will look again into it!

I have also submitted the patches for Haiku support to the SDCC team, and we are discussing which of the changes are useful to merge on their side. Kevin's relocation patch has a known bug, that will need to be fixed before they accept it upstream. Unfortunately, fixing it requires some changes to the way the relocation info is encoded. I'll see what I can do about it.

I also found bugs in the ACE CPC emulator (setting the PC register from the Z80 editor window actually sets IX instead?). So that's another bug fixed in ACE and I should look into that as one of my next projects. I want to do a point release of it with a collection of bugfixes, and port and publish all the ACEpansions that are available for the MorphOS version now. Oh well, the TODO list never really goes down!

BGhostview postscript viewer for Haiku

Posted by pulkomandy on Sat Apr 29 13:27:30 2023  •  Comments (0)  • 

Today I released version 1.0 of BGhostView, a postscript document viewer for Haiku.

Screenshot of BGhostView, showing some USB document from Openboot specifications

This software started in the late 90s as a port of a postscript viewer from UNIX/Linux to BeOS. Back then, Ghostscript did not have a cross platform API, and the BeOS port had to work with a patched up version of the Windows GSDLL API, heavily modified to run on BeOS.

I started working on it because in my past attempt to port Haiku to SPARC machines, I found that a lot of the documentation for these was distributed as PS files instead of the now more typical PDF. At the time, no version of ghostscript was available for Haiku. So I started digging and found an old port of Ghostscript whic provided a starting point, and this viewer I could use it with. But it wasn't working very well.

I then found that Ghostscript now has a slighly better API, and I could make use of that instead. So now BGhostView is running with an up to date version of Ghostscript (thanks to other people who also have postscript interpretation needs on Haiku, this was not taken care entirely by me).

I had not touched BGhostview since 2019, but I got reports that it was crashing recently. So, this week I dug into the code again and made some fixes and updates and decided to make a 1.0.0 version for all to enjoy. It is certainly not yet perfect, but for the basic needs of viewing Postscript documents, it should be fine.

This is yet another one of these applications that is currently hosted by HaikuArchives on Github, meaning it is more or less open for many people to contribute to, but left without someone to really take care of it and move it forward. Well, I guess that can be me when there are bugs to fix, but I probably won't have time to manage the larger refactorings and cleanups that would be needed: converting the UI to Haiku layout system so that it can automatically scale for High DPI displays, reindenting and reformatting all the sourcecode (it's very inconsistent at the moment, I guess most of it was written without a proper code editor that would watch the indentation a bit?), and reviewing the Ghostscript integration code to make better use of the APIs available in modern versions. Postscript isn't exactly great for that kind of usage, just figuring out how many pages there are in a document turns out to be a somewhat tricky problem.

There's also the question of wether we want a separate viewer for each document format. Wouldn't it be nice if the same viewer could do both PDF and PostScript? And what about DVI and XPS and FOP? And maybe docx and opendocument while we're at it? Could we use translators for this, so we can write the GUI once and then have all formats added to it later on? That would certainly be a cool project, but I already have many other things on my TODO list, so, not for now...

Get the sourcecode here

If you just want to run BGhostView on Haiku you can simply install it from HaikuDepot as you'd usually do.

Developer console

Posted by pulkomandy on Mon Apr 10 15:45:46 2023  •  Comments (0)  • 

I wrote new software today! Well, sort of.

This does not happen very often. A lot of my software work is fixing and improving existing code, and not writing new things. Maybe because I'm a bit lazy and I find it easier to fix some bugs in existing code than having to start from a blank page. It provides easier reward for me (that may not be the case for everyone, digging into an existing codebase is a learnt skill).

Anyway, so, the story is, somewhat recently (ok, actually, it's already more than a year ago), I got a new laptop. This was an opportunity to do an install of Haiku from scratch, and while doing so, I decided to go with the 64bit version. The only limitation in the 64bit version of Haiku is that it can't run 32bit software, including several applications that were compiled two decades ago for BeOS, and for which the sourcecode isn't publicly available.

I didn't think I was needing any of these applications, as, over the years, a lot of them have either been open sourced (mainly thanks to the effort of the Haiku Archives project in collecting such software and reaching out to the original authors to get the sourcecode published and/or relicensed under opensource licenses), or has been replaced by newer software or rewriten.

It turns out, one piece of software I occasionally use had not been through this yet. And so I got to work on rewriting it.

The software in question is BeDC. No, not the Direct Connect client of that name, but the rewrite of the earlier "Developer Console" (I think? it is unclear how BeDC and Developer Console are related). The idea is quite simple: this application receives text messages from other applications and logs them in a window. I discovered this software while working on PadBlocker, an input filter add-on that disables the touchpad while the keyboard is being typed on. Because of the way input server add-ons work, it is not easy to grab their output in the common way (sending it to stdout) because they run inside of input_server, which normally does not have its stdout route to anywhere.

I thought the idea was interesting and started using the app in some of my other projects, mainly in WebKit, where it was useful to collect logs from the different processes started by a single web browser instance and clearly marking where each message comes from, and in Renga, an XMPP client, as a way to log incoming and outgoing XML messages for debugging.

So, of course, on my shiny new 64bit system I did not have access to this nice tool, until now. I have rewritten my own version of it. That was made quite simple thanks to the APIs available in Haiku: the whole thing fit in about 200 lines of code. It is fully compatible with existing apps that used to target the old BeDC app, but it looks a bit nicer, thanks to the modern UI classes in Haiku. For example, when logging a BMessage, it can be shown as a nice foldable structure instead of just a bunch of lines.

I have some future plans for this, mainly to make it more useful with Renga where having some formatting of the XML would be great. But I don't know when I'll get to that. Until then, you can find the sourcecode on my Gerrit.

IFF catalog add-on for Haiku Locale Kit

Posted by pulkomandy on Fri Feb 17 22:24:00 2023  •  Comments (0)  • 

I made this as part of my work on porting ACE to Haiku. ACE originates from MorphOS, and so it uses "catalog" files for internationalization in the format used there. The format is based on the IFF container typical on Amiga originated software.

Since the Haiku version of ACE uses pretty much exactly the same strings as the MorphOS version, it would be silly to have to re-translate all the strings. So I made this add-on to Haiku locale kit to handle catalogs in the MorphOS format.

At the moment this is not useful to any other software than ACE. However, maybe someone will find it useful. The format is a bit different than what is done in Haiku. In the Haiku locale kit, the original (usually English) string is used as a key for translations. This requires hashing the whole string, which makes everything a bit slower. It isn't very noticeable on modern machines, but it is definitely part of what makes Haiku slower than BeOS. On the other hand, the format used on MorphOS assigns an integer to each string, which can be used to refer to it efficiently. It still provides fallback strings inside the executable, so if there is no catalog, things will still work.

Maybe we could use this format more on Haiku and get better performance. But it would require a lot of changes to the tooling built around the existing format. Maybe a project for later...

You can get the iffcatalog sourcecode:

If you want to simply use it, the binaries are available in Haiku package manager.

Version history:

  • 0.1 - 04/2015 - First public release
  • 0.2 - 11/2017 - Skip '\0' in translated strings (used for keyboard shortcuts on MorphOS)
  • 0.3 - 06/2020 - Fix catalog search directory
  • 0.4 - 02/2022 - Add a python script to generate locale_strings.h from catalog definitions

Programming GALs in 2022

Posted by pulkomandy on Sun Oct 9 11:20:35 2022  •  Comments (0)  • 

I am using GALs for some electronic projects. It is a bit of a lost ancient art these days, or maybe I'm doing it wrong and failed to find any modern info.

I need GALs because I make hardware for retro-computers, where the logic uses 5V, so most modern options are out. Surprisingly, Microchip is still producing GALs. Also, the toolchain is mostly free software, and I can run it on Haiku (almost all of it), which is cool. The official closed source software seems unstable and very confusing.

Anyway, so the devices I'm using are the ATF16V8 and ATF22V10C, depending on how much IO I need. They are compatible with JED files designed for the older GAL16V8 and GAL22V10, which mean I can use tools designed for these.

The GAL chips are programmed from "JEDEC" files. These are roughly similar to Intel hex or Motorola S-Record and just describe the state of each fuse inside the GAL. For the simplest devices, the representation is fairly straightforward, but the newer ones add more and more fuses for different functions. It is possible to reverse engineer how a GAL works interally by generating a lot of these files from equations using an existing design tool, and analyzing what changes in the output. The next step can also be analyzed, by looking at an existing GAL programmer with a logic analyzer while it's programming or reading a chip. This is how open source tools came to be developped. It's also not impossible that in the past, some people just decided to edit their JEDEC files directly instead of going through a tool to assemble them from equations. That would have been doable on the first generations of chips, but would get a bit out of control on the current ones, I guess.

My current setup is using galasm for creating JEDEC files from equations, and atfblast to load the JEDEC files into the chip, using a cheap and simple programmer that I could assemble myself.

The original authors for both of these have disappeared off the internet, I hope they are doing ok. Thanks to both of you if you read this.

Currently you can find the sources for galasm on github. The documentation is included, but it may be easier to browse it online from another place where it's hosted. There is also a clone of it called Galette, written in Rust and supposedly much cleaner and easier to maintain (I don't know, I have not looked very closely at the sourcecode of either). So if you're looking to add more features (support more chips, maybe?) it would be a good idea to start there instead. Also it has a better license, since galasm is derived from the older Amiga program GALer, which had a license restricting it to non-commercial use.

For aftblast, you can find documentation about the hardware also on Github. However, the version of the software provided there will not run on current Windows versions (it will appear to, but it is not able to access the parallel port). So you need to get a version modified to use inpout32.dll which allows access to the hardware on modern Windows systems.

With that, you're all set to program these GALs.

Of course, it would be great to be able to program newer devices too, like the ATF750. It looks like there is some work in progress on that in the "afterburner" arduino based GAL programmer. But there is no effort from the galasm side to allow it, so the equations would need to be assembled in WinCUPL or some other tool.

The algorithm for programming the chips is now well understood, for example it is documented here. It's unfortunate that Atmel/Micrchip does not want to give any information, but in the end the algorithm is deried from the one used for previous GALs and so it isn't so hard to adjust it (different address and data sizes, pretty much).

This document also explains how the fuses work, and, completing it with what was discovered about the ATF750, and careful reading of the datasheet (it does give some fuse line and column address in the block schematics, for example, but doesn't explain what they are), it should be possible to build a new version of galasm or galette for the newer chips. That seems like a large-ish project, and certainly it isn't a great idea to start working on both the assembler and the programmer at the same time. Also it's questionable if galasm should be used as a base at all, it is old and obscure, and also very low level (it would be nice to be able to write more complex equations and have the tool expand and optimize them). Will I finally have to learn Rust in order to add this all to Galette instead?

The progress on the afterburner approach has stalled because the Arduino used there does not have enough RAM. But the prototype was working fine. On the other hand, attempts to add it to the Minipro tool failed due to limitations in the hardware and firmware used (on which the Minipro team has no control). It looks like the good old parallel port based atfblast should not suffer from this.

If I'm going to try this, my first step would be, of course, to port atfblast to Haiku, because I'm not crazy enough to attempt doing development for Windows.

Pourquoi les hackatons, c'est de la merde

Posted by pulkomandy on Wed May 25 19:02:11 2022  •  Comments (0)  • 

Bon, on est sortis du confinement, on commence à voir des gens organiser des évènements en présentiel. C'est donc logiquement le retour des hackatons organisés par plein d'entreprises. J'ai pas trouvé (en cherchant 3 secondes) de page qui résumait pourquoi c'est pas une bonne idée de faire ou de participer à un hackaton. Alors j'vais en écrire une.

Pour ceux qui n'ont pas suivi le sujet, le principe d'un hackaton est de constituer des équipes qui vont développer un projet en un temps assez court, par exemple 48h (mais maintenant on voit des hackaton de une semaine). Dans ces 48h, il faut avoir une idée et commencer à écrire un "proof of concept", un logiciel qui permet de démontrer rapidement le principe. À la fin, chaque équipe présente son travailm, et un jury décide d'une équipe gagnante. On attend des participants qu'ils travaillent sur leur projet à fond, jour et nuit sans s'arrêter, compte tenu du délai très court accordé.

Bien sûr les participants ne sont pas payés, sauf éventuellement l'équipe gagnante qui récoltera au mieux quelques centaines d'euros (divisé par le nombre de membres de l'équipe, ça ne fait pas un salaire raisonable pour du travail de nuit).

La plupart du temps, le code développé va finir à la poubelle. Et c'est probablement la meilleure fin. Quand on décide de réaliser un projet dans un temps aussi court, on a pas le temps de réfléchir à une architecture propre. On va donc surtout créer de la dette technique et pas grand chose d'exploitable. Si quelqu'un trouve que l'idée de départ est bonne, il fera probablement mieux de refaire le code de zéro.

Parlons des idées justement. Normalement quand on a une idée et qu'on envisage d'en faire quelque chose, soit on la garde secrète jusqu'à que le produit soit prêt, ou alors si c'est un truc un peu plus avancé, on peut éventuellement poser un brevet (qui suppose que l'idée n'était pas diffusée avant, sinon c'est plus possible). Un hackaton, c'est une très bonne solution pour une entreprise de vous forcer à publier gratuitement vos idées pour les réutiliser ensuite. Vous allez donc travailler gratuitement pour eux.

En plus de l'aspect compétition, les hackatons représentent la culture d'entreprise et la façon de travailler la pire qui soit: on va jeter à la fois la qualité du code et la santé des développeurs, juste pour tenir un délai arbitraire. C'est tout le contraire de ce qu'il faudrait faire. Sur le long ou même le moyen terme (plus de deux jours), un projet a surtout besoin d'un code bien architecturé avec une dette technique gérable, et d'une équipe en pleine forme qui peut durer plusieurs années. Je vous laisse réfléchir qui peut avoir intérêt à habituer les développeurs ou futur développeurs à autre chose. Dans un hackaton, l'aspect compétitif est là pour mettre la pression sur les participants et les pousser à bout.

En plus de ça, ce mode de fonctionnement où on s'attend à ce que les gens soient disponibles 48h ou même parfois une semaine d'affilée en continu n'est pas du tout inclusif. Vous ne trouverez par exemple pas parmi les participants (liste bien sûr pas du tout exhaustive):

  • Des personnes qui ont une famille dont ils doivent s'occuper,
  • Des personnes qui ont un emploi ou des études avec des horaires fixes,
  • Des personnes souffrant de toute une liste de handicaps qui nécessitent du repos ou imposent d'autres contraintes,
  • Tout simplement des personnes qui préfèrent avoir une hygiène de vie plus raisonable et n'ont pas envie de faire une ou plusieurs nuit blanches.

Leaving Twitter

Posted by pulkomandy on Thu Apr 28 22:51:23 2022  •  Comments (0)  • 

That's it. I'm off Twitter now.

I used it for 5 years. I now have archives of everything I posted there.

Now you can find me on Mastodon instead. See you there!

Forgotten console: Giochi Prewiosi My Life

Posted by pulkomandy on Sun Mar 20 11:10:36 2022  •  Comments (0)  • 

A few months ago, while visiting a surplus store in my area, I noticed this thing that looked like a game cartridge caled "Disney My Life Hannah Montana". Looking on the back I saw it was for the "My Life" console (sold separately). I had never heard of that console. So I left the thing there, went back home and did some research.

I did not find a lot. The console was released in 2007 and there was a later version called My Real Life. It was sold at least in Italy, France, and the US. It is strongly marketed "for girls", with pink cases, heart-shaped buttons, etc. It's fine (no, really, it's not, why would anyone do that?). I'm not a girl, but I love pink.

There are several cartridges and expansions for it. But no one has written an emulator or even published a teardown. And despite initially selling relatively well, it was not that easy to find a console for an acceptable price.

Yesterday I visited that store again. The poor cartridges were still there gathering dust. So I decided to buy one this time.

The packaging is surprisingly nice. The thing is sealed in (relatively thick) plastic wrap, with extrusions for two cardboard pieces that stand out, a bubble for the cartridge (both the cartridge and cardboard are held with extra pieces of plastic), and an extrusion on the back so that the whole thing can be put vertical on a shelve. There is also a full color, 35 page manual (all in French, while the outside packaging is bilingual French and Italian).

The cartridge contains an exention to the "My Life" game built into the console. I could not try it yet, but from the screenshots in the manual and on the packaging this appears to be isometric pixel art (somehwat similar to Habbo hotel), you play a character and have to buy clothese, meet boys, go to toilets regularly to keep your hygiene bar up, go to school, take care of your pet, etc. With the Hannah Montana cartridge, you can go to the airport and visit Malibu to attend to Hannah's show. So your goal there is to find tickets for the show, and maybe manage to meet the star backstage. How exciting!

The cartridge itself has a connector for another extension with extra items to collect in-game. Clearly they were trying to get parents to buy more and more things... The extension is shaped like a small guitar, because why not?

I opened the cartridge to see what's inside. There is a serial EEPROM and a blob, which is probably some kind of parralel ROM or nor-flash. I have not tried to match the pinout with existing flash/ROM chips yet. I don't even know if it is 8 or 16 or 32bits and what size it is. I figured out I would know more about it if I had the console. And also I'd like to try the game before I do anything destructive to it (hopefully I don't need to).

So I went hunting on the internet. The usual websites were offering it for higher-than-new prices, which I didn't really want to pay for this thing. So I did the most crazy thing and went to page 2 of Google search results. In fact I went down to page 4, and there found a link to someone selling it for a very acceptable 5€ on I had never heard about that website, and indeed it seems not very popular. The website lists less than 160 items for sale, from about 6 different sellers. Anyway, I placed an order, hoping it was not a scam website (who would attempt to scam people looking for that console, anway?). A few minutes later I got an email from the seller. She said that I should have contacted her because she could have sold me the items through Kiabi Seconde Main, another website I had never heard of that initially specializes on second-hand clothes, but expanded to children toys as well (not the first time such a thing happens, in fact I managed to buy some VTech gear for low prices from Vinted, where collectors don't really look for it (who am I kidding, no one but me is collecting VTech gear arouns here!).

Anyway, the console is ordered and will be shipped on monday. I'll post a follow-up when I receive it. I hope it will help figure out the pinout, and I'm not sure how useful the data in the cartridge will be in figuring out how things work, if it's only an expansion to the built-in game it may or may not have a lot of code. I hope I can manage to dump some ROMs, and then maybe attempt to write an emulator?

I have some scans of the manual and packaging, as well as pictures of the cartridge. Let me know if you need them, I'm too lazy to upload them all right now.

Website mirroring

Posted by pulkomandy on Sat Jan 1 15:19:32 2022  •  Comments (0)  • 

Please do not mirror my whole website using wget mirroring mode, WebReaper, or other similar tools. It results in a lot of requests to my poor old server, too much memory and CPU use, and the server fan spins up and makes a lot of annoying noise. So I will ban your IP or IP range from accessing the website if you try this.

If you want a full copy of some parts of the website, please contact me so we can set up a better way to share the data (I can set up an ftp or sftp or rsync thing, for example)

Gravis GrIP to HID converter

Posted by pulkomandy on Wed Oct 27 17:51:10 2021  •  Comments (0)  • 

A few years ago (too many years to remember when I started this, in fact), I wrote down some notes about the Gravis Gamepad Pro and the protocol it uses to communicate with a computer over the simple joystick port.

Finally, I have completed the work on making an interface to use these gamepads with an USB port! The interface can handle up to 4 gamepads, and make them show as normal USB HID devices to the computer, which means no specific drivers are needed. Just plug and play!

It is based on an AT90USB162 microcontroller. I originally started experimenting with various other things, but it turns out, this old and simple microcontroller is good enough for this task, and writing the code wasn't so hard.

The schematics, PCB files and sourcecode can be found in my avrstuff repository.

It is also possible to buy boards from me if you want to, the cost is 15€ (that covers the components and PCB costs and the shipping). I made a first batch of 10 boards, but I could build more if there is enough demand for it. Just send me an email to order one. Please do not send me money without asking first, in case there is no stock available I don't want to be owing you money for months or years. If you want to order, remember to give details on where I should ship the thing (I need both your name and your physical address).

Some random thoughts about XMPP spaces

Posted by pulkomandy on Tue Aug 17 17:58:46 2021  •  Comments (0)  • 

You may or may not know I am involved in XMPP in a way or another for some time. Recently I have started work on Renga, an XMPP client for Haiku, and participated in an online meeting and discussion about why Discord is so succesful and what ideas XMPP could borrow from it. A part of the discussion revolved around the way Discord organizes multiple channels in a "server" and how that fits very well with their user base.

Today someone contacted me and shared a work in progress document about XMPP "spaces" which is an attempt to see how something similar could be made in XMPP. I was surprised to see the document dive straight into discussion about protocols and stuff like that, with the UI/UX part being "TODO write this later". I am not sure this is the right way to design the thing. I was asked my input on it, so here it is. I have not a lot of experience of the XMPP protocol, but as a user, I chat on various systems with various people and there are several instances where I can see an use for such things.

So, let's tackle this from the user experience point of view. I will completely ignore the "but how do we do that?" part and focus on what I think could work well. Let's start by going back to basics and define some use cases. Why do we want to do "Spaces" in the first place?

Use cases

Let's imagine that XMPP is a very popular protocol and everyone uses it. No other chat system exists anymore. Let's see what it did to become so succesful. I will take my own usage of various IM networks to see how this could look in that alternate (or future?) world.

Communicating with my family

My parents are doing ok with phones and computers, but still, let's keep things simple for them. A single chat channel and ability to send 1:1 messages will be enough. A media library archiving all the pictures and links we sent to each other could be nice. There will be almost no movement of users joining/leaving this space (maybe a new girlfriend/boyfriend joining the family or leaving after a breakup once every few years?), and everyone can be a moderator or it could be just one person.

I think that was the easy case which is already mostly covered by existing options

In the office

I am working remotely this year and in our company this meant reviewing and improving our chat system, which we now use a lot.

I work in a company that has in total about 800 employees, of which 150 in the local branch I work at. We are software engineers and developers. We work on many projects for different customers. Each team is typically 3 to 30 people (with sub-teams in the largest teams). We also have some people who need to do things for many teams at once (for example our sysadmins are taking care of services and tools deployed globally or specifically for a given team).

In our current chat system, we have one single space for the 150 persons in the local branch. Each project has one or more private channels, which are not listed anywhere in the UI. When people join a project, their account is invited to all the corresponding channels. This works quite nicely for us and there doesn't seem to be a reason to group channels together here.

What we would like to have, however, is a way to create temporary sub-channels for discussing specific issues. Something that would be similar to an e-mail thread. Slack and Zulip are examples of chat systems which allow this. Zulip is very close to the email way, having separate threads at the core of its UI. In Slack, it is done by picking a specific message in a channel and replying to it, which creates a sub-discussion. This would be great to organize our chats and more easily keep the info we need.

Other nice to have features are a way to search for old messages in a specific set of channels (but probably this doesn't need to have them formally tied together as a "space"), and a way to pin things (mainly URLs or file attachments) to be able to find them easily. I can imagine also more advanced features such as a shared calendar to place our meetings and days off work in.

Probably, larger companies will want a more segregated system, and I can imagine companies which have non-computer-inclined people (not software engineers) may need some more centralized admin roles to oversee who has access to what. So that probably means accounts tied to some LDAP server, not being able to list MUCs unless your account is added to the appropriate space, and not allowing people to leave a space on their own because they would be unable to re-join it.

Opensource projects

I contribute to a lot of projects, some large, some small.

I will not go on for very long about the small projects because the existing solution (just a single MUC) is just fine for me. So let's see about the larger ones which have a need to split their discussion into multiple aspects.

So, in this case, the main thing to think about is onboarding. If you don't care about onboarding, you will be just fine with a dozen independant channels which have no apparent relation to each other, except they are listed together on your website, and maybe they all have your project logo or some variation of it on them. If you care about onboarding, you want to make it easy for a newcomer to click on a single button/link and immediately join your Space and discover all the channels from inside there, in their favourite IM client.

You will probably want some kind of "backstage" channel for moderators to discuss ongoing issues. This should not be visible to regular users, of course. Which means multiple channels in a space can have different access rights. On the other hand, you may want to nominate moderators and automatically allow them to be moderators on all the channels. Speaking of moderation, you also want the ability to kick/ban someone from the whole space if they misbehave.

As an opensource project, you want to be transparent and have an archive of everything that was said and shared, possibly over the course of decades. This includes channels that are currently unused because the project was reorganized. Possibly you'll want to split the history of a space because one project was split into two separate parts. You may want to copy it to create a fork of the project while retaining the past history in both branches of the fork. And you may also want to merge the history from two projects together and form a single space, but probably I'm going a little crazy here.

You also want to preserve the privacy of your users. It should not be easily possible to identify that user A in space X is in fact the same person as user B in space Y, if they decided to use different nicknames in each place. On the other hand, you want to be really sure that if you talk to someone named "user A", it is really them, and not some other person using the same nickname.

Another aspect to think about here is notifications. For high traffic channels and projects, probably I won't read everything. I will have the chat client on my computer and read it when I have time or maybe if someone pings me. But I don't want this to ring my phone everytime something happens. It should be a distraction free thing that I can have running in the background. This mean I need easy configuration for which notifications I want on each of my clients. I think both for the whole space, and for specific channels (there may be some channels I have no interest at all in following, maybe because they are in languages I don't understand, maybe because the project is large and some topics are not interesting to me).

Chat with friends

One of my uses of IM currently is organizing board games sessions with friends (but whatever your hobby is, probably some of the same applies). Here, there isn't really a notion of a fixed "space". Some of my friends don't know each other or have met once during a board game afternoon and then never met again. Currently I have one rather large channel with a lot of people but I think I will just create and delete smaller groups as needed. In my case, a "space" is probably not useful here.

Gamer communities

I am a lot less familiar with this. I think a large part of the "opensource" section will also apply. Probably channels with restricted permissions (only a few people can talk) are needed. Also, some nice to have things: custom "stickers"/emojis specific to the server, ability to define and rename roles and assign them specific permissions, ... Just read the Discord documentation.

Chat with strangers

One place where IRC is still somewhat popular. There are chat services with various thematic or so channels (by age, location, or shared interests) all thrown together into a "space". People can join and talk with complete strangers. There are a lot of trolls and people with inappropriate behavior. Users of the service need an easy way to signal such things so a moderator can quickly intervene. If the space is big enough, there will be separate moderator staff for each channel, but probably still a common backstage channel for coordination

Thinking about the user interface

So, what do we need to put in our user interface? Here is an attempt to summarize it:

  • Single-button way to join a space
  • Ability to see a list of channels in a space you joined, with a description of what their purpose is
  • Media library with all pictures/links/? or pinned messages
  • Ability to see long term logs (multiple years) of all channels, including now inactive ones
  • Possibility for space moderators to archive a channel (only past logs available, no way to post new messages)
  • Manage permissions for a single channel and for the whole space (who can talk, who is a moderator, etc)
  • Ability to configure notifications, per-client, globally on a space and more specifically on each channel
  • Know who is joined in a space, ability to reliably ban people (in a way they can't avoid just by rejoining with a different nickname)
  • No way to identify that two users in two different spaces are in fact the same person
  • Multiple levels of administration: the owner of a space can nominate moderators for different channels, control which channels are visible to all users or to users with some specific role only, etc. Moderators can adjust some, but not all, settings of the channel they are moderating
  • Ability to join a space but only join some of the channels inside and not all

In terms of user interface, channels from the same space should of course be grouped together. There will probably be a LOT of channels so you probably won't get away with a single tree view, it will never fit everything on screen. Which means you need a first level with a list of all the spaces, showing which ones have ongoing activity. Then you can select one of the spaces and see the channels inside.

In the XMPP world, one thing to think about is how to handle things that are not in a space. Maybe they can just be put into a "default" space from the UI point of view?

If you know someone's real JID, and you start a chat with them from inside a MUC, it would be super annoying if that ended up being a separate chat history than if you contact them directly. Or maybe it's a feature to have separate discussions (let's say if you have a colleague and you talk work things, but they're also a friend and at other times you talk non-work things).

You will have some kind of management menu (maybe right click on the space icon/name) to decide if you want to leave a space, configure notifications, see who is a moderator or admin.

Obscure Soundchip Tuesday: The SGS M114

Posted by pulkomandy on Wed Jul 14 20:44:33 2021  •  Comments (0)  • 

(yes, I'm writing this article on a Monday. But the title sounded better this way. Whatever.)

As you may know, I'm interested in old computers and sound and music. Recently I was reminded by a youtube video about the Amstrad CKX100, a toy-synthetizer from 1988. I had already heard about it but never had an opportunity to disassemble one, so I didn't know how it was built. Well, this video did just that and got me curious about the soundchip used, the ST M114S. I had not heard about it before and was curious how it worked and if I could possibly connect it to a computer to play some music.

So, a few web searches later, I didn't find a lot, but I found what I was looking for: a datasheet and a research paper from the chip creators, both explaining in some detail how the chip operates.

The research paper is dated from 1985 and mentions that the chip was developped in cooperation with GEM, another synth keyboard manufacturer (who went on to use it in several of their keyboards). It was designed by SGS before merging in ST, so it was the opportunity for me to learn a little more about the Italian side of ST Microelectronics. Previously I had known them mostly for the EF9345 (used in the Matra Alice and the Minitel) and some of the chips used in the Thomson TO8 and MO6 machines, mainly the palette circuit that was developped for the TO9 but later became an off-the-shelf component in ST databooks.

The chip uses an 8KB ROM where sound samples are stored. The samples are in power of two sizes from 16 to 2048 bytes, and are played in a loop to sustain the sound. They use delta coding, which means they encode the derivative of the actual sound. An analogue integrator is used to turn this back into the original signal, which has the advantage of providing some level of smoothing of the output.

The chip does a bit more than just playing the table, however, it can smoothly transition from one sample to another by mixing them together. And it can also play the sample at various speeds by using only one out of two or one out of four bytes (but this risks having a not perfectly balanced signal, which will drive the integrator into saturation).

Moreover, it is indeed designed to be driven by a CPU. It is not a "keyboard-on-a-chip" system that would handle keyboard scanning directly and generate the sounds from there. Instead there is an interface for a normal CPU bus where you can send commands to trigger notes. The commands are made of 8 6-bit words. This may seem a bit strange, 6 8-bit words may have made more sense (especially as most of the values transmitted are indeed 8 bits), but I guess it allowed to save some pins and fit the thing in a 40 pin DIP package.

As a result, this chip was apparently used in some pinball and arcade machines. However, MAME doesn't have an emulation for it yet.

During my search for the Datasheet, I of course looked at ST databooks, and found that there is a larger version called M114A. This one has a 48 pin package, which allows to address 265K of memory instead of 8K. Surely this must allow for much more complex sounds.

Interestingly, the datasheet for the M114S shows a clever hack to increase the ROM space to 16K instead of 8. The chip has an "output enable" pin to signal the ROM when it wants to read a byte. This signal will always trigger twice within a short time since the chip will always read a byte from two samples (remember, it then mixes them together). So, they suggest connecting a flip-flop to this output and resetting it with an RC circuit tuned to a longer delay. The output is then used as an extra address bit, and as a result, the first sample will be from the first half of the ROM, and the second sample from the second half. This simulates the behavior of one of the pins of the M114A, which probably does the same without needing an RC circuit as it knows about the chip internal timing.

Of course I am interested in wiring the chip to RAM. The datasheet says it's possible, but some arbitration will be needed to make sure the M114 and CPU don't try to both access the RAM at the same time. Should I go with dual port RAM? Can I simply block the M114 from accessing the bus when the CPU wants to use it? Maybe I can do some fun tricks where the CPU manages to synchronize itself with the chip and feed it data without using the RAM at all? And, first of all, can I even get one of these chips? There seem to be someone selling them ("used") online, but will they be real chips, or will they be some random other chip being relabelled?

I'm also considering writing an emulator for this chip, just to hear how it could sound like. However, to do anything like that, I think I need ROM dumps from one or more of the original devices using it. At least to make sure my understanding of the storage format is correct. There is a dump from one of the pinball machines using it, but it is using mainly or only PCM samples, and not delta encoding.

Finally I am surprised that this chip was not more popular, for example in home computers. Ok, maybe needing a whole 8K of ROM may be the cause. But it sounds quite nicely, and it would have been interesting to see it alongside the AY3, the SID, and the various options from Yamaha, don't you think?

Programming notes

This information is directly from the datasheet, but here in easier to read HTML format.

All communication with the chip is made with 8 byte commands (only 6 bits in each byte). The bytes must be no more than 128us apart, otherwise the chip considers itself out of sync and the command is aborted.

The command layout is as follows:

2OutputT1 address MSBT2 address MSB
3T2 address LSB
4T1 address LSB
5T1 lengthMode
6InterpolationImmediateOctave Divider
7ChannelTuning LSB
7NoteTuning MSB
  • Attenuation: higher values for lower volume
  • Output: route the channel to one of the four outputs
  • Table addresses: bits A12-A4 of the ROM address to read from
  • Length: number of bytes in T1 sample, from 16 to 2048
  • Mode: various ways to access the two samples, see below
  • Interpolation: Mixing value K. The generated output is S1 * (K + 1)/16 + S2 * (15 - K)/16. A value of 15 plays only table 1, and lower values add more and more of the second sample to the mix.
  • Immediate: apply the new attenuation immediately (otherwise a ramp from the previous value is generated)
  • Octave divider: divide the frequency by two, to play an octave lower
  • Channel: channel on which the command must be run
  • Tuning: finetune the selected note, see below.
  • Note: from 0 to E, 15 possible notes a semitone apart, covering a bit more than an octave. F is reserved for special commands (See below)

The possible values for the tuning:

  • 0 to 5: detune by -6/12 to -1/12
  • 6: detune by -2/1000
  • 7: detune by -1/1000
  • 8: exact note
  • 9: detune by 1/1000
  • A: detune by 2/1000
  • B to F: detune by +1/12 to +5/12

The special commands are not related to a channel. They are globally applied

  • F8: ROM ID mode. The chip will generate addresses 0 to 8 in a loop and send them to the ROM.
  • F9: SSG, enable synchronous mode globally. In synchronous mode, frequency changes are delayed until the next loop point in the sample
  • FB: RSG, disable synchronous mode. Frequency changes happen immediately.
  • FA: RSS, invert the state of synchronous mode just for the next command.
  • FC: Keep the existing frequency from a previously played note.
  • FF: Immediately stop the channel playing.

TODO: SSG and RSG are swapped in another part of the datasheet. Check which one is correct.

And finally the modes affect how the waveforms are accessed:

ModeT1 speedT2 speedT2 length
000 /2 /2 =T1
001 1 1 =T1
010 /4 /4 =T1
011 1 1 max(T1/2, 16)
100 1 /2 T1/2
101 1 1 max(T1/4, 16)
110 1 /4 T1/4
111 1 1 max(T1/8, 16)


It turns out someone already wrote an emulator!

Next steps

I'm looking for ROM dumps of the Amstrad CKX100 (both the samples and the CPU code) so I can learn more about how it uses the chip. Anyone has one and is willing to dump the ROMs?

Hello World

Posted by pulkomandy on Sun Feb 18 16:30:21 2018  •  Comments (4)  • 

This is the new server of the PulkoTeam! Enjoy your stay here.

On this website you can find various stuff I work on, around the Haiku project, electronics, 8bit computers, and random things depending on the day mood.


Posted by pulkomandy on Wed Jul 30 10:43:02 2014  •  Comments (0)  • 

Today I discovered Rome2Rio, which is a multi-modal travel search engine. I've been looking for such a tool for some time. Instead of searching only flights, it provides train and bus routes, and allows to mix and match all of these (and even ridesharing) to find the best way to go where you want. It also features door-to-door pricing, which means not just the cost of the flight, but also any shuttle you may need to use from the airport to city center.

They have their own dataset and don't do API queries to other operators. There is a risk of out of date data, but on the other hand, this makes the search super-fast. The trip is visualized on a map and you can easily see what's the best solution.

I can finally plan mixed train/bus/plane trips easily!

Rainloop webmail

Posted by pulkomandy on Thu Jan 30 16:14:57 2014  •  Comments (0)  • 

Pendant des années j'ai utilisé Roundcube comme webmail. Mais je n'en ai jamais été vraiement satisfait..

Et aujourd'hui, j'ai installé Rainloop sur mon serveur. C'est propre, c'est beau, c'est facile à installer, ça marche tout seul, et on a même pas besoin d'avoir les mails sur le même serveur car tout passe par de l'IMAP et du SMTP. Adopté!