/** * Sets the message's opcode * * @see Opcode */ public void setOpcode(Opcode opcode) { int value = opcode.getValue(); if (value < 0 || value > 0xF) throw new IllegalArgumentException("DNS Opcode " + value + "is out of range"); flags &= 0x87FF; flags |= (value << 11); }
@Override protected void outputLocalInfo(XmlWriter writer) { super.outputLocalInfo(writer); // Opcode if (opcode != null) writer.write("code", opcode.getID()); // Label if (label != null) writer.write("label", label); // Immediate operands if (reference != null) reference.output(writer); if ((targets == null) && (operand != null)) writer.write(operand); // Switch-like instructions if ((targets != null) && (targets.size() > 0)) { ReadOnlyCollection<Integer> labels = targets.keys(); for (int key : labels) { writer.start("target"); writer.write("key", key); writer.write(targets.get(key)); writer.end("target"); } if (operand != null) { writer.start("default"); writer.write(operand); writer.end("default"); } } }
public String toString() { return String.format("#%d (@%d) %s", index() + 1, offset(), Opcode.forOpcode(opcode())); }
public void cycle() { if (halted) { return; } try { if (ip >= memory.length) { // Loop back to the beginning of memory ip = 0; } Opcode opcode = Opcode.get(memory[ip++]); byte flags = 0; if (opcode.argumentCount > 0) { flags = memory[ip++]; } Register reg; switch (opcode) { case NOP: break; case MOV: if (argumentType(flags, 0) == ArgumentType.CONSTANT) { // Memory address // Note - only the least significant byte is set here int address = argument(flags, 0); int value = argument(flags, 1); memory[address] = (byte) value; } else if (argumentType(flags, 0) == ArgumentType.REGISTER) { reg = Register.index(memory[ip++]); int value = argument(flags, 1); register(reg, value); } else { throw new NonMaskableInterrupt("invalid argument type"); } break; case ADD: reg = Register.index(memory[ip++]); register(reg, register(reg) + argument(flags, 1)); break; case SUB: reg = Register.index(memory[ip++]); register(reg, register(reg) - argument(flags, 1)); break; case MUL: reg = Register.index(memory[ip++]); register(reg, register(reg) * argument(flags, 1)); break; case DIV: reg = Register.index(memory[ip++]); register(reg, register(reg) / argument(flags, 1)); break; case PUSH: push(Register.index(memory[ip++])); break; case POP: pop(Register.index(memory[ip++])); break; case APUSH: push(Register.EDX); push(Register.ECX); push(Register.EBX); push(Register.EAX); break; case APOP: pop(Register.EAX); pop(Register.EBX); pop(Register.ECX); pop(Register.EDX); break; case JMP: ip = argument(flags, 0); break; case JEZ: int jezDest = argument(flags, 0); if (argument(flags, 1) == 0) { ip = jezDest; } break; case JNZ: int jnzDest = argument(flags, 0); if (argument(flags, 1) != 0) { ip = jnzDest; } break; case JLZ: int jlzDest = argument(flags, 0); if (argument(flags, 1) < 0) { ip = jlzDest; } break; case JGZ: int jgzDest = argument(flags, 0); if (argument(flags, 1) > 0) { ip = jgzDest; } break; case HWID: break; case HLT: halt(); break; } } catch (Exception ex) { throw new NonMaskableInterrupt(ex); } }
/** * Retrieves the mesasge's opcode * * @see Opcode */ public Opcode getOpcode() { return Opcode.valueOf((flags >> 11) & 0xF); }