<?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>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;
 &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;
 &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;
 &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>
