<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Paul Newell</title>
    <description>The latest articles on DEV Community by Paul Newell (@newellpaul).</description>
    <link>https://dev.to/newellpaul</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F172670%2Ff6157e1c-7e08-4ff5-8370-a657633a4ff2.jpeg</url>
      <title>DEV Community: Paul Newell</title>
      <link>https://dev.to/newellpaul</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/newellpaul"/>
    <language>en</language>
    <item>
      <title>43 Years Later: Finishing My BBC Micro Game in Assembly</title>
      <dc:creator>Paul Newell</dc:creator>
      <pubDate>Wed, 10 Jun 2026 12:30:00 +0000</pubDate>
      <link>https://dev.to/newellpaul/43-years-later-finishing-my-bbc-micro-game-in-assembly-4fd4</link>
      <guid>https://dev.to/newellpaul/43-years-later-finishing-my-bbc-micro-game-in-assembly-4fd4</guid>
      <description>&lt;p&gt;In 1983, the first program I ever wrote appeared in the September issue of &lt;em&gt;Computer &amp;amp; Video Games&lt;/em&gt; which was the pre-eminent UK games magazine of the day.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn3b45vu38wjo8vs9187j.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn3b45vu38wjo8vs9187j.jpg" alt="Computer &amp;amp; Video Games issue 23, September 1983" width="800" height="1107"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Computer &amp;amp; Video Games issue 23, September 1983&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Inside that issue, in the type-in listings section, was my game:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Caterpillar&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Like most type-in games of the era, it was pretty awful. Mine was doubly so as it was my first fumbling attempt at programming, written in BBC BASIC.&lt;/p&gt;

&lt;p&gt;And like a lot of coders back then, I told myself I'd rewrite it properly in assembly one day.&lt;/p&gt;

&lt;p&gt;This is that rewrite.&lt;/p&gt;

&lt;p&gt;It's only 43 years late.&lt;/p&gt;


&lt;h2&gt;
  
  
  📖 The original
&lt;/h2&gt;

&lt;p&gt;Back in the early 80s, publishing a game didn't mean uploading to GitHub or pushing to Steam.&lt;/p&gt;

&lt;p&gt;It meant seeing your code printed across pages of a magazine and hoping someone, somewhere, would type it in correctly. And that was no easy feat, as anyone who ever tackled a multi-page listing will remember. One mistyped &lt;code&gt;DATA&lt;/code&gt; statement and the whole thing fell over.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnqcbxpw11zihiewk3chy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnqcbxpw11zihiewk3chy.png" alt="The Caterpillar type-in listing as printed in C&amp;amp;VG" width="800" height="549"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The Caterpillar type-in listing as printed in C&amp;amp;VG&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The premise was simple: guide a caterpillar through a maze, collecting food and avoiding the poisonous mushrooms. About 110 lines of BASIC. It ran, it was playable-ish, and it was slow and I mean SLOW ...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg0rgp1iklrmo0hqgsbaq.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg0rgp1iklrmo0hqgsbaq.gif" alt="The 1983 original in play — flat green mushrooms, all in BBC BASIC" width="500" height="332"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The 1983 original in play. Jerky movement and painfully slow in BBC BASIC&lt;/em&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  💾 The constraints
&lt;/h2&gt;

&lt;p&gt;The BBC Micro Model B gave you 32K of RAM, a 2 MHz 6502, and not much else. The original Caterpillar lived inside that, and the limits showed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;BASIC was the bottleneck.&lt;/strong&gt; BBC BASIC was truly one of the best versions of the language but still pretty hopeless for action games.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance.&lt;/strong&gt; Scrolling was very slow even using hardware calls.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Collision detection.&lt;/strong&gt; I remember struggling to get this right&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  ⚙️ The promise
&lt;/h2&gt;

&lt;p&gt;Even as a kid, I knew what the "proper" version would need to be coded in:&lt;/p&gt;

&lt;p&gt;6502 Assembly.&lt;/p&gt;

&lt;p&gt;I just could not get to grips with it in those early days.&lt;/p&gt;

&lt;p&gt;I did eventually become competent in 6502 a couple of years later but that was with the Commodore 64 (C64) and its hardware sprites which were way easier to get moving.&lt;/p&gt;

&lt;p&gt;I never did get back to the BBC game.&lt;/p&gt;


&lt;h2&gt;
  
  
  🧠 43 years later
&lt;/h2&gt;

&lt;p&gt;I knew my original game was hosted in the &lt;a href="https://www.bbcmicro.co.uk/game.php?id=1066" rel="noopener noreferrer"&gt;BBC Micro Archive&lt;/a&gt; and it always nagged me that I was never able to make the game I wanted back in the day.&lt;/p&gt;

&lt;p&gt;So this wasn't just a translation. It was adding all the things I wanted to do on the first version but could not fit in.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;6502 assembly handles the game.&lt;/strong&gt; Sprites, scrolling, collision and the season cycle, in MODE 2 (16 colours), running on a vsync-locked 50Hz loop.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;BASIC runs &lt;code&gt;CALL &amp;amp;1900&lt;/code&gt; to hand control to the engine; the engine plays the game, then returns a result code and the score in zero page for BASIC to display.&lt;/p&gt;


&lt;h2&gt;
  
  
  🔍 1983 vs 2026
&lt;/h2&gt;

&lt;p&gt;Although they look similar, they are quite different under the hood.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hardware scrolling, kept.&lt;/strong&gt; Both versions scroll the easy way: a &lt;code&gt;VDU 30, 11&lt;/code&gt; at the top of the screen makes the MOS nudge the CRTC display-start registers, so the hardware does the work for almost free. The 1983 version already got this right, so the rewrite kept it. I did consider writing directly to the CRTC's R12/R13 registers itself instead of going through the MOS, games like Repton did this, but I backed out of that pretty quickly due to the added complexity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Direct sprite blits.&lt;/strong&gt; Each sprite is pre-encoded and written straight to screen memory, four bytes per scanline. No slow BASIC, no OS character calls in the path.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ring-buffer collision.&lt;/strong&gt; Items are tracked in a 24-slot ring as they scroll from the top of the screen down to the caterpillar's row, so a "hit" is just a position lookup, with no per-pixel scan.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deterministic by design.&lt;/strong&gt; The original just splatted random mushrooms on the screen but this one has a proper map like any other speed runner.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Score Attack.&lt;/strong&gt; The new version finishes at 4 seasons. Score is everything - grab what you can.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Game mechanics.&lt;/strong&gt; Hot streaks, bonus rounds and an easter egg 🥚&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What I could not grasp in 1983 was that MODE 2 memory is laid out in character cells of 8 bytes. So stepping down one pixel row is usually just &lt;code&gt;+1&lt;/code&gt;, until you fall off the bottom of a cell and have to leap &lt;code&gt;+633&lt;/code&gt; bytes to land on the next character row down:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.advance_scanline
    INC temp0
    LDA temp0 : AND #7        ; still inside this character cell?
    BNE as_same_row           ; yes next byte is just +1
    CLC                       ; no cross to the next character row
    LDA scr_addr_lo : ADC #LO(633) : STA scr_addr_lo
    LDA scr_addr_hi : ADC #HI(633) : STA scr_addr_hi
.as_same_row
    INC scr_addr_lo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That one odd number, 633, is the whole quirk of BBC screen memory in a nutshell. No wonder I struggled with this at the time and why I found C64 sprites so much easier.&lt;/p&gt;

&lt;p&gt;The original was ~110 lines of BASIC. The rewrite is around 1,250 lines of lightly commented 6502, which assembles down to just &lt;strong&gt;3 KB&lt;/strong&gt; of machine code.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎮 Seeing it run again
&lt;/h2&gt;

&lt;p&gt;There's something uniquely satisfying about seeing old code come back to life.&lt;/p&gt;

&lt;p&gt;Not really modernised. Just finished, the way I always meant to write it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxxb4z8y7ki867quy17zh.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxxb4z8y7ki867quy17zh.gif" alt="The 2026 rewrite — the same game in native 6502, with proper multi-colour sprites" width="500" height="346"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The 2026 rewrite — the same game in native 6502, fast and fluid sprites&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🏆 Score to beat
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Will Newell - 4605&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ⏳ Why this mattered
&lt;/h2&gt;

&lt;p&gt;This was never really about optimisation.&lt;/p&gt;

&lt;p&gt;It was about finishing something.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If I say I'll do something, I'll do it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Some things just take a little longer than expected 😄&lt;/p&gt;




&lt;h2&gt;
  
  
  🔗 Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;BBC Micro Archive (the 1983 original): &lt;a href="https://www.bbcmicro.co.uk/game.php?id=1066" rel="noopener noreferrer"&gt;https://www.bbcmicro.co.uk/game.php?id=1066&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/newell-paul/caterpillar-assembler" rel="noopener noreferrer"&gt;https://github.com/newell-paul/caterpillar-assembler&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Play in the browser: &lt;a href="https://newell-paul.github.io/caterpillar-assembler/" rel="noopener noreferrer"&gt;https://newell-paul.github.io/caterpillar-assembler/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>retrocomputing</category>
      <category>assembly</category>
      <category>gamedev</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Claude Code Has a Power Meter. You Just Have to Wire It Up</title>
      <dc:creator>Paul Newell</dc:creator>
      <pubDate>Tue, 02 Jun 2026 12:00:00 +0000</pubDate>
      <link>https://dev.to/newellpaul/claude-code-has-a-power-meter-you-just-have-to-wire-it-up-386g</link>
      <guid>https://dev.to/newellpaul/claude-code-has-a-power-meter-you-just-have-to-wire-it-up-386g</guid>
      <description>&lt;p&gt;&lt;em&gt;One bash script. Your session cost in dollars, live, so you stop burning Opus on work that doesn't need it.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj1wbdl9q8xpaj28n25rs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj1wbdl9q8xpaj28n25rs.png" alt="HUD with subset of segments" width="798" height="168"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I kept leaving sessions on Opus long after the hard thinking was done. Claude Code does warn you, but the context and rate-limit notices flash past and you dismiss them without reading. Discipline loses to a number you can't see.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Grab &lt;code&gt;statusline-hud.sh&lt;/code&gt; from &lt;strong&gt;&lt;a href="https://github.com/newell-paul/statusline-hud" rel="noopener noreferrer"&gt;github.com/newell-paul/statusline-hud&lt;/a&gt;&lt;/strong&gt;, drop it in &lt;code&gt;~/.claude/&lt;/code&gt;, &lt;code&gt;chmod +x&lt;/code&gt; it.&lt;/li&gt;
&lt;li&gt;Add a &lt;code&gt;statusLine&lt;/code&gt; block to &lt;code&gt;~/.claude/settings.json&lt;/code&gt; (snippet below).&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Wire it up
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;jq&lt;/code&gt; on your &lt;code&gt;PATH&lt;/code&gt;. The script hard-exits with &lt;code&gt;⚠ jq missing&lt;/code&gt; without it.&lt;/li&gt;
&lt;li&gt;A terminal with 256-colour and UTF-8 support, and a font that renders &lt;code&gt;🔥 ⚡ ↺ ↩ ✗ ░ █ ▏▎▍▌▋▊▉&lt;/code&gt;. Any modern terminal with a Nerd Font, or the macOS/iTerm2/GNOME defaults, will do.&lt;/li&gt;
&lt;li&gt;macOS or Linux. Native Windows isn't supported; the script is bash and uses POSIX tools (WSL should work, untested).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Install&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Copy &lt;code&gt;statusline-hud.sh&lt;/code&gt; to &lt;code&gt;~/.claude/&lt;/code&gt; and make it executable.&lt;/li&gt;
&lt;li&gt;Add this to &lt;code&gt;~/.claude/settings.json&lt;/code&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"statusLine"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"~/.claude/statusline-hud.sh"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;refreshInterval&lt;/code&gt; is optional. Leave it out and the bar redraws on Claude Code events: each new assistant message, after &lt;code&gt;/compact&lt;/code&gt;, and on permission-mode or vim-mode changes. Add &lt;code&gt;"refreshInterval": 5&lt;/code&gt; if you want it to also tick on a timer, for example to keep the countdown accurate while background subagents are running.&lt;/p&gt;

&lt;p&gt;The repo has 80 bats tests and a hardened &lt;code&gt;git_safe()&lt;/code&gt; wrapper that disables &lt;code&gt;core.fsmonitor&lt;/code&gt; and &lt;code&gt;core.hooksPath&lt;/code&gt;, so a hostile &lt;code&gt;.git/config&lt;/code&gt; can't execute code via the bar.&lt;/p&gt;

&lt;p&gt;Settings reload; the bar appears on your next interaction.&lt;/p&gt;

&lt;h2&gt;
  
  
  The JSON hiding in the statusline
&lt;/h2&gt;

&lt;p&gt;Claude Code's statusline is just a shell command: JSON in on stdin, one line of text out. Cost, effort, fast mode, cache stats, both rate-limit windows are all already in there, emitted on every render (debounced 300ms). Nothing's missing. There's just nothing showing it. (Tap the pipe with &lt;code&gt;tee&lt;/code&gt; to see the full payload; PAYG (pay-as-you-go) and API users will find &lt;code&gt;rate_limits&lt;/code&gt; absent.)&lt;/p&gt;

&lt;h2&gt;
  
  
  What the bar shows
&lt;/h2&gt;

&lt;p&gt;With everything switched on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Directory + git status (&lt;code&gt;↑N↓N&lt;/code&gt;, &lt;code&gt;✗&lt;/code&gt; if dirty)&lt;/li&gt;
&lt;li&gt;Model name with effort badge (&lt;code&gt;⚡Lo&lt;/code&gt; / &lt;code&gt;⚡Med&lt;/code&gt; / &lt;code&gt;⚡Hi&lt;/code&gt; / &lt;code&gt;⚡xHi&lt;/code&gt; / &lt;code&gt;⚡Max&lt;/code&gt;) and fast-mode rocket 🚀 when &lt;code&gt;/fast&lt;/code&gt; is active&lt;/li&gt;
&lt;li&gt;Context-window bar: 5 cells using eighths (&lt;code&gt;▏▎▍▌▋▊▉█&lt;/code&gt;) so the bar moves smoothly within a tier, with the tier colour stepping green → yellow → orange → red (see the README for the exact ctx and rate-limit breakpoints; they differ)&lt;/li&gt;
&lt;li&gt;5-hour and 7-day rate-limit bars (both shown by default; comment either out in &lt;code&gt;SEGMENTS&lt;/code&gt;). A reset countdown (&lt;code&gt;↺2h14m&lt;/code&gt;) attaches to whichever limit is more constrained, and only once it crosses 60%&lt;/li&gt;
&lt;li&gt;Cache hit ratio (&lt;code&gt;↩97%&lt;/code&gt;), only after &amp;gt;5k input tokens&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;🔥&lt;/code&gt; cumulative session spend in USD (or input tokens; see toggle below)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything is configurable from the &lt;code&gt;CONFIG&lt;/code&gt; block at the top of the script.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjnseh3c207ev1m35z291.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjnseh3c207ev1m35z291.png" alt="Segments array" width="800" height="296"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The &lt;code&gt;SEGMENTS&lt;/code&gt; array is your control panel. Comment out a line to hide that segment, reorder lines to rearrange the bar. Want git status on the right and the flame on the left? Move the lines.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Other knobs you'll probably touch:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;TURN_UNIT&lt;/code&gt;: &lt;code&gt;usd&lt;/code&gt; (default) shows the flame in dollars; flip to &lt;code&gt;tokens&lt;/code&gt; for input-token count instead. In &lt;code&gt;tokens&lt;/code&gt; mode the value is the &lt;em&gt;live context window&lt;/em&gt; (see the flame section below), so its thresholds are fractions of a 200k context, not session totals.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;TIER_COLOR&lt;/code&gt;, &lt;code&gt;BAR_CTX&lt;/code&gt;, &lt;code&gt;BAR_LINEAR&lt;/code&gt;: bar palette and the tier thresholds at which each bar flips colour.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;TURN_HI_USD&lt;/code&gt; / &lt;code&gt;TURN_MED_USD&lt;/code&gt;: USD thresholds for the flame's amber/red (&lt;code&gt;TURN_HI_TOK&lt;/code&gt; / &lt;code&gt;TURN_MED_TOK&lt;/code&gt; for tokens mode).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One &lt;code&gt;jq&lt;/code&gt; call and a few &lt;code&gt;git&lt;/code&gt; invocations per render. Cheap enough to ignore.&lt;/p&gt;

&lt;h2&gt;
  
  
  The flame: a session-scale spend gauge
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;🔥 $5.64&lt;/code&gt; is the cumulative session spend, read straight from &lt;code&gt;cost.total_cost_usd&lt;/code&gt;. Green under $5, amber $5–$20, red ≥ $20, tuned for Max users where a long Opus session runs that high in estimated spend. Red doesn't mean stop. It means &lt;em&gt;the next routine task is the one to drop to Sonnet for, or &lt;code&gt;/clear&lt;/code&gt; and start fresh&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;PAYG users paying list price should dial down: try &lt;code&gt;TURN_MED_USD=0.50&lt;/code&gt; / &lt;code&gt;TURN_HI_USD=2.00&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The discomfort isn't financial, it's &lt;em&gt;visible&lt;/em&gt;. Same psychology as a power meter: you don't read the number, you notice when it pegs into the red.&lt;/p&gt;

&lt;p&gt;Green means I haven't checked the bar in a while and don't need to. Amber means the session has grown legs, fine if I meant it, worth noticing if I didn't. Red means I'm running Opus on a long, heavy context, and it's time to make a choice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Acting on the red
&lt;/h2&gt;

&lt;p&gt;Opus for architecture, complex debugging, ugly refactors. Sonnet for most everyday work. Haiku for routine commands.&lt;/p&gt;

&lt;p&gt;On Pro and Max, &lt;code&gt;cost.total_cost_usd&lt;/code&gt; is an estimate, not your bill: API list rates applied client-side, which can differ from what you're actually billed. It's still the best signal for what the flame answers, which is how much have I put through the model so far.&lt;/p&gt;

&lt;p&gt;If you'd rather see input tokens, flip &lt;code&gt;TURN_UNIT=tokens&lt;/code&gt; in the CONFIG block, but be aware that as of v2.1.132 &lt;code&gt;total_input_tokens&lt;/code&gt; reflects &lt;em&gt;current&lt;/em&gt; context window, not cumulative session totals, and can drop after a &lt;code&gt;/compact&lt;/code&gt;. The default token thresholds (&lt;code&gt;TURN_MED_TOK&lt;/code&gt; / &lt;code&gt;TURN_HI_TOK&lt;/code&gt;) are tuned to that: fractions of a 200k context, so red means "context is filling up," not "expensive session."&lt;/p&gt;

&lt;p&gt;For historical totals, &lt;code&gt;/usage&lt;/code&gt; gives you the deeper view. The bar nudges you in the moment; &lt;code&gt;/usage&lt;/code&gt; is the rear-view mirror.&lt;/p&gt;

&lt;p&gt;Once the bar is in front of you, two habits move the needle:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pin routine slash commands to &lt;code&gt;model: haiku&lt;/code&gt;. Commit, lint, review-diff: none of these need Opus.&lt;/li&gt;
&lt;li&gt;Use subagents for delegation. They get a fresh, isolated context window, not your full history.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When a session has done its job, &lt;code&gt;/clear&lt;/code&gt; before the next task so you're not dragging a stale context forward; if you want to keep the thread, &lt;code&gt;/compact&lt;/code&gt; reclaims the space instead. Then swap to the model the next task actually needs.&lt;/p&gt;




&lt;p&gt;The data was always there. Now you can see it.&lt;/p&gt;




&lt;p&gt;The repo is at &lt;strong&gt;&lt;a href="https://github.com/newell-paul/statusline-hud" rel="noopener noreferrer"&gt;github.com/newell-paul/statusline-hud&lt;/a&gt;&lt;/strong&gt;. Issues and PRs welcome.&lt;/p&gt;

</description>
      <category>claude</category>
      <category>programming</category>
      <category>ai</category>
      <category>productivity</category>
    </item>
    <item>
      <title>I Programmed an AI in 6502 Assembly - It Worked</title>
      <dc:creator>Paul Newell</dc:creator>
      <pubDate>Wed, 06 May 2026 12:21:00 +0000</pubDate>
      <link>https://dev.to/newellpaul/i-programmed-an-ai-in-6502-assembly-it-worked-gpi</link>
      <guid>https://dev.to/newellpaul/i-programmed-an-ai-in-6502-assembly-it-worked-gpi</guid>
      <description>&lt;p&gt;In 1975 the 6502 processed 8-bit values through memory and control flow. A Claude Code skill now uses the same mnemonics to process forge tickets through triage loops.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Paul Newell&lt;/strong&gt; · Apr 2026 · 8 min read&lt;/p&gt;




&lt;p&gt;I'll be honest, this started as a joke. I wanted to see if I could get Claude Code to understand 6502 assembly language. &lt;/p&gt;

&lt;p&gt;The 6502 powered the Apple II, the Commodore 64, the BBC Micro, the NES. It had 56 opcodes, 64KB of address space and absolutely no business anywhere near a large language model.&lt;/p&gt;

&lt;p&gt;So I built a Claude Code skill that maps its instruction set onto a modern triage-and-fix workflow. You write &lt;code&gt;.s&lt;/code&gt; files. Claude executes them. Its response is also assembly. There's a zero-page. There's a stack. &lt;code&gt;BRK&lt;/code&gt; means "commit and halt."&lt;/p&gt;

&lt;h2&gt;
  
  
  Same Verbs, Bigger Nouns
&lt;/h2&gt;

&lt;p&gt;Forty years later I'm writing LDA to load issue 42, which arrives with a description, acceptance criteria, a set of labels, screenshots Claude can actually &lt;em&gt;see&lt;/em&gt; with vision and a graph of linked PRs. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The verbs haven't changed. The nouns got about six orders of magnitude bigger.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The Smallest Useful Program
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj7fse810fejq252dsh2l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj7fse810fejq252dsh2l.png" alt="peek.s" width="788" height="466"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;peek.s - &lt;em&gt;6502 looking very out of place in colour&lt;/em&gt;&lt;/em&gt;&lt;br&gt;
&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Six opcodes, three flags in play. This is the heart of what the whole thing does:&lt;/p&gt;

&lt;p&gt;It's not a real 6502, of course. I just borrowed the mnemonics.&lt;/p&gt;

&lt;p&gt;If the tests pass (&lt;code&gt;C=1&lt;/code&gt;), commit and halt. If they fail (&lt;code&gt;C=0&lt;/code&gt;), branch to &lt;code&gt;skip&lt;/code&gt; and return without committing. That's it. The &lt;code&gt;BCC&lt;/code&gt;/&lt;code&gt;BCS&lt;/code&gt; pattern carries over directly from the real 6502. Carry set means success, carry clear means failure.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Trace Is the Reply
&lt;/h2&gt;

&lt;p&gt;An 800-token prose response ("Let me analyse this issue. I'll start by examining the file at...") becomes a handful of lines of assembly trace.&lt;/p&gt;

&lt;p&gt;Issue fetched, file fixed, tests passed, diff reviewed, committed, PR opened. No "Let me now...", no "I'll proceed to...", no "Here's what I did...". Just the trace.&lt;/p&gt;

&lt;p&gt;That trace is structured. Diffable. Greppable. Re-runnable. Whether it costs fewer tokens than prose turned out to be more complicated than I expected, but the structural value is still there.&lt;/p&gt;

&lt;h2&gt;
  
  
  One Shot, One Fix
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;oneshot.s&lt;/code&gt; is the next step up: fetch an issue, analyze it, fix it, test it, self-review, and commit, with a single retry branch if the first attempt fails.&lt;/p&gt;

&lt;p&gt;If the first fix passes tests and review, &lt;code&gt;BRK&lt;/code&gt; commits immediately. If not, the retry branch gives it one more shot. If that also fails, &lt;code&gt;RTS&lt;/code&gt; leaves the branch uncommitted for a human to pick up. The carry flag is doing exactly what it did on the original chip,  routing control flow on a binary result.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgoogz5aichu7hd32m3w7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgoogz5aichu7hd32m3w7.png" alt="oneshot.s" width="800" height="640"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;oneshot.s - that's better, much easier on the eyes&lt;/em&gt;&lt;br&gt;
&amp;nbsp;&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Works: 15 Opcodes and 9 Vectors
&lt;/h2&gt;

&lt;p&gt;The skill is called &lt;strong&gt;opcode&lt;/strong&gt; and it defines a semantic DSL that borrows the 6502's mnemonics but maps them onto issue triage. The core ISA is just 15 opcodes. You can genuinely hold the entire thing in your head.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;LDA&lt;/code&gt; loads an issue. &lt;code&gt;STA&lt;/code&gt; persists to a slot. &lt;code&gt;LDX&lt;/code&gt;/&lt;code&gt;INX&lt;/code&gt;/&lt;code&gt;CPX&lt;/code&gt; handle loops. &lt;code&gt;JSR&lt;/code&gt; calls one of nine I/O vectors: &lt;code&gt;FETCH&lt;/code&gt;, &lt;code&gt;FIX&lt;/code&gt;, &lt;code&gt;TEST&lt;/code&gt;, &lt;code&gt;LINT&lt;/code&gt;, &lt;code&gt;REVIEW&lt;/code&gt;, &lt;code&gt;PUSH&lt;/code&gt;, &lt;code&gt;PULL&lt;/code&gt;, &lt;code&gt;CLONE&lt;/code&gt;, &lt;code&gt;ANALYZE&lt;/code&gt;. &lt;code&gt;BCC&lt;/code&gt;/&lt;code&gt;BCS&lt;/code&gt; branch on test results. &lt;code&gt;BRK&lt;/code&gt; commits and halts. &lt;code&gt;PHA&lt;/code&gt;/&lt;code&gt;PLA&lt;/code&gt; push and pop todos from a stack that maps directly to Claude Code's task list.&lt;/p&gt;

&lt;p&gt;There's a zero-page with named slots. &lt;code&gt;$00&lt;/code&gt; is the current issue ID, &lt;code&gt;$01&lt;/code&gt; is the branch name, &lt;code&gt;$02&lt;/code&gt; is the current file, &lt;code&gt;$05&lt;/code&gt; is the commit message. The fetched issue queue lives at &lt;code&gt;$10-$1F&lt;/code&gt;. The stack page at &lt;code&gt;$0100-$01FF&lt;/code&gt; &lt;em&gt;is&lt;/em&gt; the Claude Code task list.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Opcode Oriented Programming (OOP, obviously 🙂)&lt;/p&gt;

&lt;p&gt;6502 mnemonics. Modern AI execution. Workflows as programs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It talks to GitHub or GitLab through a forge abstraction layer so &lt;code&gt;JSR PUSH&lt;/code&gt; opens a PR on GitHub or an MR on GitLab. Nobody has to compromise their vocabulary.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Real Triage Session
&lt;/h2&gt;

&lt;p&gt;This program loops through every issue labelled bug, tries to fix each one and only commits the ones where tests pass and the self-review is clean. Failed fixes get skipped. At the end it opens PRs for everything that worked. The &lt;code&gt;PHA&lt;/code&gt;/&lt;code&gt;PLA&lt;/code&gt; cycle maps directly onto Claude Code's task list so each pushed issue becomes a real tracked todo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl2hrws5b6bfl3brbpyj5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl2hrws5b6bfl3brbpyj5.png" alt="drain-the-swap.s" width="800" height="600"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;drain-the-swamp.s - in its preferred output format; complete with historically accurate code review comments&lt;/em&gt;&lt;br&gt;
&amp;nbsp;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Constraint Is the Feature
&lt;/h2&gt;

&lt;p&gt;The 6502 aesthetic isn't just nostalgic decoration, it's a forcing function. When your output format is assembly you commit to a verb sequence before execution instead of wandering through chat mode. The resulting traces scan way faster than prose. They're diffable, greppable and versionable. You can commit a &lt;code&gt;.s&lt;/code&gt; file alongside your code and re-run it on the next batch of issues.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The temptation to add "just one sentence of context" is the whole failure mode. Resist it absolutely.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The skill is pretty militant about this. Claude's response must be a valid &lt;code&gt;.s&lt;/code&gt; program. No greetings, no sign-offs, no "Let me", no markdown headers. If it doesn't fit as an instruction, a directive or a semicolon comment it doesn't get said. There are escape hatches like &lt;code&gt;.ASK&lt;/code&gt; for questions (≤60 chars), &lt;code&gt;.NOTE&lt;/code&gt; for observations (≤80 chars) and &lt;code&gt;.ERR&lt;/code&gt; for errors. But these are pressure-release valves, not invitations to prose.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Extended ISA: For Completeness and Nostalgia
&lt;/h2&gt;

&lt;p&gt;There's a full extended layer (~40 more mnemonics) you can opt into with &lt;code&gt;.EXTENDED ON&lt;/code&gt;. Shifts become priority promotions (&lt;code&gt;ASL A&lt;/code&gt; = "promote priority"). Logic ops become label-filter algebra (&lt;code&gt;AND #imm&lt;/code&gt; = "intersect label mask"). &lt;code&gt;BVS&lt;/code&gt; branches on merge conflict. Most of these are tagged as metaphor so they get narrated in the trace but not actually executed.&lt;/p&gt;

&lt;p&gt;And for completeness there are six illegal opcodes behind &lt;code&gt;.UNSAFE ON&lt;/code&gt;. The real undocumented 6502 ops like &lt;code&gt;LAX&lt;/code&gt;, &lt;code&gt;SAX&lt;/code&gt; and &lt;code&gt;DCP&lt;/code&gt;. Pure flavour. Narrated, never executed, not even with the directive set. They exist simply because I could not resist adding them.&lt;/p&gt;

&lt;h2&gt;
  
  
  What about tokens?
&lt;/h2&gt;

&lt;p&gt;I expected the tight assembly output to translate to substantial cost savings versus prose Claude. The story turned out more nuanced.&lt;/p&gt;

&lt;p&gt;The reason is asymmetric overhead. For small, deterministic tasks, the orchestration overhead dominates the work — like running a CI pipeline to compile a single file. Opcode comes out ahead on larger programs with more decision points (multi-issue queue walks, longer reasoning chains where prose Claude would actually ramble).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Prose prompts invite interpretation. Assembly doesn't.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  So Is This Actually Useful?
&lt;/h2&gt;

&lt;p&gt;Maybe. if you're running the same triage pattern across many issues like scanning a backlog, fixing straightforward bugs and opening PRs then the token savings start making sense and the structured output is way tighter to read than endless TL;DR prose. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;.s&lt;/code&gt; files are reviewable artifacts. &lt;/p&gt;

&lt;p&gt;The traces are audit logs. &lt;/p&gt;

&lt;p&gt;And the constraint of planning your workflow as a sequence of opcodes before execution turns out to be surprisingly good discipline.&lt;/p&gt;

&lt;h2&gt;
  
  
  BRK
&lt;/h2&gt;

&lt;p&gt;At the end of the day the question is the same one it's always been. &lt;/p&gt;

&lt;p&gt;Are you a quiche eater or a Real Programmer?&lt;/p&gt;

&lt;p&gt;Real Programmers don't need prose. &lt;/p&gt;

&lt;p&gt;They need opcodes, a carry flag and a &lt;code&gt;BRK&lt;/code&gt; at the end.&lt;/p&gt;

&lt;p&gt;Commit the work. Halt the machine 🙂&lt;/p&gt;




&lt;p&gt;Somewhere between &lt;code&gt;JSR FETCH&lt;/code&gt; and &lt;code&gt;BRK&lt;/code&gt; this stopped feeling entirely satirical &lt;/p&gt;

&lt;p&gt;But if this article raised a smile or jogged some long-distant memories then please comment below.&lt;/p&gt;




&lt;h2&gt;
  
  
  The code
&lt;/h2&gt;

&lt;p&gt;Full skill and example programs: &lt;a href="https://github.com/newell-paul/opcode" rel="noopener noreferrer"&gt;github.com/newell-paul/opcode&lt;/a&gt;&lt;/p&gt;




</description>
      <category>ai</category>
      <category>webdev</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
