Commit c44caf9d by Jessica Hawkwell

organized a lot of stuffs, fixed ValueHelper. closes #1

1 parent a3a1cc32
Pipeline #210 passed
in 1 minute 9 seconds
Showing with 440 additions and 309 deletions
......@@ -9,8 +9,9 @@ import java.util.Arrays;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import me.felinewith.kcpu.hardware.Kmcp;
import me.felinewith.kcpu.memory.BootRom;
import me.felinewith.kcpu.hardware.Kmcu;
import me.felinewith.kcpu.interfaces.IDevice;
import me.felinewith.kcpu.interfaces.IMemory;
import me.felinewith.kcpu.util.BaseDevice;
import me.felinewith.kcpu.util.HardwareExec;
import me.felinewith.kcpu.util.HardwareMemIrq;
......@@ -23,14 +24,14 @@ public class KBoard extends BaseDevice implements IMemory {
final ThreadPoolExecutor tpe;
private IDevice[] devices;
private KMemoryRange[] deviceMaps;
IDevice[] devices;
KMemoryRange[] deviceMaps;
private IMemory[] memDevs;
private KMemoryRange[] memDevMaps;
IMemory[] memDevs;
KMemoryRange[] memDevMaps;
private Charset cs;
private Kcpu cpu;
Charset cs;
Kcpu cpu;
public KBoard() {
tpe = new ThreadPoolExecutor(16, 32, 30, TimeUnit.SECONDS, new LinkedBlockingQueue<>(16));
......@@ -47,11 +48,11 @@ public class KBoard extends BaseDevice implements IMemory {
public void init() {
cpu = new Kcpu(this);
attachDevice(0, 0x8000, cpu);
attachDevice(1, 0x8800, new Kmcp());
attachDevice(0x8000, cpu);
attachDevice(0x8800, new Kmcu());
//attachMemory(0, 0xff00, new Buffer());
attachMemory(1, 0x1000, new BootRom());
//attachMemory(1, 0x1000, new BootRom());
System.out.println("CPU up...");
......@@ -115,6 +116,7 @@ public class KBoard extends BaseDevice implements IMemory {
@Override public void write(short addr, byte data) {
short dev = checkDevice(addr);
System.err.printf("\tWriting %2x to %04x\n", data, addr);
short rdev = (short)(0x0f & dev);
if ( dev == 0x7f ) { memory[0xffff & addr] = data; }
if ( dev <= 0x0f ) {
......@@ -129,8 +131,17 @@ public class KBoard extends BaseDevice implements IMemory {
}
}
public void attachDevice(int port, int offset, IDevice device) {
attachDevice(port, (short)offset, device); }
public void attachDevice(int offset, IDevice device) { attachDevice((short)offset, device); }
public void attachDevice(int port, int offset, IDevice device) { attachDevice(port, (short)offset, device); }
public void attachDevice(short offset, IDevice device) {
int a;
for (a = 0; a < 16; a++) {
if (devices[a] == null) {
attachDevice(a, offset, device);
return;
}
}
}
public void attachDevice(int port, short offset, IDevice device) {
if ( devices[port] != null ) { return; }
else if ( deviceMaps[port] != null ) { return; }
......@@ -141,8 +152,17 @@ public class KBoard extends BaseDevice implements IMemory {
device.init(this);
}
public void attachMemory(int port, int offset, IMemory device) {
attachMemory(port, (short)offset, device); }
public void attachMemory(int offset, IMemory device) { attachMemory((short)offset, device); }
public void attachMemory(int port, int offset, IMemory device) { attachMemory(port, (short)offset, device); }
public void attachMemory(short offset, IMemory device) {
int a;
for (a = 0; a < 16; a++) {
if (memDevs[a] == null) {
attachMemory(a, offset, device);
return;
}
}
}
public void attachMemory(int port, short offset, IMemory device) {
if ( memDevs[port] != null ) { return; }
else if ( memDevMaps[port] != null ) { return; }
......@@ -162,7 +182,7 @@ public class KBoard extends BaseDevice implements IMemory {
if ( deviceMaps[a] != null ) {
io = deviceMaps[a];
devOff = io.getOffset();
devTop = (short)(devOff + io.getLength());
devTop = (short)(devOff + (io.getLength() - 1));
if ( devOff <= addr && addr <= devTop ) { return a; } // range is entirely in device
}
......@@ -172,7 +192,7 @@ public class KBoard extends BaseDevice implements IMemory {
if ( memDevMaps[a] != null ) {
io = memDevMaps[a];
devOff = io.getOffset();
devTop = (short)(devOff + io.getLength());
devTop = (short)(devOff + (io.getLength() - 1));
if ( devOff <= addr && addr <= devTop ) { return (short)(0x10 + a); } // range is entirely in device
}
......
......@@ -8,8 +8,9 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import me.felinewith.kcpu.hardware.KcmpOpCodes;
import me.felinewith.kcpu.hardware.kmcu.KmcuOpCodes;
import me.felinewith.kcpu.opcodes.OpDirector;
import me.felinewith.kcpu.util.Converter;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
......@@ -47,13 +48,13 @@ public class Kasm {
if (cli.hasOption("co")) {
logln("Supported CPU Opcodes:");
for (OpDirector oc : OpDirector.values()) {
logln("\t%04x -> [%10s]", oc.getOpcode(), oc.name());
logln("\t[%10s] %s", oc.name(), oc.getDescription());
}
logln("");
}
if (cli.hasOption("mo")) {
logln("Supported CPU Opcodes:");
for (KcmpOpCodes oc : KcmpOpCodes.values()) {
logln("Supported MCU Opcodes:");
for (KmcuOpCodes oc : KmcuOpCodes.values()) {
logln("\t%04x -> [%10s]", oc.getOpcode(), oc.name());
}
logln("");
......@@ -115,28 +116,38 @@ public class Kasm {
else { parts = new String[]{kasm}; }
parts[0] = parts[0].toUpperCase();
opcode = OpDirector.valueOf(parts[0]);
if (verbose) { log("[%10s] ", opcode.name()); }
writeShort(baos, opcode.getOpcode());
if (verbose) { log(" : "); }
if (parts.length >= 2) { ref += asmType(parts[1]); }
if (parts.length >= 3) { ref += (short)(asmType(parts[2]) << 2); }
if (parts.length >= 4) { ref += (short)(asmType(parts[3]) << 4); }
if (parts.length >= 5) { ref += (short)(asmType(parts[4]) << 6); }
if (parts.length >= 5) { ref += 0x0400; }
else if (parts.length >= 4) { ref += 0x0300; }
else if (parts.length >= 3) { ref += 0x0200; }
else if (parts.length >= 2) { ref += 0x0100; }
writeShort(baos, ref);
if (verbose) { log(" -> "); }
if (parts.length >= 2) { writeShort(baos, numberize(parts[1])); }
if (parts.length >= 3) { writeShort(baos, numberize(parts[2])); }
if (parts.length >= 4) { writeShort(baos, numberize(parts[3])); }
if (parts.length >= 5) { writeShort(baos, numberize(parts[4])); }
if (verbose) { logln(""); }
if (parts[0].equals("FILL")) {
int a;
int max = numberize(parts[1]);
byte fill = 0;
if (parts.length >= 3) { fill = (byte)numberize(parts[2]); }
for (a = 0; a < max; a++) { baos.write(fill); }
return baos.toByteArray();
}
else {
opcode = OpDirector.valueOf(parts[0]);
if (verbose) { log("[%10s] ", opcode.name()); }
writeShort(baos, opcode.getOpcode());
if (verbose) { log(" : "); }
if (parts.length >= 2) { ref += asmType(parts[1]); }
if (parts.length >= 3) { ref += (short)(asmType(parts[2]) << 2); }
if (parts.length >= 4) { ref += (short)(asmType(parts[3]) << 4); }
if (parts.length >= 5) { ref += (short)(asmType(parts[4]) << 6); }
if (parts.length >= 5) { ref += 0x0400; }
else if (parts.length >= 4) { ref += 0x0300; }
else if (parts.length >= 3) { ref += 0x0200; }
else if (parts.length >= 2) { ref += 0x0100; }
writeShort(baos, ref);
if (verbose) { log(" -> "); }
if (parts.length >= 2) { writeShort(baos, numberize(parts[1])); }
if (parts.length >= 3) { writeShort(baos, numberize(parts[2])); }
if (parts.length >= 4) { writeShort(baos, numberize(parts[3])); }
if (parts.length >= 5) { writeShort(baos, numberize(parts[4])); }
if (verbose) { logln(""); }
}
}
return baos.toByteArray();
}
......@@ -169,8 +180,8 @@ public class Kasm {
static short numberize(String input) {
String temp = stripType(input);
String[] pt;
if ( temp.contains("_") ) { temp = temp.replaceAll("_", ""); }
if ( temp.contains(",") ) {
if (temp.contains("_")) { temp = temp.replaceAll("_", ""); }
if (temp.contains(",")) {
pt = temp.split("[,]");
short radix = Short.valueOf(pt[1], 10);
return (short)(0xffff & Integer.valueOf(pt[0], radix));
......@@ -196,4 +207,23 @@ public class Kasm {
if ( outer == null ) { return; }
outer.println(String.format(format, vals));
}
public static KasmBuilder builder() { return new Kasm.KasmBuilder(); }
short BASEaddr;
private Kasm() { }
private Kasm(KasmBuilder builder) {
BASEaddr = builder.BASEaddr;
}
public static class KasmBuilder {
short BASEaddr;
public KasmBuilder() { }
public Kasm build() { return new Kasm(this); }
public KasmBuilder setBASEaddr(short BASEaddr) { this.BASEaddr = BASEaddr; return this; }
}
}
package me.felinewith.kcpu;
import java.io.PrintStream;
import me.felinewith.kcpu.memory.MemHelper;
import me.felinewith.kcpu.interfaces.IMemory;
import me.felinewith.kcpu.opcodes.OpDirector;
import me.felinewith.kcpu.opcodes.ValueHelper;
import me.felinewith.kcpu.util.BaseDevice;
import me.felinewith.kcpu.util.helpers.MemHelper;
import me.felinewith.kcpu.util.helpers.ValueHelper;
import me.felinewith.kcpu.util.helpers.ValueType;
/**
*
......@@ -74,7 +76,11 @@ public class Kcpu extends BaseDevice {
short inst = MemHelper.readShort(pc, kboard);
short ref = MemHelper.readShort(pc + 2, kboard);
short[] values = new short[4];
if ((0xffff & inst) == 0xffff){
logln("Break!");
}
switch (0x0700 & ref) {
case 0x0700: case 0x0600: case 0x0500:
case 0x0400: values[3] = MemHelper.readShort(pc + 10, kboard);
case 0x0300: values[2] = MemHelper.readShort(pc + 8, kboard);
case 0x0200: values[1] = MemHelper.readShort(pc + 6, kboard);
......@@ -89,14 +95,14 @@ public class Kcpu extends BaseDevice {
}
}
log("%04x : [%10s] %04x %04x ->", pc, ((od == null)?"nop":od.name()), inst, ref);
log("%04x : [%10s] %04x ->", pc, ((od == null)?"nop":od.name()), ref);
log(" %04x %04x %04x %04x\t\t", registers[0], registers[1], registers[2], registers[3]);
if ((0x0700 & ref) >= 0x0100) { log(" %04x", values[0]); }
if ((0x0700 & ref) >= 0x0200) { log(" %04x", values[1]); }
if ((0x0700 & ref) >= 0x0300) { log(" %04x", values[2]); }
if ((0x0700 & ref) >= 0x0400) { log(" %04x", values[3]); }
if ((0x0700 & ref) >= 0x0100) { log(" %2s.%04x", ValueType.valueOf(ref, 0), values[0]); }
if ((0x0700 & ref) >= 0x0200) { log(" %2s.%04x", ValueType.valueOf(ref, 1), values[1]); }
if ((0x0700 & ref) >= 0x0300) { log(" %2s.%04x", ValueType.valueOf(ref, 2), values[2]); }
if ((0x0700 & ref) >= 0x0400) { log(" %2s.%04x", ValueType.valueOf(ref, 3), values[3]); }
logln("");
if (od == null) { pc += 12; return 0; } // inc if nop
......@@ -131,13 +137,13 @@ public class Kcpu extends BaseDevice {
case JMPA: pc = data; return 0;
case JMPD: pc = (short)(pc - (0xffff & data)); return 0;
case GPC:
registers = ValueHelper.writeShort(0, ref, registers, values, board, pc);
registers = ValueHelper.writeShort(0, ref, registers, values, kboard, pc);
return 0;
case ZPWR: return 0xff;
}
short data2 = ValueHelper.readShort(1, ref, registers, values, kboard);
short data3 = ValueHelper.readShort(2, ref, registers, values, board);
short data3 = ValueHelper.readShort(2, ref, registers, values, kboard);
switch (od) {
// conditionals
case JE: if (data == data2) { pc += data3; } return 0;
......
package me.felinewith.kcpu;
import java.io.IOException;
import java.util.ArrayList;
import me.felinewith.kcpu.memory.BootRom;
import me.felinewith.kcpu.memory.Buffer;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
/**
*
......@@ -17,10 +27,55 @@ public class Kemulator {
}
}
ArrayList<Option> option = new ArrayList<>();
option.add(Option.builder("b")
.longOpt("bootrom")
.argName("bootrom.kc")
.hasArg()
.numberOfArgs(8)
.build()
);
option.add(Option.builder("h")
.longOpt("help")
.build()
);
Options options = new Options();
option.forEach((t) -> { options.addOption(t); });
CommandLineParser clp = new DefaultParser();
CommandLine line = null;
try {
line = clp.parse(options, args);
}
catch (ParseException x) {
System.err.printf("Parsing error: %s\n", x.getMessage());
try { line = clp.parse(options, new String[]{"-h"}); }
catch (ParseException e) {}
}
BootRom bootrom = new BootRom();
if (line != null) {
if (line.hasOption("h")) {
HelpFormatter hf = new HelpFormatter();
hf.printHelp("kemulator", options, true);
return;
}
if (line.hasOption("b")) {
bootrom.reset();
for (String s : line.getOptionValues("b")) {
try { bootrom.load(s); }
catch (IOException x) {}
}
}
}
bb.setInputStream(System.in);
bb.setOutputStream(System.out);
kb.attachMemory(0, 0xff00, bb);
kb.attachMemory(0xff00, bb);
kb.attachMemory(0x1000, bootrom);
kb.init();
......
package me.felinewith.kcpu.hardware;
/**
*
* @author jlhawkwell
*/
public enum KcmpOpCodes {
// basic math stuffies
ADD(0x0001),
SUB(0x0002),
MUL(0x0003),
DIV(0x0004),
// math library
ABS (0x0010),
ACOS (0x0011),
ASIN (0x0012),
ATAN (0x0013),
ATAN2(0x0014),
CBRT (0x0015),
CEIL (0x0016),
COS (0x0017),
COSH (0x0018),
EXP (0x0019),
EXPM1(0x001a),
FLR (0x001b),
FDIV (0x001c),
FMOD (0x001d),
GEXP (0x001e),
HYPOT(0x001f),
IEEER(0x0020),
LOG (0x0021),
LOG10(0x0022),
LOG1P(0x0023),
MAX (0x0024),
MIN (0x0025),
NEXTA(0x0026),
NEXTD(0x0027),
NEXTU(0x0028),
POW (0x0029),
RAND (0x002a),
RINT (0x002b),
ROUND(0x002c),
SCALB(0x002d),
SIGNM(0x002e),
SIN (0x002f),
SINH (0x0030),
SQRT (0x0031),
TAN (0x0032),
TANH (0x0033),
TDEG (0x0034),
TRAD (0x0035),
ULP (0x0036),
// conversions
VC2B (0x0080),
VC2S (0x0081),
VC2I (0x0082),
VC2F (0x0083),
VL2B (0x0084),
VL2S (0x0085),
VL2I (0x0086),
VL2F (0x0087),
// bitwise operations
AND(0x0090),
OR(0x0091),
XOR(0x0092),
BSU(0x0093), BSL(0x0093),
BSD(0x0094), BSR(0x0094)
;
private short o;
private KcmpOpCodes(short opcode) { o = opcode; }
private KcmpOpCodes(int opcode) { o = (short)(0xffff & opcode); }
public short getOpcode() { return o; }
}
package me.felinewith.kcpu.hardware;
import me.felinewith.kcpu.hardware.kmcu.KmcuOp;
import java.io.PrintStream;
import java.util.Arrays;
import me.felinewith.kcpu.Converter;
import me.felinewith.kcpu.util.Converter;
import me.felinewith.kcpu.util.BaseDevice;
/**
*
* @author jlhawkwell
*/
public class Kmcp extends BaseDevice {
public class Kmcu extends BaseDevice {
private static PrintStream outer;
/**
......@@ -31,7 +32,7 @@ public class Kmcp extends BaseDevice {
outer.println(String.format(format, vals));
}
public Kmcp() {
public Kmcu() {
setOuter(System.err);
memory = new byte[0x20];
name = "Kmcp";
......@@ -59,7 +60,7 @@ public class Kmcp extends BaseDevice {
read(starts + 1)
};
short opcode = Converter.bytes2short(data);
KmcpOp od = new KmcpOp(opcode);
KmcuOp od = new KmcuOp(opcode);
logln("Kmcp : [%10s] %04x -> %04x %04x %04x %04x %04x %04x %04x %04x",
((od.name() == null)?"nop":od.name()), opcode,
......@@ -78,7 +79,7 @@ public class Kmcp extends BaseDevice {
}
}
private byte[] performCalc(KmcpOp opcode, byte[] reg) {
private byte[] performCalc(KmcuOp opcode, byte[] reg) {
byte[] out = new byte[8];
switch (opcode.getOperation()) {
......@@ -90,7 +91,7 @@ public class Kmcp extends BaseDevice {
return out;
}
private byte[] performCalcByte(KmcpOp opcode, byte[] reg) {
private byte[] performCalcByte(KmcuOp opcode, byte[] reg) {
byte[] work = new byte[]{reg[0], reg[4]};
byte[] out = new byte[8];
......@@ -170,7 +171,7 @@ public class Kmcp extends BaseDevice {
}
return out;
}
private byte[] performCalcShort(KmcpOp opcode, byte[] reg) {
private byte[] performCalcShort(KmcuOp opcode, byte[] reg) {
short[] work = new short[]{
Converter.bytes2short(new byte[]{reg[0], reg[1]}),
Converter.bytes2short(new byte[]{reg[4], reg[5]})
......@@ -265,7 +266,7 @@ public class Kmcp extends BaseDevice {
return output;
}
private byte[] performCalcInt(KmcpOp opcode, byte[] reg) {
private byte[] performCalcInt(KmcuOp opcode, byte[] reg) {
int[] work = new int[]{
Converter.bytes2int(new byte[]{reg[0], reg[1], reg[2], reg[3]}),
Converter.bytes2int(new byte[]{reg[4], reg[5], reg[6], reg[7]}),
......@@ -365,7 +366,7 @@ public class Kmcp extends BaseDevice {
return output;
}
private byte[] performCalcFloat(KmcpOp opcode, byte[] reg) {
private byte[] performCalcFloat(KmcuOp opcode, byte[] reg) {
float[] work = new float[]{
Converter.bytes2float(new byte[]{reg[0], reg[1], reg[2], reg[3]}),
Converter.bytes2float(new byte[]{reg[4], reg[5], reg[6], reg[7]}),
......
package me.felinewith.kcpu.hardware;
package me.felinewith.kcpu.hardware.kmcu;
/**
*
* @author jlhawkwell
*/
public class KmcpOp {
private KcmpOpCodes oc;
public class KmcuOp {
private KmcuOpCodes oc;
private KmcpValueType operation;
private KmcuValueType operation;
public KmcpOp(short opcode) {
public KmcuOp(short opcode) {
short tmpcode;
oc = null;
// decode the opcode
tmpcode = (short)(0x00ff & opcode);
for (KcmpOpCodes t : KcmpOpCodes.values()) {
for (KmcuOpCodes t : KmcuOpCodes.values()) {
if (t.getOpcode() == tmpcode) {
oc = t;
break;
......@@ -24,7 +24,7 @@ public class KmcpOp {
// decode the operation
tmpcode = (short)((0xf000 & opcode) >> 8);
for (KmcpValueType t : KmcpValueType.values()) {
for (KmcuValueType t : KmcuValueType.values()) {
if (t.mask() == tmpcode) {
operation = t;
break;
......@@ -32,11 +32,11 @@ public class KmcpOp {
}
}
public KcmpOpCodes getOpCode() {
public KmcuOpCodes getOpCode() {
if (oc == null) { return null; }
return oc;
}
public KmcpValueType getOperation() { return operation; }
public KmcuValueType getOperation() { return operation; }
public String name() {
if (oc == null) { return null; }
return oc.name();
......
package me.felinewith.kcpu.hardware.kmcu;
/**
*
* @author jlhawkwell
*/
public enum KmcuOpCodes {
// basic math stuffies
ADD(0x0001, "[bsi ] r0 += r1"),
SUB(0x0002, "[bsi ] r0 -= r1"),
MUL(0x0003, "[bsi ] r0 *= r1"),
DIV(0x0004, "[bsi ] r0 /= r1, remainder stored in r1"),
// math library
ABS (0x0010, "[ if]"),
ACOS (0x0011, "[ f]"),
ASIN (0x0012, "[ f]"),
ATAN (0x0013, "[ f]"),
ATAN2(0x0014, "[ f] r1"),
CBRT (0x0015, "[ f]"),
CEIL (0x0016, "[ f]"),
COS (0x0017, "[ f]"),
COSH (0x0018, "[ f]"),
EXP (0x0019, "[ f]"),
EXPM1(0x001a, "[ f]"),
FLR (0x001b, "[ f]"),
FDIV (0x001c, "[bsif] r1"),
FMOD (0x001d, "[bsif] r1"),
GEXP (0x001e, "[ f]"),
HYPOT(0x001f, "[ f] r1"),
IEEER(0x0020, "[ f] r1"),
LOG (0x0021, "[ f]"),
LOG10(0x0022, "[ f]"),
LOG1P(0x0023, "[ f]"),
MAX (0x0024, "[bsif] r1"),
MIN (0x0025, "[bsif] r1"),
NEXTA(0x0026, "[ f] r1"),
NEXTD(0x0027, "[ f]"),
NEXTU(0x0028, "[ f]"),
POW (0x0029, "[ f] r1"),
RAND (0x002a, "[ f]"),
RINT (0x002b, "[ f]"),
ROUND(0x002c, "[bsif]"),
SCALB(0x002d, "[ f] r1"),
SIGNM(0x002e, "[ f]"),
SIN (0x002f, "[ f]"),
SINH (0x0030, "[ f]"),
SQRT (0x0031, "[ f]"),
TAN (0x0032, "[ f]"),
TANH (0x0033, "[ f]"),
TDEG (0x0034, "[ f]"),
TRAD (0x0035, "[ f]"),
ULP (0x0036, "[ f]"),
// conversions
VC2B (0x0080, "[bsif] Type conversion to byte"),
VC2S (0x0081, "[bsif] Type conversion to short"),
VC2I (0x0082, "[bsif] Type conversion to int"),
VC2F (0x0083, "[bsif] Type conversion to float"),
VL2B (0x0084, "[bsif] Length conversion to byte"),
VL2S (0x0085, "[bsif] Length conversion to short"),
VL2I (0x0086, "[bsif] Length conversion to int"),
VL2F (0x0087, "[bsif] Length conversion to float"),
// bitwise operations
AND(0x0090, "[bsi ] r0 & r1"),
OR(0x0091, "[bsi ] r0 | r1"),
XOR(0x0092, "[bsi ] r0 ^ r1"),
BSU(0x0093, "[bsi ] r0 << r1"), BSL(0x0093, "Alias for BSU"),
BSD(0x0094, "[bsi ] r0 >> r1"), BSR(0x0094, "Alias for BSD")
;
private short o;
private String description;
private KmcuOpCodes(short opcode) { hCons(opcode, ""); }
private KmcuOpCodes(int opcode) { hCons((short)(0xffff & opcode), ""); }
private KmcuOpCodes(short opcode, String desc) { hCons(opcode, desc); }
private KmcuOpCodes(int opcode, String desc) { hCons((short)(0xffff & opcode), desc); }
private void hCons(short opcode, String desc) {
o = opcode;
description = desc;
}
public short getOpcode() { return o; }
public String getDescription() { return description; }
}
package me.felinewith.kcpu.hardware;
package me.felinewith.kcpu.hardware.kmcu;
/**
*
* @author jlhawkwell
*/
public enum KmcpValueType {
public enum KmcuValueType {
VTBYTE(0x0001),
VTSHORT(0x0002),
VTINT(0x0003),
VTFLOAT(0x0004),
;
private short m;
private KmcpValueType(short mask) { m = mask; }
private KmcpValueType(int mask) { m = (short)(0xffff & mask); }
private KmcuValueType(short mask) { m = mask; }
private KmcuValueType(int mask) { m = (short)(0xffff & mask); }
public short mask() { return m; }
}
package me.felinewith.kcpu.memory;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;
import me.felinewith.kcpu.Converter;
import me.felinewith.kcpu.Kasm;
import me.felinewith.kcpu.util.BaseMemory;
......@@ -25,26 +28,24 @@ public class BootRom extends BaseMemory {
// hardcoding some bootrom
writeBytes(Kasm.compile("movs $0 r2"));
writeBytes(Kasm.compile("movs 10,16 1"));
writeBytes(Kasm.compile("add r0 16"));
writeBytes(Kasm.compile("add r2 1"));
writeBytes(Kasm.compile("movs $0 r2"));
writeBytes(Kasm.compile("jdl r0 512 2a,16"));
writeBytes(Kasm.compile("jdl r0 512 22,16"));
//writeBytes(Kasm.compile("movs r0 0"));
//writeBytes(Kasm.compile("movs r1 0"));
//writeBytes(Kasm.compile("movs r2 0"));
//writeBytes(Kasm.compile("movs r3 0"));
writeBytes(Kasm.compile("gpc %0300,16"));
writeBytes(Kasm.compile("mov ff00,16 61,16"));
writeBytes(Kasm.compile("irqm ff01,16"));
}
@Override public void memIrq(short addr) {
if ((prev2 == 0x4b63) && (prev == 0x7075) && (addr == 0x7f)) { writable = true; }
else { writable = false; }
writable = ((prev2 == 0x4b63) && (prev == 0x7075) && (addr == 0x7f));
if ((0xff & prev) == 0) { prev += addr; }
else if ((0xff00 & prev) == 0) { prev = (short)(prev << 8); prev += addr; }
......@@ -55,26 +56,6 @@ public class BootRom extends BaseMemory {
if (!writable) { return; }
super.write(addr, data);
}
private void writeInt(int input) {
byte[] data = Converter.int2bytes(input);
writeByte(data[3]);
writeByte(data[2]);
writeByte(data[1]);
writeByte(data[0]);
}
private void writeInt(short input) { writeInt(0xffff & input); }
private void writeInt(byte input) { writeInt(0xff & input); }
private void writeShort(int input) { writeShort((short)(0xffff & input)); }
private void writeShort(short input) {
byte[] data = Converter.short2bytes(input);
writeByte(data[1]);
writeByte(data[0]);
}
private void writeShort(byte input) { writeShort((short)(0xff & input)); }
private void writeByte(int input) { writeByte((byte)(0xff & input)); }
private void writeByte(short input) { writeByte((byte)(0xff & input)); }
private void writeByte(byte input) {
memory[writepos] = input;
writepos++;
......@@ -84,4 +65,21 @@ public class BootRom extends BaseMemory {
private void writeBytes(byte[] input) {
for (byte b : input) { writeByte(b); }
}
public void reset() { writepos = 0; }
public void load(String filename) throws FileNotFoundException, IOException { load(new File(filename)); }
public void load(File file) throws FileNotFoundException, IOException {
if (!file.isFile() || !file.canRead()) { return; }
FileInputStream fis = new FileInputStream(file);
byte[] buffer = new byte[512];
int a;
int read = 0;
read = fis.read(buffer);
while (read != -1) {
for (a = 0; a < read; a++) { writeByte(buffer[a]);}
read = fis.read(buffer);
}
fis.close();
}
}
package me.felinewith.kcpu.opcodes;
import java.util.Arrays;
import me.felinewith.kcpu.IMemory;
import me.felinewith.kcpu.interfaces.IMemory;
import me.felinewith.kcpu.util.helpers.ValueHelper;
/**
*
* @author jlhawkwell
*/
public class BasicMath implements IHandler {
public class BasicMath implements IOpcodeHandler {
@Override public short[] opcode(OpDirector opcode, short pc, short ref, short[] regs, short[] values, IMemory memory) {
short[] out = Arrays.copyOf(regs, regs.length);
......@@ -15,17 +16,14 @@ public class BasicMath implements IHandler {
short vb = ValueHelper.readShort(1, ref, out, values, memory);
switch (opcode) {
case ADD: out[0] = new Integer(va + vb).shortValue(); break;
case ADD: out = ValueHelper.writeShort(0, ref, out, values, memory, new Integer(va + vb).shortValue()); break;
case DIV:
out[0] = (short)(va / vb);
out[1] = (short)(va % vb);
out = ValueHelper.writeShort(0, ref, out, values, memory, new Integer(va / vb).shortValue());
out = ValueHelper.writeShort(1, ref, out, values, memory, new Integer(va % vb).shortValue());
break;
case MUL: out[0] = (short)(va * vb); break;
case SUB: out[0] = (short)(va - vb); break;
case MUL: out = ValueHelper.writeShort(0, ref, out, values, memory, new Integer(va * vb).shortValue()); break;
case SUB: out = ValueHelper.writeShort(0, ref, out, values, memory, new Integer(va - vb).shortValue()); break;
}
short output[] = Arrays.copyOf(regs, regs.length);
output = ValueHelper.writeShort(0, ref, regs, values, memory, out[0]);
output = ValueHelper.writeShort(1, ref, output, values, memory, out[1]);
return output;
return out;
}
}
package me.felinewith.kcpu.opcodes;
import me.felinewith.kcpu.IMemory;
import me.felinewith.kcpu.interfaces.IMemory;
/**
*
* @author jlhawkwell
*/
public interface IHandler {
public interface IOpcodeHandler {
public abstract short[] opcode(OpDirector opcode, short pc, short ref, short[] regs, short[] values, IMemory memory);
}
package me.felinewith.kcpu.opcodes;
import me.felinewith.kcpu.util.helpers.ValueHelper;
import java.util.Arrays;
import me.felinewith.kcpu.IMemory;
import me.felinewith.kcpu.interfaces.IMemory;
/**
*
* @author jlhawkwell
*/
public class Memory implements IHandler {
public class Memory implements IOpcodeHandler {
@Override public short[] opcode(OpDirector opcode, short pc, short ref, short[] regs, short[] values, IMemory memory) {
short data;
......
package me.felinewith.kcpu.opcodes;
import me.felinewith.kcpu.IMemory;
import me.felinewith.kcpu.interfaces.IMemory;
/**
*
......@@ -9,75 +9,89 @@ import me.felinewith.kcpu.IMemory;
public enum OpDirector {
// basic math stuffies
ADD(0x0001, BasicMath.class),
SUB(0x0002, BasicMath.class),
MUL(0x0003, BasicMath.class),
DIV(0x0004, BasicMath.class),
ADD(0x0001, BasicMath.class, "n0 += n1"),
SUB(0x0002, BasicMath.class, "n0 += n1"),
MUL(0x0003, BasicMath.class, "n0 += n1"),
DIV(0x0004, BasicMath.class, "n0 /= n1, remainder to n1"),
// memory stuffies
MOV (0x0010, Memory.class), MOVB(0x0010, Memory.class),
MOVS(0x0011, Memory.class),
MOV (0x0010, Memory.class, "Alias for MOVB"), MOVB(0x0010, Memory.class, "dest value"),
MOVS(0x0011, Memory.class, "dest value"),
// cpu stuffies
DEVA(0xff00), // get device port from address
DEVD(0xff01), // detach device
DEVM(0xff02), // relocate device
DEVP(0x1003), // get device address from port
IRQD(0xff10), // interrupt to port
IRQM(0xff11), // interrupt to memory
JMP (0xff18), // jump up
JMPA(0xff19), // jump absolute addr
JMPD(0xff1a), // jump down
GPC (0xff1b), // get instruction pointer
JE (0xff20), // jump if =
JAE (0xff21),
JDE (0xff22),
JG (0xff23), // jump if >
JAG (0xff24),
JDG (0xff25),
JL (0xff26), // jump if <
JAL (0xff27),
JDL (0xff28),
JGE (0xff29), // jump if >=
JAGE(0xff2a),
JDGE(0xff2b),
JLE (0xff2c), // jump if <=
JALE(0xff2d),
JDLE(0xff2e),
VCMP(0xff2f),
ZPWR(0xffff), // power off
DEVA(0xff00, "n0; get device at address n0"), // get device port from address
DEVD(0xff01, "n0: detach device on port n0"), // detach device
DEVM(0xff02, "n0 n1: relocate device n0 to address n1"), // relocate device
DEVP(0x1003, "n0: get device address for device on port n0"), // get device address from port
IRQD(0xff10, "n0: send interrupt to port n0"), // interrupt to port
IRQM(0xff11, "n0: send interrupt to memory address n0"), // interrupt to memory
JMP (0xff18, "Alias of JMPU"), // jump up
JMPU(0xff18, "n0: jump up n0 addresses"),
JMPA(0xff19, "n0: jump to address n0"), // jump absolute addr
JMPD(0xff1a, "n0: jump down n0 addresses"), // jump down
GPC (0xff1b, "write instruction pointer"), // get instruction pointer
JE (0xff20, "Alias of JUE"), // jump if =
JUE (0xff20, "n0 n1 n2: jump if n0 == n1, see JMPU"),
JAE (0xff21, "n0 n1 n2: jump if n0 == n1, see JMPA"),
JDE (0xff22, "n0 n1 n2: jump if n0 == n1, see JMPD"),
JG (0xff23, "Alias of JUG"), // jump if >
JUG (0xff23, "n0 n1 n2: jump if n0 > n1, see JMPU"),
JAG (0xff24, "n0 n1 n2: jump if n0 > n1, see JMPA"),
JDG (0xff25, "n0 n1 n2: jump if n0 > n1, see JMPD"),
JL (0xff26, "Alias of JUL"), // jump if <
JUL (0xff26, "n0 n1 n2: jump if n0 < n1, see JMPU"),
JAL (0xff27, "n0 n1 n2: jump if n0 < n1, see JMPA"),
JDL (0xff28, "n0 n1 n2: jump if n0 < n1, see JMPD"),
JGE (0xff29, "Alias of JUGE"), // jump if >=
JUGE(0xff29, "n0 n1 n2: jump if n0 >= n1, see JMPU"),
JAGE(0xff2a, "n0 n1 n2: jump if n0 >= n1, see JMPA"),
JDGE(0xff2b, "n0 n1 n2: jump if n0 >= n1, see JMPD"),
JLE (0xff2c, "Alias of JULE"), // jump if <=
JULE(0xff2c, "n0 n1 n2: jump if n0 <= n1, see JMPU"),
JALE(0xff2d, "n0 n1 n2: jump if n0 <= n1, see JMPA"),
JDLE(0xff2e, "n0 n1 n2: jump if n0 <= n1, see JMPD"),
VCMP(0xff2f, "n0 n1: performs multiple comparissons of n0 and n1"),
ZPWR(0xffff, "Power off"), // power off
;
short o;
Class<? extends IHandler> c;
private OpDirector(short opcode, Class<? extends IHandler> cls) {
String description;
Class<? extends IOpcodeHandler> c;
private OpDirector(short opcode, Class<? extends IOpcodeHandler> cls) { hCons(opcode, "", cls); }
private OpDirector(int opcode, Class<? extends IOpcodeHandler> cls) { hCons((short)(0xffff & opcode), "", cls); }
private OpDirector(short opcode) { hCons(opcode, "", null); }
private OpDirector(int opcode) { hCons((short)(0xffff & opcode), "", null); }
private OpDirector(short opcode, String desc, Class<? extends IOpcodeHandler> cls) { hCons(opcode, desc, cls); }
private OpDirector(int opcode, String desc, Class<? extends IOpcodeHandler> cls) {
hCons((short)(0xffff & opcode), desc, cls); }
private OpDirector(short opcode, String desc) { hCons(opcode, desc, null); }
private OpDirector(int opcode, String desc) { hCons((short)(0xffff & opcode), desc, null); }
private OpDirector(short opcode, Class<? extends IOpcodeHandler> cls, String desc) { hCons(opcode, desc, cls); }
private OpDirector(int opcode, Class<? extends IOpcodeHandler> cls, String desc) {
hCons((short)(0xffff & opcode), desc, cls); }
private void hCons(short opcode, String desc, Class<? extends IOpcodeHandler> cls) {
o = opcode;
c = cls;
}
private OpDirector(int opcode, Class<? extends IHandler> cls) {
o = (short)(0xffff & opcode);
c = cls;
}
private OpDirector(short opcode) {
o = opcode;
c = null;
}
private OpDirector(int opcode) {
o = (short)(0xffff & opcode);
c = null;
description = desc;
}
public short getOpcode() { return o; }
public boolean hasHandler() { return (c != null); }
public String getDescription() { return description; }
public short[] call(short pc, short ref, short[] regs, short[] values, IMemory memory) {
try {
if (c == null) { return regs; }
IHandler ih = c.newInstance();
IOpcodeHandler ih = c.newInstance();
return ih.opcode(this, pc, ref, regs, values, memory);
}
catch (IllegalAccessException | InstantiationException e) {}
......
package me.felinewith.kcpu.opcodes;
/**
*
* @author jlhawkwell
*/
public enum ValueType {
NONE(0),
REGISTER(1),
DATA(2),
ADDRESS(3);
int t;
private ValueType(int type) { t = type; }
public int getValue() { return t; }
}
package me.felinewith.kcpu.util;
import me.felinewith.kcpu.IDevice;
import me.felinewith.kcpu.IMemory;
import me.felinewith.kcpu.interfaces.IDevice;
import me.felinewith.kcpu.interfaces.IMemory;
/**
*
......
package me.felinewith.kcpu.util;
import me.felinewith.kcpu.IMemory;
import me.felinewith.kcpu.interfaces.IMemory;
/**
*
......
package me.felinewith.kcpu.util;
import java.util.TimerTask;
import me.felinewith.kcpu.IDevice;
import me.felinewith.kcpu.interfaces.IDevice;
/**
*
......
package me.felinewith.kcpu.util;
import java.util.TimerTask;
import me.felinewith.kcpu.IMemory;
import me.felinewith.kcpu.interfaces.IMemory;
/**
*
......
package me.felinewith.kcpu.util;
import java.util.TimerTask;
import me.felinewith.kcpu.IDevice;
import me.felinewith.kcpu.interfaces.IDevice;
/**
*
......
package me.felinewith.kcpu.util;
import me.felinewith.kcpu.IDevice;
/**
*
* @author jlhawkwell
*/
public class IDeviceRunner implements Runnable {
IDevice id;
public IDeviceRunner(IDevice device) {
id = device;
}
@Override public void run() { id.exec(); }
}
package me.felinewith.kcpu.memory;
package me.felinewith.kcpu.util.helpers;
import me.felinewith.kcpu.Converter;
import me.felinewith.kcpu.IMemory;
import me.felinewith.kcpu.util.Converter;
import me.felinewith.kcpu.interfaces.IMemory;
/**
*
......
package me.felinewith.kcpu.opcodes;
package me.felinewith.kcpu.util.helpers;
import java.util.Arrays;
import me.felinewith.kcpu.IMemory;
import me.felinewith.kcpu.memory.MemHelper;
import me.felinewith.kcpu.interfaces.IMemory;
/**
*
......@@ -57,9 +56,9 @@ public class ValueHelper {
case 3: cref = (short)(0x00c0 & ref); break;
}
switch (cref) {
case 0x0000:
case 0x0001: case 0x0004: case 0x0010: case 0x0040:
output[reg] = data; break;
case 0x0000:
case 0x0002: case 0x0008: case 0x0020: case 0x0080:
MemHelper.writeByte(values[pos], data, memory); break;
case 0x0003: case 0x000c: case 0x0030: case 0x00c0:
......@@ -111,9 +110,9 @@ public class ValueHelper {
case 3: cref = (short)(0x00c0 & ref); break;
}
switch (cref) {
case 0x0000:
case 0x0001: case 0x0004: case 0x0010: case 0x0040:
output[reg] = data; break;
case 0x0000:
case 0x0002: case 0x0008: case 0x0020: case 0x0080:
MemHelper.writeShort(values[pos], data, memory); break;
case 0x0003: case 0x000c: case 0x0030: case 0x00c0:
......@@ -121,4 +120,6 @@ public class ValueHelper {
}
return output;
}
private ValueHelper() { }
}
package me.felinewith.kcpu.util.helpers;
/**
*
* @author jlhawkwell
*/
public enum ValueType {
D(0),
R(1),
AD(2),
AR(3);
int t;
private ValueType(int type) { t = type; }
public static ValueType valueOf(int value, int position) {
int temp = value >> (position * 2);
return valueOf(temp);
}
public static ValueType valueOf(int value) {
int test = 0x0003 & value;
for (ValueType vt : ValueType.values()) {
if (vt.getValue() == test) { return vt; }
}
return D;
}
public int getValue() { return t; }
}
movs r0 0
movs r1 0
movs r2 0
movs r3 0
mov ff00,16 61,16
irqm ff01,16
movs $0 r2
add r0 16
add r2 1
movs $0 r2
jdl r0 512 2a,16
deva 0
deva 1
gpc
gpc %300,16
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!