{"id":18191100,"url":"https://github.com/pescetti-studio/flip01-cpu","last_synced_at":"2025-07-22T11:03:10.366Z","repository":{"id":260833430,"uuid":"867192642","full_name":"pescetti-studio/Flip01-CPU","owner":"pescetti-studio","description":"A small and simple 8-bit CPU built in Logisim. The project also includes an assembler and a manual for those who want to learn how a processor works.","archived":false,"fork":false,"pushed_at":"2025-05-12T12:44:58.000Z","size":9985,"stargazers_count":28,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-07-22T11:02:41.879Z","etag":null,"topics":["8-bit-cpu","8bit","8bit-cpu","assembler","cpu","cpu-simulator","flip01","logisim","logisim-cpu","logisim-evolution","processor"],"latest_commit_sha":null,"homepage":"","language":"C++","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/pescetti-studio.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}},"created_at":"2024-10-03T15:57:40.000Z","updated_at":"2025-07-16T08:38:07.000Z","dependencies_parsed_at":"2024-11-02T22:26:03.172Z","dependency_job_id":"ca4ce357-f6cb-49cb-841c-e5cb1cb22742","html_url":"https://github.com/pescetti-studio/Flip01-CPU","commit_stats":{"total_commits":68,"total_committers":2,"mean_commits":34.0,"dds":"0.13235294117647056","last_synced_commit":"bf0ef8f3c68dc45f2d53a1b746e3b5c38701a686"},"previous_names":["pescetti-studio/flip01-cpu"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/pescetti-studio/Flip01-CPU","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pescetti-studio%2FFlip01-CPU","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pescetti-studio%2FFlip01-CPU/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pescetti-studio%2FFlip01-CPU/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pescetti-studio%2FFlip01-CPU/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pescetti-studio","download_url":"https://codeload.github.com/pescetti-studio/Flip01-CPU/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pescetti-studio%2FFlip01-CPU/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266481734,"owners_count":23935938,"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-07-22T02:00:09.085Z","response_time":66,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"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","8bit","8bit-cpu","assembler","cpu","cpu-simulator","flip01","logisim","logisim-cpu","logisim-evolution","processor"],"created_at":"2024-11-03T05:03:00.152Z","updated_at":"2025-07-22T11:03:10.343Z","avatar_url":"https://github.com/pescetti-studio.png","language":"C++","funding_links":["https://www.patreon.com/c/PescettiStudio/posts)!","https://www.patreon.com/PescettiStudio/posts","https://paypal.me/PescettiStudio?country.x=IT\u0026locale.x=it_IT)!"],"categories":[],"sub_categories":[],"readme":"# Flip01: a simple yet versatile 8-bit CPU\n\n# Overview\n\n**Flip01**, short for _First Level Instructional Processor_, is a small **8-bit CPU** with a **16-bit address bus**.  \nThis means it can handle data ranging from 0 to 2⁸–1 (255) and can store up to 2¹⁶ (65536 bit ~ 64 KB) different pieces of data.  \n\nData and addresses travel on two separate connection networks called the **data bus** and **address bus**, respectively.  \n\n![2](https://github.com/user-attachments/assets/67aaeb13-bdc0-4479-894d-588990f07793)\n\u003e The schematic datapath of Flip01: it shows the connections between the components and the two buses (Data and Address).\n\nFlip01 is based on a **Harvard architecture**, meaning that data and instructions (the actions the processor must execute) are stored in two separate memories: **MEM1 for data** and **MEM2 for instructions**.  \nMEM1 is an 8-bit memory with a capacity of 64 KB, while MEM2 is a 9-bit memory with a capacity of 64 KB.  \n\n![3](https://github.com/user-attachments/assets/ad15f7d3-d63a-4b4a-ba9b-cbd9139cb408)\n\u003e Schematic representation of the features of MEM1 and MEM2 and their connections to the rest of the circuit.\n\nTo move, temporarily store, and possibly modify these data, a component called register is used.  \n\n# REGISTERS\nIn very simple terms, a register can be described as a standalone memory cell with **fast read and write capabilities**.  \nIn Flip01, there are **10 main registers** (_+ 1: spoiler_), and their size and connection (data or address bus) are defined by their **specific function**.  \n\n- **AX:** This is the first of two **general-purpose registers**.  \n  This means it has no specific function within the processor but is used to store data for calculations.  \n  Since it only handles data, it is 8 bits in size and is connected solely to the **data bus**.\n- **BX:** The second and final **general-purpose register**, with the same properties as AX.\n  Like AX, it is 8 bits and connected only to the data bus. \n- **STAUTSAX (SAX):** An 8-bit register designed to **save the contents of AX** when needed.\n  It can only communicate with AX, so it is not directly connected to either the data bus or the address bus. \n- **STATUSBX (SBX):** A mirror register to STATUSAX.\n  It is also an 8-bit register but **saves the contents of BX** when required.\n  Like SAX, it is not connected directly to the data or address buses.\n- **DATA REGISTER (DR):** This register **communicates directly with the memory holding data** (MEM1).   \nSince it handles both data and addresses, it is a 16-bit register connected to **both the data and address buses**.   \nIt uses converters to adapt the size before input and output:\n  - On **input**, data is converted **from 8 to 16 bits** by padding with zeros.\n  - On **output**, data is converted back **from 16 to 8 bits** by discarding the first 8 bits.    \n  If any discarded bits contain data, an **error LED** will light up as a preventive measure.\n- **INSTRUCTION REGISTER (IR):** A mirror register to DR, but it **interfaces with the memory that holds instructions** (MEM2).   \nInstructions in memory are 9 bits long, divided as follows:   \nThe first bit specifies which general-purpose register (AX or BX) the instruction refers to:   \n  - **1 for AX, 0 for BX**.\n  - The remaining 8 bits contain the **actual instruction**.   \n  Only the 8 bits representing the instruction are loaded into the IR, so it is an 8-bit register.\n- **ALUIN:** Inside the processor, there is a unit responsible for performing calculations, called the ALU.   \nThe ALUIN register **takes and stores the first of the two operands for the ALU**.   \nThis is necessary because both operands cannot enter at the same time (they would conflict on the data bus).   \nThis register **holds the first operand** until the second arrives.   \nThe second operand doesn’t need to be stored since the ALU processes it immediately upon arrival.   \nThis register is also 8 bits, as it only handles data. \n- **ALUOUT:** This register **stores the result of the ALU operation**, then passes it to one of the general-purpose registers if needed for future operations.   \nALUOUT is also an 8-bit register.\n- **MEMORY ADDRESS REGISTER (MAR):** This register **stores the memory address of the data to be read or rewritten**.   \nIt is useful when an instruction refers to reading data from a specific memory location, which is different from the instruction’s own location.   \nMAR helps **retrieve the address of the data, locate it in memory, and either read its value or overwrite it with a new one**.   \nSince it deals only with addresses, it is a 16-bit register connected to the address bus both for input and output.   \nIt is also connected to the data bus for output, with a **16-to-8-bit converter** (similar to the one in DR) that triggers an error LED if data is lost during conversion. \n- **PROGRAM COUNTER (PC):** This register **holds the address of the next instruction to be executed**.   \nIt ensures that, at each step of the program, the processor knows exactly where to read the next instruction.   \nThis is particularly useful when the execution flow is non-linear.   \n_(foreshadowing jump instructions????)_   \nLike MAR, the PC is a 16-bit register connected to the address bus for both input and output and to the data bus for output, with an **intermediary converter**.   \n\nAll registers update when there is a state change in a common signal that goes to all components that require it.   \nThis signal is called **the clock**, and ideally, it looks like this:   \n\n![4](https://github.com/user-attachments/assets/c2511464-eeda-4584-a3a3-90f50d8c3842)\n\u003e A diagram showing the behavior of the clock signal over time.\n\nIt **oscillates between 0 and 1**, and the instant change from 0 to 1 **updates the values stored in the registers** based on the data circulating in the bus at that exact moment.   \n  \nIf registers are used to temporarily store data, as previously mentioned, another fundamental component called the **ALU** (_Arithmetic Logic Unit_) is used to modify it.   \n\n# ALU\nEvery processor has a different ALU in terms of **calculation power** or **data handling capabilities**.   \nThe ALU of Flip01 is designed to take **two 8-bit inputs** and produce a single output of the same size.   \n\nBased on the configuration and the combination of **6 binary control signals** (0 or 1), the ALU can perform **8 main operations** and **4 derived ones**.  \nThe 6 control signals are as follows:\n\n- **BRin:** Sets the second input of the ALU to 0.\n- **s0, s1, s2:** The unique combinations of these signals determine which of the 8 main operations will be executed.\n- **Cin, op:** These signals control **additional bits** for operations that require them.\n  \nThe 8 main operations are:\n\n- **ADD:** When given two inputs, A and B, this configuration **outputs the sum of the two**: `A + B`\n- **SUB:** With the same inputs, A and B, this configuration **outputs the difference**: `A — B`\n- **AND:** For the same inputs, this configuration performs a **bitwise AND operation** on A and B: `A AND B`   \nFollowing the logical structure of a single-bit AND operator.\n\n![5](https://github.com/user-attachments/assets/bc612089-21f1-4143-a9e3-3dcb9f56d757)\n\u003e Logic table of the AND operator (left) and two examples with 8-bit operands (right)\n\n- **OR:** For the same inputs, this configuration performs a **bitwise OR operation** on A and B: `A OR B`   \nFollowing the logical structure of a single-bit OR operator.\n\n![6](https://github.com/user-attachments/assets/6055b97d-bff2-442a-bdce-0e82994c1cac)\n\u003e Logic table of the OR operator (left) and two examples with 8-bit operands (right)\n\n- **NOT:** In this case, only one operand is considered as input (A).   \nThis configuration outputs the **bitwise inverse of the input operand**: `NOT A`   \nFollowing the logical structure of a NOT operator\n\n![7](https://github.com/user-attachments/assets/bb6cedb0-cdf2-448c-a791-0635abfcee20)\n\u003e Logic table of the NOT operator (left) and two examples with 8-bit operands (right)\n\n- **SHIFTL:** This configuration **shifts the bits of operand A to the left by B positions**, keeping the result 8 bits long.   \nThe vacated positions on the right are filled with 0 padding.\n- **SHIFTR:** This configuration **shifts the bits of operand A to the right by B positions**, keeping the result 8 bits long.   \nThe vacated positions on the left are filled with 0 padding, regardless of the leftmost bit (logical shift).\n\n![8](https://github.com/user-attachments/assets/46f9cf36-4804-4415-861c-f5a69d3c527c)\n\u003e Practical example of how left shift (shiftl) and right shift (shiftr) operations work.\n\n- **MUL:** With bits s0, s1, and s2 set this way, **operand A is multiplied by operand B**.\n  The operation performed is a standard arithmetic multiplication.\n\nBelow are the specific configurations for the 6 contol signals _(BRin, Cin, op, s0, s1, and s2)_ used for each of the 8 main operations.\n\n![12](https://github.com/user-attachments/assets/7855a9cf-6379-47aa-8ed1-4a9af3610faf)\n\u003e Control signal combinations that define the various main operations indicated.\n\nBy manipulating the ALU’s inputs, you can derive **four additional operations**:\n\n- **INC:** The first input to the ALU remains unchanged, while the second is forced to 1.   \nSetting the ALU to the add configuration gives `A + 1`, **incrementing the value by one unit**.\n- **DEC:** Similarly, the first input remains unchanged, while the second is forced to 1.   \nHowever, setting the ALU to the sub configuration gives `A — 1`, **decrementing the value by one unit**.\n- **0:** Regardless of the input, this operation **outputs the value 0**.   \nGiven input A, forcing the second input to 0 and performing an AND operation results in 0, no matter the value of A.\n- **A:** Finally, you can **output the same value as the first input without modifying it**.   \nGiven input A, forcing the second input to 0 and performing a sub operation results in A: `A — 0 = A`.   \n\n![11](https://github.com/user-attachments/assets/ce15d75f-0181-4de0-a23f-fb393ff980c0)\n\u003e Control signal combinations that define the four additional operations.\n\nConnected to the ALU there is an additional, **critical register**:\n\n## FLAG REGISTER\nThis is the third and final register that communicates with the ALU.   \n\nIt’s an 8-bit register where **each bit indicates a specific aspect of the most recent operation**:\n\n- **X (Shift/Mul Error):** This bit is set **if the number of bits to shift exceeds 8**, surpassing the maximum allowable length for the operands involved in the shift operation, **or if the result of a multiplication operation exceeds the usual 8-bit limit**.\n  The bit is updated regardless of the operation type. Therefore, if the operation performed is neither a shift (_shiftl or shiftr_) nor a multiplication (_mul_), the X flag bit can be ignored.\nIt can be ignored if the executed operation is of a different type.\n- **L _(A \u003c B)_:** This bit is set if **operand A is less than operand B** in absolute value.\n- **E _(A = B)_:** This bit is set if **operand A is equal to operand B** in absolute value.\n- **G _(A \u003e B)_:** This bit is set if **operand A is greater than operand B** in absolute value.\n- **C _(Carry)_:** This bit is set if there was a carry during the operation, meaning **the most significant bit had to generate a carry to the previous bit**.\n- **V _(Overflow)_:** This bit is set if **the result exceeds the 8-bit limit**, even though both operands are 8 bits.   \nThis indicates that an extra bit would have been required for the result to be correct.\n- **Z _(Zero)_:** This bit is set if **the result of the operation is zero**.\n- **N _(Negative)_:** This bit is set if **the result of the operation is negative** for any reason.\n\n\u003e [!TIP]\n\u003e Quick reminder before we continue: if you enjoy these kinds of projects, feel free to follow us **FOR FREE** on [Patreon](https://www.patreon.com/c/PescettiStudio/posts)!\n\u003e You’ll get early updates and exclusive content, and even a “_simple_” follow really helps keep these projects free and open source.\n\u003e Thanks :)\n\n# INSTRUCTIONS\n\nInstructions represent the full range of actions the processor can perform.   \nFlip01 has **48 instructions**, each identified by a **unique operation code** _(op-code)_ in hexadecimal format.   \n\nInstructions consist of **micro-instructions**, which are movements of data between registers or arithmetic and logical operations.   \nFor example, the addR instruction, which adds the contents of the two general-purpose registers AX and BX, is made up of the following micro-instructions:\n\n![12](https://github.com/user-attachments/assets/a89c9f5a-5935-4854-8315-a31251f71e5d)\n\u003e Example of reading and interpreting microinstructions (using the microinstructions of the add$ instruction as a case study).\n\nIf two micro-instructions operate on different buses (data and address) and are sequential, **they can be executed in the same clock cycle**, as no data will conflict.   \n\nIn MEM1 memory cells, it’s possible to assign a unique name to each cell, allowing access to it during program execution through read and write actions.   \nTo assign a name to a memory cell, the following syntax is used:   \n```\n[name] = [value]\n```\nThe **`=`** operator symbolizes an **assignment operation**.   \n\nFor the remainder of the manual, this type of memory cell will be referred to as a **VARIABLE**, adopting standard terminology.   \n\nIn textual form, this can be expressed as:   \n_“The cell named [name] will initially contain the value [value] at the start of the program.”_   \n\nThe **address of the memory cell**, or its location within MEM1, **is assigned procedurally**, typically as the first available cell after those reserved for program parameters.   \n\nThe value indicated represents only the initial assignment to the cell, and to modify its content later, you must use the CPU instructions.   \n\nCurrently, the instructions available on Flip01 can be grouped into **five categories**:\n1. **Direct addressing instructions**\n2. **Single-operand instructions**\n3. **Zero-operand instructions**\n4. **Immediate instructions**\n5. **Jump instructions**\n\n## Direct Addressing Instructions\nThese instructions consist of **two parameters**: the first is the **general-purpose register** (AX or BX) they refer to, and the second is the memory address containing the value to be considered.   \nIn Flip01’s high-level syntax, the memory address specified as the second parameter is associated with the **unique name of a variable**.   \nThese instructions involve memory access for reading the data.   \n```\nInstruction syntax: Instruction [register] [variable]\n```\n### **load**\n`(syntax: load [register] [variable])`   \n**_op-code: 0x02_**   \nThis instruction copies the value of the variable specified in the _[variable]_ parameter into the register indicated in the _[register]_ parameter.\n  - MEM1 _[variable]_ -\u003e DR\n  - DR -\u003e _[register]_\n    \nThe load instruction requires 2 clock cycles to execute.\n### **store** \n`(syntax: store [register] [variable])`   \nop-code: 0x04   \nThis instruction copies the value in the _[register]_ parameter into the memory cell assigned to the variable specified in the _[variable]_ parameter.\n  - _[register]_ -\u003e DR\n  - DR -\u003e MEM1 _[variable]_\n    \nThe store instruction requires 2 clock cycles to execute.\n### **add** \n`(syntax: add [register] [variable])`   \n_**op-code: 0x06**_   \nThis instruction adds the value associated with the _[variable]_ parameter to the value stored in the _[register]_ parameter. The result is saved in the specified register.   \n_[register]_ = _[register]_ + _[variable]_\n  - MEM1 _[variable]_ -\u003e DR, _[register]_ -\u003e ALUA\n  - DR + ALUA -\u003e ALUOUT\n  - ALUOUT -\u003e _[register]_\n    \nThe add instruction requires 3 clock cycles to execute.\n### **sub** \n`(syntax: sub [register] [variable])`   \n_**op-code: 0x09**_   \nThis instruction subtracts the value associated with the _[variable]_ parameter from the value stored in the _[register]_ parameter. The result is saved in the specified register.   \n_[register]_ = _[register]_ — _[variable]_\n  - MEM1 _[variable]_ -\u003e DR, _[register]_ -\u003e ALUA\n  - DR — ALUA -\u003e ALUOUT\n  - ALUOUT -\u003e _[register]_\n    \nThe sub instruction requires 3 clock cycles to execute.\n### **and** \n`(syntax: and [register] [variable])`   \n_**op-code: 0x0C**_   \nThis instruction performs a bitwise AND operation between the value stored in the _[register]_ and the value associated with the _[variable]_. The result is saved in the specified register.   \n_[register]_ = _[register]_ AND _[variable]_\n  - MEM1 _[variable]_ -\u003e DR, _[register]_ -\u003e ALUA\n  - DR AND ALUA -\u003e ALUOUT\n  - ALUOUT -\u003e _[register]_\n    \nThe and instruction requires 3 clock cycles to execute.\n### **or** \n`(syntax: or [register] [variable])`   \n_**op-code: 0x0F**_   \nThis instruction performs a bitwise OR operation between the value stored in the _[register]_ and the value associated with the _[variable]_. The result is saved in the specified register.   \n_[register]_ = _[register]_ OR _[variable]_\n  - MEM1 _[variable]_ -\u003e DR, _[register]_ -\u003e ALUA\n  - DR OR ALUA -\u003e ALUOUT\n  - ALUOUT -\u003e _[register]_\n    \nThe or instruction requires 3 clock cycles to execute.\n### **cmp** \n`(syntax: cmp [register] [variable])`   \n_**op-code: 0x30**_   \nThe CMP instruction compares the value in the register specified in the _[register]_ field with the value of the variable indicated in the _[variable]_ field.   \nThe flags are updated upon completion of this operation.\n  - MEM1 _[variable]_ -\u003e DR, _[register]_ -\u003e ALUA\n  - ALUA — DR -\u003e ALUOUT\n    \nThe cmp instruction requires 2 clock cycles to execute.\n\n### **test** \n`(syntax: test [register] [variable])`   \n_**op-code: 0x69**_   \nThis instruction performs an AND operation between the value stored in the _[register]_ and the specified _[variable]_. The result is stored in the specified register.   \n_[register]_ AND _[variable]_\n- MEM1 _[variable]_ -\u003e DR, _[register]_ -\u003e ALUA\n- DR AND ALUA -\u003e ALUOUT\n  \nThe test instruction requires 2 clock cycles to execute.\n\n### **mul** \n`(syntax: mul [register][variable])`   \n_**op-code: 0x60**_   \nThis instruction multiplies the value stored in the _[register]_ by the value specified in _[variable]_.\n_[register]_ = _[register]_ * _[variable]_\n- MEM1 _[variable]_ -\u003e DR, _[register]_ -\u003e ALUA\n- ALUA * DR -\u003e ALUOUT\n- ALUOUT -\u003e _[register]_\n  \nThe mul instruction requires 3 clock cycles to execute.\n\n## Single-Operand Instructions\nThese instructions involve only one parameter, usually the general-purpose register (AX or BX) they refer to.   \n```\nInstruction syntax: Instruction [register]\n```\n### **not** \n`(syntax: not [register])`   \n_**op-code: 0x12**_   \nThis instruction inverts the bits of the value stored in the _[register]_. The result is saved in the specified register.   \n_[register]_ = NOT _[register]_\n  - DR -\u003e ALUA\n  - ALUA — _[register]_ -\u003e ALUOUT\n  - ALUOUT -\u003e _[register]_\n    \nThe not instruction requires 3 clock cycles to execute.\n### **neg** \n`(syntax: neg [register])`   \n_**op-code: 0x15**_   \nThis instruction negates the value stored in the _[register]_. The result is saved in the specified register.    \n_[register]_ = NEG _[register]_\n  - DR -\u003e ALUA\n  - ALUA — _[register]_ + 1 -\u003e ALUOUT\n  - ALUOUT -\u003e _[register]_\n    \nThe neg instruction requires 3 clock cycles to execute.\n### **inc** \n`(syntax: inc [register])`   \n_**op-code: 0x24**_   \nThis instruction increments the value stored in the _[register]_ by 1. The result is saved in the specified register.   \n_[register]_ = _[register]_ + 1\n  - _[register]_ -\u003e ALUA\n  - ALUA + 1 -\u003e ALUOUT\n  - ALUOUT -\u003e _[register]_\n    \nThe inc instruction requires 3 clock cycles to execute.\n### **dec** \n`(syntax: dec [register])`   \n_**op-code: 0x27**_   \nThis instruction decrements the value stored in the _[register]_ by 1. The result is saved in the specified register.   \n_[register]_ = _[register]_ — 1\n  - _[register]_ -\u003e ALUA\n  - ALUA — 1 -\u003e ALUOUT\n  - ALUOUT -\u003e _[register]_\n    \nThe dec instruction requires 3 clock cycles to execute.\n### **rnd** \n`(syntax: rnd [register])`   \n_**op-code: 0x37**_   \nThis instruction stores a random value between 0 and 255 in the _[register]_.\n  - RND-\u003e _[register]_\n    \nThe rnd instruction requires 1 clock cycle to execute.\n### **save** \n`(syntax: save [register])`   \n_**op-code: 0x5C**_   \nThis instruction copies the value from the _[register]_ into the corresponding status register.\n  - _[register]_ -\u003e STATUS _[register]_\n    \nThe save instruction requires 1 clock cycle to execute.\n### **read** \n`(syntax: read [register])`   \n_**op-code: 0x5D**_   \nThis instruction copies the value from the corresponding status register into the _[register]_.\n  - STATUS _[register]_ -\u003e _[register]_\n    \nThe read instruction requires 1 clock cycle to execute.\n### **copy** \n`(syntax: copy _[register]_)`   \n_**op-code: 0x73**_   \nThis instruction copies the value in the specified [register] to another register.\n- _[register]_ -\u003e ALUA\n- ALUA OR 0 -\u003e ALUOUT\n- ALUOUT -\u003e AX, ALUOUT -\u003e BX\n\nThe copy instruction requires 3 clock cycles to execute.\n\n## Zero-Operand Instructions\nThese instructions do not take any parameters.   \nThey primarily act on the processor state or perform operations between the two general-purpose registers, without needing to specify a target.\n```\nInstruction syntax: Instruction\n```\n### **addR** \n`(syntax: addR)`   \n_**op-code: 0x18**_   \nThis instruction adds the values contained in the two general-purpose registers (AX and BX). The result is stored in register AX.   \nAX = AX + BX\n  - AX -\u003e ALUA\n  - ALUA + BX -\u003e ALUOUT\n  - ALUOUT -\u003e AX\n    \nThe addR instruction requires 3 clock cycles to execute.\n### **subR** \n`(syntax: subR)`   \n_**op-code: 0x1E**_   \nThis instruction subtracts the value in register BX from the value in register AX. The result is stored in register AX.   \nAX = AX — BX\n  - AX -\u003e ALUA\n  - ALUA — BX -\u003e ALUOUT\n  - ALUOUT -\u003e AX\n    \nThe subR instruction requires 3 clock cycles to execute.\n### **andR** \n`(syntax: andR)`   \n_**op-code: 0x21**_   \nThis instruction performs a bitwise AND operation between the values stored in the general-purpose registers. The result is stored in register AX.   \nAX = AX AND BX\n  - AX -\u003e ALUA\n  - ALUA AND BX -\u003e ALUOUT\n  - ALUOUT -\u003e AX\n    \nThe andR instruction requires 3 clock cycles to execute.\n### **orR** \n`(syntax: orR)`   \n_**op-code: 0x1B**_   \nThis instruction performs a bitwise OR operation between the values stored in the general-purpose registers. The result is stored in register AX.   \nAX = AX OR BX\n  - AX -\u003e ALUA\n  - ALUA OR BX -\u003e ALUOUT\n  - ALUOUT -\u003e AX\n    \nThe orR instruction requires 3 clock cycles to execute.\n### **cmpR** \n`(syntax: cmpR)`   \n_**op-code: 0x32**_   \nThis instruction compares the values stored in the general-purpose registers. The comparison is performed by subtracting the value in register BX from the value in register AX, updating the Flag register accordingly, and discarding the result.\n  - AX -\u003e ALUA\n  - ALUA — BX -\u003e ALUOUT\n    \nThe cmpR instruction requires 2 clock cycles to execute.\n### **flip** \n`(syntax: flip)`   \n_**op-code: 0x34**_   \nThis instruction swaps the values stored in the two general-purpose registers (AX and BX).\n  - AX -\u003e ALUA\n  - BX -\u003e AX, ALUA-\u003e ALUOUT\n    \nThe flip instruction requires 2 clock cycles to execute.\n### **stop** \n`(syntax: stop)`   \n_**op-code: 0x38**_   \nThis instruction halts the execution of the program.\n  - CLKDIS = 1\n  - (wait)\n    \nThe stop instruction requires 2 clock cycles to execute.\n### **testR** \n`(syntax: testR)`   \n_**op-code: 0x6B**_   \nThis instruction performs an AND operation between the two general-purpose registers. The result is stored in the AX register.   \nAX AND BX\n- [register] -\u003e ALUA\n- ALUA -1 -\u003e ALUOUT\n- ALUOUT -\u003e [register]\n  \nThe testR instruction requires 3clock cycles to execute.\n### **nop** \n`(syntax: nop)`   \n_**op-code: 0x6F**_   \nThis instruction does nothing.\n- nothing\n  \nThe nop instruction requires 1 clock cycle to execute.\n### **wait** \n`(syntax: wait)`   \n_**op-code: 0x70**_   \nThis instruction does nothing for 3 clock cycles, creating a 5-cycle pause in execution (including 2 fetch cycles).\n- nothing\n- nothing\n- nothing\n  \nThe wait instruction requires 3 clock cycles to execute.\n\n### **mulR**\n`(syntax: mulR)`   \n_**op-code: 0x63**_   \nThis instruction multiplies the values in the two general-purpose registers. The result is stored in the AX register.   \nAX = AX * BX\n- AX -\u003e ALUA\n- ALUA * BX -\u003e ALUOUT\n- ALUOUT -\u003e AX\n  \nThe mulR instruction requires 3 clock cycles to execute.\n\n## Immediate Instructions\nThese instructions consist of two parameters: the first is the general-purpose register (AX or BX) they refer to, and the second is the constant value to be considered.\n```\nInstruction syntax: Instruction [register] [value]\n```\nUnlike direct instructions, these instructions do not require memory access to read the data.     \n\n### **load$** \n`(syntax: load$ [register] [value])`   \n_**op-code: 0x59**_   \nThis instruction copies the _[value]_ parameter into the _[register]_. It is a load instruction.\n  - DR -\u003e _[register]_\n    \nThe load$ instruction requires 1 clock cycle to execute.\n### **add$** \n`(syntax: add$ [register] [value])`   \n_**op-code: 0x50**_   \nThis instruction adds the _[value]_ parameter to the value stored in the _[register]_. The result is saved in the specified register.   \n_[register]_ = _[register]_ + _[value]_\n  - _[register]_ -\u003e ALUA\n  - ALUA + DR -\u003e ALUOUT\n  - ALUOUT -\u003e _[register]_\n    \nThe add$ instruction requires 3 clock cycles to execute.\n### **sub$** \n`(syntax: sub$ [register] [value])`   \n_**op-code: 0x4D**_   \nThis instruction subtracts the _[value]_ parameter from the value stored in the _[register]_. The result is saved in the specified register.   \n_[register]_ = _[register]_ — _[value]_\n  - _[register]_ -\u003e ALUA\n  - ALUA — DR -\u003e ALUOUT\n  - ALUOUT -\u003e _[register]_\n    \nThe sub$ instruction requires 3 clock cycles to execute.\n### **and$** \n`(syntax: and$ [register] [value])`   \n_**op-code: 0x53**_   \nThis instruction performs a bitwise AND operation between the value stored in the _[register]_ and the _[value]_ parameter. The result is saved in the specified register.   \n_[register]_ = _[register]_ AND _[value]_\n  - _[register]_ -\u003e ALUA\n  - ALUA AND DR -\u003e ALUOUT\n  - ALUOUT -\u003e _[register]_\n    \nThe and$ instruction requires 3 clock cycles to execute.\n### **or$** \n`(syntax: or$ [register] [value])`   \n_**op-code: 0x56**_   \nThis instruction performs a bitwise OR operation between the value stored in the _[register]_ and the _[value]_ parameter. The result is saved in the specified register.   \n_[register]_ = _[register]_ OR _[value]_\n  - _[register]_ -\u003e ALUA\n  - ALUA OR DR -\u003e ALUOUT\n  - ALUOUT -\u003e _[register]_\n    \nThe or$ instruction requires 3 clock cycles to execute.\n### **shiftl$** \n`(syntax: shiftl$ [register] [value])`   \n_**op-code: 0x2A**_   \nThis instruction performs a logical left shift on the value stored in the _[register]_ by the number of bits specified in the _[value]_ parameter. The result is saved in the specified register.   \n_[register]_ = _[register]_ shiftl _[value]_\n  - _[register]_ -\u003e ALUA\n  - ALUA SHIFTL DR -\u003e ALUOUT\n  - ALUOUT -\u003e _[register]_\n    \nThe shiftl$ instruction requires 3 clock cycles to execute.\n### **shiftr$** \n`(syntax: shiftr$ [register] [value])`   \n_**op-code: 0x2D**_   \nThis instruction performs a logical right shift on the value stored in the _[register]_ by the number of bits specified in the [value] parameter. The result is saved in the specified register.   \n_[register]_ = _[register]_ shiftr _[value]_\n  - _[register]_ -\u003e ALUA\n  - ALUA SHIFTR DR -\u003e ALUOUT\n  - ALUOUT -\u003e _[register]_\n    \nThe shiftr$ instruction requires 3 clock cycles to execute.\n### **cmp$** \n`(syntax: cmp$ [register] [value])`   \n_**op-code: 0x5A**_   \nThis instruction compares the value stored in the [register] with the _[value]_ parameter.   \nThe comparison is performed by subtracting the _[value]_ from the register’s value, updating the Flag register accordingly, and discarding the result.\n  - _[register]_ -\u003e ALUA\n  - ALUA OR DR -\u003e ALUOUT\n    \nThe cmp$ instruction requires 2 clock cycles to execute.\n### **test$** \n`(syntax: test _[register] [value]_)`   \n_**op-code: 0x6D**_   \nThis instruction performs an AND operation between the value stored in the _[register]_ and the specified _[variable]_. The result is stored in the _[register]_.   \n_[register]_ AND _[variable]_\n- _[register]_ -\u003e ALUA\n- ALUA — DR-\u003e ALUOUT\n- ALUOUT -\u003e _[register]_\n  \nThe test$ instruction requires 3 clock cycles to execute.\n\n### **mul$** \n`(syntax: mul$ [register][value])`   \n_**op-code: 0x66**_   \nThis instruction multiplies the value stored in the _[register]_ by the value specified in _[value]_.   \n_[register]_ = _[register]_ * _[value]_\n- _[register]_ -\u003e ALUA\n- ALUA * DR -\u003e ALUOUT\n- ALUOUT -\u003e _[register]_\n  \nThe mul$ instruction requires 3 clock cycles to execute.\n\n## Jump Instructions\nThese instructions interrupt the linear execution of the program to execute code segments identified by labels. \n```\nInstruction syntax: Instruction [label]\n```\n### **jmp** \n`(syntax: jmp [label])`   \n_**op-code: 0x4C**_   \nThis instruction unconditionally jumps to the specified _[label]_.\n  - DR -\u003e PC\n    \nThe jmp instruction requires 1 clock cycle to execute.\n### **jc** \n`(syntax: jc [label])`   \n_**op-code: 0x3A**_   \nThis instruction jumps to the specified _[label]_ if the carry bit © is set to 1 by the previous instruction.\n  - DR -\u003e PC\n    \nThe jc instruction requires 1 clock cycle to execute.\n### **jv** \n`(syntax: jv [label])`   \n_**op-code: 0x3C**_   \nThis instruction jumps to the specified _[label]_ if the overflow bit (V) is set to 1 by the previous instruction.\n  - DR -\u003e PC\n    \nThe jv instruction requires 1 clock cycle to execute.\n### **jn** \n`(syntax: jn [label])`   \n_**op-code: 0x3E**_   \nThis instruction jumps to the specified _[label]_ if the negative bit (N) is set to 1 by the previous instruction.\n  - DR -\u003e PC\n    \nThe jn instruction requires 1 clock cycle to execute.\n### **jz** \n`(syntax: jz [label])`   \n_**op-code: 0x40**_   \nThis instruction jumps to the specified _[label]_ if the zero bit (Z) is set to 1 by the previous instruction.\n  - DR -\u003e PC\n    \nThe jz instruction requires 1 clock cycle to execute.\n### **je** \n`(syntax: je [label])`   \n_**op-code: 0x42**_   \n⚠ This instruction must immediately follow a compare instruction (cmp, cmpR, cmp$).   \nIt jumps to the specified _[label]_ if and only if the operands specified by the previous compare instruction are equal; otherwise, the program continues normally.\n  - DR -\u003e PC\n    \nThe je instruction requires 1 clock cycle to execute.\n### **jg** \n`(syntax: jg [label])`   \n_**op-code: 0x44**_   \n⚠ This instruction must immediately follow a compare instruction (cmp, cmpR, cmp$).   \nIt jumps to the specified _[label]_ if and only if the first operand in the previous compare instruction is greater than the second operand; otherwise, the program continues normally. \n  - DR -\u003e PC\n    \nThe jg instruction requires 1 clock cycle to execute.\n### **jl** \n`(syntax: jl [label])`   \n_**op-code: 0x46**_   \n⚠ This instruction must immediately follow a compare instruction (cmp, cmpR, cmp$).   \nIt jumps to the specified _[label]_ if and only if the first operand in the previous compare instruction is less than the second operand; otherwise, the program continues normally.\n  - DR -\u003e PC\n    \nThe jl instruction requires 1 clock cycle to execute.\n### **jle** \n`(syntax: jle [label])`   \n_**op-code: 0x48**_   \n⚠ This instruction must immediately follow a compare instruction (cmp, cmpR, cmp$).   \nIt jumps to the specified _[label]_ if and only if the first operand in the previous compare instruction is less than or equal to the second operand; otherwise, the program continues normally.\n  - DR -\u003e PC\n    \nThe jle instruction requires 1 clock cycle to execute.\n### **jge** \n`(syntax: jge [label])`   \n_**op-code: 0x4A**_   \n⚠ This instruction must immediately follow a compare instruction (cmp, cmpR, cmp$).   \nIt jumps to the specified _[label]_ if and only if the first operand in the previous compare instruction is greater than or equal to the second operand; otherwise, the program continues normally.\n  - DR -\u003e PC\n    \nThe jge instruction requires 1 clock cycle to execute.\n\nA processor must also be capable of receiving data from external sources, processing it, and displaying it to the user.  \nTo accomplish this, Flip01 utilizes an external circuit called the Input \u0026 Output Manager, or simply the: \n\n# I/O Manager\nThis circuit is responsible for reading from and writing to **64 unique I/O devices**.   \nSplit into **32 input devices** and **32 output devices**, each port has an identifier ranging from 0 to 31.  \nDuring the program, the user will decide which port to connect their devices to and assign them an identifier number accordingly.   \n\nIn the demo version of Flip01 on Logisim, both in the `“Flip01_Full”` circuit and the `“Playground”` version (which features a compact processor design to facilitate external connections), the I/O Management module **already has devices connected in specific positions**, with ports already assigned.   \n\n### input\n- Port **I00** — Keyboard Data [7 bits]\n- Port **I01** — Keyboard Ready: Indicates if the keyboard buffer contains a character [1 bit]\n- Port **I23** — BTN0: A push-button _(1/8)_ [1 bit]\n- Port **I24** — BTN1: A push-button _(2/8)_ [1 bit]\n- Port **I25** — BTN2: A push-button _(3/8)_ [1 bit]\n- Port **I26** — BTN3: A push-button _(4/8)_ [1 bit]\n- Port **I27** — BTN4: A push-button _(5/8)_ [1 bit]\n- Port **I28** — BTN5: A push-button _(6/8)_ [1 bit]\n- Port **I29** — BTN6: A push-button _(7/8)_ [1 bit]\n- Port **I30** — BTN7: A push-button _(8/8)_ [1 bit]\n\nThe **21 input ports** from **I02 to I22** are unassigned and can be freely used by the user.\n\n### output\n- Port **O00** — TTY Data (Teletypewriter, capable of displaying text messages) [7 bits]\n- Port **O01** — RGB Video X Coordinate [8 bits]\n- Port **O02** — RGB Video Y Coordinate [8 bits]\n- Port **O03** — RGB Video Write Enable: When set to 1, it writes to the cursor position defined by X and Y [1 bit]\n- Port **O04** — LED State 0: Turns on if it receives 1, and stays on until it receives 2, and vice versa _(1/4)_ [2 bits]\n- Port **O05** — LED State 1: Turns on if it receives 1, and stays on until it receives 2, and vice versa _(2/4)_ [2 bits]\n- Port **O06** — LED State 2: Turns on if it receives 1, and stays on until it receives 2, and vice versa _(3/4)_ [2 bits]\n- Port **O07** — LED State 3: Turns on if it receives 1, and stays on until it receives 2, and vice versa _(4/4)_ [2 bits]\n- Port **O23** — LED Matrix 8x8 Row 0 _(1/8)_ [8 bits]\n- Port **O24** — LED Matrix 8x8 Row 1 _(2/8)_ [8 bits]\n- Port **O25** — LED Matrix 8x8 Row 2 _(3/8)_ [8 bits]\n- Port **O26** — LED Matrix 8x8 Row 3 _(4/8)_ [8 bits]\n- Port **O27** — LED Matrix 8x8 Row 4 _(5/8)_ [8 bits]\n- Port **O28** — LED Matrix 8x8 Row 5 _(6/8)_ [8 bits]\n- Port **O29** — LED Matrix 8x8 Row 6 _(7/8)_ [8 bits]\n- Port **O30** — LED Matrix 8x8 Row 7 _(8/8)_ [8 bits]\n- Port **O31** — Reset Bit: When set to 1, it resets the connected device.   \nIf multiple devices are in use, it might be helpful to assign different reset bits to reset devices at different times.\n\nThe **15 output ports** from **O08 to O22** are unassigned and can be freely used by the user.     \n\nIf you need to change the reference ports for certain components, you will have to **update the corresponding port** entered as a constant within the module.   \nThe port inside the module must match the selected port.   \nThis step is also crucial if **additional components of the same type** are added.   \nThe devices that require this change are:   \n\n+ **The 8x8 LED matrix controller**: Each row corresponds to an output, meaning each port must be synchronized with the I/O Manager.\n+ **The RGB video controller**: The X and Y coordinate inputs correspond to two ports that also need to be synchronized with the I/O Manager.\n\n## I/O Instructions\nThese instructions **handle the communication between external devices and the CPU**.   \nThey require **two parameters**: the first is the register that will be affected by the instruction, while the second is the name of the device that will interact with that register.\n```\nInstruction syntax: Instruction [register][device]\n```\n### **input** \n`(syntax: input [register] [device])`   \n_**op-code: 0x5E**_   \nThis instruction reads the value transmitted from the input device _[device]_ connected to the port _[port number]_ and copies it into the specified register _[register]_.   \nEach input device must be declared using the syntax:   \n_\u003e [device] [port number]_\n  - DR -\u003e I/O Manager, _[device]_ \u003e _[register]_\n    \nThe input instruction requires 1 clock cycle to execute.\n### **output** \n`(syntax: output [register] [device])`   \n_**op-code: 0x5F**_   \nThis instruction reads the value stored in the specified register _[register]_ and transmits it to the output device _[device]_ connected to the port _[port number]_.   \nEach output device must be declared using the syntax:   \n_\u003c [device] [port number]_\n  - DR -\u003e I/O Manager, _[register]_ \u003e _[device]_\n    \nThe output instruction requires 1 clock cycle to execute.   \n\nWriting programs and manually replacing op-codes, hexadecimal values, and addresses can be tiresome, so we have created a small **assembler**, which acts as a **translator from high-level language**.\n\n# THE ASSEMBLER\nThis program is responsible for **translating mnemonic instructions** (load, sub, add$, etc.) into their corresponding opcodes, while also converting numeric values and memory references into formats understandable by the processor.\n\n![4](https://github.com/user-attachments/assets/6da3b320-6bfd-496b-ae5a-4adff5caa7a8)\n\u003e The assembler after startup\n\nThe code should be written in the panel that, on startup, displays the message `“write your text here”`.   \nThe conversion is automatically shown in the space below.     \n\n**To disable the live machine code conversion**, simply press the corresponding button labeled Live analysis enabled.  \nAt that point, the button and interface will indicate that live translation has been paused.    \n**To resume real-time conversion** or to view the corresponding translation, press the button again.   \n\nTo:\n\n- **open a text file** (.txt) containing code you want to analyze\n- **save the current file**\n- **clear the content**\n- **start a new file**\n\njust click the corresponding buttons.   \n\nAfter specifying the name or the path for the current file, it won’t be necessary to do so again, and all subsequent saves will be made to that file.   \nThis continues until the user initializes a new file via the New Code button.   \n\nThe assembler comes with a built-in decimal-hexadecimal-binary converter.   \nTo access it, just click the **Conversion Table** button, which opens the converter in a new window.   \nSimply select the input format, enter the value in the text bar, and the conversions into all three formats will happen automatically.   \nA control panel below the results **displays any input errors or format issues** in real time.  \n\n![6](https://github.com/user-attachments/assets/2d74f8f1-4a2c-4a90-9410-63871ffaae67)\n\u003e The converter\n\n\u003e [!NOTE]\n\u003e Closing the converter window won’t affect the assembler, but closing the assembler will also close the converter window if it’s open.  \n\nAnother handy feature of the assembler is the **View Manual** button.   \nAs the name suggests, it opens the free Flip01 manual in your default browser.   \nThe manual is incredibly useful for programming, as it includes a full description of the processor, along with opcodes, details, and explanations of all supported CPU instructions.  \n\nThe manual is a visually enhanced and easier-to-read version of the information found in this README.   \nIt’s the same free manual available on Medium, which has been previously mentioned.  \n\nAny changes made in the assembler’s text editor are automatically saved in a _log.txt_ file located in the same folder as the assembler.   \nIf the assembler crashes for any reason, your unsaved work won’t be lost.   \nYou can recover it by opening the _log.txt_ file directly from the assembler.   \nThink of it as a real-time safety net, creating backup files on the fly to safeguard your progress in case something goes wrong.\n\n**To add a comment to the code**, use the following syntax:\n```\n// Comment\n```\nComments can only be added at the beginning of a new line.   \n\n\u003e [!NOTE]\n\u003eThe assembler was developed in _C/C++_ using the _Dev C++ IDE_.\n\nWe hope that the UI and UX are quite intuitive, but it may be helpful to explicitly outline **all possible errors**, their **corresponding codes**, and **how to resolve them**:   \n\n## Errors\n- **E — 000:** The file you are trying to open and read using the designated button may be corrupted or unreachable.   \nPlease check that the file is intact and in the correct format (.txt).\n- **E — 001:** The code you have written is too large for Flip01!   \nTry to shorten it and clean it up by using calls to labels for repeated code segments.\n- **E — 002:** The instruction you have written is not among those supported by Flip01.   \nDouble-check that the syntax is correct and remember that the assembler is case-sensitive: instructions must be written in lowercase (except for the R in immediate instructions).\n- **E — 003:** The instruction does not have a declared variable as its second argument. This argument must not be a number.\n- **E — 004:** The instruction is missing some required parameters.   \nRefer to the previous chapter to check how many and which arguments are needed for each instruction.\n- **E — 005:** This instruction requires a general-purpose register (AX or BX) as the first argument.   \nThe parameter written in the first position is likely incorrect or undefined.\n- **E — 006:** The instruction has more parameters than required.   \nRefer to the previous chapter to check how many and which arguments are needed for each instruction.\n- **E — 007:** The argument associated with this direct instruction is too large!   \nRemember that acceptable values range from 0 to 255.\n- **E — 008:** The argument associated with the direct instruction is not an integer.   \nIt is likely that an alphanumeric value was entered or that this parameter has not been defined.\n- **E — 009:** The variable has not been declared at the beginning of the program.   \nEnsure that the variable name is spelled correctly and that the name written in the declaration matches the one used in the instruction.   \nRemember that the assembler is case-sensitive, and the declaration must follow the structure:   \n`[variable name] = [numeric value]`\n- **E — 010:** The value associated with the variable is not an integer.   \nAn alphanumeric value may have been entered, or this parameter has not been defined.\n- **E — 011:** This variable has been defined multiple times within the code.   \nRemember that to change the value of a memory cell, you must use processor instructions and not assignment operations; the latter are only for declarations.\n- **E — 012:** The value associated with this variable is too large! Acceptable values range from 0 to 255.\n- **E — 013:** The label has been called but not declared.   \nEach label must be defined with the syntax `[label:]`.   \nCheck for any spelling errors or issues related to the case-sensitivity of the assembler.\n- **E — 014:** This label is defined multiple times within the code.   \nA label can have only one definition, and two labels cannot share the same name.\n- **E — 015:** You have declared too many input devices.   \nFlip01 supports up to 32 different input devices.\n- **E — 016:** You have declared too many output devices.   \nFlip01 supports up to 32 different output devices.\n- **E — 017:** The name assigned to this variable is a number. Variable names must contain at least one letter.\n- **E — 018:** You have declared a device as input but then used it as output.   \nEnsure that the declaration and usage are consistent _(\u003e input)_.\n- **E — 019:** You have declared a device as output but then used it as input.   \nEnsure that the declaration and usage are consistent _(\u003c output)_.\n- **E — 020:** You are using a device that you have not declared.   \nEnsure that the name matches the declaration and remember that Flip01 is case-sensitive.\n- **E — 021:** The name assigned to this label is a number.   \nLabel names must contain at least one letter.\n- **E — 022:** The name assigned to this device is a number.   \nI/O device names must contain at least one letter.\n- **E — 023:** You have not specified which device to use for this input or output operation.\n- **E — 024:** The name you have chosen for this I/O device has already been used for another device.\n- **E — 025:** The port number you have chosen for this device has already been assigned to another device.   \nTo avoid conflicts, use different ports for different devices.\n- **E — 026:** The field that should contain the port number for the I/O device does not contain an integer.   \nPlease check the format.\n- **E — 027:** The port number assigned to this device is not a valid integer.   \nRemember that port numbers must be between 0 and 31.\n\n\u003e [!CAUTION]\n\u003e The assembler is only compatible with Windows-based operating systems\n\n# MICRO PROGRAM COUNTER\nThe micro program counter is a section of Flip01 that, upon receiving the op-code of the currently active function, **sequentially produces all the control signals** that regulate the state of each component of the circuit and define the operation of the micro-instructions associated with that instruction.   \n\nTo achieve this, the following steps are executed in sequence:\n\n1. The micro program counter **reads the first micro-instruction** from a third memory (MEM3) at the address corresponding to the op-code of the instruction.\n2. If there is another micro-instruction linked to that instruction, it executes it; otherwise, the address returns to 0, executing the fetch instruction, which retrieves the next instruction to be executed. **This process is repeated until the described condition becomes true**.\n\n![9](https://github.com/user-attachments/assets/3addefe3-ba99-456a-81e7-1aa8c4228804)\n\u003e The mechanism that outlines the sequential operation of Flip01’s micro program counter.\n\nThe memory accessed by the micro program counter (MEM3) is non-volatile, and **the set of control signal instructions is referred to as the ISA** (_Instruction Set Architecture_).\n\n\u003e [!TIP]\n\u003e One last note before wrapping up : if you enjoy these kinds of projects, feel free to follow us **FOR FREE** on [Patreon](https://www.patreon.com/c/PescettiStudio/posts)!\n\u003e You’ll get early updates and exclusive content, and even a “_simple_” follow really helps keep these projects free and open source.\n\u003e Thanks :)\n\n# How to Use the Processor (Beginner’s Tutorial)\nThe first step is to open the file **[Flip01_Circuit.circ](Flip01_Circuit.circ)** with **[Logisim Evolution](https://github.com/logisim-evolution/logisim-evolution)**.   \nAt this point, the file containing the entire circuit should open, but for now, we'll set it aside since we first need to generate the code for the CPU to interpret.   \n\nTo do this, you will need to open the **[assembler](Flip01_Assembler)** and write the code, or open a previously prepared file for this purpose _(you can find examples in the [Code Examples](Code_Examples) folder)_.   \nIf the code is correct and contains no errors, the assembler will directly produce the code readable by the CPU.   \n\nIt should look like this:   \n![5](https://github.com/user-attachments/assets/a290e868-8bca-40de-9aa2-5e11f9cc6cc9)\n\u003e Program successfully assembled: No errors or warnings detected.\n\nAt this point, simply copy the first line of hexadecimal values _(the one corresponding to the data)_ and paste it into the **RAM MEM1** component in the Logisim file. To do this, right-click on the component and select **`Edit Contents`**.   \n\nYou will need to repeat the same process with the second line of hexadecimal values _(the one corresponding to the instructions)_, pasting it into the **RAM MEM2** component in the Logisim file. Again, right-click on the component and select **`Edit Contents`**.   \n\nNow everything is ready to start the simulation. In the main menu at the top, click on **`Simulate`** to open a dropdown menu.   \nYou can modify the \"simulation speed\" by changing the **clock frequency** in the **`Auto-Tick Frequency`** section _(a higher value corresponds to a greater execution speed)_.   \n\nOnce you have made this choice, in the same dropdown menu, just press **`Auto-Tick Enabled`**, or use the shortcut `Ctrl + K`to start the simulation.      \n\nAs mentioned at the beginning of the guide, all the referenced files and additional materials are available here on **GitHub** and on **[Patreon](https://www.patreon.com/PescettiStudio/posts)** for **free**.     \n\nFlip01 has been in development for a long time, perhaps too long for what it is, and yet it is still far from being a complete project.   \nThere are still many possible implementations to explore, which is why I’ve made it open source.   \nNow Flip01 is in your hands; use your creativity, play with it, break it, and push beyond every limit we have designed.   \nHave fun! :)      \n \nFlip01 is a project by **Biasolo Riccardo** and **Croci Lorenzo**, developed for the **Pescetti Studio** collective.     \n\nIf you come across any errors, inaccuracies, or typos, feel free to reach out to us!   \nSend us an email at _**pescettistudio@gmail.com**_ with **[bug]** at the beginning of the subject line.   \n\n# Updates\n\n## Upgrade 1) FliPGA01\nThe basic version of Flip01 now also has an FPGA implementation! \n![Flipga01v2](https://github.com/user-attachments/assets/b26b4ea7-9e27-4e5a-aa8a-b5ccd1575914)  \nThe project, called FlipGA01, is of course free and open source.   \nYou can find all the files here on [GitHub](https://github.com/pescetti-studio/FliPGA01), and there’s a detailed guide available on [Medium](https://medium.com/@crocilorenzo01/flipga01-a-simple-8-bit-cpu-on-a-fpga-db3e0fb82fe6).\n\n## Upgrade 2) It’s Dangerous to Go Alone! Take This\nThis one’s all about the assembler, and it introduces three handy tools to make your life a little easier.\n![IDTGATT](https://github.com/user-attachments/assets/f199704e-40fe-4e39-a582-2b33414bb2bc)\n1. **Conversion Table**   \nNow you can quickly switch between binary, decimal, and hexadecimal values using a dedicated button.   \nThe converter opens in a separate window, leaving the main assembler workspace untouched.\n\n2. **View Manual**   \nA new button lets you open the free Flip01 manual in your default browser.   \nThis free detailed guide covers not just how to program Flip01, but everything you need to know about the processor itself.\n\n3. **Auto-Save Feature**   \nThis one's a bit behind-the-scenes: every change you make in the assembler is now automatically saved to a file named _log.txt_ in the same folder as the assembler.   \nIf the program crashes unexpectedly, you won’t lose your work!   \nSimply click _Open File_ after restarting, select _log.txt_, and pick up right where you left off.\n\n## Upgrade 3) Instruction Bonanza\n\nWe’ve added six new instructions\n\n![bonanza](https://github.com/user-attachments/assets/ee728237-8559-4e89-9a90-73274d34ff0c)\n\n- **test**: Performs an AND operation between the specified general-purpose register and the indicated variable, but doesn’t save the result.\n- **testR**: Performs an AND operation between two registers, again without saving the result.\n- **test$**: Performs an AND operation between the specified general-purpose register and the given value, but doesn’t save the result.\n- **nop**: Does nothing for 1 clock cycle.\n- **wait**: Does nothing for 3 clock cycles. Combined with the 2 fetch cycles, this creates a visible 5-cycle pause in execution.\n- **copy**: Copies the value from the specified general-purpose register into another general-purpose register.\n  \n\u003e [!NOTE]\n\u003e All the details on how to use these new instructions can be found in the dedicated section of this manual.\n\n\u003e [!IMPORTANT]\n\u003e The previously named **`pause`** instruction has been renamed to **`stop`** to avoid confusion.\n\u003e _All the sample programs here on GitHub and the various manuals online have already been updated._\n\n## Upgrade 4) X Factor\nWe've expanded Flip01's capabilities by adding a module for multiplication and updating all the necessary logic structures accordingly.\n\n![mul](https://github.com/user-attachments/assets/b20f7099-e1ad-4a9f-8fb8-4722eefda3b6)\n\nTo support this, we've introduced three new instructions specifically for handling multiplication operations:\n- **mul:** Multiplies the value in the specified general-purpose register with the indicated variable. The result is saved in the original register.\n- **mulR:** Multiplies the values in two general-purpose registers. The result is saved in the AX register.\n- **mul$:** Multiplies the value in the specified general-purpose register with the given constant. The result is saved in the original register.\n\n## Upgrade 5) Glorious Evolution\nThe three updates: \"_It’s Dangerous to Go Alone! Take This_\", \"_Instruction Bonanza_\" and \"_X Factor_\" are now available on Flip01's FPGA implementation: **FliPGA01**.\n\n![glorious evolution](https://github.com/user-attachments/assets/6c70be91-aeeb-42a0-9085-5b757b866a16)\n\nThe entire project is free, open-source, and accessible through [this GitHub repository](https://github.com/pescetti-studio/FliPGA01).\n\n\u003e [!NOTE]\n\u003e All the details on how to use these new instructions can be found in the dedicated section of this manual.\n\n\u003e [!IMPORTANT]\n\u003e The flag bit previously named X, which was used solely to check the validity of shift operations, has now been repurposed to also ensure that multiplication results stay within the 8-bit limit.\n\nDo you like this stuff?   \nSupport us with a [donation on PayPal](https://paypal.me/PescettiStudio?country.x=IT\u0026locale.x=it_IT)!   \nIt helps us keep everything free and open source for everyone.   \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpescetti-studio%2Fflip01-cpu","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpescetti-studio%2Fflip01-cpu","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpescetti-studio%2Fflip01-cpu/lists"}