name: SIC author: Alain Brobecker (abrobecker@yahoo.com) size: 504 bytes needs: Arm2 + RiscOS 2 descr.: Emulator for a Single Instruction Computer ---------------------------------------------------------------------------- Files included in this directory are: SIC ;Single Instruction Computer emulator ReadMe ;Guess More.MkSIC ;Sourcecode for SIC, requires a Ramdisc More.asmsic ;SIC assembler More.add ;Sample SIC program, asks two numbers and adds them More.fact ; ", asks a number and returns its factorial More.primes ; " ,lists all primes between 2-127 More.simple ; " ,asks a number and prints it More.umul ; " ,asks two positive numbers and muls them More.???X ;Compiled programs 0. 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 implementation for CodeCraft 2. 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! 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. In such case, the few examples will change your mind! 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. 1. SIC 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: * Try to know what possible sign(s) the result of an operation will have. If it will always positive, then the C byte can be used as a variable. I do this very, very often, and the labels are very handy for this. * The result of 127+1 is -128, with a negative sign! The same kind of statement applies for 126+2 and -128-1... * It is really convenient to have the NUL (0), INC (-1) variables defined in the code, so that "INC NUL BranchLabel" will be a branch always instruction. And since you will probably have a 255=-1 somewhere in the program to quit or print, you already have INC for free. 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