Connect AI to microM8 Apple IIe Emulator using MCP (Model Context Protocol) for ‘Vibe Coding’ and other activities…

Use Large Language Models such as ChatGPT, Claude or Grok to code and / or execute Apple II programs

The newly-released desktop versions of our microM8 Apple IIe emulator now include an MCP (Model Context Protocol) server built-in.

Claude Code playing Zork

These allow external AI applications to control them in various ways. We will explain the ‘how’ a little bit after we explain the ‘why’:

WHY ‘VIBE CODE’ AN APPLE II?

The usage of Large Language Models (LLMS) has always been contentious, especially their disruption in creative industries and education, where they’ve upended the traditional model of examinations and research papers and forced more practical evaluations.

These disruptions have caused a mixture of worry and excitement that they would be coming for the software engineers at some point. But they have struggled to become truly useful at programming, especially novel programming.

This has much to do with their ability to actually reason. Even a year ago they were really bad at thinking but over the last year that has changed somewhat — they’re a little less terrible. This has changed due to three main factors, the scale and resolution of the model itself, the algorithm behind getting a result, which now iterates better in an attempt to refine a result and improve accuracy, and a larger ‘context’ that allows for the insertion of large amounts of reference material, consideration of past history and the ability to search the Internet for information.

All of that has begun to make them vaguely useful, not just for regurgitating boiler-plate or cribbing from open source projects but to actually divine and write original code.

And so as a result companies have begun to use LLMs to write configuration and in-house production software, despite the fact that the intellectual property status of their output is still largely unsettled. But for internal use in creating infrastructure code or tools there’s little concern about that and so where practical they are finding use. But they are a tool not an oracle and so it still does and probably always will need some talent and a great deal of understanding to use them properly, like any other tool. A great tool needs a great craftsperson, always has and always will.

Anyway, so it looks like LLMs may be here to stay, and assuming they continue to improve will continue to encroach into other areas of software development. But as I’ve alluded to it’s not just future technological improvements that will determine their success, there is an additional factor to consider — when the Apple II originally came out, programs were rather crude, because programmers were new to them, reference material was scarce and techniques were primitive. Over time they improved, not because the Apple II changed but because programmers learned how to utilize the hardware and ROM code better. They developed understanding, techniques and strategies to leverage what they had as best as they could, and this learning was continuous over time.

LLM’s are the same. They are a technology that we have even barely begun to learn how to properly exploit. Currently we want to treat it like a rock, and just smash stuff with it, with obvious results. But you can’t use it like a rock. If you just ask it to make a game, with all of the associated mechanics, in a single prompt then it’s almost certainly not going to work, and attempts to fix the code after the fact are going to fail because the bad code is all that there is to work with. It becomes a fruit of the poison tree situation.

And so you have to learn to be incremental and patient, provide all of the necessary information, and really think about how you engineer your prompts to get the best results out of the LLM, and especially if you want to use them to write programs for the Apple II, which LLMs know very little about.

So, why would we want to use LLMs in retrocoding. Well, there are a few areas that they can assist with:

  • Writing new code — it’s fun to code but it can be tedious and frustrating and I know a lot of us have a sense of reward when we make a trivial mechanic work especially if it was buggy but most people don’t enjoy that sort of sadomasochism, but would still find enjoyment making something out of their imagination work, and it’s certainly easier to make something work on a retrocomputing platform than on a modern computer, unless you want to write it in Scratch or turtleSpaces, which we’ll get to later.
  • Debugging existing code (theirs and ours) so even if the code itself is written by hand they can still get us out of a bind, especially if you use an MCP so the LLM can control the emulator itself, which is something we will get to shortly. Debugging sucks, really stubborn bugs suck, if an LLM can circumvent us spending hours and days on a bug who can complain, really?
  • Learning how to code with the Apple II architecture — most of us are tinkerers at heart but learning things like assembly is a bit of a task given you have to do a fair amount to get it to do anything of substance. Getting the LLM to write some code helps learn about assembly but more importantly it helps learn about the architecture, memory maps, zero page and all that stuff. So as an educational tool it’s quite useful.

On that note too, just in general LLMs can actually a really good educational tool, from a constructivist perspective, assuming you use them to actually create something substantial and sophisticated. It’s one thing to use it to just barf out some text or a single throwaway image but engineering a prompt to get precisely what you want can take a lot of trial and error and you start to develop an understanding of how and why you need to phrase things in certain ways to get the LLM to do what you want. Which is a lot of thinking about its way of thinking. It’s like a really fancy Logo turtle. It will draw what you want to draw but you have to tell it how to draw it in really fine detail.

Also, many of us learned how to code debugging faulty magazine listings because it was our only source of new software. Once you can start helping the LLM debug by following program flow and learning what all the symbols do you’re on your way to being able to start writing programs yourself, or begin to refine the detail in which you describe what you want to the LLM, which does a much better job if you can describe things in terms of the language and architecture more specifically, and less broadly.

Claude Code creating a Print Shop card

HOW TO ‘VIBE CODE’ FOR AN APPLE II (BRIEFLY)

Two easy ways to begin are to use our web-based CyaniIDE Merlin Assembler / Editor or Applesoft BASIC editor (you can copy and paste any LLM’s output into the editor and assemble / execute it to test) or you can use the MCP server with microM8 to have the LLM assemble code directly into microM8 (see directions below).

First we’ll look at creating a new coding conversation. With modern LLMs luckily we don’t need to provide all of the information with every prompt, their ‘context’ or how much external information they can process has grown over time and they can reference an entire conversation, to a point. Conversations only last so long and if you’re not done quickly you will often need to start a new one and bring the LLM up to date. Also conversations are seeded with randomness and if things aren’t going well you can benefit by starting a new one.

But for a new conversation coding Apple II Merlin assembly, you should probably provide it with a bunch of information about the Apple II, which has a lot of esoteric idiosyncrasies that have to be taken into account.

First there’s some general things you want to tell it:

FOR EACH CHANGE:

ONLY DEAL WITH THE IMMEDIATE ISSUE 
DO NOT REVISIT ISSUES DISCUSSED EARLIER UNLESS CHANGES COULD REINTRODUCE THEM / CREATE REGRESSIONS
ANALYZE, FORMULATE AND DESCRIBE AN APPROACH
IMPLEMENT SAID APPROACH. DO NOT DEVIATE, BUT NOTE CONCERNS
DELIVER CHANGED CODE AND IF APPROPRIATE, CONCERNS
VOLUNTEER TO ACT ON CONCERNS IF USER AGREES
COMMENT EVERYTHING! (This is as much for you as it is for the LLM — you can help debug if it gets stuck)
REMEMBER TO REMOVE STREAM OF CONSCIOUSNESS THOUGHTS FROM CODE (Sometimes Grok will do this, which is odd)
IF YOU ARE UNCERTAIN ABOUT SOMETHING, ASK USER (It won’t always ask even if you ask it to, though)

And then Merlin specific things:

RETURN OUTPUT IN CODE BLOCK
INDENT AND USE ORG $XXXX
CONSULT MEMORY MAP BELOW AND ENSURE THAT COMPILED CODE WILL NOT VENTURE INTO INAPPROPRIATE MEMORY AREAS
USE ONLY SEMICOLONS FOR COMMENTS
DO NOT USE DS WITH ZEROPAGE, USE EQU POINTERS AND VERIFY AVAILABILITY
PLACE EQU AT TOP OF SOURCE
PLACE DATA AT END OF SOURCE

And then documents about Merlin Assembly, 6502 opcodes and addressing, Apple II memory areas, ROM routines, Zero page and so on.

BE INCREMENTAL. Although you can have it plan out implementation of a broader game idea, you want to implement it incrementally. If you’re making a pong game, make the paddle code first, or make the ball code first, but don’t try to make the paddle and ball code at the same time, it probably won’t end well.

If you can provide some relevant code that works and is commented, that will be useful too. The LLM will look to it for guidance.

The MCP documentation appears after this message from our AI sponsor:

 

HOW TO START MICROM8 APPLE IIE EMULATOR AS AN MCP SERVER (FOR VIBE CODING AND OTHER ACTIVITIES…)

MCP (Model Context Protocol) Server Integration

Enables AI assistants and LLMs to interact with microM8:

  • Compatible with Claude, ChatGPT, and other MCP-enabled clients
  • Two transport modes: stdio (default) and SSE (Server-Sent Events)

How to Enable MCP Server (you must start the executable from the command line using a terminal)

Stdio Mode (default):

./microM8 -mcp

Config:

{
    "mcpServers": {
        "microm8": {
            "args": [
                "-mcp"
            ],
            "command": "microM8",
            "description": "MCP server for controlling the microM8 Apple II emulator. Provides tools for disk management, keyboard input, memory access, and emulator control.",
            "name": "microM8 Emulator Control"
        }
    }
}

  • Uses standard input/output for communication
  • Best for direct integration with AI tools

SSE Mode (for web-based clients):

./microM8 -mcp -mcp-mode sse
./microM8 -mcp -mcp-mode sse -mcp-port 8080

Config:

{
    "mcpServers": {
        "microm8": {
            "url": "http://localhost:1983/mcp/sse",
            "type": "sse",
            "description": "MCP server for controlling the microM8 Apple II emulator. Provides tools for disk management, keyboard input, memory access, and emulator control."
        }
    }
}
  • HTTP-based Server-Sent Events transport
  • Default port: 1983
  • Includes CORS support and heartbeat mechanism
  • Health check endpoint at /mcp/health

Once the LLM is connected, it can do the following things:

MCP Emulator Control Tools

  • reboot: Restart the emulator
  • pause: Pause/unpause emulation
  • break: Send break signal (Ctrl+C)
  • set_cpu_speed: Adjust CPU speed multiplier (0.25x to 4x)
  • screenshot: Capture emulator screen
  • type_text: Type text with configurable keystroke delay
  • key_event: Send individual keyboard events

MCP Disk Management

  • insert_disk: Insert disk images into drives
  • insert_disk_file: Insert disks from virtual file system
  • eject_disk: Remove disks from drives
  • get_mounted_disks: List currently mounted disks with paths and write protection status
  • Automatic detection of 5.25” vs 3.5”/HD disk types

MCP Recording and Rewind Tools

  • enable_live_rewind: Enable live rewind functionality
  • rewind_back: Rewind emulator state by milliseconds (default: 5000ms)
  • start_file_recording: Start recording to file with optional full CPU mode
  • stop_recording: Stop any active recording (file or live rewind)

MCP File System Access

  • list_files: Browse the virtual file system
  • read_file: Read files with automatic text/binary detection
  • Access local files, disk images, and remote resources
  • Support for all microM8 file providers

MCP Memory Operations

  • read_memory: Read bytes from any memory location
  • write_memory: Write individual bytes
  • write_memory_range: Write multiple bytes efficiently
  • get_text_screen: Capture current text display

MCP Programming Tools

  • assemble: Compile 6502 assembly code to memory
  • disassemble: Disassemble memory to 6502 instructions
  • applesoft_read: Extract BASIC programs from memory
  • applesoft_write: Tokenize and load BASIC programs

MCP Debugger Integration

  • debug_cpu_control: Step, continue, pause execution
  • debug_breakpoint_*: Manage breakpoints
  • debug_register_*: Read/set CPU registers
  • debug_memory_*: Advanced memory operations
  • debug_instruction_trace: View execution history
  • Automatic debugger initialization when needed

MCP Implementation Details

  • Uses official Go SDK for protocol compliance
  • JSON-RPC 2.0 communication protocol
  • SSE mode includes 30-second heartbeat for connection stability
  • Comprehensive error handling and validation
  • Type-safe parameter structures with JSON schema

…so as you can see, the LLM can do much more than simply code, it can also use various features in the emulator. It can create Print Shop cards for you, play an adventure game, etc. Fun!

Download microM8 Apple IIe Emulator here

Downloads available for Windows, macOS and Linux

 

Be the first to comment

Leave a Reply