Compare commits
2 Commits
Author | SHA1 | Date |
---|---|---|
Walker Fowlkes | 317af8c4d1 | 7 months ago |
Walker Fowlkes | 7cef2b5eb7 | 7 months ago |
@ -1 +0,0 @@
|
|||||||
Subproject commit f5416177b806650d8014201a3e12c24d6e1c8747
|
|
@ -0,0 +1,21 @@
|
|||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
@ -1,209 +0,0 @@
|
|||||||
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"));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,49 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,51 @@
|
|||||||
|
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 {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,101 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
package net.brokenmoon.redcontrol.api.uxn
|
||||||
|
|
||||||
|
import net.walksanator.uxnkt.vm.WrappingByteArray
|
||||||
|
|
||||||
|
class MMIOWrappingByteArray : WrappingByteArray(0x10000) {
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
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")
|
||||||
|
}
|
||||||
|
}
|
@ -1,12 +0,0 @@
|
|||||||
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);
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
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();
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
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);
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
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