Tuesday, May 12, 2020

Time to write some programs!

With the CPU implementation completed, it's now time to write some programs. For starters we will take a simple program:

r = 20 + 22
print r

Using the Scott CPU and the differents levels of languages I've implemented, we can achieve this in several ways:

Level 1: Machine Code

So the low-level machine instructions to do this operation are as such:

00100000
00010100
00100001
00010110
10000001
00100000
00000001
01111100
01111001
01100001

When fed into the Scott CPU, these instructions will add 20 and 22, select the I/O device 1, which is the equivalent of a teletype, and send the resulting value, 42, to it. The "teletype" will then print the character equivalent to ASCII(42), which is "*".

Coding in machine language is tedious, but since the instruction set can be implemented as a little assembly language, we'll use that instead.

Level 2: Assembly

The "language" described in the book is as such:

ADD   RA, RB
SHR   RA, RB
SHL   RA, RB
NOT   RA, RB
AND   RA, RB
OR    RA, AB
XOR   RA, RB
CMP   RA, RB
LD    RA, RB
ST    RA, RB
DATA  RB, data
JMPR  RB
JMP   addr
JCAEZ addr
CLF
IN    data, RB
IN    addr, RB
OUT   data, RB
OUT   addr, RB

To facilitate coding with it, and to avoid writing a parser, I implemented a small DSL directly in Perl. So the sample program above can now be written like this:

DATA R0, 20 ;
DATA R1, 22 ;
ADD  R0, R1 ;
REM "Activate the TTY device" ;
DATA R0, DEVICES::TTY() ;
OUTA R0 ;
OUTD R1 ;
GOTO "stop" ;
LABEL "stop" ;
HALT ; 

My instruction set is the same as in the book, but I added few things in the assembly language:
  • A HALT instruction, that stop the machine, or else it just keeps incrementing the IAR forever and running whatever is in RAM. I did this by using a sub-case of the CLF instruction, 01100001, which is detected by the computer and stops it.
  • A LABEL instruction, which identifies a specific instruction
  • A GOTO instruction, which allows one to jump to a named location (a LABEL) instead of having to calculate manually where that place is
That's better, but we can go a step further and implement a high level language.

Level 3: High-Level Language

Writing assembly is a lot better than writing machine code, but it's still pretty tedious. The next step is to write in a high-level language.
My high-level language, also implemented as a DSL in Perl, has the following features so far:
  • Variables. You can create variables, assign values to them and copy values between them. In the high-level language you can no longer access the registers, you use variables. Variables live in RAM. In order to coexist with the actual program instructions that are also in RAM, variables are allocated starting from the end of RAM going backwards. If ever the instructions meet the variables, you have run out of RAM and an error is thrown.
  • The PRINT($var) function, which prints (the character corresponding to the ASCII code of) the  value of the variable.
With these simple features, the small program from before now becomes:

my $a = VAR(20) ;
my $b = VAR(22) ;
my $c = PLUS($a, $b) ;
PRINT($c) ;

Now it's getting interesting, but there are more features to come... 

No comments:

Post a Comment