diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..bff4449 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "J65el02"] + path = J65el02 + url = git@github.com:simon816/J65el02.git diff --git a/J65el02 b/J65el02 new file mode 160000 index 0000000..c6de658 --- /dev/null +++ b/J65el02 @@ -0,0 +1 @@ +Subproject commit c6de658396d537fd0c1fc0046d5222c2dc44de3d diff --git a/build.gradle b/build.gradle index fb9fffa..060ef0c 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,7 @@ plugins { id 'fabric-loom' version '1.6-SNAPSHOT' id 'maven-publish' + id 'com.github.johnrengelman.shadow' version '8.1.1' } version = project.mod_version @@ -38,6 +39,8 @@ dependencies { // Fabric API. This is technically optional, but you probably want it anyway. modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" + + shadow(implementation(project(":J65el02"))) } diff --git a/settings.gradle b/settings.gradle index 75c4d72..0f7a9fc 100644 --- a/settings.gradle +++ b/settings.gradle @@ -7,4 +7,6 @@ pluginManagement { mavenCentral() gradlePluginPortal() } -} \ No newline at end of file +} + +include ':J65el02' \ No newline at end of file diff --git a/src/main/java/net/brokenmoon/redcontrol/blockentities/CpuEntity.java b/src/main/java/net/brokenmoon/redcontrol/blockentities/CpuEntity.java index e3f8d0f..33ee5ec 100644 --- a/src/main/java/net/brokenmoon/redcontrol/blockentities/CpuEntity.java +++ b/src/main/java/net/brokenmoon/redcontrol/blockentities/CpuEntity.java @@ -1,12 +1,137 @@ package net.brokenmoon.redcontrol.blockentities; +import com.simon816.j65el02.Bus; +import com.simon816.j65el02.Cpu; +import com.simon816.j65el02.device.*; import net.brokenmoon.redcontrol.RedControl; import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntity; import net.minecraft.util.math.BlockPos; -public class CpuEntity extends BlockEntity { +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.Semaphore; + +public class CpuEntity extends BlockEntity implements Runnable{ + + static long interruptTimer = 50L; + //Adjust as needed to match original clock speed + + TimerTask cpuTask = new TimerTask(){ + public void run(){ + for(int i = 0; i < 50; i++) + step(); + } + }; + + static Timer timer = new Timer(); + + private boolean running = false; + private Semaphore waiInterrupt = new Semaphore(2); + private final Bus bus; + private final Cpu cpu; + private final RedBus redBus; + private Path bootloader; + + { + bootloader = Paths.get("/home/astoria/code/java/mods/RedControl/src/main/resources/assets/redcontrol/image/rpcboot.bin"); + } + + private int defaultMonitorId = 1; + private int defaultDriveId = 2; public CpuEntity(BlockPos pos, BlockState state) { super(RedControl.CPU_BLOCK_ENTITY, pos, state); + RedControl.LOGGER.info("Making CpuEntity"); + this.cpu = new Cpu(); + this.redBus = new RedBus(); + this.bus = new Bus(this.redBus); + this.cpu.setBus(this.bus); + + Memory ram = new Memory(0x0000, 0x2000); + try { + ram.loadFromFile(bootloader, 0x400, 0x100); + } catch (IOException e) { + throw new RuntimeException(e); + } + this.bus.addDevice(ram); + reset(); + } + + public Bus getBus() { + return this.bus; + } + + public void setPeripheral(int id, RedBus.Peripheral peripheral) { + this.redBus.setPeripheral(id, peripheral); + } + + public int getDefaultDriveId() { + return this.defaultDriveId; + } + + public void setDefaultDriveId(int id) { + this.defaultDriveId = id; } + + public int getDefaultMonitorId() { + return this.defaultMonitorId; + } + + public void setDefaultMonitorId(int id) { + this.defaultMonitorId = id; + } + + public void signal() { + if (this.waiInterrupt.availablePermits() < 2) { + this.waiInterrupt.release(); + } + } + + public boolean isRunning() { + return this.running; + } + + public void run() { + this.running = true; + do { + step(); + } while (this.running); + } + + public void stop() { + this.running = false; + while (this.waiInterrupt.availablePermits() <= 0) { + this.waiInterrupt.release(); + } + this.waiInterrupt.drainPermits(); + this.waiInterrupt.release(2); + } + + public void reset() { + stop(); + this.cpu.reset(); + this.bus.write(0, this.defaultDriveId); + this.bus.write(1, this.defaultMonitorId); + } + + public void step() { + this.waiInterrupt.acquireUninterruptibly(); + this.cpu.step(); + this.bus.update(); + if (this.cpu.isStopped()) { + this.stop(); + return; + } + if (this.cpu.isWaitingForInterrupt()) { + this.waiInterrupt.acquireUninterruptibly(); + this.cpu.assertIrq(); + } + if (this.waiInterrupt.availablePermits() < 2) { + this.waiInterrupt.release(); + } + } + } diff --git a/src/main/java/net/brokenmoon/redcontrol/driver/MonitorBlockDriver.java b/src/main/java/net/brokenmoon/redcontrol/driver/MonitorBlockDriver.java new file mode 100644 index 0000000..5f61b1c --- /dev/null +++ b/src/main/java/net/brokenmoon/redcontrol/driver/MonitorBlockDriver.java @@ -0,0 +1,25 @@ +package net.brokenmoon.redcontrol.driver; + +import com.simon816.j65el02.device.RPMonitor; + +public class MonitorBlockDriver implements RCMonitorDriver{ + @Override + public void setMonitor(RPMonitor monitor) { + + } + + @Override + public void setMonitor(RCMonitor monitor) { + + } + + @Override + public void updateCursor(int cursorX, int cursorY, int cursorMode) { + + } + + @Override + public void update(byte[][] windowData) { + + } +} diff --git a/src/main/java/net/brokenmoon/redcontrol/driver/RCMonitor.java b/src/main/java/net/brokenmoon/redcontrol/driver/RCMonitor.java new file mode 100644 index 0000000..e2292f4 --- /dev/null +++ b/src/main/java/net/brokenmoon/redcontrol/driver/RCMonitor.java @@ -0,0 +1,20 @@ +package net.brokenmoon.redcontrol.driver; + +import com.simon816.j65el02.device.RedBus; + +public class RCMonitor implements RedBus.Peripheral { + @Override + public void write(int address, int data) { + + } + + @Override + public int read(int address) { + return 0; + } + + @Override + public void update() { + + } +} diff --git a/src/main/java/net/brokenmoon/redcontrol/driver/RCMonitorDriver.java b/src/main/java/net/brokenmoon/redcontrol/driver/RCMonitorDriver.java new file mode 100644 index 0000000..5e15bb6 --- /dev/null +++ b/src/main/java/net/brokenmoon/redcontrol/driver/RCMonitorDriver.java @@ -0,0 +1,36 @@ +package net.brokenmoon.redcontrol.driver; + +import com.simon816.j65el02.device.MonitorDriver; +import com.simon816.j65el02.device.RPMonitor; + +public interface RCMonitorDriver extends MonitorDriver { + /** + * Called when the {@link RPMonitor} is constructed in order to associate the monitor with the + * driver. + * + * @param monitor The monitor + */ + public void setMonitor(RCMonitor monitor); + + /** + * Called when the cursor data is changed. + * + * @param cursorX + * @param cursorY + * @param cursorMode + */ + public void updateCursor(int cursorX, int cursorY, int cursorMode); + + /** + * Called when the display data has changed. The array is a 2D array of size + * [{@link RPMonitor#HEIGHT}][{@link RPMonitor#WIDTH}]. + * + * The display data is character data (not pixels). The lower 7 bits is the character while the + * MSB is a flag whether the color should be inverted (i.e. foreground and background color + * should be switched). Mapping for the 7 bit value to character is defined by a charset, which + * must be agreed upon by the display driver and programs written for the device. + * + * @param windowData The character data + */ + public void update(byte[][] windowData); +} diff --git a/src/main/resources/assets/redcontrol/gui/C64ProMonoMonitor.ttf b/src/main/resources/assets/redcontrol/gui/C64ProMonoMonitor.ttf new file mode 100644 index 0000000..de231bc Binary files /dev/null and b/src/main/resources/assets/redcontrol/gui/C64ProMonoMonitor.ttf differ diff --git a/src/main/resources/assets/redcontrol/gui/display.png b/src/main/resources/assets/redcontrol/gui/display.png new file mode 100644 index 0000000..2048d70 Binary files /dev/null and b/src/main/resources/assets/redcontrol/gui/display.png differ diff --git a/src/main/resources/assets/redcontrol/image/rpcboot.bin b/src/main/resources/assets/redcontrol/image/rpcboot.bin new file mode 100644 index 0000000..60ce042 Binary files /dev/null and b/src/main/resources/assets/redcontrol/image/rpcboot.bin differ diff --git a/src/main/resources/assets/redcontrol/image/slideshow.img b/src/main/resources/assets/redcontrol/image/slideshow.img new file mode 100644 index 0000000..d87d408 Binary files /dev/null and b/src/main/resources/assets/redcontrol/image/slideshow.img differ