• Stars
    star
    1,871
  • Rank 24,773 (Top 0.5 %)
  • Language
    Go
  • Created over 5 years ago
  • Updated about 4 years ago

Reviews

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

Repository Details

the scott CPU from "But How Do It Know?" by J. Clark Scott

Simple Computer

Whilst reading But How Do It Know? by J. Clark Scott I felt compelled to write something to simulate the computer the book describes.

Starting from NAND gates, and moving up through to registers, RAM, the ALU, the control unit and adding I/O support, I eventually ended up with a fully functional machine.

All the components of the system are based on logic gates and the way they are connected together via the system bus.

For a write up about this project, see my blog post about it here https://djharper.dev/post/2019/05/21/i-dont-know-how-cpus-work-so-i-simulated-one-in-code/

text writer

Specs

  • ~0.006mhz
    • at least on my machine
  • 16-bit
    • the book describes an 8-bit CPU for simplicity but I wanted more RAM and there is only one system bus
  • 65K RAM
  • 240x160 screen resolution
  • 4x 16-bit registers (R0, R1, R2, R3)

Missing features

  • Interrupts, so you have to write awful polling code
    • The book does shortly describe how to extend the system to support interrupts but would involve a lot more wiring
  • Stack pointer register + stack + stack manipulation instructions so nested CALL instructions won't work and registers may be left in an inconsistent state
  • Hard drive
  • Subtract instruction
  • MOV instruction
  • Floating point math (lol)
  • Everything else you could think of from a modern CPU

Bonus features

  • No Meltdown/SPECTRE risk
  • Can easily overwrite any portion of memory without any protective mode getting in the way
  • Currently incapable of accessing the internet
    • I can see how you might write a simple networking I/O adapter, although I'd imagine it would be tedious writing the assembly to get bytes in and out of it πŸ€”

Instructions

Instruction Type Description Example
LOAD Ra, Rb Machine Load value of memory address in register A into register B LOAD R1, R2
STORE Ra, Rb Machine Store value of register B into memory address in register A STORE R3, R1
DATA Ra, <VALUE> Machine Put <VALUE> into register A. <VALUE> can either be a symbol, prefixed with % (e.g. %LINE-X) or a numeric value (e.g. 0x00F2 or 23) DATA R3, %KEYCODE
JR Ra Machine Jump to instruction in memory address in register A JR R2
JMP <LABEL> Machine Jump to instruction in memory address for <LABEL> JMP startloop
JMP[CAEZ]+ <LABEL> Machine Jump to instruction in memory address for <LABEL> if flags register for any combination of CAEZ is true JMPEZ endloop
CLF Machine Clear contents of flags register CLF
IN <MODE>, Ra Machine Request input from IO device to Register A IN Data, R3
OUT <MODE>, Ra Machine Send output to IO device for register A OUT Addr, R2
ADD Ra, Rb Machine 16 bit addition of two registers ADD R0, R2
SHR Ra Machine Shift right register A SHR R0
SHL Ra Machine Shift left register A SHL R0
NOT Ra Machine Bitwise NOT on register A NOT R2
AND Ra, Rb Machine Bitwise AND on two registers AND R2, R3
OR Ra, Rb Machine Bitwise OR on two registers OR R0, R1
XOR Ra, Rb Machine Bitwise XOR on two registers XOR R1, R0
CMP Ra, Rb Machine Compare register A and register B (will set flags register) CMP R1, R2
CALL <LABEL> Pseudo Call a subroutine. This will jump to the subroutine, on completion, the subroutine should jump back and continue from the next instruction. Note: there is no stack functionality here so all registers may be in a different state at the end of the subroutine. CALL pollKeyboard

I/O devices

The following I/O devices are supported by the computer.

Device Address
Keyboard 0x000F
Display 0x0007

Memory layout

There is no memory management unit or protected areas of memory.

However the assembler and simulator will start executing user code from offset 0x0500

Assembler

Machine code can be written in text and assembled using a crude assembler I wrote.

See assembler for more information.

Compiler

@realkompot made an awesome compiler https://github.com/realkompot/llvm-project-scott-cpu for this using LLVM that produces working binaries to run on the simulator, check out the cool little snake game example https://github.com/realkompot/llvm-project-scott-cpu/tree/scott-cpu/_scott-cpu

Building

Requirements

  • go 1.12+
  • GLFW 3.2+

Building:

make

There are some unit tests that take 30-45 seconds to run through, by running

make test

Running

The computer can be run using the wrapper tool I wrote that utilises GLFW for I/O functionality.

Example of running the brush.bin program

./bin/simulator -bin _programs/brush.bin

Example programs

You can see some example programs I wrote under _programs/, note the ASM code I wrote for these is very bad and I lost my sanity a bit when writing them.

Why bother?

I'm taking myself on a journey, a hardware journey you might say. I want to understand how computers work at a lower level but not quite low enough for the physics/digital electronics side of things.

Just enough to see all the pieces of the system interacting. I remember doing a lot of this stuff in school but I'd say my education seemed to focus on the concepts (Von-Neumann architecture, fetch-decode-execute) rather than the actual construction of a CPU.

This simple computer is the start of that journey, it's actually been a very rewarding little project.

I hope to move onto playing around with X86/ARM/RISC-V next although I suspect it will be quite a leap (of faith)

More Repositories

1

gomeboycolor

Gameboy Color emulator
Go
399
star
2

gomeboycolor-wasm

WASM port of gomeboycolor
HTML
115
star
3

go-lambda-invoke

Go
84
star
4

stegtool

Steganography tool
Rust
53
star
5

theunwrapper

HTML
42
star
6

steg

Steganography library
Rust
30
star
7

blinkt-tube-status

Python
14
star
8

gomeboycolor-glfw

Gameboy Color Emulator (libglfw frontend)
Go
14
star
9

pngrun

Executable PNGS
Rust
8
star
10

bf

brainfuck compiler in Java
Java
7
star
11

gmail-mailer

Programatically send emails using a given gmail account. No username/passwords needed, just use your OAUTH credentials
Ruby
6
star
12

simpleCPU

Go
6
star
13

kindlemail

Push items to your kindle via the personal document service
Ruby
6
star
14

testproject

Source for "Getting started with ClojureScript and Noir #1"
Clojure
5
star
15

djhworld.github.io

thoughts
HTML
4
star
16

dropwizard-jooq

JOOQ integration for Dropwizard
Java
4
star
17

bigdan-table

daniel's bigtable implementation
Java
3
star
18

count

Count unique entries in line delimited input from stdin
Go
2
star
19

card

Estimates cardinality (count-distinct) of inputs using HyperLogLog++ algorithm
Go
2
star
20

ScalaPythonChallenges

Solutions to the Python Challenges series in Scala
Scala
2
star
21

strex

An extension to the strings library that takes inspiration from Data.List in Haskell (for strings only)
Go
2
star
22

rosetta-warn

Plugin for xbar that displays a warning icon on your OSX status bar when applications are running under Rosetta, and outputs the processes in a menu.
Shell
2
star
23

articlr-backend

Ruby
1
star
24

Daniel

Small utility functions and things for various tasks.
Haskell
1
star
25

XboxLiveStatus

Displays the status of given XBL gamertags
1
star
26

redis-mq

Redis helpers for pub/sub and queue processing in Clojure apps. Great for prototyping stuff quickly
Clojure
1
star
27

ReallyEZTV

Parses data from EZTV RSS feeds into a more friendly format. Most shows in the EZTV RSS feeds have a "Show/Season/Episode" hierarchy, my system just takes that and converts them into a usable data structure. This application sits on top of Sinatra to provide a frontend for that data. Please note this code is very, very messy and could easily be improved but this is my first "project" as such after spending a bit of time getting up to speed with the basics of Ruby
Ruby
1
star