This repository contains the code for the Factorio CPU, including an assembler and a python simulator.
I gave a talk at the 39th Chaos Communication Congress, the recording is here:
- https://media.ccc.de/v/39c3-cpu-entwicklung-in-factorio-vom-d-flip-flop-bis-zum-eigenen-betriebssystem#l=deu (German)
- https://youtu.be/FLUeSurkMOI (German)
- https://media.ccc.de/v/39c3-cpu-entwicklung-in-factorio-vom-d-flip-flop-bis-zum-eigenen-betriebssystem#l=eng (English, live-translated)
Few days later, I recorded an English video at home (basically translating my talk), which you can find here:
- 5‑stage pipelined architecture
- 32 general‑purpose registers
- 64 kB RAM
- 128 kB hard drive
- Interrupt handler
- ~700 Hz frequency
- Peripherals
- ASCII character display
- Color display
- Keyboard
- RNG
- We recommend the
uvPython Environment manager. Once installed, useuv syncto get the python environment. - Activate the environment using
. .venv/bin/activate(Linux/MacOS) or.venv\Scripts\activate(Windows).
-
You need Factorio (main game, not the Space Age expansion). You can get it from the developer, on Good Old Games, or on Steam.
-
Place the save file
factoriscoV3_official.zip(from the main folder of this repository) into your saves folder. You can find the folder using this article. -
Open Factorio and load the world. Confirm to load the needed mods.
-
You should be in the map editor (window top right corner, and missing character). If not, enter the map editor by pressing
Ctrl+Shift+F11in-game. -
It is recommended to add the UPS counter by pressing
F4to open the Debug Settings and enableshow-fps -
Change the simulation speed up to 64x by checking out the Time tab of the map editor
-
Standard speed has 60 UPS, so 64x can have up to 3700 UPS. However, most laptops will not reach that, and should be areound 700-1000 UPS. Try out 16x or 32x speed up for better scrolling experience (if you speed up by 64x and your machine does not support that, scrolling in the world becomes very slow)
-
If the clouds are going crazy, disable them in the main settings (
Esc>Settings>Graphics>Show clouds) -
You need to set a control in order to work with the Pushbuttons mod (used for the buttons from the keyboard). For that, go to
Esc>Settings>Controlsand search forToggle Entity. It should be in theDebugcategory. Set the key of that for example to the middle mouse button or the.key. -
Then, find the power button in the top right corner of the user display (next to the display). Hit the power button using the key you set in the last step. The terminal should appear
-
For a debug program, enter
R0in the editor using the keyboard of the CPU (and press one of the 3 buttons symbolizing theEnterkey). -
It should print 10 Fibonacci numbers, starting from 2.
-
There are already some example programs on the hard drive. Try out
RUN /BIN/MINEfor Minesweeper orRUN /BIN/SNAKEfor Snake. -
Next Section covers all the commands you can enter in the terminal.
The command line interface called FactOS is attached to the file system Chest32. Currently, there is no current working directory, instead you have to enter always the absolute path to a file or a folder.
Pay attention to the syntax, they are a bit quirky.. (TODO: Make better syntax)
FactOShas currently the following commands implemented:
CLS: Clears the screenR0: Runs the program currently loaded in ROM 0R1: Runs the program currently loaded in Rom 1LS <path>: List the contents of a folder. Example:LS /BINorLS /(for the root folder, the single/is mandatory)MKDIR <path> <folder name>: Creates a folder in the given folder path with name<folder name>. Max. 8 chars are allowed for a folder name. Example:MKDIR / testcreates a test folder in the root dir.TOUCH <path> <file name>: Same as MKDIR, but creates an empty file instead. Example:TOUCH /BIN EXAMPLEcreates a file/BIN/EXAMPLECPROM <ROM index> <file name>: Copies the content of the User Rom to a file. the File must exist (useTOUCHfor that). Example:CPROM 0 /BIN/EXAMPLERUN <path>: Executes the program given by the path. Example:RUN /BIN/EXAMPLERM <path>: Removes a file or a directory. The directory must be empty to remove it. Currently, there is no recursive mode implemented. Example:RM /BIN/EXAMPLEFSINIT: Formats the complete file system. The CPU will stop working and you have to restart the computer (power on -> power off).
You need to write an assembler program. An example is given in factosico_v_assembly/fib_5.s in this repository. The CPU uses mainly the RISC-V ISA, a (not the best documented, TODO) spreadsheet of the ISA is here:
ISA Spreadsheet
However, an overview of the assembly language is planned (TODO).
Once you have an assembly program, you can assemble it using the run_assembler.py script.
You have to define your program (the root is always the folder factorisco_v_assembly) in the run_assembler.py script (and omit the .s file extension). The script shows an example how to assemble factorisco_v_assembly/fib_5.s.
Then, run the assembler from the root directory of this repo:
python run_assembler.py
The assembler should print out a long string of the "Data Blueprint".
Copy that string (you can mark the whole line by clicking 3 times on it for most editors).
it will also save the blueprint string in output/factorisco/<your_program>.txt.
The decimal numbers for the instructions are saved in output/factorisco/<your_program>_machine_code.txt.
Then, open Factorio and press the "Import String" button in the bottom row:

Paste the copied string. A column of constant combinators should be loaded. Insert them either as the left column of ROM 0 or ROM 1.
Then, you can run the program by entering R0 or R1 inside the CPU terminal.
First of all, the simulator lacks right now the perfect user experience, but it is runnable with some minor steps:
- The main script is
run_simulator.pyin the main repo. - Start it from the root directory of this repo:
python run_simulator.py
- You need to provide a program to load besides the OS and the interrupt handler code. Right now, the compiled program fib_5 is loaded. You need to specify
output/factorisco/fib_5_machine_code.txtfor the simulatorfib_5.txtis the blueprint string and not readable to the simulator. the machine code is just a list of integers (i.e. the machine code in decimal format)
- If you want to try out your program, adapt the code in
run_simulator.py:- you can assemble it using
user_program("<Your program>", verbose=False)and then load it in the user program list.
- you can assemble it using
- Once the simulator opens, it should behave like the CPU in Factorio. That means you can execute your user program with the command
R0(=Run Program in ROM 0 slot). However, the file system is always empty (TODO: Save file system state over multiple runs) - Also, the color display is not implemented yet, so the display you see inside the simulator is just a stub
- Finally, programs like snake don't have a pause programmed, or a max FPS limit, so they will run too fast (nearly instant) in the simulator
- So to summarize: the simulator is not perfect yet, but it is a start.
