Showing posts with label EXORsim. Show all posts
Showing posts with label EXORsim. Show all posts

Thursday, October 24, 2024

ALPP 03-09 -- Keyboard Input on the 6800, 6801, and 6809 (EXORsim)

Keyboard Input on the
6800, 6801, and 6809
(EXORsim)

(Title Page/Index)

 

Now that we can get both binary and hexadecimal output, including on the 68000, let's get some input. 

(I'm itching to move on to multiplication and division, but before we do that we really need to make sure we can get input from the keyboard.)

First, we'll just get a key and output it. Then we'll try something a bit more interesting.

Assuming your framework rigging is in place, lets go look at the BIOS routines again, referring back to the not-yet-on-the-beach example

You'll remember we found a facts file, and we found suspicious labels when looking for an output character routine. Nearby the OUTCH function was an INCH function and an INCHN function. The explanations weren't very clear, but we later dug into the M6809 EXORciser manual and found more information on page 3-33. Even though that's for the 6809, and is not included in the M6800 EXORciser manual, the facts files are the same, so we guess that the functional descriptions are good for the 6800, too.

XINCHN strips a "parity" bit off. That's the high bit that in many terminals of the day would be a parity bit rather than a data bit -- 7 bits of data, 1 bit of parity, stop and start bits, etc. We don't need that. 

Then there is XINCH:

XINCH	EQU	$F012	; wait for key, return in A, preserves B, X, see AECHO

XINCH waits for a key input and brings it back to us. That ought to be useful. What's AECHO? Maybe we don't need to know. Let's see if we can do something simple, something along the lines of  

* Essential monitor ROM routines
XINCH	EQU	$F012	; wait for key, return in A, preserves B, X, see AECHO
XOUTCH	EQU	$F018	; output ACCM A to debug terminal, preserves B,X
*
	ORG	$2000
START	JSR	XINCH
	JSR	XOUTCH
	BRA	START 

 Looks possible. Get a 6800 session of EXORsim going, assemble that, and see what it does.

$ ./exor --mon
Load facts file 'facts'
'exbug.bin' loaded.
  EXBUG-1.1 detected
'mdos.dsk' opened for drive 0 (double sided)

OSLOAD...

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

>         0 A=00 B=00 X=0000 SP=00FF ------          0020: B6 E8 00 LDA E800                 

6800 Monitor: Ctrl-C to exit, 'c' to continue, or type 'help'
% a 0
0000: * Essential monitor ROM routines
0000: XINCH	EQU	$F012	; wait for key, return in A, preserves B, X, see AECHO
0000: XOUTCH	EQU	$F018	; output ACCM A to debug terminal, preserves B,X
0000: *
0000: 	ORG	$2000
2000: START	JSR	XINCH
2003: 	JSR	XOUTCH
2006: 	BRA	START
2008: 
% 

Step through until we see something?

% s 2000
          0 A=00 B=00 X=0000 SP=00FF ------ START    2000: BD F0 12 JSR F012  EA=F012(XINCH) 

>         1 A=00 B=00 X=0000 SP=00FD ------ XINCH    F012: 7E FA 8B JMP FA8B                 

6800 Monitor: Ctrl-C to exit, 'c' to continue, or type 'help'
% s

          2 ---- Subroutine at FA8B processed by simulator ---- RTS executed ---

>         3 A=00 B=00 X=0000 SP=00FF ------          2003: BD F0 18 JSR F018                 


6800 Monitor: Ctrl-C to exit, 'c' to continue, or type 'help'
% 

That was sudden. Not sure why it wouldn't let us step through the ROM at  FA88. 

But I don't see any input or anything, and it didn't seem to wait for a key. Step some more?

% s

          3 A=00 B=00 X=0000 SP=00FF ------          2003: BD F0 18 JSR F018  EA=F018(XOUTCH) 

>         4 A=00 B=00 X=0000 SP=00FD ------ XOUTCH   F018: 7E F9 DC JMP F9DC                 

6800 Monitor: Ctrl-C to exit, 'c' to continue, or type 'help'
% s

          4 A=00 B=00 X=0000 SP=00FD ------ XOUTCH   F018: 7E F9 DC JMP F9DC  EA=F9DC(OUTCH) 
>         5 A=00 B=00 X=0000 SP=00FD ------ OUTCH    F9DC: 37       PSHB                     Output character with NULs

6800 Monitor: Ctrl-C to exit, 'c' to continue, or type 'help'
% s

          5 A=00 B=00 X=0000 SP=00FD ------ OUTCH    F9DC: 37       PSHB                     Output character with NULs
>         6 A=00 B=00 X=0000 SP=00FC ------          F9DD: F6 FC F4 LDB FCF4                 

6800 Monitor: Ctrl-C to exit, 'c' to continue, or type 'help'
% s

          6 A=00 B=00 X=0000 SP=00FC ------          F9DD: F6 FC F4 LDB FCF4  EA=FCF4(ACIA0) D=03 
>         7 A=00 B=03 X=0000 SP=00FC ------          F9E0: C5 02    BITB #02                 

6800 Monitor: Ctrl-C to exit, 'c' to continue, or type 'help'
% s

          7 A=00 B=03 X=0000 SP=00FC ------          F9E0: C5 02    BITB #02  EA=F9E1 D=02   
>         8 A=00 B=03 X=0000 SP=00FC ------          F9E2: 27 F9    BEQ F9DD                 

6800 Monitor: Ctrl-C to exit, 'c' to continue, or type 'help'
% s

          8 A=00 B=03 X=0000 SP=00FC ------          F9E2: 27 F9    BEQ F9DD  EA=F9DD        
>         9 A=00 B=03 X=0000 SP=00FC ------          F9E4: B7 FC F5 STA FCF5                 

6800 Monitor: Ctrl-C to exit, 'c' to continue, or type 'help'
% s

          9 A=00 B=03 X=0000 SP=00FC ------          F9E4: B7 FC F5 STA FCF5  EA=FCF5(ACIA1) D=00 
>        10 A=00 B=03 X=0000 SP=00FC ---Z--          F9E7: 81 0D    CMPA #0D                 

6800 Monitor: Ctrl-C to exit, 'c' to continue, or type 'help'
% s

         10 A=00 B=03 X=0000 SP=00FC ---Z--          F9E7: 81 0D    CMPA #0D  EA=F9E8 D=0D   
>        11 A=00 B=03 X=0000 SP=00FC --N--C          F9E9: 26 1B    BNE FA06                 

6800 Monitor: Ctrl-C to exit, 'c' to continue, or type 'help'
% s

         11 A=00 B=03 X=0000 SP=00FC --N--C          F9E9: 26 1B    BNE FA06  EA=FA06        
>        12 A=00 B=03 X=0000 SP=00FC --N--C          FA06: 7D FF 02 TST FF02                 

6800 Monitor: Ctrl-C to exit, 'c' to continue, or type 'help'
% s

         12 A=00 B=03 X=0000 SP=00FC --N--C          FA06: 7D FF 02 TST FF02  EA=FF02(NULCTRL) 
>        13 A=00 B=03 X=0000 SP=00FC ---Z--          FA09: 2A F9    BPL FA04                 

6800 Monitor: Ctrl-C to exit, 'c' to continue, or type 'help'
% s

         13 A=00 B=03 X=0000 SP=00FC ---Z--          FA09: 2A F9    BPL FA04  EA=FA04        
>        14 A=00 B=03 X=0000 SP=00FC ---Z--          FA04: 33       PULB                     

6800 Monitor: Ctrl-C to exit, 'c' to continue, or type 'help'
% s

         14 A=00 B=03 X=0000 SP=00FC ---Z--          FA04: 33       PULB                     
>        15 A=00 B=00 X=0000 SP=00FD ---Z--          FA05: 39       RTS                      


6800 Monitor: Ctrl-C to exit, 'c' to continue, or type 'help'
% 

Like me, are you not seeing anything that looks like we got input from the keyboard and put it out?

Let's try just running it from here.

% c

SSAADDKKQQWWEE999900DDLLKKJJAASSDDFFInterrupt!
     139572 ---- Subroutine at FA8B processed by simulator ---- RTS executed ---

>    139573 A=00 B=00 X=0000 SP=00FF ---Z--          2003: BD F0 18 JSR F018                 


6800 Monitor: Ctrl-C to exit, 'c' to continue, or type 'help'
% 

Well, that definitely was grabbing keys from the keyboard and putting them out until I hit Ctrl-C. 

But twice?

Like an echo? 

When working with terminals that take input from the keyboard and send it to a computer, it can be useful to just let the character echo back out to the screen before the computer processes it. Or, at least, back in the 1970s, it could be. 

So we read about XINCH again, and then we go looking for AECHO in the 6809 manual, and it looks like

* Essential monitor ROM parameters
* ECHO suppress -- set non-zero before each call to XINCH/XINCHN 
* to suppress echo for that call only.

 But the facts file says AECHO is

ff53 rmb 1 AECHO	Echo flag: 0=echo

where the EXORciser 6809 manual says it's at $FF58.

The facts09 file agrees with the facts file. Which is it?

So I decided to trust the manual first. It says it must be set non-zero before every call to suppress echo. Weird, but I tried it. No effect. 

So, among a few other things, I tried the value in the facts file, but setting it non-zero before every call like the EXORciser 6809 manual says, like this:

* Essential monitor ROM routines
XINCH	EQU	$F012	; wait for key, return in A, preserves B, X, see AECHO
XOUTCH	EQU	$F018	; output ACCM A to debug terminal, preserves B,X
*
* Essential monitor ROM parameters
* ECHO suppress -- set non-zero before each call to XINCH/XINCHN 
* to suppress echo for that call only.
* Not the same address as 6809 EXBUG09.
AECHO	EQU	$FF53	; ECHO suppress per-call
*
	ORG	$2000
START	LDAA	#-1
	STAA	AECHO
	JSR	XINCH
	JSR	XOUTCH
	BRA	START

I pasted that into the assemble command in a 6800 session, and it performed as expected, pretty much. Give it a try.

And while your practicing your typing skills, try Ctrl-H, Ctrl-J, Ctrl-K, and Ctrl-L just for fun. 

Trying this code in EXORsim6801's exor command, I discovered that EXORsim 6801's assembler doesn't seem to like -1 for immediates. So I tried 0-1:

START	LDAA	#0-1

That worked the way it should -- just remember that, when you hit Ctrl-C, EXORsim is going to throw a long backtrace at you. 

On the 6809, I did have to define AECHO according to the manual, to location $FF581:

AECHO	EQU	$FF58	; ECHO suppress per-call

And remember LDAA is LDA, and STAA is STA on the 6809. 

So I backed up the facts09 file to something named facts09.bk20241024 or something and fixed that line in the facts09 file. 

Something to think about, but a load and a store before calling keyboard input seems like a bit of waste motion, maybe? Since XINCH requires that variable to be set before every call, to suppress echo, it must be resetting it after every call.

That means, every time we want to call XINCH, it must have been cleared already.

So if we just INCrement it, or DECrement, or COMplement it, it will be non-zero. And we can two instructions in 5 bytes for one instruction in 3 bytes. Something to think about, right?

Now, we want our input character routine to be compatible with the rest of the functions in the framework we're building, so we need to define some glue and entry points and test code, starting with the 6800. But this chapter is getting a little long to put the code for all three 8-bit CPUs in.


  


(Title Page/Index)

 

 

 

 

Sunday, June 16, 2024

ALPP 01-03 -- Running Code on the 6800 and 6809

 Running Code on the
6800 and 6809

(Title Page/Index)

 

Now that you have EXORsim running on your workstation, let's look at how you can use it to run some code.

If you shut down after working through the last post, boot back up and change directory to get back in the directory you built EXORsim in, doing something like

$ cd asmwork/exor/exorsim

In the directory where you built EXORsim, start it up with the --mon option.

$ ./exor --mon
Load facts file 'facts'
'exbug.bin' loaded.
  EXBUG-1.1 detected
'mdos.dsk' opened for drive 0 (double sided)

OSLOAD...

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

>         0 A=00 B=00 X=0000 SP=00FF ------          0020: B6 E8 00 LDA E800                 

6800 Monitor: Ctrl-C to exit, 'c' to continue, or type 'help'
% 

We can start with the 6800 example showing how an accumulator works. The 6800 code, again:

START LDAA	#8	; Gotta start somewhere.
 ADDA	#5
 ADDA	#2
 ADDA	#7
 ADDA	#4
 NOP		; landing pad for breakpoint 

Select it from the START label and copy it to the end of the NOP line.

At the % prompt in the debugger, type 

a 1000

and enter/return. 

You could type it in by hand, but since you've just selected and copied it, just paste it in. Use the right button on the mouse to pull up an edit menu over the session window and paste it. Hit enter again after the paste:

% 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: 
% 

What have you done?

The "a" command is the assemble command. Joe put the ability to assemble source code into the hosted debugger. (Thanks, Joe!) So you've just assembled the source code of the example into memory starting at hexadecimal $1000.

You can unassemble it if you want, with the "u" command:

% 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                  ???
...

Unassemble, disassemble, same thing. 

Note that the address specified for the debugger commands is read by the debugger as hexadecimal. (Values in the assembler itself are default decimal.)

You can display the contents of memory where you assembled it with the "d 1000" command:

% 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 ................
...

Now you know why it's "u" for unassemble instead of "d" for disassemble. "d" is for display. (Or dump, if you prefer, but dump can mean other things.)

How do you run it? One way is to use the "s" command, for step:

% s 1000

          0 A=00 B=00 X=0000 SP=00FF ------ START    1000: 86 08    LDA #08   EA=1001 D=08   
>         1 A=08 B=00 X=0000 SP=00FF ------          1002: 8B 05    ADDA #05                 

6800 Monitor: Ctrl-C to exit, 'c' to continue, or type 'help'
% 

You'll see that it went to address $1000 and stepped one op-code, showing you the next op-code. And it's nice to see the op-codes disassembled. Unassembled.

Hit "s" all by itself and return and it steps the next one:

% s

          1 A=08 B=00 X=0000 SP=00FF ------          1002: 8B 05    ADDA #05  EA=1003 D=05   
>         2 A=0D B=00 X=0000 SP=00FF ------          1004: 8B 02    ADDA #02                 

6800 Monitor: Ctrl-C to exit, 'c' to continue, or type 'help'
% s

          2 A=0D B=00 X=0000 SP=00FF ------          1004: 8B 02    ADDA #02  EA=1005 D=02   
>         3 A=0F B=00 X=0000 SP=00FF ------          1006: 8B 07    ADDA #07                 

6800 Monitor: Ctrl-C to exit, 'c' to continue, or type 'help'
% s

          3 A=0F B=00 X=0000 SP=00FF ------          1006: 8B 07    ADDA #07  EA=1007 D=07   
>         4 A=16 B=00 X=0000 SP=00FF H-----          1008: 8B 04    ADDA #04                 

6800 Monitor: Ctrl-C to exit, 'c' to continue, or type 'help'
% s

          4 A=16 B=00 X=0000 SP=00FF H-----          1008: 8B 04    ADDA #04  EA=1009 D=04   
>         5 A=1A B=00 X=0000 SP=00FF ------          100A: 01       NOP                      

6800 Monitor: Ctrl-C to exit, 'c' to continue, or type 'help'
% 

And you can watch the effects -- watch the sum accumulate in the accumulator, and watch the program counter increment as it the simulator sequences through the op-codes.

If stepping is a little slow for you, you can set a breakpoint with the "b" command, and use the "c" command for continue, until it hits the breakpoint:

% b 100a
Breakpoint set at 100A
% c 1000


Breakpoint!
          9 A=16 B=00 X=0000 SP=00FF H-----          1008: 8B 04    ADDA #04  EA=1009 D=04   
>        10 A=1A B=00 X=0000 SP=00FF ------          100A: 01       NOP                      

6800 Monitor: Ctrl-C to exit, 'c' to continue, or type 'help'
% 

Note that the simulator's PC has to hit the exact breakpoint to stop. That's part of the reason I use the NOP as a landing pad. It's easier to see where to set the breakpoint.

But you wanted to see it trace through the operations, not just hum away in silence until it hit the breakpoint?

Use the "t" command to turn trace on:

% t on
% c 1000

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

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

6800 Monitor: Ctrl-C to exit, 'c' to continue, or type 'help'
% 

Fortunately, the breakpoint was still set.

And you've probably noticed by now that there's a help command. Try it now, just for grins.

Okay, you've got the basics of the debugger in EXORsim down now, you can play around a bit. 

Go ahead and try things. If it gets hung up, you can always hit ctrl-C, and if that doesn't work, just close the shell session window and open a new one. 

How about the 6809?

Here's the 6809 code for the above:

START LDA	#8	; 6809 mnemonic: LoaD accumulator A
 ADDA	#5	; Mnemonic shared with 6800/6801.
 ADDA	#2
 ADDA	#7
 ADDA	#4 
 NOP		; landing pad for breakpoint 

 In EXORsim, it's not a whole lot different. The commands are the same. The main difference is the set of op-codes and their mnemonics. 

Oh, and the command to start it running is "exor09":

$ ./exor09 --mon
Load facts file 'facts09'
'exbug09.bin' loaded.
  EXBUG09-2.1 detected
'mdos09.dsk' opened for drive 0 (double sided)

OSLOAD...

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

>         0 A=00 B=00 X=0000 Y=0000 U=0000 S=00FF P=00 --------            0020: 86 10        LDA #$10                   

6809 Monitor: Ctrl-C to exit, 'c' to continue, or type 'help'
% 
Everything above looks pretty much the same for the code example above, except for the 6809's extra registers, for assembling, copying and pasting, disassembling, displaying, stepping, setting breakpoints, continuing, tracing:
% a 1000
1000: START LDA	#8	; 6809 mnemonic: LoaD accumulator A
1002:  ADDA	#5	; Mnemonic shared with 6800/6801.
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: 12                  NOP 
100B: 00 00               NEG $00
100D: 00 00               NEG $00
...
% d 1000
1000: 86 08 8B 05 8B 02 8B 07  8B 04 12 00 00 00 00 00 ................
1010: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00 ................
...
$ s 1000

         10 A=1A B=00 X=0000 Y=0000 U=0000 S=00FF P=00 -------- START      1000: 86 08        LDA #$08                   
>        11 A=08 B=00 X=0000 Y=0000 U=0000 S=00FF P=00 --------            1002: 8B 05        ADDA #$05                  

6809 Monitor: Ctrl-C to exit, 'c' to continue, or type 'help'
% s

         11 A=08 B=00 X=0000 Y=0000 U=0000 S=00FF P=00 --------            1002: 8B 05        ADDA #$05                  
>        12 A=0D B=00 X=0000 Y=0000 U=0000 S=00FF P=00 --------            1004: 8B 02        ADDA #$02                  

6809 Monitor: Ctrl-C to exit, 'c' to continue, or type 'help'
% s

         12 A=0D B=00 X=0000 Y=0000 U=0000 S=00FF P=00 --------            1004: 8B 02        ADDA #$02                  
>        13 A=0F B=00 X=0000 Y=0000 U=0000 S=00FF P=00 --------            1006: 8B 07        ADDA #$07                  

6809 Monitor: Ctrl-C to exit, 'c' to continue, or type 'help'
% s

         13 A=0F B=00 X=0000 Y=0000 U=0000 S=00FF P=00 --------            1006: 8B 07        ADDA #$07                  
>        14 A=16 B=00 X=0000 Y=0000 U=0000 S=00FF P=00 --H-----            1008: 8B 04        ADDA #$04                  

6809 Monitor: Ctrl-C to exit, 'c' to continue, or type 'help'
% s

         14 A=16 B=00 X=0000 Y=0000 U=0000 S=00FF P=00 --H-----            1008: 8B 04        ADDA #$04                  
>        15 A=1A B=00 X=0000 Y=0000 U=0000 S=00FF P=00 --------            100A: 12           NOP                        

6809 Monitor: Ctrl-C to exit, 'c' to continue, or type 'help'
%  
% b 100a
Breakpoint set at 100A
% c 1000


Breakpoint!
          4 A=16 B=00 X=0000 Y=0000 U=0000 S=00FF P=00 --H-----            1008: 8B 04        ADDA #$04                  
>         5 A=1A B=00 X=0000 Y=0000 U=0000 S=00FF P=00 --------            100A: 12           NOP                        

6809 Monitor: Ctrl-C to exit, 'c' to continue, or type 'help'
% t on
% c 1000

          5 A=1A B=00 X=0000 Y=0000 U=0000 S=00FF P=00 -------- START      1000: 86 08        LDA #$08                   
          6 A=08 B=00 X=0000 Y=0000 U=0000 S=00FF P=00 --------            1002: 8B 05        ADDA #$05                  
          7 A=0D B=00 X=0000 Y=0000 U=0000 S=00FF P=00 --------            1004: 8B 02        ADDA #$02                  
          8 A=0F B=00 X=0000 Y=0000 U=0000 S=00FF P=00 --------            1006: 8B 07        ADDA #$07                  
          9 A=16 B=00 X=0000 Y=0000 U=0000 S=00FF P=00 --H-----            1008: 8B 04        ADDA #$04                  

Breakpoint!
>        10 A=1A B=00 X=0000 Y=0000 U=0000 S=00FF P=00 --------            100A: 12           NOP                        

6809 Monitor: Ctrl-C to exit, 'c' to continue, or type 'help'
% 

So, give the 6809 code a try, too, looking for differences. 

Then take a rest  before proceeding to getting a simulator for the 6801.

 

(Title Page/Index)

 

Saturday, June 15, 2024

ALPP 01-02 -- Getting a Simulator for the 6800 and 6809

Getting a Simulator for the
6800 and 6809

(Title Page/Index)

 

Okay, so we've introduced assembly language by talking a little about adding small integers. But if we want to understand what's going on, we really need some way to watch what the processor does when it executes the code.

If I had more time and money, I would design my own hardware and build my own simulator software, and offer the hardware for sale and put the software up for download and all that, and it would all be real easy to use. (Of COURSE! ;-)

Fortunately, there are useful simulators (software-based emulators) already available, as I have mentioned. 

There are options other than the one I'm recommending, such as XRoar for the 6809 and 6801, which simulates the Dragon, the Tandy Color Computers 1, 2, and 3, and the Radio Shack MC-10, and the original Matra Alice 4K. If Ciaran doesn't beat me to it, I may try (again) to add hosted debugging to XRoar, but you can always run a self-hosted debugger (such as Disk EDTASM) on the emulated computer. 

Now, Ciaran and his friends do provide an on-line emulator, and you can download Disk EDTASM and run it on the on-line simulator, but I don't want to be encouraging lots of people to put a heavy load on Ciaran's server. 

I'll talk a little about getting XRoar and building it locally on your own hardware and using EDTASM for debugging later, but It's a pretty steep start-up for a topic that already has a steep learning curve.)

Similarly, VCC for MSWindows requires compiling (if I read the website right), and only emulates the Color Computer 3 (6809). I think I have heard that it supports direct debugging fairly well, but cannot vouch for that. It might be an option if you're running MSWindows. 

Both VCC and Xroar require several libraries that are themselves dependent on other libraries, so building them is not necessarily straightforward. I want to avoid that kind of mess as a requirement.

Yes, MAME would work, too, but it's huge. Just huge. I understand it provides hosted debugging, but I have not gotten that far with it yet. It does tend to be available on a number of common platforms.

So,

EXORciser

What I will use for 6800 and 6809 code, especially in the first part of this, will be Joe. H. Allen's EXORciser simulator, EXORsim

(I suppose the name, EXORciser, was a deliberate pun on Motorola's part. Both hardware and software needs exercising to find weak places, and sometimes debugging designs does seem to be a little like exorcising demons. But it does make searching for information on it a little difficult now. Looking for EXORsim, in particular, will find your search engine determined to tell you about exorcism, instead.)

The EXORciser was Motorola's 6800-based workstation microcomputer for developing both software and hardware for the 6800. It ran an operating system called MDOS provided by Motorola, along with applications supplied by Motorola and 3rd-party developers.

The EXORciser was a little expensive compared to popular microcomputers that came out shortly after, but it turned out to work well enough as a general purpose microcomputer to be used as an office computer, as well. Southwest Technical Products (SWTPC) and others released microcomputers based on, and somewhat compatible with the EXORciser, with less support for hardware development, but also less expensive.

When Motorola introduced the 6809, they developed a CPU board for it with the 6809 replacing the 6800, and the software was kept mostly compatible, not taking full advantage of the 6809's improved architecture.This allowed the same Exorciser hardware to be shared across projects using each processor.

EXORsim

Joe Allen's EXORsim simulates in software both the EXORciser, and the SWTPC 6800-based microcomputers. Recently, Joe added the 6809, so it can be used for both CPUs, as well.

EXORsim is very convenient, in that the simulated terminal allows you to copy and paste, simplifying the process of getting code and data into the simulated microcomputer. 

More importantly, it can be compiled easily on pretty much anything that supports ANSI C and a few of the basic POSIX libraries, which includes, well, lots of OSses and lots of compiler toolchains. In specific, you can definitely compile it on pretty much any Linux OS, Mac OS, or BSD OS, with the GNU compiler or CLang toolchains. You can also compile it on MSWindows with the Cygwin environment and compilers.

(It should be possible to get it working under Microsoft's LSW, but I don't want to take the time to verify that. If you go that route, save yourself some time and go ahead and load Ubuntu or openSUSE or whatever on top of LSW, and work in that.) 

You'll need the compilers and toolchains anyway, so you'll need to go ahead and get them now.

Old PCs running a Linux OS or BSD OS

If you aren't already using a Linux OS or Mac OS or freeBSD or netBSD, and you have an old (from even as long as 15 years ago) PC you aren't using, with 4 GB or more RAM, 40 GB or more of hard disk, and a CPU with at least two physical cores running faster than 1.2 GHz (or one core running faster than 2.5 GHz), you can save any data on it that you might need, wipe it clean, and install Devuan, Ubuntu, Debian, Mint OS, Cent OS, openSUSE, NetBSD, or FreeBSD or whatever on it.

(Note that openBSD may be a little too security-oriented to compile EXORciser and Hatari easily.)

Do remember to check it for important data before you do, and to back any important data up somewhere safe.

Or, if it has at least 80 GB free on the hard disk, you might be able to defragment it, resize the MSWindows partition, and install the Linux or BSD OS in a dual-boot configuration. It's still best to back up any important data first.

If the old PC is a little tighter for  resources than that, Ubuntu provides LUbuntu and XUbuntu that might fit, and Debian and the others can be configured with a light-weight window and desktop manager, and so forth.

While you're installing the OS, make sure you also install the C compilers, either GNU or CLang, and the POSIX libraries. (These should come along with any basic developers' environment option the distribution provides.) 

Also make sure you install a programmers' text editor, such as gedit, kate, geany, VIM, or eMacs. And a command-line terminal window emulator for running commands in, like Xterm. And if your choice of Linux OS has gforth in the repositories, you might want to grab that, too, but it isn't, strictly speaking, necessary.

Just for the record, I do not recommend dual-booting. You tend to avoid switching back and forth, so you tend not to do things that require switching.

If you're not dual-booting, installing a Linux OS is really not that hard.  FreeBSD or NetBSD will be a little on the difficult side for some people. They all have instructions on their sites oriented towards the technical level of people that the OS is geared towards, and these days it's relatively rare to run into exceptions in the install process. Look at the install instructions and pick one that feels comfortable.

Just one thing, again -- don't forget to check the hard drive for valuable data, and make sure you back anything important up off to some external medium, like an SD card or a USB memory device.

(Porn collections? Go ahead and wipe 'em. Retro computing is way more fun.)

Daily-driving User Account!

Oh, and one more thing. Just one. Promise.

PLEASE! for the love of peace, sanity, and a computer that can be somewhat protected from its internet connection, make yourself a non-admin privilege daily-driving user account to work in.

Once the default administrator-capable account is created, and everything you chose in the OS install is loaded, find where you can add users, and add a user without administrator privileges. This account should be the one you use for surfing around the internet, and for working on retro stuff, etc.

This is true no matter what OS you choose. 

I know it requires some learning of how to handle privileges and such, but it's worth it for the peace of mind and the trouble you don't end up causing others so easily.

ARM based lightweight computers

If you don't have an old computer, a Raspberry PI or similar ARM-based lightweight computer can be had for pretty cheap, and versions of Debian or Ubuntu or NetBSD (in particular) can be loaded on them. Raspberry Pi, in particular, comes with Raspberry PI OS (Raspbian) already installed by default, which is basically Debian pre-customized and pre-loaded on the PI. 

To find other computers similar to the Raspberry PI, search for "computers similar to raspberry pi" and you'll get links to lots. Le Potato, Orange, and Odroid are trending as I write this.

Note that I don't have any experience on these, but the ones named above should just work.

Mac OS

Doing this under Mac OS will also be pretty straightforward, and you don't have to worry about installing the OS. You will need to install the BSD developer tools subsystem  (cough), well, I mean, XCode, which has the compiler toolchain. But that's straightforward, too. All the libraries and bc should just come with XCode. And XCode has its own integrated editor, so you don't need to choose a text editor. (But there are lots of great 3rd party text editors available, too, including those I mentioned for Linux and BSD OSses.)

MSWindows and Cygwin

If, for some reason, you must use an MSWindows computer for this project, you probably want Cygwin.

Visual Studio will have you jumping through hoops of Microsoft telling you, "Let us help you! Let us HELP you!!!!!" and sending you on wild goose chases, mostly to get you corralled back into their world. That's not why you're reading this blog. Yes, LSW might work. If you load a Linux OS on top, it should work. But if you have questions about that, I haven't been there, and I'm afraid I won't give them priority.

So I recommend Cygwin if you can't do a Linux, BSD or Mac OS. 

Make sure you're accessing the real https://cygwin.com/ site, download the installer, and check the checksum of the installer after the download is complete.

For MSWindows 10, the command-line command for checking checksums was 

certutil -hashfile <TYPE>

search the web for how to specify the type of checksum, etc. 

Once Cygwin is installed, open up the installer again and get either the gnu C compiler or the Clang compiler. Either should work. And you'll need the ANSI and Posix libraries. While you're at it, get bc, too. (I think it's in the repositories.) I don't think they currently have gforth in the repositories, so we'll just kind of punt on that. Terminal emulation should be in the default install.

Get a text editor (see above). 

VS Code? I'm not going to tell you don't do that, but give yourself an alternative. Get a separate text editor so you can dodge when Microsoft's stuff wants to fight with you.

Checking your environment

We need to check that the compiler works. Open up a terminal emulation window (XTerm or equivalent, Cygwin shell if you are using Cygwin) and type 

cc --version

and it should report which compiler and which version. GNU's toolchain will tell you it's from the Free Software Foundation, and Clang should report that it's clang. Both should give you a version number.

If you're not getting that, check your package manager to see whether it gave you an error or something when it tried to install the compiler and toolchain.

When you get a version number, make a working directory and change into it, something like

  ~$ mkdir asmwork
  ~$ cd asmwork
  ~/asmwork$

open up an editor window or editor session and type the following program in and save it in asmwork as "beachead.c": 



/* beachead.c 
** by Joel Rees, Japan; assigned to public domain.
*/
#include <stdio.h>
#include <stdlib.h>
int main( int argct, char *args[] )
{  char * arg1 = ( argct < 2 ) ? "none" : args[ 1 ];
   printf( "%s on the beach\n", arg1 );
   return EXIT_SUCCESS;
}

 

Compiling and running it should give you something like this:

~/asmwork$ cc -o beachead beachead.c
~/asmwork$ ./beachead one
one on the beach
~/asmwork$ ./beachead
none on the beach

(Type what comes on the lines after the "$" dollar sign prompt. The computer should respond with the lines without the prompt. Don't forget ./ before the program name, so the shell knows that the beachead program is in the directory you are in.)

Compiling EXORsim

Once you have your system and  toolchain ready to work with,  open your web browser and go to Joe Allen's EXORsim repository on github:

https://github.com/jhallen/exorsim

And read through the description. For the record, we won't need to use MDOS or FLEX, and we won't need to use blank disk images. Not at this point. Maybe later. Also, whether you install EXORdisk in your system's /usr/bin to make it available to every user, or just run it from your user directories, will be up to you.

You can find a link to download the source as a .ZIP archive file by clicking the [<> code] button above the directory listing. Make a directory for EXORsim under the asmwork directory (such as "~/asmwork/exor") and unpack the archive there. Drag, select, and click in your GUI should work.

Alternatively, you can copy the URL shown there and use the git clone command -- if you've installed git. (It's worth installing, by the way.)

Change directory into the exor directory you made and then into the source code directory, if you didn't end up with the source code directly under the exor directory that you just made. Check the README file, and ...

Hold on. The build instructions you have read are okay, if you want to install it where you any user on your system can run it. If you don't want to do that, you can just make it without the sudo or runas command.

If make does not successfully complete, you'll need to look at the error messages to see if you need a library or something. But it should successfully complete on any of the OSses I've described above, if you have the ANSI and POSIX libraries installed.

If you have problems, leave a message in the comments here and I'll try to get back to you.

Now, if you don't want it installed system-wide, but you don't want to type the full (relative) path every time you run it, you can add a directory for locally runnable stuff in your user directory. Call it ~/me/prg or something you like, and add it to your search paths. Then make a symbolic link from the compiled object files into your local programs directory and you're set. 

For now, you can run these from the directory where they are compiled. Type

$ ./exor -? 

and the 6800 version of EXORsim should give you some helpful output about how to run it. For now, type "./exor --mon" and hit enter:

$ ./exor --mon
Load facts file 'facts'
'exbug.bin' loaded.
  EXBUG-1.1 detected
'mdos.dsk' opened for drive 0 (double sided)

OSLOAD...

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

>         0 A=00 B=00 X=0000 SP=00FF ------          0020: B6 E8 00 LDA E800                 

6800 Monitor: Ctrl-C to exit, 'c' to continue, or type 'help'
% 

and you are in the hosted debugger, being prompted to type a command. (The "%" is the prompt in the hosted debugger.) 

And that is enough for this post. (It has likely been a long road, really.) 

Type Q or ctrl-C to quit. Or leave it there and continue with the next post, if you aren't tired out.

Next post will be a short introduction to using EXORsim for running code on the 6800 and 6809.

 

(Title Page/Index)

 

Saturday, August 13, 2022

VTL-2 part 3, Optimizing for the 6801

The 6801 is one of my favorite hobby horses -- or one of my favorite axes to grind. Motorola kind of missed out on some opportunities with it. I've ranted about that elsewhere, here I'll just make use of it for what it is.

If you wonder why I would do a hand-optimization of VTL-2 for the 6801, John Linville got me digging into the getting the 6800 version running, and I enjoy working with the 6801 almost as much as I enjoy working with the 6809. Anyway, it's a kind of recreational activity for me.

Two notes before I dig in: 

One is a CPX trick someone used in the 6800 source that won't work on the 6801. There's an FCB $9C at line 541 of the source I posted with the variables moved out of the direct page, in the middle of the DIVide routine. (It's from the original that I'm working with.) That's the op-code for CPX, and CPX doesn't affect carry or overflow on the 6800. It is used as an effective no-op to skip the SEC instruction, instead of using a branch around the set carry instruction. It saves one precious byte (and a couple of processor cycles). 

I've replaced it with a branch around in the optimizations for the 6801, because the 6801 fixes the CPX instruction to fully implement all flags for the sixteen-bit comparison, which means it ain't gonna work on the 6801. And it won't work for the 6809, either. 

(That's the thing about such tricks. They fall apart under progress.)

The other is that the 6800 uses a post-decrement push, so that the stack pointer is always pointing to the next available byte, not the last byte pushed. That's important in the insert-line-by-stack-blast routine, which I'm going to replace just as a matter of principle before I'm done, but the first version for the 6801 keeps it. 

For anyone getting ahead of me and cribbing from my conversions to work on the 6809 transliteration, remember that, and position Y or U correctly before you copy down or up, as you may choose, in your line insertion routine.

At the present point, I have it running on my fake 6801 simulator that I added to Joe H. Allen's EXORsim. This first version does easy stuff, like converting two-byte load and store sequences using the accumulators to single double-accumulator sequences. 

It also moves the temporary/local variables out of where they were hiding among the VTL pre-declared variables (and saving RAM space). Two of the temporaries were easily replaced with PSHX and PULX sequences (since the 6801 can do that). The others have usage patterns that don't fit so easily to shoving them off on the stack, so I moved them to the direct page.

Why, you ask? Why use extra RAM in the direct page when I just moved things out of the direct page?

Well, twenty bytes is a lot different from the entire 256 bytes of the direct page. Twenty bytes can be moved around with an appropriate ORG to fit your hardware. And moving those temporaries back into the direct page gives us back some of our code byte count savings that came from having it all in the direct page in the first place.

But the big reason is that it is an excuse to give them more meaningful names than SAVE0, SAVE1, ... etc. labels, which will help when moving the code to the 6809.

See the code for the rest of the story:

https://osdn.net/users/reiisi/pastebin/8475 (replaced with following:)

https://osdn.net/users/reiisi/pastebin/8605 (See notes for 20220904 and 20220911 below.)

[202208140155: add (yeah, up way too early on a Sunday morning]

Here is source that clears out the stack blasts, for clarity and for playing nice with interrupts:

https://osdn.net/users/reiisi/pastebin/8476 (replaced with following:)

https://osdn.net/users/reiisi/pastebin/8606 (See notes for 20220904 and 20220911 below.)

[202208140155: add end]

I'll add at least one more when I get it running on the MC10 emulator, then I should be ready to tackle the 6809 transliteration -- if no one beats me to it.

[202209022213: add (Oh! how embarrassing!)]

I have discovered, on the road to getting the MC10 version up, that my emulation was faulty. For all the discussion on the difference between CPX on the 6800 and on the 6801, I forgot to set the carry flag in my emulation, and the RAM check routine I added to the 6801 version has its end test inverted. Eventually, I'll delete the pastebins above and replace them with pastebins that have the BHI on line 150/152 fixed. Until then, go in and edit that line in whichever source, change the BHI to BLO:

PROBET	CPX	#COLD
	BLO	PROBE	; CPX on 6801 works right.

And get the most recent revision to my 6801 version of EXORsim. Hopefully I'll get the fixed simulator code up sometime tomorrow (3 Sept.). 

[202209031747: Done. Corrected pastebuffers added and linked, buggy pastebuffers deleted.]

[202209022213: add end]

[202209041331: add (more embarrassment!)]

I made a bad optimization to the random function in both of the above, and in the MC-10 version. Don't know how I missed this one, either. Blame it on my age?

At the label AR2 in both the above, I falsely corrected, without thinking, the addition of the low byte to the high, and vice-versa. My false correction looks like this:

AR2	STD	0,X	; STORE NEW VALUE
	ADDD	QUITE	; RANDOMIZER
	STD	QUITE
	RTS

Looks reasonable, right? As long as you ignore the comment about randomizer?

Well, here's what it looked like in the original 6800 code:

AR2	STAA	0,X	; STORE NEW VALUE
	STAB	1,X
	ADDB	QUITE	; RANDOMIZER
	ADCA	QUITE+1
	STAA	QUITE
	STAB	QUITE+1
	RTS

 See what was going on? 

Well, I probably should fix the pastebuffer, but OSDN won't let me today. Maybe I have too many. But I don't want to publish this code in a repository without some explicit permission from the authors. Anyway, the fix I recommend is below, with a couple of lines of code to detect lack of initialization and semi-auto initialize it:

AR2	STD	0,X	; STORE NEW VALUE
	BNE	AR2RND	; Initialize/don't get stuck on zero.
	INCB		; Keep it known cheap.
*	ADDD	QUITE	; RANDOMIZER	; NO! Don't do this.
AR2RND	ADDB	QUITE	; RANDOMIZER	; Adding the low byte to the high byte
	ADCA	QUITE+1	;		; is cheap but intentional.
	STD	QUITE
	RTS
*

Just search the code for "RANDOMIZER", cut the bad code out, and paste in the fix. Or, better yet, edit it with your own, improved random function.

Initialization -- yeah, this is another place where the original code left initialization out to keep the code tiny.

[202209041331: add end]

[202209111229: add] 

While transliterating for the 6809, I discovered that I missed some more opportunities to optimize for the 6801.

If you look for the label 

SUBTR    SUBD    0,X

you'll notice that, in the 6800 source, it was a very short routine to subtract whatever X pointed to from D. Every call to SUBTR in the source for the 6801 can be replaced with the actual body of the subroutine, with no increase of code size. You can search for BSR SUBTR and JSR SUBTR and replace each with SUBD 0,X. (I don't think there will be any JSR SUBTR, but if there are, you can.)

[202209111229: add end]

[JMR202209231810: add]

I have written up a post on VTL expressions, here: https://joels-programming-fun.blogspot.com/2022/09/short-description-vtl-2-expressions-very-tiny-language-p1.html , which will help in testing and otherwise making use of the language. I should also shortly have a post up introducing programming in VTL-2.

[JMR202209231810: add end]

[JMR202210011737: add]

I now have my work on VTL-2 up in a private repository:

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

There is a downloadable version of VTL-2 for the Tandy MC-10 (6801) in the stock 4K RAM configuration in there, with source, executable as a .c10 file, and assembly listing for reference. Look for it in the directory mc10:

https://osdn.net/users/reiisi/pf/nsvtl/files/

[JMR202210011737: add end]

 

Friday, August 12, 2022

VTL-2 part 2, Moving the Variables Out of the Direct Page

Swtpc6800 en:User:Swtpc6800 Michael Holley, Public domain, via Wikimedia Commons

 

In my previous post on VTL-2, I described how I got Very Tiny Language running on Joe H. Allen's EXORsim simulator. I noted in that post that the use it makes of the entire direct page address space would likely cause conflicts with many run-time operating environments. 

I'm not sure how much of a problem on 6800 systems this will be, but I know it will be a problem on any 6801 system that doesn't map the built-in peripherals completely out of the memory map.

So, preparatory to working through the code to optimize it to the 6801, and in an effort to understand some things that will be necessary in transliterating the code for the 6809, I worked out how to move the variables out of the direct page. It was actually quite a bit easier than it could have been.

To make it easier to take a diff to see what I have done, I'll include links to the previous two paste buffers:

  1. Adding semicolons to make it easier to assemble accurately:
    https://osdn.net/users/reiisi/pastebin/8440
  2. Modifications for EXORsim (and EXORciser):
    https://osdn.net/users/reiisi/pastebin/8441

And this is the version with the variables moved out of the direct page:

https://osdn.net/users/reiisi/pastebin/8474

[Work in progress here, left live to help integrate with paste buffer.]

A brief rundown of the changes (if not how I figured them out) --

The original uses a number of magic numbers -- 72, $87, and several implicit zeroes (NULL vectors). I added definitions to the code that clarified what those magic numbers mean and made it easier to redefine them. 

The most important of those was ZERO, which, in this version, is no longer $0000.

The next most important was BUFOFF, which is $88. This allows the code to be explicit about what it is doing with the index register at several important points, particularly where ZERO was implicitly $0000.

One of the problems I had getting the original version running was the problem of initializing two variables that are necessary for the program to know where it can store VTL program code for editing and running: 

  • & (AMPR in the assembler) to 264 and 
  • * (STAR in the assembler) to something like the end of your RAM.

Running the original, the user was required to set those by hand because the assumption was that you would get a ROM and plug it into your single-board computer or system, and the ROM code would not be able to know how much RAM it could use and where it would end.

The assumptions change here. Now we assume that you will assemble this to run on whatever you want to run it on. So the source code can set AMPR for you, and can probe to set STAR for you. 

Comment that code out, or simply jump to START instead of COLD if you don't want to do that. And remember to set those yourself.

More details:

At line 33, set the source code to start at address $200 instead of address 0. This address can be moved, but be aware that, in order to keep the code simple, the code assumes that the lower  byte of this address is 0. In other words, wherever you move it, it must be to an address evenly divisible by $100. 

(In case you are unfamiliar with Motorola assemblers, $prefix makes it hexadecimal base: $100 is 100sixteen, or 256ten.)

At line 81, SAVOFF was something I decided I didn't want to do. It's commented out, ignore it. 

From line 84, I mentioned the magic numbers for LINBUF and BUFOFF above, read the comments for details. Note that BUFOFF is actually $88, but it is used every as BUFOFF-1. No biggy.

From line 88, I moved the stack. No big deal. Remember that the bottom of the allocation area is the limit of the stack, and the stack pointer gets initialized to the top.

In particular, and this is important, note that on the 6800 and 6801 the stack pointer is always pointing to the next available byte, not to the last byte pushed. In other words, the CPU stores a byte where S is pointing, then decrements, ready for the next byte. And it increments before popping (PULing) the most recently pushed byte.

Note especially that this is different from the 6809, which always points to the last byte pushed, or to one beyond the stack.

(POP vs. PUL. Motorola used a different jargon from the most visible literature. In the most visible literature, PULL is associated with queues -- first in, first out. POP is for stacks, last-in/first-out. In Motorola 8-bit assemblers, however, POP is PUL. Think about it. The most common metaphor was a stack of trays at the lunchroom. You don't POP a tray off the stack, you PULL it off, whether at the top or the bottom. Confused? Study stacks and queues. It will all become clear -- eventually. Someday, I'm going to write a runtime library that will help clarify this. Sometime before I die, God willing.)

Line 91 sets up the beginning of the area where VTL stores lines of code (and leaves its single array allocated, if you use that).

Line 99 is where the code starts, I mentioned COLD vs. START above. 

Line 232 is just a place where the extra code size required because the variables are no longer in the direct page moved a branch target out of range. On the 6800/6801 there is no long branch, so we invert the test and follow with a JMP to the target, instead. Not a meaningful change.

Note its proximity to the machine language stuff, which did not require changes, somewhat to my surprise.

Well, basically, if you put some machine language stuff in there, you're going to need the monitor to support you through the way it handles SWI. My changes should not affect that.

Line 439 is more branch target out of range, but there's no condition, so it's just changing a BSR to a JSR.

From line 452 is the key change, very dependent on making ZERO explicit. (See also lines 591, 595, and 597.) Read the comments in the code, note that I commented out the most obvious code and used instead the math mentioned above that depends on ZERO being declared at an even 256-byte boundary. (I'm trying to avoid pushing the capabilities of your assembler of choice too far. Also procrastinating about making my assembler more conformant to current assemblers.)

The comments on 591, 595, and 597 explain again why I got rid of the magic numbers and used explicit labels.

Note the puzzle at line 541. I'm not the one who said, What? I'll explain more carefully in my post of the optimization for the 6801.

And that should cover this step in the project.

Well, actually, it's tempting to back up here and post another version, bringing in the progress from the 6801 version: in other words, 

  1. without the CPX trick at line 541, using an explicit branch around instead, 
  2. using a non-stack-blast method of inserting and deleting lines,
  3. and giving the temporary SAVEnn variables meaningful names.

But I'll postpone that, with a few comments: 

If you want to do an automatic (or mechanical manual) conversion of 6800 source code to 6809 source code, at a minimum, the CPX trick must be replaced with an explicit branch around, as I have done in the 6801 optimizations. Moving the variables out of the direct page, as I've done here, should help, since the implicit linkage becomes explicit. I'm not sure whether the stack blast will survive the conversion, so you might want to bring that in from the 6801 optimizations.

[I may be able to come back to finish this up, or I may not. I do think the 6800 version needs more work.]

[JMR202209231810: add]

I have written up a post on VTL expressions, here: https://joels-programming-fun.blogspot.com/2022/09/short-description-vtl-2-expressions-very-tiny-language-p1.html , which will help in testing and otherwise making use of the language. I should also shortly have a post up introducing programming in VTL-2.

JMR202209231810: add end]

[JMR202210011737: add]

I now have my work on VTL-2 up in a private repository:

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

There is a downloadable version of VTL-2 for the Tandy MC-10 (6801) in the stock 4K RAM configuration in there, with source, executable as a .c10 file, and assembly listing for reference. Look for it in the directory mc10:

https://osdn.net/users/reiisi/pf/nsvtl/files/

[JMR202210011737: add end]

 

Sunday, August 7, 2022

Adventures Getting VTL-2 (Very Tiny Language) Running on EXORsim

I don't think I really had this much spare time, but there was a question in the 6809/6309, 6800 programming language Facebook group about getting or building a version of VTL-2 (Very Tiny Language) for the 6809. 

There were a couple of guys working on this. You can check David Wiens post and John W. Linville's post for the progress they've made so far.

This kind of thing piques my curiosity (... killed the cat, as they say).

So, for the past several weeks, part of what little spare time I have has disappeared down this rabbit hole, and I'm now bringing back some results. Nothing for the 6809, just yet, but some results.

First thing I did, since the assembly language sources they have for the 6809 came from someone working with a very perverse syntax assembler, and since I don't like the way other people write 6809 code, etc., was go looking for a base line source, something that runs with known results.

A little history:

As near as I can tell (from copyright dates on manuals and in source code, etc., and from the manuals themselves), the original VTL and VTL-2 came to life on the 6800-based MITS ALTAIR 680, motivated (as I understand it) in no small part by the lack of manufacturer options for the 680.

VTL was a minimal programmable calculator-style language that would run from a very small ROM on a 680 with minimal memory expansion. 

After making VTL-2 available for the 680, responding to interest from the larger, more established market for the 8080-based ALTAIR 8800, the authors, Gary Shannon and Frank McCoy from The Computer Store, re-implemented it for the 8800.

Thus, there are two base versions of the source code and manual for VTL-2, one for the 680 and the other for the 8800.

After that, versions for the 6502 and some other CPUs, and, ultimately, versions in C, were produced by others. If you go looking for source code now, the easiest to find is for the 6502.

I suppose I should leave links to everything I found, but I was tired after work and not keeping records. I think deramp.com and altairclone.com were among the places I visited. 

But where I finally started getting traction was T. Nakagawa's page on VTL. Down the page a ways is a link to a zip file containing a C language implementation of VTL that is straightforward to compile on *nix (and some other platforms). (Yes, his pages are mostly Japanese. Use Google Translate if you need to.)

Now I had something running to test my understanding of the manuals I had found elsewhere. (There is a searchable PDF version of the manual for the ALTAIR 680 down towards the bottom of his page, too. Easier to read and more complete than what I had been reading for the 680.)

He also has a table of memory usage for the VTL variables in his implementation, which is useful (though not definitive) in understanding how the microprocessor versions work. And the C source code is also useful in decrypting things under the hood in VTL.

And he has a link to Jun Mizutani's Return of Very Tiny Language page, which has a link to his very useful history and comparison of major versions table, where I finally rediscovered the command to list out the program you're typing in. On the 6800 versions, it's generally a zero typed by itself on the command line. Yes. 

0

LOL.

And somehow (I don't remember how), I found the sbc6800 page on switch-science.com. Inside the software for the sbc6800, there is clean source for VTL-2 that almost works with my tools. 

Almost. My assembler allows whitespace in operand expressions, which means you really need a leader character for comments to make sure that in lines like

VAR    CMPB    #'$    OR STRING

don't end up trying to use the OR of the character $ and the label string as the operand. 

I need to fix that sometime, put in a switch to shut off whitespace in operand expressions. Another project for the back burners.

Switch Science has a sbc6809, as well, but there is no VTL in the software for that. Maybe we can fix that.

Okay, so I used semicolon for the comment leaders and inserted them by hand. Good thing VTL is really tiny. Took me less than a half hour, I don't remember how much less. (Paste buffer on my OSDN pages.) 

But I don't have an sbc6800. I should probably get one, but not yet. I do have Joe H. Allen's EXORsim simulator for Motorola's EXORciser running, however. And the fun begins. 

First I had to move the code for the VTL interpreter down from $FC00, where it was set up to assemble in the source code, to some place that doesn't conflict with the EXORciser monitor and system object code. I moved it to $7800.

Then I patched the I/O calls and had to figure out why I wasn't getting any output from EXORsim. 

For some reason, it turns out that I have to hit the output port about thirty times before things start showing up. I should ask Joe about that sometime. I added code to do that in an initialization routine. (Paste buffer.) Not a lot of changes yet, use diff if you're interested in seeing what I added. Oh. I think there were also a couple of branches that were no longer in range, which I changed to appropriate jumps.

I was expecting there were going to be problems with using all of the direct page for VTL's variables and stack. There will be conflicts if I try to assemble a version that works under a disk operating system.

But with the I/O patched and the code moved down, it worked as a simple calculator. Trying to enter a program, however, did not produce happy results. Crashing, freezing.

After spinning my wheels for a couple more days, I began to become sure that it was just something about VTL itself that I was missing. Specifically, looking in the code, there are two system variables that I didn't see getting set any place in the code -- program base & and end * address. So I went back and worked my way through the manual with both VTL-2 on EXORsim and and VTL-C, and there it was, towards the end of the manual --

The microprocessor versions of VTL require one more step of initialization after you get the interpreter running and before you start typing in programs. 

The variables in question are & and *, the program space base and the end. 

264 should work for the base, per the manual. I used 300 to be safe. Look for the PRGM label in the source code to see what's going on. (Really, there should be no problem setting that automatically in the code, but I guess the authors were saving every byte they could for the user program space.) 

The end depends on how much RAM you have installed and where you assemble the interpreter. It ought to work as large as 30719 ($77FF), but I used 8192 to be sure. (This could be probed and set, but it would take probably ten to twenty bytes to do a simple probe. Or you could just hard code it so you don't forget, and remember to reassemble if your memory layout changes.)

So, to get it running in EXORsim, copy the code from the paste buffer, save and assemble it, open the S1/S9 object in the source.x file in a text editor. Something like

asm68c -l1 vtl_6800_exorciser.asm > vtl_6800_exorciser.list
gedit vtl_6800_exorciser.list vtl_6800_exorciser.x

Run exorsim in a terminal session, something like

./exor --mon

You should have a starting message and a reminder you can type help, and the % prompt, at which you give the load command:

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'
%  l

Don't forget to hit return after the load command. (The load command is the lone "l" you type in after the % prompt on the last line I just showed.)

It will wait for you to feed it S-record object code, so go to the object file in the text editor and select and copy the whole of the S1/S9 object as text:

S1090000000000000000F6
S113000600000000000000000000000000000000E6
S113001600000000000000000000000000000000D6
S113002600000000000000000000000000000000C6
S11100360000000000000000000000000000B8
S113004400000000000000000000000000000000A8
S11300540000000000000000000000000000000098
S11300640000000000000000000000000000000088
...
S10C7AF8C60D8D02C60A7E7B1B3B
S1087B010D0A4F4B00CA
S10C7B06C628BDF0215A26FA3903
S1087B0FF6FCF45739F7
S10A7B1436BDF012163239F0
S10A7B1B3617BDF0183239E2
S903780084
Paste it into the exorsim session. It'll just paste in like the above. Hit the return key once at the end and it should say

PC set to 7800

Now hit CTL-C to get out of load mode, and at the % prompt type

% c 7800

or just "c" (continue), since it should have set the PC to 7800 for you anyway. And hit return. It should give you some empty lines and then the OK prompt.






OK

 at which you need to set the base and end. Type

&=300
*=8192
at the OK prompt. (Woops, not 300, see edit below.) Or you should be able to get away with
OK
&=264

OK
*=16*1024

OK

And it should run and allow you to type in programs.

[JMR202208092108: add]

After some study, it appears that the program area base variable needs to equal the assembler PRGM label for listing and program editing to work. In other words, the 6800 versions need to write

&=264

[JMR202208092108: add end]

[JMR202209231810: add]

I have written up a post on VTL expressions, here: https://joels-programming-fun.blogspot.com/2022/09/short-description-vtl-2-expressions-very-tiny-language-p1.html , which will help in testing and otherwise making use of the language. I should also shortly have a post up introducing programming in VTL-2.

JMR202209231810: add end]

My next step is probably to move the interpreter variables out of the direct page ...

[JMR202208131113: add]

I've got this done, see part 2 here: https://joels-programming-fun.blogspot.com/2022/08/vtl-2-part-2-moving-variables-out-of-direct-page.html

[JMR202208131113: add end]

... so I can optimize it for the 6801 (which usually has I/O at the bottom of the memory map)

[JMR202208140202: add]

And this is now done, see part 3 here: https://joels-programming-fun.blogspot.com/2022/08/vtl-2-part-3-optimizing-for-6801.html

[JMR202208140202: add end] 

... and then assemble it to run on the MC-10.

After that, if Dave and John haven't made any more progress, I'll see if I can make a quick transliteration to 6809.

[JMR202210011737: add]

I now have my work on VTL-2 up in a private repository:

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

There is a downloadable version of VTL-2 for the Tandy MC-10 (6801) in the stock 4K RAM configuration in there, with source, executable as a .c10 file, and assembly listing for reference. Look for it in the directory mc10:

https://osdn.net/users/reiisi/pf/nsvtl/files/

[JMR202210011737: add end]