Example #1
0
        private uint DecodeStoreOperand(Opcode opcode, byte type, ref uint operandPos)
        {
            uint address;
            switch (type)
            {
                case 0:
                    // discard result
                    WriteTrace("discard");
                    return 0;

                // case 1..4: unused

                case 5:
                    address = image.ReadByte(operandPos++);
                    WriteTrace("ptr_" + address.ToString());
                    break;
                case 6:
                    address = image.ReadInt16(operandPos);
                    operandPos += 2;
                    WriteTrace("ptr_" + address.ToString());
                    break;
                case 7:
                    address = image.ReadInt32(operandPos);
                    operandPos += 4;
                    WriteTrace("ptr_" + address.ToString());
                    break;

                // case 8: push onto stack
                case 8:
                    // push onto stack
                    WriteTrace("sp");
                    return 0;

                case 9:
                    address = image.ReadByte(operandPos++);
                    WriteTrace("local_" + address.ToString());
                    break;
                case 10:
                    address = image.ReadInt16(operandPos);
                    operandPos += 2;
                    WriteTrace("local_" + address.ToString());
                    break;
                case 11:
                    address = image.ReadInt32(operandPos);
                    operandPos += 4;
                    WriteTrace("local_" + address.ToString());
                    break;

                // case 12: unused

                case 13:
                    address = image.RamStart + image.ReadByte(operandPos++);
                    WriteTrace("ram_" + (address - image.RamStart).ToString());
                    break;
                case 14:
                    address = image.RamStart + image.ReadInt16(operandPos);
                    operandPos += 2;
                    WriteTrace("ram_" + (address - image.RamStart).ToString());
                    break;
                case 15:
                    address = image.RamStart + image.ReadInt32(operandPos);
                    operandPos += 4;
                    WriteTrace("ram_" + (address - image.RamStart).ToString());
                    break;

                default:
                    throw new ArgumentException("Invalid operand type");
            }
            return address;
        }
Example #2
0
        private uint DecodeLoadOperand(Opcode opcode, byte type, ref uint operandPos)
        {
            uint address, value;
            switch (type)
            {
                case 0:
                    WriteTrace("zero");
                    return 0;
                case 1:
                    value = (uint)(sbyte)image.ReadByte(operandPos++);
                    WriteTrace("byte_" + value.ToString());
                    return value;
                case 2:
                    operandPos += 2;
                    value = (uint)(short)image.ReadInt16(operandPos - 2);
                    WriteTrace("short_" + value.ToString());
                    return value;
                case 3:
                    operandPos += 4;
                    value = image.ReadInt32(operandPos - 4);
                    WriteTrace("int_" + value.ToString());
                    return value;

                // case 4: unused

                case 5:
                    address = image.ReadByte(operandPos++);
                    WriteTrace("ptr");
                    goto LoadIndirect;
                case 6:
                    address = image.ReadInt16(operandPos);
                    operandPos += 2;
                    WriteTrace("ptr");
                    goto LoadIndirect;
                case 7:
                    address = image.ReadInt32(operandPos);
                    operandPos += 4;
                    WriteTrace("ptr");
                LoadIndirect:
                    WriteTrace("_" + address.ToString() + "(");
                    switch (opcode.Attr.Rule)
                    {
                        case OpcodeRule.Indirect8Bit:
                            value = image.ReadByte(address);
                            break;
                        case OpcodeRule.Indirect16Bit:
                            value = image.ReadInt16(address);
                            break;
                        default:
                            value = image.ReadInt32(address);
                            break;
                    }
                    WriteTrace(value.ToString() + ")");
                    return value;

                case 8:
                    if (sp <= fp + frameLen)
                        throw new VMException("Stack underflow");
                    value = Pop();
                    WriteTrace("sp(" + value.ToString() + ")");
                    return value;

                case 9:
                    address = image.ReadByte(operandPos++);
                    goto LoadLocal;
                case 10:
                    address = image.ReadInt16(operandPos);
                    operandPos += 2;
                    goto LoadLocal;
                case 11:
                    address = image.ReadInt32(operandPos);
                    operandPos += 4;
                LoadLocal:
                    WriteTrace("local_" + address.ToString() + "(");
                    address += fp + localsPos;
                    switch (opcode.Attr.Rule)
                    {
                        case OpcodeRule.Indirect8Bit:
                            if (address >= fp + frameLen)
                                throw new VMException("Reading outside local storage bounds");
                            else
                                value = stack[address];
                            break;
                        case OpcodeRule.Indirect16Bit:
                            if (address + 1 >= fp + frameLen)
                                throw new VMException("Reading outside local storage bounds");
                            else
                                value = BigEndian.ReadInt16(stack, address);
                            break;
                        default:
                            if (address + 3 >= fp + frameLen)
                                throw new VMException("Reading outside local storage bounds");
                            else
                                value = ReadFromStack(address);
                            break;
                    }
                    WriteTrace(value.ToString() + ")");
                    return value;

                // case 12: unused

                case 13:
                    address = image.RamStart + image.ReadByte(operandPos++);
                    WriteTrace("ram");
                    goto LoadIndirect;
                case 14:
                    address = image.RamStart + image.ReadInt16(operandPos);
                    operandPos += 2;
                    WriteTrace("ram");
                    goto LoadIndirect;
                case 15:
                    address = image.RamStart + image.ReadInt32(operandPos);
                    operandPos += 4;
                    WriteTrace("ram");
                    goto LoadIndirect;

                default:
                    throw new ArgumentException("Invalid operand type");
            }
        }