Converting games for GX4000 - How to/FAQ

Hi guys, with the interest in converting disk games to gx4000 cartridge, I thought I would put together a short (well it started out short in my head) how-to/FAQ detailing the methods I use. And disclaimer, I have only been doing this for a short while and am learning as I go, so please don’t take anything I say as gospel, I am by no means an expert on the Asmtrad hardware. However I do very much enjoy learning about this old machine and challenging myself, it can be a very satisfying and addictive hobby.

When I decided to first have a crack, I read the good CPC fanzine article here https://www.cpcwiki.eu/imgs/6/6f/CPC_Fanzine_-_GX4000_conversion.pdf

That article has a lot of very useful information which got me started, and I was very fortunate that the first game I chose to convert, Dynamite Dan, was suitable for conversion with the methods described. Unfortunately, there are a few situations the article does not mention and in fact the majority of games I have converted since would not be convertible using the methods in that article.

The article describes using a hex editor to edit a disk file directly, to make byte-level changes to the game code. This only works in situations where the program is neither compressed or encrypted. For the majority of games you will be attempting to convert, the disk file you start with will be “cracked”, and crackers just love encrypting and (especially) compressing their works. Although with crude forms of encryption (often just using simple xor algorithms) you can work backwards to figure out what the bytes on disk should be (I did this with Shogun), it is very laborious and requires intense concentration and note-keeping. Not a path I would recommend.

Why do you often need to start with a cracked version rather than a commercial version? In a lot of cases, disk games load data from the disk at some point - even if it’s just a loading screen. A lot of larger games will load each level individually. Often, commercial games accessed the floppy disk controller directly rather than via the ASMDOS ROM. As soon as a game does this, it cannot be converted with nocart, so won’t run on the gx4000. Crackers often took commercial games and replaced the direct floppy access with calls to the AMSDOS firmware, as this would allow bypassing of copy-protection etc. So cracked versions often will work with nocart, as-is.

There are two reliable ways to check if the .dsk file you have uses the firmware or not. First, load it up in Winape and go to the “edit disk” menu. Click to “show system files”. If you see multiple files, chances are it will work with nocart as-is, as it is using AMSDOS standard files with standard headers. To confirm, you can run the game in winape and set a breakpoint on the FDC (floppy disk controller) via Debug → Breakpoints → Input/Output → Add → FDC Data. When the debugger breaks when the game tries to load data, have a look at the bottom of the debugger and see if the checkbox for “Upper ROM” is ticked. If it is, that is good as it means AMSDOS is being used.

I should state that I have not tried every single emulator out there, but of those I have tried Winape is far and away the best for doing any sort of development work, despite having a few little minor niggles I would love to change.

So I did convert a couple of games using the manual .dsk file manual edit method (using a hex editor, HxD) but I found it frustrating as it was very hard to keep track of any changes made, and if you screwed up one byte you could be back to square one or in an unknown state. As a programmer by trade, I am used to using source control such as git so that I can break all my changes down into small commits so that I can always see a history with notes of what I’ve done.

So with the next game I converted, I decided to experiment with an alternative method and it proved successful and this is the method I have used with every game I have converted since.

I start with a CPCTelera blank project. You will possibly be familiar with this excellent utility, it is a c compiler for the amstrad which generates a .dsk file. There are lots of docs if you Google it.

There are two possibilites now with any given game, are the files compressed or not. To find out, run the game (the actual game where you are playing) and pause its execution anywhere with F7. In the debugger you will see the current instruction address (PC) with the opcode bytes on the right. Open the .dsk file in a hex editor and search for the handful of bytes starting from where you are paused. If you find them in the .dsk file and everything matches, great, the binaries are probably not compressed and you can skip the next bit.

If they are compressed, it’s a bit more tricky as you need to locate the exact point where the decompression is complete and the game launches. The easiest way to do this is to run game (e.g. run "disc) and set a breakpoint in WinAPE on the actual start address beforehand. You can find this in the disc editor, by right-clicking a file and selecting “Properties” then looking at Exec Address.

Now I will talk about using AI to comment and annotate disassembly, which is the most useful tool in the toolbox. To do this by hand is possible, but a huge time-consuming and frustrating task - not really viable if you have a job, family, or any other hobbies. So once you are paused somewhere at the beginning of or inside the decompression routine, scroll around in the debugger, usually forward in memory and keep going for 0x1000 bytes or so. Generally until you see a “RET” but end address is not crucial as you can pick up more later. Shift-click to select that block of instructions, then right-click and “Disassemble”. Just push OK on the dialog. Push F3 to show the assembler if it didn’t pop up. Now you have the source-code, but in a very raw format, which is basically useless without being broken up into routines and thoroughly commented.

Once you have the raw assembly from WinApe, copy and paste it into a new file in your project (start a new git folder/project for each game you convert). I use a naming convention like “GameZ0x1000-0x2000.raw.asm”. Then use an AI tool with a specific prompt to convert this into something readable. You don’t need to pay any money for AI tools! The free ones are perfectly adequate. The ones I use are Opencode and Freebuff, both provide a variety of models you can use completely for free. They are extermely easy to set up and use. Choose the most powerful model available on its max setting (ask AI if unsure which is best). I’ll include the prompt I use below, you can put this in a file and either copy/paste it or point the AI tool at it, and your .asm file:

“For the z80 code block at (your file path), designed to run on the Amstrad CPC, add inline comments showing high-level functions and separate into subroutines, with a header for each major/minor subroutine describing its purpose. Alter any labels to be more descriptive, but retain the address at the end of the label. At the top of the file add a summary comment with a bullet point list of the major functions contained within. Output the commented disassembly as a single block without dropping any instructions or data into a new file beside the existing. Try to identify any areas that are actually data and not code where possible. Refer to the firmware manual here if necessary for ROM calls etc: https://www.cantrell.org.uk/david/tech/cpc/cpc-firmware/firmware.pdf”

Once the AI has done its job, you will have something hopefully readable that you can analyse. If it’s done a poor job, or the routines don’t look relevant to decompression and game launch, just grab another section of memory and repeat, or try another alternative AI model.

Hopefully you will see something like decompress data, then JP 0xXXXX to actually launch the game (or its title screen). In my experience there is almost always a JP XXXXX statement which is the entry point to what would’ve been in the commercial game. Quite often it is a whole number like 0x100 or 0x500 as developers like picking round numbers. Another alternative for finding the entry point is to run the actual commercial version and see where it actually launches by examining disk file properties.

Once you have the game entry point (which is trivial if you don’t have a compressed/encrypted version), you can dump the contents of RAM by putting a break point at this adress.

OK this is getting much longer than I intended so if anyone is interested in more let me know and I will keep writing below or move it to a wiki article!

5 Likes