__
            _____       |__|            _____
           |__  -|      |  |           |  ___|
           |_____|ingle |__|nstruction |_____|omputer  -  implemented by Alain Brobecker

SIC basics

You've heard about the CISC (Complex Instruction Set Computer) vs RISC (Reduced Instruction Set Computer) competition. Ross Cunniff pushed the idea a bit and designed a One Instruction Set Computer (OISC). I liked the idea and coded this little Acorn implementation for the CodeCraft 2 coding competition.

The instruction is "substract and jump if negative", and has three operands: A, B, and C. The instruction will load the content at adress A, substract the content of adress B from it, store the result in adress A and if the latter is negative, jump to C. Here's an example:

  0: 10  11   6         ;[10]=[10]-[11]=7-4=3, >=0 so continue with 3
  3:  0  10   12        ;[ 0]=[ 0]-[10]=3-7=-4, <0 so jump to 12
     ...
 10:  7
 11:  4
     ...

Believe it or not, you can write any program you can dream of with this single instruction. Well, almost any program, it lacks little things like graphics... ;) And it's small, too! For example the program to list all primes between 2 and 127 is only 36 bytes long!

;primes - list all primes between 2 and 127
; Alain Brobecker (baah/Arm's Tech)
; 07-Aug-1999

;N is the number we are checking
;D is the opposite of the divisor
;M is the modulo

PrimeLoop:
  D   D   D:0           ;D=0
  D   0   *+1           ;D=-2
OneDivisor:
  M   M   M:0           ;M=0
  M   D   N:2           ;M=-D
  M   N   *+4           ;M=-D-N, if <0 then N>-D so continue
  INC NUL PrintPrime    ;Otherwise N is a prime
SearchModulo:
  M   D   SearchModulo  ;M-=D, if <0 then N>k*-D
  M   DEC NotAPrime     ;If modulo is zero then N is not a prime
  D   DEC OneDivisor    ;D-=1 is always negative

PrintPrime:
  255 N   DEC:1
NotAPrime:
  N   INC INC:255       ;N+=1, quit if <0 (ie bigger than 127)
  INC NUL NUL:PrimeLoop ;INC=-1, so go to PrimeLoop

This implementation of the emulator has some small differences over the original design by Ross Cunniff. First, memory is only 256 bytes, ie 85 instructions + one extra byte. Then the byte 255 (the extra one ;) has a special meaning, because when PC=255 the program stops, and it's also used for I/O handling:

   255   B   C        ;outputs [B] on screen and goto C if B<0
     A 255   C        ;ask user for [A] and goto C if A<0

Note that "255 255 C" will print the byte at adress 255 (most likely garbage), but won't ask the user to enter one.

Here's a simple SIC program, which reads a number, prints it out and then quits the emulator:

  0:   0 255   3      ;[0]=IN, then goto 3
  3: 255   0   6      ;OUT=[0], then goto 6
  6:   4   2 255      ;[4]=[4]-[2]=0-3=-3<0, so jump to 255 and STOP

You might be skeptical that *ANY* program can be written with this system, but it has been proven to be Turing-complete. If you stil doubt, the provided examples will change your mind!

SIC usage and programming

To run a program, just type "SIC FileNameX" in the CLI or in a TaskWindow. If you launch SIC without parameters, it will run the hardcoded program (primesX). If you add an extra "*" in the command line (like "SIC * FileNameX") then the emulator will run in "debug" mode. All this in 504 bytes! ;)

As for programming, err, are you sure? Really sure? It took me a whole hour to design the primes program, and i must say SIC programming is even worse than SockZ programming! ;).

Still there? Okidoki, then i'll briefly present asmsic (designed in less than one hour, basic rules! ;) which tries to ease things a bit. To use it, type "asmsic source" in the CLI. If the assembly went ok, it will produce a file called "sourceX". Now for a small example:

;This is a comment, and is finished by LF
label:              ;Labels *MUST* finish with :
  255 A   A:3       ;Will print the number at adress A=2, ie 3
  A   255 6         ;Asks for a number and put it in A
  A   255 *+1       ;*+1 stands for current adress+1, ie 8+1=9
  *   *   255       ;Same as 9 10 255, which quits because [9]-[10]=9-10<0

It will be assembled as:

  0: FF 02 03
  3: 02 FF 06
  6: 02 FF 09
  9: 09 0A FF

I don't know if this is enough to understand how the assembler works, but if you have any doubt, just have a look at the examples provided.

Now some hints/rules for SIC programming:

2.Slightly Insane Concept

The original OISC program (written in C) has been designed by Ross Cunniff and might be of some interest. It features a 16 bits memory model, and has a better assembler able of handling macros. Some parts of this text come from his documentation.

A port exists for Acorn computers at http://www.armada-fr.net/

cu, Alain