• Please review our updated Terms and Rules here

Using f9dasm to decompile 4051 cartridge code

WaveyDipole

Experienced Member
Joined
Jul 23, 2021
Messages
133
Location
United Kingdom
I am trying to use f9dasm to decompile code from a 4051 cartridge. The code is in a file in binary format that can be loaded and veiwed in a hex editor. Since cartridges load at address 8000, I have used the -offset parameter to specify that as the start address. I want to decompile code between offset 03E and 151 so have specified a command like like so:

Code:
./f9dasm -begin 003E -end 0151 -offset 8000 -6800 bpl.bin

The output begins at address 8000 as expected, but starts at the beginning of the code:

Code:
;****************************************************
;* Program Code / Data Areas                        *
;****************************************************

        ORG     $8000

        NEGA                             ;8000: 40             '@'
        FCB     $51                      ;8001: 51             'Q'
        FCB     $00                      ;8002: 00             '.'
        FCB     $00                      ;8003: 00             '.'
        FCB     $00                      ;8004: 00             '.'
        FCB     $00                      ;8005: 00             '.'
        FCB     $00                      ;8006: 00             '.'
        FCB     $00                      ;8007: 00             '.'
        FCB     $00                      ;8008: 00             '.'
        FCB     $00                      ;8009: 00             '.'
        ......

I expected the output to start at offset 803E and finish at offset 8151. Instead, it starts at offset 0 and runs all the way to the end of the file. I have also tried specifying the offsets as 3E/151 803E/8151, but same result. The whole file is de-compiled. What am I missing?

BTW, is there a detailed reference to the 4051 System ROM space anywhere including entry points to various functions? I think I am already seeing anomalous instructions, for example:

Code:
        LDX     M003D                    ;803E: DE 3D          '.='
        BNE     Z8047                    ;8040: 26 05          '&.'
        LDAA    #$3B                     ;8042: 86 3B          '.;'
        STAA    M004B                    ;8044: 97 4B          '.K'
        RTS                              ;8046: 39             '9'
Z8047   JSR     Z8F64                    ;8047: BD 8F 64       '..d'
        BEQ     Z804D                    ;804A: 27 01          ''.'
        RTS                              ;804C: 39             '9'

Looking at the JSR instruction at label Z8047, there is no code to jump to at address 8F 64. There are only FF bytes to the end of the dump. I did wonder whether the dis-assembler might have mi-interpreted due to the wrong starting point, but accoreding to the M6800 Programming Guide, 39 is indeed an RTS and logically the the next address would be the start of a new block of instructions. Its probably me who is mis-interpreting, but in my defence, it has been a very long time since I looked at any assembly language and that was for the 6502.
 
Last edited:
Where did you get your copy of f9dasm from, and which version is it?

Just wondering if you have an old version of it, or does the documentation file come with the f9dasm specifying the options?

Yes, there is the source code available for the ROMs, and there are some documents around detailing the ROM entry points.

I'll post a link a bit later. I think they are on butsavers though.

Dave
 
The 'definitive' reference to Tektronix 4051 BASIC ROM entry points is the 4051 Assembler doc I posted on my github repo:
https://github.com/mmcgraw74/Tektronix-4051-4052-4054-Program-Files/blob/master/4051-Assembler/Tek%204051%20Assembler%20Program%20Instructions%20Tekniques%20Vol%207%20No4%20062-7456-01.pdf

RAM variables used by the BASIC ROM are described starting on pdf page 28 followed by ROM entry point names on pdf page 30, and including complete description of ALL the ROM entry points starting on pdf page 86 to the end of the document.

In addition - in that same folder on my repo is a document from Michael D Cranford - author of Fast Graphics with additional documentation for his experience creating that ROM with tips and tricks:

https://github.com/mmcgraw74/Tektronix-4051-4052-4054-Program-Files/blob/master/4051-Assembler/4051%20assembly%20code%20documentation.pdf
 
I think you need to add -6800 to get the right instruction set to your f9dasm command.
I've found that -offset works but couldn't get the disassembler -begin to work right.
Here is syntax I found in history on my PC using f9dasm from cygwin:

./f9dasm.exe -6800 -offset c000 -begin c429 "4051 C000.BIN" > C429.lst

and here is the listing file zipped:
 

Attachments

  • C429.zip
    23 KB · Views: 3
one more interesting file in the 4051 Assembler folder in my repo is CALL EXEC my English Translation.

I found this file in 2018 while searching the internet for information on Tektronix 4051 undocumented CALL EXEC function and used google translate to translate the text and then cleaned up the formatting manually.

This doc was discussing a 4051 BACKRAM - which I don't have any other information on, but had an interesting section on the layout of the Option ROM code:

Code:
     :(IV)            Construction of the backpack RAM content
     :                 ====================================
     :
     : As the owner of a 4051 BACKPACK RAM, you can create your own
     : and store machine programs in this ram and by yourself
     : call defined callnames from BASIC.
     :
     : For this it is necessary to the understand the exact structure of the
     : backpack beginning with the entry point of the callnames.
     :
     : Address in         function
     : Back Pack
     :
     : 8800-8801          here must be (in the form '@q') $4051, it serves
     :                    to identify the back pack
     : 8802-8803          RESTART (s.u.)
     : 8804-8805          INIT       "
     : 8806-8807          DELETE ALL "
     : 8808-8809          CLOSE      "
     : 880A-880B          Pointer to a jump table for external
     :                    Functions (e.g., MPY, TRN, etc. in MATRIX ROM)
     : 880C
     : 880D-8812          1. Callname (6 bytes, possibly filled with blanks)
     : 8813-8814          Address of the associated routine
     : 8815-881A          2. Call name etc.
     :                       or: 0 -> call name table over
     :
     : The following memory space is fully available to the user.
     :
     : For RESTART, INIT, DELETE ALL and CLOSE the addresses of
     : Routines entered when RESTART is executed (i.e. of the calculator or calling
     : routine $BC30) or the corresponding one
     : BASIC commands should be called. This can be a
     : Initialization performed on all connected backpacks
     : be, e.g. INIT sets up WINDOW, VIEWPORT and ROTATE in the graphic ROM
     : restoring the default parameters. In the fewest applications these become
     : However, vectors are needed so they can be set to 0000.
     :
     : With this information, the user should be able to
     : developing programs yourself and making them available via CALL.
     :
     : To transfer machine programs to BACK RAM, use the
     : Routine "getrom". It assumes that the ROM contents in up to 4
     : Strings per 2048 bytes of length in Binary format on tape or disk file
     : saved.
 
Thank you for all the information.

Daver2, thats a fair point. The version I am using is from here:


It doesn't appear to have been updated in a while but a list of options is produced with:

Code:
./f9dasm  --help

The options are also described in the README and both include those flags.

I have raised an issue and the author had responded pretty quickly and given me some guidance including the need to specify -begin and -end in the context of -offset, i.e -offset 8000 -begin 803E -end 8151. However, even that produces the problem which the author has now acknowledged and identified a section of code that might be responsible. He is giving the problem some thought, so I am hoping this might be fixed soon.

Monty, you were correct that I had omitted the -6800 from my command line example above, although I was, in fact, using that flag during my actual tests.

I see that your listing exhibits the same problem, i.e starts at C000 rather than the intended start point of C429, which would seem to corroborate my finding.

Thank you for the pointer to the documents on ROM entry points and other useful information. Thanks also for the details of the backpack layout from the description of the CALL EXEC function. That is very helpful. I will have a look at these references in more detail. I should have realised that all this information would be in your repository somewhere... I did have a bit of a dig around this morning but it was a bit rushed.
 
Last edited:
If you're not running Windows, you can try my disassembler, see my sig. Amusingly, I use -b for the address base and -o for the file offset, exactly the opposite, and -s for the size of the code area (usually I only use that when a large chunk at the end is empty). It's also interactive so that you can get the disassembly right instead of just grinding it through a filter.
 
Well the good news is that the author has issued a fix for f9dasm and `-begin` and `-end` now work as expected from the command line. Not quite working from an info file yet though.

Bruce, in the meantime I also downloaded, compiled and tried your disx but I ran into a little difficulty:

Code:
$ ./disx -c 6800 -b 8000 -o 8035 -s 8113 bpl.bin
./disx: unable to load binary file 'bpl.bin'

I realised I was still thinking in terms of f9dasm so I then tried the following:

Code:
$ ./disx -c 6800 -b 8000 -o 3E -s 113 bpl.bin

The -s parameter was calculated on the basis of 0x0151 - 0x003E = 0x0113

This did give me a list of bytes, but there were no mnemonics. I am not sure whether I am using it correctly, although I did try left padding the -o and -s parameters with zeroes (003E and 0113). I do think your use of -b, -o and -s is logical. Even though -s may require calculating of the number of bytes to show that is not a big deal.

Screenshot from 2022-10-07 10-31-07.png

I now need to move on to looking at Monty's ROM entry point information. I am still having difficulty comprehending this block:

Code:
Z8047   JSR     Z8F64                    ;8047: BD 8F 64       '..d'
        BEQ     Z804D                    ;804A: 27 01          ''.'
        RTS                              ;804C: 39             '9'

Code:
        STX     MFFFF                    ;8F62: FF FF FF       '...'
        STX     MFFFF                    ;8F65: FF FF FF       '...'
        STX     MFFFF                    ;8F68: FF FF FF       '...'
        STX     MFFFF                    ;8F6B: FF FF FF       '...'
        STX     MFFFF                    ;8F6E: FF FF FF       '...'
        STX     MFFFF                    ;8F71: FF FF FF       '...'
        STX     MFFFF                    ;8F74: FF FF FF       '...'
        STX     MFFFF                    ;8F77: FF FF FF       '...'
        STX     MFFFF                    ;8F7A: FF FF FF       '...'
        STX     MFFFF                    ;8F7D: FF FF FF       '...'

I mean how can the program JSR to an area of memory which contains nothing but FF bytes?

In a de-compilation of the complete file, there are several references to this jump off point, and label Z8F64, but there is no such label listed in the used labels section?
 
That means start disassembling from file offset 0x8035. Really it's best to just use -b and bring in the whole file because it's interactive.

This did give me a list of bytes, but there were no mnemonics.
You didn't read the instructions, did you? This isn't a "filter" style disassembler, it's interactive. You're thinking grep or sed when this is like vi. Or maybe think "IDA Amateur". Start it with just -b8000, go to 8035, and press shift-T to disassemble a block of code and all trace all the references from it. For one instruction it's lowercase c, for one block of code it's shift-C. This way you don't get a bunch of off-phase crap, and useless ASCII dumps of code.
Then you can go back and use commands on the header, like at 8000 I'd use "9a" to make a 9-byte run of ASCII. For "junk" you can use "16h" to collapse stuff. The "*" key repeats the last data command, so try going to 8100, type "16h", then hold down "*". Better yet, type ":8100(enter)" then 16h *
Then when you're done use ":w" to save your hints, and then do ":asm" or ":list" to generate a listing file.
 
I did look at disx4.txt, but I didn't read far enough. Mea culpa. I literally needed to scroll down to the next section! I do get the vi paradigm and should have realised there would some further commands, although I didn't "catch on" to the interactive nature of the program.

I had a little play with the steps that you suggested above and now get a better idea of how the de-compiler operates. Thank you for that. I find this a very interesting approach! I have not used a de-compiler in an interactive way like that before. I can see how such an approach can be useful and I do like it. One can work step by step through the de-compile and save the listing at each stage. Nice!.

I will have experiment some more an familiarise with this approach. I am struggling with undo a little at the moment although I can see that it combines shift-u with ctrl-u. I might have inadvertently hit ctrl-u (as they are next to each other) and saved the last state which might be the problem. I guess once the state is saved there is no going back beyond that point except top do a q! and re-load? I see that wiping the .ctl file completely resets things back to the start. I guess the idea is to ctrl-u after every successful and convenient step, being careful to to catch the wrong key! I look forward to learning more about this program.
 
Last edited:
From the CALL EXEC document - it appears that all the option ROMs load at 8800 - not 8000, maybe that will help.
 
I can see how such an approach can be useful and I do like it. One can work step by step through the de-compile and save the listing at each stage.
I don't know if you realized what some of the intro meant, but this is basically the result of over 20 years of doing it The Hard Way after not being satisfied with dumb disassembly. Months later, the feeling of living in the future still hasn't worn off yet. I don't even bother to make listings now unless I need one, I just leave the .ctl file there, and deal with not being able to put comments on non-code lines. It's hard to understand every line of code the first time through.

I can see that it combines shift-u with ctrl-u. I might have inadvertently hit ctrl-u (as they are next to each other) and saved the last state which might be the problem.
Undo barely works, isn't easy to do it right. I don't like it how it is and don't use it. The only time it's really useful is after a T goes very bad. I usually just :w every now and then, but still :q! happens. The main thing is where the labels are, if you scribble over some code, a few times with the C key puts it back.

Also try making the window bigger. 136 wide is enough for 32h lines. And I was really relieved when I got stuff like window resizing working properly. And notice where the cursor ends up as you move through the file, I had to put it somewhere.
 
From the CALL EXEC document - it appears that all the option ROMs load at 8800 - not 8000, maybe that will help.
Monty. Ah! So that was it. I looked at the memory map and saw ROMs are at 8000 and used that as the starting point. The address 8600 makes sense as 8780 - 87FF is for peripheral control. Cartridges sit above that in the space for Switchable Bank. Would the the section at 8000 - 877F perhaps be reserved for actual the Backpack/Expander ROMs?. Setting the base address to 8600 makes all the difference as JSR 8F64 now points at a valid block of code. That now gives me something to run with. Thank you for spotting my mistake.
I don't know if you realized what some of the intro meant, but this is basically the result of over 20 years of doing it The Hard Way after not being satisfied with dumb disassembly. Months later, the feeling of living in the future still hasn't worn off yet. I don't even bother to make listings now unless I need one, I just leave the .ctl file there, and deal with not being able to put comments on non-code lines. It's hard to understand every line of code the first time through.
I didn't realise that this was the culmination of 20 years of work! You are right though that a lot of dis-assemblers just run through the binary code without taking into account sections of data or reserved memory spaces. They just rattle through everything assuming that it is code.
Wow! I didn't realise that one could add comments. I was wondering how I might annotate the code as I worked though it. After reading this I just discovered the ; command. That's a great feature!
Undo barely works, isn't easy to do it right. I don't like it how it is and don't use it. The only time it's really useful is after a T goes very bad. I usually just :w every now and then, but still :q! happens. The main thing is where the labels are, if you scribble over some code, a few times with the C key puts it back.
Shift-T or Shift-T following a previous Shift-T going wrong was the scenario I had in mind. Shift-C seems a more cautious way forward though.
Also try making the window bigger. 136 wide is enough for 32h lines. And I was really relieved when I got stuff like window resizing working properly. And notice where the cursor ends up as you move through the file, I had to put it somewhere.
Thank you for the hint. It will no doubt prove useful. More space to see comments for a start.
Thank you for making this dis-assembler generally available.

In the meantime, the author of f9dasm has been very responsive. He is aware that there still is a problem with the way that .info files work and is looking into it. I sent him a copy of my examples so he could directly see what I was seeing. Hopefully this will result in an improved f9dasm as well. Once nice feature of the .info files is that you can include several consecutive dump files and treat them as one entity. Useful for when you have several separate 2k ROM dumps. Of course, it is easy enough to combine the files using `cat`. Of course, f9dasm does not have the interactive features of disx4.
 
My colorized address map for the 4051 versus 4052/4054 is from the service manuals.

Since the top address of the 8K ROM Switchable Bank is A800 - that implies the beginning of the 8K switchable bank is 8800.

The table below the 4051 Peripheral Control Addresses lists the beginning and end of each range:

  • 8000 to 877F is part of the BASIC ROM
  • 8780 to 87FF is memory mapped I/O addresses including the bank switch registers
  • 8800 to A7FF is the 8K ROM switchable bank address range


4051 4052 4054 address map color.png
 
The author has now fixed the issue with the operation of the .info file in f9dasm and has now released version 1.82. The flags now seem to work as expected on both the command line and when used in the info file.

I now have the option of two good 6800 dis-assemblers on the PC as well as the information I was looking for, so will now get stuck into my dis-assembly project. I expect disx4 will play a key role but I am grateful to both authors for making their dis-assembler projects available.
 
I just tried the new version of f9dasm on Michael D. Cranford's Fast Graphics small relocatable binary executable that runs with the 4051 CALL "EXEC",A$ command and the output looks fine! Yes I know this is not option ROM code @8800 and it was designed to be relocated anywhere by the BASIC CALL "EXEC" command.

Now I need to use Michael's assembly doc and the 4051 assembler doc to create an INFO file for the Memory and BASIC ROM entry points and see how that works!

Code:
; f9dasm: M6800/1/2/3/8/9 / H6309 Binary/OS9/FLEX9 Disassembler V1.82
; Loaded binary file FG.BIN

;****************************************************
;* Used Labels                                      *
;****************************************************

M004B   EQU     $004B
M0071   EQU     $0071
M0085   EQU     $0085
M0091   EQU     $0091
M0093   EQU     $0093
M00A5   EQU     $00A5
M00A8   EQU     $00A8
M00A9   EQU     $00A9
M00AA   EQU     $00AA
M00AB   EQU     $00AB
M011E   EQU     $011E
M011F   EQU     $011F
M021E   EQU     $021E
M0380   EQU     $0380
M0381   EQU     $0381
M0382   EQU     $0382
ZA9E7   EQU     $A9E7
ZA9FD   EQU     $A9FD
ZCB81   EQU     $CB81
ZCBBF   EQU     $CBBF
ZDCA8   EQU     $DCA8
ZE00C   EQU     $E00C

;****************************************************
;* Program Code / Data Areas                        *
;****************************************************

        ORG     $8800

        JSR     ZA9E7                    ;8800: BD A9 E7       '...'
        LDX     #M021E                   ;8803: CE 02 1E       '...'
        STX     M0085                    ;8806: DF 85          '..'
Z8808   BSR     Z8849                    ;8808: 8D 3F          '.?'
        STAA    M0380                    ;880A: B7 03 80       '...'
        BSR     Z8849                    ;880D: 8D 3A          '.:'
        STAA    M0381                    ;880F: B7 03 81       '...'
        BSR     Z8849                    ;8812: 8D 35          '.5'
        STAA    M0382                    ;8814: B7 03 82       '...'
        CLR     >M00A5                   ;8817: 7F 00 A5       '...'
        LDAA    M0380                    ;881A: B6 03 80       '...'
        BITA    #$40                     ;881D: 85 40          '.@'
        BEQ     Z8824                    ;881F: 27 03          ''.'
        INC     >M00A5                   ;8821: 7C 00 A5       '|..'
Z8824   TAB                              ;8824: 16             '.'
        ANDB    #$07                     ;8825: C4 07          '..'
        STAB    M00A8                    ;8827: D7 A8          '..'
        ASRA                             ;8829: 47             'G'
        ASRA                             ;882A: 47             'G'
        ASRA                             ;882B: 47             'G'
        ANDA    #$07                     ;882C: 84 07          '..'
        STAA    M00AA                    ;882E: 97 AA          '..'
        LDAA    M0381                    ;8830: B6 03 81       '...'
        ASLA                             ;8833: 48             'H'
        ASR     >M00AA                   ;8834: 77 00 AA       'w..'
        RORA                             ;8837: 46             'F'
        STAA    M00AB                    ;8838: 97 AB          '..'
        LDAA    M0382                    ;883A: B6 03 82       '...'
        ASLA                             ;883D: 48             'H'
        ASR     >M00A8                   ;883E: 77 00 A8       'w..'
        RORA                             ;8841: 46             'F'
        STAA    M00A9                    ;8842: 97 A9          '..'
        JSR     ZCB81                    ;8844: BD CB 81       '...'
        BRA     Z8808                    ;8847: 20 BF          ' .'
Z8849   LDX     M0085                    ;8849: DE 85          '..'
        CPX     #M021E                   ;884B: 8C 02 1E       '...'
        BNE     Z886D                    ;884E: 26 1D          '&.'
        CLR     >M0071                   ;8850: 7F 00 71       '..q'
        JSR     ZE00C                    ;8853: BD E0 0C       '...'
        LDX     #M011F                   ;8856: CE 01 1F       '...'
        STX     M0091                    ;8859: DF 91          '..'
        LDX     #M021E                   ;885B: CE 02 1E       '...'
        STX     M0093                    ;885E: DF 93          '..'
        JSR     ZDCA8                    ;8860: BD DC A8       '...'
        JSR     ZCBBF                    ;8863: BD CB BF       '...'
        LDX     #M011E                   ;8866: CE 01 1E       '...'
        LDAA    M004B                    ;8869: 96 4B          '.K'
        BNE     Z8875                    ;886B: 26 08          '&.'
Z886D   INX                              ;886D: 08             '.'
        STX     M0085                    ;886E: DF 85          '..'
        LDAA    ,X                       ;8870: A6 00          '..'
        BMI     Z8875                    ;8872: 2B 01          '+.'
        RTS                              ;8874: 39             '9'
Z8875   INS                              ;8875: 31             '1'
        INS                              ;8876: 31             '1'
        JMP     ZA9FD                    ;8877: 7E A9 FD       '~..'

        END
 
I have started working on dis-assembling the Binary Program Loader ROM in an effort to better understand how the binary file format works and am using the 4051 Assembler documentation (document 062-7456-01) to reference the entry points, but, the table is organised by symbol name which means that the memory addresses appear in random order. Looking up what is held at a particular memory address in this way is very time consuming. I was considering re-typing these tables into a spreadsheet as that would be searchable and one could then sort either by symbol name or memory location. I see, however, that Michael Cranford's document has all of these in memory location order more or less, but grouped by label types. That information could form another column. On the other hand, the Tek document has more detailed information so it might be worthwhile to combiner the information from both. Would such a spreadsheet still be worthwhile? Is that the sort of thing you had in mind?
 
Last edited:
Michael Cranford's document seems to have duplicate entries, for example:

Code:
REGISTER12    0H00018    PSEUDO REGISTER 12
INTEGERTWO    0H00018    INTEGER WORKING STORAGE

Both of these refer to the same memory address but have different description.

A similar thing happens here:

Code:
REGISTER03    0H00006    PSEUDO REGISTER 03
K6    0H00006  
REGISTER04    0H00008    PSEUDO REGISTER 04
REGISTER05    0H0000A    PSEUDO REGISTER 05

I presume that K6 is another label for the higher bit in registers 03 appear at every other address, skiping one byte in between. I am guessing here that each register is 16-bits (2 bytes)?

We also have duplication here:

Code:
REGISTER11    0H00016    PSEUDO REGISTER 11
INTEGERONE    0H00016    INTEGER WORKING STORAGE
REGISTER12    0H00018    PSEUDO REGISTER 12
INTEGERTWO    0H00018    INTEGER WORKING STORAGE
REGISTER13    0H0001A    PSEUDO REGISTER 13
DIMSUBSCRIP    0H0001A    DIMENSION SUBSCRIPT COUNTER

Address 0017 was of interest as it cropped up duiring my dis-assembly, but it is not described, whereas 0016 and 0018 are both described as registers and 'INTEGER WORKING STORAGE' so which is it? Its a similar story for 001A. It has two descriptions.

There are other examples of this so I am a bit confused.

There are also some locations described as System Constants AND System Variables, e.g. 0020. They obviously can't be both? Is this a PSEUDO REGISTER, DIMENSION LOOP COUNTER or simply the ASCII SPACE CHARACTER?

Incidentally, what does the term "PSEUDO REGISTER" mean in this context anyway?
 
A "PSEUDO REGISTER" as not a 'real' CPU register (e.g. A, B, X, ...) but RAM masquerading as a register for the purpose of a subroutine or collection of subroutines.

For example, the floating point processing subroutines may use REGISTER11 and REGISTER12 as the two input arguments and REGISTER13 as the output result (assuming these RAM registers are all declared with the appropriate number of bytes of course).

However, outside of these subroutines, it would be a potential waste of RAM to permanently allocate them to the specific function. Therefore, having the same address for two (or even more) symbolic names may actually be valid - it just means they share the same memory address.

The collection of subroutines then refer to the appropriate symbolic name to maintain a description within the source code of what the parameter actually is that is being referred to.

Of course, if the expectation is that (say) REGISTER13 maintains its value across a number of subroutine calls - and a separate subroutine that is called inadvertently refers to DIMSUBSCRIP - then all bets are off because the memory for the value held within REGISTER13 has just been destroyed!

I suspect all of these values are WORDS (hence addresses 16 and 17 would be part of the same WORD for REGISTER11) - but there is nothing to say that a WORD variable couldn't be treated as two separate bytes. In fact, I see this a lot in 6800 assembler code - it is 'messy' like that. For example storing CPU registers A and B (both 8-bit registers) into X (a 16-bit register) involves storing A and B (as bytes) into two consecutive memory locations (in the correct order) and loading X from the same address (but this time all 16 bits are transferred). Ugh...

I converted a 6800 assembler program into Z80 - and this was where I spent most of my debugging time - as both machines have the opposite byte order for 16-bit quantities.

Hope this makes sense?

Dave
 
Last edited:
Back
Top