VTL-2: golfing and preservation

I’ve been playing with Gary Shannon and Frank McCoy’s minimalist programming language from the ‘70s, VTL-2 PDF as of late. Written for the Altair 8800 and 680 machines, it was designed around being very small – the interpreter takes 768 bytes in ROM. It has quite a few tricks for staying lean: it assumes the programmer knows what they’re doing and therefore offers no errors, it uses system variables in lieu of many standard commands, and it requires that the results of expressions be assigned to variables. It is in some ways terse, and its quirks evoke a lot of the fun of the constrained languages of yore. So, I’ve been playing with it to come up with some solutions for challenges on Programming Puzzles and Code Golf Stack Exchange (PPCG)1.

I mentioned that it is in some ways terse, and this is a sticking point for code golf. VTL-2 is a line-numbered language, and lines are rather expensive in terms of byte count. Without factoring in any commands, any given line requires 4 bytes: (always) two for the line number, a mandatory space after the line number, and a mandatory CR at the end of the line. So, at a minimum, a line takes 5 bytes. This became obvious when golfing a recent challenge:

3 B=('/A)*0+%+1

saved a byte over

3 B='/A
4 B=%+1

These almost certainly look nonsensical, and that is largely because of two of the things I mentioned above: the result of an expression always needs to be assigned to a variable, and a lot of things are handled via system variables instead of commands. For example, ' in the code above is a system variable containing a random number. There is no modulo nor remainder command, rather % is a system variable containing the remainder of the last division operation. Thus originally, I thought I had to do a division and then grab that variable on the next line. As long as the division is performed, however, I can just destroy the result (*0) and add the mod variable, making it a single shot. It’s a waste of our poor Altair’s CPU cycles, but I’m simulating that on modern x64 hardware anyway. And despite the extra characters, it still saves a byte2.

Other notable system variables include ? for input and output:

1 A=?
2 ?="Hello, world! You typed "
3 ?=A

Line 1 takes input – it assigns variable A to the I/O variable, ?. Line 2 prints “Hello, world! You typed &rquo;, and then line 3 prints the contents of variable A. Lines 2 and 3 assign values to the I/O variable. The system variable # handles line numbers. When assigned to another variable (I=#), it simply returns the current line number. When given an assignment (#=20), it’s akin to a GOTO. The former behavior seems like it could come in handy for golf: if you need to assign an initial value to a variable anyway, you’re going to be spending 4 bytes on the line for it. Therefore, it may come in handy to, say, initialize a counter by using its line number: 32 I=#.

Evaluation happens left-to-right, with functional parentheses. Conditionals always evaluate to a 1 for true and a 0 for false. Assigning the line number variable to a 0 in this way is ignored. With that in mind, we can say IF A==25 GOTO 100 with the assignment #=A=25*100. A=25 is evaluated to a 1 or a 0 first, and this is multiplied by 100 and # is assigned accordingly. ! contains the last line that executed a #= plus 1, and therefore #=! is effectively a RETURN.

There’s obviously more to the language, which I may get into in a future post3. Outside of the syntactical quirks which make it interesting for hobbyist coding, the matter of running the thing makes it less than ideal for programming challenges. Generally speaking, challenges on PPCG only require that a valid interpreter exists, not that one exists in an online interpreter environment such as Try It Online (TIO). In order to futz around in VTL-2, I’m running a MITS Altair 8800 emulator and loading the VTL-2 ROM. TIO, notably, doesn’t include emulation of a machine from the ‘70s with a bundle of obscure programming language ROMs on the side.

This brings me to my final point: how much effort is being put into preserving the lesser-known programming languages of yore, and how much should be? I personally think there’s a lot of value in it. I’ve become so smitten with VTL-2 because it is a beautiful piece of art and a brilliant piece of engineering. Many languages of that era were, by the necessity of balancing ROM/RAM limitations with functionality and ease of use. Yet, there’s no practical reason to run VTL-2 today. It’s hard to even justify the practicality of programming in dc, despite its continued existence and its inclusion a requirement for POSIX-compliance. New esoteric languages pop up all the time, often for golfing or for sheer novelty, yet little to no effort seems to be out there to preserve the experimental languages of yesteryear. We’re seeing discussions on how streaming gaming platforms will affect preservation, we have archive.org hosting a ton of web-based emulators and ROMs, we have hardware like Applesauce allowing for absolutely precise copies to be made of Apple II diskettes. Yet we’re simply letting retro languages… languish.

To be clear, I don’t think that this sort of preservation is akin to protecting dying human languages. But I do think these forgotten relics are worth saving. Is “Hello, world!” enough? An archive of documentation? An interpreter that runs on an emulator of a machine from 1975? I don’t know. I don’t feel like I have the authority to make that call. But I do think we’re losing a lot of history, and we don’t even know it.

  1. Without littering the post, here’s Hello, World!, Simulating Exploding Dice, Print every character your program doesn’t have, Implement a Truth-Machine, and Capitalize first letter of each word of input. ↩︎
  2. I realized after making this edit that the parentheses were unnecessary as well. I left them in here to show that even with those two extraneous bytes, the single line was golfier. ↩︎
  3. One thing that I couldn’t quite figure out how to fit elsewhere: & is the last byte of the program, so ?=& before and after entering a program should make byte counting simple. ↩︎

The unsettling meows of a Garf

This post is about the 2007 Nintendo DS game, Garfield’s Nightmare. While it would not be terribly off-brand for me to review a 12 year old video game based on a syndicated comic strip, I don’t really plan to do that. Because honestly, there isn’t much to review. It’s a serviceable platformer with very little in the way of challenge. There are some hidden things can find, some very lightweight box-moving challenges, some enemies to stomp on. It’s a simple game, and, you know… it’s fine.

Gameplay is actually extremely similar to the developer’s earlier GBA games based on the Maya the Bee franchise: Maya the Bee: The Great Adventure and Maya the Bee: Sweet Gold. The developer in question is Shin’en Multimedia, a studio made up of – I shit you not – a bunch of current and former demosceners. This makes more sense when you look at, say, their first GBA game, Iridion 3D which is incredibly impressive from a technical standpoint, or even their recent F-Zero-esque Wii U/Switch title, Fast Racing Neo/Fast RMX. Aside from demos, the Abyss1 group dabbled in games early on with Rise of the Rabbits and Rise of the Rabbits 2 – both, of course, for the Amiga. They developed Rinkapink for the GBC. While it doesn’t appear to have ever been published2, it seems they used bits of it for Ravensburger’s Käpt’n Blaubärs verrückte Schatzsuche. A promotional brochure for Rinkapink seems to be selling their demoscene experience as a company that can avoid “bad programming, flickering graphics, and awful music”, which… makes a lot of sense! You don’t win at demo parties without knowing how to make the most of a given system. Abyss was and is particularly known for its music, at the time largely done by Manfred Linzner, the lead programmer on Iridion 3D, Maya the Bee: Sweet Gold, and, yes, Garfield’s Nightmare. They developed trackers and audio toolchains for the Amiga (AHX) and Gameboy (GHX). They’re still releasing audio demos.

What does any of this really have to do with Garfield’s Nightmare? Likely not much, but it sure is fascinating. If anything I think it explains how technically competent this game is while also being a pretty sub-par Garfield experience. Which brings me to something that I highly doubt was intentional and can only imagine was a byproduct of a team of highly-skilled demosceners having agreed to take on a licensed title about a syndicated comic strip cat: Garfield’s Nightmare is actually fairly nightmarish. Not in a blatantly scary, horrorish way, but rather in its completely disquieting approach to what Garfield’s world is. The basic premise is that Garfield ate too much (shocker) before going to bed, and is now stuck in his own nightmare. But throughout the game, he really doesn’t seem concerned himself. Either he has good enough lucid dream control abilities to will himself into perfect calmness, or else he’s just oddly resigned to being in this nightmare world that he is, of course, ostensibly trying to escape. It doesn’t make any sense, and the disconnect that it presents as perfectly normal is more and more discomforting the more one thinks about it.

This isn’t the only weird disconnect. Aside from spiders (which Garfield does canonically hate)3, none of the enemies are things that bother canon Garfield, or even things that exist in his world as we know it. They seem like entirely generic platformer enemies (for instance, turtle thing with a cannon built into its back) yet they’re in a very specific licensed setting. I’m sure the studio just didn’t want to cough up the handful of dollars to license a sound bite or two of Lorenzo Music’s voice, but Garfield meows when he gets injured in this game. It shouldn’t be unsettling to hear a cat meow, but I assure you it is extremely so to hear what sounds like a sample of a real live cat coming out of Garfield. There’s no lasagna in sight; pizza stands in for health points and donuts are akin to coins. There are hidden doors that lead to brief minigame reprieves in the real world, but this version of the real world is cold and empty, it feels like the Garfield who is in the nightmare has himself fallen asleep and is experiencing a nightmare version of the real world. Even the box-moving puzzles feel planned and placed, which… Obviously they were, by Peter Weiss of Shin’en, but it makes the nightmare feel like an escape room situation that someone has built for the sole purpose of torturing Garfield. On the surface it’s almost certainly just a bunch of half-hearted design decisions, but it adds up and makes for an unnerving, uncanny experience.

So, should you play the game? I don’t know. I mean you can grab one on eBay for like six bucks, and if you let your mind really take in the nightmare world, it’s… weird. It’s fascinating to think about how the developers, active demosceners, got into the DS development program and got shit on for making a Santa Claus demo that they couldn’t link to because of licensing violations months before releasing this oddity. Everything about Garfield’s Nightmare is just weird, and that in itself is worth quite a few donuts to me.

  1. While it takes a bit of digging, the connection between Abyss and Shin’en is readily available. See this retrospective on demosceners gone professional, for example. Manfred Linzner, AKA Pink is credited as the programmer and sound effects designer for Garfield’s Nightmare. Florian Freisleder (Wintermute) and Martin Sauter (Fade1 of TRSI) are credited with graphics. Bernhard Wodok (Bartman) is credited with tools programming. ↩︎
  2. It was, apparently playable enough to win 3rd place at the 2002 Mekka & Symposium console demo competition. ↩︎
  3. Spiders in Garfield’s Nightmare do have 6 legs, which is oddly true to the strip. ↩︎

VT100 Line Drawing

One of those totally useful1 things that crosses my mind occasionally is recompiling a version of dc that won’t choke on characters above code point 127. Among other reasons, occasionally code golf questions come up that really want box drawing characters used for some reason, and it just isn’t possible in dc. Except, I got to thinking… it absolutely is on a VT100, and xterm supports the same escape codes. I just haven’t really explored them. By moving into the “DEC Special Character and Line Drawing Set”, printing the characters in the 96-126 range (127 is still DEL) yields:

`: ♦      a: ▒      b: →      c: ƒ
d: r      e: ↴      f: °      g: ±
h: ↴      i: ↓      j: ┘      k: ┐
l: ┌      m: └      n: ┼      o: ⎺
p: ⎻      q: ─      r: ⎼      s: ⎽
t: ├      u: ┤      v: ┴      w: ┬
x: │      y: ≤      z: ≥      {: π
|: ≠      }: £      ~: ·

The above table was generated in dc with the following code:

96[AP]sF[ddP[: ]P27P[(0]PP27P[(B      ]P1+dd4%0=F127>M]dsMx

To switch character sets, we just need to send the appropriate escape code: 27P[(0]P to switch to the special characters, and 27P[(B]P to switch back2. ASCII code 27 (decimal) is ESC. ( is the escape code to ‘Designate G0 Character Set (ISO 2022)’, and 0 and B are the graphics set and ASCII set respectively.

Aside from not being super useful, it’s also not very golfy. There is one more trick that can be used to cut down on code if we’re going to be switching back and forth a lot: Shift Out (ASCII 14) and Shift In (ASCII 15). Shifting out switches us to the G1 character set; shifting in switches us back to G0. We can reassign G1 instead of G0 by using ) instead of (, so, 27P[(0]P. Then when we need to switch to the special characters, we shift out with 14P and back in with 15P.

  1. This is a lie, and we all both know it. ↩︎
  2. (B is the code for US ASCII, UK should be (A. I haven’t looked through the DEC tables to see what the difference is, nor do I know if modern terminal emulators in a UK locale operate under this character set by default. ↩︎


My ‘daily driver’ USB drive gave up the ghost recently, and after having secured a replacement1, it was time for the always-fun task of formatting. I could’ve left things as-is, but the stock partition was FAT32 with 32K block allocations. While not the end of the world, I was really hoping to set the new drive up with smaller block allocations. The previous drive was partitioned with 32K allocations, which wasn’t ideal given that I tend to keep a lot of small files around. To make a point, the largest of my blog posts is the colorful release of decolletage.vim at a whopping 12K. The directory for my blog (including all templates, server logs, boring behind-the-scenes stuff) is under 25MB, yet consumed over 90MB on the drive. This is a trivial, petty thing to be bothered by when dealing with today’s drive sizes, but it bugged me, and I was hoping to get smaller blocks on my next drive. I also wanted to stick with FAT32 as the 4GB file size limitation is meaningless to me, and exFAT just isn’t as widely supported. As far as I know, FUSE is still the only way to get exFAT support in Linux, and, well… ew. Here were my initial attempts:

Windows 10 Format Utility
Won’t do FAT32 on a 64GB drive.
CMD/DOS2 format Utility (under Windows 10)
Also won’t do FAT32 on a 64GB drive. Of course, before it gets around to yelling at you for that it yells at you for choosing too small of an allocation size. Though I think it let me get to 16K before saying no to FAT32.
This is a neat little utility that will allow you to format large FAT32 volumes under modern versions of Windows. It will also seamlessly make the drive bootable into FreeDOS if you’d like, which is a nice perk. The lowest allocation size it seems to support is 16K, which isn’t ideal but I might’ve stuck with it just to be done. However, when I tried this, it actually formatted it with 32K blocks anyway.
macOS Disk Utility
Didn’t seem to want to do a drive of that size in FAT32.
macOS diskutil
I’m pretty sure you can force a FAT32 drive this way, but nothing in the manpages indicated that there was any way to adjust the allocation size (nor what the default was).
Seemingly no way to set allocation size. GParted, particularly in its live USB stick incarnation, is an incredibly useful tool though.
GParted’s CLI pal. I started flipping through the manpages and realized that using it as a one-stop shop to handle partitioning and filesystem creation is discouraged, and didn’t get around to finding out whether or not adjusting allocation size was even a possibility. Didn’t seem worth it.

So, this was discouraging. I figured I’d try one last-ditch effort, fussing around with tools I haven’t touched for… likely a decade: fdisk and mkfs. parted was essentially asking me to do the same thing – start with it and finish off with mkfs, and that may have been a smoother, less arcane process. I mean, starting up fdisk greets you with

Command (m for help):

Because of course ’m’ means help. Not that there’s an ‘h’ command. Anyway. fdisk or parted just handles the partitioning bit, and I probably didn’t need to do that again since I had already reformatted the thing several times with unsatisfactory FAT32 partitions, but I opted to clear the thing out anyway. The juicy bit is using mkfs.fat, and explicitly specifying -F 32 to ensure FAT32 and -s 16 which was a lucky-ish guess, giving me 8K blocks. Even reading the manpage, it’s tricky figuring out how -s and -S interact – -S 4096 -s 1 left me with a broken filesystem, but ignoring -S and guessing at -s got me to a happy place.

It’s probably a good thing that disk partitioning and formatting utilities are becoming more streamlined, though I think the mainstream OSes pushing folks to exFAT for large removable media is bound to lead to trouble. I sure didn’t need to go through all of this trouble to set up a small allocation size; I would’ve been fine with how the thing came, or how Rufus formatted it. It’s likely for the best that things like that aren’t generally exposed to users. But it’s worth noting that if you do want to do something funky, the old tools are there and they work.

  1. The old stick was a Transcend JetFlash unit that died after about 2 years. I’ve replaced it with a Corsair Flash Voyager Vega. I cannot speak to the Vega’s longevity yet (obviously), but I can say that the physical design is superior in every way: the metal feels sturdier (the aluminum had deformed and been reshaped a few times on the Transcend), the metal is grippier, there’s an activity light, and the bit that sticks out is raised just enough more to make it easy to pull from the port. Oh, and it also fits the port properly. I’ve been happy with other Corsair products, hoping this proves to be a winner. ↩︎
  2. There’s also a PowerShell formatting command or module or whatever the heck you call the things that you type into PowerShell. But PowerShell is the closest thing I have to evidence that hell is real, so… thank u, next. ↩︎

Baba is Turing Complete (external)

Baba is You is a wonderful puzzle game that has been frustrating the heck out of me lately. Its primary conceit is that puzzles are solved by moving textual blocks around to form subject/predicate constructions that rewrite the rules of the puzzle. Matthew Rodriguez has, as explained in the external link above, implemented Rule 1101 in Baba is You, with a video of the automaton in action on his Twitter feed. Matthew Cook famously proved Rule 110 to be Turing complete, which means (given an infinite grid, blah blah) the grammar and mechanics that make for a puzzle in Baba is You also make for a Turing complete system.

Humorously, the first response on the Twitter post is along the lines of ‘can it play DOOM?’ which… Sure! A Turing machine can theoretically do all of the computations that DOOM makes! Ignoring how much processing power and RAM one would need for this (a convenient thing to ignore, but we’re talking hypotheticals here), folks always seem to jump right from Turing machine to something resembling a modern computer. The only thing on the table is computational ability, and at a bare minimum, one still needs a viable I/O interface in order to do anything beyond turning bits into other bits.

  1. Here’s an implementation of Rule 110 in CSS which both helps demonstrate the rules of 110 and shows Turing completeness in CSS. ↩︎