Compare commits
5 Commits
Author | SHA1 | Date |
---|---|---|
Astoria | c4ffe016d5 | 7 months ago |
Astoria | 9302d35daa | 7 months ago |
Astoria | 789d41d92f | 7 months ago |
Astoria | 2db508cbdb | 7 months ago |
Astoria | 6ace534075 | 7 months ago |
@ -1 +1,4 @@
|
|||||||
|
|
||||||
|
[submodule "J65el02"]
|
||||||
|
path = J65el02
|
||||||
|
url = git@github.com:walksanatora/J65el02.git
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
Subproject commit f5416177b806650d8014201a3e12c24d6e1c8747
|
@ -1,21 +0,0 @@
|
|||||||
package net.brokenmoon.redcontrol.api
|
|
||||||
|
|
||||||
import net.walksanator.uxnkt.vm.Device
|
|
||||||
import net.walksanator.uxnkt.vm.IDevice
|
|
||||||
|
|
||||||
class DeviceBus {
|
|
||||||
var isValid = true
|
|
||||||
val devices = Array<IDevice>(256) { Device() }
|
|
||||||
|
|
||||||
fun tryClaimId(id: Byte, device: IDevice): Boolean {
|
|
||||||
val obj = devices[id.toInt()]
|
|
||||||
if (obj.javaClass == Device::class.java) {
|
|
||||||
devices[id.toInt()] = device
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
fun forceClaimId(id: Byte, device: IDevice) {
|
|
||||||
devices[id.toInt()] = device
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,209 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A serializable emulator
|
||||||
|
*/
|
||||||
|
public class Emulator {
|
||||||
|
|
||||||
|
private RedBus bus;
|
||||||
|
public Cpu cpu;
|
||||||
|
private Memory ram;
|
||||||
|
|
||||||
|
public Emulator(RedBus bus){
|
||||||
|
this.bus = bus;
|
||||||
|
cpu = new Cpu();
|
||||||
|
cpu.setLogCallback((i) -> RedControl.LOGGER.info("CPU emitted a byte {}",i));
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gets the RedBus attached to this Emulator
|
||||||
|
* @return the red bus attached to this emulator
|
||||||
|
*/
|
||||||
|
public RedBus getBus() {
|
||||||
|
return bus;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the bus and sets redbus on the CPU
|
||||||
|
* @param bus the bus to set the cpu and this emu to
|
||||||
|
*/
|
||||||
|
public void setBus(RedBus bus) {
|
||||||
|
this.bus = bus;
|
||||||
|
((BusAccessor)this.cpu.getBus()).setRedBus(bus);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns if the CPU is waiting on interupt
|
||||||
|
* @return if the cpu is waiting on a interupt
|
||||||
|
*/
|
||||||
|
public boolean isWaitingOnInterrupt(){
|
||||||
|
return cpu.isWaitingForInterrupt();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the CPU's interupt state
|
||||||
|
* @param interrupt the new interupt state
|
||||||
|
*/
|
||||||
|
public void setWaitingOnInterrupt(boolean interrupt){
|
||||||
|
cpu.getCpuState().intWait = interrupt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* steps the CPU by 1 instruction
|
||||||
|
* and updates all bus/redbus attached devices
|
||||||
|
*/
|
||||||
|
public void step() {
|
||||||
|
if(!isWaitingOnInterrupt()) {
|
||||||
|
this.cpu.step();
|
||||||
|
this.cpu.getBus().update(((CpuAccessor)cpu).getRedBusState());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* resets the CPU to default values, and loads driveID and monitorID back for bootloader to use
|
||||||
|
* @param driveId the drive bootloader will read from
|
||||||
|
* @param monitorId the monitor id bootloder and initial program will write to
|
||||||
|
*/
|
||||||
|
public void reset(int driveId, int monitorId){
|
||||||
|
cpu.reset();
|
||||||
|
ram.write(0, driveId, ((CpuAccessor)cpu).getRedBusState());
|
||||||
|
ram.write(1, monitorId, ((CpuAccessor)cpu).getRedBusState());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* save the emulator into NBT
|
||||||
|
* @param nbt the NBT to write state into
|
||||||
|
*/
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* load emulator state from NBT
|
||||||
|
* @param nbt the NBT to load from.
|
||||||
|
*/
|
||||||
|
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"));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
package net.brokenmoon.redcontrol.api;
|
||||||
|
|
||||||
|
import com.simon816.j65el02.device.RedBus;
|
||||||
|
import net.brokenmoon.redcontrol.blocks.NetworkCarrier;
|
||||||
|
import net.minecraft.server.world.ServerWorld;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Bus holder including the blockpos and redbus and a cached world
|
||||||
|
* also holds if the bus is valid
|
||||||
|
*/
|
||||||
|
public class RCWorldBus {
|
||||||
|
|
||||||
|
private boolean isValid = false;
|
||||||
|
|
||||||
|
private RedBus redBus;
|
||||||
|
|
||||||
|
private World backupWorld;
|
||||||
|
private BlockPos backupPos;
|
||||||
|
|
||||||
|
public RCWorldBus(RedBus redBus, World world, BlockPos pos) {
|
||||||
|
this.redBus = redBus;
|
||||||
|
backupWorld = world;
|
||||||
|
backupPos = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void generateBus(ServerWorld world, BlockPos pos){
|
||||||
|
((NetworkCarrier)(world.getBlockState(pos).getBlock())).generateBus(world, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RedBus getRedBus() {
|
||||||
|
return redBus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRedBus(RedBus redBus) {
|
||||||
|
this.redBus = redBus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValid(boolean val){
|
||||||
|
this.isValid = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getValid(){
|
||||||
|
return this.isValid;
|
||||||
|
}
|
||||||
|
}
|
@ -1,51 +0,0 @@
|
|||||||
package net.brokenmoon.redcontrol.api.drive;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
|
|
||||||
public class ByteDiskDriver implements DiskDriver{
|
|
||||||
|
|
||||||
private final ByteBuffer bytes;
|
|
||||||
private final byte[] drive_name;
|
|
||||||
private final byte[] drive_serial;
|
|
||||||
|
|
||||||
public ByteDiskDriver(byte[] bytes, String name, String serial) {
|
|
||||||
this.bytes = ByteBuffer.wrap(bytes);
|
|
||||||
this.drive_name = name.getBytes(StandardCharsets.UTF_8);
|
|
||||||
this.drive_serial = serial.getBytes(StandardCharsets.UTF_8);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] getDriveName() {
|
|
||||||
return drive_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] getDriveSerial() {
|
|
||||||
return drive_serial;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void seek(int location) throws IOException {
|
|
||||||
this.bytes.position(Math.min(bytes.limit(),location));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void read(ByteBuffer buffer) throws IOException {
|
|
||||||
int size = Math.min(buffer.capacity(),bytes.remaining());
|
|
||||||
for (int i = 0; i < size; i++) {
|
|
||||||
buffer.put(bytes.get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void write(ByteBuffer buffer) throws IOException {
|
|
||||||
this.bytes.position(this.bytes.position() + buffer.capacity());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void writeDiskName(byte[] diskName) throws IOException {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,73 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018 Simon816
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package net.brokenmoon.redcontrol.api.drive;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
|
|
||||||
public interface DiskDriver {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the name of the drive.
|
|
||||||
*
|
|
||||||
* @return Drive name
|
|
||||||
*/
|
|
||||||
byte[] getDriveName();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the serial name of the drive.
|
|
||||||
*
|
|
||||||
* @return Drive serial
|
|
||||||
*/
|
|
||||||
byte[] getDriveSerial();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Seeks to the given location in the drive.
|
|
||||||
*
|
|
||||||
* @param location Absolute location in the drive
|
|
||||||
* @throws IOException If the seek operation fails
|
|
||||||
*/
|
|
||||||
void seek(int location) throws IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads data from the drive at the current position into the buffer.
|
|
||||||
*
|
|
||||||
* @param buffer Buffer where data is to be put into
|
|
||||||
* @throws IOException If the read operation fails
|
|
||||||
*/
|
|
||||||
void read(ByteBuffer buffer) throws IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write data from the buffer into the drive at the current position.
|
|
||||||
*
|
|
||||||
* @param buffer Buffer to pull data from
|
|
||||||
* @throws IOException If the write operation fails
|
|
||||||
*/
|
|
||||||
void write(ByteBuffer buffer) throws IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates the name of the disk to the given name.
|
|
||||||
*
|
|
||||||
* @param diskName New name of the disk
|
|
||||||
* @throws IOException If the name update operation fails
|
|
||||||
*/
|
|
||||||
void writeDiskName(byte[] diskName) throws IOException;
|
|
||||||
|
|
||||||
}
|
|
@ -1,101 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018 Simon816
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package net.brokenmoon.redcontrol.api.drive;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.nio.channels.SeekableByteChannel;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.nio.file.StandardOpenOption;
|
|
||||||
import java.util.EnumSet;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A {@link DiskDriver} backed by a real file.
|
|
||||||
*/
|
|
||||||
public class FileDiskDriver implements DiskDriver {
|
|
||||||
|
|
||||||
private final SeekableByteChannel channel;
|
|
||||||
private byte[] driveName;
|
|
||||||
private byte[] driveSerial;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a disk driver backed by a real file. The file is opened for reading, and optionally
|
|
||||||
* writing, until {@link #close} is called.
|
|
||||||
*
|
|
||||||
* @param file Path to the file backing this disk
|
|
||||||
* @param driveName Name of the drive presented to the program
|
|
||||||
* @param serial Serial number of the drive
|
|
||||||
* @param readOnly Whether the file should be opened for reading only
|
|
||||||
* @throws IOException If the file cannot be opened
|
|
||||||
*/
|
|
||||||
public FileDiskDriver(Path file, String driveName, String serial, boolean readOnly) throws IOException {
|
|
||||||
EnumSet<StandardOpenOption> openOptions = EnumSet.of(StandardOpenOption.READ);
|
|
||||||
if (!readOnly) {
|
|
||||||
openOptions.add(StandardOpenOption.WRITE);
|
|
||||||
}
|
|
||||||
this.channel = Files.newByteChannel(file, openOptions);
|
|
||||||
this.driveName = driveName.getBytes(StandardCharsets.US_ASCII);
|
|
||||||
this.driveSerial = serial.getBytes(StandardCharsets.US_ASCII);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Closes the underlying open file for this drive.
|
|
||||||
* <p>
|
|
||||||
* This should be called after the machine has been terminated. Using the drive after closing is
|
|
||||||
* undefined.
|
|
||||||
*
|
|
||||||
* @throws IOException If an error occurs when closing
|
|
||||||
*/
|
|
||||||
public void close() throws IOException {
|
|
||||||
this.channel.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] getDriveName() {
|
|
||||||
return this.driveName;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] getDriveSerial() {
|
|
||||||
return this.driveSerial;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void seek(int location) throws IOException {
|
|
||||||
this.channel.position(location);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void read(ByteBuffer buffer) throws IOException {
|
|
||||||
this.channel.read(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void write(ByteBuffer buffer) throws IOException {
|
|
||||||
this.channel.write(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void writeDiskName(byte[] diskName) throws IOException {
|
|
||||||
// TODO This does nothing
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
package net.brokenmoon.redcontrol.api.uxn
|
|
||||||
|
|
||||||
import net.walksanator.uxnkt.vm.WrappingByteArray
|
|
||||||
|
|
||||||
class MMIOWrappingByteArray : WrappingByteArray(0x10000) {
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
package net.brokenmoon.redcontrol.api.uxn
|
|
||||||
|
|
||||||
import net.walksanator.uxnkt.vm.Computer
|
|
||||||
import net.walksanator.uxnkt.vm.Uxn
|
|
||||||
import java.util.function.Consumer
|
|
||||||
|
|
||||||
class MinecraftComputer(cpu: Uxn) : Computer(cpu) {
|
|
||||||
|
|
||||||
|
|
||||||
override fun queue(prerun: Consumer<Computer>) {
|
|
||||||
TODO("Not yet implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun run() {
|
|
||||||
TODO("Not yet implemented")
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,12 @@
|
|||||||
|
package net.brokenmoon.redcontrol.mixin;
|
||||||
|
|
||||||
|
import com.simon816.j65el02.Bus;
|
||||||
|
import com.simon816.j65el02.device.RedBus;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||||
|
|
||||||
|
@Mixin(Bus.class)
|
||||||
|
public interface BusAccessor {
|
||||||
|
@Accessor(value = "redBus",remap = false)
|
||||||
|
void setRedBus(RedBus redBus);
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package net.brokenmoon.redcontrol.mixin;
|
||||||
|
|
||||||
|
import com.simon816.j65el02.Cpu;
|
||||||
|
import com.simon816.j65el02.CpuState;
|
||||||
|
import com.simon816.j65el02.device.RedBusState;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||||
|
|
||||||
|
@Mixin(Cpu.class)
|
||||||
|
public interface CpuAccessor {
|
||||||
|
@Accessor(value = "redBusState",remap = false)
|
||||||
|
RedBusState getRedBusState();
|
||||||
|
@Accessor(value = "state",remap = false)
|
||||||
|
CpuState getState();
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package net.brokenmoon.redcontrol.mixin;
|
||||||
|
|
||||||
|
import com.simon816.j65el02.device.Memory;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||||
|
|
||||||
|
@Mixin(Memory.class)
|
||||||
|
public interface MemoryAccessor {
|
||||||
|
@Accessor(value = "mem",remap = false)
|
||||||
|
byte[] getMem();
|
||||||
|
@Accessor(value = "mem",remap = false)
|
||||||
|
void setMem(byte[] mem);
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
package net.brokenmoon.redcontrol.mixin;
|
||||||
|
|
||||||
|
import com.simon816.j65el02.device.RedBus;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||||
|
|
||||||
|
@Mixin(RedBus.class)
|
||||||
|
public interface RedBusAccessor {
|
||||||
|
@Accessor(value = "peripherals",remap = false)
|
||||||
|
RedBus.Peripheral[] getPeripherals();
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue