Zilog z80 to Motorola 6809 Transcode – Part 001 – General CPU transcoding info


For my own knowledge I’m trying to port the original Pac Man arcade game to run on my old Color Computer 3.  This will probably be a more general description of the Z80 to 6809 conversion, so it should be useful to others if they want to do the same thing for other old games.  This could also be used to convert the TRS-80 Model 1 which also has a Z80 processor to work on a CoCo 3.  I don’t know how far I’m going to get with future blogs, but I might as well start somewhere…

So far what I have done is found all the information I could for the hardware I’m trying to convert.  This means finding disassemblies of the ROM code on the internet.  If you’re lucky you’ll find some awesome commented disassembly code like the ones on the Computer Archeology website.  With Pac Man I wasn’t so lucky, but I did find some disassembly code that has some comments on them.  I found that Namco has also had some take downs of some disassembly posts.  😦  So what I ended up with was a couple of disassemblies, one with some comments and one that has the actual bytes in the disassembly.

For example code 1 with some comments:

0272 CoinDebounce:
0272                 LD      A,(InterruptEnable)
0275                 LD      B,A
0276                 RLC     B
0278                 LD      A,(CoinState)  ; Coin state shifted left 1
027B                 RLA
027C                 AND     0Fh
027E                 LD      (CoinState),A  ; Coin state shifted left 1
0281                 SUB     0Ch

For example code 2 with data bytes:

0272  3A0050    LD      A,(#5000)
0275  47        LD      B,A
0276  CB00      RLC     B
0278  3A664E    LD      A,(#4E66)
027B  17        RLA     
027C  E60F      AND     #0F
027E  32664E    LD      (#4E66),A
0281  D60C      SUB     #0C

Out of the above it would be best to combine the two disassemblies to use to transcode, since having the actual bytes can sometimes help to figure out how the code works.  So first I wrote up a program to merge the two files which gives me this.

0272: 3A 00 50                 LD      A,(InterruptEnable)
0275: 47                       LD      B,A                     
0276: CB 00                    RLC     B                     
0278: 3A 66 4E                 LD      A,(CoinState)  ; Coin state shifted left 1
027B: 17                       RLA                     
027C: E6 0F                    AND     0Fh                     
027E: 32 66 4E                 LD      (CoinState),A  ; Coin state shifted left 1
0281: D6 0C                    SUB     0Ch                     

From here I use another program that will transcode the Z80 codes to the 6809 equivalent code (or at least a close version).  For this I wrote another program that basically looks up the Z80 instruction and inserts the 6809 instruction in it’s place and keeps the Z80 code as comments beside the 6809 code.  This will look like this:

        LDA     InterruptEnable                     ;0272 3A 00 50       LD      A,(InterruptEn
        TFR     A,B                                 ;0275 47             LD      B,A           
        ROLB    * ROL is 9bit check code            ;0276 CB 00          RLC     B             
        LDA     CoinState                           ;0278 3A 66 4E       LD      A,(CoinState)  Coin state shifted left 1
        ROLA                                        ;027B 17             RLA                   
        ANDA    #$0F                                ;027C E6 0F          AND     0Fh           
        STA     CoinState                           ;027E 32 66 4E       LD      (CoinState),A  Coin state shifted left 1
        SUBA    #$0C                                ;0281 D6 0C          SUB     0Ch 

With the code side by side it will be easier to see if things don’t look right and compare the 6809 with Z80 code.

There are still some bugs in my translating program and it needs to be hand tweaked quite a bit depending on the Z80 source code.

Once I get the code all transcoded to a 6809 version I will then split the Z80 source code into two parts one is the Z80 data section, and the other with just the Z80 instructions.  The reason to split them is so that I can make sure to have the data in the exact same RAM/ROM locations that the original Pac Man hardware would look for it.  So I’ll take all the sections of the source code that has DB, DW & DL statements and turn these sections into FCB statements in a 6809 compatible version at the proper points in memory.  Another thing to deal with here is that Z80 disassemblers swap the bytes around when you have DW & DL instructions.

For example :

03D0:        DW    05E5h

will be stored in memory at 03D0 as E5 and memory address 03D1 will be 05 (backwards to what you would think looking at the code).

With the 6809 you would convert this as:

03D0:        FCB   $E5,$05
03D0:        FDB   $E505

It is the same with the DL instruction but it’s the entire 4 bytes that need to be swapped, so the following Z80 instruction needs to converted from:

33BB:        DL    B5AD5AD6h

To this in the 6809 assembly version:

33BB:        FCB   $D6,$5A,$AD,$B5

We want to make sure all the data that the 6809 converted code will read is in the same location and read the same way the original Z80 program did.  So once the data sections have been pulled out into a separate file and ORG statements put in place so that the data gets assembled into the correct location we can then work on the actual Z80 translated code.  This is what I did (mostly) when I was doing this type of translation from the Intel 8080 to 6809 conversion for Space Invaders.

A little more information about the big endian and little endian differences between 6809 vs the Z80.  Of course the 6809 is the processor that I first learned to program assembly language on and all the number orders made sense to me and still do today.  As far as I’m concerned when you load a register from a word in memory it should always be MSB & LSB just as when you are counting bits.  A byte is made up of bits 7,6,5,4,3,2,1,0 and two bytes (one word) is bits 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 or MSB,LSB and this is exactly how these values are stored and loaded on the 6809 CPU it all makes sense and you never have to think twice about it.  Bit Intel messed it all up and this is going to make the life of a transcoder a pain in the ass.  Intel CPUs and the Zilog Z80 store one byte as bit 7,6,5,4,3,2,1,0 which is perfect.  But when you are storing a word in memory it get’s stored as bits 7,6,5,4,3,2,1,0,15,14,13,12,11,10,9,8 or LSB,MSB.  When the Z80 loads the 16 bit word into a register it’s value is correctly ordered as MSB,LSB so you can deal with the values as normal 16 bit numbers.  I’m not sure at this time what I should do about this type of data.  For the most part on my Space Invaders transcode I loaded the data with the LDD command and did an EXG A,B then TFR D,X to use in the X register.  This way I didn’t have to think about what the program was doing just let the computer swap the bytes and carry on.  Now the 8080 was and older CPU and the 6809 code do this switch and it didn’t seem to effect the speed.  But with Pac Man and a Z80 CPU I might need to figure out what data locations will be accessed as words and swap the original data in those locations.  This will speed up the program but it will mean a lot more decoding on my part.  I still don’t know what I’m going to do.

I’ll have to look closer at the code and see if there are any ambiguous sections of code.  If I see a bunch of LDX  $2000 bytes then that will be simple enough to swap out in the original data.

See you in the next post…


This entry was posted in CoCo Programming. Bookmark the permalink.

5 Responses to Zilog z80 to Motorola 6809 Transcode – Part 001 – General CPU transcoding info

  1. William Carlin says:

    Thanks for sharing. I was aware of the endian thing but did not realize the challenges involved when transcoding from one to the other.

  2. allenhuffman says:

    This will be a fun read. A few years ago, I was working on a PAC-MAN for Arduino, and I found this site very helpful:


    • nowhereman999 says:

      Thanks for the link, this looks like a great site. The more I know about the game the better I’ll be able to understand the code.

  3. Pingback: Porting Arcade Pac Man to TRS-CoCo – Developer’s Journal shows you how – Vintage is the New Old

  4. Pingback: 2nd of April a new ym player… | Vectrex Release

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s