Porting my 1993 Amiga game to Godot, with an LLM reading the 68000 assembly
Posted by rabahs 5 days ago
These are my notes from porting my Amiga game, which I originally built in Baghdad in 1993 in MC68000 assembly, to Godot, using Claude Fable 5 during last July holiday. It took an evening! Getting the feel right and shipping it took a few more weekends and evenings.
I spent the last few weeks analyzing what Claude did, feeding it my 33 years of memory of how I built the game, my notes and the git repos. It wrote the first draft of the article, and I edited line by line over a week. The screenshots of my 1993 map editor is the first I have run it since then. The one thing I never verified myself is the 108-byte explanation.
"Before starting everything, the model assembled the code using vasm on my Mac, and kept going till the binary is byte-identical to the binaries I had in my original game. Even after that, the there was mismatch of about 108 bytes. I originally used AsmOne which assembles into memory, and the game saved into the disk by saving that memory after running the game. So the original shipped files are a snapshot of the game that had already been running, not clean asm-one output."
Please post any questions. I am also releasing the original game for free.
Comments
Comment by gmerc 4 days ago
- The Adventures of Robin Hood - Opus 4.7/Sonnet https://robin.tooclever.org
- Syndicate - Sol/Luna 5.6/Opus ( https://this.os.isfine.org/blog/posts/modern-game-port-syndi... )
- Kaiser 2
- Populous Plus - Sol/Luna 5.6/Opus
- Dragon Strike - (Fable 5.1 almost one shot)
- War of the Lance - Qwnen-3.7-27B-dense (got stuck, finished with) Qwen-3.8-Flash-Next https://this.os.isfine.org/blog/posts/what-reverse-engineeri...
- Dungeon Keeper - Various
- Red Baron - Opus 4.8, DeepSeek 4
- Test Drive 3 (Qwen-3.8-Flash Next, DeepSeek-4-Flash-exp, GLM-5.3-Flash)
- In progress Ultima 6 ... to 3d (Fable, GLM-5.3) ( https://this.os.isfine.org/#ultima6-atlas )
Some straight source ports (Kaiser), some full RE jobs (Dragon Strike, Test Drive, WOTL)
Some a mix of available sources (Syndicate, Populous)
Some of the findings are documented here: https://this.os.isfine.org/blog/
Comment by iamflimflam1 4 days ago
Comment by s-macke 4 days ago
One of the most difficult reverse-engineering projects from that era for me was Stunt Car Racer on the C64 (also ported to DOS). It features a highly optimized 8-bit 3D graphics and physics engine. Fable was the first one that was able to generate a complete port of the game.
Now I am trying of Flight Simulator 4 and Wing Commander 1. Then maybe Frontier Elite 2. So much fun ....
Comment by gmerc 4 days ago
Comment by aidenn0 4 days ago
Comment by gilleain 4 days ago
Comment by shevy-java 4 days ago
Comment by Steve16384 4 days ago
Comment by gmerc 4 days ago
There's really nothing much to it, all the knowledge needed is in the weights of the model, so regardless of what you want to do, you can ask "if I wanted to do this, what would be the best way / best practices to get there with my machine"
https://georgzoeller.com/blog/posts/what-reverse-engineering...
Comment by s-macke 4 days ago
1. For each topic, write a result Markdown file in `spec/`.
2. Identify the file formats.
3. Reverse Engineer and extract all assets, followed by manual review. This works in 90% of the cases.
4. Determine the compression/packing used for the executable. Most binaries used one of roughly five common executable packers.
5. Unpack the executable manually.
6. Use an ancient free IDA-Pro for disassembly, or a modified DOSBox to determine all code/data blocks and the relevant segment-register values for the 8086 architecture. In the second case I use my vibe-coded disassembler.
7. Identify the major functional domains in the disassembly and split the files accordingly.
...Comment by muro 4 days ago
Comment by LordDefender 4 days ago
Comment by gmerc 4 days ago
Comment by mt_ 4 days ago
Comment by gmerc 4 days ago
Comment by hippietrail 3 days ago
Comment by jdw64 4 days ago
Comment by mattjoyce 5 days ago
What a crazy thing it is to be first at the advent of personal computing, and then in the inflection point where AI treats that first experience as archeology.
Comment by EagnaIonat 4 days ago
Comment by rabahs 4 days ago
Comment by btbuildem 5 days ago
aka The Book... my, this brings back dusty memories
Babylonian Twins has such strong "Gods: Into the Wonderful" vibes, I wonder if that game was an inspiration for you
Comment by rabahs 5 days ago
Comment by anonzzzies 5 days ago
Comment by larodi 4 days ago
Besides, if it wasn't for BBSs and pirated software, we'd never be ever able to put hands on it, as my country was going through regime change in 1989 and in 1992 the economy was completely mashed down and the game's price was half my mother's salary at the time. What a time to be alive. Of course it was not dad, but a friend who dug it from some BBS or perhaps the eraly tucows archive.
Comment by parlortricks 4 days ago
Comment by dannyobrien 5 days ago
Comment by rabahs 5 days ago
Comment by TacticalCoder 5 days ago
Sooooo cool! I did something similar a few months ago: had the old source code (and executable files) of a game I wrote in 1991 (PC DOS) and a few notes in source code and, well, my old memories of how things worked. I didn't know how to compile it anymore but with the help of LLMs I managed to get it compiling again.
Since then I found about 8 pages of handwritten notes I took back in the days and I did immediately scan them and I added them to the repo.
Now my PC DOS from 1991/1992 does compile again and, well, I really should blog post about it one of these days (if only I had a blog...).
Comment by rabahs 5 days ago
Comment by rererereferred 4 days ago
Comment by rabahs 4 days ago
Comment by cesaref 4 days ago
Back in the day, most Amiga games were made in Europe, so were tuned for 50Hz refresh, and played 'normally' over here. At 60hz, they would feel wrong, and likewise, US games could feel sluggish and unsatisfying.
Locking the machine to the monitor refresh rate in this way was a curse but also a blessing. It allowed the machines to drive a standard television in various regions, although the image was somewhat blurry, but also the use of dedicated monitors once you started taking it seriously. This reduced the price point and allowed lots of kids to convince their parents to get one :) The higher resolution modes just didn't work out though, so lots of stuff targeted the 320x256 resolution.
The surprise benefit was also that the amiga could genlock to a TV signal and used to overlay onto a video feed, leading to many interesting cheap graphics overlay capabilities which were otherwise totally unobtainable by small TV channels or enthusiasts.
Those were happy days.
Comment by Gamemaster1379 4 days ago
Since then I've done static/native ecosystems for the Super NES, GBA. Nintendo DS, Playstation (most popular) and even Sega Genesis, such also uses the 68k.
https://github.com/mstan/segagenesisrecomp
I even extracted the 68k decoder to its own repo because I wanted to reuse it for the Phillips CDI.
Sega does Sonic 1 2 and 3&K. Also Rocket Knight adventures. Still early yet though. CD-I does the BIOS. Didn't get a game running end to end yet though.
Comment by pixelpoet 4 days ago
Comment by rabahs 4 days ago
Comment by Gamemaster1379 4 days ago
https://1379.tech/building-enhancing-recomps-ecosystem-updat... https://1379.tech/recomp-ai-5-months-later/
Ultimately, Sega Genesis has been low priority. I've been focusing mostly on community feedback for my existing ones. Playstation is by far the most popular and the one I get the most PRs on. SNES is second. And right now Nintendo DS is newer, but has a very popular Metroid Prime Hunters I've been working a ton on.
NES and Sega Genesis get little attention. CDI and VirtualBoy [understandably] get no real attention.
I have an early original Xbox LLE prototype. Hoping to do more with it soon, but I'm all tapped out of usage at the moment. I got a lot done during all the crazy resets with OpenAI there for a while.
Comment by hedgehog 5 days ago
Comment by rabahs 5 days ago
Comment by sedawkgrep 5 days ago
Oh wow...I hadn't even thought of trying something like this. There are soooo many games from that era that I'd love to play again without the hackery of emulation.
Comment by rabahs 5 days ago
Comment by WarcrimeActual 4 days ago
Comment by rabahs 4 days ago
Comment by ericd 5 days ago
Comment by asimovDev 4 days ago
this is the closest thing I could find. do you have a link to the reverse engineered RA2? I am surprised I do not get any recent repositories or forum posts about this, you'd think it would be more talked about
Comment by hnlmorg 5 days ago
Comment by rabahs 5 days ago
Comment by Steve16384 4 days ago
Comment by rabahs 4 days ago
Comment by ecliptik 5 days ago
Comment by 1313ed01 4 days ago
Comment by ndiddy 4 days ago
Comment by asimovDev 5 days ago
Comment by rabahs 5 days ago
Comment by asimovDev 5 days ago
Comment by b112 5 days ago
Comment by robviren 5 days ago
The amount of non standard hackish and obtuse things that had to be done to implement things in the past feel impossibly complicated to touch today. Lots of people made it up as they went along and used the hardware in ways no one expected. Reminds me of Tim Follin doing the audio for Plock on SNES and Miamoto being shocked the audio was real. It would be so interesting to see what we could learn about development of the past from agentic insights into how code was constructed. I love stuff like this an appreciate the in depth post.
Comment by seobotaicom 4 days ago
Comment by kschiffer 4 days ago
It's amazing that this is possible. I took quite a bit of steering and was definitely not a one prompt endeavor but having a lot of fun with it.
Comment by ericd 5 days ago
Comment by efficax 5 days ago
Comment by ericd 5 days ago
Comment by nnevatie 4 days ago
Amiga 500 (and 1000 prior to it) supported smooth scrolling by simply setting the screen-visible pointer in memory.
Comment by snvzz 4 days ago
move.l #$dff000,a0 ;Base for hardware registers
lea save(pc),a1 ;Get the system
move.w #$4000,intena(A0) ;from the AMIGA
Crude, although perfectly fine in practice. The system-friendly way is to call the function exec.library has for the purpose, Disable()[0].
0. http://amigadev.elowar.com/read/ADCD_2.1/Includes_and_Autodo...
Comment by rabahs 4 days ago
Comment by snvzz 2 days ago
It's all in the NDKs, which I didn't have at the time, either. I only got my hands on the AHRM once I started university, and that was after 2000.
Having very belated fun with Amiga development today. It's never been easier to get into, with all the archived tools and books, and the modern ones.
Comment by coder-pm 5 days ago
Comment by Lerc 5 days ago
The proof of the pudding would be to have a look at what the differing bytes were encoding.
Comment by coder-pm 4 days ago
Comment by rabahs 5 days ago
Comment by coder-pm 4 days ago
Comment by rabahs 3 days ago
Comment by coder-pm 3 days ago
Comment by Lerc 5 days ago
Their approach to replicating the behaviour is to run the original game logic. The display has to be totally rewritten but they had the advantage of 68k for both machines.
I don't know of any games that used the blitter for calculation like some programs did for MFM decoding, that might have presented quite the porting challenge.
Comment by rabahs 5 days ago
Comment by abrookewood 4 days ago
Comment by rabahs 4 days ago
Comment by Sharlin 5 days ago
Comment by rabahs 5 days ago
I have not compared the 2010 port to the current Godot port. However, I felt the Godot port was smoother. I think that was because Godot uses the latest graphics frameworks (e.g Metal) vs old Opengl ES 1. It would also be interesting to compare the godot port of the original game vs the original in assembly. Curious how I can achieve that. A good question to ask Claude.
Comment by Sharlin 4 days ago
Yeah, that's fair. I was just wondering what the performance of a modern version as close to the original would be, if written with Godot or another vastly higher-level framework than handwritten assembly. Given the 3+ orders of magnitude difference in processing power and memory.
Comment by rabahs 4 days ago
Comment by Sharlin 4 days ago
I also doubt the Godot version fits in 512kB of RAM ;)
Comment by glimshe 5 days ago
Comment by rabahs 5 days ago
Comment by saulpw 5 days ago
Comment by glimshe 4 days ago
Comment by saulpw 4 days ago
Comment by glimshe 3 days ago
Comment by byako 5 days ago
Comment by ropable 4 days ago
Comment by rabahs 4 days ago
Comment by appstorelottery 4 days ago
Comment by gmerc 4 days ago
Comment by rabahs 4 days ago
Comment by larodi 4 days ago
Comment by sgt 5 days ago
Comment by rabahs 5 days ago
Comment by sgt 5 days ago
Comment by rabahs 5 days ago
Comment by pkilgore 4 days ago
Confirmed in that last paragraph. Just interesting to me I can detect gradations of AI speak at this point.
Comment by smilbandit 4 days ago
Comment by shevy-java 4 days ago
But why is the 2026 twin facing right when the original faced left?
It's only a minor detail, but IMO it would be easier for comparison if they both would point in the same direction.
Comment by rabahs 3 days ago
Comment by deterministic 3 days ago
Comment by rabahs 3 days ago
Comment by jeanmichelselli 4 days ago
Comment by Jach 4 days ago
Your game looks cool. It's a full, real game! And while I now think that there's no longer strong "platform convenience" reasons to choose any tech stack if these AIs can just bulldoze their way through difficulties, I'm sure running in Godot still made a lot of things easier for it.
Comment by Steve16384 4 days ago
Comment by Jach 4 days ago
More reasons come from trying to predict where AIs and our interactions with them will be in 6 months, 1 year, 2 years, 5 years. Will we even be alive? Other reasons from wondering about alternative actions: is asking the magic box to do this particular thing, rather than some other particular thing, the thing that will actually bring you (or others) joy right now? Or money? Satisfaction? Fame? Upvotes? Some other things you want to feel or experience or do? (And in the OP's case, I think there's actually quite a good case of actions matching motivations, given the full history, and especially as earlier pre-AI-tooling ports were well-received enough to get a couple million downloads. Still, what about something new?) For my own small efforts this week, the main things I got out of it, besides the nostalgia (which is quite valuable to me), were similar to what I've been getting out of any AI-using projects this year, which is a strange mix of satisfaction, a bit of fun, a bit more awe at these magic boxes (even the dumber ones like Opus and Sonnet), anticipation of showing/telling a few people in person about this particular kind of pointless adventure, and a bit more melancholy about a few things, like the makeup of some of my online hangouts, or that my programming skills have been rapidly decreasing in their having a point to exist, or that my revealed preferences in this case are that I'm happier to let the AI do all the coding for this project and barely look at the code myself (there's a bit of disgust/gross feelings here too). I last thought of doing this work in 2019/2020, never got very far, now it's suddenly done, and even more than I thought of doing. (I still keep the AI out of some other projects, as programming the old fashioned way is in general still pretty fun to me at least.) Now it's on to the next project, when I decide that will be more fun than playing a game (I have such a backlog after all), and I'm sure it'll also be relatively pointless. More the honor to people doing bigger things impacting the world, with or without these tools.
This whole comment is also kind of pointless, I'd rank it as probably more so than the other mentioned things (except I guess watching paint dry), and yet it's here.
Comment by caruasdo 5 days ago
Comment by a2ff6eeb0 5 days ago
Since Claude did the port, wrote the article, and apparently understands it better than you do at this point, can we ask Claude? Is there a git repo we can point Claude at to interrogate it on the way things were done? Maybe you can share the transcripts you used to port it?
It's marvelous that software can be written with minimal human input, but I guess I'm confused about why I would talk to the human that prompted the AI, rather than the AI that did the work.
Comment by rabahs 5 days ago
While doing the analysis, I came to know about this 108 byte delta. I didn't quite understand the explanation Claude gave me. I added more details about this in the post above. It could be the difference in the assembler used, the environment used (Amiga 500 vs M5 Macbook), or how the binary was saved from memory 33 years ago
Comment by rmunn 4 days ago
One reason is because you can't talk to the AI that did the work, not unless the human who prompted it is able to hand you a file with the complete session and/or context data. (And I'm not at all certain whether Anthropic would allow users to obtain that kind of thing, since it would probably be extremely useful to people trying to distill their models. It's possible they might allow user A to say "Hey, allow user B" (or anyone with the link) "to access my session with GUID ba5eba11-1234-5678-abcd-0decafc0ffee", but I doubt they'd ever allow context data to be downloaded and passed around).
Without the context, you're talking to a different instance of the AI that doesn't have the memory of the instance that ported the code, so the answers you get won't be nearly as useful.
Comment by actionfromafar 4 days ago
Comment by mattbruv 5 days ago
Comment by dang 5 days ago
Comment by tomcam 5 days ago
Comment by dang 5 days ago
We understand that our non-native English speaking users are in a special position with all of this, and we sympathize - but we don't have an easy way to treat posts differently on that basis. What we're telling such users is to please write in your own voice and don't worry about any mistakes, because those are rapidly becoming signs of authenticity at this point (https://hn.algolia.com/?dateRange=all&page=0&prefix=false&qu...).
To judge by how the AI classifiers react, translation tools are leaving a ton of LLM imprints on text which are not strictly about translation. As many of us have been learning, it's hard to restrict what these systems do. They are overeager on every level.
Comment by IshKebab 5 days ago
> The test was deliberate.
> Step one, the safe ask
> Step two, the unfair ask
My guess "AI write a blog post about this" and then he edited it, but didn't quite eliminate the stench. Pretty close though to be fair.
Comment by abrookewood 4 days ago
Comment by khazhoux 5 days ago
Think of it as: this is a story that quite possibly would not be told without AI to help with the writeup.
Comment by rabahs 5 days ago
Comment by aenis 5 days ago
Though I'd admit that using claude for a few hours every day this year desensitivized me to its prose :-)
Comment by rabahs 5 days ago
Comment by deterministic 3 days ago
Comment by saadyousfi 5 days ago
Comment by TokenLat 4 days ago
Comment by jocelyner 4 days ago
Comment by xuchenyi 4 days ago
Comment by harisingh1612 4 days ago
Comment by quarrykit 4 days ago
Comment by techsage 4 days ago
Comment by fleroviumna 4 days ago
Comment by lstodd 5 days ago
There is no point in "porting to Godot" because either you port Amiga stuff to UAE-likes or FPGAs or you in fact advertise "AN AI REWROTE MY CRAP GWBASIC GAME FROM 93 LOL". Lol. Which is riduculous.
and people will just laugh.
also 68k asm is actually human-readable compared to x86.
Comment by cstrahan 5 days ago
Why complain about the outcome? The old game remains available, and you can play it for free. This isn’t some zero sum situation where the existence of the remastered game sets the world back in some way. I could see being more interested (or only interested) in playing the original, but I don’t see what motivates the negativity.
Comment by rabahs 5 days ago
Comment by mickeyp 4 days ago
I miss my Amiga 500 and all those days spent playing wonderful games so much. Thank you for the hit of nostalgia.
Comment by tomcam 5 days ago
Comment by urbnspacecowboy 5 days ago
Comment by lstodd 5 days ago