Paolo Amoroso's Journal

Tech projects, hobby programming, and geeky thoughts of Paolo Amoroso

I upgraded my Raspberry Pi 400 to 64-bit Raspberry Pi OS 2024-11-19 based on Debian Bookworm 12.9:

The desktop of 64-bit Raspberry Pi OS 2024-11-19 on a Raspberry Pi 400.

Since I had no files to preserve the process was surprisingly easy as I went with a full installation. And this time I finally used the Raspberry Pi Imager.

When I first set up the Pi 400 my only other desktop computer was a Chromebox that couldn't run the Imager on Crostini Linux. This imposed a less convenient network installation which, combined with a subtle bug, made me waste a couple of hours over three installation attempts.

Now I have a real Linux PC that runs the Imager just fine. Downloading Raspberry Pi OS, configuring it, and flashing the microSD card went smoothly. When I booted the Pi 400 from the card I was greeted by a ready to run system.

On the newly upgraded system, building Medley Interlisp from source for X11 took an hour or so. The environment still runs well with the labwc Wayland cmpositor that now ships with Raspberry Pi OS. But, like the previous Raspberry Pi OS release, Medley doesn't run under TigerVNC because of a connection issue.

#pi400 #linux

Discuss... Email | Reply @amoroso@fosstodon.org

I wrote Bitsnap, a tool in Interlisp for capturing screenshots on the Medley environment. It can capture and optionally save to a file the full screen, a window with or without title bar and borders, or an arbitrary area.

This project helped me learn the internals of Medley, such as extending the background menu, and produced a tool I wanted. For example, with Bitsnap I can capture some areas like specific windows without manually framing them; or the full screen of Medley excluding the title bar and borders of the operating systems that hosts Medley, Linux in my case.

Medley can natively capture various portions of the screen. These facilities produce 1-bit images as instances of BITMAP, an image data structure Medley uses for everything from bit patterns, to icons, to actual images. Some Lisp functions manipulate bitmaps.

Bitsnap glues together these facilities and packages them in an interactive interface accessible as a submenu of the background menu as well as a programmatic interface, the Interlisp function SNAP.

To provide feedback after a capture Bitsnap displays in a window the area just captured, as shown here along with the Bitsnap menu.

A bitmap captured with the Bitsnap screenshot tool and its menu on Medley Interlisp.

The tool works by copying to a new bitmap the system bitmap that holds the designated area of the screen. Which is straighforward as there are Interlisp functions for accessing the source bitmaps. These functions return a BITMAP and capture:

  • SCREENBITMAP: the full screen
  • WINDOW.BITMAP: a window including the title bar and border
  • BITMAPCOPY: the interior of a window with no title bar and border
  • SNAPW: an arbitrary area

The slightly more involved part is bringing captured bitmaps out of Medley in a format today's systems and tools understand. Some Interlisp functions can save a BITMAP to disk in text and binary encodings, none of which are modern standards.

The only Medley tool to export to a modern — or less ancient — format less bound to Lisp is the xerox-to-xbm module which converts a BITMAP to the Unix XBM (X BitMap) format. However, xerox-to-xbm can't process large bitmaps.

To work around the issue I wrote the function BMTOPBM that saves a BITMAP to a file in a slightly more modern and popular format, PBM (Portable BitMap). I can't think of anything simpler and, indeed, it took me just half a dozen minutes to write the function. Linux and other modern operating systems can natively display PBM files and Netpbm converts PBM to PNG and other widely used standards. For example, this Netpbm pipeline converts to PNG:

$ pbmtopnm screenshot.pbm | pnmtopng > screenshot.png

BMTOPBM can handle bitmaps of any size but its simple algorithm is inefficient. However, on my PC the function takes about 5 seconds to save a 1920x1080 bitmap, which is the worst case as this is the maximum screen size Medley allows. Good enough for the time being.

Bitsnap does pretty much all I want and doesn't need major new features. Still, I may optimize BMTOPBM or save directly to PNG.

#Bitsnap #Interlisp #Lisp

Discuss... Email | Reply @amoroso@fosstodon.org

I initially used Linux from the mid 1990s to 2015, first as dual boot with Windows 95 and then as my only desktop operating system.

Back then my PC had an Nvidia graphics card and system updates frequently broke X11 on Linux, leaving me at the text console with no idea what to do. At some point I stopped applying the updates as I dreaded change. In 2015 I had enough and switched to ChromeOS.

Although I still used Crostini Linux on ChromeOS, over the years I increasingly bumped into the limitations of this containerized approach. The rumors of Google considering for ChromeOS a feature like Windows Recall eventually made the cloud operating system a deal breaker. So I decided to migrate back to Linux for good, bought a System76 Merkaat mini PC with no Nvidia hardware, and installed Linux Mint Cinnamon.

It's been seven months since my switch back to Linux in July of 2024 and, despite some early issues, my experience with Mint has been smooth and uneventful. Linux supports all my hardware, system updates install seamlessly, and everything works. The system fades into the background and I can focus on running the programs I need.

In my early Linux years I often upgraded to every major and minor version of my distro. There were good reasons as Linux evolved rapidly, significant features came out regularly, online updates weren't a thing, and getting online was costly and impractical. It helped that I was younger and eager to play with Linux.

In January of 2025 Linux Mint 22.1 was released, the first minor version since my current Mint 22. But this time I'll defer upgrading until at least the next major release, or possibly for a year or two. I feel no pressure as system updates flow regularly over the support period of Mint 22 that ends in 2029. Besides, upgrading involves some preparation and work I don't look forard to doing.

If some features I really want do come out I may consider upgrading. But, for now, I want to savor this newfound Linux stability.

Linux has really come a long way.

#Linux

Discuss... Email | Reply @amoroso@fosstodon.org

It's a joy to use the Cardputer uLisp Machine, a nice little microcontroller system that runs uLisp. But after a short experience I had to put aside my Cardputer due to a showstopper issue that made it impractical to program the device.

Since then a good workaround emerged and I learned how to improve the experience with the device.

The showstopper is a buffer overflow when sending Lisp code from Emacs to the Cardputer over a serial USB line. If the receive buffer fills up too fast the device will crash and disconnect. Sending more than a few hundred bytes triggers the issue and makes it impractical to evaluate medium or large code blocks. This acknowledged Arduino issue reported in February of 2022 has not been addressed yet.

Meanwhile, Dennis Draheim devised a workaround. He wrote some Emacs Lisp code to open a serial connection to the Cardputer and send an expressions or region for evaluation. The trick is to split the input into lines and send one line at a time, with a delay in between to keep the Cardputer's serial buffer from overflowing.

Dennis' code works well and makes uLisp usable on the Cardputer. The only downside is the echoed input clutters the Emacs serial buffer. Our attempts at turning off echo failed as we don't know where Emacs handles this.

The workaround enables running more substantial and interesting uLisp programs such as this nice surface of rotation graphics demo:

3D function plot on the display of a Cardputer uLisp Machine device.

The Cardputer has a tiny built-in keyboard that is handy for short interactions. But it's prone to overtyping when entering a character that requires pressing two keys, such as shifted characters or the parentheses.

I originally attempted to press at the same time the Aa shift key and the key with the desired symbol. But this often results in typing more than one character as hitting such tiny targets simultaneously is difficult. I later stumbled upon a way to consistently avoid overtyping: I press and hold Aa, then press the key with the desired character.

#Cardputer #Lisp

Discuss... Email | Reply @amoroso@fosstodon.org

In 2023 I migrated my personal website from Squarespace to Blot. Blot is a static site generator that publishes as a website a folder stored on Google Drive, Dropbox, or a Git repository.

Back then I set up Blot to publish a Google Drive folder but I recently switched the synchronization to a Git repository. It was necessary as Blot has been unable to access Google Drive since Google eventually imposed onerous and expensive auditing processes to use their API. This forced Blot and other small developers to drop support for Google Drive.

Blot's developer is implementing a workaround that will allow to continue using Google Drive. But I decided to go with Git anyway as it's a better fit for my current tools and workflows.

Switching to Git instantaneously and seamlessly created a repository I can clone and update to change the site.

#blogging #Google

Discuss... Email | Reply @amoroso@fosstodon.org

MattoF has tagged me for the Blog Question Challenge which asks bloggers questions about their background and motivations, tools, and workflows. It is a variation by Kev Quirk of a challenge originally created by Ava at Bear Blog.

I have accepted this fun challenge and this is my entry.

Why did you start blogging in the first place?

I started in 2004 in the golden era of blogging. I enjoyed blogs and their community, wanted to experiment with the new medium and tools, and thought I had something to say. So I set up a blog to tap into and amplify this energy.

What platform are you using to manage your blog, and why do you use it?

For my blog Paolo Amoroso's Journal I use Write.as because it's a lightweight blogging platform with a clean design and excellent support for technical writing, which is what I mostly do. As a byproduct these features reduce friction in writing and publishing.

I settled on Write.as after a long journey across blogging platforms.

Have you blogged on other platforms before?

Yes, and I used static site generators well before it was cool.

My first platform was BlogMax, an Emacs package we would now describe as a static site generator. Back then I was a heavy Emacs user and it seemed natural to blog with Emacs. My first blog has been online since I started it in August of 2004, now an abandoned time capsule of what its name unambiguously hints has always been my obsessionpassion: Lisp Propulsion Laboratory log.

For my blogs I later used Blogger, Micro.blog, and eventually Write.as. I also used the elephant in the room, WordPress, for contributing to other blogs.

How do you write your posts?

I just use the online Markdown editor of Write.as as I don't need anything fancier.

When do you feel most inspired to write?

I mostly do technical writing and my blog is a sort of lab log. It's usually clear what to write about and inspiration is rarely involved. In general I write when I complete a project, am stuck with a technical issue, or I just want to record the progress and experience with a project or something I do.

Do you normally publish immediately after writing, or do you let it simmer a bit?

I never publish immediately. I'm a slow writer and do lots of editing rounds, especially as a non native English speaker. Letting it simmer improves the final result.

What’s your favorite post on your blog?

My favorite is My encounter with Medley Interlisp, which captured my exhilaration at approaching and exploring Medley Interlisp. I was beginning to dive deep into this 1980s Lisp workstation environment I had always dreamed of, and blogging the experience seemd a natural way of sharing my excitement and explaining what's unique about Medley.

This is apparently also the favorite post of my readers. It's the most visited of the blog and received over 38K views, most of which when it was shared on Hacker News.

Any future plans for the blog?

No, which is a feature. Everything is going so smoothly I just want to continue blogging without worrying about tools and platforms.

Who's next?

I nominate Fabrizio Ferri Benedetti, Kevin Tofel, and Rob Roland. I hope they will accept as they have interesting blogs and diverse stories.

#blogging

Discuss... Email | Reply @amoroso@fosstodon.org

I wrote Interpinkie, a basic Finger client in Interlisp that runs on the Medley environment. This is the main window of the program:

Main window of the Interpinkie Interlisp Finger client.

It was a fun challenge considering I couldn't use Medley's TCP/IP stack.

I always wanted to do some network programming with Medley. But the bitrot of its TCP/IP stack left it in a non working state since before the Medley Interlisp project, and the revival effort hasn't got around to the stack yet. The XNS stack still mostly works with the Dodo Services XNS implementation. But, as far as I know, XNS provides LAN services and I'm not sure whether or how it allows access to the outside Internet.

So I cheated and reached for Medley's escape hatch.

As part of the Medley modernization effort, the UNIXUTILS library module provides the ShellCommand function to run a Unix program on the host operating system and send the output to a stream. Since I can run arbitrary Unix commands from Medley, it's trivial to build a client that talks the Finger protocol via Netcat.

For example, to run the Finger query amoroso@happynetbox.com I can just execute this from the Linux shell:

$ echo "amoroso" | nc -C -w 3 happynetbox.com finger

where -C sends \r\n as line-ending, -w 3 sets a timeout of 3 seconds, and finger is the Finger port number as per /etc/services.

All Interpinkie does is to build and feed a query to ShellCommand, pipe the output through tr to remove extra \rs, and redirect the output to a suitable destination.

The Interlisp function QUERY.FINGER.SERVER wraps this functionality. By default the output goes to the primary output (Interlisp jargon for stdout), or optionally to a separate window with menu options for running another Finger query or quitting the program.

Interpinkie builds upon user interface techniques I used in previous projects such as attaching a menu to a TEdit window.

TEdit, the WYSIWYG the rich text editor of Medley, can be driven by other programs that send output to the editor buffer. This is handy as the programs get an automatically repainted scrollable window for free from TEdit. In addition, Interpinkie attaches a command menu to the TEdit window and uses TEdit's prompt window (Interlisp jargon for an edit field and status area) to request input and display errors.

Unlike my previous Interlisp projects, however, Interpinkie doesn't call the TEdit API to insert text in the buffer. Instead, the program redirects the ShellCommand output to the Lisp stream associated with the TEdit window, causing the text to appear in the buffer.

By default ordinary Lisp printing functions such as PRIN1 and PRINT send the output to the REPL or optionally to another Lisp I/O stream. Along with these output destinations, some Interlisp components and programs like TEdit have an associated stream. So it's easy to send output to TEdit by just printing to the stream returned by (TEXTSTREAM Window), where Window is a TEdit window, or redirecting to that stream the output of printing functions like PRIN1. In other words, ordinary stream I/O is the API.

Since ShellCommand accepts a stream as an optional argument, QUERY.FINGER.SERVER passes TEdit's stream to ShellCommand thus causing the output to go to the editor buffer. The benefit is Interpinkie uses the same QUERY.FINGER.SERVER function to output to both the primary output and a TEdit window.

If the destination is a window Interpinkie does some additional processing before and after sending the output. For example, before doing output the program updates the window title to reflect the Finger query, and sets the TEdit buffer to read-only once the output finishes.

These days there are not many Finger servers and I was lucky to stumble upon happynetbox.com. It is managed by Happy Net Box, a nice public Finger server anyone can sign up to for for free and publish a status file. Happy Nex Box was essential for developing and testing Interpinkie, as well as fun — and addictive — as you can see by running the query random@happynetbox.com to look up a random user.

#Interpinkie #Interlisp #Lisp

Discuss... Email | Reply @amoroso@fosstodon.org

For Chrismtas 2024 I bought myself a lovely little Cardputer uLisp Machine, an M5Stack Cardputer that can run uLisp.

The M5Stack Cardputer is a card-sized, microcontroller-based portable system for home automation, hobby, and industrial applications. Although not designed for Lisp the Cardputer can run uLisp, an implementation optimized for microcontrollers. This is my unit:

Cardputer uLisp Machine card-sized microcontroller-based computer.

The uLisp system provides a capable Lisp implementation, a rich anvironment, debugging and editing tools, and lots of libraries and examples. It's well maintained and has an active user community.

Motivation

Like many Lispers I always wanted to play with Lisp on the bare metal and the Cardputer uLisp Machine is a simple and inexpensive solution.

uLisp runs on a wide variety of microcontrollers and boards. I picked the ESP32-S3 based Cardputer because it's compact, can run off rechargeable batteries or USB without an external power source, and comes with a graphics display. And at $29.90 it was a no brainer.

Hardware

The Cardputer is a self-contained device with a keyboard, a 240x135 color TFT display, a USB-C port, and a microSD card slot.

Despite the minuscle keyboard, if I hold the Cardputer with both hands I can accurately press any key with my thumbs. However, the keys are very sensitive to pressure and if I hit one with slightly more force than needed I end up repeatedly typing the same character. Entering code and expressions with the built-in keyboard isn't practical for anything longer than a line or two.

The stamp sized display is tiny too but my new eyes help me read the microscopic text on it.

Software

The first thing I did was to install the uLisp firmware to replace the stock system software. The installation procedure is straightforward, took a few minutes, and required only the Arduino IDE which I run on Linux.

There are two main ways of interacting with uLisp. The first is to access the REPL using the Cardputer keyboard and display, the other is to connect from a desktop computer over a USB serial line via the Arduino Serial Monitor or a terminal emulator such as GNU Screen or Minicom. There is also experimental user contributed code for accessing uLisp from Emacs via an inferior Lisp mode or Swank.

A limitation of interacting over USB is that sending code blocks longer than 256 characters overflows the serial buffer, which results in a string of error messages due to the dropped characters.

A workaround is to preceed the code with a comment line starting with a semicolon ; which temporarily turns off echo mode on the device and prevents it from being overwhelmed. Lisp mode on Emacs has no support for the workaround though. So the extra comment line needs to be manually copied from the source buffer and pasted into the inferior REPL along with the code, instead of executing commands such as eval-defun or C-M-x. This introduces friction in the rapid cycles of REPL and editor interactions Lispers are used to.

A showstopper

The limitations of interacting with the Cardputer over serial are just inconveniences that may be fixed by improving existing tools. But a showstopper forces me to set the Cardputer aside until a major Arduino core issue is resolved.

The Cardputer's ESP32-S3 native USB manages the serial port via software and currently has a nasty bug: if the receive buffer fills up too fast the ESP32-S3 will crash and disconnect. I can't do anything practical with the Cardputer without reliably sending medium or large Lisp code blocks to uLisp for evaluation.

The uLisp website does warn about the issue but I incorrectly assumed it affected the Cardputer only when connected to Macs, whereas I use Linux.

Only the Arduino team can fix this issue not caused by uLisp. But since it has been known for a couple of years I’m not holding my breath.

#Cardputer #Lisp

Discuss... Email | Reply @amoroso@fosstodon.org

I always preferred the light theme and never figured what's the fuss with the dark theme. Until cataract came.

In May of 2024 my ophthalmologist confirmed what I surmised: both of my eyes were affected by cataract. It came earlier than my age would suggest but that's apparently not unusual.

I realized something was off when I noticed everything looked blurry, faded, and washed out as if seen through glass coated with yellowish dirt. The view was often immersed in more glare than the lighting conditions would imply. My old prescription glasses not only didn't help, they made things worse. What surprised and initially worried me were the occasional changes in the intensity of the blurriness and fading, which took place over the course of days whereas eyesight usually changes over years.

My ophthalmologist scheduled cataract operations for mid November and mid December of 2024. The only thing I could do was wait. But I faced the challenge of reading computer and mobile screens through such an unpleasant filter.

My daily driver is a Linux PC on the desktop and a Pixel 7 Pro phone on mobile. On the computer screen most text of websites or Linux programs was hardly legible with the light theme. The beautiful designs of some light theme sites featuring subtle shades, low contrast, or small fonts made reading a nightmare. Coming close to the screen and bending in search of an angle that could help make out something left my back aching in the evening.

Surprisingly to me, the dark theme improved legibility. I set the dark theme everywhere I could: in Linux programs; in Forefox; and on the websites that offered a choice.

The worst experience came from Gmail on the web. Its dark theme is a cruel joke as it doesn't affect the body of email messages, which is what I spend the most time reading. Invert Colors, an open source Firefox add-on that inverts the colors of any web page at the press of a keychord, tamed Gmail and made message bodies bearable. Thanks Max!

The legibility of text was initially less of an issue with the light theme on mobile. I still had to increase the font size one notch larger than the default in the Android system settings. And I eventually had to turn on dark mode too.

In the fall of 2024 the cataract surgeries finally came and I could see the world with new eyes, literally.

The detail, sharpness, and depth my eyes now deliver make the view almost hyperreal. For example, since the left eye gained a visual acuity of 20/20 I can read tiny text, whereas the same eye always struggled to read newspaper and magazine headlines, barely. Even my ophthalmologist couldn't believe it.

It's been a few days since the second cataract operation and I finally stowed my glasses in a drawer for good, restored the light theme on all devices, uninstalled Invert Colors, and set the font size back to the default on the phone. But I see the light about the dark theme.

Christmas is days away and this is the best present I could ever hope for. Cataract surgery is an underrated miracle of medicine.

#personal

Discuss... Email | Reply @amoroso@fosstodon.org

Ten years ago today my astronaut friend Samantha Cristoforetti began her first space flight. On November 23, 2014 she was launched aboard the Soyuz TMA-15M spacecraft for a mission to the International Space Station.

I had the privilege of helping Samantha with a public outreach project to share this adventure.

Shortly after the announcement of her mission in early July of 2013, Samantha decided on a way to tell the experience as it happened and engage the public. She wrote the Logbook, a diary to document the last 500 days of the mission training and her stay on the ISS. From July 19, 2013 to September 10, 2015 Samantha posted to Google+ more or less daily entries from the ground and in space. These long form entries in English reported on her training and life aborad the ISS and often attached some photos.

Since the beginning I provided the official Italian translation of the Logbook published on AstronautiNEWS, the news site of the space outreach organization I'm a member of.

The Italian news outlets and media that covered the mission soon began quoting or referencing my translations to inform the public of Samantha's home country. ESA later republished the translations to Avamposto42, the official website of the mission. Other space enthusiasts eventually translated the English entries into French, Spanish, German, and Russian.

Contributing to the project was an adventure for me too.

My daily routine involved waiting for Samantha to post to Google+, translating, and publishing a new entry to AstronautiNEWS as soon as possible for dissemination to the press and public. Translating rocket science terms was mostly easy, the hard part was conveying words and expressions from domains unfamiliar to me such as physical exercise and equipment.

The Logbook is a unique resource. It's the most extensive series of candid written thoughts on preparing for and carrying out a space flight, published as the events unfolded. As far as I know the L-0 entry, posted less than a day from launch, is the only written account of the thoughts and emotions of an astronaut published just hours from launch.

Google+ was shut down in 2019 but the Logbook is not lost.

Carlo Gandolfi archived the text and photos of all the original Google+ posts and published the Logbook as a free ebook. Another free ebook collects my Italian translation of the Logbook.

#space

Discuss... Email | Reply @amoroso@fosstodon.org

Enter your email to subscribe to updates.