コード例 #1
0
ファイル: Stack.cs プロジェクト: Celarix/IronArc
        public Stack(int stackSize)
        {
            if (stackSize <= 0)
            {
                new SystemError("InvalidStackSize", "Stack size must be greater than zero.").WriteToError();
            }

            this.bytes = ByteBlock.FromLength(stackSize);
        }
コード例 #2
0
ファイル: Operand.cs プロジェクト: Celarix/IronArc
 public Operand(Processor cpu, OperandType optype)
 {
     Type = optype;
     switch (Type)
     {
         case OperandType.AddressBlock:
             Address = new AddressBlock(cpu, cpu.ReadULong());
             break;
         case OperandType.Register:
             // add
             break;
         case OperandType.StackIndex:
             // add
             break;
         case OperandType.NumericByte:
             Value = new ByteBlock(cpu.ReadByte());
             break;
         case OperandType.NumericSByte:
             Value = new ByteBlock(cpu.ReadSByte());
             break;
         case OperandType.NumericShort:
             Value = new ByteBlock(cpu.ReadShort());
             break;
         case OperandType.NumericUShort:
             Value = new ByteBlock(cpu.ReadUShort());
             break;
         case OperandType.NumericInt:
             Value = new ByteBlock(cpu.ReadInt());
             break;
         case OperandType.NumericUInt:
             Value = new ByteBlock(cpu.ReadUInt());
             break;
         case OperandType.NumericLong:
             Value = new ByteBlock(cpu.ReadLong());
             break;
         case OperandType.NumericULong:
             Value = new ByteBlock(cpu.ReadULong());
             break;
         case OperandType.NumericFloat:
             Value = new ByteBlock(cpu.ReadFloat());
             break;
         case OperandType.NumericDouble:
             Value = new ByteBlock(cpu.ReadDouble());
             break;
         case OperandType.LPString:
             uint length = cpu.ReadUInt();
             ByteBlock bytes = cpu.Read(length);
             Value = new ByteBlock(System.Text.Encoding.UTF8.GetString(bytes.ToByteArray()));
             break;
         default:
             break;
     }
 }
コード例 #3
0
ファイル: ByteBlock.cs プロジェクト: Celarix/IronArc
        public void WriteAt(ByteBlock bytes, int address)
        {
            if (address < 0 || address + bytes.Length >= this.Length)
            {
                throw new ArgumentOutOfRangeException(string.Format("Cannot write at 0x{0:X2}. Argument out of range.", address));
            }

            for (int i = 0; i < bytes.Length; i++)
            {
                *(this.pointer + address) = *(bytes.pointer + i);
                address++;
            }
        }
コード例 #4
0
ファイル: ByteBlock.cs プロジェクト: Celarix/IronArc
        public static ByteBlock FromLength(int length)
        {
            ByteBlock result = new ByteBlock();
            result.pointer = (byte*)Marshal.AllocHGlobal(length);
            result.Length = length;

            for (int i = 0; i < length; i++)
            {
                *(result.pointer + i) = 0;
            }

            return result;
        }
コード例 #5
0
ファイル: Stack.cs プロジェクト: Celarix/IronArc
 public void Push(ByteBlock bytes)
 {
     this.objectSizes.Push(bytes.Length);
     this.bytes.WriteAt(bytes, this.stackPointer);
     this.stackPointer += bytes.Length;
 }
コード例 #6
0
ファイル: Processor.cs プロジェクト: Celarix/IronArc
        private void LongArithmeticInstruction(DataOpcode opcode, Operand left, Operand right, Operand dest)
        {
            if (left.Type == Operand.OperandType.LPString || right.Type == Operand.OperandType.LPString)
            {
                throw new ArgumentException("can't do arithmetic on strings");
            }
            if (dest.Type != Operand.OperandType.AddressBlock && dest.Type != Operand.OperandType.Register && dest.Type != Operand.OperandType.StackIndex)
            {
                throw new ArgumentException("can't assign to a literal");
            }

            ByteBlock op1 = GetValue(left);
            ByteBlock op2 = GetValue(right);

            ulong uresult;
            long sresult;
            double fresult;
            ByteBlock result;
            if ((left.Type == Operand.OperandType.NumericByte || left.Type == Operand.OperandType.NumericUShort ||
                 left.Type == Operand.OperandType.NumericUInt || left.Type == Operand.OperandType.NumericULong ||
                 left.Type == Operand.OperandType.Register || left.Type == Operand.OperandType.AddressBlock) &&
                (right.Type == Operand.OperandType.NumericByte || right.Type == Operand.OperandType.NumericUShort ||
                 right.Type == Operand.OperandType.NumericUInt || right.Type == Operand.OperandType.NumericULong ||
                 right.Type == Operand.OperandType.Register || right.Type == Operand.OperandType.AddressBlock)) // for now, register & memory values are only treated as ulongs.  Fix
            {
                uresult = UnsignedArithmetic(opcode, op1.ToULong(), op2.ToULong());
                if (dest.Type == Operand.OperandType.Register)
                {
                    result = new ByteBlock(uresult);
                    WriteRegister((byte)dest.Value, result);
                }
                else
                {
                //	this.Memory.WriteULongAt(uresult, (int)(((AddressBlock)dest.Value).Address)); fix
                }
            }
            else if ((left.Type == Operand.OperandType.NumericSByte || left.Type == Operand.OperandType.NumericShort ||
                      left.Type == Operand.OperandType.NumericInt || left.Type == Operand.OperandType.NumericLong) &&
                     (right.Type == Operand.OperandType.NumericSByte || right.Type == Operand.OperandType.NumericShort ||
                      right.Type == Operand.OperandType.NumericInt || right.Type == Operand.OperandType.NumericLong))
            {
                sresult = SignedArithmetic(opcode, op1.ToLong(), op2.ToLong());
                if (dest.Type == Operand.OperandType.Register)
                {
                    result = new ByteBlock(sresult);
                    WriteRegister((byte)dest.Value, result);
                }
                else
                {
                //	this.Memory.WriteLongAt(sresult, (int)(((AddressBlock)dest.Value).Address)); fix
                }
            }
            else
            {
                fresult = FPArithmetic(opcode, op1.ToDouble(), op2.ToDouble());
                if (dest.Type == Operand.OperandType.Register)
                {
                    result = new ByteBlock(fresult);
                    WriteRegister((byte)dest.Value, result);
                }
                else
                {
                //	this.Memory.WriteDoubleAt(fresult, (int)(((AddressBlock)dest.Value).Address)); fix
                }
            }
        }
コード例 #7
0
ファイル: Processor.cs プロジェクト: Celarix/IronArc
        public void WriteRegister(byte register, ByteBlock value)
        {
            if (register >= 0x00 && register <= 0x07)
            {
                if (value.Length > 8)
                {
                    new SystemError("InvalidWriteLength", string.Format("Cannot write a {0}-byte value to a standard 8-byte register.", value.Length)).WriteToError();
                }
            }
            else if (register == 0x08)
            {
                if (value.Length > 4)
                {
                    new SystemError("InvalidWriteLength", string.Format("Cannot write a {0}-byte value to the 4-byte instruction pointer.", value.Length)).WriteToError();
                }
            }

            switch (register)
            {
                case 0x00:
                    this.EAX = 0UL;
                    this.EAX.WriteAt(value, 8 - value.Length);
                    break;
                case 0x01:
                    this.EBX = 0UL;
                    this.EBX.WriteAt(value, 8 - value.Length);
                    break;
                case 0x02:
                    this.ECX = 0UL;
                    this.ECX.WriteAt(value, 8 - value.Length);
                    break;
                case 0x03:
                    this.EDX = 0UL;
                    this.EDX.WriteAt(value, 8 - value.Length);
                    break;
                case 0x04:
                    this.EEX = 0UL;
                    this.EEX.WriteAt(value, 8 - value.Length);
                    break;
                case 0x05:
                    this.EFX = 0UL;
                    this.EFX.WriteAt(value, 8 - value.Length);
                    break;
                case 0x06:
                    this.EGX = 0UL;
                    this.EGX.WriteAt(value, 8 - value.Length);
                    break;
                case 0x07:
                    this.EHX = 0UL;
                    this.EHX.WriteAt(value, 8 - value.Length);
                    break;
                case 0x08:
                    this.InstructionPointer = value.ToUInt();
                    break;
                case 0x09:
                    break;
            }
        }