#######################################################################
"Educational Virtual Computer - Simple Byte Machine (SBM) 
        and its implementation in python"
                   Author: Sang Cho Ph.D., Professor at ChongJu University, S. Korea
                           sangcho@cju.ac.kr
--------------------------------------------------------------------------------------
 This document is put into public domain by the author.                   2005-01-23 
=======================================================================================
 
 
SBM consists of CPU and 3 Memories and Keyboard and Screen.

Instructions of SBM consists of two parts: 
5-bit Opcode and 11-bit Address thus which gives the following possible
memory spaces.
   2K instructions of Program Memory 
   2K words  of Data Memory    
   2K words  of Stack Memory   

Components of SBM

ACC   :  16-bit Accumulator 
AUX   :  16-bit Auxiliary Accumulator 
PC    :  11-bit of Program Counter
SP    :  11-bit of Stack Pointer
XP    :  11-bit of Stack Pointer
memP  :  2K instructions of Program memory
memD  :  2K words of Data memory
memS  :  2K words of Stack memory
BFR   :  memD[0..5] First 6 words of memD for decimal binary conversion
KBD   :  Keyboard - input device
SCR   :  Screen   -  output device

a word is 16 bit and can hold 16-bit signed integer 
or (zero extended) ascii code 

Instruction formats
All instructions are 16-bit format.
   Type 1 : 5-bit Opcode, 11-bit filler
   Type 2 : 5-bit opcode, 11-bit address
   Type 3 : 5-bit opcode, 11-bit value 
   Type 4 : 5-bit opcode, 11-bit delta

       address : unsigned 11-bit integer
       value   :  signed   11-bit integer
       delta   :  signed   11-bit integer

#######################################################################

Operation Machine Code       Meaning
--------- ------------ ------------------------------------
   NOP       00000        No operation  
                          PC <- PC + 1
   GET       00001        Read 1 byte ascii code from KBD to ACC
                          PC <- PC + 1
   PUT       00010        Write 1 byte ascii code from ACC to SCR
                          PC <- PC + 1
   DCA    00011 value=1   Convert ACC to decimal into BFR
                          PC <- PC + 1  
   DCLR   00011 value=2   Clear BFR with spaces
                          PC <- PC + 1
   BIN       00100        Convert BFR to binary into ACC
                          PC <- PC + 1
   SETV   00101 value     ACC <- value
                          PC <- PC + 1
   SWAP      00110        Swap AUX and ACC
                          PC <- PC + 1
   LDA    00111 address   Load 1 word from memD to ACC
                          ACC <- memD[address]
                          PC <- PC + 1
   STA    01000 address   Store ACC to memD
                          memD[address] <- ACC
                          PC <- PC + 1
   LDAI   01001 address   Load indirect 1 word memD to ACC
                          naddress <- memD[address]
                          ACC <- memD[naddress]
                          PC <- PC + 1
   STAI   01010 address   Store indirect ACC to memD
                          naddress <- memD[address]
                          memD[naddress] <- ACC
                          PC <- PC + 1
   ADD    01011 address   Add 1 word memD to ACC
                          PC <- PC + 1
   SUB    01100 address   Subtract 1 word memD from ACC
                          PC <- PC + 1
   MULT   01101 address   Multiply 1 word memD to ACC
                          PC <- PC + 1
   DIV    01110 address   Divide ACC by 1 word memD 
                          PC <- PC + 1
   INC    01111 address   Increment 1 word memD by 1  
                          PC <- PC + 1
   DEC    10000 address   Decrement 1 word memD by 1
                          PC <- PC + 1
   AND    10001 address   Logical and of 1 word memD to ACC
                          PC <- PC + 1
   OR     10010 address   Logical or of 1 word memD to ACC
                          PC <- PC + 1  
   XOR    10011 address   Logical xor of 1 word memD to ACC
                          PC <- PC + 1  
   NOT       10100        Logical invert of ACC
                          PC <- PC + 1
   JMP    10101 address   Unconditional jump to address
                          PC <- address
   JMPZ   10110 address   When ACC=0 jump to address
                          if ACC=0 PC <- address
                          else PC <- PC + 1
   JMPP   10111 address   When ACC>0 jump to address
                          if ACC>0 PC <- address
                          else PC <- PC + 1
   JMPM   11000 address   when ACC<0 jump to address
                          if ACC<0 PC <- address 
                          else PC <- PC + 1
   CALL   11001 address   Subroutine call to address
                          SP <- SP - 1, memS[SP] <- PC + 1
                          XP <- XP - 1, memS[XP] <- SP
                          SP <- SP - 31   # reserve 31 word for local variable
                          PC <- address
   RET      11010         Return to the calling point
                          SP <- memS[XP], XP <- XP + 1
                          PC <- memS[SP], SP <- SP + 1
   PUSH     11011         Push ACC into stack
                          SP <- SP - 1, memS[SP] <- ACC
                          PC <- PC + 1
   POP      11100         Pop ACC
                          ACC <- memS[SP], SP <- SP + 1
                          PC <- PC + 1
   XLDA   11101 delta     Load stack memory to ACC
                          PC <- PC + 1
   XSTA   11110 delta     Store ACC to stack memory
                          PC <- PC + 1
   HALT     11111         Stops exceution 
                          PC will not be incremented  

#######################################################################

Format of Assembly language for SBM

DATA Mydata
    <data declare>
END Mydata

PROGRAM Hello
    <program body>
END Hello

FUNCTION Fact
    <function body>
END Fact

<data declare>
    x: WORD          # This is a variable x of type WORD
    y: WORD  = 100
    c: CHAR     
    d: CHAR* = "A",0
    s: CHAR* = "Hello World!",0
    Buf: WORD*100 

<program body>, <function body>
    label1:        # This is first label
        LDA   n     # Load value in variable n into the accumulator
        ADD   a
        STA   n
        DCA
        LDA   BFR+4   # simple additon to the variable is allowed
        PUT
        LDA   BFR+5
        PUT
        JMP label1
    label2:
        RET
        CALL Fact

comment starts with # and ends at the end of line.
id: when it is used in program body id is a label and 
when it is used in data declare id is a variable.


#######################################################################
HOW TO RUN SBM
================

prompt:>python sbm.py
Input file: asm1.s<enter>

You only need to type asm1.s and <enter>   
(or asm2.s or asm3.s or asm4.s)


p/s

This SBM is ideal for beginners who want to be a programmer.
It is intentionally designed as machine w/o interrupts.

You can see this machine captures the essense of C language
very closely.

I am proud of my work. This works have been done only a week period.
I love python. This work is my first big python project.
I have some experience in CPU emulation and disassembler business.

If you have any suggestions or questions please give me e-mail.
