Giter VIP home page Giter VIP logo

comp-cpp's Introduction

Comp

Simple 4-bit/1 Hz virtual computer for learning purposes

screenshot

For quick start see HOW TO RUN.

Memory

instructions - 4 bits
  |  +-- addresses - 4 bits
  v  v
----***-  <- 0  ----
--*-**-*  <- 1  ---*
---***--  <- 2  --*-
---*****  <- 3  --**
----***-  <- 4  -*--
---***-*  <- 5  -*-*
----**--  <- 6  -**-
---****-  <- 7  -***
-***---*  <- 8  *---
-*--****  <- 9  *--*
--------  <- 10 *-*-
--------  <- 11 *-**
--------  <- 12 **--
-------*  <- 13 **-*
-------*  <- 14 ***-
<OUTPUT>  <- 15 ****
  • Execution starts at the first address (0).
  • Execution stops when program reaches last address (15).
  • Whatever gets written to the last address is sent to the printer.
  • When reading from the last address (15), we get a random byte value.
  • CPU has one 8 bit register.

Instruction set

  • READ ---- - Copies the value at the specified address into register.
  • WRITE ---* - Copies value of the register to the specified address.
  • ADD --*- - Adds value at the specified address to the value of the register, and writes result to the register. If the result is bigger than the maximum possible value (255 = ********) then 255 gets written.
  • SUBTRACT --** - Subtracts value at the speicfied address from the value of the register, and writes result to the register. If the result is smaller than 0 then 0 gets written.
  • JUMP -*-- - Changes the value of the program counter to the specified address, meaning that in the next cycle execution will continue at that address.
  • IF MAX -*-* - Jumps to the specified address if register has value 255 = ********.
  • IF MIN -**- - Jumps to the specified address if register has value 0 = --------.
  • SHIFT R -*** - Moves every bit of the register one spot to the right. This way rightmost bit gets lost, and a leftmost becomes '-'. This is the only instruction that doesn't use the address part, making the last four bits irrelevant.
  • Any instruction that is not defined above is interpreted as READ ---- instruction.

How to run on…

Windows

  • Install Tiny Core Linux on VirtualBox using this instructions.
  • Run the UNIX commands.

UNIX

$ git clone https://github.com/gto76/comp-cpp.git
$ cd comp-cpp
$ ./run

Other versions

  • Mark II, model with separate address space for code and data, and with more instructions. Programs can be saved and loaded and it can run without the interface (instead of a printer, it then uses stdout). Also input can be piped in.

screenshot

comp-cpp's People

Contributors

gto76 avatar hoke-t avatar ketralnis avatar nsajko avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

comp-cpp's Issues

Doesn't build on OSX

$ bash run

mkdir -p obj
g++ -c -std=c++11 -o obj/comp.o src/comp.cpp 
2015-06-18 12:44:01.700 xcodebuild[2174:15376188] [MT] PluginLoading: Required plug-in compatibility UUID 9F75337B-21B4-4ADC-B558-F9CADF7073A7 for plug-in at path '~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/Unity4XC.xcplugin' not present in DVTPlugInCompatibilityUUIDs
src/comp.cpp:361:27: error: use of undeclared identifier 'pow'
        if (Util::getInt(reg) >= pow(2, WORD_SIZE)-1) {
                                 ^
1 error generated.
make: *** [obj/comp.o] Error 1

More examples and a list of challenges

would be great. I for one don't really know what to expect to be able to do with this. I've written a simple Fibonacci sequence program, and I don't really know where to go next.

Why not use more conventional terminology?

It's quite interesting, but why not use more conventional microprocessor terminology?

READ -> LOAD
WRITE -> STORE
IF -> BRANCH
SHIFT RIGHT -> ASR (Arithmetic shift right)

It's also seems a bit limiting that the code and data share the same address space, when there is so little to share. Almost seems to encourage the use of self-modifying code.

segfault on long running programs

If I leave a simple incrementing loop running for a long time (several hours), the process will eventually die with a segfault.

This is on OS X 10.9.5, running as of 3998227. The only local diff I have applied is:

-const int FQ = 333;
+const int FQ = 100;

so that it will reproduce faster. I pulled the backtrace from the core that dumps:

~/src/comp-cpp$ lldb -c /cores/core.83853 ./comp
(lldb) target create "./comp" --core "/cores/core.83853"
warning: (x86_64) /cores/core.83853 load command 66 LC_SEGMENT_64 has a fileoff + filesize (0x1d1f8000) that extends beyond the end of the file (0x1d1f7000), the segment will be truncated to match
warning: (x86_64) /cores/core.83853 load command 67 LC_SEGMENT_64 has a fileoff (0x1d1f8000) that extends beyond the end of the file (0x1d1f7000), ignoring this section
Core file '/cores/core.83853' (x86_64) was loaded.
Process 0 stopped
* thread #1: tid = 0x0000, 0x00007fff8f2e0bcc libsystem_c.dylib`__vfprintf + 41, stop reason = signal SIGSTOP
    frame #0: 0x00007fff8f2e0bcc libsystem_c.dylib`__vfprintf + 41
libsystem_c.dylib`__vfprintf + 41:
-> 0x7fff8f2e0bcc:  movq   %rdi, -0x3c0(%rbp)
   0x7fff8f2e0bd3:  leaq   -0x19cf87ba(%rip), %rax   ; __stack_chk_guard
   0x7fff8f2e0bda:  movq   (%rax), %rax
   0x7fff8f2e0bdd:  movq   %rax, -0x30(%rbp)
(lldb) bt
* thread #1: tid = 0x0000, 0x00007fff8f2e0bcc libsystem_c.dylib`__vfprintf + 41, stop reason = signal SIGSTOP
  * frame #0: 0x00007fff8f2e0bcc libsystem_c.dylib`__vfprintf + 41
    frame #1: 0x00007fff8f3092db libsystem_c.dylib`__v2printf + 471
    frame #2: 0x00007fff8f3096b0 libsystem_c.dylib`__xvprintf + 633
    frame #3: 0x00007fff8f2e0b2a libsystem_c.dylib`vfprintf_l + 54
    frame #4: 0x00007fff8f2de970 libsystem_c.dylib`printf + 200
    frame #5: 0x000000010fa3f5ac comp`printString(s=<unavailable>, x=<unavailable>, y=<unavailable>) + 332 at output.c:68
    frame #6: 0x000000010fa34d97 comp`drawScreen() + 583 at comp.cpp:67
    frame #7: 0x000000010fa3f6ef comp`redrawScreen + 79 at output.c:105
    frame #8: 0x000000010fa355b8 comp`Cpu::exec(this=0x000000010fa41658) + 120 at comp.cpp:294
    frame #9: 0x000000010fa3566b comp`Cpu::exec(this=<unavailable>) + 299 at comp.cpp:333
    frame #10: 0x000000010fa3566b comp`Cpu::exec(this=<unavailable>) + 299 at comp.cpp:333
    frame #11: 0x000000010fa3566b comp`Cpu::exec(this=<unavailable>) + 299 at comp.cpp:333
    frame #12: 0x000000010fa3566b comp`Cpu::exec(this=<unavailable>) + 299 at comp.cpp:333
...
    frame #24953: 0x000000010fa3566b comp`Cpu::exec(this=<unavailable>) + 299 at comp.cpp:333
    frame #24954: 0x000000010fa3566b comp`Cpu::exec(this=<unavailable>) + 299 at comp.cpp:333
    frame #24955: 0x000000010fa352ba comp`run() + 154 at comp.cpp:118
    frame #24956: 0x000000010fa35914 comp`userInput() + 84 at comp.cpp:166
    frame #24957: 0x000000010fa36f2f comp`main(argc=<unavailable>, argv=<unavailable>) + 79 at comp.cpp:421
    frame #24958: 0x00007fff8f9d15fd libdyld.dylib`start + 1
    frame #24959: 0x00007fff8f9d15fd libdyld.dylib`start + 1

Where I put the ... there are thousands of lines identical to the ones surrounding it, differing only by the frame number

Signal handlers call unsafe signal functions (race conditions may result in undefined behavior)

Great project. I noticed the following while browsing the code: The signal handler is not async signal safe (for example printf and fflush are called during the signal handler); this is a race condition and may result in the simulator crashing, generating incorrect output, or deadlocking when the window is resized.

http://man7.org/linux/man-pages/man7/signal.7.html
"If a signal interrupts the execution of an unsafe function, and handler calls an unsafe function, then the behavior of the program is undefined."

void sigWinChCatcher(int signum) {
    redrawScreen();
}
void redrawScreen() {
    updateConsoleSize();
    clearScreen();
    drawScreen();
    fflush(stdout);
}

Some suggestions:
If the main event loop sleep() will be interrupted and return early so is it necessary to redraw the screen - why not delegate it back to the main thread?
write(2) is async signal safe.
Let the main loop know that a redraw is required after sleep using a simple boolean flag.

Similar arguments apply to the SIGINT handler. exit() is not async-signal-safe; a simple 'pleaseexit' boolean flag may be better implementation.

Saving and loading executables

Just in ascii form, or in bytes I guess. Tiny files. Wouldn't even need an in-interface load option, just use cli flags :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.