Saturday, June 22, 2024

ALPP 01-04 -- Getting a Simulator for the 6801 and Running Code on It

Getting a Simulator for the 6801
and Running Code on It

(Title Page/Index)

 

I'll assume that you've already gone through the steps for getting the necessary operating system environment and tools, and have got EXORsim up and running, and have tested it with the example I gave showing how to use the accumulator to accumulate a sum of a series of constants.

Several years back, I needed (wanted?) a nice debug system for developing some 6801 code. At the time I started the project (if I recall correctly) Ciaran and his friends had not yet added MC-10 emulation to XRoar. Or maybe I didn't want to jump through the hoops of a self-hosted debugger on it. Or something.

An option I considered was to write my own 6801 simulator (a project I had already shown myself I didn't have the discipline to take to completion) or get enough of the documentation for the M6801 USE module for the EXORciser and the MC6801 EXORciser Support System to add that module to Joe Allen's EXORsim. But that latter begged the question of where to get the documentation, and whether I could afford the persuasion rate if I could find someone who had it.

A less ambitious option would be to write an alternative reality main CPU module for EXORsim, from a world in which Motorola had made the bare 6801 core available as a direct substitute for the 6800 -- in other words, with no built-in IO or RAM. It could be invoked as exor01, just as the 6809 version of EXORsim is invoked as exor09. That would allow me (and you) to use git to pull in Joe's updates without (too much) conflict with my  6801 tools. 

Just for the record, the timing differences might have meant MDOS and other system-level software wouldn't run on the 6801 simulation, even if you cleared the built-in I/O devices out the memory map.

I just wanted to run code, didn't care about timing, didn't know at the time how Joe would implement the 6809 modules, etc. So I simply made a fork of the EXORsim project (allowed by the GPL license) and added 6801 instructions (without attention to timing) to the 6800 instruction set, with a command-line switch to enable 6801 instructions. It worked for my project, and that is what I'm going to recommend you use for the 6801 here -- for now.

Which is going to take a little extra explanation.

Now, for the accumulator example, the 6801 code and execution will be exactly the same as for the 6800, so it might be tempting to skip it. But you'll need the explanation of how to get, compile, and use the EXORsim6801 tools, so we won't. And we can talk a little about 8-bit bytes vs. 16-bit words while we are at it.

EXORsim6801

There was a local code repository provider here called sourceforge.jp, and I started using them because they are local. They changed their name to Open Source Developers' Network (osdn.net) about the time SourceForge changed hands and started going a little crazy, so I started using OSDN as my main repository provider. Things have changed more since then, with some of SourceForge's original owners being able to buy it back, and all. And OSDN's team has not been able to keep it the easy-to-use place it was. And Microsoft bought Github. Etc. 

Excuses, what-ifs, and excuses, but EXORsim6801 is in my personal chambers (workspaces) on OSDN, here:

https://osdn.net/users/reiisi/pf/exorsim6801/wiki/FrontPage

It takes patience to access sometimes. If you get a timeout or a gateway error, refresh it, stop it, and refresh again, and it should come up, although, if it still doesn't come up, you may need to wait an hour or three, or a day, and try again.

I kept it in a chamber workspace because I intended to give the code back to Joe. He then told me he didn't really see the point, since it didn't reflect any real retro computing hardware or software that ever existed -- which is not unreasonable. 

If I make a real alternate reality project out of it, I should at least get the timing right, and make it a separate executable so I can pull in his updates. But that will take time I don't have.

You can read my summary from back then, and then go to the source code menu and select "source tree", or you can go directly to the source tree here:

https://osdn.net/users/reiisi/pf/exorsim6801/scm/tree/master/

On the right of the source tree page, towards the top, you'll find the git URL for cloning, and ZIP and TAR buttons for export. Hit your choice of ZIP or TAR (.tar.gz) to download, or use the git clone command to get your copy.

You should probably want to clone it or unpack the archive in a directory called exor6801 under your assembly language working directory (as in "~/asmwork/exor6801"), or use some other clear structure to keep it separate from Joe's exorsim.

After cloning or unpacking, change into the source code directory produced and do NOT do a "sudo make install"! 

Just do a "make", without sudo and without install. 

If you want to make it available without the path, when it's built, you can link it into your executable directory under a different name, such as "exorprime" or something.

But for what we want to do for the present, we can work directly in the build directory. So, in the build directory, basically do the same as you did for the 6800, except this time you'll invoke exor with two switches:

./exor --6801 --mon

Other than that, the session should look pretty much like the 6800 session:

$ cd asmwork/exorsim6801/exorsim
$ ./exor --mon --6801
Load facts file 'facts'
'exbug.bin' loaded.
'mdos.dsk' opened for drive 0 (single sided)

Hit Ctrl-C for simulator command line.  Starting simulation...

>         0 A=00 B=00 X=0000 SP=FF8A ------ OSLOAD   E800: 8E FF 8A LDS #$FF8A                Load OS

Type 'help'
% a 1000
1000: START LDAA	#8	; Gotta start somewhere.
1002:  ADDA	#5
1004:  ADDA	#2
1006:  ADDA	#7
1008:  ADDA	#4
100a:  NOP		; landing pad for breakpoint
100b: 
% u 1000
1000: 86 08               LDA #$08
1002: 8B 05               ADDA #$05
1004: 8B 02               ADDA #$02
1006: 8B 07               ADDA #$07
1008: 8B 04               ADDA #$04
100A: 01                  NOP
100B: 00                  ???
100C: 00                  ???
...
% d 1000
1000: 86 08 8B 05 8B 02 8B 07  8B 04 01 00 00 00 00 00 ................
1010: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00 ................
...
% s 1000
          0 A=00 B=00 X=0000 SP=FF8A ------ START    1000: 86 08    LDA #08   EA=1001 D=08   
>         1 A=08 B=00 X=0000 SP=FF8A ------          1002: 8B 05    ADDA #05                 

Type 'help'
% s
          1 A=08 B=00 X=0000 SP=FF8A ------          1002: 8B 05    ADDA #05  EA=1003 D=05   
>         2 A=0D B=00 X=0000 SP=FF8A ------          1004: 8B 02    ADDA #02                 

Type 'help'
% s
          2 A=0D B=00 X=0000 SP=FF8A ------          1004: 8B 02    ADDA #02  EA=1005 D=02   
>         3 A=0F B=00 X=0000 SP=FF8A ------          1006: 8B 07    ADDA #07                 

Type 'help'
% s
          3 A=0F B=00 X=0000 SP=FF8A ------          1006: 8B 07    ADDA #07  EA=1007 D=07   
>         4 A=16 B=00 X=0000 SP=FF8A H-----          1008: 8B 04    ADDA #04                 

Type 'help'
% s
          4 A=16 B=00 X=0000 SP=FF8A H-----          1008: 8B 04    ADDA #04  EA=1009 D=04   
>         5 A=1A B=00 X=0000 SP=FF8A ------          100A: 01       NOP                      

Type 'help'
% b 100a
Breakpoint set at 100A
% c 1000

Breakpoint!
          0 A=00 B=00 X=0000 SP=FF8A ------ START    1000: 86 08    LDA #08   EA=1001 D=08   
          1 A=08 B=00 X=0000 SP=FF8A ------          1002: 8B 05    ADDA #05  EA=1003 D=05   
          2 A=0D B=00 X=0000 SP=FF8A ------          1004: 8B 02    ADDA #02  EA=1005 D=02   
          3 A=0F B=00 X=0000 SP=FF8A ------          1006: 8B 07    ADDA #07  EA=1007 D=07   
          4 A=16 B=00 X=0000 SP=FF8A H-----          1008: 8B 04    ADDA #04  EA=1009 D=04   
          5 A=1A B=00 X=0000 SP=FF8A ------ START    1000: 86 08    LDA #08   EA=1001 D=08   
          6 A=08 B=00 X=0000 SP=FF8A ------          1002: 8B 05    ADDA #05  EA=1003 D=05   
          7 A=0D B=00 X=0000 SP=FF8A ------          1004: 8B 02    ADDA #02  EA=1005 D=02   
          8 A=0F B=00 X=0000 SP=FF8A ------          1006: 8B 07    ADDA #07  EA=1007 D=07   
          9 A=16 B=00 X=0000 SP=FF8A H-----          1008: 8B 04    ADDA #04  EA=1009 D=04   
>        10 A=1A B=00 X=0000 SP=FF8A ------          100A: 01       NOP                      

Type 'help'
% t on
% c 1000
         10 A=1A B=00 X=0000 SP=FF8A ------ START    1000: 86 08    LDA #08   EA=1001 D=08   
         11 A=08 B=00 X=0000 SP=FF8A ------          1002: 8B 05    ADDA #05  EA=1003 D=05   
         12 A=0D B=00 X=0000 SP=FF8A ------          1004: 8B 02    ADDA #02  EA=1005 D=02   
         13 A=0F B=00 X=0000 SP=FF8A ------          1006: 8B 07    ADDA #07  EA=1007 D=07   
         14 A=16 B=00 X=0000 SP=FF8A H-----          1008: 8B 04    ADDA #04  EA=1009 D=04   

Breakpoint!
>        15 A=1A B=00 X=0000 SP=FF8A ------          100A: 01       NOP                      

Type 'help'
%   

This older version likes to give you traceback after a breakpoint, if tracing is off. You can ignore it or examine it, as you like.

But that was all a bit boring since you've done it before, twice, so, before you hit control-C to break out, let's try adding a little code that does not assemble or  run on the 6800, just to be sure we actually have the 6801 emulator running. Go ahead and type this in by hand. It's not long:

% a 100b
100b: DSTART LDD #2056
100e:  ADDD #1285
1011:  ADDD #514
1014:  ADDD #1799
1017:  ADDD #1028
101a:  NOP
101b: 

Hit enter at the blank line to quit assembling, and then display the bytes and disassemble it:

% d 1000
1000: 86 08 8B 05 8B 02 8B 07  8B 04 01 CC 08 08 C3 05 ................
1010: 05 C3 02 02 C3 07 07 C3  04 04 01 00 00 00 00 00 ................
1020: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00 ................
...
% u 1000
1000: 86 08               LDA #$08
1002: 8B 05               ADDA #$05
1004: 8B 02               ADDA #$02
1006: 8B 07               ADDA #$07
1008: 8B 04               ADDA #$04
100A: 01                  NOP
100B: CC 08 08            LDD #$0808
100E: C3 05 05            ADDD #$0505
1011: C3 02 02            ADDD #$0202
1014: C3 07 07            ADDD #$0707
1017: C3 04 04            ADDD #$0404
101A: 01                  NOP
101B: 00                  ???
101C: 00                  ???

You see that my choice of numbers to add was deliberate, right?

Set the break point at $101A  and set trace on, then restart execution at $1000:

% b 101a
Breakpoint set at 101A
% t on
% c 1000
         39 A=1A B=1A X=0000 SP=FF8A ------ START    1000: 86 08    LDA #08   EA=1001 D=08   
         40 A=08 B=1A X=0000 SP=FF8A ------          1002: 8B 05    ADDA #05  EA=1003 D=05   
         41 A=0D B=1A X=0000 SP=FF8A ------          1004: 8B 02    ADDA #02  EA=1005 D=02   
         42 A=0F B=1A X=0000 SP=FF8A ------          1006: 8B 07    ADDA #07  EA=1007 D=07   
         43 A=16 B=1A X=0000 SP=FF8A H-----          1008: 8B 04    ADDA #04  EA=1009 D=04   
         44 A=1A B=1A X=0000 SP=FF8A ------          100A: 01       NOP                      
         45 A=1A B=1A X=0000 SP=FF8A ------ DSTART   100B: CC 08 08 LDD #$0808 EA=100C D=0808 
         46 A=08 B=08 X=0000 SP=FF8A ------          100E: C3 05 05 ADDD #$0505 EA=100F D=0505 
         47 A=0D B=0D X=0000 SP=FF8A ------          1011: C3 02 02 ADDD #$0202 EA=1012 D=0202 
         48 A=0F B=0F X=0000 SP=FF8A ------          1014: C3 07 07 ADDD #$0707 EA=1015 D=0707 
         49 A=16 B=16 X=0000 SP=FF8A ------          1017: C3 04 04 ADDD #$0404 EA=1018 D=0404 

Breakpoint!
>        50 A=1A B=1A X=0000 SP=FF8A ------          101A: 01       NOP                      

Type 'help'
% 

Notice what's happening in the accumulators. 

(This additional code, by the way, also runs on the 6809.)

******

Ah. Yes. I need to mention this. 

You may be wondering, when loading integer constants into the double accumulator on the 6801 and 6809, which accumulator gets the more significant byte? It's not apparent in this code, but, in both, A gets the more significant byte and B gets the less significant byte. 

This can be confusing when reading early code for the 6800, because the 6800 was apparently designed under the opposite assumption. Check the stacking order of interrupts. On both the 6800 and the 6801, A gets pushed before B, which results in B being saved lower in memory, where the most significant byte should be. And much of the code written for the 6800, including the EXORciser EXBug monitor ROM, follows the same order, with B holding the more significant byte in two-byte operations, and being stored lower in memory.

But when loading two-byte integers into D on either the 6809 or the 6801, B gets the less significant byte and A gets the more significant byte.

The push order is fixed on the 6809, by the way.

Trivia, but not trivia.

******

This should motivate our discussion of hexadecimal, and of the limits of sizes of integers within the CPU. Play around with it, or hang on to your questions for now, either way.

Again, there are other options, including XRoar or MAME emulating Tandy's MC-10 (which actually has a 6803, but that's just a 6801 without internal ROM). Also, for MSWindows, users, VMC10 can be found in the Color Computer Archives

If you decide to use XRoar or MAME or VMC10 or such, you'll also need self-hosted tools like HumBug and MCOS, which can also be found in the Color Computer Archives. And, if I remember right, the syntax will be a little different, so you'll have to figure that out. (It's not hard once you have the basic ideas down.)

And all that discussion should get us a little bit more ready to go after Hatari for working on the 68000.

 

(Title Page/Index)

 

No comments:

Post a Comment