From 551d8d165849c44725b4d4d85f571c29e52859ed Mon Sep 17 00:00:00 2001 From: Astoria Date: Fri, 12 Apr 2024 10:48:40 -0500 Subject: [PATCH] Save CPU State --- J65el02 | 2 +- .../brokenmoon/redcontrol/api/Emulator.java | 111 +++++++++++++++++- .../brokenmoon/redcontrol/api/RCWorldBus.java | 4 + .../redcontrol/blockentities/CpuEntity.java | 69 +++++++++-- 4 files changed, 175 insertions(+), 11 deletions(-) diff --git a/J65el02 b/J65el02 index f541617..c127f1a 160000 --- a/J65el02 +++ b/J65el02 @@ -1 +1 @@ -Subproject commit f5416177b806650d8014201a3e12c24d6e1c8747 +Subproject commit c127f1a2e5873ee3333b4dac05459cdbf002c662 diff --git a/src/main/java/net/brokenmoon/redcontrol/api/Emulator.java b/src/main/java/net/brokenmoon/redcontrol/api/Emulator.java index dd88ca7..4ca583e 100644 --- a/src/main/java/net/brokenmoon/redcontrol/api/Emulator.java +++ b/src/main/java/net/brokenmoon/redcontrol/api/Emulator.java @@ -8,6 +8,7 @@ import com.simon816.j65el02.device.RedBus; import net.brokenmoon.redcontrol.RedControl; import net.brokenmoon.redcontrol.mixin.BusAccessor; import net.brokenmoon.redcontrol.mixin.CpuAccessor; +import net.minecraft.nbt.NbtCompound; import java.io.IOException; import java.nio.file.Paths; @@ -56,9 +57,113 @@ public class Emulator { } } - public void reset(){ + public void reset(int driveId, int monitorId){ cpu.reset(); - ram.write(0, 2, ((CpuAccessor)cpu).getRedBusState()); - ram.write(1, 1, ((CpuAccessor)cpu).getRedBusState()); + ram.write(0, driveId, ((CpuAccessor)cpu).getRedBusState()); + ram.write(1, monitorId, ((CpuAccessor)cpu).getRedBusState()); + } + + public void writeNbt(NbtCompound nbt) { + //Cpu write nbt + + //Cpu state write nbt + nbt.putInt("aRegister", cpu.getCpuState().a); + nbt.putInt("aTopRegister", cpu.getCpuState().aTop); + nbt.putInt("xRegister", cpu.getCpuState().x); + nbt.putInt("yRegister", cpu.getCpuState().y); + nbt.putInt("spRegister", cpu.getCpuState().sp); + nbt.putInt("pcRegister", cpu.getCpuState().pc); + nbt.putInt("irRegister", cpu.getCpuState().ir); + nbt.putInt("iRegister", cpu.getCpuState().i); + nbt.putInt("rRegister", cpu.getCpuState().r); + nbt.putInt("dRegister", cpu.getCpuState().d); + nbt.putInt("brkRegister", cpu.getCpuState().brk); + nbt.putInt("porRegister", cpu.getCpuState().por); + nbt.putInt("nextirRegister", cpu.getCpuState().nextIr); + nbt.putInt("args1Register", cpu.getCpuState().args[0]); + nbt.putInt("args2Register", cpu.getCpuState().args[1]); + nbt.putInt("nextArgs1Register", cpu.getCpuState().nextArgs[0]); + nbt.putInt("nextArgs2Register", cpu.getCpuState().nextArgs[1]); + nbt.putInt("instSizeRegister", cpu.getCpuState().instSize); + nbt.putBoolean("opTrap", cpu.getCpuState().opTrap); + nbt.putBoolean("irqAsserted", cpu.getCpuState().irqAsserted); + nbt.putBoolean("nmiAsserted", cpu.getCpuState().nmiAsserted); + nbt.putInt("lastPc", cpu.getCpuState().lastPc); + nbt.putBoolean("intWait", cpu.getCpuState().intWait); + nbt.putBoolean("signalStop", cpu.getCpuState().signalStop); + + nbt.putBoolean("carryFlag", cpu.getCpuState().carryFlag); + nbt.putBoolean("negativeFlag", cpu.getCpuState().negativeFlag); + nbt.putBoolean("zeroFlag", cpu.getCpuState().zeroFlag); + nbt.putBoolean("irqDisable", cpu.getCpuState().irqDisableFlag); + nbt.putBoolean("decimalMode", cpu.getCpuState().decimalModeFlag); + nbt.putBoolean("breakFlag", cpu.getCpuState().breakFlag); + nbt.putBoolean("overflowFlag", cpu.getCpuState().overflowFlag); + nbt.putBoolean("emuFlag", cpu.getCpuState().emulationFlag); + nbt.putBoolean("mWidth", cpu.getCpuState().mWidthFlag); + nbt.putBoolean("indexWidth", cpu.getCpuState().indexWidthFlag); + nbt.putLong("stepCounter", cpu.getCpuState().stepCounter); + + //Redbus state write nbt + nbt.putInt("deviceId", cpu.redBusState.activeDeviceId); + nbt.putInt("offset", cpu.redBusState.offset); + nbt.putInt("memoryWindow", cpu.redBusState.memoryWindow); + nbt.putBoolean("enabled", cpu.redBusState.enabled); + nbt.putBoolean("enableWindow", cpu.redBusState.enableWindow); + + //Ram write nbt. + nbt.putByteArray("ramValues", this.ram.getMem()); + } + + public void readNbt(NbtCompound nbt) { + //Cpu write nbt + + //Cpu state write nbt + cpu.getCpuState().a = nbt.getInt("aRegister"); + cpu.getCpuState().aTop = nbt.getInt("aTopRegister"); + cpu.getCpuState().x = nbt.getInt("xRegister"); + cpu.getCpuState().y = nbt.getInt("yRegister"); + cpu.getCpuState().pc = nbt.getInt("pcRegister"); + cpu.getCpuState().sp = nbt.getInt("spRegister"); + cpu.getCpuState().ir = nbt.getInt("irRegister"); + cpu.getCpuState().i = nbt.getInt("iRegister"); + cpu.getCpuState().r = nbt.getInt("rRegister"); + cpu.getCpuState().d = nbt.getInt("dRegister"); + cpu.getCpuState().brk = nbt.getInt("brkRegister"); + cpu.getCpuState().por = nbt.getInt("porRegister"); + cpu.getCpuState().nextIr = nbt.getInt("nextirRegister"); + cpu.getCpuState().args[0] = nbt.getInt("args1Register"); + cpu.getCpuState().args[1] = nbt.getInt("args2Register"); + cpu.getCpuState().nextArgs[0] = nbt.getInt("nextArgs1Register"); + cpu.getCpuState().nextArgs[1] = nbt.getInt("nextArgs2Register"); + cpu.getCpuState().instSize = nbt.getInt("instSizeRegister"); + cpu.getCpuState().opTrap = nbt.getBoolean("opTrap"); + cpu.getCpuState().irqAsserted = nbt.getBoolean("irqAsserted"); + cpu.getCpuState().nmiAsserted = nbt.getBoolean("nmiAsserted"); + cpu.getCpuState().lastPc = nbt.getInt("lastPc"); + cpu.getCpuState().intWait = nbt.getBoolean("intWait"); + cpu.getCpuState().signalStop = nbt.getBoolean("signalStop"); + + cpu.getCpuState().carryFlag = nbt.getBoolean("carryFlag"); + cpu.getCpuState().negativeFlag = nbt.getBoolean("negativeFlag"); + cpu.getCpuState().zeroFlag = nbt.getBoolean("zeroFlag"); + cpu.getCpuState().irqDisableFlag = nbt.getBoolean("irqDisable"); + cpu.getCpuState().decimalModeFlag = nbt.getBoolean("decimalMode"); + cpu.getCpuState().breakFlag = nbt.getBoolean("breakFlag"); + cpu.getCpuState().overflowFlag = nbt.getBoolean("overflowFlag"); + cpu.getCpuState().emulationFlag = nbt.getBoolean("emuFlag"); + cpu.getCpuState().mWidthFlag = nbt.getBoolean("mWidth"); + cpu.getCpuState().indexWidthFlag = nbt.getBoolean("indexWidth"); + cpu.getCpuState().stepCounter = nbt.getLong("stepCounter"); + + //Redbus state write nbt + cpu.redBusState.activeDeviceId = nbt.getInt("deviceId"); + cpu.redBusState.offset = nbt.getInt("offset"); + cpu.redBusState.memoryWindow = nbt.getInt("memoryWindow"); + cpu.redBusState.enabled = nbt.getBoolean("enabled"); + cpu.redBusState.enableWindow = nbt.getBoolean("enableWindow"); + + //Ram write nbt. + ram.setMem(nbt.getByteArray("ramValues")); } } diff --git a/src/main/java/net/brokenmoon/redcontrol/api/RCWorldBus.java b/src/main/java/net/brokenmoon/redcontrol/api/RCWorldBus.java index 9629110..b1efaf5 100644 --- a/src/main/java/net/brokenmoon/redcontrol/api/RCWorldBus.java +++ b/src/main/java/net/brokenmoon/redcontrol/api/RCWorldBus.java @@ -36,4 +36,8 @@ public class RCWorldBus { public void setValid(boolean val){ this.isValid = val; } + + public boolean getValid(){ + return this.isValid; + } } diff --git a/src/main/java/net/brokenmoon/redcontrol/blockentities/CpuEntity.java b/src/main/java/net/brokenmoon/redcontrol/blockentities/CpuEntity.java index a5f3a13..4faee09 100644 --- a/src/main/java/net/brokenmoon/redcontrol/blockentities/CpuEntity.java +++ b/src/main/java/net/brokenmoon/redcontrol/blockentities/CpuEntity.java @@ -4,9 +4,15 @@ import com.simon816.j65el02.device.RedBus; import net.brokenmoon.redcontrol.RedControl; import net.brokenmoon.redcontrol.api.Emulator; import net.brokenmoon.redcontrol.api.RCWorldBus; +import net.brokenmoon.redcontrol.blocks.NetworkCarrier; import net.minecraft.block.BlockState; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.network.listener.ClientPlayPacketListener; +import net.minecraft.network.packet.Packet; +import net.minecraft.network.packet.s2c.play.BlockEntityUpdateS2CPacket; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import org.jetbrains.annotations.Nullable; public class CpuEntity extends Peripheral{ public int i = 0; @@ -16,18 +22,37 @@ public class CpuEntity extends Peripheral{ private int defaultMonitorId = 1; private int defaultDriveId = 2; + + private boolean isRunning = true; + private boolean isResetting = false; + private boolean isReset = false; + private int resetTimer = 5; + public CpuEntity(BlockPos pos, BlockState state) { super(RedControl.CPU_BLOCK_ENTITY, pos, state, 0); } public static void tick(World world, BlockPos pos, BlockState state, CpuEntity be) { - if(be.notTicked) { - be.notTicked = false; + if(be.worldBus == null || !be.worldBus.getValid()){ + ((NetworkCarrier)state.getBlock()).generateBus(world, pos); } - for(int i = 0; i < 500; i++) - be.step(); - if(be.core.isWaitingOnInterrupt()){ - be.core.setWaitingOnInterrupt(); + if(!world.isClient) { + if (be.notTicked) { + be.notTicked = false; + } + if(be.isRunning) { + for (int i = 0; i < 500; i++) + be.step(); + } else{ + if (be.isResetting && !be.isReset && be.resetTimer > 0){ + be.resetTimer--; + } else { + be.core = new Emulator(be.getBus().getRedBus()); + } + } + if (be.core.isWaitingOnInterrupt()) { + be.core.setWaitingOnInterrupt(); + } } } @@ -50,7 +75,7 @@ public class CpuEntity extends Peripheral{ public void reset() { - this.core.reset(); + this.core.reset(this.defaultDriveId, this.defaultMonitorId); } public void step() { @@ -78,4 +103,34 @@ public class CpuEntity extends Peripheral{ this.bus.setPeripheral(id, this); this.worldBus = bus; } + + @Nullable + @Override + public Packet toUpdatePacket() { + return BlockEntityUpdateS2CPacket.create(this); + } + + @Override + protected void writeNbt(NbtCompound nbt) { + nbt.putBoolean("isRunning", this.isRunning); + nbt.putBoolean("isResetting", this.isResetting); + nbt.putBoolean("isReset", this.isReset); + nbt.putInt("resetTimer", this.resetTimer); + nbt.putInt("defaultMonitorId", this.defaultMonitorId); + nbt.putInt("defaultDriveId", this.defaultDriveId); + core.writeNbt(nbt); + super.writeNbt(nbt); + } + + @Override + public void readNbt(NbtCompound nbt) { + this.isReset = nbt.getBoolean("isRunning"); + this.isResetting = nbt.getBoolean("isResetting"); + this.isReset = nbt.getBoolean("isReset"); + this.resetTimer = nbt.getInt("resetTimer"); + this.defaultMonitorId = nbt.getInt("defaultMonitorId"); + this.defaultDriveId = nbt.getInt("defaultDriveId"); + core.readNbt(nbt); + super.readNbt(nbt); + } }