CPU-S Simulator

Simulator for the hypothetical CPU mentioned in the materials for Computer Systems at Loughborough University.

Program Memory

Data Memory


When you have a program, click Run to see register states, data memory and output.

Click line numbers in program memory to set breakpoints. When running, if a breakpoint is hit you can continue execution or run instructions one step at a time.


  • IP = 0
  • IR =
  • DP1 = 0
  • DP2 = 0
  • ACC = 0
  • ODR = 0

Data Memory

Output Log

Examples & Instruction Set


Lecture Instruction Set

  • LOAD1 <address> - Load DP1 with <address>
  • LOAD2 <address> - Load DP2 with <address>
  • ADD - Put data[DP1] + data[DP2] in ACC
  • SUB - Put data[DP1] - data[DP2] in ACC
  • MULT - Put data[DP1] * data[DP2] in ACC
  • STORE - Put ACC into data[DP1]
  • JUMP <address> - Set IP to <address> if data[DP1] != 0
  • INPUT "prompt" - Set data[DP1] to prompted number
  • OUTPUT - Put data[DP1] into ODR
  • STOP - Halt program exection

Extra Instructions

  • LSHIFT <steps> - Put data[DP1] << <steps> in ACC
  • RSHIFT <steps> - Put data[DP1] >> <steps> in ACC
  • DIV - Put round(data[DP1] / data[DP2]) in ACC
  • XOR - Put data[DP1] ^ data[DP2] in ACC
  • OR - Put data[DP1] | data[DP2] in ACC
  • AND - Put data[DP1] & data[DP2] in ACC
  • MOD - Put data[DP1] % data[DP2] in ACC
  • INC - Increment data[DP1] in place
  • DEC - Decrement data[DP1] in place
  • OUTPUTCHAR - Like OUTPUT but converts numeric value to ASCII


This is a very rough simulator for the hypothetical CPU brought up in a module at Loughborough university ~2008 called CPU-S. This is not a full emulator, it does not work based on binary opcodes, I have used javascript to make many things easier for me rather than be correct to a low level. I only made this for fun and so I could see what algorithms I could code given the constraints of the limited Instruction Set so you should not expect to be able to pop up the source and see anything fancy going on.

There was a previous version but it stopped being functional in modern browsers when I neglected to keep the code up to standard. I re-wrote this in 2013 to use CodeMirror and run client side using vanilla javascript. This new version now has the ability to use breakpoints, accept input, and output characters. As I did a full re-write I also fixed many bugs along the way .

Credit mostly goes to Dr. Daniel Reidenbach who wrote the module materials, without which I wouldn't have written this.

If you have any issues, get in touch

First Program Walkthrough

Ok, so you have no clue what this is or how to use it? Fear no longer for help is at hand.

Basically this is just a little simulator (a script in wolfs clothing) for CPU-S, which is the very basic and idealised CPU defined in the lecture notes for module COA124/COA126 (Computer Systems and Computer Systems for Engineers) at Loughborough University (or at least it was in ~2007).

So, if you check out This Diagram of what this script is pretending to be you might get a better understanding of how things work together.

I'll skip over a full explanation as I assume we all went to lectures...right? So you& already know what registers are what and what they do. Thus we can now skip straight to the joys of programming!

Lesson 1: Basic Assembly

Assembly is just one rung higher on the ladder of computer languages above machine code, which is as low level as you get. I chose to keep this simulator at the assembly level as that is all we dealt with in the lectures and I wasn't up for spending more time writing an assembler and coming up with opcodes for each instruction.

Assembly generally consists of instructions and parameters. Instructions, usually mapping directly to opcodes, can have parameters following on the same line, e.g. ADD 1,2 However, CPU-S is VERY simple, so only one parameter at a time, for instructions that take parameters. That's about all, check the Instruction Set above for more details on what instructions are available, what they do and what parameter is needed, if any.

Lesson 2: Memory

In a modern computer memory is generally treated as one block, be it opcodes for the program, memory that has been cached or even external devices sometimes. However CPU-S has two separate memory modules; one for the program and one for the data that the program manipulates. Hence the two boxes above titled "Program memory" and "Data memory".

Lesson 3: Programming a basic counter

Adding numbers is too basic and Hello World would be pointless as the lecture notes keep CPS-S as a numerical system with no ASCII character output. Instead let's write a simple program that counts from one number up to another.

First we need to work out some basic pseudocode:

from := 5
to  := 10
count := from
increment := 1

  OUTPUT count
  count := count + increment
WHILE count != to

This should do, it enters a loop, outputs the current count, increments the count and continues the loop while the count has not yet reached the upper limit. From that simple bit of code we can list some variables, or data to work on. Data? Data memory! I see a connection...

So in the data memory for our CPU-S program we need four things: Where we start counting from, what we count up to, a variable to count up with and a variable to increment it.

So our data memory could look like this (comments start with a #):

5  # from
10 # to
0  # count
1  # What we increment with

Now on to the program. First that count variable, in our pseudocode it was created with the value of from but we can't do that with assembly. To make it equal to the starting value we need to copy it. How do we do that though, there isn't any copy command? Why not load a 0, the value, add them and store where the 0 was (or in a different place on other occasions)? Sounds good:


Now we copied data cell 0 into data cell 2. Next we need to start the do loop. It's fairly simple; we need to output the count and increment the counter:


Then we need to do the conditional jump of the while part (Read how JUMP works if you forgot already). You'll also note I store the result of the comparison in a new data cell, so as not to interfere with current data:

JUMP [[ To the start of the previous segment ]]

And then we end it:


So the full program would be (Program data):


There you have it. Not the best example and certainly not the best final code but it's written to give some guidelines on various opcodes and how they can be used together to make something more advanced, like a do-while loop.

Click Here to load this code into the editors (Saves copy/paste).

If you don't really get what's going on you should try loading the example with the link above and running it. Then change some of the data variables and see what happens. Perhaps modify the code to count down?

You may also note that I added some extra opcodes myself which aren't used in lectures. With these you can make the code much simpler, but that would be cheating! But then I am a cheater so with a few minor modifications, and some use of the extra instructions I added, like INC and OUTPUTCHAR, you can modify this code to make a relatively simple Hello World program, Click here to load Hello World. This uses the counter to indirectly load memory at the counter locations and then output the ASCII code as a character with OUTPUTCHAR