Commit 0ce4a166 by Jessica Hawkwell

Added a reference position, all variations now possible

1 parent d5f32759
Pipeline #205 passed
in 1 minute 3 seconds
...@@ -3,7 +3,7 @@ package me.felinewith.kcpu; ...@@ -3,7 +3,7 @@ package me.felinewith.kcpu;
import java.util.TimerTask; import java.util.TimerTask;
import me.felinewith.kcpu.memory.MemHelper; import me.felinewith.kcpu.memory.MemHelper;
import me.felinewith.kcpu.opcodes.OpDirector; import me.felinewith.kcpu.opcodes.OpDirector;
import me.felinewith.kcpu.opcodes.ValueType; import me.felinewith.kcpu.opcodes.ValueHelper;
/** /**
* *
...@@ -57,6 +57,13 @@ public class Kcpu extends TimerTask implements IDevice { ...@@ -57,6 +57,13 @@ public class Kcpu extends TimerTask implements IDevice {
private void workCycle() { private void workCycle() {
short inst = MemHelper.readShort(pc, board); short inst = MemHelper.readShort(pc, board);
short ref = MemHelper.readShort(pc + 2, board);
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);
OpDirector od = null; OpDirector od = null;
for (OpDirector o : OpDirector.values()) { for (OpDirector o : OpDirector.values()) {
if (o.getOpcode() == inst) { if (o.getOpcode() == inst) {
...@@ -65,85 +72,45 @@ public class Kcpu extends TimerTask implements IDevice { ...@@ -65,85 +72,45 @@ public class Kcpu extends TimerTask implements IDevice {
} }
} }
if ( od == null ) { pc += 2; return; } if ( od == null ) { pc += 2; return; } // inc 2 if nop
if ( od.hasHandler() ) { if ( od.hasHandler() ) {
registers = od.call(pc, registers, board); registers = od.call(pc, ref, registers, values, board);
ValueType[] vt = od.getArgs(); int vt = od.getArgs();
if ( vt == null ) { pc += 2; } pc += 2;
else if ( vt[0] == ValueType.NONE ) { pc += 2; } if ( vt != 0 ) { pc += 2 + (vt * 2); }
else { pc += (2 * vt.length); }
return; 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 data;
short rb = (short)(0x03 & b); data = ValueHelper.readValue(0, ref, registers, values, board);
short rc = (short)(0x03 & c);
short rd = (short)(0x03 & d);
switch (od) { switch (od) {
// ask what device is using which address // ask what device is using which address
case ASK : registers[0] = board.checkDevice((short)0); case ASK:
case ASK: registers[0] = board.checkDevice((short)0); data = board.checkDevice((short)(0x000f & data));
case ASK: registers[0] = board.checkDevice((short)0); registers = ValueHelper.writeValue(1, ref, registers, values, board, data);
case ASK: registers[0] = board.checkDevice((short)0); return;
// interrupt to port // interrupt to port
case IRQD : board.sendIrq((byte)registers[0]); return; case IRQD:
case IRQD_A: board.sendIrq((byte)MemHelper.readShort(a, board)); return; board.sendIrq((byte)(0x000f & data));
case IRQD_D: board.sendIrq((byte)a); return; return;
case IRQD_R: board.sendIrq((byte)registers[ra]); return;
// interrupt to memory address // interrupt to memory address
case IRQM : board.memIrq(registers[0]); return; case IRQM:
case IRQM_A: board.memIrq(a); return; board.memIrq(data);
case IRQM_D: board.memIrq(MemHelper.readShort(a, board)); return; return;
case IRQM_R: board.memIrq(registers[ra]); return;
// jump absolute // jump absolute
case JMPA : pc = registers[0]; return; case JMPA: pc = data; 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 // jump down
case JMPD : pc -= registers[0]; return; case JMPD: pc = (short)(pc - (0xffff & data)); 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 // jump up
case JMP : pc += registers[0]; return; case JMP: pc = (short)(pc + (0xffff & data)); return;
case JMP_A: pc += MemHelper.readShort(a, board); return;
case JMP_D: pc += a; return;
case JMP_R: pc += registers[ra]; return;
} }
} }
} }
...@@ -9,24 +9,27 @@ import me.felinewith.kcpu.IMemory; ...@@ -9,24 +9,27 @@ import me.felinewith.kcpu.IMemory;
*/ */
public class BasicMath implements IHandler { public class BasicMath implements IHandler {
@Override public short[] opcode(OpDirector opcode, short pc, short[] regs, IMemory memory) { @Override public short[] opcode(OpDirector opcode, short ref, short pc, short[] regs, short[] values, IMemory memory) {
short[] output = Arrays.copyOf(regs, regs.length); 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);
switch (opcode) { switch (opcode) {
case ADD: output[0] += output[1]; break; case ADD: va += vb; break;
case DIV: case DIV:
short rem = (short)(output[0] % output[1]); short rem = (short)(va % vb);
output[0] /= output[1]; va /= vb;
output[1] = rem; vb = rem;
break; break;
case MUL: output[0] *= output[1]; break; case MUL: va *= vb; break;
case SUB: output[0] -= output[1]; break; case SUB: va -= vb; break;
} }
output = ValueHelper.writeValue(0, ref, output, values, memory, va);
output = ValueHelper.writeValue(1, ref, output, values, memory, vb);
return output; return output;
} }
@Override public ValueType[] getArgs(OpDirector opcode) { @Override public int getArgs(OpDirector opcode) {
return new ValueType[]{ValueType.NONE}; return 2;
} }
} }
...@@ -7,6 +7,6 @@ import me.felinewith.kcpu.IMemory; ...@@ -7,6 +7,6 @@ import me.felinewith.kcpu.IMemory;
* @author jlhawkwell * @author jlhawkwell
*/ */
public interface IHandler { public interface IHandler {
public abstract short[] opcode(OpDirector opcode, short pc, short[] regs, IMemory memory); public abstract short[] opcode(OpDirector opcode, short ref, short pc, short[] regs, short[] values, IMemory memory);
public abstract ValueType[] getArgs(OpDirector opcode); public abstract int getArgs(OpDirector opcode);
} }
...@@ -9,75 +9,45 @@ import me.felinewith.kcpu.memory.MemHelper; ...@@ -9,75 +9,45 @@ import me.felinewith.kcpu.memory.MemHelper;
* @author jlhawkwell * @author jlhawkwell
*/ */
public class Memory implements IHandler { public class Memory implements IHandler {
@Override public short[] opcode(OpDirector opcode, short pc, short[] regs, IMemory memory) { @Override public short[] opcode(OpDirector opcode, short ref, short pc, short[] regs, short[] values, IMemory memory) {
short a = MemHelper.readShort(pc + 2, memory); short a = MemHelper.readShort(pc + 2, memory);
short b = MemHelper.readShort(pc + 4, memory); short b = MemHelper.readShort(pc + 4, memory);
short ra = (short)(0x03 & a); short data;
short rb = (short)(0x03 & b);
short[] output = Arrays.copyOf(regs, regs.length); short[] output = Arrays.copyOf(regs, regs.length);
switch (opcode) { switch (opcode) {
case MOVRR: // movrr case MOV: // movrr
output[ra] = output[rb]; data = ValueHelper.readValue(0, ref, output, values, memory);
return output; output = ValueHelper.writeValue(1, ref, output, values, memory, data);
case MOVRD: // movrd return output;
output[ra] = b; // case MOVRD: // movrd
return output; // output[ra] = b;
case MOVRA: // movra // return output;
output[ra] = MemHelper.readShort(b, memory); // case MOVRA: // movra
return output; // output[ra] = MemHelper.readShort(b, memory);
case MOVDR: // movdr // return output;
MemHelper.writeShort(a, output[rb], memory); // case MOVDR: // movdr
return output; // MemHelper.writeShort(a, output[rb], memory);
case MOVAR: // movar // return output;
MemHelper.writeShort(MemHelper.readShort(a, memory), output[rb], memory); // case MOVAR: // movar
return output; // MemHelper.writeShort(MemHelper.readShort(a, memory), output[rb], memory);
case MOVAD: // movad // return output;
MemHelper.writeShort(MemHelper.readShort(a, memory), b, memory); // case MOVAD: // movad
return output; // MemHelper.writeShort(MemHelper.readShort(a, memory), b, memory);
case MOVAA: // movaa // return output;
MemHelper.writeShort(MemHelper.readShort(a, memory), MemHelper.readShort(b, memory), memory); // case MOVAA: // movaa
return output; // MemHelper.writeShort(MemHelper.readShort(a, memory), MemHelper.readShort(b, memory), memory);
// return output;
} }
return output; return output;
} }
@Override public ValueType[] getArgs(OpDirector opcode) { @Override public int getArgs(OpDirector opcode) {
ValueType[] output = new ValueType[2];
output[0] = ValueType.NONE;
output[1] = ValueType.NONE;
switch (opcode) { switch (opcode) {
case MOVRR: // movrr case MOV: // movrr
output[0] = ValueType.REGISTER; return 2;
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; return 0;
} }
} }
...@@ -15,59 +15,18 @@ public enum OpDirector { ...@@ -15,59 +15,18 @@ public enum OpDirector {
DIV(0x0004, BasicMath.class), DIV(0x0004, BasicMath.class),
// memory stuffies // memory stuffies
MOVRR(0x0011, Memory.class), MOV(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 // cpu stuffies
ASK_AA(0x1000, null), ASK(0x1000, null),
ASK_AD(0x1001, null),
ASK_AN(0x1002, null),
ASK_AR(0x1003, null),
ASK_DA(0x1004, null),
ASK_DD(0x1005, null),
ASK_DN(0x1006, null),
ASK_DR(0x1007, null),
ASK_NA(0x1010, null),
ASK_ND(0x1011, null),
ASK_NN(0x1012, null),
ASK_NR(0x1013, null),
ASK_RA(0x1014, null),
ASK_RD(0x1015, null),
ASK_RN(0x1016, null),
ASK_RR(0x1017, null),
IRQM (0x8f00, null), IRQM (0x8f00, null),
IRQM_R(0x8f01, null),
IRQM_D(0x8f02, null),
IRQM_A(0x8f03, null),
IRQD (0x8f10, null), IRQD (0x8f10, null),
IRQD_R(0x8f11, null),
IRQD_D(0x8f12, null),
IRQD_A(0x8f13, null),
JMP (0x8f08, null),
JMPA (0x8f0c, null), JMPA (0x8f0c, null),
JMPA_R(0x8f0d, null),
JMPA_D(0x8f1c, null),
JMPA_A(0x8f1d, null),
JMPD (0x8f18, 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; short o;
...@@ -83,23 +42,23 @@ public enum OpDirector { ...@@ -83,23 +42,23 @@ public enum OpDirector {
public short getOpcode() { return o; } public short getOpcode() { return o; }
public boolean hasHandler() { return (c != null); } public boolean hasHandler() { return (c != null); }
public short[] call(short pc, short[] regs, IMemory memory) { public short[] call(short ref, short pc, short[] regs, short[] values, IMemory memory) {
try { try {
if (c == null) { return regs; } if (c == null) { return regs; }
IHandler ih = c.newInstance(); IHandler ih = c.newInstance();
return ih.opcode(this, pc, regs, memory); return ih.opcode(this, ref, pc, regs, values, memory);
} }
catch (IllegalAccessException | InstantiationException e) {} catch (IllegalAccessException | InstantiationException e) {}
return regs; return regs;
} }
public ValueType[] getArgs() { public int getArgs() {
try { try {
if (c == null) { return null; } if (c == null) { return 0; }
IHandler ih = c.newInstance(); IHandler ih = c.newInstance();
return ih.getArgs(this); return ih.getArgs(this);
} }
catch (IllegalAccessException | InstantiationException e) {} catch (IllegalAccessException | InstantiationException e) {}
return null; return 0;
} }
} }
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;
}
}
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!