Disassembling my old code from 1988 – part 5


This is part 5 of a blog series I’m doing to catalog some of the programs I wrote back in 1988. I’m doing this because I like doing it, it brings back memories of how I started my career with computers, and my first attempts at programming using Z80 machine code. I’m also trying to fully understand how I programmed Disced and I’m relearning how things work on the old Amstrad CPC 6128.

This series will be as long as it takes me to complete, the other parts are listed below.

  • Disassembling my old code part 5 – Get Shift key and set translate (this part)
  • Disassembling my old code part 4 – Set cursor position and disc cache
  • Disassembling my old code part 3 – Text operations
  • Disassembling my old code part 2 – Setting screen mode and using Soft 968
  • Disassembling my old code part 1 – Getting started with WinAPE

So let’s resume where we left off, and that was going through the initial calls at the start of the program. Call L9388 is the next call that we need to understand so let’s get stuck in.

And here’s the source code in focus for that label.

From what I can make out it’s loading the C register with a value of &001A (DEC 26), and then it increases C by 1, before storing the value of C in the A register and then compares it to &0048 (DEC 72) and if so return, if not true it will make a call to the &BB30 firmware routine called KM GET SHIFT (KM=Keyboard Manager).

Now I’ll be honest, at this point I’ve no idea why I’m doing this yet but obviously it’s some sort of key press check. It’ll probably become clear later in my investigations.

Ok back to the routine. After making the call to &BB30 it does some additional instructions.

It loads the value of the A register into B, then subtracts &0041 (DEC 65) and then subtracts &001A, before jumping to L938A if C is reset, if not, it loads the C register into A and then calls the firmware &BB27 which is KM SET TRANSLATE which translates what a key should be if CTRL or SHIFT are not pressed at the same time. It then jumps back to L938A.

So based on the above, I’ll assume that this routine is for checking whether shift/ctrl are being pressed and name the routine accordingly, I can always change it later as necessary.

So here’s that routine all updated with new labels.

Resources used in this post

That’s it for this part, see you again soon in the next part !




Posted in Disassemble, Disced, notepad ++, WinApe, Z80 Machine code | 7 Comments

Disassembling my old code from 1988 – part 4


This is part 4 of a blog series I’m doing to catalog my adventures through some of the programs I wrote back in 1988. If you missed the previous parts, they are listed below.

  • Disassembling my old code part 5 – Get Shift key and set translate
  • Disassembling my old code part 4 – Set cursor position and disc cache (this part)
  • Disassembling my old code part 3 – Text operations
  • Disassembling my old code part 2 – Setting screen mode and using Soft 968
  • Disassembling my old code part 1 – Getting started with WinAPE

I decided that I wanted to start clearing up the beginning part of the code and make sense of the early calls that appear right at the start of the code. So that’s where today’s part begins, on the second call to label L941A.

I don’t yet know what this code does but let’s dig into it.

Here’s the source code in question for this particular label, it’s merely loading the HL register with an address &0605 and then loading that into another address at label &9626.

It then merges into another block of code which utilizes two firmware addresses namely:

  • BE66
  • BE78

So maybe those two firmware addresses will give me some clues as to what is happening here.

And indeed, those two addresses are important, &BE66 is for disc retries (default &10) and & BE78 is for disc error message flag (&00=on; &FF=off – reversed again) as you can see from this Amstrad CPC Firmware Guide.

So I’ve now added those comments from above into the functions (routines ? not sure what they are called in assembly) and hopefully MAXAM won’t complain about the way I’ve added these comments when I eventually try and reassemble this code.

This little code block (which is made up of two blocks of code) therefore seems to disable disc error messages and set’s the disc retries to 5 (I think).

I’m just not exactly sure why I’m loading HL with &0605 and then storing that value at L9626 before it actually sets the retry and disc error message status.

Let’s take a closer look at L9626. Doing so reveals the values &05 &06 which came from the value stored in HL above. So we can assume that these two bytes of data are important in relation to Disc bios actions, so I’ll assign this L9626 a label called DISC_BIOS_DATA: as I don’t yet know what the &05 &06 values are for.

I’ll populate those two bytes in the assembly source code with blank values (&00) seeing as we’ll be poking &05 &06 into them later anyway.

So they now look like this.

And next I use notepad++’s search and replace functionality to replace all instances of L9626 with the new label.

After those edits, I can see our wee block of code now looks like this.

And what’s clear here is that there are a few more areas used for temporary data storage, so for now i’ll just keep using the DISC_BIOS_DATA label but increment it by 1 each time I think it’s relevant, remembering that I’ll probably change a lot of these labels later on once I get it actually running.

I also replaced all references to L9628 with DISC_RELATED_FUNCTION as I see I used before calling &BCD4 later in the code, and that firmware call is to find a ROM command.

As these blocks of code are called right at the beginning of the program I’ll label them DISC_INIT_X, so here’s how it looks now.

and the very start of Disced looks like this now.

Update !

I had the WinAPE disassembler still open after submitting this blog post and I assumed I was done for the day, but the &05 &06 values still had me curious, so I decided to play around with them, hacking the values just like back in the day to see if I could figure what they were for.

And what I found was interesting, here’s what Disced looks like normally.

Notice how the moveable cursor is sitting in the Hexadecimal window pane on the left, and positioned on the first character there. I then changed &05 and replaced it with &01, to see what would happen.

then I closed that window (the disassembler view) and went back to Disced. Nothing changed, so I pressed Ctrl + Up arrow in Disced and it browsed to the next track, at that point it updated the UI and I could see a change, the cursor had moved up !

So that got me excited, I next changed the value to something bigger, like &08 and lo and behold it has moved the cursor down.

So at this point I’m certain that the &05 value tells Disced where to put our moveable cursor in relation to the X axis.

But what about the other value (&06). I reset &08 back to &05 and changed &06 to &00, and look at the result of that change !

So armed with that knowledge, I now know that the &05 &06 values are for defining exactly where I want the cursor to appear in my program !

I modified the Source Code to correspond to that new knowledge. After doing that, I set about hacking the other HL value of &88 &00, and I discovered that that address is where the contents of the disc being read are cached in memory, and any edits are stored in the cache and not directly on the disc.

Disced allows you to do it this way, you actually have to commit the changes in memory to the discs sector using CTRL+W. This saves you from destroying data on discs accidentally.

Awesome ! So after modifying the source code with my new found knowledge the little block of code now looks like this.

That’s it for this part, see you in Part 5.

Recommended reading

Posted in Amstrad, Disassemble, Disced, notepad ++, WinApe, Z80 Machine code | 4 Comments

Disassembling my old code from 1988 – part 3


This is part 3 of a blog series I’m doing to catalog my adventures through some of the programs I wrote back in 1988. If you missed the previous parts, they are listed below.

  • Disassembling my old code part 5 – Get Shift key and set translate
  • Disassembling my old code part 4 – Set cursor position and disc cache
  • Disassembling my old code part 3 – Text operations (this part)
  • Disassembling my old code part 2 – Setting screen mode and using Soft 968
  • Disassembling my old code part 1 – Getting started with WinAPE

So let’s get stuck in. I resumed where I left off in the last part and that was to continue converting the source code into meaningful blocks of code, so that means converting the ASCII to readable text and once done, modifying the labels pointing to those text blocks. I also hope to understand how those blocks of TEXT are formed in order to understand how the functions that print them to screen know where the beginning and end of a TEXT block occurs.

At the moment I’m doing this on my Surface Book 2, but it would probably make more sense to run this on my gaming computer downstairs in my office to avail of my 3 monitor setup, I might try that later.

In the screenshot below you can see the WinApe emulator running Disced, and in the left pane we have the disassembly showing the section I’m working on (Press F7 in WinAPE to disassemble), with the source code on top and the hexadecimal/ASCII representation of that code to the right of the lower left pane.

In the Lower right, you can just make out that I’ve got Notepad++ with my source code  that I exported in Part 1 and I’m slowly adding the text but more importantly including every space, and opcode that is listed.

Marking the end of a block of text

I’ve already noticed that two lines of text ended with a NOP (or NULL) code (&00). For example:

TEXT "Press Control + H for Help or Press ESC to Exit",&00

Hopefully this means I’ve found out how my TEXT writing functions are working within the program as those functions must know where the beginning and end of a text block is.

We already know that the start of the text blocks are referred to within the code as Labels, but that only marks the start of the text block, it doesn’t show where it ends.

Here you can see two of those NOP (or NULL) codes at the end of some TEXT blocks.

A slight scroll down through the code and I can see this pattern of ending TEXT blocks with NOP codes (or NULL) repeated, so I think I’m on to something here.

I also noticed that if  I want to see the text within the program on WinAPE that I have to close the disassembler and activate that page in Disced before going back to the disassembler, I guess this is because it freezes the program while disassembling.

If you look at the repeated blocks of code after some TEXT you’ll see


This pattern signifies a carriage return (&0d) followed by two line feeds (&0a). I use this pattern or a similar pattern with just one line feed repeatedly throughout the text blocks.


This is to make the TEXT displayed on screen more readable (formatting the text).

This use of line feed and carriage returns to denote Newlines is explained here and is not Amstrad CPC specific. My next challenge was the character set of the Amstrad CPC in relation to up arrow, down arrow, left arrow and right arrow. These characters are listed in the following wiki.


But when I looked at CharMap in Windows 10 I didn’t see anything quite the same, so I instead added those special characters as byte codes in the TEXT blocks, like so.

Turn off text cursor

After reading that Amstrad Character MAP wiki page, I could see that the &02 code was used to turn off the text cursor, this makes sense as it was just after the the title text and before the graphics routines start on the front page of Disced, so I added a comment to that effect in my source code.

This brings back memories to me from when I coded it originally, I think that if you didn’t turn off the text cursor prior to drawing graphics (lines etc), that you’d see a flashing cursor move across the screen, I can experiment with this later on when I actually try to Assemble the finished source code (if I ever finish it :P).

The next oddity I found was the use of &07,&18 just before the last two (Y/N) prompts.


As you can see highlighted here…

So when I looked at the WIKI page it explains that those codes could be for BEEP and  to exchange the PEN and PAPER inks (reverse video effect).

So I tested it, and sure enough, when I press ESC in Disced it BEEPS and shows the text in reverse video ! as you can see here in the GIF (it won’t BEEP however, but trust me that’s what happened).

So I decided that was enough for this part ! here’s the final look at the source code I modified this morning.

Recommended reading

Please join me in Part 4 where we’ll no doubt learn more about the inner workings of Z80 machine code on a CPC.

Posted in Disassemble, Disced, WinApe, Z80 Machine code | 5 Comments

Disassembling my old code from 1988 – Part 2


In Part 1 of this series of blog posts I showed you how I started disassembling one of my old programs that I wrote in Z80 Machine code way back in 1988, my end goal is to not only have the source code all clearly laid out and readable, but once it’s done, I want to edit it and re-release it with a 2020 date stamp (assuming I get it finished this year).

  • Disassembling my old code part 5 – Get Shift key and set translate
  • Disassembling my old code part 4 – Set cursor position and disc cache
  • Disassembling my old code part 3 – Text operations
  • Disassembling my old code part 2 – Setting screen mode and using Soft 968 (this part)
  • Disassembling my old code part 1 – Getting started with WinAPE

But it’s harder than I thought, just looking through the code I realize that in order to properly label things in the source code I’ll need to re-learn about Z80 Machine code and how assemblers (like MAXAM which is what I will use to compile it) deal with it, so I’ve started doing that.

For example, I needed to know that the Assembler can use directives in the source code to decide what to do with various data. So how did I find out about that, well there’s a great website called https://archive.org and in there you can search for many things, I searched for Amstrad Assembly

and that revealed quite a few hits, I selected a few of the books listed and found the following page *after searching for DEFB* in a book called Mastering Machine Code on your Amstrad 464 664 6128.

Armed with that knowledge I continued reviewing the disassembled code side by side with the source code and started filling in some data.

Such as the following block of code used for changing the mode to 2 and then setting the ram memory address to &C000.

In the screenshot below you can see the WinAPE debugger showing the block of code i’m interested in, and to the right you have the source code opened in the excellent notepad++ which I’m manually editing to add clarity.

In this very small block of code a few things are happening. First of all the block of code (I’m not sure what we call that yet) is marked with a label which contains some descriptive text and has a colon appended to the label name “:” e.g.


directly after that label, you’ll see I’ve used a semi-colon “;” to allow me to type in clear text and add notes about what each line is doing.

change_screen_mode: ; change screen mode

These are comments to make it clear to me what is happening in certain areas of code.

The label allows you to add labels to blocks of code in your source code and the assembler will rewrite those labels as hard coded addresses when you compile the source code.

As I’m re-learning Z80 machine code and assembly language I need to also understand exactly what each block of code is doing in this program, it’s going to take a lot of time but I think it’ll be worth it (for me at least).

If I look at Soft 968 which describes the innards of  the Amstrad Firmware (you can see that book here) you’ll see exactly what the firmware address &BC0e does and what it needs to carry out the function.

So we can see what this firmware address does. What about the remaining instructions, well I can see that I’m loading the register A with a value of &C0, and then I jump (rather than call) to an address of &BC08.

Here’s what Soft 968 tells us about that firmware call.


How do I actually call my block of code ? It actually happens at the start of the program using a call label format.

Actually, the change_screen_mode: block of code has me confused as I don’t see how it’s returning back to the source call, there’s no RET statement, but maybe after changing to mode 2 and setting the memory address to C000 the jp doesn’t need a RET.

The data available online for Amstrad is truly impressive and I’m really enjoying re-learning about how this all works. So much so that I purchased an original Soft 968 from Jason Brooks (member of the Amstrad CPC 464 facebook group).

Next I moved on to starting to modify some of the text in the code, as you can see here.

And after chatting with Jason Brooks and Chris Perver in that facebook group, it seems I need to edit this section so it looks something like this, I do recall TEXT being used in Maxam so maybe this is how I did it originally. I won’t really know until I try to compile it later.

So as you can see the progress is slow but I have to relearn all of this while I’m doing it, and I want to be sure I understand everything.

Well that’s it for part 2, please join me in the part 3 and we’ll see how far I’m getting.

Recommended reading

Posted in Disassemble, Disced, MAXAM, WinApe, Z80 Machine code | 4 Comments

Disassembling my old code from 1988 – Part 1


I’ve always regretted losing the original discs (and CPC computer itself) that came with my original CPC 6128 as those discs contained every program I wrote using Z80 machine code. Losing that source code and all the comments I had inserted at the time is a major bummer, I’d love to look through it today.

  • Disassembling my old code part 5 – Get Shift key and set translate
  • Disassembling my old code part 4 – Set cursor position and disc cache
  • Disassembling my old code part 3 – Text operations
  • Disassembling my old code part 2 – Setting screen mode and using Soft 968
  • Disassembling my old code part 1 – Getting started with WinAPE (this part)

I wrote the code using a ROM in a Rombo Rombox called MAXAM, it was an assembler/disassembler/text editor for Amstrad CPC and it was using that hardware that I learned how to program in Z80 machine code.

This blog post is going to explain how I’m trying to get back into my old code and to see why I coded it the way I did, I will slowly work my way through the code and document it here.

This is the first part, how I actually disassembled my old Z80 machine code on a Windows 10 computer using the WINAPE Amstrad CPC Emulator. I wrote this code back in 1988 and I was 21 years old at the time, a long time ago indeed, I’m 53 now at the time of writing this blog post.

I didn’t instantly understand how to program in Z80 machine code, I had to teach myself by trial and error over a period of years, and that involved reading books and acquiring hardware to assist me to program (such as Maxam). Back then the internet was not really a thing so anything you wanted to learn was done via college courses, books, magazines or strangely enough Encyclopedias.

So now you have an idea of what I’m trying to do, let’s get on with it.

Download Winape

Head over to http://www.winape.net/ and download the latest version of the software. Extract the zip file somewhere useful.

Download Disced

Download Disced (which is what I will be using to disassemble) from here.

Now that you’ve got what you need, start Winape by clicking on the winape.exe file.

When the program loads, click on File, select Drive A: then selct Insert Disc Image…

Point it to a disk image file (file.dsk) such as my disc called niall.dsk

Click Open. In Winape type the following


and then press


Next, type


and then press


Here’s the output.

So those are 3 programs I wrote back in 1988 and my intention is to disassemble all 3 and re-write (with comments) the source code. But how do we do that ? First of all, you could load one of the applications and then run it, they are three basic listings which poke in the machine code into RAM.

To see what those basic programs look like, let’s load disced.bas and then change the mode of the screen to 2 and then type list.


load "disced.bas


mode 2



This will show all of the text in the basic listing.

If you look at the listing in detail you’ll see it’s pokes the machine code instructions into address memory &9000.

Ok, now that we have the data loaded, let’s run the program.



then press


You should see Disced load.

Disassembling the code

Ok, now that we’ve got a program up on screen, how do we disassemble it. Well I know that my code is loaded into the CPC ram at the following address &9000, so we need to disassemble from that address onwards to see the actual Z80 machine code. To bring up the disassembler built into Winape, press F7.

A little disassembler window should appear like below.

Maximize the window and click on the hand icon to enter an address, enter 9000 and press enter.

The code will be revealed

Select the first line (line &9000) and scroll down to where the code ends (at &962e)

Exporting Z80 code to file

Now that you’ve marked the code, let’s export it to a file. Right click on the marked code and choose Disassemble from the options.

And next select the output location to File, and change the Number format as well if you wish

Once done, open the exported .asm file with Notepad++

Here’s the resulting output and I’ve started adding comments to my code. The first ORG &9000 tells the assembler to load the code at that address


and the first call is to a block of code which loads the A register with a value of &0002 and then calls an Amstrad Firmware Jumpblock which does a mode change, let’s look at that little block of code at L933D

how do I know, because I looked up the codes here.

90 #BC0E    SCR SET MODE    Set screen into new mode.

So that’s it ! this is the end of Part 1 of this new mini-series, please continue on to Part 2.




Posted in Disassemble, Disced, MAXAM, WinApe, Z80 Machine code | 4 Comments

Amstrad CPC 472 facebook group


This is an extremely short post to let you know I’ve created a Facebook group devoted to the Amstrad CPC 472 – we will use this group to post about anything related to the Amstrad CPC 472 including for sale ad or photos of newly acquired 472’s etc.

You can join it at the following link


thanks !



Posted in CPC 472 | Leave a comment

My second CPC 472 !

Well I think i’ll take a break from buying CPC’s as i’ve now got 7 of them,

2x CPC 472

2x CPC 664

2x CPC 464

1x CPC6128

This is 6 more CPC’s than I had back in the 80’s, oh well, it’s fun. Yesterday my 2nd CPC 472 arrived and it’s working great, it even came with a Colour Monitor (in Spanish) and a game and the TV modulator. I’ve no idea what I’ll do with the TV modulator. Oh it also came with a joystick.

So here it is

I have seen read error a and read error b on some tape games but it improved after I cleaned the read head with IPA alcohol. I played my first game on it, Airwolf. Everything works perfectly but I can hear something rattling around on the inside so I’ll need to open it up and inspect it.

There you can see the ‘new’ monitor sitting on top of my old one, it works but when i adjust the brightness knob on the right side it flashes white across the screen, so that probably needs to be addressed.

Here’s the game that came with this CPC, it’s called Satan 2, seems to be a very colourful box.

and here’s the QuickShot joystick which looks brand new 🙂

The photos below are all from the ebay ad for posterity sake.

Posted in CPC 472 | Leave a comment

CPC 472 user manual arrived in the post

I bought this manual on the Spanish version of ebay, and it arrived today !. The interesting thing to note is that the cover states CPC 464 but the manual’s title stated CPC 472.

The CPC472 came with some bizarre aspects, too. Reading 464 on the cover, but 472 on the bookneck. And, claiming that the 72K RAM would be required because of using the ROM of the CPC664 (whilst, the real CPC664 has only 64K RAM).

You can see photos of it here.


Posted in CPC 472 | Leave a comment

My second CPC 464


I got this grey keyed 464 in February 11th or so 2020, but never got around to posting about it here.

But, better late than never 🙂

Unfortunately It wouldn’t power on at all.

Dead !

The motherboard is much smaller than the one in my original colour CPC 464, and the following wiki shows the different motherboards manufactured for CPC’s.



So I took it apart and found a loose connection, and after wiggling it (I’m pointing at the connection), the computer came to life !

This particular CPC was made in Germany using Schneider parts (keyboard and colouring) but made after the partnership with Amstrad/Schneider ended, so they used the parts remaining, in other words the grey keyboard, but with the Amstrad logo.

for details on the keyboard types see here https://www.cpcwiki.eu/index.php/Keyboard_Versions

and for help with non starting CPC’s see here


Posted in CPC 464 | Leave a comment

Today I got a CPC 472 !

I’m growing my collection bit by bit, after doing a swap with Noel Llopis (in Spain), I got back a CPC 472 in the mail today, and it’s in lovely condition.


here’s the basic info (notice, BASIC 1.0) and it has the Spanish ROM, so (s1)

Here’s my entire family of CPC’s together.

Posted in CPC 472 | Leave a comment