Commit 8aa59d72 by Jessica Hawkwell

got some opcodes

1 parent 486876bc
Pipeline #203 passed
in 1 minute 4 seconds
......@@ -34,13 +34,13 @@ public class Converter {
}
private static byte[] byteShifterDown(int input, int length) {
int a = 0;
int a;
byte[] temp = new byte[length];
int shift = 0;
int shift;
int mask = 0xff;
for (a = 0; a < length; a++) {
shift = a * 8;
mask = mask << shift;
mask <<= shift;
temp[a] = (byte)((mask & input) >> shift);
}
return temp;
......@@ -54,4 +54,6 @@ public class Converter {
}
return output;
}
private Converter() {}
}
......@@ -6,13 +6,7 @@ package me.felinewith.kcpu;
*/
public interface IDevice extends IMemory {
public void init(IMemory board);
public short getInterrupt();
public void setInterrupt(short irq);
public short getSetting(short setting);
public void setSetting(short setting, short value);
public byte[] getName();
public abstract void sendIrq(byte irq);
public void exec();
}
......@@ -6,7 +6,8 @@ package me.felinewith.kcpu;
*/
public interface IMemory {
public abstract short length();
public abstract byte[] read(short offset, short length);
public abstract void write(short offset, byte[] data);
public void copy(short offsetSrc, short offsetDest, short length, IMemory dest);
public abstract byte read(short addr);
public abstract void write(short addr, byte data);
public void copy(short addrSrc, short addrDest, IMemory dest);
public abstract void memIrq(short addr);
}
package me.felinewith.kcpu;
import java.util.Arrays;
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 java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import me.felinewith.kcpu.hardware.BootRom;
import me.felinewith.kcpu.hardware.Kfpu;
import me.felinewith.kcpu.memory.KMemoryRange;
import me.felinewith.kcpu.util.BaseMemory;
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.HardwareTask;
import me.felinewith.kcpu.util.IDeviceRunner;
/**
*
* @author jlhawkwell
*/
public class KBoard extends BaseMemory implements IMemory {
public class KBoard extends BaseDevice implements IMemory {
ThreadPoolExecutor tpe;
TimerTask tt;
Timer t;
byte[] memory;
private final ThreadPoolExecutor tpe;
private TimerTask tt;
private Timer t;
IDevice[] devices;
KMemoryRange[] deviceMaps;
private final IDevice[] devices;
private final KMemoryRange[] deviceMaps;
private final IMemory[] memDevs;
private final 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;
public KBoard() {
tpe = new ThreadPoolExecutor(16, 32, 30, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(16));
memory = new byte[0xffff];
tpe = new ThreadPoolExecutor(16, 32, 30, TimeUnit.SECONDS, new LinkedBlockingQueue<>(16));
memory = new byte[0x010000];
devices = new IDevice[16];
deviceMaps = new KMemoryRange[16];
memDevs = new IMemory[16];
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));
attachDevice(1, 0x8800, new Kfpu());
attachDevice(2, 0x1000, new BootRom());
attachDevice(1, 0x8800, new Kmcp());
attachMemory(0, 0xff00, new Buffer());
attachMemory(1, 0x1000, new BootRom());
tt = new HardwareTask(devices[0]);
t = new Timer("CPU Cycler");
t.schedule(tt, 0, 1);
}
@Override public void memIrq(short addr) {
short dev = checkDevice(addr);
short rdev = (short)(0x0f & dev);
if ( dev == 0x7f ) { devices[0].memIrq(addr); }
else if ( dev <= 0x0f ) {
short devOff = deviceMaps[rdev].getOffset();
short devAddr = (short)(addr - devOff);
devices[rdev].memIrq(devAddr);
}
else if ( 0x10 <= dev && dev <= 0x1f ) {
short devOff = memDevMaps[rdev].getOffset();
short devAddr = (short)(addr - devOff);
memDevs[rdev].memIrq(devAddr);
}
}
@Override public void sendIrq(byte irq) {
if ( irq >= 16 ) { return; }
if ( devices[irq] != null ) { devices[irq].exec(); }
}
@Override public short length() { return (short)memory.length; };
@Override public byte[] read(short offset, short length) {
short dev = checkDevice(offset, length);
if ( dev == 0x7f ) { return Arrays.copyOfRange(memory, offset, offset + length); }
else {
short devOff = (short)(offset - deviceMaps[dev].getOffset());
return devices[dev].read(devOff, length);
@Override public byte read(short addr) {
short dev = checkDevice(addr);
short rdev = (short)(0x0f & dev);
if ( dev <= 0x0f ) {
short devOff = deviceMaps[rdev].getOffset();
short devAddr = (short)(addr - devOff);
return devices[rdev].read(devAddr);
}
else if ( 0x10 <= dev && dev <= 0x1f ) {
short devOff = memDevMaps[rdev].getOffset();
short devAddr = (short)(addr - devOff);
return memDevs[rdev].read(devAddr);
}
return memory[addr];
}
@Override public void write(short offset, byte[] data) {
IDeviceRunner idr;
short dev = checkDevice(offset, (short)data.length);
if ( dev == 0x7f ) {
short len = (short)data.length;
short a;
short addr;
for (a = 0; a < len; a++) {
addr = (short)(offset + a);
memory[addr] = data[a];
}
idr = new IDeviceRunner(devices[0]);
@Override public void write(short addr, byte data) {
short dev = checkDevice(addr);
short rdev = (short)(0x0f & dev);
if ( dev <= 0x0f ) {
short devOff = deviceMaps[rdev].getOffset();
short devAddr = (short)(addr - devOff);
devices[rdev].write(devAddr, data);
}
else {
short devOff = (short)(offset - deviceMaps[dev].getOffset());
devices[dev].write(devOff, data);
idr = new IDeviceRunner(devices[dev]);
else if ( 0x10 <= dev && dev <= 0x1f ) {
short devOff = memDevMaps[rdev].getOffset();
short devAddr = (short)(addr - devOff);
memDevs[rdev].write(devAddr, data);
}
tpe.execute(idr);
memory[addr] = data;
}
private void attachDevice(int port, int offset, IDevice device) {
......@@ -85,10 +141,22 @@ public class KBoard extends BaseMemory implements IMemory {
devices[port] = device;
deviceMaps[port] = new KMemoryRange(offset, device.length());
device.init(this);
}
private short checkDevice(short offset, short length) {
private void attachMemory(int port, int offset, IMemory device) {
attachMemory(port, (short)offset, device); }
private void attachMemory(int port, short offset, IMemory device) {
if ( memDevs[port] != null ) { return; }
else if ( memDevMaps[port] != null ) { return; }
memDevs[port] = device;
memDevMaps[port] = new KMemoryRange(offset, device.length());
}
private short checkDevice(short addr) {
short a;
short top = (short)(offset + length);
KMemoryRange io;
short devOff;
......@@ -100,12 +168,38 @@ public class KBoard extends BaseMemory implements IMemory {
devOff = io.getOffset();
devTop = (short)(devOff + io.getLength());
if ( devOff <= offset && offset <= devTop ) { return a; }
else if ( devOff <= top && top <= devTop ) { return a; }
if ( devOff <= addr && addr <= devTop ) { return a; } // range is entirely in device
}
}
for (a = 0; a < 16; a++) {
if ( memDevMaps[a] != null ) {
io = memDevMaps[a];
devOff = io.getOffset();
devTop = (short)(devOff + io.getLength());
if ( devOff <= addr && addr <= devTop ) { return (short)(0x10 + a); } // range is entirely in device
}
}
return 0x7f;
}
@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]);
}
}
}
catch (IOException e) {}
}
}
package me.felinewith.kcpu.memory;
package me.felinewith.kcpu;
import me.felinewith.kcpu.KMemoryRange;
/**
*
......
package me.felinewith.kcpu;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.TimerTask;
import me.felinewith.kcpu.memory.MemHelper;
import me.felinewith.kcpu.opcodes.OpDirector;
import me.felinewith.kcpu.opcodes.ValueType;
/**
*
......@@ -10,38 +11,26 @@ import java.util.TimerTask;
*/
public class Kcpu extends TimerTask implements IDevice {
byte[] memory;
String name;
short[] settings;
private byte[] memory;
private String name;
private short[] settings;
KBoard board;
short pc;
short[] registers;
private KBoard board;
public Kcpu(KBoard system) {
memory = new byte[0x0800];
name = "Kcpu";
settings = new short[4];
settings = new short[6];
board = system;
}
@Override public void init(IMemory system) { }
@Override public short getInterrupt() { return 0; }
@Override public void setInterrupt(short irq) { }
@Override public short getSetting(short setting) {
int addr = 0x07f0 + setting;
if (addr > 0x07ff) { return 0x7fff; }
return memory[addr];
}
@Override public void setSetting(short setting, short value) {
int addr = 0x07f0 + setting;
if (addr > 0x07ff) { return; }
memory[addr] = (byte)(0xff & value);
pc = 0x1000;
registers = new short[4];
}
@Override public byte[] getName() { return "Kcpu".getBytes(Charset.forName("UTF-8"));}
@Override public void init(IMemory system) { }
// use this one during interrupts
@Override public void exec() {
......@@ -49,16 +38,106 @@ public class Kcpu extends TimerTask implements IDevice {
@Override public short length() { return 0x07ff; }
@Override public byte[] read(short offset, short length) {
return Arrays.copyOfRange(memory, offset, offset + length);
@Override public byte read(short addr) {
if ( (0xffff & addr) > length() ) { return (byte)0xff; }
return memory[addr];
}
@Override public void write(short offset, byte[] data) { }
@Override public void copy(short offsetSrc, short offsetDest, short length, IMemory dest) { }
@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() {
@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() {
short inst = MemHelper.readShort(pc, board);
OpDirector od = null;
for (OpDirector o : OpDirector.values()) {
if (o.getOpcode() == inst) {
od = o;
break;
}
}
if ( od == null ) { pc += 2; return; }
if ( od.hasHandler() ) {
registers = od.call(pc, registers, board);
ValueType[] vt = od.getArgs();
if ( vt == null ) { pc += 2; }
else if ( vt[0] == ValueType.NONE ) { pc += 2; }
else { pc += (2 * vt.length); }
return;
}
pc += 2; // increment the program counter
switch (od) {
case IRQD_A:
case IRQD_D:
case IRQD_R:
case IRQM_A:
case IRQM_D:
case IRQM_R:
case JMPA_A:
case JMPA_D:
case JMPA_R:
case JMPD_A:
case JMPD_D:
case JMPD_R:
case JMP_A:
case JMP_D:
case JMP_R:
pc += 2;
break;
}
short a = MemHelper.readShort(pc + 2, board);
short b = MemHelper.readShort(pc + 4, board);
short c = MemHelper.readShort(pc + 6, board);
short d = MemHelper.readShort(pc + 8, board);
short ra = (short)(0x03 & a);
short rb = (short)(0x03 & b);
short rc = (short)(0x03 & c);
short rd = (short)(0x03 & d);
switch (od) {
// interrupt to port
case IRQD : board.sendIrq((byte)registers[0]); return;
case IRQD_A: board.sendIrq((byte)MemHelper.readShort(a, board)); return;
case IRQD_D: board.sendIrq((byte)a); return;
case IRQD_R: board.sendIrq((byte)registers[ra]); return;
// interrupt to memory address
case IRQM : board.memIrq(registers[0]); return;
case IRQM_A: board.memIrq(a); return;
case IRQM_D: board.memIrq(MemHelper.readShort(a, board)); return;
case IRQM_R: board.memIrq(registers[ra]); return;
// jump absolute
case JMPA : pc = registers[0]; return;
case JMPA_A: pc = MemHelper.readShort(a, board); return;
case JMPA_D: pc = a; return;
case JMPA_R: pc = registers[ra]; return;
// jump down
case JMPD : pc -= registers[0]; return;
case JMPD_A: pc -= MemHelper.readShort(a, board); return;
case JMPD_D: pc -= a; return;
case JMPD_R: pc -= registers[ra]; return;
// jump up
case JMP : pc += registers[0]; return;
case JMP_A: pc += MemHelper.readShort(a, board); return;
case JMP_D: pc += a; return;
case JMP_R: pc += registers[ra]; return;
}
}
}
......@@ -7,12 +7,11 @@ import me.felinewith.kcpu.util.BaseDevice;
*
* @author jlhawkwell
*/
public class Kfpu extends BaseDevice {
public class Kmcp extends BaseDevice {
public Kfpu() {
memory = new byte[0x010];
name = "Kfpu";
settings = new short[2];
public Kmcp() {
memory = new byte[0x20];
name = "Kmcp";
}
@Override public void exec() {
......@@ -28,13 +27,25 @@ public class Kfpu extends BaseDevice {
reg[a] = readReg(setting, a);
}
a = (short)(0xff & settings[setting]);
temp = doTheWork(a, reg[0], reg[1]);
short starts;
switch (setting) {
case 0: starts = 0x10; break;
case 1: starts = 0x12; break;
default: starts = 0; break;
}
byte[] data = {
read(starts),
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];
a = (short)((0xff00 & setting) >> 8);
temp = doTheWork(a, reg[2], reg[3]);
a = (short)((0xff00 & opcode) >> 8);
temp = do2reg(a, reg[2], reg[3]);
reg[2] = temp[0];
reg[3] = temp[1];
......@@ -42,12 +53,13 @@ public class Kfpu extends BaseDevice {
writeReg(setting, a, reg[a]);
}
}
private short[] doTheWork(short setting, short reg0, short reg1) {
private short[] do2reg(short opcode, short reg0, short reg1) {
short[] out = new short[2];
out[0] = reg0;
out[1] = reg1;
switch (setting) {
switch (opcode) {
case 0x10: // add
out[0] = (short)(reg0 + reg1);
break;
......@@ -71,7 +83,12 @@ public class Kfpu extends BaseDevice {
if (setting == 1) { addr += 0x8; }
addr += (reg * 2);
return Converter.byte2short(read(addr, (short)2));
byte[] data = {
read(addr),
read(addr + 1)
};
return Converter.byte2short(data);
}
private void writeReg(short setting, short reg, short data) {
......@@ -79,6 +96,16 @@ public class Kfpu extends BaseDevice {
if (setting == 1) { addr += 0x8; }
addr += (reg * 2);
write(addr, Converter.short2byte(data));
byte[] bytes = Converter.short2byte(data);
int a;
for (a = 0; a < bytes.length; a++) {
write(addr + a, bytes[a]);
}
}
@Override public void memIrq(short addr) {
if ( 0 <= addr && addr <= memory.length ) { exec(); }
}
@Override public void sendIrq(byte irq) { }
}
package me.felinewith.kcpu.hardware;
package me.felinewith.kcpu.memory;
import java.util.Arrays;
import me.felinewith.kcpu.util.BaseDevice;
import me.felinewith.kcpu.util.BaseMemory;
/**
*
* @author jlhawkwell
*/
public class BootRom extends BaseDevice {
public class BootRom extends BaseMemory {
public BootRom() {
memory = new byte[0x0fff];
Arrays.fill(memory, (byte)0x75);
settings = new short[0];
name = "BootRom";
}
@Override public void write(short offset, byte[] data) { }
@Override public void exec() { }
@Override public void write(short offset, byte data) { }
}
package me.felinewith.kcpu.memory;
import me.felinewith.kcpu.util.BaseMemory;
/**
*
* @author jlhawkwell
*/
public class Buffer extends BaseMemory {
public Buffer() {
memory = new byte[32];
}
}
package me.felinewith.kcpu.memory;
import me.felinewith.kcpu.Converter;
import me.felinewith.kcpu.IMemory;
/**
*
* @author jlhawkwell
*/
public class MemHelper {
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];
data[0] = memory.read(addr);
data[1] = memory.read((short)(addr + 1));
return Converter.byte2short(data);
}
public static void writeShort(int addr, short data, IMemory memory) { writeShort((short)addr, 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]);
}
}
package me.felinewith.kcpu.opcodes;
import java.util.Arrays;
import me.felinewith.kcpu.IMemory;
/**
*
* @author jlhawkwell
*/
public class BasicMath implements IHandler {
@Override public short[] opcode(OpDirector opcode, short pc, short[] regs, IMemory memory) {
short[] output = Arrays.copyOf(regs, regs.length);
switch (opcode) {
case ADD: output[0] += output[1]; break;
case DIV:
short rem = (short)(output[0] % output[1]);
output[0] /= output[1];
output[1] = rem;
break;
case MUL: output[0] *= output[1]; break;
case SUB: output[0] -= output[1]; break;
}
return output;
}
@Override public ValueType[] getArgs(OpDirector opcode) {
return new ValueType[]{ValueType.NONE};
}
}
package me.felinewith.kcpu.opcodes;
import me.felinewith.kcpu.IMemory;
/**
*
* @author jlhawkwell
*/
public interface IHandler {
public abstract short[] opcode(OpDirector opcode, short pc, short[] regs, IMemory memory);
public abstract ValueType[] getArgs(OpDirector opcode);
}
package me.felinewith.kcpu.opcodes;
import java.util.Arrays;
import me.felinewith.kcpu.IMemory;
import me.felinewith.kcpu.memory.MemHelper;
/**
*
* @author jlhawkwell
*/
public class Memory implements IHandler {
@Override public short[] opcode(OpDirector opcode, short pc, short[] regs, IMemory memory) {
short a = MemHelper.readShort(pc + 2, memory);
short b = MemHelper.readShort(pc + 4, memory);
short ra = (short)(0x03 & a);
short rb = (short)(0x03 & b);
short[] output = Arrays.copyOf(regs, regs.length);
switch (opcode) {
case MOVRR: // movrr
output[ra] = output[rb];
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 ValueType[] getArgs(OpDirector opcode) {
ValueType[] output = new ValueType[2];
output[0] = ValueType.NONE;
output[1] = ValueType.NONE;
switch (opcode) {
case MOVRR: // movrr
output[0] = ValueType.REGISTER;
output[1] = ValueType.REGISTER;
return output;
case MOVRD: // movrd
output[0] = ValueType.REGISTER;
output[1] = ValueType.DATA;
return output;
case MOVRA: // movra
output[0] = ValueType.REGISTER;
output[1] = ValueType.ADDRESS;
return output;
case MOVDR: // movdr
output[0] = ValueType.DATA;
output[1] = ValueType.REGISTER;
return output;
case MOVAR: // movar
output[0] = ValueType.ADDRESS;
output[1] = ValueType.REGISTER;
return output;
case MOVAD: // movad
output[0] = ValueType.ADDRESS;
output[1] = ValueType.DATA;
return output;
case MOVAA: // movaa
output[0] = ValueType.ADDRESS;
output[1] = ValueType.ADDRESS;
return output;
}
return output;
}
}
package me.felinewith.kcpu.opcodes;
import me.felinewith.kcpu.IMemory;
/**
*
* @author jlhawkwell
*/
public enum OpDirector {
// basic math stuffies
ADD(0x0001, BasicMath.class),
SUB(0x0002, BasicMath.class),
MUL(0x0003, BasicMath.class),
DIV(0x0004, BasicMath.class),
// memory stuffies
MOVRR(0x0011, Memory.class),
MOVRD(0x0012, Memory.class),
MOVRA(0x0013, Memory.class),
MOVDR(0x0014, Memory.class),
MOVAR(0x0015, Memory.class),
MOVAD(0x0016, Memory.class),
MOVAA(0x0017, Memory.class),
// cpu stuffies
IRQM (0x8f00, null),
IRQM_R(0x8f01, null),
IRQM_D(0x8f02, null),
IRQM_A(0x8f03, null),
IRQD (0x8f10, null),
IRQD_R(0x8f11, null),
IRQD_D(0x8f12, null),
IRQD_A(0x8f13, null),
JMPA (0x8f0c, null),
JMPA_R(0x8f0d, null),
JMPA_D(0x8f1c, null),
JMPA_A(0x8f1d, null),
JMPD (0x8f18, null),
JMPD_R(0x8f19, null),
JMPD_D(0x8f1a, null),
JMPD_A(0x8f1b, null),
JMP (0x8f08, null),
JMP_R(0x8f09, null),
JMP_D(0x8f0a, null),
JMP_A(0x8f0b, null),
;
short o;
Class<? extends IHandler> c;
private OpDirector(short opcode, Class<? extends IHandler> cls) {
o = opcode;
c = cls;
}
private OpDirector(int opcode, Class<? extends IHandler> cls) {
o = (short)(0xffff & opcode);
c = cls;
}
public short getOpcode() { return o; }
public boolean hasHandler() { return (c != null); }
public short[] call(short pc, short[] regs, IMemory memory) {
try {
if (c == null) { return regs; }
IHandler ih = c.newInstance();
return ih.opcode(this, pc, regs, memory);
}
catch (IllegalAccessException | InstantiationException e) {}
return regs;
}
public ValueType[] getArgs() {
try {
if (c == null) { return null; }
IHandler ih = c.newInstance();
return ih.getArgs(this);
}
catch (IllegalAccessException | InstantiationException e) {}
return null;
}
}
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 java.nio.charset.Charset;
import me.felinewith.kcpu.IDevice;
import me.felinewith.kcpu.IMemory;
......@@ -11,32 +10,21 @@ import me.felinewith.kcpu.IMemory;
public abstract class BaseDevice extends BaseMemory implements IDevice {
protected String name;
protected short[] settings;
protected IMemory board;
@Override public void init(IMemory system) {
board = system;
}
@Override public short getInterrupt() { return settings[0]; }
@Override public void setInterrupt(short irq) { settings[0] = irq;}
@Override public short getSetting(short setting) {
if ( setting > settings.length ) { return 0x7fff; }
return settings[setting];
@Override public void memIrq(short addr) {
if ( 0 <= addr && addr <= memory.length ) { exec(); }
}
@Override public void setSetting(short setting, short value) {
if ( setting > settings.length ) { return; }
else if ( setting == 0 ) { return; }
settings[setting] = value;
protected void sendIrq() {
int addr = memory.length - 1;
sendIrq(memory[addr]);
}
@Override public byte[] getName() { return name.getBytes(Charset.forName("UTF-8")); }
@Override public short length() {
return (short)memory.length;
}
@Override public short length() { return (short)memory.length; }
}
package me.felinewith.kcpu.util;
import java.util.Arrays;
import me.felinewith.kcpu.IMemory;
/**
......@@ -11,24 +10,27 @@ public abstract class BaseMemory implements IMemory {
protected byte[] memory;
@Override public byte[] read(short offset, short length) {
return Arrays.copyOfRange(memory, offset, offset + length);
@Override public short length() {
return (short)memory.length;
}
@Override public void write(short offset, byte[] data) {
short len = (short)data.length;
short a;
short addr;
public final byte read(int addr) { return read((short)addr); }
@Override public byte read(short addr) {
if ( (0xffff & addr) > length() ) { return (byte)0xff; }
return memory[addr];
}
for (a = 0; a < len; a++) {
addr = (short)(offset + a);
memory[addr] = data[a];
}
public final void write(int addr, byte data) { write((short)addr, data); }
@Override public void write(short addr, byte data) {
if ( (0xffff & addr) > length() ) { return; }
memory[addr] = data;
}
@Override public void copy(short offsetSrc, short offsetDest, short length, IMemory dest) {
byte[] data = read(offsetSrc, length);
dest.write(offsetDest, data);
public final void copy(int addrSrc, int addrDest, IMemory dest) { copy((short)addrSrc, (short)addrDest, dest); }
@Override public void copy(short addrSrc, short addrDest, IMemory dest) {
if ( (0xffff & addrSrc) > length() ) { return; }
dest.write(addrDest, read(addrSrc));
}
@Override public void memIrq(short addr) { }
}
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!