Z80Instruction { public byte[] compile(final String asm, final ExpressionProcessor expressionCalc) { final Matcher m = this.compilePattern.matcher(asm.trim()); if (m.find()) { for (int i = 0; i < this.compileGroupTypes.length; i++) { final int value = this.compileGroupTypes[i]; if (value < SPEC_INDEX) { final int result = expressionCalc.evalExpression(m.group(i + 1)); if (result != value) { return null; } } } final byte[] resultBuff = new byte[16]; int resultIndex = 0; for (int i = 0; i < this.instructionCodeTemplate.length; i++) { final int type = this.instructionCodeTemplate[i]; if (type < SPEC_INDEX) { resultBuff[resultIndex++] = (byte) type; } else { int groupIndex = -1; for (int j = 0; j < this.compileGroupTypes.length; j++) { if (this.compileGroupTypes[j] == type) { groupIndex = j + 1; break; } } if (groupIndex < 0) { throw new Error("Unexpected state, group nt found!"); } final int result = expressionCalc.evalExpression(m.group(groupIndex)); switch (type) { case SPEC_INDEX: { if (result < -128 || result > 127) { throw new CompileInstructionException(this, "Wrong index value [" + result + ']'); } resultBuff[resultIndex++] = (byte) result; } break; case SPEC_OFFSET: { if (result < -128 || result > 127) { throw new CompileInstructionException(this, "Wrong offset value [" + result + ']'); } resultBuff[resultIndex++] = (byte) result; } break; case SPEC_UNSIGNED_BYTE: { resultBuff[resultIndex++] = (byte) result; } break; case SPEC_UNSIGNED_WORD: { resultBuff[resultIndex++] = (byte) result; resultBuff[resultIndex++] = (byte) (result >>> 8); } break; default: { throw new Error("Unexpected type [" + type + ']'); } } } } return Arrays.copyOf(resultBuff, resultIndex); } else { return null; } } Z80Instruction(final String def); static List<Z80Instruction> getInstructions(); static String indexToHex(final byte index); boolean matches(final String asm); byte[] compile(final String asm, final ExpressionProcessor expressionCalc); boolean hasIndex(); boolean hasOffset(); boolean hasByte(); boolean hasWord(); int getFixedPartLength(); int getLength(); int[] getInstructionCodes(); boolean matches(final MemoryAccessProvider memoryAccessProvider, int offset); String decode(final MemoryAccessProvider memoryAccessProvider, int address,
                       final int pcCounter); @Override String toString(); static final int SPEC_INDEX; static final int SPEC_OFFSET; static final int SPEC_UNSIGNED_BYTE; static final int SPEC_UNSIGNED_WORD; }
@Test public void testCompile_LD_IY_d_n() { final Z80Instruction ins = new Z80Instruction("FD36 d n LD (IY+d),n"); final byte[] compiled = ins.compile("ld (iy+16),87", new Z80Instruction.ExpressionProcessor() { @Override public int evalExpression(final String expression) { return Integer.parseInt(expression); } }); assertArrayEquals(new byte[] {(byte) 0xFD, (byte) 0x36, (byte) 0x10, 87}, compiled); }
@Test public void testCompile_CALL_nn() { final Z80Instruction ins = new Z80Instruction("CD nn CALL nn"); final byte[] compiled = ins.compile("call 16384", new Z80Instruction.ExpressionProcessor() { @Override public int evalExpression(final String expression) { return Integer.parseInt(expression); } }); assertArrayEquals(new byte[] {(byte) 0xCD, (byte) 0x00, (byte) 0x40}, compiled); }