Commit 0cbce396 by Jessica Hawkwell

added lots of stuffs, it executes code now

1 parent eb9f4a4c
Pipeline #208 passed
in 1 minute 10 seconds
# project-specific stuffs
*.mem
*.bin
*.kc
# swap
[._]*.s[a-v][a-z]
[._]*.sw[a-p]
......
......@@ -154,7 +154,7 @@
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
<classpathLayoutType>repository</classpathLayoutType>
<packageName></packageName>
<mainClass>me.felinewith.kcpu.Kemulator</mainClass>
</manifest>
</archive>
</configuration>
......
......@@ -10,4 +10,6 @@ public interface IMemory {
public abstract void write(short addr, byte data);
public void copy(short addrSrc, short addrDest, IMemory dest);
public abstract void memIrq(short addr);
public void powerOff();
}
package me.felinewith.kcpu;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import java.util.Timer;
import java.util.TimerTask;
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.memory.Buffer;
import me.felinewith.kcpu.util.BaseDevice;
import me.felinewith.kcpu.util.HardwareExec;
import me.felinewith.kcpu.util.HardwareMemIrq;
......@@ -27,24 +22,15 @@ import me.felinewith.kcpu.util.HardwareMemIrq;
public class KBoard extends BaseDevice implements IMemory {
final ThreadPoolExecutor tpe;
TimerTask tt;
Timer t;
private final IDevice[] devices;
private final KMemoryRange[] deviceMaps;
private IDevice[] devices;
private KMemoryRange[] deviceMaps;
private final IMemory[] memDevs;
private final KMemoryRange[] memDevMaps;
private IMemory[] memDevs;
private KMemoryRange[] memDevMaps;
private final Charset cs;
private final InputStream stdin;
private final OutputStream stdout;
private final byte[] bin;
private final InputStreamReader bufin;
private final OutputStreamWriter bufout;
private Charset cs;
private Kcpu cpu;
public KBoard() {
tpe = new ThreadPoolExecutor(16, 32, 30, TimeUnit.SECONDS, new LinkedBlockingQueue<>(16));
......@@ -56,26 +42,37 @@ public class KBoard extends BaseDevice implements IMemory {
memDevMaps = new KMemoryRange[16];
cs = Charset.forName("UTF-8");
bin = new byte[16];
stdin = new ByteArrayInputStream(bin);
stdout = new ByteArrayOutputStream(16);
bufin = new InputStreamReader(stdin);
bufout = new OutputStreamWriter(stdout);
}
public void init() {
attachDevice(0, 0x8000, new Kcpu(this));
cpu = new Kcpu(this);
attachDevice(0, 0x8000, cpu);
attachDevice(1, 0x8800, new Kmcp());
attachMemory(0, 0xff00, new Buffer());
//attachMemory(0, 0xff00, new Buffer());
attachMemory(1, 0x1000, new BootRom());
tt = new HardwareExec(devices[0]);
t = new Timer("CPU Cycler");
t.schedule(tt, 0, 1);
System.out.println("CPU up...");
while (cpu.workCycle() != 0xff) {
Thread.yield();
}
System.err.println("CPU Stopped [zpwr]");
tpe.shutdown();
System.err.println("Timers stopped");
int a;
for (a = 0; a <= 0xf; a++) {
if (devices[a] != null) {
devices[a].powerOff();
System.err.println(String.format("device %x stopped", a));
}
if (memDevs[a] != null) {
memDevs[a].powerOff();
System.err.println(String.format("memdev %x stopped", a));
}
}
dumpEverything();
}
@Override public void memIrq(short addr) {
......@@ -91,9 +88,7 @@ public class KBoard extends BaseDevice implements IMemory {
short devOff = memDevMaps[rdev].getOffset();
short devAddr = (short)(addr - devOff);
tpe.execute(new HardwareMemIrq(memDevs[rdev], devAddr));
memDevs[rdev].memIrq(devAddr);
}
}
@Override public void sendIrq(byte irq) {
......@@ -121,6 +116,7 @@ public class KBoard extends BaseDevice implements IMemory {
@Override public void write(short addr, byte data) {
short dev = checkDevice(addr);
short rdev = (short)(0x0f & dev);
if ( dev == 0x7f ) { memory[0xffff & addr] = data; }
if ( dev <= 0x0f ) {
short devOff = deviceMaps[rdev].getOffset();
short devAddr = (short)(addr - devOff);
......@@ -130,13 +126,7 @@ public class KBoard extends BaseDevice implements IMemory {
short devOff = memDevMaps[rdev].getOffset();
short devAddr = (short)(addr - devOff);
memDevs[rdev].write(devAddr, data);
if (rdev == 0) {
try { bufout.write(0xff & data); }
catch (IOException x) {}
}
}
memory[0xffff & addr] = data;
}
public void attachDevice(int port, int offset, IDevice device) {
......@@ -224,21 +214,76 @@ public class KBoard extends BaseDevice implements IMemory {
}
@Override public void exec() {
try {
if ( bufin.ready() ) {
byte[] temp = bufin.toString().getBytes(cs);
int len = temp.length;
if ( len >= 16) { len = 16; }
short addr;
short a;
for (a = 0; a < len; a++) {
addr = (short)(0x10 + a);
memDevs[0].write(addr, temp[a]);
}
public void dumpEverything() {
dumpMemory("system", memory);
int a;
for (a = 0; a < 16; a++) {
if (devices[a] != null) { dumpMemory(String.format("device-%x", a), devices[a]); }
}
for (a = 0; a < 16; a++) {
if (memDevs[a] != null) { dumpMemory(String.format("memDev-%x", a), memDevs[a]); }
}
}
public void dumpMemory(String filename, IMemory mem) {
byte[] temp = new byte[mem.length()];
int a;
for (a = 0; a < mem.length(); a++) {
temp[a] = mem.read((short)a);
}
dumpMemory(filename, temp);
}
public void dumpMemory(String filename, byte[] mem) {
File f = new File(filename.concat(".mem"));
try (FileWriter fw = new FileWriter(f)) {
int max = mem.length - 12;
int a;
for (a = 0; a < max; a += 12) {
fw.write(String.format("[%04x] %02x%02x : ", a, mem[a], mem[a + 1]));
fw.write(String.format("%02x%02x -> ", mem[a + 2], mem[a + 3]));
fw.write(String.format("%02x%02x ", mem[a + 4], mem[a + 5]));
fw.write(String.format("%02x%02x ", mem[a + 6], mem[a + 7]));
fw.write(String.format("%02x%02x ", mem[a + 8], mem[a + 9]));
fw.write(String.format("%02x%02x\n", mem[a + 10], mem[a + 11]));
}
if ( a < mem.length ) {
while (a < mem.length) {
fw.write(String.format("[%04x] %02x\n", a, mem[a]));
a++;
}
}
fw.flush();
fw.close();
}
catch (IOException e) {}
}
catch (IOException x) {}
f = new File(filename.concat(".mem.bin"));
try (FileOutputStream fos = new FileOutputStream(f)) {
if (mem.length <= 4096) {
System.err.println(String.format("%s Writing %d bytes...", filename, mem.length));
fos.write(mem);
}
else {
int max = mem.length - 4096;
int a;
byte[] temp;
for (a = 0; a < max; a += 4096) {
temp = Arrays.copyOfRange(mem, a, a + 4096);
System.err.println(String.format("%s Writing %d bytes...", filename, temp.length));
fos.write(temp);
}
if ( a < mem.length ) {
temp = Arrays.copyOfRange(mem, a, mem.length);
System.err.println(String.format("%s Writing %d bytes...", filename, temp.length));
fos.write(temp);
}
}
fos.flush();
fos.close();
}
catch (IOException x) {}
}
}
package me.felinewith.kcpu;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import me.felinewith.kcpu.opcodes.OpDirector;
/**
*
* @author jlhawkwell
*/
public class Kasm {
private static PrintStream outer;
public static void main(String[] args) {
setOuter(System.out);
for (String a : args) {
if ( a.endsWith(".kasm") ) {
try { assemble(a); }
catch (IOException x) {}
}
}
}
static void assemble(String filename) throws IOException { assemble(new File(filename));}
static void assemble(File file) throws IOException {
File out = new File(file.getCanonicalPath().concat(".kc"));
logln("\nInput : %s\nOutput: %s", file.getCanonicalPath(), out.getCanonicalPath());
FileInputStream fis = new FileInputStream(file);
FileOutputStream fos = new FileOutputStream(out);
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr);
String line;
byte[] temp;
int a;
while ((line = br.readLine()) != null) {
temp = compile(line);
fos.write(temp);
}
fos.flush();
fos.close();
br.close();
isr.close();
fis.close();
}
static public byte[] compile(String kasm) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if ( kasm.startsWith("#") || kasm.startsWith("//") || kasm.length() == 0 ) {}
else {
String[] parts;
OpDirector opcode;
short ref = 0;
if ( kasm.contains(" ") ) { parts = kasm.split(" "); }
else { parts = new String[]{kasm}; }
parts[0] = parts[0].toUpperCase();
opcode = OpDirector.valueOf(parts[0]);
log("[%10s] ", opcode.name());
writeShort(baos, opcode.getOpcode());
log(" : ");
if (parts.length >= 2) { ref += asmType(parts[1]); }
if (parts.length >= 3) { ref += (short)(asmType(parts[2]) << 4); }
if (parts.length >= 4) { ref += (short)(asmType(parts[3]) << 8); }
if (parts.length >= 5) { ref += (short)(asmType(parts[4]) << 12); }
writeShort(baos, ref);
log(" -> ");
if (parts.length >= 2) { writeShort(baos, numberize(parts[1])); } else { writeShort(baos, (short)0); }
if (parts.length >= 3) { writeShort(baos, numberize(parts[2])); } else { writeShort(baos, (short)0); }
if (parts.length >= 4) { writeShort(baos, numberize(parts[3])); } else { writeShort(baos, (short)0); }
if (parts.length >= 5) { writeShort(baos, numberize(parts[4])); } else { writeShort(baos, (short)0); }
logln("");
}
return baos.toByteArray();
}
static void writeShort(ByteArrayOutputStream baos, short value) {
byte[] temp = Converter.short2byte(value);
log("%02x%02x ", temp[0], temp[1]);
baos.write(temp, 0, temp.length);
}
static void writeShort(FileOutputStream fos, short value) throws IOException {
byte[] v = Converter.short2byte(value);
log("[%02x%02x]", v[0], v[1]);
fos.write(v);
}
static String stripType(String input) {
if (asmType(input) == 0) { return input; }
return input.substring(1);
}
static short asmType(String input) { return asmType(input.charAt(0)); }
static short asmType(char input) {
switch (input) {
case 'r': return 0x01;
case '%': return 0x02;
case '$': return 0x03;
default: return 0x00;
}
}
static short numberize(String input) {
String temp = stripType(input);
String[] pt;
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));
}
else { return (short)(0xffff & Integer.valueOf(temp)); }
}
/**
* @return the outer
*/
public static PrintStream getOuter() { return outer; }
/**
* @param aOuter the outer to set
*/
public static void setOuter(PrintStream aOuter) { outer = aOuter; }
private static void log(String format, Object... vals) {
if ( outer == null ) { return; }
outer.print(String.format(format, vals));
}
private static void logln(String format, Object... vals) {
if ( outer == null ) { return; }
outer.println(String.format(format, vals));
}
}
package me.felinewith.kcpu;
import java.util.TimerTask;
import java.io.PrintStream;
import me.felinewith.kcpu.memory.MemHelper;
import me.felinewith.kcpu.opcodes.OpDirector;
import me.felinewith.kcpu.opcodes.ValueHelper;
import me.felinewith.kcpu.util.BaseDevice;
/**
*
* @author jlhawkwell
*/
public class Kcpu extends TimerTask implements IDevice {
public class Kcpu extends BaseDevice {
private static PrintStream outer;
/**
* @return the outer
*/
public static PrintStream getOuter() { return outer; }
/**
* @param aOuter the outer to set
*/
public static void setOuter(PrintStream aOuter) { outer = aOuter; }
private static void log(String format, Object... vals) {
if ( outer == null ) { return; }
outer.print(String.format(format, vals));
}
private static void logln(String format, Object... vals) {
if ( outer == null ) { return; }
outer.println(String.format(format, vals));
}
private byte[] memory;
private String name;
//private byte[] memory;
//private String name;
private short[] settings;
short pc;
short[] registers;
private KBoard board;
private KBoard kboard;
public Kcpu(KBoard system) {
memory = new byte[0x0800];
name = "Kcpu";
settings = new short[6];
board = system;
kboard = system;
pc = 0x1000;
registers = new short[4];
}
@Override public void init(IMemory system) { }
// use this one during interrupts
@Override public void exec() {
@Override public void init(IMemory system) {
setOuter(System.err);
OpDirector[] list = OpDirector.values();
for (OpDirector od : list) {
logln("[%10s] %04x", od.name(), od.getOpcode());
}
}
@Override public short length() { return 0x07ff; }
@Override public void exec() { workCycle(); }
@Override public byte read(short addr) {
if ( (0xffff & addr) > length() ) { return (byte)0xff; }
......@@ -46,24 +69,19 @@ public class Kcpu extends TimerTask implements IDevice {
@Override public void write(short offset, byte data) { }
@Override public void copy(short addrSrc, short addrDest, IMemory dest) { }
// this one for normal execution
@Override public void run() { workCycle(); }
@Override public void memIrq(short addr) {
if ( 0 <= addr && addr <= memory.length ) { exec(); }
}
@Override public void sendIrq(byte irq) { board.sendIrq(irq); }
private void workCycle() {
public int workCycle() {
if ( pc >= 0xfff0 ) { pc = 0; }
short inst = MemHelper.readShort(pc, board);
short ref = MemHelper.readShort(pc + 2, board);
short inst = MemHelper.readShort(pc, kboard);
short ref = MemHelper.readShort(pc + 2, kboard);
short[] values = new short[4];
values[0] = MemHelper.readShort(pc + 4, board);
values[1] = MemHelper.readShort(pc + 6, board);
values[2] = MemHelper.readShort(pc + 8, board);
values[3] = MemHelper.readShort(pc + 10, board);
values[0] = MemHelper.readShort(pc + 4, kboard);
values[1] = MemHelper.readShort(pc + 6, kboard);
values[2] = MemHelper.readShort(pc + 8, kboard);
values[3] = MemHelper.readShort(pc + 10, kboard);
OpDirector od = null;
for (OpDirector o : OpDirector.values()) {
......@@ -73,43 +91,48 @@ public class Kcpu extends TimerTask implements IDevice {
}
}
if ( od == null ) { pc += 12; return; } // inc 2 if nop
logln("%04x : [%10s] %04x %04x -> %04x %04x %04x %04x",
pc, ((od == null)?"nop":od.name()), inst, ref, values[0], values[1], values[2], values[3]
);
if ( od == null ) { pc += 12; return 0; } // inc if nop
if ( od.hasHandler() ) {
registers = od.call(pc, ref, registers, values, board);
registers = od.call(pc, ref, registers, values, kboard);
pc += 12;
return;
return 0;
}
pc += 12;
short data;
data = ValueHelper.readValue(0, ref, registers, values, board);
data = ValueHelper.readShort(0, ref, registers, values, kboard);
switch (od) {
// device management
case DEVA: registers[0] = board.checkDevice(data); return;
case DEVD: board.detachDevice(data); return;
case DEVA: registers[0] = kboard.checkDevice(data); return 0;
case DEVD: kboard.detachDevice(data); return 0;
case DEVM:
short d2 = ValueHelper.readValue(1, ref, registers, values, board);
board.setDeviceRange(data, d2);
return;
short d2 = ValueHelper.readShort(1, ref, registers, values, kboard);
kboard.setDeviceRange(data, d2);
return 0;
case DEVP:
KMemoryRange kmr = board.getDeviceRange(data);
KMemoryRange kmr = kboard.getDeviceRange(data);
registers[0] = kmr.getOffset();
registers[1] = kmr.getLength();
return;
return 0;
// interrupts
case IRQD: board.sendIrq((byte)(0x000f & data)); return;
case IRQM: board.memIrq(data); return;
case IRQD: kboard.sendIrq((byte)(0x000f & data)); return 0;
case IRQM: kboard.memIrq(data); return 0;
// jumps
case JMP: pc = (short)(pc + (0xffff & data)); return;
case JMPA: pc = data; return;
case JMPD: pc = (short)(pc - (0xffff & data)); return;
case JMP: pc = (short)(pc + (0xffff & data)); return 0;
case JMPA: pc = data; return 0;
case JMPD: pc = (short)(pc - (0xffff & data)); return 0;
case ZPWR:
board.t.cancel();
case ZPWR: return 0xff;
}
return 0;
}
}
package me.felinewith.kcpu;
import me.felinewith.kcpu.memory.Buffer;
/**
*
* @author jlhawkwell
*/
public class Kemulator {
public static void main(String[] args) {
KBoard kb = new KBoard();
Buffer bb = new Buffer();
for (String s : args) { System.out.println(String.format("\t%s", s)); }
if ( args.length != 0 ) {
for (String s : args) {
if (s.equals("-kasm")) { Kasm.main(args); return; }
}
}
bb.setInputStream(System.in);
bb.setOutputStream(System.out);
kb.attachMemory(0, 0xff00, bb);
kb.init();
System.out.flush();
}
}
package me.felinewith.kcpu.hardware;
/**
*
* @author jlhawkwell
*/
public enum KcmpOpCodes {
// basic math stuffies
ADD(0x0001),
SUB(0x0002),
MUL(0x0003),
DIV(0x0004),
// everything here is same as above
;
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 java.io.PrintStream;
import java.util.Arrays;
import me.felinewith.kcpu.Converter;
import me.felinewith.kcpu.util.BaseDevice;
......@@ -8,8 +10,29 @@ import me.felinewith.kcpu.util.BaseDevice;
* @author jlhawkwell
*/
public class Kmcp extends BaseDevice {
private static PrintStream outer;
/**
* @return the outer
*/
public static PrintStream getOuter() { return outer; }
/**
* @param aOuter the outer to set
*/
public static void setOuter(PrintStream aOuter) { outer = aOuter; }
private static void log(String format, Object... vals) {
if ( outer == null ) { return; }
outer.print(String.format(format, vals));
}
private static void logln(String format, Object... vals) {
if ( outer == null ) { return; }
outer.println(String.format(format, vals));
}
public Kmcp() {
setOuter(System.err);
memory = new byte[0x20];
name = "Kmcp";
}
......@@ -39,43 +62,46 @@ public class Kmcp extends BaseDevice {
read(starts + 1)
};
short opcode = Converter.byte2short(data);
a = (short)(0xff & opcode);
temp = do2reg(a, reg[0], reg[1]);
reg[0] = temp[0];
reg[1] = temp[1];
short tmpcode = (short)(0x7fff & opcode);
KcmpOpCodes od = null;
for (KcmpOpCodes o : KcmpOpCodes.values()) {
if (o.getOpcode() == tmpcode) {
od = o;
break;
}
}
logln("Kmcp : [%10s] %04x -> %04x %04x %04x %04x",
((od == null)?"nop":od.name()), opcode, reg[0], reg[1], reg[2], reg[3]
);
a = (short)((0xff00 & opcode) >> 8);
temp = do2reg(a, reg[2], reg[3]);
reg[2] = temp[0];
reg[3] = temp[1];
reg = performCalc(od, reg);
for ( a = 0; a <= 3; a++ ) {
writeReg(setting, a, reg[a]);
}
}
private short[] do2reg(short opcode, short reg0, short reg1) {
short[] out = new short[2];
out[0] = reg0;
out[1] = reg1;
private short[] performCalc(KcmpOpCodes opcode, short[] reg) {
short[] out = Arrays.copyOf(reg, reg.length);
switch (opcode) {
case 0x10: // add
out[0] = (short)(reg0 + reg1);
case ADD: // add
out[0] = (short)(reg[0] + reg[1]);
break;
case 0x11: // subt
out[0] = (short)(reg0 - reg1);
case DIV: // div
out[0] = (short)(reg[0] / reg[1]);
out[1] = (short)(reg[0] % reg[1]);
break;
case 0x12: // mult
out[0] = (short)(reg0 * reg1);
case SUB: // subt
out[0] = (short)(reg[0] - reg[1]);
break;
case 0x13: // div
out[0] = (short)(reg0 / reg1);
out[1] = (short)(reg0 % reg1);
case MUL: // mult
out[0] = (short)(reg[0] * reg[1]);
break;
}
return new short[]{reg0, reg1};
return out;
}
private short readReg(short setting, short reg) {
......
package me.felinewith.kcpu.memory;
import java.util.Arrays;
import me.felinewith.kcpu.Converter;
import me.felinewith.kcpu.Kasm;
import me.felinewith.kcpu.util.BaseMemory;
/**
......@@ -9,18 +11,52 @@ import me.felinewith.kcpu.util.BaseMemory;
*/
public class BootRom extends BaseMemory {
private short writepos;
public BootRom() {
writepos = 0;
memory = new byte[0x1000];
Arrays.fill(memory, (byte)0xff);
// hardcoding some bootrom
memory[0] = 0x11;
memory[1] = 0x00;
memory[2] = 0x01;
memory[3] = 0x00;
memory[4] = 0x61;
memory[5] = 0x41;
// clearing the registers is as close to a reset as we can get
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("mov ff00,16 61,16"));
writeBytes(Kasm.compile("irqm ff01,16"));
}
@Override public void write(short offset, byte data) { }
private void writeInt(int input) {
byte[] data = Converter.int2byte(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.short2byte(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++;
if ( writepos == memory.length ) { writepos = 0; }
}
private void writeBytes(byte[] input) {
for (byte b : input) { writeByte(b); }
}
}
package me.felinewith.kcpu.memory;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import me.felinewith.kcpu.util.BaseMemory;
/**
......@@ -8,7 +16,87 @@ import me.felinewith.kcpu.util.BaseMemory;
*/
public class Buffer extends BaseMemory {
private InputStream stdin;
private OutputStream stdout;
private byte[] bin;
private Charset cs;
private InputStreamReader bufin;
private OutputStreamWriter bufout;
public Buffer() {
memory = new byte[32];
bin = new byte[16];
stdin = new ByteArrayInputStream(bin);
stdout = new ByteArrayOutputStream(16);
cs = Charset.forName("UTF-8");
bufin = new InputStreamReader(stdin);
bufout = new OutputStreamWriter(stdout);
}
@Override public void memIrq(short addr) {
short a;
short value;
if (addr <= 0x0f) {
try {
for (a = 0; a <= 0x0f; a++) {
if ( memory[a] == 0 ) { break; }
bufout.write(memory[a]);
memory[a] = 0;
}
bufout.flush();
}
catch (IOException x) {}
}
if (addr >= 0x10) {
try {
if ( bufin.ready() ) {
byte[] temp = bufin.toString().getBytes(cs);
int len = temp.length;
if ( len >= 16) { len = 16; }
for (a = 0; a < len; a++) {
value = (short)(0x10 + a);
memory[value] = temp[a];
}
}
}
catch (IOException e) {}
}
}
@Override public byte read(short addr) {
if (addr >= memory.length) { return (byte)0xff; }
// input buffer clears when read
if ( addr >= 0x10 ) {
byte b = memory[addr];
memory[addr] = 0;
return b;
}
return memory[addr];
}
@Override public void write(short addr, byte data) {
// doing this to prevent programs from clobbering the input buffer
if ( addr >= 0x10 ) { return; }
super.write(addr, data);
}
public InputStream getInputStream() { return stdin; }
public OutputStream getOutputStream() { return stdout; }
public void setInputStream(InputStream is) {
stdin = is;
bufin = new InputStreamReader(stdin);
}
public void setOutputStream(OutputStream os) {
stdout = os;
bufout = new OutputStreamWriter(stdout);
}
}
......@@ -8,6 +8,18 @@ import me.felinewith.kcpu.IMemory;
* @author jlhawkwell
*/
public class MemHelper {
public static byte readByte(int addr, IMemory memory) { return readByte((short)addr, memory); }
public static byte readByte(short addr, IMemory memory) {
return memory.read(addr);
}
public static void writeByte(int addr, int data, IMemory memory) { writeByte((short)addr, (byte)data, memory); }
public static void writeByte(int addr, short data, IMemory memory) { writeByte((short)addr, (byte)data, memory); }
public static void writeByte(int addr, byte data, IMemory memory) { writeByte((short)addr, data, memory); }
public static void writeByte(short addr, int data, IMemory memory) { writeByte(addr, (byte)data, memory); }
public static void writeByte(short addr, short data, IMemory memory) { writeByte(addr, (byte)data, memory); }
public static void writeByte(short addr, byte data, IMemory memory) { memory.write(addr, data); }
public static short readShort(int addr, IMemory memory) { return readShort((short)addr, memory); }
public static short readShort(short addr, IMemory memory) {
byte[] data = new byte[2];
......@@ -16,12 +28,14 @@ public class MemHelper {
return Converter.byte2short(data);
}
public static void writeShort(int addr, int data, IMemory memory) { writeShort((short)addr, (short)data, memory); }
public static void writeShort(int addr, short data, IMemory memory) { writeShort((short)addr, data, memory); }
public static void writeShort(int addr, byte data, IMemory memory) { writeShort((short)addr, (short)data, memory); }
public static void writeShort(short addr, int data, IMemory memory) { writeShort(addr, (short)data, memory); }
public static void writeShort(int addr, int data, IMemory memory) { writeShort((short)addr, (short)data, memory); }
public static void writeShort(short addr, short data, IMemory memory) {
byte[] dt = Converter.short2byte(data);
memory.write(addr, dt[0]);
memory.write((short)(addr + 1), dt[1]);
}
public static void writeShort(short addr, byte data, IMemory memory) { writeShort(addr, (short)data, memory); }
}
......@@ -11,8 +11,8 @@ public class BasicMath implements IHandler {
@Override public short[] opcode(OpDirector opcode, short ref, short pc, short[] regs, short[] values, IMemory memory) {
short[] output = Arrays.copyOf(regs, regs.length);
short va = ValueHelper.readValue(0, ref, output, values, memory);
short vb = ValueHelper.readValue(1, ref, output, values, memory);
short va = ValueHelper.readShort(0, ref, output, values, memory);
short vb = ValueHelper.readShort(1, ref, output, values, memory);
switch (opcode) {
case ADD: output[0] = (short)(va + vb); break;
......@@ -25,8 +25,4 @@ public class BasicMath implements IHandler {
}
return output;
}
@Override public int getArgs(OpDirector opcode) {
return 2;
}
}
......@@ -8,5 +8,4 @@ import me.felinewith.kcpu.IMemory;
*/
public interface IHandler {
public abstract short[] opcode(OpDirector opcode, short ref, short pc, short[] regs, short[] values, IMemory memory);
public abstract int getArgs(OpDirector opcode);
}
......@@ -2,7 +2,6 @@ package me.felinewith.kcpu.opcodes;
import java.util.Arrays;
import me.felinewith.kcpu.IMemory;
import me.felinewith.kcpu.memory.MemHelper;
/**
*
......@@ -10,44 +9,20 @@ import me.felinewith.kcpu.memory.MemHelper;
*/
public class Memory implements IHandler {
@Override public short[] opcode(OpDirector opcode, short ref, short pc, short[] regs, short[] values, IMemory memory) {
short a = MemHelper.readShort(pc + 2, memory);
short b = MemHelper.readShort(pc + 4, memory);
short data;
short[] output = Arrays.copyOf(regs, regs.length);
switch (opcode) {
case MOV: // movrr
data = ValueHelper.readValue(0, ref, output, values, memory);
output = ValueHelper.writeValue(1, ref, output, values, memory, data);
case MOV: case MOVB:
data = ValueHelper.readByte(1, ref, output, values, memory);
output = ValueHelper.writeByte(0, ref, output, values, memory, data);
return output;
case MOVS:
data = ValueHelper.readShort(1, ref, output, values, memory);
output = ValueHelper.writeShort(0, ref, output, values, memory, data);
return output;
// case MOVRD: // movrd
// output[ra] = b;
// return output;
// case MOVRA: // movra
// output[ra] = MemHelper.readShort(b, memory);
// return output;
// case MOVDR: // movdr
// MemHelper.writeShort(a, output[rb], memory);
// return output;
// case MOVAR: // movar
// MemHelper.writeShort(MemHelper.readShort(a, memory), output[rb], memory);
// return output;
// case MOVAD: // movad
// MemHelper.writeShort(MemHelper.readShort(a, memory), b, memory);
// return output;
// case MOVAA: // movaa
// MemHelper.writeShort(MemHelper.readShort(a, memory), MemHelper.readShort(b, memory), memory);
// return output;
}
return output;
}
@Override public int getArgs(OpDirector opcode) {
switch (opcode) {
case MOV: // movrr
return 2;
}
return 0;
}
}
......@@ -15,7 +15,9 @@ public enum OpDirector {
DIV(0x0004, BasicMath.class),
// memory stuffies
MOV(0x0011, Memory.class),
MOV (0x0010, Memory.class),
MOVB(0x0010, Memory.class),
MOVS(0x0011, Memory.class),
// cpu stuffies
DEVA(0xff00, null), // get device port from address
......
package me.felinewith.kcpu.opcodes;
import java.util.Arrays;
import me.felinewith.kcpu.IMemory;
import me.felinewith.kcpu.memory.MemHelper;
/**
*
* @author jmahoney5
*/
public class ValueHelper {
public static short readValue(int pos, int ref, short[] regs, short[] values, IMemory memory) {
return readValue((short)pos, (short)ref, regs, values, memory);
}
//public static short readValue(int ref, short dval, int register, short[] regs, IMemory memory) {
// return readValue((short)ref, dval, (short)register, regs, memory);
//}
public static short readValue(short pos, short ref, short[] regs, short[] values, IMemory memory) {
short output = 0;
short reg = (short)(0x03 & values[pos]);
// 01: direct
// 02: register
// 03: direct address
// 04: register address
switch (ref) {
case 0x0001: case 0x0010: case 0x0100: case 0x1000:
output = values[pos]; break;
case 0x0002: case 0x0020: case 0x0200: case 0x2000:
output = regs[reg]; break;
case 0x0003: case 0x0030: case 0x0300: case 0x3000:
output = MemHelper.readShort(values[pos], memory); break;
case 0x0004: case 0x0040: case 0x0400: case 0x4000:
output = MemHelper.readShort(regs[reg], memory); break;
}
return output;
}
public static short[] writeValue(int pos, int ref, short[] regs, short[] values, IMemory memory, short data) {
return writeValue((short)pos, (short)ref, regs, values, memory, data);
}
public static short[] writeValue(short pos, short ref, short[] regs, short[] values, IMemory memory, short data) {
short[] output = Arrays.copyOf(regs, regs.length);
short reg = (short)(0x03 & values[pos]);
short cref = 0;
switch (pos) {
case 0: cref = (short)(0x000f & ref); break;
case 1: cref = (short)(0x00f0 & ref); break;
case 2: cref = (short)(0x0f00 & ref); break;
case 3: cref = (short)(0xf000 & ref); break;
}
switch (cref) {
case 0x0002: case 0x0020: case 0x0200: case 0x2000:
output[reg] = data; break;
case 0x0001: case 0x0010: case 0x0100: case 0x1000:
case 0x0003: case 0x0030: case 0x0300: case 0x3000:
MemHelper.writeShort(values[pos], data, memory); break;
case 0x0004: case 0x0040: case 0x0400: case 0x4000:
MemHelper.writeShort(output[reg], data, memory); break;
}
return output;
}
}
package me.felinewith.kcpu.opcodes;
import java.util.Arrays;
import me.felinewith.kcpu.IMemory;
import me.felinewith.kcpu.memory.MemHelper;
/**
*
* @author jmahoney5
*/
public class ValueHelper {
public static short readByte(int pos, int ref, short[] regs, short[] values, IMemory memory) {
return readByte((short)pos, (short)ref, regs, values, memory);
}
public static short readByte(short pos, short ref, short[] regs, short[] values, IMemory memory) {
short output = 0;
short reg = (short)(0x03 & values[pos]);
// 00: direct
// 01: register
// 02: direct address
// 03: register address
short cref = 0;
switch (pos) {
case 0: cref = (short)(0x000f & ref); break;
case 1: cref = (short)(0x00f0 & ref); break;
case 2: cref = (short)(0x0f00 & ref); break;
case 3: cref = (short)(0xf000 & ref); break;
}
switch (cref) {
case 0x0000: output = values[pos]; break;
case 0x0001: case 0x0010: case 0x0100: case 0x1000:
output = regs[reg]; break;
case 0x0002: case 0x0020: case 0x0200: case 0x2000:
output = MemHelper.readByte(values[pos], memory); break;
case 0x0003: case 0x0030: case 0x0300: case 0x3000:
output = MemHelper.readByte(regs[reg], memory); break;
}
return output;
}
public static short[] writeByte(int pos, int ref, short[] regs, short[] values, IMemory memory, short data) {
return writeByte((short)pos, (short)ref, regs, values, memory, (byte)(0xff & data));
}
public static short[] writeByte(short pos, short ref, short[] regs, short[] values, IMemory memory, short data) {
return writeByte(pos, ref, regs, values, memory, (byte)(0xff & data));
}
public static short[] writeByte(int pos, int ref, short[] regs, short[] values, IMemory memory, byte data) {
return writeByte((short)pos, (short)ref, regs, values, memory, data);
}
public static short[] writeByte(short pos, short ref, short[] regs, short[] values, IMemory memory, byte data) {
short[] output = Arrays.copyOf(regs, regs.length);
short reg = (short)(0x03 & values[pos]);
short cref = 0;
switch (pos) {
case 0: cref = (short)(0x000f & ref); break;
case 1: cref = (short)(0x00f0 & ref); break;
case 2: cref = (short)(0x0f00 & ref); break;
case 3: cref = (short)(0xf000 & ref); break;
}
switch (cref) {
case 0x0001: case 0x0010: case 0x0100: case 0x1000:
output[reg] = data; break;
case 0x0000:
case 0x0002: case 0x0020: case 0x0200: case 0x2000:
MemHelper.writeByte(values[pos], data, memory); break;
case 0x0003: case 0x0030: case 0x0300: case 0x3000:
MemHelper.writeByte(output[reg], data, memory); break;
}
return output;
}
public static short readShort(int pos, int ref, short[] regs, short[] values, IMemory memory) {
return readShort((short)pos, (short)ref, regs, values, memory);
}
public static short readShort(short pos, short ref, short[] regs, short[] values, IMemory memory) {
short output = 0;
short reg = (short)(0x03 & values[pos]);
// 00: direct
// 01: register
// 02: direct address
// 03: register address
short cref = 0;
switch (pos) {
case 0: cref = (short)(0x000f & ref); break;
case 1: cref = (short)(0x00f0 & ref); break;
case 2: cref = (short)(0x0f00 & ref); break;
case 3: cref = (short)(0xf000 & ref); break;
}
switch (cref) {
case 0x0000: output = values[pos]; break;
case 0x0001: case 0x0010: case 0x0100: case 0x1000:
output = regs[reg]; break;
case 0x0002: case 0x0020: case 0x0200: case 0x2000:
output = MemHelper.readShort(values[pos], memory); break;
case 0x0003: case 0x0030: case 0x0300: case 0x3000:
output = MemHelper.readShort(regs[reg], memory); break;
}
return output;
}
public static short[] writeShort(int pos, int ref, short[] regs, short[] values, IMemory memory, short data) {
return writeShort((short)pos, (short)ref, regs, values, memory, data);
}
public static short[] writeShort(short pos, short ref, short[] regs, short[] values, IMemory memory, short data) {
short[] output = Arrays.copyOf(regs, regs.length);
short reg = (short)(0x03 & values[pos]);
short cref = 0;
switch (pos) {
case 0: cref = (short)(0x000f & ref); break;
case 1: cref = (short)(0x00f0 & ref); break;
case 2: cref = (short)(0x0f00 & ref); break;
case 3: cref = (short)(0xf000 & ref); break;
}
switch (cref) {
case 0x0001: case 0x0010: case 0x0100: case 0x1000:
output[reg] = data; break;
case 0x0000:
case 0x0002: case 0x0020: case 0x0200: case 0x2000:
MemHelper.writeShort(values[pos], data, memory); break;
case 0x0003: case 0x0030: case 0x0300: case 0x3000:
MemHelper.writeShort(output[reg], data, memory); break;
}
return output;
}
}
......@@ -25,6 +25,8 @@ public abstract class BaseDevice extends BaseMemory implements IDevice {
sendIrq(memory[addr]);
}
@Override public void sendIrq(byte irq) { }
@Override public short length() { return (short)memory.length; }
}
......@@ -33,4 +33,6 @@ public abstract class BaseMemory implements IMemory {
}
@Override public void memIrq(short addr) { }
@Override public void powerOff() { }
}
movs r0 0
movs r1 0
movs r2 0
movs r3 0
mov ff00,16 61,16
irqm ff01,16
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!