• Stars
    star
    105
  • Rank 328,196 (Top 7 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created about 15 years ago
  • Updated over 9 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

CPU design and toolchain for a simple computer architecture

SUBLEQ (SUbtract and Branch if Less than or EQual to zero) is a type of OISC (One Instruction Set Computer) / URISC (Ultimate Reduced Instruction Set Computer) architecture. It has only one instruction of the form:

A B C

This is equivalent to the following pseudocode:

mem[B] = mem[B] - mem[A]
if mem[B] <= 0 then goto C

Compound instructions, such as addition, can be formed from sequences of these simple SUBLEQ instructions. For examples of these, see the source files - most compound instructions include a comment about their function. Indirect addressing (pointers) can be emulated through self-modifying code, where operations are performed on the instructions themselves. See (1,2,3,4,6) for further information.

This project consists of four main parts:

  • a CPU capable of executing SUBLEQ instructions
  • libraries for programs written in SUBLEQ assembly, and a demo program to demonstrate these
  • a minimal SUBLEQ interpreter (with I/O) written in C
  • JSubleq: a SUBLEQ interpreter written in JavaScript

CPU

Schematics for a SUBLEQ-based CPU are provided.

CPU schematic

A recent version of Logisim is required to simulate the CPU. Simulation instructions are provided below.

There are three main buses in the CPU:

  • A bus: contains the address of the current memory location
  • B bus: contains the output of the ALU
  • D bus: contains the data read from memory

The CPU has six control signals:

  • MAR: the Memory Address Register should be updated with the value of the D bus at the end of this cycle
  • PC: the Program Counter should be updated at the end of this cycle
  • JMP: the PC should be loaded with the value of the D bus at the end of this cycle if the LEQ flag has been set by the ALU, otherwise PC is just incremented if either JMP or LEQ are false
  • RD: the value of MAR should be loaded onto the A bus, otherwise it is loaded with the value of PC if RD is false
  • WR: the value of the B bus should be stored to memory at the end of this cycle, and the value of the LEQ flag should be updated
  • A: signals that the "A" operand is currently on the D bus, so the A register should be updated at the end of this cycle

These signals are controlled by a 5-microinstruction microprogram which runs in a continous loop. The signals enabled by each of these microinstructions are:

  1. MAR, PC: load mem[PC] (address of A operand) into MAR, increment PC
  2. RD, A: load mem[MAR] into the A register
  3. MAR, PC: load mem[PC] (address of B operand) into MAR, increment PC
  4. RD, WR: load mem[MAR] onto the D bus, then write the value of the B bus (equal to the value of the D bus minus the value of the A register) into mem[MAR]
  5. PC, JMP: if the LEQ flag is set (the result of B-A was less than or equal to zero) then set PC to mem[PC] (the C operand) i.e. jump to C, otherwise increment PC

Input/output is performed through memory-mapped I/O, with the I/O driver mapped to address 0xffffffff (-1). If the A signal is enabled, then reading from this address returns the negation of the next input character. If the A signal is not enabled, then the value 0xffffffff is returned. Writing to this address prints the character obtained by performing a bitwise NOT on the value of the B bus. This behaviour allows the following I/O instructions to be performed:

  • (-1) X: add the input character to X (X -= -input)
  • X (-1): output the character in X (subtracting X from 0xffffffff gives NOT X, then performing a NOT on this yields the original X)

Jumping to address 0xffffffff (-1) disables the clock signal, effectively halting the CPU.

Simulation

To simulate the CPU:

  1. open cpu.circ in Logisim
  2. increase the simulation speed: Simulate > Tick Frequency > 1024 Hz
  3. load a program: to run the demo program, first make sure you have run make in the project root directory, then right-click the component labeled "RAM" > Load Image... > ../image.hex
  4. start the simulation: Simulate > Ticks Enabled
  5. make sure you're using the hand tool, and select the component labeled "Input" by clicking on it
  6. interact with the program as you would with any other console-based application
  7. if the clock line turns blue, it means that the program has halted
  8. to stop the machine, uncheck Simulate > Ticks Enabled, then press the reset button labeled "R"
  9. repeat from step 3 if necessary

Libraries/Demo

Libraries for programs written in SUBLEQ assembly, as accepted by sqasm, are available.

They provide several common functions:

  • getint (read integer from input)
  • gets (read string from input)
  • putint (write integer to output)
  • puts (write string to output)

Several useful procedures are also available:

  • bubblesort (sort a string of characters)
  • calc (perform a given operation on two integers)
  • factorial (calculate the factorial of a positive integer)
  • primes (generate and print a list of primes)

Usage information and equivalent C code (where appropriate) is provided in the comments of each of these files.

A menu-driven program demonstrating the above libraries is also provided. Simply call make run in the project root directory to run the demo program.

Interpreter

A very minimal (only 222 bytes in size) SUBLEQ interpreter written in C is available:

#include<stdio.h>
main(int C,char**A){FILE*F=fopen(A[1],"r");int P=0,_[9999],*i=_;while(fscanf(F,
"%d",i++)>0);while(P>=0){int a=_[P++],b=_[P++],c=_[P++];a<0?_[b]+=getchar():b<0
?printf("%c",_[a]):(_[b]-=_[a])<=0?P=c:0;}}

It has been somewhat obfuscated to reduce the code size, so a more readable version is also provided. It should function similarly to sqrun.

JSubleq

This terminal demonstrates the JavaScript interpreter running the provided demo program.

More Repositories

1

lljvm

Low Level Java Virtual Machine
Java
441
star
2

pandiff

Prose diffs for any document format supported by Pandoc
TypeScript
274
star
3

jasmin

Jasmin is an assembler for the Java Virtual Machine ⛺
Java
158
star
4

tensor

Cross-platform Qt5/QML-based Matrix client
C++
156
star
5

pixelstruct

a tool for visualising 3D scenes reconstructed from photographs
C++
45
star
6

TeX.js

TeXify: Typesetting for the Web
HTML
44
star
7

c-hashtable

Git mirror of the hash table data structure in C by Christopher Clark ⛺
C
44
star
8

eigenGPT

Minimal C++ implementation of GPT2
C++
39
star
9

scholarpedia

An outdated Scholarpedia mirror
37
star
10

ipfs-maps

OSM vector tiles on IPFS
CSS
29
star
11

dblp.yaml

DBLP in citeproc-yaml format
TeX
27
star
12

hs-ipfs-api

A Haskell client library for the IPFS API
Haskell
26
star
13

hubot-matrix

Matrix adapter for hubot
JavaScript
26
star
14

sdbm

Git mirror of sdbm source code ⛺
C
25
star
15

pyzui

PyZUI is an implementation of a Zooming User Interface (ZUI) for Python.
Python
19
star
16

stochaskell

Haskell
10
star
17

fpgatoy

Shadertoy for FPGAs
Verilog
9
star
18

gvwin

Shell
9
star
19

librtneat

A cleaned-up distribution of rtNEAT
C++
9
star
20

cspeak

C
8
star
21

mfc7400c

Implementation of the Brother MFC-7400C scanning protocol
C
7
star
22

aspi

Answer Set Programming, Interactively
Python
7
star
23

iccsh

Interactive C Compiler Shell
C
7
star
24

bib

Command-line bibliography manager
Python
6
star
25

polya

Hierarchical Bayesian Nonparametrics (Python/C++)
C++
6
star
26

latex-glassware

5
star
27

tp

SCSS
5
star
28

datum

Datum is a simple question answering system.
Java
4
star
29

texfonts

OpenType fonts included in TeX Live
CSS
4
star
30

librw-web

WebAssembly build of librw, with TypeScript bindings
TypeScript
4
star
31

dff2gltf

Converts DFF models to glTF, based on OpenRW
C++
3
star
32

deciban

3
star
33

latex-circuit

3
star
34

bootsh

Bootstrappable, self-hosting POSIX shell
C
3
star
35

blog

archive of my old blog
3
star
36

streetcar

C#
2
star
37

classfileanalyzer

Analyzer and Disassembler (Jasmin syntax 2) for Java class files
Java
2
star
38

davidar.github.com

My GitHub Page
HTML
2
star
39

cosmetic-filter

Basic cosmetic / element hiding filtering
JavaScript
2
star
40

toki-ante

CSS
2
star
41

3dglobe

PHP
2
star
42

jclassification

Java implementation of Support Vector Machine (SVM) and multi-layer neural-network, for supervised classification
Java
2
star
43

pytextcat

Python
2
star
44

rtneatbox

rtNEATbox is a simple neuro-evolution sandbox.
C++
2
star
45

fragx

GLSL Fragment Shader Executable Compiler
Python
2
star
46

pandoc-lang

Pandoc filter to detect the language of text
JavaScript
2
star
47

django-tabs

Git mirror of the django-tabs svn repository
Python
2
star
48

candc-docker

Docker image of C&C parser and Boxer
C
2
star
49

django-codehilite

Codehilite (source code syntax highlighting) template filter for Django
2
star
50

etc

Perl
1
star
51

glsl

https://www.shadertoy.com/user/davidar
GLSL
1
star
52

base-data

Python
1
star
53

fsimage

Shell
1
star
54

nodejs-sh

Call any program as if it were a Node.js function
TypeScript
1
star
55

bearssl

C
1
star
56

da.vidr.cc

Source code of da.vidr.cc
Java
1
star
57

blue-lacuna

Inform 7
1
star
58

obsidian-lacuna

Logseq graph of the island in Blue Lacuna https://blue-lacuna.textories.com/source.html
1
star
59

cutil

Various utility functions for C
C
1
star
60

django-helloworld

Django template tag that displays "Hello World!" in one of over 50 different languages
Python
1
star
61

docker-csx

Dockerised CiteSeerX
1
star
62

sdl-cube

C++
1
star
63

django-recurse

Git mirror of the recurse template tag by Lucas Murray
Python
1
star
64

django-quotes

Django template tag that displays a random quote
Python
1
star