8bit Computer by Retr0Company - 1

Simulators

Simple 8bit Microcontroller Simulator

Unity 2020.1.2f1MIT LicenseUpdated 78 days agoCreated on October 6th, 2020
Go to source

Unity 8bitComputer

An 8-bit computer simulator built in Unity that shows how components of a computer actually work.

I’m currently adding basic opcodes as well as Flag registers.
I implemented CycleCounter and basic Interrupt Trigger but haven’t implemented any operations for it.

alt text

Installation (for Unity Editor)

Clone or download the repository

Open UnityHub, click add, and select 8bitComputer-master

Examples

    LDA 10          // Load value 10 into Accumulator
    STR GPR_00      // Store Accumulator into Register GPR_00
    SUB 5           // Substract 5 to Accumulator   
    SWP GPR_00      // Swipe values from Accumulator with GPR_00 (ACC -> GPR_00 & GPR_00 -> ACC)
    ADDR 00         // Add value stored in register GPR_00 to Accumulator
    STA 3000        // Store Accumulator into Memory address 3000 (16bit)
    HLT             // Halt CPU

Opcodes

    00 NOP : No Operation
    
    01 LDA [byte] : Load Value into Accumulator
    02 STA [word] : Store Accumulator into Memory(16bit address)
    03 STR GPR_X : Store Accumulator into Registery (GPR_X)
    
    04 SWP GPR_X : Swipe values from Accumulator with GPR_X
    
    05 ADD [byte] : Add Value to Accumulator
    06 ADDR GPR_X : Add Value stored into GPR_X to Accumulator
    07 SUB [byte] : Substract Value from Accumulator
    08 SUBR GPR_X : Substract Value stored into GPR_X form Accumulator

    09 HLT : Halt CPU

CPU_8016.cs

using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine;

public class CPU_8016
{
    List<OPCODE> OpCodes;

    // ---------------------------------------
    // Counters : Program + Cycle
    // ---------------------------------------
    private int PC, CC;

    // ---------------------------------------
    // Memory : 16bit memory
    // ---------------------------------------
    private byte[] Memory;
     
    // ---------------------------------------
    // Registers (ACC + 16 GPR)
    // ---------------------------------------
    private byte A;
    private byte[] gpr;

    public bool Halted => halted;
    private bool halted = false;
    
    // ---------------------------------------
    // Interrupt Register (Timer_Overflow (256 by default))
    // ---------------------------------------
    private int TIMER_OVF = 256;

    public CPU_8016(byte[] code, int offset = 0)
    {
        Memory = new byte[4096];
        Array.Copy(code, 0, Memory, offset, code.Length);

        OpCodes = new List<OPCODE>()
        {
            new OPCODE(()=>{PC++;}), // 00 NOP
            
            new OPCODE(() => {

                A = Memory[++PC]; // Load Value into Accumulator
                PC++;

            }, 2), // 01 LDA VALUE
            new OPCODE(() => {

                int addr = Memory[++PC] << 8 | Memory[++PC];    // Get 16bit address
                Memory[addr] = A;                               // Store value
                PC++;

            }, 3), // 02 STA ADDRESS_16
            new OPCODE(() => {

                int addr = Memory[++PC];    // Get 16bit address
                gpr[addr] = A;              // Store value
                PC++;

            }, 3), // 03 STR GPR_X

            new OPCODE(() => {

                byte index = Memory[++PC];
                byte _temp = A;
                A = gpr[index];
                gpr[index] = _temp;
                PC++;

            }, 4), // 04 SWP GPR_X

            new OPCODE(() => 
            {
                
                byte val = Memory[++PC];
                A = (byte)(A + val);
                PC++;

            }, 3), // 05 ADD VALUE
            new OPCODE(() => 
            {
                byte index = Memory[++PC];
                byte val = gpr[index];
                A = (byte)(A + val);
                PC++;

            }, 4), // 06 ADDR GPR_X

            new OPCODE(() =>
            {

                byte val = Memory[++PC];
                A = (byte)(A - val);
                PC++;

            }, 3),  // 07 SUB VALUE
            new OPCODE(() =>
            {
                byte index = Memory[++PC];
                byte val = gpr[index];
                A = (byte)(A - val);
                PC++;

            }, 4),  // 08 SUBR GPR_X

            new OPCODE(()=>{ halted = true; }) // HLT
        };

        Reset();
    }

    public void Reset()
    {
        PC = 0;
        CC = TIMER_OVF;

        gpr = new byte[16];

    }

    public void Step()
    {
        byte I = Memory[PC];

        if(I >= 0 && I < OpCodes.Count)
        {
            /* Execute Instruction */
            OpCodes[I].action.Invoke();
            CC -= OpCodes[I].cycleCount;
        }

        if(CC <= 0)
        {
            /* Check for interrupts and do other hardware emulation here */
            CC += TIMER_OVF;
        }

        if (halted) throw new Exception("CPU Halted !");

    }

    public struct OPCODE
    {
        public int cycleCount;
        public Action action;

        public OPCODE(Action _action = null, int _cycleCount = 1)
        {
            cycleCount = _cycleCount;
            action = _action;
        }
    }

    public override string ToString()
    {
        StringBuilder builder = new StringBuilder();
        builder.Append(____ROOT____quot;A={A}").AppendLine();
        builder.Append(____ROOT____quot;GPR_00={gpr[0]}");
        builder.Append(____ROOT____quot;Memory[321]={Memory[321]}").AppendLine();
        return builder.ToString();
    }
}

Notes

I suggest having an understanding of how the individual components of a computer work. This should be used to aid that process or experiment with low level operations. Trying out some basic programs, having a large delay time, and checking each operation via the log will seriously help your understanding. Also, I suggest hovering over the components to see what is what and to get familiar with the scene.

References

Ben Eater is awesome. If you have any questions or confusions I strongly suggest watching his series on building an 8-bit computer. This is how I was able to implement the computer in Unity along with previous experience from school.

Link: https://www.youtube.com/watch?v=HyznrdDSSGM&list=PLowKtXNTBypGqImE405J2565dvjafglHU

I also recommend seeing other projects like this one :
https://github.com/MichaelGaidas/Unity_8BitComputerSimulator/ Wich is really simple to understand and is a first step in understanding how computers work.

Show all projects by Retr0Company