
The newly-released desktop versions of our microM8 Apple IIe emulator, and turtleSpaces Logo coding environment now include an MCP (Model Context Protocol) server built-in.
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 had 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.
So 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.
Be the first to comment