A Minecraft datapack that emulates a MIPS32 Release 6 processor in a Minecraft world.
This is still a work in progress, and there is much left to finish.
Aaron Lucia (@engineal)
Minecraft Java 1.16.2 or newer
This project provides several datapacks in the datapacks directory, detailed below.
To play around with this emulator, it is currently suggested to load the mips32r6 and boot datapacks. The other datapacks either are non-functional, broken, or used for development of this project.
- Go to the
Create New Worldmenu and enter a name for your world. - Choose
Game Mode: Creativeand ensure thatAllow Cheats: ONis selected. - Select
Data Packsand thenOpen Pack Folder. - Copy the datapacks you want to install into the folder that was opened.
- Select the datapacks you want to enable. Note that the ordering of the datapacks in the selected pane matters. The mips32r6 datapack should always be loaded first. If a datapack specifies any dependencies they must be loaded before it. You can reorder datapacks by using the up and down arrows when hovering over a datapack.
I prefer using The Void Superflat world type preset to initialize the world with no blocks:
- Select
More World Options...and chooseGenerate Structures: OFF. - Choose
World Type: Superflat, then selectCustomize. - Select
Presetsand useThe Voidpreset.
A world download may come eventually so that you can skip these steps, along with a zip file release of the datapacks.
Caution: this datapack will replace blocks in your world on load, so be careful if adding to an existing world! You may want to take a backup first!
- Copy the datapacks you want to install into the datapacks folder in your world's save file.
- Use the
datapackMinecraft command to list the available datapacks and to enable and disable them. Note that the ordering of the datapacks in the list matters. The mips32r6 datapack should always be loaded first. If a datapack specifies any dependencies they must be loaded before it. You can reorder datapacks by enabling the datapacks in the order you want them loaded.
The MIPS32 Release 6 emulator, a 256 KB ROM, and a 2 MB RAM.
This is the main datapack and it should be ordered before any of the others.
To start the emulator, set the running mips32r6_tick score to 1 by running the scoreboard players set running mips32r6_tick 1 Minecraft command.
To halt the emulator, set the running mips32r6_tick score to 0 by running the scoreboard players set running mips32r6_tick 0 Minecraft command.
A single CPU cycle can executed by running the function mips32r6:cpu Minecraft command, which can be useful to debug a program.
The reload Minecraft command will reset the emulator, clearing all registers and memory and placing the program counter at the reset vector.
By default, a single Minecraft tick will execute a single CPU cycle while the emulator is running, resulting in a base clock speed of 20Hz.
You can overclock the emulator by setting the multiplier mips32r6_tick score to the number of CPU cycles to execute per Minecraft tick.
Care should be taken so that you don't exceed the maxCommandChainLength gamerule limit; if a multiplier causes the command limit to be reached, you will see an error in the chat and the CPU will halt.
Depending on what the host computer can handle, with the default maxCommandChainLength of 65,536 an overclock with a x64 multiplier should be achievable, resulting in a clock speed of 1.28 kHz.
To debug the emulator, you can set emulator logging levels for each component using the following Minecraft commands:
scoreboard players set alu_level logging <level>(0-1)scoreboard players set cop0_level logging <level>(0-1)scoreboard players set cpu_level logging <level>(0-1)scoreboard players set gpr_level logging <level>(0-1)scoreboard players set mem_level logging <level>(0-4)scoreboard players set rom_level logging <level>(0-2)scoreboard players set ram_level logging <level>(0-2)
The Boot-MIPS bootloader for the MIPS32 Release 6 emulator.
- mips32r6
This datapack will load the Boot-MIPS bootloader into the ROM at the reset vector when the world is loaded or with the reload Minecraft command.
See mips32r6-usage for how to start the emulator.
A LCD display for the MIPS32 Release 6 emulator.
- mips32r6
Development in progress.
A test suite for the MIPS32 Release 6 emulator.
- mips32r6
Run the function #test:all Minecraft command to run every test. The test results will be reported in the Minecraft chat.
Individual tests or groups of tests may be also be run by executing those tags/functions directly.
A VGA display for the MIPS32 Release 6 emulator. (currently non-functional)
- mips32r6
This datapack will create a black screen in the world when the world is loaded or with the reload Minecraft command.
It currently does nothing else.
Example software for the MIPS32 Release 6 emulator. (currently broken)
- mips32r6
Please don't use.
This MIPS emulator will eventually be able to run any binary created for the MIPS32 architecture, although keep in mind this project is very much still a WIP. I've used the following toolchain to cross-compile for the MIPS architecture: https://codescape.mips.com/components/toolchain/2020.06-01/index.html.
Example commands:
- Assemble code:
as example.s -o example.o -mips32r6 - Or:
mips-mti-elf-gcc example.s -mips32r6 -c - Link code:
ld example.o -o example.bin --oformat=binary - Combined:
mips-mti-elf-gcc example.s -o example.bin -Xlinker --oformat=binary - Extract binary from object file:
objcopy -O binary example.o example.bin
MIPS binaries can be loaded into the emulator's memory through Minecraft commands. The included flash_mc Python app will convert binary files into a .mcfunction file, which you can then run in Minecraft to load the binary into memory.
Currently, the processor starts executing code at ROM address 0, so before loading any binaries, you might need to apply address offsets. The script allows you to specify the address that the binary will be loaded at, but will not relocate memory addresses yet.
- TLB
- Permanent storage
- Proper text mode display
- IO (such as buttons)
- Floating-point accelerator
- Multi-core GPU
- "Speakers"
- Linux
- Minecraft
The MIPS processor uses memory mapped I/O to communicate with other hardware components.
To create your own custom hardware that can communicate with this emulator:
-
Create a new minecraft datapack: https://minecraft.gamepedia.com/Data_pack.
Note: you'll want to make sure you create a new namespace for your component's functions. If you use the mips32r6 namespace or a namespace used by another datapack, you risk colliding with existing functions and something might break.
-
Create a new function to handle memory requests.
- This function should read the physical address from the
physical_address mips32r6_memscoreboard value. Your function should only respond to the range of physical addresses this device listens to, the function should not do anything if the physical address is outside this range. You'll have to make sure this range doesn't collide with any other hardware components. - This function should read the access length in bits from the
length mips32r6_memscoreboard value. - This function should read the read/write mode from the
write mips32r6_memscoreboard value. If the value ofwrite mips32r6_memis 0, the memory request is a read request. If the value ofwrite mips32r6_memis 1, the memory request is a write request.- If the memory request is a read request, this function should return the result in the
value mips32r6_memscoreboard value. - If the memory request is a write request, this function should read the value to write from the
value mips32r6_memscoreboard value.
- If the memory request is a read request, this function should return the result in the
- This function should increment the
handled mips32r6_memscoreboard value.
- This function should read the physical address from the
-
Tag this function in the mips32r6:mem tag by including your function in a file in your datapack with this path:
data/mips32r6/tags/functions/mem.json.
Reference the RAM, ROM, LCD, and VGA hardware components in this repo for examples.
Copyright (c) 2020 Aaron Lucia
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.