stardance has been extended another month! the new deadline is october 31 :)

You are browsing as a guest. Sign up (or log in) to start making projects!

MINERVA-8

  • 2 Devlogs
  • 32 Total hours

This is MINERVA-8 - A custom 8-bit assembler

Ship #1 Changes requested

What did I build?
I built MINERVA-8, a custom console-based 8-bit assembler written entirely from scratch in C++. MINERVA-8 emulates a complete low level computer system from the command line. It has registers, a hardware stack pointer, flags (CF & ZF), 256 bytes of simulated memory, and full CPU emulation. There is also a compiler which converts assembly code with symbolic names to machine instructions. Implemented in C++.
What Was Challenging?
There were quite a few issues that I ran into when running assembly programs but they were fixable using my ‘step’ flag and watching the CPU states(flags/registers). However, one major hurdle I encountered with forward labels was that my assembler did not support jumping to an undefined label that wasn’t declared yet(forward jumps) used in JMP, CALL, JZ, and JNZ instructions. I could not solve this problem until I learned during my C++ class how V-tables are created during compile time. Thus, I decided on an “unresolved array” which would store the label and not have a resolved address which would be patched later when the label is actually found. My dad also suggested a two pass assembler would be more elegant. During the first pass all labels can be resolved and during the second pass the machine code can be generated. I chose to keep the single pass design because it produced a faster assembler despite requiring a small tracking array.
What are you proud of?
I am more satisfied than being proud of building a functional hardware stack infrastructure capable of handling nested subroutines using low-level PUSH, POP, CALL, and RET commands. It was amazing to watch a processor simulator I wrote entirely by hand successfully use stack memory to jump into subroutines, run math operations, and bounce back to the main program loop cleanly without crashing or corrupting memory boundaries.

How to Test My Project

Go to https://github.com/sudeeps-projects/Minerva-8/blob/master/README.md
look for the section Quick Start & Usage
It describes how to test my project

The compiled executable MINERVA-8.exe is located inside the release folder of this repository.

General Usage
Open your command prompt, navigate to the release folder, and run the executable with your assembly file and optional flags:

MINERVA-8.exe <filename.asm> [options]
Parameters & Options
filename.asm (Required): The path to the MINERVA-8 assembly file you want to execute.
–step (Optional): Step Mode. Displays the current CPU state and next instruction, then waits for ENTER before executing the next step.
–ram (Optional): RAM Mode. Displays the fully assembled machine code stored in the 256-byte RAM.

Command Examples

  1. Standard Execution
    MINERVA-8.exe DEC.asm

  2. Running Step Mode
    MINERVA-8.exe DEC.asm –step

  3. Running RAM Mode
    MINERVA-8.exe DEC.asm –ram

  4. Combining Step and RAM Modes The optional flags can be supplied together in any order:

MINERVA-8.exe DEC.asm –step –ram

OR

MINERVA-8.exe DEC.asm –ram –step

Look at my youtube channel on this topic: https://www.youtube.com/watch?v=7CmpW0mE3cQ

  • 2 devlogs
  • 32h
Try project → See source code →
Open comments for this post

3h 16m 9s logged

over the last few weeks, I have been working on many test cases.. I have added many negative test cases where I try to pop from an empty stack or ‘ret’ instruction without a call. I found many issues that i fixed in the last few weeks. I have also written a fibonacci series using my instruction set and have been successfully able to ‘OUT’ the result to console.
This has been my most proud activity. It took me 4-5 days to come up with fibonacci flow as I was hand-calculating the output using my instructions. When I tried it , i was getting wrong answers. My step flag helped me debug the flow and eventually I could come up with correct fibonacci instruction flow. I have put many examples in the release folder. In the release folder, I have put Minerva-8.exe which takes the file name <fibonacci.asm> as an argument. It also takes additional optional arguments such as [–step | –ram] . The –step argument provides the user with the ability to debug instruction by instruction flow and shows the CPU state after execution of every instruction. This helped me debug my own fibonacci.asm which took quite a bit of time.
Also, I have struggling with logging hours on hackatime. My github is on [email protected] account and i logged to hackatime using [email protected]. Using the help from slack and some from Google , I tried to link both the emails but it is still not clear on why it shows 0hours when hackatime clearly logged 30hrs for Minerva-8 and 1:30 hrs for compiler

0
0
9
Open comments for this post

28h 32m 30s logged

In my 10th grade Summer, I took C++ course in Folsom Lake Community College. The Professor was teaching about how C++ code gets converted to Assembly language, how the assembler converts the Assembly instructions into Machine code then the CPU will execute the machine code. I got confused and asked my friends on what that means. My friends did not know it either. At home, my dad explained with a block diagram. I got more curious about the innerworkings and read the documentation of RISC-V instruction set. This led me to come up with MINERVA-8 a custom CPU 8 bit architecture.

MINERVA-8

MINERVA-8 (CUSTOM 8-BIT ASSEMBLY LANGUAGE) is a console-based 8-bit CPU simulator written in C++ that demonstrates how a processor executes instructions through the fetch-decode-execute cycle while showing changes to registers, memory, flags, and control flow.

The project includes a custom assembler that translates MINERVA-8 assembly language into machine code and loads the resulting instructions and data into 256 bytes of simulated RAM.

Architecture

MINERVA-8 currently includes:

  • 8-bit CPU architecture
  • 256 bytes of RAM
  • Program Counter (PC)
  • Register A
  • Register B
  • Carry Flag (CF)
  • Zero Flag (ZF)
  • Custom instruction set
  • Custom assembler
  • Symbolic labels
  • Console display of CPU state and memory
  • Numeric and character console output

Fetch-Decode-Execute Cycle

Fetch

The fetch unit uses the Program Counter to retrieve the next opcode from RAM.

Decode

The decoding unit determines which instruction the opcode represents and identifies any associated operand or memory address.

Execute

The execution unit performs the requested operation. Depending on the instruction, it can:

  • modify registers
  • perform arithmetic
  • perform bitwise logic
  • update CPU flags
  • load or store memory
  • change program control flow
  • output values or characters

Instruction Set

Instruction Description LDA Load a value into Register A LDB Load a value into Register B LDM Load a value from memory into Register A ADD Add Register B to Register A SUB Subtract Register B from Register A STA Store Register A in memory OUT Output Register A as a number OUTC Output Register A as an ASCII character JNZ Jump if the Zero Flag is not set JZ Jump if the Zero Flag is set JMP Unconditional jump AND Bitwise AND of Register A and Register B OR Bitwise OR of Register A and Register B XOR Bitwise XOR of Register A and Register B SHL Shift Register A left by one bit SHR Shift Register A right by one bit NOT Invert every bit in Register A INC Increment Register A DEC Decrement Register A CMP Compare Register A and Register B and update flags PUSH Push Register A contents to stack POP Pop stack into Reg A and update flags CALL Call subroutine RET Return from subroutine to the caller HLT Halt execution
0
0
2

Delete project?

Are you sure you want to permanently delete this project? This action cannot be undone.

All devlogs, followers, and associated data will be removed.

Followers

Loading…