private MachineOperand ParseOperandInner(byte addressMode, byte operandBits, PrimitiveType dataWidth, ImageReader rdr) { Constant offset; switch (addressMode) { case 0: // Data register direct. return DataRegisterOperand(operandBits, 0); case 1: // Address register direct return new RegisterOperand(AddressRegister(operandBits, 0)); case 2: // Address register indirect return MemoryOperand.Indirect(dataWidth, AddressRegister(operandBits, 0)); case 3: // Address register indirect with postincrement. return MemoryOperand.PostIncrement(dataWidth, AddressRegister(operandBits, 0)); case 4: // Address register indirect with predecrement. return MemoryOperand.PreDecrement(dataWidth, AddressRegister(operandBits, 0)); case 5: // Address register indirect with displacement. offset = Constant.Int16(rdr.ReadBeInt16()); return MemoryOperand.Indirect(dataWidth, AddressRegister(operandBits, 0), offset); case 6: // Address register indirect with index return AddressRegisterIndirectWithIndex(dataWidth, rdr); case 7: switch (operandBits) { case 0: // Absolute short address return new M68kAddressOperand(rdr.ReadBeUInt16()); case 1: // Absolute long address return new M68kAddressOperand(rdr.ReadBeUInt32()); case 2: // Program counter with displacement var off = rdr.Address - dasm.instr.Address; off += rdr.ReadBeInt16(); return new MemoryOperand(dataWidth, Registers.pc, Constant.Int16((short) off)); case 3: // Program counter with index var addrExt = rdr.Address; ushort extension = rdr.ReadBeUInt16(); if (EXT_FULL(extension)) { if (EXT_EFFECTIVE_ZERO(extension)) { return new M68kImmediateOperand(Constant.Word32(0)); } Constant @base = null; Constant outer = null; if (EXT_BASE_DISPLACEMENT_PRESENT(extension)) @base = EXT_BASE_DISPLACEMENT_LONG(extension) ? rdr.ReadBe(PrimitiveType.Word32) : rdr.ReadBe(PrimitiveType.Int16); if (EXT_OUTER_DISPLACEMENT_PRESENT(extension)) outer = EXT_OUTER_DISPLACEMENT_LONG(extension) ? rdr.ReadBe(PrimitiveType.Word32) : rdr.ReadBe(PrimitiveType.Int16); RegisterStorage base_reg = EXT_BASE_REGISTER_PRESENT(extension) ? Registers.pc : null; RegisterStorage index_reg = null; PrimitiveType index_width = null; int index_scale = 0; if (EXT_INDEX_REGISTER_PRESENT(extension)) { index_reg = EXT_INDEX_AR(extension) ? Registers.AddressRegister((int)EXT_INDEX_REGISTER(extension)) : Registers.DataRegister((int)EXT_INDEX_REGISTER(extension)); index_width = EXT_INDEX_LONG(extension) ? PrimitiveType.Word32 : PrimitiveType.Int16; index_scale = (EXT_INDEX_SCALE(extension) != 0) ? 1 << EXT_INDEX_SCALE(extension) : 0; } return new IndexedOperand(dataWidth, @base, outer, base_reg, index_reg, index_width, index_scale, (extension & 7) > 0 && (extension & 7) < 4, (extension & 7) > 4); } return new IndirectIndexedOperand( EXT_8BIT_DISPLACEMENT(extension), Registers.pc, EXT_INDEX_AR(extension) ? Registers.AddressRegister((int)EXT_INDEX_REGISTER(extension)) : Registers.DataRegister((int)EXT_INDEX_REGISTER(extension)), EXT_INDEX_LONG(extension) ? PrimitiveType.Word32 : PrimitiveType.Int16, 1 << EXT_INDEX_SCALE(extension)); case 4: // Immediate if (dataWidth.Size == 1) // don't want the instruction stream to get misaligned! rdr.ReadByte(); return new M68kImmediateOperand(rdr.ReadBe(dataWidth)); default: throw new NotImplementedException(string.Format("Address mode {0}:{1} not implemented.", addressMode, operandBits)); } default: throw new NotImplementedException(string.Format("Address mode {0:X1} not implemented.", addressMode)); } }
public MachineOperand GetOperand(ImageReader rdr, string args, PrimitiveType dataWidth) { if (i >= args.Length) return null; for (; ; ) { if (args[i] == ',') ++i; Address addr; switch (args[i++]) { case 'A': // Address register A0-A7 encoded in in instrution return new RegisterOperand(AddressRegister(opcode, GetOpcodeOffset(args[i++]))); case 'c': // CCR register return new RegisterOperand(Registers.ccr); case 'D': // Data register D0-D7 encoded in instruction return DataRegisterOperand(opcode, GetOpcodeOffset(args[i++])); case 'E': // Effective address (EA) return ParseOperand(opcode, GetOpcodeOffset(args[i++]), dataWidth, rdr); case 'e': // Effective address with 3-bit halves swapped return ParseSwappedOperand(opcode, GetOpcodeOffset(args[i++]), dataWidth, rdr); case 'I': // Immediate operand return GetImmediate(rdr, GetSizeType(0, args[i++], dataWidth)); case 'J': // PC Relative jump addr = rdr.Address; int offset = opcode & 0xFF; if (offset == 0xFF) offset = rdr.ReadBeInt32(); else if (offset == 0x00) offset = rdr.ReadBeInt16(); else offset = (sbyte) offset; return new M68kAddressOperand(addr + offset); case 'M': // Register bitset return new RegisterSetOperand(rdr.ReadBeUInt16()); case 'n': // cache bitset bitSet = rdr.ReadBeUInt16(); break; case 'm': // Register bitset reversed return RegisterSetOperand.CreateReversed(bitSet); case 'q': // "Small" quick constant (3-bit part of the opcode) return GetQuickImmediate(GetOpcodeOffset(args[i++]), 0x07, 8, PrimitiveType.Byte); case 'Q': // "Large" quick constant (8-bit part of the opcode) return GetQuickImmediate(GetOpcodeOffset(args[i++]), 0xFF, 0, PrimitiveType.SByte); case 'R': // relative addr = rdr.Address; int relative = 0; switch (args[i++]) { case 'w': relative = rdr.ReadBeInt16(); break; case 'l': relative = rdr.ReadBeInt32(); break; default: throw new NotImplementedException(); } return new M68kAddressOperand(addr + relative); case 's': // SR register return new RegisterOperand(Registers.sr); case '+': // Postincrement operator; following character specifies bit offset of the address register code. return new PostIncrementMemoryOperand(dataWidth, AddressRegister(opcode, GetOpcodeOffset(args[i++]))); case '-': // Predecrement operator; following character specifies bit offset of the address register code. return new PredecrementMemoryOperand(dataWidth, AddressRegister(opcode, GetOpcodeOffset(args[i++]))); default: throw new FormatException(string.Format("Unknown argument type {0}.", args[--i])); } } }
public virtual short read_word(ImageReader f) { if (!f.IsValid) return -1; if (!f.IsValidOffset(1)) return -2; return f.ReadBeInt16(); }