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;
import java.util.TimerTask;
import me.felinewith.kcpu.memory.MemHelper;
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 {
private void workCycle() {
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;
for (OpDirector o : OpDirector.values()) {
if (o.getOpcode() == inst) {
......@@ -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() ) {
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); }
registers = od.call(pc, ref, registers, values, board);
int vt = od.getArgs();
pc += 2;
if ( vt != 0 ) { pc += 2 + (vt * 2); }
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);
short data;
data = ValueHelper.readValue(0, ref, registers, values, board);
switch (od) {
// ask what device is using which address
case ASK : registers[0] = board.checkDevice((short)0);
case ASK: registers[0] = board.checkDevice((short)0);
case ASK: registers[0] = board.checkDevice((short)0);
case ASK: registers[0] = board.checkDevice((short)0);
case ASK:
data = board.checkDevice((short)(0x000f & data));
registers = ValueHelper.writeValue(1, ref, registers, values, board, data);
return;
// 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;
case IRQD:
board.sendIrq((byte)(0x000f & data));
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;
case IRQM:
board.memIrq(data);
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;
case JMPA: pc = data; 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;
case JMPD: pc = (short)(pc - (0xffff & data)); 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;
case JMP: pc = (short)(pc + (0xffff & data)); return;
}
}
}
......@@ -9,24 +9,27 @@ import me.felinewith.kcpu.IMemory;
*/
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 va = ValueHelper.readValue(0, ref, output, values, memory);
short vb = ValueHelper.readValue(1, ref, output, values, memory);
switch (opcode) {
case ADD: output[0] += output[1]; break;
case ADD: va += vb; break;
case DIV:
short rem = (short)(output[0] % output[1]);
output[0] /= output[1];
output[1] = rem;
short rem = (short)(va % vb);
va /= vb;
vb = rem;
break;
case MUL: output[0] *= output[1]; break;
case SUB: output[0] -= output[1]; break;
case MUL: va *= vb; 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;
}
@Override public ValueType[] getArgs(OpDirector opcode) {
return new ValueType[]{ValueType.NONE};
@Override public int getArgs(OpDirector opcode) {
return 2;
}
}
......@@ -7,6 +7,6 @@ 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);
public abstract short[] opcode(OpDirector opcode, short ref, short pc, short[] regs, short[] values, IMemory memory);
public abstract int getArgs(OpDirector opcode);
}
......@@ -9,75 +9,45 @@ 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) {
@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 ra = (short)(0x03 & a);
short rb = (short)(0x03 & b);
short data;
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;
case MOV: // movrr
data = ValueHelper.readValue(0, ref, output, values, memory);
output = ValueHelper.writeValue(1, 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 ValueType[] getArgs(OpDirector opcode) {
ValueType[] output = new ValueType[2];
output[0] = ValueType.NONE;
output[1] = ValueType.NONE;
@Override public int getArgs(OpDirector opcode) {
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;
case MOV: // movrr
return 2;
}
return output;
return 0;
}
}
......@@ -15,59 +15,18 @@ public enum OpDirector {
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),
MOV(0x0011, Memory.class),
// cpu stuffies
ASK_AA(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),
ASK(0x1000, null),
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),
JMP (0x8f08, 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;
......@@ -83,23 +42,23 @@ public enum OpDirector {
public short getOpcode() { return o; }
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 {
if (c == null) { return regs; }
IHandler ih = c.newInstance();
return ih.opcode(this, pc, regs, memory);
return ih.opcode(this, ref, pc, regs, values, memory);
}
catch (IllegalAccessException | InstantiationException e) {}
return regs;
}
public ValueType[] getArgs() {
public int getArgs() {
try {
if (c == null) { return null; }
if (c == null) { return 0; }
IHandler ih = c.newInstance();
return ih.getArgs(this);
}
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!