December Adventure 2025
The Advent of Code is cool, but a lot, and not everyone's jam.
The December Adventure is low key. The goal is to write a little bit of code every day in December.
...doesn't even really have to be code! Let the December Adventure be for all kinds of creative pursuits.
This is my third year (see 2023 and 2024)
doing this. Be sure to check out the full list of adventure logs from other participients at
https://eli.li/december-adventure.
DecAdv2025 2025.12.01 ==========================================
It's time to start a new December Adventure. I'll be focusing on
my Forth systems again. I don't have a planned out set of tasks,
so this will probably be a variety of things as the month progr-
esses.
I started today by setting up a script to extract my logs from
my blocks and generate a basic index.html and plain text copy.
To begin this year's projects, I am starting with a few new ilo
implementations. My initial targets are Pascal and Ada.
I've set up compilers (fpc, gnat) for these on a Linux system,
and created skeletons with the basic function definitions, along
the same organization as I did in C.
For the Pascal, I have some advantages; I've used Pascal in the
past, so have some familiarity with it, and I can look at Rob
Judd's nga implementation in Pascal if I get stuck. (Though I do
not plan to use that as a starting point).
Much of this has just been reading the FPC documentation; the
actual implementation is pretty straightforward. I've put a copy
of the source at charles.childe.rs/DA2025/ilo.pas and added it
to the fossil repository.
It's probably closer in spirit to a C program than a Pascal one,
but I can improve that later. Tomorrow I'll start on the Ada
implementation. I expect that to be more difficult.
DecAdv2025 2025.12.02 ==========================================
For the second day, I started work on an Ada implementation of
ilo. I'm using GNU Ada (gnat) for this.
I started with the Pascal version from yesterday. First, redoing
the variable declarations & function declaration syntax. Then
reading documentation and translating each function.
I found some difficulty in the i/o parts. At this point, I have
it supporting the keyboard (mostly) and display, and reading
blocks. The keyboard has an issue with handling of newlines, but
I think I know how to fix that. For writing blocks, I should be
able to get that working tomorrow.
As a final bit of work on the new Ada version, I've added range
checks to help the system handle errors better. I'll backport
these to the Pascal version later.
I might try to do an Oberon-7 version of ilo as well.
DecAdv2025 2025.12.03 ==========================================
Getting the keyboard input fixed wasn't a problem after a more
careful look at the documentation on Ada.Text_IO, so I can now
enter code properly.
The block writing code is also finished now, so I can edit my
blocks, making this fully usable port.
I backported the range & error checks to the pascal version.
I had a long, sleepless night, so am stopping my programming for
today. I will continue down the path of languages from Wirth
tomorrow with an ilo implementation in Oberon. I have setup a
compiler for this, and have a copy of the language documentation
to read later today.
DecAdv2025 2025.12.04 ==========================================
The Oberon implementation went smoothly. It's (as expected) very
similar to the Pascal and Ada versions. Most of my time on this
was prototyping different ways to deal with reading/writing the
blocks & rom.
I considered doing a Modula-2 version, but am a little bored
with the Wirth langauges, so I'll put that aside for now and
start on something different tomorrow. Maybe Smalltalk?
I pushed the code for this to the Fossil repository.
The Oberon version works under obnc (https://miasap.se/obnc/). I
tried building under Vishap, but this didn't work (maybe type
related issues?). I'll look more into that later.
This gives me three new implementations of ilo in the Wirth fam-
ily of langages. I'm not doing Modula-2 for now, so will turn my
attention towards one more: Smalltalk.
I'll be using GNU Smalltalk for this. I built the system today,
and have done a few tests in reading the rom & blocks, so I am
estimating that it'll only take a day or two to complete, if my
RSI pain remains at a level I can tolerate.
Looking a bit more forward, I think I'll be stepping back into
RetroForth next week, to work on a big set of changes in how the
initial image is built & how the dictionary headers are structu-
red. This has been on my todo list for a very long time, so I
think it'll be a good task for the continuing adventure.
DecAdv2025 2025.12.05 ==========================================
Day 5 has been about SmallTalk. Specifically, I ported the ilo
vm code into (not very idiomatic) GNU Smalltalk. It's functional
but doesn't feel right yet. I committed it to the repository,
and will likely revisit it later to make improvements.
I think the major things to do when I revisit this will be
refactoring, trying to eliminate the opcode switch, and adding
in some bounds checking.
With this done, ilo has been implemented in 25 languages. I have
a couple more I want to try to do (f#, ocaml, i386 assembly,
risc-v assembly), but those will need to wait. Maybe I'll get
to work on some of them before this year's adventure is over.
I've also done some work on the ilo spec document. This isn't in
the repository yet, but will be uploaded over the weekend. It's
mainly just clarifications around a few areas, no functionality
changes.
Tomorrow it's on to RetroForth, starting a number of changes
which should make it easier for me to continue evolving it.
I may have transitioned to using Konilo for most of my small,
day to day tasks, but RetroForth remain essential as a lot of
my personal unix tools are written in it.
DecAdv2025 2025.12.06 ==========================================
Today I turned my attention towards RetroForth. Over the years,
the implementaion and build process have grown fairly complex,
and after a couple of years working with a much more constrained
system, I'd like to make some improvements.
I started by setting up a directory for this work, with a copy
of the assembler, the minimal nga vm, and the basic image code.
My initial goal in this is to drop the need for retro-extend. I
currently build a minimal image from assembly, then use a tool
which embeds the nga vm, knowledge of the dictionary structure
to locate the interpreter/compiler words, and then uses these to
process forth code.
The basic image does not include any i/o functionality, and does
not have a full interpreter loop. Those are added in the higher
level code.
So what I'm doing now is translating enough of the higher level
code into assembly to allow the essential interpreter be part of
the initial image. I can then pass in the higher level code and
save the image from within the system.
I'll then be doing a deeper evaluation of what's in the initial
image, and deciding how to move things around. I'd like the base
image to be closer to Konilo in functionality (being a small,
but functionally complete system), rather than the very sparse
model it currently has.
For today, I have the working tree set up, a separate repo for
my work on this, and have begun implementing the listener.
I didn't actually get much code written today, partly due to
some RSI pain, and partly due to a bad headache, but I'm happy
to have started this, and will be working on my design notes as
the rest of the day progresses.
DecAdv2025 2025.12.07 ==========================================
Not a lot of headway today. I have begun translating some of the
words used by the i/o and strings into assembly. Today's work
included the indexed-times combinator, a few variable words, and
the core two terminal i/o words.
Tomorrow I should be able to get a larger chunk of this done,
hopefully the rest of the flow control combinators and the start
of the string vocabulary.
I will also add a new directive to muri to help create diction-
ary headers (based on what I do in pali).
DecAdv2025 2025.12.08 ==========================================
I began today by adding several directives to the muri assembler
These are specifically the `o` to set the offset in memory, `*`
to reserve space, and `D` to build an initial dictionary. I then
updated the retro.muri source to use the new `D` directive.
I finished the `indexed-times`, `times`, `while`, `until`, and
`forever` combinators.
With this done, I now have some input capability working. It'll
still be a lot more work to get the full listener up, but I'm at
a good place to stop for today.
I have a bit more time free, so I decided to write a couple of
little tools to generate samples from my bitmap font files.
These have been uploaded to charles.childe.rs
I'm spending my evening reading and preparing a new campaign for
an upcoming TTRPG session.
DecAdv2025 2025.12.09 ==========================================
I decided to take a quick diversion from the Forth projects to
address part of my gopher stack. My search database & tool
(contrition) hasn't been working reliably for a while, and I'd
like to resolve that.
The original system kept all of the search data in a single
(very large) sqlite3 database. This has proven slow for updates,
and troublesome to restructure. In addition, my tool for crawls
of the gopherspace was quite inefficient, and had issues with
proper handling of robots.txt. I had suspended scans using it as
a result.
So I'm going to rebuild. I had made some plans for this a couple
of years back, but RSI issues lead to me delaying them.
So I've put together a new crawler. I'm testing this in small
steps, mainly against my own servers. It's working well in the
test setup, so I'll likely do a wider scan in the near future.
The new crawler, in addition to respecting robots.txt, takes
care to avoid duplicate entries for known selectors, supports
an adaptive rate limiting mode, and tracks when a server was
last crawled, to reduce repeated hits. It also lets me limit
the depth of menus it traverses.
It's fun to be working on gopher related stuff again. I've not
done anything new for a while (and not really felt much need,
since other than this, my other gopher projects are all still
working without issue).
I'll be switching back to RetroForth development tomorrow, but
will spend a few days on this as the adventure continues. I'd
like to get Contrition back online before January.
As a note for those curious, the new crawler is written in
Python, I'm still planning to do the actual Gopher server part
in RetroForth.
DecAdv2025 2025.12.10 ==========================================
We're roughly a third of the way through the December Adventure
today.
I continued working on the translation of RetroForth's higher
level code into assembly, which went pretty well. I didn't get
as far on this as I'd like since today is going to be a long,
busy day at work, but it's a bit closer to done.
I also continued with my scan of gopherspace. I've now crawled
236 servers, have mentions of a total of 904, and found 53 that
are unreachable currently. It's identified 764k selectors, with
4.1 million descriptions.
DecAdv2025 2025.12.11 ==========================================
I started by trying to get a remotely accessable wayland setup,
but this didn't work out, so I'm back to just using good old X11
instead.
I decided to do a bit of work on ilo-x, trying to improve the
display performance. The original implementation was very slow;
looking at the code more closely, this was partially due to an
excessive number of XFlush and XDrawPoint calls. There were also
some design issues that lead to needed repaints, which greatly
impacted the performance.
The changes made to fix this included adding a dirty flag for
helping to track when a repaint is actually needed, and use of
XCopyArea instead of a manual redraw when scrolling.
I also added a backing buffer for off-screen rendering, which
seems to help a little. The overall performance improvement is
very noticeable.
I also ported the changes into the mult/ilo-x system. For m/ilo
the original system had a single screen buffer. The new one has
a separate buffer for each display. There's one lingering issue
with m/ilo, which is that a space is added to the input stream
when switching sessions. I'll look into that later; for now it's
a minor annoyance.
Other than this, my scans of the gopherspace are continuing. I
will post an update on this tomorrow or Saturday I think.
DecAdv2025 2025.12.12 ==========================================
Thanks to some helpful feedback last night, I was able to get a
wayland (weston + rdp) configuration working, so today's goal is
to try to complete an ilo-wayland. (I had started writing code
for this in the past, but without a working wayland had no way
to test it).
My initial code had a number of issues, which I was able to find
and fix with use of gdb and some trial & error. I've managed to
get it operational, though it doesn't show any window chrome. (I
did figure out enough to use CSD to allow movement of the window
though).
I found programming for Wayland to be more annoying than the X11
version. I'll do more with this in the future (esp. as it seems
this will be needed for Linux going forward), but I'll probably
grumble about it a bit as I do so.
With that done, I'm going to do one more day on related bits of
this. There's a Windows version of ilo (ilo+graphica.cs) which
also needs updates to improve the performance, similar to what I
did for X11 yesterday. I'll probably do that tomorrow.
DecAdv2025 2025.12.13 ==========================================
I went for an easy day. I updated ilo+graphica.cs for windows to
include the improvements from ilo-x.
The rest of the day was walking outside, reading, and enjoying a
variety of tea and coffee.
DecAdv2025 2025.12.14 ==========================================
I decided to do something a bit different today. I'm stuck using
Windows 11 at work, and I dislike it. So I'll start writing new
implementations of a few old tools. (Not all at once). Starting
with something akin to the Windows 3.x "Program Manager".
For this, I'm using C#, with the toolchain included with the
.NET runtime in Windows.
Today's work was working out a batch file to build my sources,
deciding on the overall structure, and starting to write parts
of the code. Mainly I achieved opening a window, the menu bar,
and creation of empty groups.
DecAdv2025 2025.12.15 ==========================================
I continued on the Program Manager today. Today I was able to
get it usable. I can create or remove items in groups and run
them.
I decided to use JSON for the program manager configuration. An
ini-style format might be more correct for the period, but being
lazy, it seemed to make sense to use JSON here instead of taking
more time to write an ini parser.
The entire project is about 1200 lines of code, in pure C#.
http://fossils.retroforth.org:8000/wintools/
DecAdv2025 2025.12.16 ==========================================
I decided to write a small system monitor rom for ilo. This is
somewhat useful as an aid in testing a new ilo implementation,
and also as a tool for bringing up a larger system like Konilo
from disk.
I've finished about half of this. When done it'll provide the
following: entry of values, display of values, calling code,
writing to the block store, reading from the block store.
I'll also provide some examples of using it.
In an unrelated bit, I drafted a set of single stroke glyphs
to represent the ilo instruction set, for hndwritten use. This
is purely for fun, I've published a photo of this to
http://charles.childe.rs/DA2025/day16.png
DecAdv2025 2025.12.17 ==========================================
Due to RSI pain increasing, I only did a little today. I wrote a
short function to display numbers for the ilo monitor rom. This
was written by hand, using my new notation form from yesterday.
https://charles.childe.rs/DA2025/day17.png for the handwritten
code.