{"id":33947505,"url":"https://github.com/AfaanBilal/NanoCore","last_synced_at":"2025-12-14T13:01:04.852Z","repository":{"id":305354219,"uuid":"1021152271","full_name":"AfaanBilal/NanoCore","owner":"AfaanBilal","description":"NanoCore 8-bit CPU","archived":false,"fork":false,"pushed_at":"2025-11-19T07:54:02.000Z","size":5568,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-11-19T09:21:14.598Z","etag":null,"topics":["8-bit","cpu","emulator","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AfaanBilal.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-07-17T01:20:01.000Z","updated_at":"2025-11-19T07:54:06.000Z","dependencies_parsed_at":"2025-07-19T19:22:45.592Z","dependency_job_id":null,"html_url":"https://github.com/AfaanBilal/NanoCore","commit_stats":null,"previous_names":["afaanbilal/nanocore"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/AfaanBilal/NanoCore","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AfaanBilal%2FNanoCore","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AfaanBilal%2FNanoCore/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AfaanBilal%2FNanoCore/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AfaanBilal%2FNanoCore/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AfaanBilal","download_url":"https://codeload.github.com/AfaanBilal/NanoCore/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AfaanBilal%2FNanoCore/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":27728753,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-12-14T02:00:11.348Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["8-bit","cpu","emulator","rust"],"created_at":"2025-12-12T18:01:41.066Z","updated_at":"2025-12-14T13:01:04.846Z","avatar_url":"https://github.com/AfaanBilal.png","language":"Rust","funding_links":[],"categories":["Table of Contents"],"sub_categories":[],"readme":"# NanoCore: An 8-bit CPU Emulator\n\n## 🌟 Introduction\n\n`NanoCore` is a meticulously crafted emulator for a custom 8-bit CPU.\n\nDeepWiki: [AfaanBilal/NanoCore](https://deepwiki.com/AfaanBilal/NanoCore)\n\nDesigned with extreme minimalism in mind, this CPU operates within a strict 256-byte memory space, with all registers, the Program Counter (PC), and the Stack Pointer (SP) being 8-bit.\n\nThis project serves as an educational exercise in understanding the fundamental principles of computer architecture, low-level instruction set design, memory management under severe constraints, and assembly language programming.\n\n\u003cimg src=\"assets/NanoCoreTUI.gif\" alt=\"NanoCore TUI\"\u003e\n\n## ✨ Key Features\n\n  * **True 8-bit Architecture:** All general-purpose registers (R0-R15), Program Counter (PC), and Stack Pointer (SP) are 8-bit.\n  * **256-byte Memory:** The entire addressable memory space is limited to 256 bytes (`0x00` to `0xFF`), making it a challenge to write highly optimized and compact code.\n  * **Variable-Length Instruction Set:** Supports both 1-byte, 2-byte and 3-byte instructions to maximize opcode efficiency and flexibility within the limited address space.\n  * **Modular Design:** CPU cycle is broken down into distinct Fetch, Decode, and Execute phases for clarity.\n  * **Inbuilt Two-Pass Assembler:** The NanoCore Assembler makes it easier to program it by writing NanoCore Assembly instead of direct machine code.\n  * **Terminal User Interface:** Fully function TUI as seen above with breakpoints for easy debugging.\n\n## 🧮 Instruction Set Architecture (ISA)\n\n\u003e See `programs/` for example programs and compiled binaries.\n\nNanoCore features a small but functional instruction set designed for its 8-bit constraints.\n\n### Instruction Format\n\n  * **1-byte instructions:** One 8-bit opcode.\n  * **2-byte instructions:** An 8-bit opcode followed by an 8-bit operand (e.g., an immediate value or an address).\n  * **3-byte instructions:** An 8-bit opcode followed by two 8-bit operands (e.g., an immediate value or an address).\n\n### Implemented Instructions\n\n| Opcode | Bytes | Mnemonic         | Description                             | Encoding Example |\n| :----- | ----: | :--------------- | :-------------------------------------- | :--------------- |\n| `0x00` |     1 | `HLT`            | Halts CPU execution                     | `0x00`           |\n| `0x01` |     1 | `NOP`            | No operation                            | `0x01`           |\n| `0x02` |     3 | `LDI Reg val`    | Load immediate `val` into `Reg`         | `0x02 0x00 0xAB` |\n| `0x03` |     3 | `LDA Reg addr`   | Load from mem address `addr` into `Reg` | `0x03 0x00 0xCC` |\n| `0x04` |     2 | `LDR Rd Rs`      | Load from mem address in `Rs` into `Rd` | `0x04 0x00 0x01` |\n| `0x05` |     2 | `MOV Rd Rs`      | Copy value from `Rs` into `Rd`          | `0x05 0x01 0x02` |\n| `0x06` |     3 | `STORE Reg addr` | Store `Reg` into mem address `addr`     | `0x05 0x01 0xAA` |\n| `0x07` |     2 | `PUSH Reg`       | Push `Reg` value into stack.            | `0x05 0x01`      |\n| `0x08` |     2 | `POP Reg`        | Pop from stack into `Reg`               | `0x05 0x01`      |\n| `0x09` |     2 | `ADD Rd Rs`      | Add value of `Rs` to `Rd`               | `0x05 0x01 0x02` |\n| `0x0A` |     3 | `ADDI Reg val`   | Add immediate `val` to `Reg`            | `0x05 0x01 0xAB` |\n| `0x0B` |     2 | `SUB Rd Rs`      | Subtract value of `Rd` from `Rs`        | `0x05 0x01 0x02` |\n| `0x0C` |     3 | `SUBI Reg val`   | Subtract immediate `val` from `Reg`     | `0x05 0x01 0xAB` |\n| `0x0D` |     2 | `INC Reg`        | Increment `Reg`                         | `0x05 0x01`      |\n| `0x0E` |     2 | `DEC Reg`        | Decrement `Reg`                         | `0x05 0x01`      |\n| `0x0F` |     2 | `AND Rd Rs`      | Set `Rd` to `Rd \u0026 Rs`                   | `0x05 0x01 0x02` |\n| `0x10` |     2 | `OR Rd Rs`       | Set `Rd` to `Rd \\| Rs`                  | `0x05 0x01 0x02` |\n| `0x11` |     2 | `XOR Rd Rs`      | Set `Rd` to `Rd ^ Rs`                   | `0x05 0x01 0x02` |\n| `0x12` |     2 | `NOT Reg`        | Set `Reg` to `!Reg`                     | `0x05 0x01`      |\n| `0x13` |     2 | `CMP Rd Rs`      | Set `Z` flag if `Rd == Rs`              | `0x05 0x01 0x02` |\n| `0x14` |     2 | `SHL Reg`        | Shift left in `Reg` by 1 (`\u003c\u003c 1`)       | `0x05 0x01`      |\n| `0x15` |     2 | `SHR Reg`        | Shift right in `Reg` by 1 (`\u003e\u003e 1`)      | `0x05 0x01`      |\n| `0x22` |     2 | `ROL Reg`        | Rotate left in `Reg` by 1               | `0x22 0x01`      |\n| `0x23` |     2 | `ROR Reg`        | Rotate right in `Reg` by 1              | `0x23 0x01`      |\n| `0x16` |     2 | `JMP addr`       | Unconditional jump to `addr`            | `0x05 0xAA`      |\n| `0x17` |     2 | `JZ addr`        | Jump to `addr` if `Z` flag is set       | `0x05 0xAA`      |\n| `0x18` |     2 | `JNZ addr`       | Jump to `addr` if `Z` flag is not set   | `0x05 0xAA`      |\n| `0x24` |     2 | `IN Reg`         | Read char from stdin into `Reg`         | `0x24 0x01`      |\n| `0x19` |     2 | `PRINT Reg`      | Print `Reg` as an ASCII character       | `0x19 0x01`      |\n| `0x1A` |     2 | `MUL Rd Rs`      | Multiply value of `Rs` to `Rd`          | `0x1A 0x01 0x02` |\n| `0x1B` |     3 | `MULI Reg val`   | Multiply immediate `val` to `Reg`       | `0x1B 0x01 0xAB` |\n| `0x1C` |     2 | `DIV Rd Rs`      | Divide value of `Rs` by `Rd`            | `0x1C 0x01 0x02` |\n| `0x1D` |     3 | `DIVI Reg val`   | Divide `Reg` by immediate `val`         | `0x1D 0x01 0xAB` |\n| `0x1E` |     2 | `MOD Rd Rs`      | Modulus value of `Rs` by `Rd`           | `0x1E 0x01 0x02` |\n| `0x1F` |     3 | `MODI Reg val`   | Modulus `Reg` by immediate `val`        | `0x1F 0x01 0xAB` |\n| `0x20` |     2 | `CALL addr`      | CALL `addr` or function label.          | `0x20 0xAA`      |\n| `0x21` |     1 | `RET`            | Return from `CALL`ed function.          | `0x21`           |\n| `0x25` |     2 | `JMPR Reg`       | Unconditional jump to address in `Reg`  | `0x25 0x01`      |\n| `0x26` |     2 | `CALLR Reg`      | CALL address in `Reg`                   | `0x26 0x01`      |\n| `0x27` |     2 | `STR Rd Rs`      | Store `Rd` to addr in `Rs`              | `0x27 0x01 0x02` |\n\n\u003e - `val` = `Immediate value`\n\u003e - `addr` = `Memory address`\n\u003e - `Reg` = `Register`\n\u003e - `Rs` = `Source register`\n\u003e - `Rd` = `Destination register`\n\u003e - `Z` flag = Zero Flag\n\u003e - `R0` = `0x00`, `R1` = `0x01` ..., `R15` = `0x0F`\n\u003e - All addition, subtraction, increment and decrement is wrapping.\n\n## 🚀 Getting Started\n\nTo run the NanoCore emulator, you'll need to setup Rust locally.\n\n1.  **Clone the repository:**\n    ```bash\n    git clone https://github.com/AfaanBilal/nanocore.git\n    cd nanocore\n    ```\n2.  **Run the example program:**\n    The `programs/test.ncb` file contains a small, assembled program that demonstrates the CPU's basic functionality.\n    ```bash\n    cargo run -- programs/test.ncb\n    ```\n    You should see the emulator's debug output and the program's output to your console. The source assembly file is `programs/test.nca`.\n\n## 🛠️ Assembling\n\nTo assemble a program (say `example.nca`), run the NanoCore Assembler (`nca`):\n```bash\ncargo r --bin nca -- -i example.nca -o example.ncb\n```\nThis should assemble the `example.nca` (NanoCore Assembly) to `example.ncb` (NanoCore Binary).\n\n### Constants \u0026 Data\n\nYou can define constants using the `.CONST` directive, and embed data using `.DB` and `.STRING`:\n```assembly\n.CONST MAX_VAL 10\n.CONST ADDR 0x10\n\n.DB 0x01 0x02 10    ; Embed bytes 0x01, 0x02, 0x0A\n.STRING \"Hello\"     ; Embed ASCII bytes for \"Hello\"\n\nLDI R0 MAX_VAL\nJMP ADDR\n```\n\n## ⚙️ Running\n\nTo run this assembled binary, run:\n```bash\ncargo r -- example.ncb\n```\n\n## 🪄 Assemble and Run\n\nTo assemble and run without saving a binary:\n```bash\ncargo r -- example.nca\n```\n\u003e Note that the filename MUST end with the `.nca` extension to be considered a NanoCore Assembly file which will be automatically assembled before running.\n\n## 📟 Terminal Interface\n\nTo run the TUI visualizer:\n```bash\ncargo r --bin tui -- programs/counter.nca\n```\n\n## 🧪 Testing\n\nTo run the test suite, including assembler verification:\n```bash\ncargo test\n```\n\n## 📂 Code Structure\n\n  * `CPU (cpu.rs)`: Defines the CPU's internal state, including registers, program counter, stack pointer, memory, and flag bits.\n  * `NanoCore (nanocore.rs)`: The main emulator struct, responsible for loading programs, running cycles, and managing the `CPU`.\n      * `NanoCore::new()`: Initializes a fresh computer state.\n      * `NanoCore::load_program()`: Places machine code into the simulated memory.\n      * `NanoCore::run()`: Executes the CPU cycle loop until halted.\n      * `NanoCore::cycle()`: Performs a single CPU cycle (Fetch, Decode, Execute).\n      * `NanoCore::fetch_decode()`: Reads the instruction byte(s) from memory and determines its type and operands.\n      * `NanoCore::execute_instruction()`: Performs the operation defined by the decoded instruction, updating the CPU state.\n  * `Assembler (assembler.rs)`: The NanoCore assembler core.\n  * `Assembler bin (bin/nca.rs)`: The NanoCore assembler binary.\n  * `TUI bin (bin/tui.rs)`: The NanoCore Terminal UI.\n\n---\n\n## Example Program `Fibonacci Sequence`\n\n```assembly\n; Print the fibonacci sequence (two-digit)\nstart:\n    LDI R0 0\n    LDI R1 1\n    LDI R2 12\n    LDI R12 32\nloop:\n    JMP print_digits\n\npost_print:\n    MOV R3 R1\n    ADD R1 R0\n    MOV R0 R3\n    DEC R2\n\n    JNZ loop\nend:\n    HLT\n\nprint_digits:\n    PUSH R10\n    PUSH R11\n\n    MOV R10 R0\n    DIVI R10 10\n\n    JZ unit_digit\n\n    ADDI R10 48\n    PRINT R10\n\nunit_digit:\n    MOV R11 R0\n    MODI R11 10\n    ADDI R11 48\n    PRINT R11\n\nprint_space:\n    PRINT R12\n\n    POP R11\n    POP R10\n    JMP post_print\n```\n\n\n## 🤝 Contributing\n\nAll contributions are welcome. Please create an issue first for any feature request\nor bug. Then fork the repository, create a branch and make any changes to fix the bug\nor add the feature and create a pull request. That's it!\nThanks!\n\n---\n\n## 📄 License\n\n**NanoCore** is released under the MIT License.\nCheck out the full license [here](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAfaanBilal%2FNanoCore","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FAfaanBilal%2FNanoCore","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAfaanBilal%2FNanoCore/lists"}