<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
 <title>Grimmoire</title>
 <description>The only difference between technology and ritual is aesthetic</description>
 <link>https://grimmwa.re/blog/html/</link>
 <lastBuildDate>Tue May  6 11:51:13 AM BST 2025</lastBuildDate>

 <item>
  <title>00019-environment</title>
  <description type="html">&lt;html&gt;
&lt;head&gt;
&lt;meta charset="utf-8"&gt;
&lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
&lt;link rel="stylesheet" href="style.css"&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;p&gt;I&amp;rsquo;ve taken the weekend to really chill out (partly hangover enforced on
Saturday) and it&amp;rsquo;s worked out well, because I&amp;rsquo;ve been feeling really chill and
I&amp;rsquo;ve also just completely revamped my desktop environment by building and
installing niri.&lt;/p&gt;

&lt;p&gt;Core to understanding my rationale in all of this is that I&amp;rsquo;m using my MNT
Pocket Reform which has a small screen, and I&amp;rsquo;m very much geared toward
avoiding using a pointing device, especially since I built the Pocket Deck
prototype which I&amp;rsquo;ve totally failed to write about yet:&lt;/p&gt;

&lt;p&gt;&lt;img src="images/00019/pocket_deck.jpeg" alt="Pocket Deck housing an MNT Pocket Reform and a Totem BLE keyboard with Gamma keycaps" /&gt;&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;m now using a sizeably different stack that feels like it&amp;rsquo;s honed in on what
it was aiming for:&lt;/p&gt;

&lt;a name="Niri-as-WM"&gt;&lt;/a&gt;
&lt;h1&gt;Niri as WM&lt;/h1&gt;

&lt;p&gt;I feel like this is a more spacious and (to create an awkward turn of phrase)
&lt;em&gt;spaceful&lt;/em&gt;. That is to say that I can find where I&amp;rsquo;ve put all of my shit
because everything sits &lt;em&gt;relative&lt;/em&gt; to everything else. I feel less inclined to
break things into workspaces unless I feel I have dedicated workstreams going
on, because I&amp;rsquo;m not going to run out of space. Focus seems easier because you
can have less on your screen but edge it with some relevant context that helps
you remember why you were in this window in the first place.&lt;/p&gt;

&lt;p&gt;&lt;img src="images/00019/screen_full.png" alt="Niri as wm showing the partial overflow windows" /&gt;&lt;/p&gt;

&lt;p&gt;It all just seems to flow a little better, and it&amp;rsquo;s somehow keeping me on the
keyboard better. This is actually potentially due to the fact that I&amp;rsquo;m learning
a new keyboard layout and having to translate workspace numbers into keypresses
is probably just meaning I break focus less, but equally I find myself spending
less time clicking for icons due to the mental load of the contortions.&lt;/p&gt;

&lt;p&gt;I think the keyboard-based application switching of other platforms just leaves
me feeling like the important thing was not where I put a window but which
window I selected last, requiring me to remember that which is really not the
point. My mind now is keeping a good enough map, and when it doesn&amp;rsquo;t it just
doesn&amp;rsquo;t take long to find out (especially if I can learn cmd+o) .&lt;/p&gt;

&lt;a name="Fuzzel-as-an-application-launcher"&gt;&lt;/a&gt;
&lt;h1&gt;Fuzzel as an application launcher&lt;/h1&gt;

&lt;p&gt;&lt;img src="images/00019/fuzzel_screen.png" alt="Fuzzel with some color changes" /&gt;&lt;/p&gt;

&lt;p&gt;I think I was using wofi before using the shipped Pocket Reform setup, and
honestly I wasn&amp;rsquo;t much of a fan of it. Fuzzel is fast and looks nice with just
a couple of colour changes.&lt;/p&gt;

&lt;p&gt;It&amp;rsquo;s more compact which is nice.&lt;/p&gt;

&lt;a name="Alacritty-as-terminal"&gt;&lt;/a&gt;
&lt;h1&gt;Alacritty as terminal&lt;/h1&gt;

&lt;p&gt;I&amp;rsquo;d previously been using foot and that was fine, but I&amp;rsquo;d found with the new WM
I really wanted to consider not using a completely integrated multiplexer that
meant I was always using a mixed paradigm and often causing friction, but I
didn&amp;rsquo;t want to lose the vim-style copy mode. Well Alacritty supports this well
enough for the features I need and allowed me to duplicate the behaviour I&amp;rsquo;d
set up here in tmux, and I happen to be using it on my work Mac too for reasons
I can&amp;rsquo;t really remember so this seemed like a portable solution.&lt;/p&gt;

&lt;p&gt;&lt;img src="images/00019/alacritty_screen.png" alt="Alacritty in vim mode visually selecting some stuff in /dev" /&gt;&lt;/p&gt;

&lt;p&gt;It doesn&amp;rsquo;t answer the question of persistence (i.e. I&amp;rsquo;d like to excise it
entirely if I can) so I&amp;rsquo;m looking at shpool right now, I just want to figure
out how I can integrate into Alacritty window titles such that I can duplicate
terminals in both ssh connection and current directory from a keybinding to the
window manager.&lt;/p&gt;

&lt;p&gt;I haven&amp;rsquo;t done that bit yet.&lt;/p&gt;

&lt;p&gt;The other thing I apparently still need to do is fix up my keybindings a little
because I&amp;rsquo;ve mapped return to effectively yank text and drop out of copy mode,
which means I don&amp;rsquo;t have a way of completing a text search without dropping out
of copy mode! I&amp;rsquo;m sure I&amp;rsquo;ll get there.&lt;/p&gt;

&lt;a name="The-same-waybar-config-and-widgets"&gt;&lt;/a&gt;
&lt;h1&gt;The same waybar config and widgets&lt;/h1&gt;

&lt;p&gt;If it ain&amp;rsquo;t broke etc&amp;hellip; I might make this smaller but I really like what MNT
shipped. Before I found that I would sometimes click the application icons to
switch because my mental map of which window was on which desktop was shot, now
I find that I just use it to keep track of how many of which window I have open
which typically has me cleaning up and reusing open terminals a lot better than
when I was using tmux. This was something of an unexpected side-effect!&lt;/p&gt;

&lt;a name="Stuff-along-the-way"&gt;&lt;/a&gt;
&lt;h1&gt;Stuff along the way&lt;/h1&gt;

&lt;p&gt;In the end I also set up a new color scheme for neovim (with a patch to remove
it&amp;rsquo;s background color) and also set up tree-sitter to have syntax highlighting
for niri&amp;rsquo;s .kdl configuration format. I also exclusively used qutebrowser
during all of this which meant that my hands were almost exclusively on the
keyboard. It lends itself well!&lt;/p&gt;

&lt;p&gt;&lt;img src="images/00019/syntax_screen.png" alt="Some syntax highlighting of kdl in nvim" /&gt;&lt;/p&gt;

&lt;p&gt;There were a whole bunch of config hacks to niri and alacritty to get them how
I like them, but I was really impressed with niri&amp;rsquo;s live config auto-reloading.
There are a couple of implementation quirks that shine through like the choice
of syntax, the mandatory splitting of command arguments and the way that
special configuration is needed to clean up rendering especially when using
transparent windows, but those configuration options &lt;em&gt;exist&lt;/em&gt; as minimal
implementation safe defaults - you don&amp;rsquo;t need all these bells and whistles so
why put them in the code path for people who don&amp;rsquo;t need the sugar?&lt;/p&gt;

&lt;a name="Up-next"&gt;&lt;/a&gt;
&lt;h1&gt;Up next&lt;/h1&gt;

&lt;p&gt;I&amp;rsquo;m really into implemenging this shpool integration. I&amp;rsquo;m not entirely sure I
know what it&amp;rsquo;s going to look like yet&amp;hellip; I think I could probably do something
using ssh session sockets, fzf and installing shpool on all my remotes (which I
can currently do for all my personal stuff).&lt;/p&gt;

&lt;p&gt;Essentially the idea is that I should be able to spawn a shell to any of my
usual remotes directly from my gui without needing to jump through any of the
usual hoops in a terminal first, so e.g. press a keybinding, fuzzy match a host
and session name and then jump straight into e.g. my remote weechat session as
if it&amp;rsquo;s native. This is obviously pretty trivial to do with a bit of shell, but
the real magic piece I want is to be able to have a keybinding for spawining a
new session on the same host as the currently selected windows, which involves
fucking around with alacritty window titles.&lt;/p&gt;

&lt;p&gt;I do wonder if I can figure out an implementation I can ship as part of my work
homedir config though&amp;hellip; The issue I face whenever I remove a bunch of the
friction from my personal setup is that it the exacerbates the issue of using
my work macbook - coercing macOS into doing user interface stuff that it thinks
you don&amp;rsquo;t need is straight up irritating and always leaves unhammered nails
that you snag yourself on.&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</description>
  <link>https://grimmwa.re/blog/html/00019-environment.html</link>
  <guid isPermaLink="false">https://grimmwa.re/blog/html/00019-environment.html</guid>
  <pubDate></pubDate>
 </item>

 <item>
  <title>00018-retrofit</title>
  <description type="html">&lt;html&gt;
&lt;head&gt;
&lt;meta charset="utf-8"&gt;
&lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
&lt;link rel="stylesheet" href="style.css"&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;p&gt;So here, I did a thing the other day.&lt;/p&gt;

&lt;p&gt;I have an old Tandy 1400LT (as opposed to what, a new one?) which is in really
good condition bar a couple of things - no battery, and no DC power supply.
I&amp;rsquo;ve previously had it running with a benchtop power supply hooked up to the
battery terminals, but that pretty much restricts where I can use it and more
critically takes up my benchtop power supply.&lt;/p&gt;

&lt;p&gt;With a lot of focus in the MNT Pocket Reform community of late on the USB-C PD
functionality of the sysctl, this got me to thinking - surely there&amp;rsquo;s a way of
just doing the power negotiation to get a fixed DC power supply. Welp it turns
out there&amp;rsquo;s a really cheap and simple way of doing that in the Adafruit
&lt;a href="https://www.adafruit.com/product/5807"&gt;HUSB238&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is a really simple install. You get the thing, you solder on the battery
terminals, cut the traces for the default supply (5V, 1A) then bridge the pads
for the supply you actually want (in my case 15V, 2A) and hook that bad boy up.&lt;/p&gt;

&lt;p&gt;&lt;img src="images/00018/husb238.jpg" alt="A USB-C cable hooked up to a small circuit board hooked
up to the battery terminals of the open battery bay of a Tandy 1400 LT
luggable. The Tandy is switched on" /&gt;&lt;/p&gt;

&lt;p&gt;Of course, it being simple meant I had a couple of minor difficulties. Firstly,
it would only negotiate 15V once I actually bridged the pads for 2A despite
open meaning 3A (and in theory the device should be able to draw what it
wants?). I think this might be because the supply I was using was only 45W and
the default voltage was just &lt;em&gt;over&lt;/em&gt; 5V so I guess it was trying to draw over
45W? Thing was I also tried it on a 100W supply and it failed more
differentlier than that. Whatever, got it working. The second issue I had was
when I finally figured this out I still wasn&amp;rsquo;t getting a 15V measurement
because I&amp;rsquo;d left the multimeter on continuity mode.&lt;/p&gt;

&lt;p&gt;Go figure.&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</description>
  <link>https://grimmwa.re/blog/html/00018-retrofit.html</link>
  <guid isPermaLink="false">https://grimmwa.re/blog/html/00018-retrofit.html</guid>
  <pubDate>Sat Oct 12 17:55:45 2024 +0100</pubDate>
 </item>

 <item>
  <title>00017-pocket-reform-lid-detection</title>
  <description type="html">&lt;html&gt;
&lt;head&gt;
&lt;meta charset="utf-8"&gt;
&lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
&lt;link rel="stylesheet" href="style.css"&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;a name="Preamble"&gt;&lt;/a&gt;
&lt;h1&gt;Preamble&lt;/h1&gt;

&lt;p&gt;I have an MNT Pocket Reform which I&amp;rsquo;ve already opened up several times for
various purposes (adding extra thermal pads to improve wifi reception, mucking
about with alternative aerials, unbricking my system controller from bad
firmware flashes). I&amp;rsquo;ve changed the keyboard layout and tested firmware
improvements for the system controller (hence the aformentioned bricking) and
even did some of the early work on packaging up the offline version of the
manual. In a couple of months I&amp;rsquo;ll have it open to replace the SoM with an
RK3855, at which point it&amp;rsquo;ll be my MNT Pocket Rocket.&lt;/p&gt;

&lt;p&gt;As you can imagine, the machine is living up to the dream for me.&lt;/p&gt;

&lt;a name="The-idea"&gt;&lt;/a&gt;
&lt;h1&gt;The idea&lt;/h1&gt;

&lt;p&gt;Today I&amp;rsquo;ve had it open for what I feel is the first innovative hack (albeit an
incomplete and fairly rudimentary one), which is to add lid-closed detection by
way of 2 &lt;a href="https://learn.adafruit.com/adafruit-lis3dh-triple-axis-accelerometer-breakout/overview"&gt;Adafruit LIS3DH&lt;/a&gt; triple axis accelerometer modules.&lt;/p&gt;

&lt;p&gt;The Pocket has a qwiic connector on the motherboard that allows you to connect
(and daisy-chain) i2c peripherals to the RP2040, and there was some talk on
the forums of wanting to be able to do closed lid detection and this struck me
as the easy way of doing it if you&amp;rsquo;re the mechanical engineering equivalent of
my dog trying to open a door that&amp;rsquo;s already slightly ajar - too stupid. The
other advantage of this approach is that instead of just having a single
purpose switch, you can subsequently use the sensors for detecting rotation and
re-orienting the screen (for instance if you want to read content off of the
pocket as if it&amp;rsquo;s a book - which I do want to do!) or just ridiculous bullshit
like shaking it to turn it on (possible due to the fact it connects to the
sysctl and not the SoM). Allegedly the sensors support a double-tap gesture too
which might be fun to play around with in the future.&lt;/p&gt;

&lt;p&gt;Anyway&amp;hellip;&lt;/p&gt;

&lt;p&gt;The basic concept here is that if you have 2 accelerometers, one in the top
half and one in the bottom and they&amp;rsquo;re in more or less the same orientation in
relation to their respective halves, when they both read roughly the same
values then you know that they&amp;rsquo;re parallel to each other and thus the lid is
shut.&lt;/p&gt;

&lt;a name="What-I-27-ve-actually-done"&gt;&lt;/a&gt;
&lt;h1&gt;What I&amp;rsquo;ve actually done&lt;/h1&gt;

&lt;p&gt;I&amp;rsquo;ll pony up here and admit that I&amp;rsquo;ve not actually done that yet because it
looks (and I&amp;rsquo;ve been too lazy this evening to verify) that there&amp;rsquo;s not really
enough space in the hinges to run another cable, and certainly not without
having to crimp my own qwiic connector which ew no. I&amp;rsquo;ve basically just done
the PoC in the top half, so I can detect when the lid is closed and it&amp;rsquo;s on a
flat surface.&lt;/p&gt;

&lt;p&gt;&lt;img src="images/00017/backoff.jpg" title="Installed" alt="The inside of the MNT Pocket Reform top half with the accelerometer module
attached via a qwiic connector in the top right corner (the bottom left when
the lid is open with the screen facing you) with a green LED lit
up." /&gt;&lt;/p&gt;

&lt;p&gt;After a while mucking about establishing which part of the machine the qwiic
was connected to (reading comprehension isn&amp;rsquo;t my strong suit when I&amp;rsquo;m trying to
skip to the end; this is totally in the manual), I jumped into the system
controller code and immediately found the unused &lt;code&gt;i2c_scan&lt;/code&gt; function which I
dilligently added in just before the main loop as this enumerates all i2c
devices and prints them out on a pretty little 2D table! I immediately bricked
my sysctl (again) because it turns out I never initialised the tinyusb
dependency for the firmware, so after rescuing that I decided to give up on
being an idiot who can&amp;rsquo;t read and got it working properly.&lt;/p&gt;

&lt;p&gt;The system controller helpfully has its USB UART connected such that you can
just &lt;code&gt;sudo tio /dev/ttyACM0&lt;/code&gt; and I was greeted with (amongst other output):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;I2C Scan
   0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
00 .  .  .  .  .  .  .  .  .  .  .  @  .  .  .  .
10 .  .  .  .  .  .  .  .  T  .  .  .  .  .  .  .
20 .  .  @  .  .  .  .  .  .  .  .  .  .  .  .  .
30 .  .  .  .  .  .  @  .  .  .  .  .  .  .  .  .
40 .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
50 .  .  .  .  .  .  .  .  .  .  .  .  @  .  .  .
60 .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
70 .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&amp;hellip; well that&amp;rsquo;s not technically true, the &lt;code&gt;T&lt;/code&gt; was an &lt;code&gt;@&lt;/code&gt; but I&amp;rsquo;ve marked it
here to show the address that was not present when I unplugged the module. This
gave me the address that is, in fact, clearly written on the datasheet. I only
learn the hard way though. Each module has a couple of pads that you can bridge
to modify 1 bit of the address so that you can safely daisy-chain 2 of them and
still address them on the same bus.&lt;/p&gt;

&lt;p&gt;So, with the device enumerated I went on to try to find code examples for the
RP2040 and what do you know, &lt;a href="https://github.com/raspberrypi/pico-examples/blob/master/i2c/lis3dh_i2c/lis3dh_i2c.c"&gt;there was a code example&lt;/a&gt; for this
peripheral on the upstream repos for the pico. This is part of the genius of
using the RP2040 as the system controller - it&amp;rsquo;s absolutely ubiquitous in the
hobbyist scene so there are plenty of libraries, examples and prior art out
there.&lt;/p&gt;

&lt;p&gt;I chopped the various bits of example code into &lt;code&gt;sysctl.c&lt;/code&gt; in the &lt;a href="https://source.mnt.re/reform/pocket-reform/-/tree/main/pocket-reform-sysctl-fw?ref_type=heads"&gt;sysctl&amp;rsquo;s
firmware&lt;/a&gt; and after a broken build I fixed the i2c&amp;rsquo;s pin numbers
(thanks &lt;a href="https://mntre.com/documentation/pocket-reform-handbook/schematics.html"&gt;schematic&lt;/a&gt;!), putting the read and print functions at the
beginning of the main loop, built and flashed and it started spamming the
accelerometer readings!&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;ve updated the code to have its own counter so it&amp;rsquo;s a little more&amp;hellip; sedate
now, giving a reading once every couple of seconds:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# [accel1]: 0.024g,0.924g,-0.384g
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;With that done, I needed to get the readings from the sysctl onto the host.
Like I say, we have &lt;code&gt;/dev/ttyACM0&lt;/code&gt; for that, but using this gains exclusive
control over it. I&amp;rsquo;m under the impression that you can either use ptys or some
ioctl on the tty([^1]), but I happened to see in the manpage for &lt;code&gt;tio&lt;/code&gt; that it
supports a &lt;code&gt;-S&lt;/code&gt; option which additionally listens on a socket. This is a nice
touch as far as I&amp;rsquo;m concerned because it means that we&amp;rsquo;ll be able to put
together a systemd socket-activated unit for multiplexing out access for any
additonal i2c peripheral we might want to add when we get round to it.&lt;/p&gt;

&lt;p&gt;So with that problem (in theory) solved, I&amp;rsquo;m keen to skip to the end because
proof-of-concept or GTFO. Here, see the dirty shit I bestow on the world every
time I do a PoC (split over multiple lines for readability - I don&amp;rsquo;t even do
that I am such a trash goblin):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo socat - UNIX-CONNECT:$HOME/sysctl.sock \
| stdbuf -o0 awk -F, '/accel1/ { print substr($2, 1, length($2)-1) }' \
| while read n; do \
  [ $(echo "$n &amp;lt; -0.1" | bc -l) -eq 1 ] &amp;amp;&amp;amp; echo open || echo closed; \
done
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Which duly tells us when the lid is angled a sufficiently small deviation from
horizontal (or I suppose swung around or something). This particular invocation
will only work if you place the module in the same orientation as mine.&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;ve now expanded this a little to:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo socat - UNIX-CONNECT:$HOME/sysctl.sock \
| stdbuf -o0 awk -F, '/accel1/ { print substr($2, 1, length($2)-1) }' \
| while read n; do \
  [ $(echo "$n &amp;lt; -0.1" | bc -l) -eq 1 ] \
    &amp;amp;&amp;amp; (echo open &amp;amp;&amp;amp; swaymsg "output * dpms on") \
    || (echo "closed" &amp;amp;&amp;amp; swaymsg "output * dpms off"); \
done
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Which will dutifully turn my display off and on again as in this shitty gif
(the delay is long because I had the readout frequency set too low):&lt;/p&gt;

&lt;p&gt;&lt;img src="images/00017/thegif.gif" title="The Gif" alt="An embarassing quality gif of closing the lid whilst the screen is on,
opening it again and it's off, and eventually it realises and turns itself
on" /&gt;&lt;/p&gt;

&lt;p&gt;There&amp;rsquo;s a better quality version of the video on &lt;a href="https://imgur.com/a/J6qkmlq"&gt;imgur&lt;/a&gt; should you care
:)&lt;/p&gt;

&lt;a name="What-still-needs-doing"&gt;&lt;/a&gt;
&lt;h1&gt;What still needs doing&lt;/h1&gt;

&lt;p&gt;So, next steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fabricate or otherwise modify a version of the OLED module (which happens to
be i2c) and daisy-chain a qwiic connector off the other side to provide a
port in the lower half without having to run a cable, as suggested by
&lt;code&gt;minute&lt;/code&gt; (Lukas Hartmann)&lt;/li&gt;
&lt;li&gt;Create the aforementioned systemd unit to fire up the tty multiplexer (or
probably more likely find the correct ioctls or whatever is more intelligent
than this)&lt;/li&gt;
&lt;li&gt;Have a unit that tails the log and activates the appropriate power state
that&amp;rsquo;s not an unholy bash one-liner.&lt;/li&gt;
&lt;li&gt;Probably refactor the code to only build in the LIS3DH code if a compiler
flag is supplied and to also check at runtime if the device is even there
before running any related code (effectively making the accelerometer safe to
unplug even with modified firmware). And not violate any licenses.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;In no particular order.&lt;/p&gt;

&lt;a name="The-code"&gt;&lt;/a&gt;
&lt;h1&gt;The code&lt;/h1&gt;

&lt;p&gt;Anyway, my work-in-progress branch for this is &lt;a href="https://source.mnt.re/grimmware/pocket-reform/-/commits/lis3dh"&gt;here&lt;/a&gt; and the commit at
the time of writing is &lt;code&gt;f9bfefaa662b98dae961ef7f9f72f352ce655612&lt;/code&gt; - if you want
to follow in my footsteps I would &lt;em&gt;very strongly&lt;/em&gt; advise you to be familiar
with manually flashing the sysctl from another machine using the internal USB-C
port and to not place any faith in any C I&amp;rsquo;ve been near.&lt;/p&gt;

&lt;p&gt;([^1]: Okay so I looked in to this and it appears that tio is setting the
ioctls for exclusive control whereas socat won&amp;rsquo;t do this for you automagically
and if you use 2 different socat instances on the same device you get half of
the output on each&amp;hellip; So I&amp;rsquo;m sticking with my tio-with-a-socket option for
now.)&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</description>
  <link>https://grimmwa.re/blog/html/00017-pocket-reform-lid-detection.html</link>
  <guid isPermaLink="false">https://grimmwa.re/blog/html/00017-pocket-reform-lid-detection.html</guid>
  <pubDate>Sun Sep 15 18:37:37 2024 +0000</pubDate>
 </item>

 <item>
  <title>00016-flaptack-mcus</title>
  <description type="html">&lt;html&gt;
&lt;head&gt;
&lt;meta charset="utf-8"&gt;
&lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
&lt;link rel="stylesheet" href="style.css"&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;blockquote&gt;&lt;p&gt;This post is from waaaaay back in the first COVID-19 lockdown, and I
never got round to converting it from .org format and actually posting it but
I&amp;rsquo;m starting to take a look at &lt;em&gt;doing&lt;/em&gt; something with what I discovered
(possibly making a Flipper Zero zigbee sniffing module) so I&amp;rsquo;m going to get
on and publish this now.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;The biggest problem you might have when pursuing your own unique brand of
technological freedom is that you might end up going deeper on it than you
thought you would, and you&amp;rsquo;ll learn a whole shitload but not actually produce
anything.&lt;/p&gt;

&lt;p&gt;So obviously in pursuit of having my own brand of smart-home sans the
completely unnecessary yet somehow synonymous data-mining, I&amp;rsquo;ve finally managed
to install a fork of Micropython on a smart switch and its only taken me
FUCKING HOURS.&lt;/p&gt;

&lt;p&gt;The impotent rage of a man who choses his own problems (like wanting to be able
to control the lights from magic rituals).&lt;/p&gt;

&lt;p&gt;In all seriousness though, in this one I got to do the following for the first time:
- Debug with &lt;code&gt;gdb&lt;/code&gt; over the J-Link
- Built and flashed Micropython
- Hacked code on to something not explicitly designed for it
- Use vendor &lt;code&gt;SVD&lt;/code&gt; files to get easy access to peripherals
- Write a &lt;code&gt;gdb&lt;/code&gt; python plugin
- Used the hardfault registers to diagnose a problem
- Patched &lt;code&gt;memset&lt;/code&gt;&lt;/p&gt;

&lt;a name="A-different-DIY"&gt;&lt;/a&gt;
&lt;h1&gt;A different DIY&lt;/h1&gt;

&lt;p&gt;Ikea have their own range of smart-home kit, called Tradfri. It&amp;rsquo;s super cheap,
it doesn&amp;rsquo;t appear to phone home unnecessarily according to more dilligent
people, and most importantly, others have already hacked on it and shown that
things like UART and SWD are easily accessed.&lt;/p&gt;

&lt;p&gt;One of the projects that I quickly found and dove into was Trammell Hudson&amp;rsquo;s
[[https://trmm.net/Ikea][Ikea hacking lightening talk]] along with his fork of
Micropython for the SiliconLabs EFR32 and partially implemented Zigbee stack.&lt;/p&gt;

&lt;p&gt;My plan here was to buy one of the super cheap smart switches along with a
couple of the peripherals (a plug and a bulb) and to try to hack the switch so
that it could be wired up over serial to a raspberry pi to send instructions
over Zigbee to the peripherals, thus enabling me to write my own HTTP endpoint
to have complete control over the devices without them having to go near the
internet (or without me having to install and app).&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;m increasingly under the impression that it&amp;rsquo;s a pretty specious assumption to
think it could all Just Work like this within any reasonable timescale, but as
you&amp;rsquo;ll see I have at least learned a lot.&lt;/p&gt;

&lt;a name="Debugging"&gt;&lt;/a&gt;
&lt;h1&gt;Debugging&lt;/h1&gt;

&lt;p&gt;Getting set up was pretty easy. Using Trammell&amp;rsquo;s photos and instructions, I quickly:
- got everything set up and the firmware built
- managed to get a pretty neat setup whereby I was using an FTDI232 to not only
  interact with the thing over serial, but also to sub out the coin cell and
  supply 3.3V to the MCU.
- Hooked up my J-Link EDU Mini running a &lt;code&gt;gdb&lt;/code&gt; server
- Loaded up the file, set up a breakpoint for the &lt;code&gt;HardFault_Handler&lt;/code&gt; function
- Flashed the code and reset the MCU&amp;hellip;&lt;/p&gt;

&lt;p&gt;Aaaaand much to my surprise we pretty much instantly hit the
&lt;code&gt;HardFault_Handler&lt;/code&gt; breakpoint.&lt;/p&gt;

&lt;p&gt;This lead to me googling and almost instantly finding
[[https://interrupt.memfault.com/blog/cortex-m-fault-debug][this fantastic
article on debugging hardfaults on Cortex-M devices]]. It teaches you all about
what peripherals are available by default on a Cortex-M which you can use to
find out why your code failed.&lt;/p&gt;

&lt;a name="Python-helpers"&gt;&lt;/a&gt;
&lt;h2&gt;Python helpers&lt;/h2&gt;

&lt;p&gt;I spent quite some time trying to figure out why the &lt;code&gt;svd&lt;/code&gt; files that give the
hex addresses for the peripherals some slightly more friendly names and
convenience functions didn&amp;rsquo;t seem to have the CFSR register that I needed to
debug - turns out that most vendors &lt;em&gt;don&amp;rsquo;t include the core ARM peripherals&lt;/em&gt; in
their machine-readable definitions, and more infuriatingly &lt;em&gt;ARM won&amp;rsquo;t provide
these either&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;To save myself some mental cycles I quickly threw together the following based
on some simple examples online:&lt;/p&gt;

&lt;pre&gt;&lt;code class="python"&gt;BFSR_ADDR = "0xE000ed29"
BFSR_LEN = "b"
BFSR_BITS = [
    "IBUSERR",
    "PRECISERR",
    "IMPRECISERR",
    "UNSTKERR",
    "STKERR",
    "LSPERR",
    "Reserved",
    "BFARVALID"
    ]

class CFSR(gdb.Command):
    def __init__(self):
        gdb.Command.__init__(self, "cfsr", gdb.COMMAND_DATA)

    def _get_bits(self, address, length):
        bits = [bit for bit
                in gdb.execute(
                    f"x/{length}t {address}", True, True
                ).split("\t")[1].strip()]
        bits.reverse()
        return bits

    def invoke(self, args, from_tty):
        cmd = str(args).split(" ")
        if cmd[0] == "bfsr":
            bits = self._get_bits(BFSR_ADDR, BFSR_LEN)
            for i in range(len(bits)):
                gdb.write(f"{BFSR_BITS[i]}: {bits[i]}\n")
                gdb.flush()
        return

if __name__ == "__main__":
    CFSR()
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I&amp;rsquo;d already determined by figuring this stuff out manually that the BFSR
register contained the information I needed, and I just needed a more
intelligible way to be able to view the output without getting into the weeds
of a full implementation:&lt;/p&gt;

&lt;pre&gt;&lt;code class="gdb"&gt;(gdb) c
Continuing.

Breakpoint 3, HardFault_Handler () at main.c:236
236             uart_str("!!!!!\\r\\n");
(gdb) cfsr bfsr
IBUSERR: 0
PRECISERR: 1
IMPRECISERR: 0
UNSTKERR: 0
STKERR: 1
LSPERR: 0
Reserved: 0
BFARVALID: 1
&lt;/code&gt;&lt;/pre&gt;

&lt;a name="Looking-for-the-error"&gt;&lt;/a&gt;
&lt;h2&gt;Looking for the error&lt;/h2&gt;

&lt;p&gt;This roughly translates to:
- PRECISERR :: We know exactly which instruction caused the hardfault
- STKERR :: It was probably access to invalid memory
- BFARVALID :: The BFAR peripheral contains the memory address that caused the
  problem&lt;/p&gt;

&lt;p&gt;This was pretty helpful because checking an actual backtrace appeared to be of
little use - it didn&amp;rsquo;t seem to make sense.&lt;/p&gt;

&lt;p&gt;The address in BFAR was just below the stack at the top of ROM, so this was a
pretty good smoking gun, and matched almost exactly the example given in the
article.&lt;/p&gt;

&lt;p&gt;By setting a watchpoint on memory just above the bottom of the stack, I was
able to see the following:&lt;/p&gt;

&lt;pre&gt;&lt;code class="gdb"&gt;...
#18 0x00015804 in memset (s=0x21000f7c, c=c@entry=0,
    n=n@entry=132) at ../../lib/libc/string0.c:86
#19 0x00015804 in memset (s=0x21000f7c, c=c@entry=0,
    n=n@entry=132) at ../../lib/libc/string0.c:86
#20 0x00015804 in memset (s=0x21000f7c, c=&amp;lt;optimized out&amp;gt;, n=132)

    at ../../lib/libc/string0.c:86
#21 0x0001e742 in RADIO_SeqInit ()
#22 0x0001f8bc in GENERIC_PHY_RACConfig ()
#23 0x0001f900 in GENERIC_PHY_Init ()
#24 0x0001d24c in RFHAL_Init ()
#25 0x0001bc8c in RAILCore_Init ()
#26 0x00014efe in radio_init () at radio.c:347
#27 radio_init () at radio.c:317
#28 0x000145c4 in main (argc=&amp;lt;optimized out&amp;gt;,

    argv=&amp;lt;optimized out&amp;gt;) at main.c:92

(gdb)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is pretty frustrating because the problem appears to be right in the
middle of a binary blob, and my reverse-engineering skills aren&amp;rsquo;t up to much,
but notably in stepping through from that point, the &lt;code&gt;memset&lt;/code&gt; frames on the
stack just keep on iterating upward.&lt;/p&gt;

&lt;p&gt;I emailed Trammell about this and he said that he&amp;rsquo;d occasionally seen similar
but not gone to deep on the debugging (which, quite frankly, made me feel like
I was doing a good job), but helpfully asked if I&amp;rsquo;d tried just commenting the
radio code out.&lt;/p&gt;

&lt;a name="Not-just-the-radio"&gt;&lt;/a&gt;
&lt;h2&gt;Not just the radio&lt;/h2&gt;

&lt;p&gt;Trying this out it transpires that even on hitting the &lt;code&gt;gc_init&lt;/code&gt; code (setting
up the heap for use as garbage collected memory for Micropython, or so I
assume) it shits the bed at &lt;code&gt;memset&lt;/code&gt; again.&lt;/p&gt;

&lt;p&gt;Reading the implementation and not being particularly au fait with
scarce-resource optimizations I didn&amp;rsquo;t really know what to make of this:&lt;/p&gt;

&lt;pre&gt;&lt;code class="C"&gt;void *memset(void *s, int c, size_t n) {
    if (c == 0 &amp;amp;&amp;amp; ((uintptr_t)s &amp;amp; 3) == 0) {
        // aligned store of 0
        uint32_t *s32 = s;
        for (size_t i = n &amp;gt;&amp;gt; 2; i &amp;gt; 0; i--) {
            *s32++ = 0;
        }
        if (n &amp;amp; 2) {
            *((uint16_t*)s32) = 0;
            s32 = (uint32_t*)((uint16_t*)s32 + 1);
        }
        if (n &amp;amp; 1) {
            *((uint8_t*)s32) = 0;
        }
    } else {
        uint8_t *s2 = s;
        for (; n &amp;gt; 0; n--) {
            *s2++ = c;
        }
    }
    return s;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Honestly? My lockdown brain can&amp;rsquo;t comprehend that, and certainly not how it
seemed to result in recursion behaviour. This was crossing a couple of areas of
expertise and none of them dovetail with mine - however &lt;code&gt;git log -p --
lib/libc/string0.c&lt;/code&gt; was very kind to me and let me know the current
implementation was a performance optimization.&lt;/p&gt;

&lt;p&gt;That meant there was an earlier implementation I could check out!&lt;/p&gt;

&lt;p&gt;I copied the old code out from before that commit:&lt;/p&gt;

&lt;pre&gt;&lt;code class="C"&gt;void *memset(void *s, int c, size_t n) {
    uint8_t *s2 = s;
    for (; n &amp;gt; 0; n--) {
        *s2++ = c;
    }
    return s;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;YEAH BOIIIII I&amp;rsquo;m smart enough to understand that!&lt;/p&gt;

&lt;p&gt;I uncommented the radio code in order to see if it all still caught fire and
hey presto, not only did it &lt;em&gt;not&lt;/em&gt; hardfault but I got a REPL over the serial
console!&lt;/p&gt;

&lt;a name="But-WHY-3f-"&gt;&lt;/a&gt;
&lt;h1&gt;But WHY?&lt;/h1&gt;

&lt;p&gt;Honestly fucked if I know. the way that it would jump back in the memset it
feels like it was perhaps accidentally rewriting the stack pointer over and
over again&amp;hellip;&lt;/p&gt;

&lt;p&gt;I &lt;em&gt;should&lt;/em&gt; probably debug this and see if it&amp;rsquo;s worth trying to fix properly in
the original implementation, but I also &lt;em&gt;should&lt;/em&gt; actually try to do the thing I
originally set out to do.&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;ll update here when I decide which to do - I&amp;rsquo;m already taking time out from
that to write it all down!&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</description>
  <link>https://grimmwa.re/blog/html/00016-flaptack-mcus.html</link>
  <guid isPermaLink="false">https://grimmwa.re/blog/html/00016-flaptack-mcus.html</guid>
  <pubDate>Wed Jan 10 18:12:44 2024 +0000</pubDate>
 </item>

 <item>
  <title>00015-speculative-friction</title>
  <description type="html">&lt;html&gt;
&lt;head&gt;
&lt;meta charset="utf-8"&gt;
&lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
&lt;link rel="stylesheet" href="style.css"&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;p&gt;Recently I came across (for the second time) the text editor &lt;a href="https://nightfall.city/nex/in/m15o/projects/bitters/"&gt;bitters&lt;/a&gt;
which is essentially a lo-fi love letter to the Canon Cat. I&amp;rsquo;d seen this
before, having some time ago watched a video about the Canon Cat and falling in
love with the simplicity and humanistic view of human/computer interaction.&lt;/p&gt;

&lt;p&gt;I gave it a try on my work macbook the other day, this being the sort of thing
that I do for a break. Because in my convoluted internal logic, obviously, your
RSI/eye-strain/mental fatigue meters all reset when you switch between work and
&amp;ldquo;leisure problem solving&amp;rdquo;.&lt;/p&gt;

&lt;p&gt;&lt;img src="./images/00015/bitters.png" title="macOS bitters reading the manual" alt="img" /&gt;&lt;/p&gt;

&lt;p&gt;Anyway, installed sdl and build the thing and off we went. I quickly realised,
however, that to have a really satisfying writing experience I would need to
adapt my keyboard to make the leap keys accessible and having a split
ortholinear keyboard (in the crkbd or &amp;ldquo;corne&amp;rdquo;) I would also have to make so
that this new layout is highly symmetrical.&lt;/p&gt;

&lt;p&gt;So fast forward to last night where, after work, I had the mental energies left
to consider Doing Something Productive, and one of the things which I&amp;rsquo;ve been
wanting to do some more is write (as evidenced), in part due to having recently
picked up a copy of &lt;a href="https://abolitionscifi.org/"&gt;Abolition Science Fiction&lt;/a&gt; and really enjoying the
succinctness of the short story format for throwing out ideas without the
deep-seated need to contextualise and explain. Luckily, the book has a set of
writing prompts and exercises in the back!&lt;/p&gt;

&lt;p&gt;So, I thought to myself, maybe now is a good time to give that a go! Let me
just reprogram my keyboard layout quickly&amp;hellip;&lt;/p&gt;

&lt;p&gt;&lt;img src="./images/00015/crkbd.jpg" title="A very old picture of my Corne before I ripped
the microUSB off the left side and before my Dell XPS 13's screen just decided
to stop working" alt="img" /&gt;&lt;/p&gt;

&lt;p&gt;And this, dear reader, is how my life proceeds. Because some time ago I
accidentally ripped off the micro-USB socket on the left-hand side of my
keyboard and had to reprogram the right side to be the master. What I didn&amp;rsquo;t
factor in when I did this (and subsequently reprogrammed the layout on the
right side to replace backspace with del so that I could essentially SIGINT on
a fresh Plan 9 install) was that I could no longer program the left side, which
would become an issue as soon as I tried to flash the &lt;em&gt;right&lt;/em&gt; side with a more
recent firmware.&lt;/p&gt;

&lt;p&gt;So yeah, last night in an effort to start writing again, I nearly bricked my
keyboard before realising that I still had the old working checkout of the old
firmware build which with some massaging (it upsets more recent versions of
avr-gcc and avr-ld without some flags and modifications, notably one
&lt;a href="https://github.com/qmk/qmk_firmware/issues/17064"&gt;compiler&lt;/a&gt; issue requiring &lt;code&gt;--param=min-pagesize=0&lt;/code&gt; and one
&lt;a href="https://github.com/qmk/qmk_firmware/issues/9147"&gt;linker&lt;/a&gt; issue requiring that I reorder some definitions.&lt;/p&gt;

&lt;p&gt;I managed to go to bed with the resumption of an equitable keyboard at the cost
of a couple of hours work.&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;ll bring my work Corne home before I try this again.&lt;/p&gt;

&lt;p&gt;And this marks a repeating frustration in my life - to achieve a frictionless
experience requires a &lt;em&gt;lot&lt;/em&gt; of speculative friction. But I think that&amp;rsquo;s
probably just the kind of person I am and this was a necessary obstacle for me
to overcome. At least I&amp;rsquo;m writing now!&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</description>
  <link>https://grimmwa.re/blog/html/00015-speculative-friction.html</link>
  <guid isPermaLink="false">https://grimmwa.re/blog/html/00015-speculative-friction.html</guid>
  <pubDate>Tue Sep 26 10:23:46 2023 +0000</pubDate>
 </item>

 <item>
  <title>00014-lc3</title>
  <description type="html">&lt;html&gt;
&lt;head&gt;
&lt;meta charset="utf-8"&gt;
&lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
&lt;link rel="stylesheet" href="style.css"&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;a name="Hello-world"&gt;&lt;/a&gt;
&lt;h1&gt;Hello world&lt;/h1&gt;

&lt;p&gt;I&amp;rsquo;ve been working on a virtual machine under 9front implementing the LC3
educational ISA. This has been a lot of fun, and I realise that probably sounds
weird to a bunch of people who did CompSci at university and were made to do
this sort of thing. In that sense I&amp;rsquo;m like a mature student - I&amp;rsquo;m actually
doing it because I care.&lt;/p&gt;

&lt;p&gt;Initially I started out when I was on a 7 week trip through Asia (I know, I
never update this thing, but then nobody reads it either). I was in Kuala
Lumpur and taking a much needed rest, and for some reason that I can&amp;rsquo;t quite
remember I just decided to search &amp;ldquo;how to write a virtual machine&amp;rdquo; and a blog
post came up which essentially lined up the problem of how you&amp;rsquo;d go about
implementing LC3. So I just started.&lt;/p&gt;

&lt;p&gt;And I continued in Nepal, where I finished off the majority of the VM and a
rudimentary assembler and patched &lt;code&gt;vexed&lt;/code&gt; hex editor for binary input to help
with my hand-hacked test machine code.&lt;/p&gt;

&lt;p&gt;And I continued on a beach in Thailand, where I wrote the beginnings of an
assembler.&lt;/p&gt;

&lt;p&gt;Yesterday I reached an important milestone - I was able to assemble and run the
following program:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    .ORIG   x3000
    NOP
    ADD R2,R2,x6    ; we need 6 loops to get to 'h'
    NOT R2,R2       ; we want to be able to subtract this number so we'll 2's complements it
    ADD R2,R2,x1
LOOPH
  ADD   R0,R0,xf
    ADD R1,R1,x1
    ADD R3,R1,R2    ; compare if we're at 6 loops yet
    BRn LOOPH
    ADD R0,R0,xe
    OUT
E   .FILL   x65
L   .FILL   x6c
O   .FILL   x6f
    LD  R0,E
    OUT
    LD  R0,L
    OUT
    OUT
    LD  R0,O
    OUT
    .BLKW   x5
    LEA R0,WRLD
    PUTSP
    HALT
WRLD
  .STRINGZ  x20776f726c64210a
    .END
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Which runs thusly:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cpu% lc3/lc3 -f out.hex
hello world!
Program complete, exiting
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I think it&amp;rsquo;s quite a fun &amp;ldquo;hello world&amp;rdquo; because I wrote it as I was implementing
features of the assembler&amp;hellip;&lt;/p&gt;

&lt;a name="Raw-data-directives"&gt;&lt;/a&gt;
&lt;h1&gt;Raw data directives&lt;/h1&gt;

&lt;p&gt;Up until the first &lt;code&gt;OUT&lt;/code&gt; (which was a &lt;code&gt;TRAP 0x21&lt;/code&gt;
at the time) I only just had assembling into a binary format working, with none
of the raw data loading directives so I had to &lt;code&gt;ADD&lt;/code&gt; the largest positive value
supported by &lt;code&gt;ADD&lt;/code&gt;&amp;rsquo;s immediate mode (which only supports a 5 bit signed
operand) 6 times and then add the remainder to get to &lt;code&gt;0x68&lt;/code&gt; or &lt;code&gt;h&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To get the rest of &lt;code&gt;ello&lt;/code&gt; I then implemented &lt;code&gt;.FILL&lt;/code&gt; and (now that I think
about it) just let the machine blast through trying to interpret those
instructions (I should probalby fix that hahah), but this means that we&amp;rsquo;re then
able to &lt;code&gt;LD&lt;/code&gt; those memory locations into &lt;code&gt;R0&lt;/code&gt; which then means we can use the
&lt;code&gt;OUT&lt;/code&gt; trap to print each one in turn.&lt;/p&gt;

&lt;p&gt;Then we have &lt;code&gt;.BLKW&lt;/code&gt; which I didn&amp;rsquo;t have much use for in this program but it
was easy to implement after &lt;code&gt;.FILL&lt;/code&gt; so my implementation also initializes to
&lt;code&gt;0x0&lt;/code&gt; which maps to &lt;code&gt;NOP&lt;/code&gt; (or more strictly, unconditional branch to &lt;code&gt;PC&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Finally, &lt;code&gt;.STRINGZ&lt;/code&gt;. As you can see, I&amp;rsquo;ve not implemented any data literals
other than hex yet, so I still have string literals and decimal to implement
but I don&amp;rsquo;t need those to demo that my VM is working.&lt;/p&gt;

&lt;a name="Future-work"&gt;&lt;/a&gt;
&lt;h1&gt;Future work&lt;/h1&gt;

&lt;p&gt;I have some plans for this VM which I&amp;rsquo;m not going to talk about, because I&amp;rsquo;ve
found in my life that talking about an idea to people often exhausts the need
to actually follow through on it - needless to say it&amp;rsquo;s weird dumb bullshit
like you&amp;rsquo;d expect from me.&lt;/p&gt;

&lt;p&gt;The plans which I &lt;em&gt;am&lt;/em&gt; going to talk about here are the 9p debugging features
I&amp;rsquo;d like to implement.&lt;/p&gt;

&lt;p&gt;Essentially, I&amp;rsquo;d like to write a filesystem which has something like the
following layout:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;reg/
  pc
  cond
  r0
  r1
  r2
  r3
  r4
  r5
  r6
mem/
  full
  0/
    0/
      0/
        0
        1
        ...
    1/
    ...
  1/
  2/
  3/
  ...
clk
cons
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The idea here is that you can read and update the state of any given memory
address or register at any point, and you can step the clock simply by reading
&lt;code&gt;clk&lt;/code&gt;. You can follow the program along by reading &lt;code&gt;reg/pc&lt;/code&gt; and then reading
the corresponding address.&lt;/p&gt;

&lt;p&gt;In fact, beyond that I doubt it would be that hard to also have a &lt;code&gt;disasm/&lt;/code&gt;
tree as well which will allow you to follow along with a disassembled version
of the program.&lt;/p&gt;

&lt;p&gt;This then means that your debugger is a simple filesystem API which you can
then instrument and script around using &lt;code&gt;rc&lt;/code&gt;, &lt;code&gt;awk&lt;/code&gt;, whatever. In that sense,
I&amp;rsquo;m kind of surprised that &lt;code&gt;acid&lt;/code&gt; was never designed in this way, because I&amp;rsquo;d
say one of the huge advantages of Plan 9 is that you don&amp;rsquo;t have to learn
someone&amp;rsquo;s implementation of a given API or language when you can simply explore
a filesystem and write tools to manipulate it.&lt;/p&gt;

&lt;p&gt;Anyway, that&amp;rsquo;s what I&amp;rsquo;ve been up to.&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</description>
  <link>https://grimmwa.re/blog/html/00014-lc3.html</link>
  <guid isPermaLink="false">https://grimmwa.re/blog/html/00014-lc3.html</guid>
  <pubDate>Fri Sep 16 11:09:55 2022 +0100</pubDate>
 </item>

 <item>
  <title>00013-emf</title>
  <description type="html">&lt;html&gt;
&lt;head&gt;
&lt;meta charset="utf-8"&gt;
&lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
&lt;link rel="stylesheet" href="style.css"&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;p&gt;This last weekend I spoke at EMF on &amp;ldquo;Computational Alchemy&amp;rdquo;. Thtalk was really
well received and despite the timings not going quite how I intended, I&amp;rsquo;m
really quite happy with the result, along with some of the other things I saw
and did.&lt;/p&gt;

&lt;a name="Cultural-Context"&gt;&lt;/a&gt;
&lt;h1&gt;Cultural Context&lt;/h1&gt;

&lt;p&gt;Generally feedback was really positive, including the constructive criticism: I
was approached afterwards by someone who had converted to Judaism and very
bravely and gently suggested that I might want to talk more about the
differences between Kabbalah and Hermetic Qabalah, particularly given the
history of Christian Cabala (a.k.a. Kabbalah with Jesus hamfistedly bolted on
to Tiphereth) in coercions to convert Jews to Christianity. Which is to say that
forms of syncretized Kabbalah have been used in an anti-semetic way.&lt;/p&gt;

&lt;p&gt;I found this to be very fair criticism personally. I&amp;rsquo;d wanted to make &lt;em&gt;more&lt;/em&gt; of
a point of separating out Hermetic Qabalah and Kabbalah itself but had kind of
screwed up the timings so had to rush past it. I wasn&amp;rsquo;t previously aware of the
cosmology having been used as a tool of this sort of behaviour, but I was aware
of the forced conversion of Jews in Spain at least from having read Owen
Davies' &amp;ldquo;Grimoires&amp;rdquo;.&lt;/p&gt;

&lt;p&gt;I feel that if you&amp;rsquo;re going to engage in syncretism then you need to be aware
of how some forms of syncretism are a subversion more than they are a
celebration, and when presenting that to an audience this point needs to be
made. I at least managed to make it clear that my iterations are iterations
upon an interation which does not accurately reflect the source material, and
that&amp;rsquo;s fundamentally part of the exploration in it&amp;rsquo;s own right.&lt;/p&gt;

&lt;a name="Computer-Church"&gt;&lt;/a&gt;
&lt;h1&gt;Computer Church&lt;/h1&gt;

&lt;p&gt;There was an installation made from several old computers and a Microsoft
Kinect in a shipping container which reactively played music and visuals based
on movements it detected. Now personally I preferred it when it didn&amp;rsquo;t detect
movement, because one of the first things I said to the artist was &amp;ldquo;It&amp;rsquo;s so
nice to see some computers enjoying themselves without people ruining it&amp;rdquo;. The
music as well was ambient, evocative and I suppose a little bit religious in a
sense, and walking in to the place I was washed over with a sense of calm and
oneness.&lt;/p&gt;

&lt;p&gt;So I think I want to do an installation or unofficial event next time: Computer
Mass. With some old computers as set dressing (or an altar if you like), I&amp;rsquo;d
like to come up with a secular religious ceremony that presents the iconography
and lore of computing, kind of in reference to the comfort that we all find in
it. I made allusions to this on social media and I think people are up for it,
which would be great!&lt;/p&gt;

&lt;p&gt;Part of this is in response to the general state of community contribution as
well. As part of the Scottish Consulate village where we had someone cooking up
deep fried buckfast and giving it away, the Scottish Drinking Experience,
contributions to WhiskeyLeaks and essentially running a DnB night every evening
out of our (quite frankly incredibly shonky) tent as DJ&amp;rsquo;d by some other members
of the community, it was easy to see how much that contribution matters but
also where it&amp;rsquo;s lacking. I like the idea of providing some real fringe stuff
that might not make it in the grand scheme of officially sanctioned events but
would be pretty comfortable outside of that.&lt;/p&gt;

&lt;p&gt;Anyway, definitely want to do some more Weird Shit and I think exploring the
shared cultural heritage of computing and acknowledging the impact of religious
experience in a trans-faith kind of way would be a really fun thing to do.&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</description>
  <link>https://grimmwa.re/blog/html/00013-emf.html</link>
  <guid isPermaLink="false">https://grimmwa.re/blog/html/00013-emf.html</guid>
  <pubDate>Wed Jun 29 10:08:39 2022 +0100</pubDate>
 </item>

 <item>
  <title>00012-qabalah-space-program</title>
  <description type="html">&lt;html&gt;
&lt;head&gt;
&lt;meta charset="utf-8"&gt;
&lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
&lt;link rel="stylesheet" href="style.css"&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;p&gt;The thing is, &lt;a href="00011-tarotfs-from-grimm-labs.html"&gt;TarotFS&lt;/a&gt; is not the most
out-there piece of software that I&amp;rsquo;ve worked on under the guise
ocyber-occultism and in fact is first real foray into what I like to call
&amp;ldquo;Computational Alchemy&amp;rdquo; is called &lt;code&gt;qsp&lt;/code&gt; which is short for &lt;a href="https://git.sr.ht/~grimmware/qsp"&gt;Qabalah Space
Program&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The name is obviously a riff on a popular rocket science simulation game, at
least in part because I&amp;rsquo;m hacking together random components with the nominal
goal of exploring some extra-dimensional space and I have absolutely no idea
what I&amp;rsquo;m doing. But let&amp;rsquo;s focus in on the &amp;ldquo;Qabalah&amp;rdquo; part&amp;hellip;&lt;/p&gt;

&lt;a name="Hermetic-Qabalah"&gt;&lt;/a&gt;
&lt;h1&gt;Hermetic Qabalah&lt;/h1&gt;

&lt;blockquote&gt;&lt;p&gt;WARNING: Do your own research! I&amp;rsquo;m oversimplifying and not heavily fact
checking here for the sake of some narrative context. It did not happen
exactly like this.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;To cut a long story short, Qabalah is pretty much a second order descendent of
the school of Jewish mysticism, Kabbalah. Something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Kabbalah -&amp;gt; Christian Cabalah -&amp;gt; Hermetic Qabalah
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;a href="https://en.wikipedia.org/wiki/Kabbalah"&gt;OG Kabbalah&lt;/a&gt; is just straight up
fantastic as far as I&amp;rsquo;m concerned. To summarise (my understanding at least),
it&amp;rsquo;s essentially a system in which God speaking the world into existence
actually functioned, so that the creative act ex nihilo is described by
mechanism of the numbers 1-10 (represented by the 10 Sephiroth, or
&amp;ldquo;emanations&amp;rdquo;) and the 22 letters of the Hebrew alphabet and their particular
categorization (3 mothers, 7 doubles, 12 simples) represented by the paths
between the emanations. Systematically it attempts to describe all of the
features of both the macrocosm and the microcosm through a series of
separations from the godhead, creating dimensionality, movement, birth, death,
so on and so forth. As complicated as that sounds, it&amp;rsquo;s a real simplification.
If you want to lose hours of your life to a deeply complex systematization of
reality and a human as a reflection of that, you know what to start reading
about.&lt;/p&gt;

&lt;p&gt;As you can imagine, due to its lineage Christian mysticism at some point wanted
a piece of the action. Also unsurprisingly, it involved trying to jam Jesus
into the scheme, much as you might try to jam too many syllables into some song
lyrics. I don&amp;rsquo;t have much to say about this because a) I don&amp;rsquo;t know too much
about it and b) Christian syncretism to my untrained eye is like a box mix that
says &amp;ldquo;JUST ADD JESUS&amp;rdquo;.&lt;/p&gt;

&lt;p&gt;Anyway, somewhat unsurprisingly with these concepts being expounded on by the
likes of Agrippa in the 16th century, it was somewhat inevitable that in the
19th century magical revival that people like and adjacent to &lt;a href="https://en.wikipedia.org/wiki/Hermetic_Order_of_the_Golden_Dawn"&gt;The Hermetic
Order of the Golden
Dawn&lt;/a&gt; were
going to pick up on the concept and run with it. Around this sort of time,
Eliphas Levi for instance was the first to attribute the Major Arcana of the
Tarot to the 22 letters of the Hebrew alphabet, creating a direct translation
between the two systems. Moves like this have triggered using the 32 paths of
the Tree of Life (10 emanations, 22 links between them) to be used as a central
pivot of equivalences in modern occultism, and if you&amp;rsquo;re tuned into these
things (or, hilariously, the right kind of anime) you may recognize at least
one graphical formulation of the system, the Etz Chaim or Tree of Life:&lt;/p&gt;

&lt;p&gt;&lt;img src="./images/00012/Kircher_Tree_of_Life.png" title="Anton Kircher's rendition of
the Tree of Life" alt="img" /&gt;&lt;/p&gt;

&lt;p&gt;This is, in of its own right, fascinating. We&amp;rsquo;re talking about a system of
Jewish mysticism that was syncretic of the creation myth, language, mathematics
and medieval terminology being increasingly built upon to become of &amp;ldquo;profound&amp;rdquo;
meaning to esotericism going forward.&lt;/p&gt;

&lt;p&gt;To my mind, there&amp;rsquo;s an exercise in credulity to be done here.&lt;/p&gt;

&lt;a name="Computational-Alchemy"&gt;&lt;/a&gt;
&lt;h2&gt;Computational Alchemy&lt;/h2&gt;

&lt;p&gt;Allow me to change subject for a moment - don&amp;rsquo;t worry, I&amp;rsquo;ll bring it back
round.&lt;/p&gt;

&lt;p&gt;Isaac Newton famously discovered calculus as a collateral offshoot of his work
in alchemy, toward the Magnum Opus of transmuting gold and of creating the
Philosopher&amp;rsquo;s Stone. Here we have an example of credulous engagement with a
historical system claiming antiquity and scientific validity producing
something world-changing, or at least demonstrably incredibly profound and
useful.&lt;/p&gt;

&lt;p&gt;Now profound and useful are all well and good if you&amp;rsquo;re in to productivity, but
personally I&amp;rsquo;m productive enough in my day job. I&amp;rsquo;ll settle for &amp;ldquo;pursue an
arbitrary goal and see what weird shit falls out&amp;rdquo;, and I think that&amp;rsquo;s kind of
what I mean by Computational Alchemy - it&amp;rsquo;s the &amp;ldquo;fuck around and find out&amp;rdquo;
answer to the scientific method. Where the scientific method requires a
hypothesis to disprove in order to not meander off into the tall grass, I&amp;rsquo;m
treating the meander into the tall grass to be the edifying bit - where will it
take me? Who knows? Who the fuck even cares?&lt;/p&gt;

&lt;a name="Qabalah-Space-Program"&gt;&lt;/a&gt;
&lt;h2&gt;Qabalah Space Program&lt;/h2&gt;

&lt;p&gt;Which brings us to what I actually did.&lt;/p&gt;

&lt;p&gt;The first thing to note is that I&amp;rsquo;ve named it for Hermetic Qabalah, on the
basis that I want it to be clear that this is very much a syncretic extension
of a syncretic system, and that I&amp;rsquo;m not about to attempt to retcon my
discoveries onto a system that stands in its own place and time and culture.
19th century Hermeticism, however, is asking for it.&lt;/p&gt;

&lt;p&gt;So what exactly are we going to try to achieve here? Well when I was at
university I did a masters' project on simulating electron energy loss
spectroscopy on transition metal silicides, and part of prepping data for that
was to compose a structurally correct formation of atoms and then running it
through several iterations to essentially seek the lowest energy configuration,
which is to say to find the natural configuration in which all of the forces
are resolved to as close to a stable state as makes no odds.&lt;/p&gt;

&lt;p&gt;So after reading some of
&lt;a href="https://en.wikipedia.org/wiki/Chaos:_Making_a_New_Science"&gt;Chaos&lt;/a&gt; by James
Gleick, one of the many books that I&amp;rsquo;m still half way through, I began to look
at the Tree of Life from the lens of a physics many-body problem - if I
resolved the forces along the paths, what would the resulting configuration
look like? What if I change the resting lengths and coefficients of restitution
of all the paths? What if I map it into 3D space and join Kether to Malkuth
(something you would reasonably do based on an understanding of the Four Worlds
scheme in Kabbalah) and then run the simulation? What will this tell me about
the universe? More importantly, what hilarious side-effects will fall out of
the pursuit?&lt;/p&gt;

&lt;p&gt;The tl;dr is that I&amp;rsquo;ve essentially implemented a scheme for doing this on
9front using libdraw for graphical rendering and composing configurations,
using ndb (yes the network configuration database format) as a graph database,
and a whole lot of farting about in &lt;code&gt;acid&lt;/code&gt; looking for memory management bugs
when my actual programming logic just sucks.&lt;/p&gt;

&lt;p&gt;This post is a bit long in the tooth already though, so let&amp;rsquo;s leave the
implementation and some early results for next time!&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</description>
  <link>https://grimmwa.re/blog/html/00012-qabalah-space-program.html</link>
  <guid isPermaLink="false">https://grimmwa.re/blog/html/00012-qabalah-space-program.html</guid>
  <pubDate>Thu May 26 11:30:51 2022 +0100</pubDate>
 </item>

 <item>
  <title>00011-tarotfs-from-grimm-labs</title>
  <description type="html">&lt;html&gt;
&lt;head&gt;
&lt;meta charset="utf-8"&gt;
&lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
&lt;link rel="stylesheet" href="style.css"&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;a name="TarotFS-from-Grimm-Labs"&gt;&lt;/a&gt;
&lt;h1&gt;TarotFS from Grimm Labs&lt;/h1&gt;

&lt;blockquote&gt;&lt;p&gt;or Why I Stopped Worrying and Wrote A Divination System Considered Harmful&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Trope subtitles are the worst.&lt;/p&gt;

&lt;p&gt;In this post I&amp;rsquo;ll be talking about TarotFS from Grimm Labs, my divination
system filesystem for Plan 9. In part, I&amp;rsquo;m using this as an exercise to figure
out what parts are going to make the cut for my EMFcamp talk.&lt;/p&gt;

&lt;a name="Divination-systems"&gt;&lt;/a&gt;
&lt;h2&gt;Divination systems&lt;/h2&gt;

&lt;p&gt;I&amp;rsquo;ll hopefully talk in depth about this at another time in another place, but
the tl;dr is that my first practical foray into occultism was through
divination systems. I can&amp;rsquo;t remember if I got a tarot deck first (thanks tj!)
or a set of Elder Futhark runes (thanks Joey and Mae!), but the value was
pretty easy to see from the point of view of a person struggling so much with
their emotional and mental health during COVID. I was able to pick out images
at random and see how they resonated with me, and what the historical symbolism
was around these archetypes that could be plumbed further to find more
interpretations and develop my own associations.&lt;/p&gt;

&lt;p&gt;Looking back it makes a lot of sense - people think in terms of narratives,
allegories and symbols, so having these arrayed out in front of you, drawn at
random such as they&amp;rsquo;re &amp;ldquo;presented by the universe&amp;rdquo; (a trope deeply embedded in
culture and religion) strikes a chord and drives engagement with what is
essentially a system for introspection and decision making with an RNG (random
number generator) built in.&lt;/p&gt;

&lt;a name="Where-did-the-idea-come-from-3f-"&gt;&lt;/a&gt;
&lt;h2&gt;Where did the idea come from?&lt;/h2&gt;

&lt;p&gt;Okay, so one of my biggest projects and the one I talk about the most if you
know me in person (or on IRC or on gridchat) is TarotFS. It&amp;rsquo;s really the first
use case for Plan 9 from Bell Labs (or the fork 9front which I&amp;rsquo;m going to
lovingly refer to as ⑨ from here on in, despite the fact that it completely
fucks with &lt;code&gt;vt&lt;/code&gt; not to use a single width character but here we are) that I had
which was really an occult system. And ⑨ really suits the use-case. One of the
most famous if not totally fundamental ideas behind Plan 9 is putting the Unix
concept of &amp;ldquo;everything is a file&amp;rdquo; to shame, showing it as the true hyperbole
that it is. In ⑨ just about everything actually &lt;em&gt;is&lt;/em&gt; a file, and the real
case-in-point here is the 9p protocol. When you access the web, you can do that
using webfs using the 9p protocal bridging with HTTP. Want to make a TCP
connection? Do the same. Want to access a file? You guessed it, use 9p.&lt;/p&gt;

&lt;p&gt;So when I started playing around with ⑨, I was really interested in this
concept and so I started playing with webFS and really liked how it effectively
meant you could leave your HTTP transactions on disk. Around the same time, I
was also reading Techniques of High Magic by Francis King and Stephen Skinner
(or at least that&amp;rsquo;s how I remember it? It could be that the book&amp;rsquo;s right in
front of me&amp;hellip;) and about various divination systems including geomancy and
runecasting. Tarot stood out because it&amp;rsquo;s well known in Western society as
being&amp;hellip; well&amp;hellip; goth as fuck quite frankly, and I was in a place where
archetype systems were incredibly appealing to me. Possibly more on that
elsewhere or later or something.&lt;/p&gt;

&lt;p&gt;At any rate, the mode of transaction with webfs really struck a chord:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;† cd /mnt/web/
† ls
clone
ctl
† cat clone
0
† cd 0
† ls
body
ctl
parsed
postbody
† echo 'url https://grimmwa.re' &amp;gt; ctl
† cat parsed/url
https://grimmwa.re/† 
† 
† cat body
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
  &amp;lt;title&amp;gt;(((GRIMMWA.RE&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;
    &amp;lt;meta charset="UTF-8"&amp;gt;
    ... and so on ...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The workflow goes like this:
1. &amp;ldquo;clone&amp;rdquo; a new session by reading the &lt;code&gt;clone&lt;/code&gt; file. This will return an
   integer which will be the name of the directory which will be created for
   your session (which you can see we &lt;code&gt;cd&lt;/code&gt; into.
2. Enter any parameters for the session into the &amp;ldquo;control&amp;rdquo; file for the
   session, &lt;code&gt;ctl&lt;/code&gt; - in this case we&amp;rsquo;re entering the (somewhat necessary) url
   parameter. We can then verify that we entered it correctly by reading out
   the &lt;code&gt;parsed/url&lt;/code&gt; file.
3. Read out the request body by reading the &lt;code&gt;body&lt;/code&gt; file! When we do this, it
   looks like we&amp;rsquo;re reading a file from disk, but actually we&amp;rsquo;re dispatching
   the HTTP request that we&amp;rsquo;ve prepared by creating the session and telling it
   the URL, and this is essentially the response body!&lt;/p&gt;

&lt;p&gt;Like I say, you have the transaction apparently &amp;ldquo;on disk&amp;rdquo; and are able to set
parameters and headers and the like by writing to files and reading responses
by reading them. A query and a response, all effectively encoded statefully in
a way that you can sensibly manage and retrospect on.&lt;/p&gt;

&lt;p&gt;Something twigged with me here, because it was at the intersection of ideas - I
was exploring ⑨ which I was clearly going to do from a participatory viewpoint,
and I was also beginning to start to understand some of the less supernatural
value in divination systems, and frankly I understand by doing and I needed a
distraction.&lt;/p&gt;

&lt;p&gt;And somewhere in here is where TarotFS was born as a concept.&lt;/p&gt;

&lt;a name="How-does-it-work-then-3f-"&gt;&lt;/a&gt;
&lt;h2&gt;How does it work then?&lt;/h2&gt;

&lt;p&gt;Yes, we&amp;rsquo;re doing this in skip-to-the-end style, mostly because I didn&amp;rsquo;t make
enough notes on the way so I can&amp;rsquo;t actually remember what I did and what
problems I hit and why. A big warning here is that the code&amp;rsquo;s a bit of a trash
fire, so I&amp;rsquo;m going to present you with a couple of things: a TarotFS session,
which I&amp;rsquo;ll use to explain a high level idea of the basic usage and rationale,
and a manpage which I&amp;rsquo;ll dump at the end.&lt;/p&gt;

&lt;a name="Example-Session"&gt;&lt;/a&gt;
&lt;h3&gt;Example Session&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;† tarot -p definitions -dkP
definitions/Smith-Waite
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We launch tarotFS with a definitions directory, and descriptions (&lt;code&gt;-d&lt;/code&gt;),
keywords (&lt;code&gt;-k&lt;/code&gt;) and paths (&lt;code&gt;-P&lt;/code&gt;) enabled in the card output. This is pretty
much the whole selection as we&amp;rsquo;ll see in a bit! Essentially these three options
only do anything if you specify a definitions directory as they simply read
data for the relevant card from it. TarotFS helpfully then tells you which
subdirectory of definitions it&amp;rsquo;s using because I haven&amp;rsquo;t fixed that old shitty
debug output yet!&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;† cd /mnt/tarot
† ls
clone
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;/mnt/tarot&lt;/code&gt; is the default mountpoint - not much to see here yet apart from
the &lt;code&gt;clone&lt;/code&gt; file!&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;† cat clone
1
deckstyle Smith-Waite
definitions_path definitions/Smith-Waite
keywords 1
description 1
orientation on
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When we read the file it does what webfs does - creates a new session for us!
This file actually redirects reads and writes from the &lt;code&gt;ctl&lt;/code&gt; file from the new
spread, so we could actually have cloned the session by overriding a setting
with a write instead if we really knew what we were doing.&lt;/p&gt;

&lt;p&gt;Helpfully, you can see that when I hacked in the &lt;code&gt;orientation&lt;/code&gt; parameter
recently I didn&amp;rsquo;t check my boolean convention and have instead used &amp;ldquo;off&amp;rdquo; and
&amp;ldquo;on&amp;rdquo;. Some parts of tarotFS are wildly inconsistent, and for my part I will
actually fix this. At some point. Maybe.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;† cd 1
† ls
ctl
draw
remaining
shuffle
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Other than the &lt;code&gt;ctl&lt;/code&gt; file, it should be pretty much immediately obvious what
each of these files will do if you read them!&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;† echo spread past present future advice &amp;gt; ctl
† cat ctl
1
deckstyle Smith-Waite
spread past present future advice
definitions_path definitions/Smith-Waite
keywords 1
description 1
orientation on
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;For the sake of showing off we&amp;rsquo;re going to specify the names of some of the
cards which will be drawn. By default, the card filenames are just incrementing
numbers, but these arguments will make so that we get names e.g. &lt;code&gt;1:past&lt;/code&gt;,
&lt;code&gt;2:present&lt;/code&gt; and so on. Part of the advantage of this is you can&amp;rsquo;t decide on one
spread and then change your mind half way through when you get a card you don&amp;rsquo;t
like ;)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;† cat remaining
78
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;78 cards in a standard Rider-Smith-Waite deck!&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;† cat draw
Four of Pentacles
reversed
path  definitions/Smith-Waite/Pentacles/Four/
UPRIGHT: Saving money, security, conservatism, scarcity, control.
REVERSED: Over-spending, greed, self-protection.


The Four of Pentacles shows a man sitting on a stool, beyond the
boundaries of his hometown. His arms are wrapped tightly around a coin
as if he fears he may lose it if he loosens his grip. He balances
... &amp;lt;SNIP&amp;gt; ...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So what we&amp;rsquo;re seeing here is the contents of one of the cards being drawn,
containing the orientation (on by default, cards can be upright or reversed),
the path of the card definition that the keywords and definition text are
coming from, and then the keywords followed by the definitions.&lt;/p&gt;

&lt;p&gt;The path is useful if you want to do things like ship the card images! It makes
it simple to script a setup to view the spread graphically!&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;† cat remaining
77
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Just in case you doubted that these are actually being drawn from a deck&amp;hellip;&lt;/p&gt;

&lt;p&gt;At any rate, that was a bit more verbose than we care about right now so we can
toggle the descriptions and the orientations off:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;† echo description &amp;gt; ctl
† echo orient &amp;gt; ctl
† cat ctl
1
deckstyle Smith-Waite
spread past present future advice
definitions_path definitions/Smith-Waite
keywords 1
description 0
orientation off
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now when we draw, we&amp;rsquo;ll just get the path and the keywords:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;† cat draw
Seven of Cups
path  definitions/Smith-Waite/Cups/Seven/
UPRIGHT: Opportunities, choices, wishful thinking, illusion.
REVERSED: Alignment, personal values, overwhelmed by choices.

† cat draw
Ⅷ: Justice
path  definitions/Smith-Waite/Major/Justice/
UPRIGHT: Justice, fairness, truth, cause and effect, law
REVERSED: Unfairness, lack of accountability, dishonesty

† cat draw
ⅩⅩ: Judgement
path  definitions/Smith-Waite/Major/Judgement/
UPRIGHT: Judgement, rebirth, inner calling, absolution
REVERSED: Self-doubt, inner critic, ignoring the call
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So what about the card names and the state on disk I was talking about? Well
here we can see that the output can be read again by reading out the respective
numbered file:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;† ls
1:past
2:present
3:future
4:advice
ctl
draw
remaining
shuffle
† cat remaining
74
&lt;/code&gt;&lt;/pre&gt;

&lt;a name="Features-and-misfeatures"&gt;&lt;/a&gt;
&lt;h3&gt;Features and misfeatures&lt;/h3&gt;

&lt;p&gt;A lot of this has grown organically, so there are a few warts, gotchas and
implementation details:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Definitions are user-supplied because I ripped mine off from the internet so
they&amp;rsquo;re not mine to redistribute&lt;/li&gt;
&lt;li&gt;A few &amp;ldquo;deckstyles&amp;rdquo;, however, are supplied (see &lt;code&gt;/lib/tarot/decks&lt;/code&gt;)! The
default is &lt;code&gt;Smith-Waite&lt;/code&gt; (as in the famous Rider-Waite deck, for whom Rider
is a publisher and Pamela Coleman-Smith is the largely unknown &lt;em&gt;artist&lt;/em&gt; who
actually did most of the &lt;em&gt;work&lt;/em&gt;), but we also have the Marseille deck which
uses slightly different card and suit names, and also &lt;code&gt;Elder-Futhark&lt;/code&gt; which
is me showing off that actually technically you can use TarotFS to do
runecasting as well:&lt;/li&gt;
&lt;/ol&gt;


&lt;pre&gt;&lt;code class="```"&gt;   † tarot
   † echo deckstyle Elder-Futhark &amp;gt; /mnt/tarot/clone
   † cd /mnt/tarot/1
   † cat draw
   ᚺ
   reversed
&lt;/code&gt;&lt;/pre&gt;

&lt;ol&gt;
&lt;li&gt;Some arguments and commands are a little inconsistent or poorly documented -
sorry about that!&lt;/li&gt;
&lt;li&gt;I&amp;rsquo;ve also been working on a fun script for rendering the spread in a &lt;code&gt;rio&lt;/code&gt;
window, with a tarot cloth as a background and everything, but it requires a
patched version of rio and also a patch which I&amp;rsquo;ve written for &lt;code&gt;page&lt;/code&gt; to
auto-resize the image which I&amp;rsquo;ve not gotten round to documenting yet (and
this post is getting pretty long anyway!)&lt;/li&gt;
&lt;/ol&gt;


&lt;a name="Future-work"&gt;&lt;/a&gt;
&lt;h3&gt;Future work&lt;/h3&gt;

&lt;p&gt;I&amp;rsquo;ve got a few plans here. For one, I&amp;rsquo;d like to be able to use arbitrary
bitstreams as an entropy source given that none of the randomness here is used
for cryptographic purposes, so it would be great to be drawing the randomness
from the processes of the universe (like gridchat!). Some more work to improve
the consistency of the interface and documentation would certainly be good, and
I&amp;rsquo;d also like to do more work on convenience scripts for graphically rendering
in Rio for example. Finally, a good default definitions source which is
appropriately licensed for redistribution would also be great.&lt;/p&gt;

&lt;a name="Appendix:-Manpage"&gt;&lt;/a&gt;
&lt;h1&gt;Appendix: Manpage&lt;/h1&gt;

&lt;p&gt;This needs updating! I&amp;rsquo;ve not actually added the instructions on using the
&lt;code&gt;orient&lt;/code&gt; command and a couple of other things, but fixing instead of writing
is how I end up never writing things.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;

     TAROT(4)                                                 TAROT(4)

     NAME
          tarot - tarot card filesystem

     SYNOPSIS
          tarot [ -DdkPh ] [ -p definitions ] [ -m mtpt ]

     DESCRIPTION
          Tarotfs presents a file system interface to generating and
          interacting with tarot spreads.  Tarotfs mounts itself at
          mtpt (default /mnt/tarot).  The -D flag enables 9P debug
          prints and other debug files and -h displays the short list
          of options.

          Tarotfs also optionally supports displaying keywords and
          definitions when reading files for the drawn cards by pro-
          viding a definitions directory with the flag -p wherein the
          directory structure should follow the structure:
          Name/Suit/Card/ and contain the files keywords and
          description, both of which can be freeform text files. The
          keywords should ideally contain a short list of keywords to
          associate with both the upright and reversed configuration
          of each file. The Name/Suit/Card naming convention has the
          following restrictions:

          Name This can be any directory name, and isn't actually uti-
               lized (yet).  Currently tarotfs will just pick the
               first named pack inside the supplied definitions direc-
               tory.

          Suit and Card
               These must match exactly the form given in `suits`, and
               `major` and `minor` for each deck definition, but with
               anything preceding and including a single colon charac-
               ter stripped, and all spaces removed. For example: "I:
               The Magician" should map to "TheMagician".   Any major
               arcana cards will always map to the suit name `Major`.

          The flags -dkP enable displaying the definitions, keywords
          and definition paths when reading the card files respec-
          tively when -p is supplied.

          The top level contains the file clone, and the directory
          card_library, the latter of which contains a tree of all the
          available cards.

          Reading or writing to the clone file creates a new numbered
          subdirectory for a new tarot spread and redirects the opera-
          tion to the ctl file at the top of the directory.

          Each "spread" directory contains the files: ctl, draw,
          shuffle and remaining.

          The ctl file is used to control the various settings for the
          spread by writing commands and arguments to the file:

          spread
               Sets the names for the drawn cards in addition to their
               numbers.  Arguments are space separated.

          keywords
               Toggles whether keywords are displayed when reading
               card files

          descriptions
               Toggles whether descriptions are displayed when reading
               card files

          paths
               Toggles whether definition paths are displayed when
               reading card files

          Reading the ctl file will return the spread number (matching
          the spread's directory) on the first line. If a deck defini-
          tion was supplied, it will also print on the following lines
          the attributes deckpath,keywords,description each followed
          by a space and then the path of the deck definition and the
          booleans for whether keywords and descriptions are enabled
          for the spread respectively.

          Reading draw draws a card, reading remaining shows how many
          cards are remaining in the deck and shuffle will reshuffle
          the deck.

          If the -D option is passed on startup, there will also be
          the deck file which outputs the integer representations of
          all the cards in the deck along with their number order.
          This is currently only used for debugging purposes.

     EXAMPLE
          The following shows a simple example of cloning a new
          spread, setting the spread name and then drawing all the
          cards from the spread.

          † tarot
          † ls /mnt/tarot
          /mnt/tarot/card_library
          /mnt/tarot/clone
          † cat /mnt/tarot/clone
          1
          † cd /mnt/tarot/1
          † ls
          ctl
          draw
          remaining
          † echo spread past present future advice &amp;gt; ctl
          † for(i in `{seq 1 4}) cat draw
          Four of Pentacles
          upright
          Ⅱ: The High Priestess
          reversed
          King of Wands
          upright
          Seven of Cups
          reversed
          † ls
          1:past
          2:present
          3:future
          4:advice
          ctl
          draw
          remaining
          † cat remaining
          74

     SOURCE
          https://git.sr.ht/~grimmware/tarotfs
&lt;/code&gt;&lt;/pre&gt;
&lt;/body&gt;
&lt;/html&gt;</description>
  <link>https://grimmwa.re/blog/html/00011-tarotfs-from-grimm-labs.html</link>
  <guid isPermaLink="false">https://grimmwa.re/blog/html/00011-tarotfs-from-grimm-labs.html</guid>
  <pubDate>Fri May 13 10:59:24 2022 +0100</pubDate>
 </item>

 <item>
  <title>00010-magnum-opus</title>
  <description type="html">&lt;html&gt;
&lt;head&gt;
&lt;meta charset="utf-8"&gt;
&lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
&lt;link rel="stylesheet" href="style.css"&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;a name="What-27-s-been-going-on-at-Grimm-Labs"&gt;&lt;/a&gt;
&lt;h1&gt;What&amp;rsquo;s been going on at Grimm Labs&lt;/h1&gt;

&lt;a name="What-I-27-ve-not-shared"&gt;&lt;/a&gt;
&lt;h2&gt;What I&amp;rsquo;ve not shared&lt;/h2&gt;

&lt;p&gt;I&amp;rsquo;ve been away for a few days with some time to think about the division in my
life between my work life and my life&amp;rsquo;s work - that is to say, what I get paid
to produce and what I &lt;em&gt;want&lt;/em&gt; to produce. Fundamentally I&amp;rsquo;m a creative person
who needs to have some kind of &amp;ldquo;output&amp;rdquo; in order to feel satisfied, but it has
to be something that comes from within rather than being something I&amp;rsquo;m obliged
to work on by some external entity (least of all the coercion of capitalism
making me do it in order to survive).&lt;/p&gt;

&lt;p&gt;Something that&amp;rsquo;s been on my mind a lot lately is sharing what I do, and I&amp;rsquo;ve
written about this before. The dumb thing that I&amp;rsquo;ve realised is that I haven&amp;rsquo;t
actually written &lt;em&gt;anything&lt;/em&gt; about what I consider to be my most important line
of work, what essentially comes closest to the goal of Computational Alchemy
(or &amp;ldquo;Occultism fuck-around-and-find-out but on a computer&amp;rdquo;). We&amp;rsquo;ll call this my
&amp;ldquo;Magnum Opus For Now&amp;rdquo; (because lol).&lt;/p&gt;

&lt;p&gt;So the core of my Computational Alchemy work is on the late 80s and early 90s
research operating system Plan 9 from Bell Labs. Rather than go deep into the
rationale here, I&amp;rsquo;m going to leave that up to a later post to try and cement my
commitment to continue writing. But essentially I use a distribution called
9front which has some newer hardware support and a more active and modern
community, and attempt to credulously take esoteric systems and codify them, or
otherwise participate in the only way I know how: technology. So far, I&amp;rsquo;ve
done work on usability hacks to customise the system to work in a way I get
along with, but also produced the foundations of a set of occult software.&lt;/p&gt;

&lt;a name="Body-of-work"&gt;&lt;/a&gt;
&lt;h2&gt;Body of work&lt;/h2&gt;

&lt;a name="Plan-9-Usability-hacks"&gt;&lt;/a&gt;
&lt;h3&gt;Plan 9 Usability hacks&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Keyboard-based text selection in the core &amp;ldquo;command prompt&amp;rdquo; interface with
some other keybindings for good measure&lt;/li&gt;
&lt;li&gt;Shell customizations for command history&lt;/li&gt;
&lt;li&gt;Convenience hacks on the core image and document viewer&lt;/li&gt;
&lt;li&gt;Helper scripts for connecting to 9p.zone gridchat&lt;/li&gt;
&lt;/ul&gt;


&lt;a name="Plan-9-Occult-software"&gt;&lt;/a&gt;
&lt;h3&gt;Plan 9 Occult software&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A program for doing tattva vision meditation&lt;/li&gt;
&lt;li&gt;A pretty fully featured tarot card filesystem that also supports runic
alphabets and custom oracle decks&lt;/li&gt;
&lt;li&gt;The beginning framework of what I like to lovingly call Qabalah Space
Program, a suite of programs for visualizing, modeling and simulating the Etz
Chaim (Kabbalistic Tree of Life) as a physics many-body problem (amongst
other things) to see what falls out.&lt;/li&gt;
&lt;/ul&gt;


&lt;a name="Other-weird-shit"&gt;&lt;/a&gt;
&lt;h3&gt;Other weird shit&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Some code to do format conversions of astrological catalogues which I
accidentally got nerd sniped on the other day and never actually finished.
Not sure that I&amp;rsquo;m too committed here.&lt;/li&gt;
&lt;/ul&gt;


&lt;a name="So-what-next-3f-"&gt;&lt;/a&gt;
&lt;h2&gt;So what next?&lt;/h2&gt;

&lt;p&gt;Effectively I&amp;rsquo;m committing myself to actually writing about this work to share
it with the world. TarotFS certainly deserves a deeper look, as I&amp;rsquo;ve worked on
it pretty extensively and actually shared the work at a virtual conference.
I&amp;rsquo;ve also submitted a talk to EMFcamp which I&amp;rsquo;m really hopeful about getting
accepted, but actually writing about my work is a good way to a) prep and b)
not put all my eggs in one basket. (EDIT: in between writing this and actually
publishing it the talk got accepted so YAY FOR ME, but also the point still
stands)&lt;/p&gt;

&lt;p&gt;Anyway, I guess watch this space! I have an rss feed at
&lt;a href="https://grimmwa.re/blog/feed.xml"&gt;https://grimmwa.re/blog/feed.xml&lt;/a&gt; that&amp;rsquo;s fully
populated with the content I produce here, so add that to your feed reader if
you want to follow along!&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</description>
  <link>https://grimmwa.re/blog/html/00010-magnum-opus.html</link>
  <guid isPermaLink="false">https://grimmwa.re/blog/html/00010-magnum-opus.html</guid>
  <pubDate>Tue May 3 21:06:20 2022 +0100</pubDate>
 </item>

 <item>
  <title>00009-magic-and-performance</title>
  <description type="html">&lt;html&gt;
&lt;head&gt;
&lt;meta charset="utf-8"&gt;
&lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
&lt;link rel="stylesheet" href="style.css"&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;p&gt;A while ago (2020? God damn it&amp;rsquo;s been a long couple of years.) I read a book
called &lt;em&gt;Magic, Science, Religion and the Scope of Rationality&lt;/em&gt; by Stanley
Jeyaraja Tambiah, which is essentially an anthropology and philosophy text
on&amp;hellip; well what you&amp;rsquo;d expect having read the title. One of my favourite points
made in reference to some peak academic sass (very possibly Wittgenstein) was
a rebuttal about how the beliefs were &amp;ldquo;in error&amp;rdquo; or essentially that people who
carry out some of the cultural practices that we in Western culture consider to
be &amp;ldquo;unenlightened&amp;rdquo; is (to put it bluntly) sourced from stupidity.&lt;/p&gt;

&lt;p&gt;The argument goes that in cultures that perform rain dances, they &lt;em&gt;only&lt;/em&gt; do
them before the rainy season starts. Because they&amp;rsquo;re not stupid, and they don&amp;rsquo;t
think that dancing makes it rain. This kind of cause-and-effect thinking is
very post-rationalism, because science itself does not (in the modern era)
encompass human nature enough to account for performative and participatory
action.&lt;/p&gt;

&lt;p&gt;If that didn&amp;rsquo;t make an awful lot of sense I&amp;rsquo;m not surpised, I&amp;rsquo;m a grate riter
and I&amp;rsquo;ve also been mulling the idea for quite some time to make it sit right
and it&amp;rsquo;s only recently settled.&lt;/p&gt;

&lt;p&gt;Take for example a teenager playing air guitar in their bedroom along to some
rock band. You wouldn&amp;rsquo;t look at that and suggest that person thinks they&amp;rsquo;re
actually in the band, and they&amp;rsquo;re clearly not contributing to the music,
practicing for some real-world skill or even performing for an audience&amp;hellip;
They&amp;rsquo;re simply participating through a want to somehow be involved with
something of importance.&lt;/p&gt;

&lt;p&gt;Obviously I can only speak to my experience of participatory practice, and for
me it&amp;rsquo;s got a lot to do with the balance between agency and control. By writing
occult software for a defunct operating system that nobody uses for profit, I
am participating in a theoretical world where humanism and utility is valued
over economic growth - a hobby that somewhat unsurprisingly grew out of a
global pandemic in which we sacrificed lives in order to appease the invisible
hand of the free market. By doing tarot every day, I pause to reflect and seek
and feel like I&amp;rsquo;m receiving help from without instead of suffering on the
continual treadmill of informational and social engagement.&lt;/p&gt;

&lt;p&gt;That said I&amp;rsquo;m not great at performative ritual personally. Aside from a couple
of banishing rituals to stop me from dwelling on things I can&amp;rsquo;t control I still
haven&amp;rsquo;t developed that muscle of turning to participatory things in order to
engage with the ebb of life rather than try to wrestle it in the direction I
feel it should be going. Maybe that&amp;rsquo;s next?&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</description>
  <link>https://grimmwa.re/blog/html/00009-magic-and-performance.html</link>
  <guid isPermaLink="false">https://grimmwa.re/blog/html/00009-magic-and-performance.html</guid>
  <pubDate>Thu Mar 17 10:10:59 2022 +0000</pubDate>
 </item>

 <item>
  <title>00008-to-dispel</title>
  <description type="html">&lt;html&gt;
&lt;head&gt;
&lt;meta charset="utf-8"&gt;
&lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
&lt;link rel="stylesheet" href="style.css"&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;a name="To-Believe"&gt;&lt;/a&gt;
&lt;h1&gt;To Believe&lt;/h1&gt;

&lt;p&gt;I suppose that part of my journey delving into magical and religious practice
is to understand the utility of belief in greasing the wheels of life (&amp;hellip; a
mixed metaphor of dubious provenance if ever I wrote one). After all, I am
very much a nihilist and as the old adage goes &amp;ldquo;[if] Nothing Is True [then]
Everything Is Permitted.&amp;rdquo;&lt;/p&gt;

&lt;p&gt;One very fundamental tenet of Chaos magic and similar systems is that you can
choose your belief to suit your purposes, or even more chaotically choose your
belief just to see what happens. It&amp;rsquo;s very much the alchemy to religion&amp;rsquo;s
science - the &amp;ldquo;fuck around and find out&amp;rdquo; of belief systems if you will.&lt;/p&gt;

&lt;p&gt;Personally I&amp;rsquo;m not much of an adherent to the random choosing of belief, or at
least not yet. Those that are prepared to precipitate &amp;ldquo;madness&amp;rdquo;, however you
want to define that, clearly don&amp;rsquo;t have much to lose societally, and I&amp;rsquo;m very
not in that place. I&amp;rsquo;ve invested a lot of time learning how to fit in with
&lt;del&gt;your&lt;/del&gt; human society, and it&amp;rsquo;s been hard won.&lt;/p&gt;

&lt;p&gt;At any rate, I can see the wisdom of picking belief to facilitate some kind of
premeditated functional purpose. It turns out that in adopting that philosophy,
pretty much every attempt to adopt a belief to my own personal utility has
really ended up with me shedding one instead.&lt;/p&gt;

&lt;a name="To-disbelieve"&gt;&lt;/a&gt;
&lt;h1&gt;To disbelieve&lt;/h1&gt;

&lt;p&gt;When you engage in the practice of reasoning about what arbitrary belief you
could adopt in order to better yourself, effectively you&amp;rsquo;re examining the
beliefs you already hold in order to modify them to better fit the result you
want. But ultimately I&amp;rsquo;m not of the ilk to reason that my beliefs should really
shape my reality - I think they change how you perceive problems, focus your
time, your interactions, your mode of communication. After all, we don&amp;rsquo;t have
that many IRL Disney Princesses despite Mickey&amp;rsquo;s psyops and propaganda
divisions' best efforts.&lt;/p&gt;

&lt;p&gt;So I ask myself what beliefs facilitate things like a less anxious approach to
life - less dwelling on the worst that could potentally happen, less expecting
the worst from people, less expectation on myself to solve everyone&amp;rsquo;s problems.
What I come away with is the realization that I believe I have responsibility
over those things, despite having very little agency over them.&lt;/p&gt;

&lt;p&gt;I like to use the analogy that we have at least two worlds we have to deal with
at any moment: the model of the world in our own heads that we use as an
abstraction to reason, predict and generally model our interactions with the
&amp;ldquo;real&amp;rdquo; world, and the physical consensus reality. A lot of satisfaction can be
gained when we can converge the two (and conversely a lot of mental anguish
when we can&amp;rsquo;t) and there are two ways to do this: shape expectation to reality
or change the physical reality to expectation.&lt;/p&gt;

&lt;p&gt;In looking at my own beliefs, I realised that I tend to do the latter:
expecting the world to react sensibly to COVID for example and getting stressed
about the human cost of it not. But I don&amp;rsquo;t have agency over that, and I
realised that I was hurting myself by carrying around the belief that people
should be better and more caring. The thing is they&amp;rsquo;re not, and to compound
that to believe that they are is to diminish your own good qualities. Another
example: pretty much every kind person I know who has suffering in their life
at the moment will caveat it with &amp;ldquo;&amp;hellip; but that&amp;rsquo;s nothing compared to what the
people in Ukraine are going through.&amp;rdquo; This one grinds my gears really hard.
Somehow we have created a social and moral system in which the kind of people
who consider others will disregard the immediate problems of their own lives
because of some perverse flavour of subjectivism in which only other people&amp;rsquo;s
problems count. I&amp;rsquo;m looking at you here Western theology&amp;hellip; At any rate, the
belief here serves nobody. Are you empowered to solve the problems in Ukraine?
I mean sure you can try to &lt;em&gt;help&lt;/em&gt; but the problems there are caused by much
more powerful people who want us to think that &lt;em&gt;everyone&lt;/em&gt; has their part to
play because &amp;ldquo;democracy&amp;rdquo;. On the flip side, for better or worse we live in our
own personal problems and are at least in some way empowered to fix them, and
to do so is not selfish or tone-deaf.&lt;/p&gt;

&lt;p&gt;Oh look I made it through without saying &amp;ldquo;cultural hegemony&amp;rdquo; or &amp;ldquo;ruling class&amp;rdquo;.&lt;/p&gt;

&lt;a name="The-tl-3b-dr"&gt;&lt;/a&gt;
&lt;h1&gt;The tl;dr&lt;/h1&gt;

&lt;p&gt;Yes I put it at the end. Sorry not sorry.&lt;/p&gt;

&lt;p&gt;The ultimate point of that meandering diatribe which probably didn&amp;rsquo;t come
through is that we all have beliefs that don&amp;rsquo;t serve us in any functional way,
and actually serve to empower the ruling class by means of cultural hegemony.
These norms are so intrinsic to the way we&amp;rsquo;re raised that it&amp;rsquo;s incredibly
difficult to spot them without explicit effort, and even then breaking the
cycle is hard - you can watch other people succumb to these beliefs, point them
out, have them agree with you and then continue to perform them simply because
they can&amp;rsquo;t quite give themselves permission to break rank. None of us truly can
because the power of how the crowd thinks and acts is a powerful, heady
pheremone. It&amp;rsquo;s almost like breaking the laws of physics. Like magic.&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</description>
  <link>https://grimmwa.re/blog/html/00008-to-dispel.html</link>
  <guid isPermaLink="false">https://grimmwa.re/blog/html/00008-to-dispel.html</guid>
  <pubDate>Thu Mar 10 10:24:50 2022 +0000</pubDate>
 </item>

 <item>
  <title>00007-to-write</title>
  <description type="html">&lt;html&gt;
&lt;head&gt;
&lt;meta charset="utf-8"&gt;
&lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
&lt;link rel="stylesheet" href="style.css"&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;a name="Why-write-at-all-3f-"&gt;&lt;/a&gt;
&lt;h1&gt;Why write at all?&lt;/h1&gt;

&lt;p&gt;I&amp;rsquo;ve been thinking a lot lately about how I want to share my work.&lt;/p&gt;

&lt;p&gt;It&amp;rsquo;s pretty difficult for me to engage with sharing these days because of what
the idea of &amp;ldquo;sharing&amp;rdquo; even entails these days. When you share something, that
usually means that you&amp;rsquo;re clicking (clicking&amp;hellip; how archaic!) a button on a
social media site or app to effectively redistribute that thing within a context
that&amp;rsquo;s somehow related to you. This is often to the aims of reinforcing your
personal brand, driving up &amp;ldquo;engagement&amp;rdquo; or simply just a reflex reaction. It&amp;rsquo;s
what you do on the modern internet.&lt;/p&gt;

&lt;p&gt;This has been such a big question in my mind because the things I&amp;rsquo;ve been
working on of late have been&amp;hellip; They&amp;rsquo;ve been weird (Normally I&amp;rsquo;d dive into that
but I&amp;rsquo;m trying this thing where I don&amp;rsquo;t fall into some completely unscoped
meandering prose on whatever discursive topic comes to mind).&lt;/p&gt;

&lt;p&gt;And that&amp;rsquo;s a core feature of esotericism - the semiotics of any esoterica are
designed such to illicit a response from the &amp;ldquo;initiated&amp;rdquo;, but when you&amp;rsquo;re
working on your own esoterica in some dark corner and you decide you want to
share your work, who do you share it with? Which bits do you explain first?
Explain &lt;em&gt;at all&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;The only way to understand, really, is to do. So I promised myself this morning
that I&amp;rsquo;d write something tonight, working towards sharing my work. I like to
write because it takes what&amp;rsquo;s internal to your mind, the vague discursive
processes that feel concrete and completed, and actually forces serialization
and by extension, internal consistency. You make those links explicit where
they&amp;rsquo;re there and removes them where they aren&amp;rsquo;t. It&amp;rsquo;s a process of conceptual
solidification. I&amp;rsquo;m just not very structured about it :P&lt;/p&gt;

&lt;p&gt;It&amp;rsquo;s a marathon not a race, however, and whilst I&amp;rsquo;d like to write something good
and considered and structured in consistent, clear and entertaining prose,
instead I&amp;rsquo;m going to settle for just turning up for my attendance mark and to
rebreak the seal.&lt;/p&gt;

&lt;p&gt;I would like to write about the work I&amp;rsquo;ve been doing with Plan 9 and occultism,
but to do that I think I need to begin to understand what I want to share, why
and with whom. This is the first step, and hopefully I&amp;rsquo;ll be doing it by writing
here. We shall see.&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</description>
  <link>https://grimmwa.re/blog/html/00007-to-write.html</link>
  <guid isPermaLink="false">https://grimmwa.re/blog/html/00007-to-write.html</guid>
  <pubDate>Tue Feb 15 12:11:06 2022 +0000</pubDate>
 </item>

 <item>
  <title>00006-crossbow-and-gdb</title>
  <description type="html">&lt;html&gt;
&lt;head&gt;
&lt;meta charset="utf-8"&gt;
&lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
&lt;link rel="stylesheet" href="style.css"&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;p&gt;Yesterday I took a break from work for half an hour to just do some of my own
futzing about, and I came back to something I&amp;rsquo;d already been playing around
with, which was attempting to figure out why the feed processor I&amp;rsquo;d just
downloaded and built wouldn&amp;rsquo;t handle the main feed,
&lt;a href="https://www.databreaches.net/feed/"&gt;https://www.databreaches.net/feed/&lt;/a&gt; that I wanted to view.&lt;/p&gt;

&lt;a name="cRoSSbow"&gt;&lt;/a&gt;
&lt;h1&gt;cRoSSbow&lt;/h1&gt;

&lt;p&gt;I first found out about &lt;code&gt;crossbow&lt;/code&gt; on &lt;a href="https://lobste.rs/s/g3clcu/crossbow_cron_friendly_rss_monitor"&gt;this lobste.rs
post&lt;/a&gt; and
decided it was probably right up my alley. I&amp;rsquo;ve written and spoken elsewhere
about work I&amp;rsquo;ve done previously with feeds, primarily on my
&lt;a href="https://github.com/oholiab/betterfeed"&gt;betterfeed&lt;/a&gt; framework for
reconstituting RSS feeds.&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;m fully aware however, that my solution is &lt;strong&gt;super&lt;/strong&gt; heavyweight, has a lot
of code that I probably wouldn&amp;rsquo;t have needed to write myself in any other
language, and is just not really usable for others.&lt;/p&gt;

&lt;p&gt;So &lt;code&gt;crossbow&lt;/code&gt; looked like a great solution. Looking at the man page for
&lt;code&gt;crossbow-cookbook&lt;/code&gt; it has all sorts of examples like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Download the full article
    This scenario is similar to the previous one, except that the item description
    contains only part of the content, or nothing at all.  The link field contains a
    valid URL, which is intended to be reached by means of a browser.

    In this case we can leverage curl(1) to do the retrieval:

                crossbow set -i "$ID" -u "$URL" \
                    -o subproc \
                    -f "curl -o %n.html %l"
                    -C /some/destination/path/
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is a much more tractable way of doing similar to what I was already doing,
but composable on the command-line. I could easily throw in a pipeline to &lt;code&gt;pup&lt;/code&gt;
for a given feed and re-use my extant CSS selectors in order to still just pull
the actual content out.&lt;/p&gt;

&lt;p&gt;But after downloading, building and installing the full set of dependencies and
&lt;a href="https://gitlab.com/dacav/crossbow"&gt;the project itself&lt;/a&gt;, I tried to use a
&lt;strong&gt;very&lt;/strong&gt; similar invocation to the one above to add
&lt;a href="https://www.databreaches.net"&gt;https://www.databreaches.net&lt;/a&gt; to &lt;code&gt;crossbow&lt;/code&gt;&amp;rsquo;s download list, returning 0, but
when I ran &lt;code&gt;crossbow-fetch&lt;/code&gt; I got the cryptic error message:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;crossbow-fetch: cannot open feed [https://www.databreaches.net/feed/]: error_code=2 (mrss: Parser error)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;God dammit.&lt;/p&gt;

&lt;p&gt;Now I &lt;strong&gt;could&lt;/strong&gt; probably have just dug through the code, but I don&amp;rsquo;t have much
patience for that, and I have been having some amount of fun and success
recently in turning to&amp;hellip;&lt;/p&gt;

&lt;a name="gdb"&gt;&lt;/a&gt;
&lt;h1&gt;gdb&lt;/h1&gt;

&lt;p&gt;This isn&amp;rsquo;t my first rodeo with &lt;code&gt;gdb&lt;/code&gt;, but I&amp;rsquo;m not a prolific writer of compiled
languages nor am I an accomplished reverse engineer - I&amp;rsquo;m largely interested in
building up my skillset because I (fairly recently) purchased a debugger for
ARM devices.&lt;/p&gt;

&lt;p&gt;Anyway, I&amp;rsquo;m going to cut a long story short here, but I learned a few things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to &amp;ldquo;break&amp;rdquo; (technically it&amp;rsquo;s a &lt;code&gt;catch&lt;/code&gt;) on a syscall (in this case
&lt;code&gt;clone&lt;/code&gt; because I wanted to see what was going on in another thread)&lt;/li&gt;
&lt;li&gt;How to lock the scheduler so other threads don&amp;rsquo;t continue to run in the
background&lt;/li&gt;
&lt;li&gt;How to step through a thread in the foreground&lt;/li&gt;
&lt;li&gt;How to enable source listing for stepping through code with debug symbols
compiled in&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Again, to cut a long story short the error logic I wanted to see was in the
&lt;code&gt;libmrss.so.0&lt;/code&gt; dependency, which in my efforts I ended up recompiling and
installing separately to &lt;code&gt;/usr/local/...&lt;/code&gt; and loading in with &lt;code&gt;LD_PRELOAD&lt;/code&gt; in
my &lt;code&gt;gdb&lt;/code&gt; invocation.&lt;/p&gt;

&lt;p&gt;I then did the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;dir ~/libmrss/src&lt;/code&gt; to get the line information corresponding to the debug
symbols&lt;/li&gt;
&lt;li&gt;&lt;code&gt;catch syscall clone&lt;/code&gt; to create a breakpoint when a thread is about to be
created&lt;/li&gt;
&lt;li&gt;&lt;code&gt;run&lt;/code&gt; because the next scheduler argument doesn&amp;rsquo;t want to work until you
start the program (we&amp;rsquo;re safe because we&amp;rsquo;ll break before threads are
created)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;set scheduler-locking on&lt;/code&gt; in order to prevent &lt;strong&gt;other&lt;/strong&gt; threads from being
scheduled whilst stepping through the current one.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;We can then step (&lt;code&gt;s&lt;/code&gt;) until the new thread is created and switch to it with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;info thread&lt;/code&gt; to view the threads and their IDs&lt;/li&gt;
&lt;li&gt;&lt;code&gt;thread 2&lt;/code&gt; if you want to, for example, switch to the thread with id=2&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;I mean turns out none of the important stuff actually happened in the second
thread which returns before thread 1 actually does the work that produces the
error, but it&amp;rsquo;s a good thing to have learned.&lt;/p&gt;

&lt;p&gt;Anyway, here&amp;rsquo;s the interesting bit:&lt;/p&gt;

&lt;pre&gt;&lt;code class="gdb"&gt;(gdb) s
mrss_parse_url_with_options_error_and_transfer_buffer (feed_size=0x0, feed_content=0x0,
        code=&amp;lt;optimized out&amp;gt;, options=0x0, ret=0x7fffffff9440,
        url=0x7fffffffd480 "https://www.databreaches.net/feed/") at mrss_parser.c:1114
1114      if (nxml_parse_buffer(doc, buffer, size) != NXML_OK) {
(gdb) s
1121      if (!(err = __mrss_parser(doc, ret))) {
(gdb) s
__mrss_parser (doc=0x555555563560, ret=ret@entry=0x7fffffff9440) at mrss_parser.c:1015
1015      if (!(cur = nxmle_root_element(doc, NULL)))
(gdb) s
1018      if (!strcmp(cur-&amp;gt;value, "rss")) {
(gdb) s
1042      else if (!strcmp(cur-&amp;gt;value, "RDF"))
(gdb) s
1045      else if (!strcmp(cur-&amp;gt;value, "feed"))
(gdb) s
mrss_parse_url_with_options_error_and_transfer_buffer (feed_size=0x0, feed_content=0x0,
        code=&amp;lt;optimized out&amp;gt;, options=0x0, ret=&amp;lt;optimized out&amp;gt;,
        url=0x7fffffffd480 "https://www.databreaches.net/feed/") at mrss_parser.c:1133
1133      nxml_free(doc);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Well up until I came to write about this, in my mind it was the case that the
feed was atom so that&amp;rsquo;s why &lt;code&gt;libmrss&lt;/code&gt; couldn&amp;rsquo;t parse it, but in checking my
facts to be able to actually post examples this doesn&amp;rsquo;t appear to be the case.&lt;/p&gt;

&lt;a name="This-is-not-the-feed-you-27-re-looking-for"&gt;&lt;/a&gt;
&lt;h1&gt;This is not the feed you&amp;rsquo;re looking for&lt;/h1&gt;

&lt;p&gt;The feed itself &lt;strong&gt;is&lt;/strong&gt; RSS and the library &lt;strong&gt;does&lt;/strong&gt; have support for Atom as
far as I can tell.&lt;/p&gt;

&lt;p&gt;So going back through, let&amp;rsquo;s see what that root value is if it&amp;rsquo;s not &lt;code&gt;rss&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class="gdb"&gt;Thread 1 "crossbow-fetch" hit Breakpoint 3, __mrss_parser (doc=0x555555563560,
        ret=ret@entry=0x7fffffff9440) at mrss_parser.c:1015
1015      if (!(cur = nxmle_root_element(doc, NULL)))
(gdb) s
1018      if (!strcmp(cur-&amp;gt;value, "rss")) {
(gdb) p cur-&amp;gt;value
$1 = 0x555555563600 "html"
(gdb)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Well there&amp;rsquo;s a turnout for the books. If I &lt;code&gt;curl&lt;/code&gt; the URL, it&amp;rsquo;s &lt;strong&gt;definitely&lt;/strong&gt;
returning RSS. I bet this is user-agent related.&lt;/p&gt;

&lt;p&gt;To test the theory out, I add a test feed that&amp;rsquo;s pointing to my website and
tail the &lt;code&gt;nginx&lt;/code&gt; logs, doing both a &lt;code&gt;crossbow-fetch&lt;/code&gt; and a regular curl:&lt;/p&gt;

&lt;pre&gt;&lt;code class="nginx/access.log"&gt;77.97.102.36 - - [13/Aug/2020:11:09:18 +0000] "GET / HTTP/1.1" 200 2090 "-" "-"
77.97.102.36 - - [13/Aug/2020:11:09:55 +0000] "GET / HTTP/1.1" 301 178 "-" "curl/7.71.1"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So the libcurl being used by &lt;code&gt;nxml_download_file&lt;/code&gt; isn&amp;rsquo;t passing &lt;strong&gt;any&lt;/strong&gt;
user-agent header.&lt;/p&gt;

&lt;p&gt;Let&amp;rsquo;s see what databreaches.net thinks of this:&lt;/p&gt;

&lt;pre&gt;&lt;code class="html"&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;!--[if lt IE 7]&amp;gt; &amp;lt;html class="no-js ie6 oldie" lang="en-US"&amp;gt; &amp;lt;![endif]--&amp;gt;
&amp;lt;!--[if IE 7]&amp;gt;    &amp;lt;html class="no-js ie7 oldie" lang="en-US"&amp;gt; &amp;lt;![endif]--&amp;gt;
&amp;lt;!--[if IE 8]&amp;gt;    &amp;lt;html class="no-js ie8 oldie" lang="en-US"&amp;gt; &amp;lt;![endif]--&amp;gt;
&amp;lt;!--[if gt IE 8]&amp;gt;&amp;lt;!--&amp;gt; &amp;lt;html class="no-js" lang="en-US"&amp;gt; &amp;lt;!--&amp;lt;![endif]--&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;title&amp;gt;Attention Required! | Cloudflare&amp;lt;/title&amp;gt;
&amp;lt;meta charset="UTF-8" /&amp;gt;
&amp;lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /&amp;gt;
&amp;lt;meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Well there we go, Cloudflare has decided that I&amp;rsquo;m not allowed to see content
because I haven&amp;rsquo;t told them what my UA is (╯ °□°）╯︵ ┻━┻&lt;/p&gt;

&lt;a name="Sticking-a-pin-in-it"&gt;&lt;/a&gt;
&lt;h1&gt;Sticking a pin in it&lt;/h1&gt;

&lt;p&gt;I need to have a bit of a think about the best way to proceed (and I need to
get some real work done) so here are some options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set up an HTTP proxy that keeps track of which site wants which UA and uses
it accordingly&lt;/li&gt;
&lt;li&gt;Add a UA argument for &lt;code&gt;crossbow-fetch&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Go the whole hog and add support to both &lt;code&gt;crossbow-fetch&lt;/code&gt; and &lt;code&gt;crossbow-set&lt;/code&gt;
so that UA can be set for each feed&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;I don&amp;rsquo;t want to put in too much speculative work for something that might not
be accepted upstream, so I&amp;rsquo;m going to stick a pin in this and come back to it
later.&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</description>
  <link>https://grimmwa.re/blog/html/00006-crossbow-and-gdb.html</link>
  <guid isPermaLink="false">https://grimmwa.re/blog/html/00006-crossbow-and-gdb.html</guid>
  <pubDate>Thu Aug 13 12:31:29 2020 +0100</pubDate>
 </item>

 <item>
  <title>00005-avra-kadabra</title>
  <description type="html">&lt;html&gt;
&lt;head&gt;
&lt;meta charset="utf-8"&gt;
&lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
&lt;link rel="stylesheet" href="style.css"&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;a name="Deep-arcana"&gt;&lt;/a&gt;
&lt;h1&gt;Deep arcana&lt;/h1&gt;

&lt;p&gt;I am, for one reason or another, attempting to build a PAL output serial
terminal. Let&amp;rsquo;s just assume that&amp;rsquo;s a reasonable thing to do because my writing
style doesn&amp;rsquo;t really sustain getting bogged down in explaining myself.&lt;/p&gt;

&lt;p&gt;Having learned over the years that diving straight in the deepend doesn&amp;rsquo;t
always produce results, I&amp;rsquo;ve decided that for my first pass I should probably
do this with more modern technology, and have opted to use the microcontroller
that is ubiquitous in my life, a knockoff Arduino Pro Micro. This board sports
an Atmel ATmega32u4 which is most common in hobbyist USB keyboards which is why
I have them just kicking around everywhere.&lt;/p&gt;

&lt;a name="Saucery"&gt;&lt;/a&gt;
&lt;h1&gt;Saucery&lt;/h1&gt;

&lt;p&gt;I&amp;rsquo;m not great with electronics outside of some real basics of digital
electronics and this is a truly analogue project where voltages matter, so I&amp;rsquo;d
be pretty lost without &lt;a href="http://www.hpcc.ecs.soton.ac.uk/dan/pic/video_PIC.htm"&gt;this amazing
page&lt;/a&gt; where the author
builds PAL games out of PIC microcontrollers. They step through all the theory
beautifully and then the practicalities of getting the full range of voltage
outputs necessary for character output on 2 IO pins. Perfect for me, so I&amp;rsquo;m not
going to paraphrase - if you want to understand just read it!&lt;/p&gt;

&lt;a name="Avra-Kadabra"&gt;&lt;/a&gt;
&lt;h1&gt;Avra Kadabra&lt;/h1&gt;

&lt;p&gt;The article says that timings are incredibly important, and I can only assume
that&amp;rsquo;s true because my attempts at producing PAL output in C didn&amp;rsquo;t appear to
do the trick as far as a TV was concerned, and looking at it under a logic
analyzer I also have my suspicions. Timing sensitive C is not my forte, so I
started to take a stab at AVR asm.&lt;/p&gt;

&lt;p&gt;For whomever comes after me, I&amp;rsquo;m leaving these words together so that modern
search engines (as fucking unhelpful as they are) can still point you to the
right place: atmega32u4 avra assembly&lt;/p&gt;

&lt;a name="The-assembler"&gt;&lt;/a&gt;
&lt;h2&gt;The assembler&lt;/h2&gt;

&lt;p&gt;You&amp;rsquo;re looking for &lt;code&gt;avra&lt;/code&gt; which is available under a few distros - in Arch it&amp;rsquo;s
in the AUR and builds and installs with no problem.&lt;/p&gt;

&lt;p&gt;The invocation is:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;avra -I ./include -o main.hex main.asm
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&amp;hellip; which will produce a flashable hexfile (if you&amp;rsquo;re converting your makefile
from C to ASM don&amp;rsquo;t leave &lt;code&gt;avr-objcopy&lt;/code&gt; in or you&amp;rsquo;ll spend hours flashing
garbage to your controller). The equivalent Makefile is below:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;AS=avra
ASFLAGS=-I ./include

%.hex: %.asm
    $(AS) $(ASFLAGS) -o $@ $&amp;lt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Notice I&amp;rsquo;m using a local &lt;code&gt;include/&lt;/code&gt; directory&amp;hellip;&lt;/p&gt;

&lt;a name="The-chip"&gt;&lt;/a&gt;
&lt;h2&gt;The chip&lt;/h2&gt;

&lt;p&gt;avra &lt;strong&gt;does not ship&lt;/strong&gt; with the definitions required for the ATmega32U4. It
ships with the definitions for the ATmega32 which, if you compare with the
datasheet, does &lt;strong&gt;not&lt;/strong&gt; put the registers at the same memory locations.&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;ll save you some effort here:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mkdir include
cd include
wget https://raw.githubusercontent.com/DarkSector/AVR/master/asm/include/m32U4def.inc
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;For some reason or other the chips need to be hardcoded into avra too, and it
only has definitions for the &lt;code&gt;ATmega32&lt;/code&gt;, and will complain about the &lt;code&gt;.DEVICE&lt;/code&gt;
directive in the include pointing to a microcontroller it doesn&amp;rsquo;t know.&lt;/p&gt;

&lt;p&gt;You need to &lt;strong&gt;change the .DEVICE definition to ATmega32&lt;/strong&gt; and it will work just
fine (at least for simple IO use cases). You can double check what your version
of &lt;code&gt;avra&lt;/code&gt; supports by doing &lt;code&gt;avra --devices&lt;/code&gt;&lt;/p&gt;

&lt;a name="Do-the-include"&gt;&lt;/a&gt;
&lt;h2&gt;Do the include&lt;/h2&gt;

&lt;p&gt;With the &lt;code&gt;avra&lt;/code&gt; flags set as above and the modified file in your local
&lt;code&gt;include&lt;/code&gt; directory, all you need to do then is:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;.include "m32U4def.inc"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And you can refer to the port definitions by their friendly names :)&lt;/p&gt;

&lt;p&gt;In my case I&amp;rsquo;m actually liable just to cherry-pick the bits I need out once
I&amp;rsquo;ve got my PoC, as PAL is actually super simple and I only really need the
definitions for &lt;code&gt;DDRD&lt;/code&gt; and &lt;code&gt;PORTD&lt;/code&gt;&lt;/p&gt;

&lt;a name="Flashing"&gt;&lt;/a&gt;
&lt;h1&gt;Flashing&lt;/h1&gt;

&lt;p&gt;It would be pretty unfair of me to not share a working solution, so here&amp;rsquo;s my entire Makefile&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;.ONESHELL:
SHELL=/bin/bash
TARGETS=pal.hex
DEFAULT:$(TARGETS)
CC=avr-gcc
AS=avra
ASFLAGS=-I ./include

%.hex: %.asm
    $(AS) $(ASFLAGS) -o $@ $&amp;lt;

flash_%: %.hex
    while ! avrdude -p m32u4 -c avr109 -U flash:w:$&amp;lt;:i -F -P /dev/ttyACM1; do sleep 1; done

clean:
    rm -f *.bin *.hex
&lt;/code&gt;&lt;/pre&gt;

&lt;a name="Notables"&gt;&lt;/a&gt;
&lt;h1&gt;Notables&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;I&amp;rsquo;ve been lazy and hardcoded in the port for flashing &lt;code&gt;/dev/ttyACM1&lt;/code&gt; - this
is trivially fixable&lt;/li&gt;
&lt;li&gt;&lt;code&gt;avrdude&lt;/code&gt; is in a loop so that I can dispatch the command and then reset the
microcontroller to flash&lt;/li&gt;
&lt;li&gt;&lt;code&gt;clean&lt;/code&gt; doesn&amp;rsquo;t have all the targets yet, but now is the time for writing,
not for fixing. avra dumps a bunch of stuff out to disk.&lt;/li&gt;
&lt;li&gt;In this format the invocation is &lt;code&gt;make flash_pal&lt;/code&gt; for e.g. &lt;code&gt;pal.hex&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;/body&gt;
&lt;/html&gt;</description>
  <link>https://grimmwa.re/blog/html/00005-avra-kadabra.html</link>
  <guid isPermaLink="false">https://grimmwa.re/blog/html/00005-avra-kadabra.html</guid>
  <pubDate>Thu Jul 16 10:57:03 2020 +0100</pubDate>
 </item>

 <item>
  <title>00004-yeet</title>
  <description type="html">&lt;html&gt;
&lt;head&gt;
&lt;meta charset="utf-8"&gt;
&lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
&lt;link rel="stylesheet" href="style.css"&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;a name="How-is-this-even-magic-3f-"&gt;&lt;/a&gt;
&lt;h1&gt;How is this even magic?&lt;/h1&gt;

&lt;p&gt;So obviously I said that this blog is about magic, but ultimately it&amp;rsquo;s about
magic with computers, and there&amp;rsquo;s an equivalence between arcane magic and
arcane computing: oldnessness.&lt;/p&gt;

&lt;p&gt;Around this time you should be realizing that you only have yourself to blame
for reading material that&amp;rsquo;s this contrived.&lt;/p&gt;

&lt;p&gt;But in all seriousness, I don&amp;rsquo;t actually think that computers work by magic,
there&amp;rsquo;s always a deeper understanding to be had of the &amp;ldquo;sufficiently advanced
technology&amp;rdquo; to make it distinguishable from magic, and there&amp;rsquo;s more &amp;ldquo;coagula&amp;rdquo;
to be had the more you &amp;ldquo;solve&amp;rdquo;. Or something. So before embarking on Fuzix, I
decided to play around a little with CP/M and utilizing the filesystem junk
that&amp;rsquo;s provided for free as part of RomWBW.&lt;/p&gt;

&lt;a name="Files"&gt;&lt;/a&gt;
&lt;h1&gt;Files&lt;/h1&gt;

&lt;p&gt;By default, an unpartitioned SD card (I assume that&amp;rsquo;s what it is, I took it
straight from the packaging and dumped it into the SPI adapter) is broken up
into &amp;ldquo;slices&amp;rdquo; of 8MB because CP/M is adorable and that&amp;rsquo;s all it can handle. On
booting into CP/M with a ludicrously overprovisioned 16GB card installed:&lt;/p&gt;

&lt;pre&gt;&lt;code class="sc130 boot"&gt;    Boot Selection? C

    Loading CP/M 80 v2.2...



    CBIOS v3.0 [WBW]

    Formatting RAMDISK...

    Configuring Drives...

       A:=MD1:0
       B:=MD0:0
       C:=SD0:0
       D:=SD0:1
       E:=SD0:2
       F:=SD0:3
       G:=SD0:4
       H:=SD0:5
       I:=SD0:6
       J:=SD0:7

       1932 Disk Buffer Bytes Free

    CP/M-80 v2.2, 54.0K TPA

    B&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here &lt;code&gt;A:&lt;/code&gt; is (I assume) an as-yet uninserted (by virtue of being nonexistant)
floppy drive, &lt;code&gt;B:&lt;/code&gt; is the flash ROM with RomWBW et al on (and our current drive
as indicated by the prompt) and &lt;code&gt;C:&lt;/code&gt; onwards are the drive labels for the
slices.&lt;/p&gt;

&lt;p&gt;I can list &lt;code&gt;C:&lt;/code&gt; thusly:&lt;/p&gt;

&lt;pre&gt;&lt;code class="A directory listing"&gt;
    B&amp;gt;dir
    B: ASM      COM : CLRDIR   COM : COMPARE  COM : COPY     CFG
    B: COPY     COM : DDT      COM : DDTZ     COM : DUMP     COM
    B: ED       COM : FA16     CFG : FDISK80  COM : FILEATTR COM
    B: FILEDATE CFG : FILEDATE COM : FLASH    COM : INITDIR  CFG
    B: INITDIR  COM : LDDS     COM : LDP2D    COM : LINK     COM
    B: LOAD     COM : MBASIC   COM : NULU     COM : PIP      COM
    B: PUTDS    COM : RELOG    COM : RMAC     COM : STAT     COM
    B: SUBMIT   COM : SUPERSUB COM : TD       CFG : TD       COM
    B: UNARC    COM : XSUB     COM : ZAP      COM : ZCAL     COM
    B: ZCNFG    COM : ZCNFG24  CFG : ZDE      COM : ZPATH    COM
    B: ZSCONFIG COM : ZXD      CFG : ZXD      COM : ASSIGN   COM
    B: FDU      COM : FORMAT   COM : MODE     COM : RTC      COM
    B: SURVEY   COM : SYSCOPY  COM : SYSGEN   COM : TALK     COM
    B: TIMER    COM : XM       COM : INTTEST  COM : CPM      SYS
    B: ZSYS     SYS
    B&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;a name="yeet"&gt;&lt;/a&gt;
&lt;h1&gt;yeet&lt;/h1&gt;

&lt;p&gt;So I mentioned in one of my previous posts that I like the idea of being able
to self-host on this thing, so for starters I&amp;rsquo;d love to have some docs
available seeing as old tools are so user hostile. To do this, I&amp;rsquo;ll need to be
able to copy files across.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;XM&lt;/code&gt; is an implementation of XModem which is a protocol for transferring files
over serial.&lt;/p&gt;

&lt;p&gt;A quick google tells us that it&amp;rsquo;s possible to set up the XM receive with:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;XM R C:SOMEFILE.TXT
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and to send over the screen session by typing the leader and then:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;: !! exec sx somefile.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And you&amp;rsquo;ll end up with &lt;code&gt;SOMEFILE.TXT&lt;/code&gt; in your C: drive. all on one line because
CP/M uses DOS-style line endings.&lt;/p&gt;

&lt;p&gt;Obviously this is a bit of a 3-point turn, and I don&amp;rsquo;t want to store my copies
of these files on Linux with dos line endings, so I wrote &lt;code&gt;yeet&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class="bash"&gt;#!/usr/bin/env bash
set -xe

FILE=$(readlink -f $1)
DEST="C:$(basename $FILE)"

if ! [[ -f $FILE ]]; then
        echo "$FILE is not a file" &amp;gt;&amp;amp;2
        exit 1
fi

screen -p 0 -X stuff "XM R $DEST\n"
sleep 1
screen -p 0 -X exec '!!' bash -c "unix2dos &amp;lt; $FILE | sx -"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is a pretty rudamentary version with lots of things hardcoded, but
essentially it uses the fact that you can send commands to &lt;code&gt;screen&lt;/code&gt; from
outside of the session.&lt;/p&gt;

&lt;p&gt;What &lt;code&gt;yeet&lt;/code&gt; does is grab the full path to the file, then extract the file&amp;rsquo;s
&lt;code&gt;basename&lt;/code&gt; and tell screen to type &lt;code&gt;XM R C:SOMEFILE.TXT\n&lt;/code&gt; into the session (so
you need to be at a CP/M prompt)&lt;/p&gt;

&lt;p&gt;It then waits a second just in case (it&amp;rsquo;s not like this sleep command is even
the longest delay anyway) and then runs the command &lt;code&gt;exec !! bash -c "unix2dos
&amp;lt; /path/to/somefile.txt | sx -"&lt;/code&gt; which will send the XModem formatted file as
piped to stdin from the output of &lt;code&gt;unix2dos&lt;/code&gt; so that not only do we get the
file sent, but it&amp;rsquo;s also got the correct line terminators.&lt;/p&gt;

&lt;p&gt;This all works surprisingly well&lt;/p&gt;

&lt;a name="What-next-3f-"&gt;&lt;/a&gt;
&lt;h1&gt;What next?&lt;/h1&gt;

&lt;p&gt;Well for starters, the contents of &lt;code&gt;ZDE.TXT&lt;/code&gt; which is the full manual for the
ZDE visual text editor is too large to open in the ZDE visual text editor - it
runs out of memory - and the &lt;code&gt;TYPE&lt;/code&gt; command dumps the whole thing without
paging, so writing a pager in Z80 ASM seems like a good next project to learn
about the platform.&lt;/p&gt;

&lt;p&gt;Also, there&amp;rsquo;s the clear case of the reciprocal command for &lt;code&gt;yeet&lt;/code&gt; to &lt;strong&gt;fetch&lt;/strong&gt;
a file. This will be trivial, and I also have a name for it.&lt;/p&gt;

&lt;p&gt;Because &amp;ldquo;yeet&amp;rdquo; is like, Gen-Z slang or something, and it was best explained to
me as the reciprocal of the word &amp;ldquo;yoink&amp;rdquo; in the phrase:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;The Lord yeeteth, and The Lord yoinketh away.&lt;/p&gt;&lt;/blockquote&gt;
&lt;/body&gt;
&lt;/html&gt;</description>
  <link>https://grimmwa.re/blog/html/00004-yeet.html</link>
  <guid isPermaLink="false">https://grimmwa.re/blog/html/00004-yeet.html</guid>
  <pubDate>Mon Jun 29 20:31:49 2020 +0100</pubDate>
 </item>

 <item>
  <title>00003-sc130</title>
  <description type="html">&lt;html&gt;
&lt;head&gt;
&lt;meta charset="utf-8"&gt;
&lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
&lt;link rel="stylesheet" href="style.css"&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;a name="Z80"&gt;&lt;/a&gt;
&lt;h1&gt;Z80&lt;/h1&gt;

&lt;p&gt;For one reason or another I&amp;rsquo;ve been thinking a lot about building a computer
from scratch.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One reason: To have a platform to fuck about with which isn&amp;rsquo;t older than I am
and thus a piece of destroyed history if I fuck it up&lt;/li&gt;
&lt;li&gt;Or another: I&amp;rsquo;m not entirely convinced that the collapse of the global supply
chain won&amp;rsquo;t happen and I&amp;rsquo;ll be left trying to scavenge chips in order to
build and repair computers so that I can bask in the warm glow of information
whilst I die of dysentary in my soiled sleeping bag in the back room of an
abandoned Tesco Metro.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;I&amp;rsquo;m not going to lie, &lt;a href="https://collapseos.org/"&gt;CollapseOS&lt;/a&gt; put the thought
into my mind and my tattooist makes some compelling arguments as to why life as
we know it will draw to a close. Any &lt;strong&gt;certainty&lt;/strong&gt; to the contrary at least
just sounds like the desperate clamourings of cognitive dissonance trying to
deny an impending Bad Thing.&lt;/p&gt;

&lt;p&gt;But regardless, much like addressing global warming, the thing is that even if
The Event doesn&amp;rsquo;t happen, I&amp;rsquo;ll have learned a bunch and honestly in lockdown
you can&amp;rsquo;t have too many hobbies.&lt;/p&gt;

&lt;p&gt;So like many (at least 2) great thinkers before me I&amp;rsquo;ve decided to go for a
platform that is understandable, robust and ubiquitous enough - the Zilog Z80.&lt;/p&gt;

&lt;a name="Z180-Yeah-except-I-wasn-27-t-paying-an--3c-strong-3e-awful-3c--2f-strong-3e--lot-of-attention-so-after-I"&gt;&lt;/a&gt;
&lt;h1&gt;Z180 Yeah except I wasn&amp;rsquo;t paying an &lt;strong&gt;awful&lt;/strong&gt; lot of attention so after I&lt;/h1&gt;

&lt;p&gt;assmebled the SC130, a lovely little starter board designed by Steve Cousins,
having a bit of a Google around about my new platform I realised that the Z180
is &lt;strong&gt;not&lt;/strong&gt; in fact just a Z80 in another package&amp;#x2026; But it looks to be a
great springboard regardless as it&amp;rsquo;s fully Z80 compatible with some extra bells
and whistles. I suppose there&amp;rsquo;s no need to jump straight from i7s to an abacus
anyway.&lt;/p&gt;

&lt;p&gt;&lt;img src="./images/00003/sc130.jpg" title="Anyway here's the finished article" alt="img" /&gt;&lt;/p&gt;

&lt;p&gt;Anyway, here it is in all it&amp;rsquo;s assembled glory. The build and test instructions
were fantastic, especially the page where the purpose of &lt;strong&gt;every component on
the board&lt;/strong&gt; was explained. This is part of the reason it&amp;rsquo;s such a great board -
it&amp;rsquo;s entirely comprehensible.&lt;/p&gt;

&lt;p&gt;Resources for the SC130 are all hosted at &lt;a href="https://smallcomputercentral.wordpress.com/sc130-z180-motherboard/"&gt;Small Computer
Central&lt;/a&gt;
but I will be taking an archive naturally ;)&lt;/p&gt;

&lt;a name="The-bleak-future."&gt;&lt;/a&gt;
&lt;h1&gt;The bleak future.&lt;/h1&gt;

&lt;p&gt;So I have the computer working just great. The 512KB ROM comes with ROMWBW
pre-flashed, which is a firmware bundling a bunch of things including CP/M,
ZSDOS, Forth and Basic (not to mention a baked in 2048 clone)&lt;/p&gt;

&lt;a name="Storage"&gt;&lt;/a&gt;
&lt;h2&gt;Storage&lt;/h2&gt;

&lt;p&gt;It&amp;rsquo;s not exactly the most self-sufficient thing just yet though. For starters,
I need some safely writeable storage which is going to come in the form of the
SPI microSD card adapter (although you can actually modify the flash if you
un-bridge the write-protect jumper). I&amp;rsquo;m off to pick up a couple today.&lt;/p&gt;

&lt;a name="Human-interface"&gt;&lt;/a&gt;
&lt;h2&gt;Human interface&lt;/h2&gt;

&lt;p&gt;Then I need to figure out how to make it a standalone computer by giving it
it&amp;rsquo;s own video out and keyboard input. This could be pretty interesting, there
are boards out there but I&amp;rsquo;d really love to learn something by building my own
solution. This could either be a standalone serial terminal module, or an
actual graphics output for the board itself (which would allow me to continue
to draw sigils which is likely what I&amp;rsquo;ll want to do shortly before I get
attacked by roaming maurauders.&lt;/p&gt;

&lt;a name="Self-2d-hosted"&gt;&lt;/a&gt;
&lt;h2&gt;Self-hosted&lt;/h2&gt;

&lt;p&gt;A self-sufficient computer should be able to self-host. This might be a tricky
one, but I&amp;rsquo;m probably going to have a play with &lt;a href="http://www.fuzix.org/"&gt;Fuzix&lt;/a&gt;
later today which apparently has its own C compiler. This would obviously be
great if it&amp;rsquo;s actually a self-hosted OS because I&amp;rsquo;m already familiar with Unix
paradigms,&lt;/p&gt;

&lt;p&gt;Failing this it&amp;rsquo;s going to be about learning CP/M or ZSDOS and figuring out how
to use either the Forth interpreter or ASM to build out new features.&lt;/p&gt;

&lt;p&gt;There&amp;rsquo;s also CollapseOS which is designed to self-host and to also bootstrap
other tech - I&amp;rsquo;d love to see if I can flash an AVR from it!&lt;/p&gt;

&lt;p&gt;This is all tremendously exciting though&lt;/p&gt;

&lt;a name="The-super-2d-distant-bleak-future"&gt;&lt;/a&gt;
&lt;h1&gt;The super-distant bleak future&lt;/h1&gt;

&lt;a name="Power"&gt;&lt;/a&gt;
&lt;h2&gt;Power&lt;/h2&gt;

&lt;p&gt;Ever since I&amp;rsquo;ve thought of the idea, I&amp;rsquo;m taking it to logical extremes in my
head&amp;hellip; The most hilarious of these is that I&amp;rsquo;ve kinda wanted to build a
generator for a while, probably out of a lawnmower or motorcycle engine or
something.&lt;/p&gt;

&lt;p&gt;I love the idea of building it &lt;strong&gt;into&lt;/strong&gt; a computer and having the computer
actually regulate the thing too. It would be a great party piece at hacker
camps.&lt;/p&gt;

&lt;a name="EMP"&gt;&lt;/a&gt;
&lt;h2&gt;EMP&lt;/h2&gt;

&lt;p&gt;I mean whilst we&amp;rsquo;re at it, if I&amp;rsquo;m going to be a complete fucking lunatic, we
may as well also build it into a faraday cage to protect the ICs from global
thermonuclear war. Fuck it, why not.&lt;/p&gt;

&lt;a name="Display"&gt;&lt;/a&gt;
&lt;h2&gt;Display&lt;/h2&gt;

&lt;p&gt;This is the thing I&amp;rsquo;m still unsure about - what will the ubiquity of displays
be like after The Event? I think building a standalone RS232 terminal that can
output to VGA and composite is probably the best scavenging solution, but then
again most displays are HDMI these days which means they likely have a limited
shelf life and would need a more complex microcontroller than the Z80 itself
just to output anything.&lt;/p&gt;

&lt;a name="In-conclusion"&gt;&lt;/a&gt;
&lt;h1&gt;In conclusion&lt;/h1&gt;

&lt;p&gt;Yes I am managing to keep myself busy during lockdown&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</description>
  <link>https://grimmwa.re/blog/html/00003-sc130.html</link>
  <guid isPermaLink="false">https://grimmwa.re/blog/html/00003-sc130.html</guid>
  <pubDate>Fri Jun 26 14:19:06 2020 +0100</pubDate>
 </item>

 <item>
  <title>00002-ancient-lisp</title>
  <description type="html">&lt;html&gt;
&lt;head&gt;
&lt;meta charset="utf-8"&gt;
&lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
&lt;link rel="stylesheet" href="style.css"&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;a name="Antiquity"&gt;&lt;/a&gt;
&lt;h1&gt;Antiquity&lt;/h1&gt;

&lt;p&gt;One of the things that&amp;rsquo;s common to the vast majority of grimoires is that they
claim antiquity, which is not something I really buy in to in most senses - I
can understand some weight being put behind the idea that a practice has lasted
because it worked, but the idea that &amp;ldquo;these sigils were definitely written down
by King Solomon&amp;rdquo; really carries no particular weight to me.&lt;/p&gt;

&lt;p&gt;As a mental anchor point though, it&amp;rsquo;s so culturally ingrained that it&amp;rsquo;s an
&lt;strong&gt;excellent&lt;/strong&gt; way to quickly and easily attribute importance to a thing, and
thus an incredible tool in your arsenal to generate gravitas around things you
want to focus on.&lt;/p&gt;

&lt;a name="Sigilum"&gt;&lt;/a&gt;
&lt;h1&gt;Sigilum&lt;/h1&gt;

&lt;p&gt;I was working on some code to generate magical sigils in the style of Crowley&amp;rsquo;s
re-interpretations of the sigils in The Lesser Key of Solomon. By which I mean
that he put them in circles with names of the angels and demons around them.&lt;/p&gt;

&lt;p&gt;My implementation was using PyCairo, and I wrote the code to produce the &amp;ldquo;name
circle&amp;rdquo; (optionally in the Malachim alphabet) around generated &amp;ldquo;*grams&amp;rdquo;
starting with a pentagram. Now as a proof of concept this was probably a great
place to start and I was able to generate some kinda weird stuff at least for
visuals in my CampGND talk, but my next artefact is really supposed to be
something to carve into my desk.&lt;/p&gt;

&lt;p&gt;I say &amp;ldquo;supposed&amp;rdquo; because I created a servitor with the express intent of
finding said sigil, which means that I &lt;strong&gt;have&lt;/strong&gt; to complete the task now or the
spell didn&amp;rsquo;t work. Yeah I&amp;rsquo;m not even going to get into that logic now but
suffice to say I intend to complete the goal.&lt;/p&gt;

&lt;p&gt;One of the things that was stopping me from working on the code was that I
didn&amp;rsquo;t really enjoy it - fact of the matter is I don&amp;rsquo;t &lt;strong&gt;like&lt;/strong&gt; writing Python
for a number of reasons that you could probably call aesthetic, but the most
important one being that it doesn&amp;rsquo;t really &lt;strong&gt;feel&lt;/strong&gt; very occult. Yeah you heard
me right, Python doesn&amp;rsquo;t feel occult enough. It feels like an anachronism when
used for occult means.&lt;/p&gt;

&lt;p&gt;You know what programming dialects feel like channeling the powers of the
universe? Lisps.&lt;/p&gt;

&lt;a name="Knights-of-the-Lambda-Calculus"&gt;&lt;/a&gt;
&lt;h1&gt;Knights of the Lambda Calculus&lt;/h1&gt;

&lt;p&gt;Now before I embark on these &amp;ldquo;ideas of antiquity&amp;rdquo; I should probably clarify
something very important out of the historical associations that exist along
the timeline of Lisp, from MIT&amp;rsquo;s AI lab to Emacs Lisp: Richard Stallman is a
relic of outdated ideas surrounding what kind of behaviours merit will excuse.
Fuck that guy.&lt;/p&gt;

&lt;p&gt;With that out of the way, Lisps and Schemes map somewhat more literally to
ideas like lambda calculus at the birth of computer science and were considered
the holy grail of programming languages back in the days of heavy iron. They
were above and beyond what the priesthood manning the IBM mainframes were
thinking about, and largely beyond the capacity of the computers of the time.
Sometimes it feels like programming with algebraic precision.&lt;/p&gt;

&lt;p&gt;That said, I first tried to rewrite in Racket. I&amp;rsquo;m now pretty sure that
&lt;code&gt;image.rkt&lt;/code&gt; is written for teaching in the DrRacket IDE, not summoning Satan or
whatever. I also realised something about Lisps.&lt;/p&gt;

&lt;p&gt;I switched back to an old heavyweight which I have come to the conclusion has
totally ruined other lisps for me: Clojure.&lt;/p&gt;

&lt;p&gt;And it&amp;rsquo;s like being in an old comfy pair of trousers. Powerful trousers with
deep arcane powers, and a function that you probably want to use that does that
one thing (whatever it is) for you.&lt;/p&gt;

&lt;p&gt;My code now adequately separates out the data processing (i.e. the &lt;strong&gt;real&lt;/strong&gt;
magic, the sacred geometries) from the horrible impure side-effecty programming
that is rendering shit to an image. Additionally, rather than using a
completely underpowered image library I&amp;rsquo;ve used &lt;code&gt;quil&lt;/code&gt; which is more geared
towards 3D live-coding visualizations, so overpowered instead of under.&lt;/p&gt;

&lt;a name="What-next"&gt;&lt;/a&gt;
&lt;h1&gt;What next&lt;/h1&gt;

&lt;p&gt;I&amp;rsquo;ve already implemented the full featureset that I already had in
significantly less time with significantly less code. Additionally because of
my emacs setup it&amp;rsquo;s got all sorts of mad symbols for lambdas and partials which
makes it look super arcane ;) I even aliased &lt;code&gt;tau&lt;/code&gt; (2 * pi) to its greek
letter heh. Next I want to do the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Define the point joining pattern by passing a lambda or generator or some
other callable to dictate which points get joined to which others. This
should be a great way of finding some gnarly looking patterns&lt;/li&gt;
&lt;li&gt;Use the animation functionality of &lt;code&gt;quil&lt;/code&gt; to create motion in the sigils&lt;/li&gt;
&lt;li&gt;Think some more about generation of non-gram patterns. Previously I&amp;rsquo;ve
achieved this by pasting images of dickbutt in the center.&lt;/li&gt;
&lt;/ol&gt;

&lt;/body&gt;
&lt;/html&gt;</description>
  <link>https://grimmwa.re/blog/html/00002-ancient-lisp.html</link>
  <guid isPermaLink="false">https://grimmwa.re/blog/html/00002-ancient-lisp.html</guid>
  <pubDate>Sat Jun 20 19:09:48 2020 +0100</pubDate>
 </item>

 <item>
  <title>00001-entry</title>
  <description type="html">&lt;html&gt;
&lt;head&gt;
&lt;meta charset="utf-8"&gt;
&lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
&lt;link rel="stylesheet" href="style.css"&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;a name="Start-as-you-don-27-t-mean-to-continue"&gt;&lt;/a&gt;
&lt;h1&gt;Start as you don&amp;rsquo;t mean to continue&lt;/h1&gt;

&lt;p&gt;I hate writing thinkpieces and &amp;ldquo;new blog&amp;rdquo; posts, because I get completely lost.
The problem being that I&amp;rsquo;m an engineer in all aspects, and when I write I like
it to be about what I did and what worked - you can&amp;rsquo;t misjudge your audience or
make false claims or generalisations when doing this because the audience is
whoever is interested in what you did, and it&amp;rsquo;s definitely true because you
were there.&lt;/p&gt;

&lt;p&gt;I want this blog to be about my experiences in magic and technology, and I&amp;rsquo;ve
written and deleted about 3 particularly stuffy statements of belief that I
can&amp;rsquo;t get to the end of because of wild tangents because I feel like I need to
contextualize. So I guess I need to summarise it in like, 3 sentence and then
call it good enough.&lt;/p&gt;

&lt;p&gt;I believe that any power in religion or magic comes from the practice and
frameworks of focussing the will (i.e. a technology for doing so) and that
anything achieved from doing so is done under the agency of the individual or
individuals participating in the practice.&lt;/p&gt;

&lt;p&gt;I hypothesize that the techologies of religion, magic and the occult likely
have further use in self mastery under recognition of the fact that the human
mind is fundamentally irrational and unless particularly well practiced, is not
incredibly obedient to the mind.&lt;/p&gt;

&lt;p&gt;Finally I believe that technology does not have enough aesthetic value, and
that a ritual is basically just a protocol with a sense of style.&lt;/p&gt;

&lt;p&gt;To summarise, you could say that I&amp;rsquo;m an irrational rationalist or a rational
irrationalist - I want to learn from historical techniques of the occult and
religion in order to develop my own to become the most effective individual I
can be. This may or may not include doing things that sound like I believe in
the supernatural, but I don&amp;rsquo;t. I&amp;rsquo;m just an engineer with limited time and
limited scruples as to which mileau I&amp;rsquo;ll engage in to have an interesting and
&amp;ldquo;effective&amp;rdquo; life.&lt;/p&gt;

&lt;p&gt;Okay that was pretty good. Blog style: keep it brief so you don&amp;rsquo;t bore yourself
hahah.&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</description>
  <link>https://grimmwa.re/blog/html/00001-entry.html</link>
  <guid isPermaLink="false">https://grimmwa.re/blog/html/00001-entry.html</guid>
  <pubDate>Sat Jun 20 19:09:48 2020 +0100</pubDate>
 </item>
</channel>
</rss>
