Пример #1
0
 private Variable ReadVariable(ref int address)
 {
     return(Variable.FromByte(memory.ReadByte(ref address)));
 }
Пример #2
0
        public Instruction NextInstruction()
        {
            var startAddress = address;

            Instruction instruction;

            if (cache.TryGet(startAddress, out instruction))
            {
                address += instruction.Length;
                return(instruction);
            }

            var opByte = memory.ReadByte(ref address);

            Opcode opcode;

            for (int i = 0; i < 8; i++)
            {
                operandKinds[i] = opKind_Omitted;
            }

            if (opByte >= 0x00 && opByte <= 0x1f)
            {
                opcode          = opcodeTable[OpcodeKind.TwoOp, LongForm(opByte)];
                operandKinds[0] = opKind_SmallConstant;
                operandKinds[1] = opKind_SmallConstant;
            }
            else if (opByte >= 0x20 && opByte <= 0x3f)
            {
                opcode          = opcodeTable[OpcodeKind.TwoOp, LongForm(opByte)];
                operandKinds[0] = opKind_SmallConstant;
                operandKinds[1] = opKind_Variable;
            }
            else if (opByte >= 0x40 && opByte <= 0x5f)
            {
                opcode          = opcodeTable[OpcodeKind.TwoOp, LongForm(opByte)];
                operandKinds[0] = opKind_Variable;
                operandKinds[1] = opKind_SmallConstant;
            }
            else if (opByte >= 0x60 && opByte <= 0x7f)
            {
                opcode          = opcodeTable[OpcodeKind.TwoOp, LongForm(opByte)];
                operandKinds[0] = opKind_Variable;
                operandKinds[1] = opKind_Variable;
            }
            else if (opByte >= 0x80 && opByte <= 0x8f)
            {
                opcode          = opcodeTable[OpcodeKind.OneOp, ShortForm(opByte)];
                operandKinds[0] = opKind_LargeConstant;
            }
            else if (opByte >= 0x90 && opByte <= 0x9f)
            {
                opcode          = opcodeTable[OpcodeKind.OneOp, ShortForm(opByte)];
                operandKinds[0] = opKind_SmallConstant;
            }
            else if (opByte >= 0xa0 && opByte <= 0xaf)
            {
                opcode          = opcodeTable[OpcodeKind.OneOp, ShortForm(opByte)];
                operandKinds[0] = opKind_Variable;
            }
            else if ((opByte >= 0xb0 && opByte <= 0xbd) || opByte == 0xbf)
            {
                opcode = opcodeTable[OpcodeKind.ZeroOp, ShortForm(opByte)];
            }
            else if (opByte == 0xbe)
            {
                opcode = opcodeTable[OpcodeKind.Ext, memory.ReadByte(ref address)];
                ReadOperandKinds();
            }
            else if (opByte >= 0xc0 && opByte <= 0xdf)
            {
                opcode = opcodeTable[OpcodeKind.TwoOp, VarForm(opByte)];
                ReadOperandKinds();
            }
            else // opByte >= 0xe0 && opByte <= 0xff
            {
                opcode = opcodeTable[OpcodeKind.VarOp, VarForm(opByte)];
                ReadOperandKinds();
            }

            if (opcode.IsDoubleVariable)
            {
                ReadOperandKinds(4);
            }

            var operands = ReadOperands();

            Variable storeVariable = null;

            if (opcode.HasStoreVariable)
            {
                storeVariable = ReadVariable(ref address);
            }

            Branch?branch = null;

            if (opcode.HasBranch)
            {
                branch = ReadBranch(ref address);
            }

            ushort[] ztext = null;
            if (opcode.HasZText)
            {
                ztext = ReadZWords(ref address);
            }

            var length = address - startAddress;

            instruction = new Instruction(startAddress, length, opcode, operands, operands.Length, storeVariable, branch, ztext);
            cache.Add(startAddress, instruction);
            return(instruction);
        }