package net.brokenmoon.redcontrol.api; import com.simon816.j65el02.Bus; import com.simon816.j65el02.Cpu; import com.simon816.j65el02.CpuState; import com.simon816.j65el02.device.Memory; import com.simon816.j65el02.device.RedBus; import com.simon816.j65el02.device.RedBusState; import net.brokenmoon.redcontrol.RedControl; import net.brokenmoon.redcontrol.mixin.BusAccessor; import net.brokenmoon.redcontrol.mixin.CpuAccessor; import net.brokenmoon.redcontrol.mixin.MemoryAccessor; import net.minecraft.nbt.NbtCompound; import java.io.IOException; import java.nio.file.Paths; public class Emulator { private RedBus bus; public Cpu cpu; private Memory ram; public Emulator(RedBus bus){ this.bus = bus; cpu = new Cpu(); cpu.setLogCallback(new LogConsumer()); cpu.setBus(new Bus(bus)); ram = new Memory(0x0000, 0x4000 - 1, ((CpuAccessor)cpu).getRedBusState()); ram.loadFromBytes(RedControl.images.get("rpcboot.bin"),0x400,0x100); cpu.getBus().addDevice(ram, ((CpuAccessor)cpu).getRedBusState()); cpu.reset(); ram.write(0, 2, ((CpuAccessor)cpu).getRedBusState()); ram.write(1, 1, ((CpuAccessor)cpu).getRedBusState()); } public RedBus getBus() { return bus; } public void setBus(RedBus bus) { this.bus = bus; ((BusAccessor)this.cpu.getBus()).setRedBus(bus); } public boolean isWaitingOnInterrupt(){ return cpu.isWaitingForInterrupt(); } public void setWaitingOnInterrupt(){ cpu.getCpuState().intWait = false; } public void step() { if(!isWaitingOnInterrupt()) { CpuState state = ((CpuAccessor)this.cpu).getState(); this.cpu.step(); this.cpu.getBus().update(((CpuAccessor)cpu).getRedBusState()); } } public void reset(int driveId, int monitorId){ cpu.reset(); 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 RedBusState redBusState = ((CpuAccessor)cpu).getRedBusState(); nbt.putInt("deviceId", redBusState.activeDeviceId); nbt.putInt("offset", redBusState.offset); nbt.putInt("memoryWindow", redBusState.memoryWindow); nbt.putBoolean("enabled", redBusState.enabled); nbt.putBoolean("enableWindow", redBusState.enableWindow); //Ram write nbt. nbt.putByteArray("ramValues", ((MemoryAccessor)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 RedBusState redBusState = ((CpuAccessor)cpu).getRedBusState(); redBusState.activeDeviceId = nbt.getInt("deviceId"); redBusState.offset = nbt.getInt("offset"); redBusState.memoryWindow = nbt.getInt("memoryWindow"); redBusState.enabled = nbt.getBoolean("enabled"); redBusState.enableWindow = nbt.getBoolean("enableWindow"); //Ram write nbt. ((MemoryAccessor)ram).setMem(nbt.getByteArray("ramValues")); } }