Skip to content
/ ONICPU Public

ONICPU is a CPU mod for OxygenNotIncluded that allows you to build programmable code execution control units to implement complex automation functions.

License

Notifications You must be signed in to change notification settings

imengyu/ONICPU

Repository files navigation

ONICPU

English Readme <- Click Me

简介

ONICPU 是游戏缺氧的一个 CPU 模组,支持你建造可编程的代码执行控制单元,用它来实现复杂的自动化功能。

目前原版游戏只有简单的逻辑门自动化,这在实现一些很大型的电路时,会非常复杂,因此设计了这个模组,使用代码来控制自动化。

主要功能:

  • CPU 运算单元,支持 4 输入 4 输出 IO,8 输入 8 输出 IO
  • CPU 支持使用汇编代码或者 JavaScript 代码进行控制
  • 拓展线组读取器、线组写入器使其支持传输 32 位数值
  • 拓展一系列传感器,使其可以直接读取数值,传给 CPU 处理
  • 数码管显示

使用方法

CPU

你可以在自动化菜单中找到 CPU(需要先解锁相应科技树),目前有三种大小的 CPU:

  • 2 输入 2 输出 IO
  • 4 输入 4 输出 IO
  • 8 输入 8 输出 IO

CPU 左侧是输入端口,程序可以读取它的值,右侧是输出端口,可以输出值,控制下游连接的设备。 CPU 使用一个控制端口(中下位置)来进行控制,只有在控制端口接收到绿色信号时,单元才会启动。

启动状态下,你的程序默认会以 5Hz 的频率执行,在每个执行周期中,你可以读取输入参数,进行自定义计算,然后修改输出端口的值。

因为游戏代码限制,所有 CPU 端口最大支持 Int32(-2,147,483,648 ~ 2,147,483,647)

每种 CPU 都有两个版本,有(JavaScript)后缀的表示这个 CPU 使用 JavaScript 代码进行控制。JavaScript 简单易上手,汇编比较复杂但有趣,你可以选择自己喜欢的。

注意: 在代码中请不要使用 while 循环来做延迟,这会导致游戏卡住,应该使用变量计数器来实现延时。

代码编辑器

你可以在选中 CPU 单元后,在右侧菜单中点击“编写程序”,来打开编辑器,在编辑器中:

  • 顶部显示的是程序当前的状态信息
  • 在左侧输入框中编写代码
  • 右上角按钮控制程序运行、暂停。
  • 右侧显示的是实时的程序 IO 数值
    • 在汇编模式中,右侧还会显示寄存器、内存数据
    • 在 JavaScript 模式中,右侧还会显示程序输出日志信息

建议你可以在 Visual Studio Code 或者其他代码编辑器软件中编写好代码再复制到游戏中。

点击 立即编译 可以立即编译程序,编译会临时暂停运行程序,可以再点击上方运行按钮开始运行,点击 保存并关闭 可以编译程序然后关闭。

提示:CPU 是否运行是受控制端口是否有绿色信号控制的,但你在代码编辑器中手动点击运行时运行不受信号限制。

数字化传感器

本模组拓展了一系列传感器,使其可以直接读取数值,你可以将其连接至 CPU,然后就可以读取数值来进行相关处理。

数码管显示器

本模组添加了数值显示器,你可以用它来显示网络中的数值。分为 3 档,分别可以显示 8 位、16 位、32 位整数。

JavaScript

当你选择有(JavaScript)后缀的 CPU 后,你就可以开始用 JavaScript 写代码了。你的程序会以下方 3 个主要函数来组织:

  • start:程序启动时执行
  • stop:程序停止时执行
  • tick:程序在运行中每逻辑帧执行

tick 函数必须存在,否则 CPU 单元会停止执行,start 和 stop 可选。

function start() {
  //代码,启动时执行
}
function stop() {
  //代码,停止时执行
}
function tick() {
  //代码,每逻辑帧执行
}

你的主要程序通常应该写在 tick 函数中,tick 函数的推荐逻辑应该是,读取数据->处理数据->输出数据。

你可以在 Demo 目录 来查看几个示例

你还可以根据更多条件来实现更多复杂功能,下方是 CPU 单元一些支持的功能说明:

输入和输出: 你可以使用 io.PX 读取或设置引脚值。例如:

  • 读 P0 输入
let pin0value = io.P0;
  • 设置 P4 输出
io.P3 = 1;

注意:游戏会在名称 start、stop、tick 执行完毕后将修改后的输出值同步到信号网络。

存储数据: 你的代码中其他的位置声明变量,在每次编译/上电/游戏重新加载会丢失,需要手动加载。 模组内置了 storage 对象,在这个对象下的数据会被游戏保存,可以在下次存档加载后读取

  • 储存数据
storage.example = 31;
  • 读取数据
io.P3 = storage.example;

辅助函数

  • **getbit: 你可以调用 **getbit(io.P0, 1) 得到输入引脚的 1 位值。
  • **changebit: 你可以调用 io.P3 = **changebit(io.P3, 1, 0) 设置输出引脚的 1 位值=0。
  • **log: 你可以调用' **log('message') '来记录编辑器中的一些消息。
  • **reset: 调用 **reset() 来重置所有输出 IO
  • **shutdown: 你可以调用 **shutdown('error message') 来关闭这个 CPU 单元。

汇编

CPU 支持使用汇编代码。但汇编比较难,推荐还是使用 JavaScript,也可以用汇编,因为挺好玩的,但在写代码之前,你需要学习汇编相关知识。

本 CPU 支持的是类 C51 汇编(部分子集,和标准不一样),所有计算指令、寄存器大小均为 32 位。本文只说明 CPU 指令相关支持情况和特殊说明,汇编相关知识你需要到互联网上搜索相关资料。

指令格式

[操作码] [操作数] 例如: MOV A, P0 :label 标签

支持的寻址方式

  • 立即数寻址 #20H 例如:MOV A,#20H
  • 寄存器寻址 PSW / A / R1 例如:MOV A,R1
  • 寄存器间接寻址 @R1 / @REG1 例如:MOV A,@R1
  • 跳转寻址 :label 例如:jne :loop

支持的寄存器

  • R0-R7 内置通用寄存器
  • PSW 程序状态字寄存器 (与 8086 定义一致)
  • A
  • B
  • C
  • ACC 累加寄存器
  • SP 堆栈指针寄存器
  • PC 程序计数器

支持的指令表

无操作数指令

  • NOP
  • RST
  • HLT
  • POP

1 操作数指令

  • SWAP
  • PUSH
  • NEG
  • JMP
  • JE
  • JNE
  • JZ
  • JO
  • JNO
  • JS
  • JNS
  • JP
  • JNP
  • JC
  • JNC
  • JB
  • JNB
  • JA
  • JNA
  • JAE
  • JNAE
  • JBE
  • JNBE

2 操作数指令

  • MOV
  • XCHG
  • XCHD
  • ADD
  • SUB
  • INC
  • DEC
  • MUL
  • MOD
  • AND
  • OR
  • XOR
  • NOR
  • MOD
  • SHL
  • SHR
  • CMP

读取写入 IO

  • 读取写入 IO 简化了,无特殊指令,需要内置寄存器一样,直接读取/写入:MOV A, P0 或者 MOV P0, #11

示例程序

mov r0,#10 mov r1,#0 mov r2,#0 :loop inc r2 dec r0 cmp r0,r1 jne :loop mov p3,r2 hlt

Steam 模组页面

About

ONICPU is a CPU mod for OxygenNotIncluded that allows you to build programmable code execution control units to implement complex automation functions.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages