Esempio n. 1
0
 public SICEvent(Instruction inst, int PC)
 {
     this.instruction = inst;
     this.Continue = true;
     this.PC = PC;
     this.Ex = null;
     this.Message = null;
 }
Esempio n. 2
0
 public SICEvent(Instruction inst, int PC, Exception ex, string message)
 {
     this.instruction = inst;
     this.Continue = false;
     this.PC = PC;
     this.Ex = ex;
     this.Message = message;
 }
Esempio n. 3
0
        public bool Step()
        {
            this.devicewrite = false;
            current = getInstruction();
            SICEvent instEvent = new SICEvent(current, ProgramCounter);
            PreInstructionHook(instEvent);
            if (!instEvent.Continue)
                return false;
            current.addrof = ProgramCounter;
            IncrementPC(current);
            if (current.twobyte)
            {
                DoTwoBye(current);

                lastInstruction = current;

                instEvent = new SICEvent(lastInstruction, ProgramCounter);
                PostInstructionHook(instEvent);
                if (!instEvent.Continue)
                    return false;

                return true;
            }

            int calcaddr, memval;

            calcaddr = GetAddress(current);
            current.calculatedaddr = calcaddr;
            try
            {
                memval = GetData(current);
            }
            catch (IndexOutOfRangeException ex)
            {
                throw new IndexOutOfRangeException(string.Format("Error: Instruction at 0x{0:X3} references memory that's out of range (0x{1:X3}).", current.addrof, calcaddr), ex);
            }

            try
            {
                switch ((OpCode)current.opcode)
                {
                    case OpCode.ADD:
                        RegisterA += memval;
                        break;
                    case OpCode.SUB:
                        RegisterA -= memval;
                        break;
                    case OpCode.MUL:
                        RegisterA *= memval;
                        break;
                    case OpCode.DIV:
                        RegisterA /= memval;
                        break;
                    case OpCode.COMP:
                        Comp(RegisterA, memval);
                        break;
                    case OpCode.J:
                        ProgramCounter = calcaddr;
                        break;
                    case OpCode.JLT:
                        if (StatusWord == -1)
                            ProgramCounter = calcaddr;
                        break;
                    case OpCode.JGT:
                        if (StatusWord == 1)
                            ProgramCounter = calcaddr;
                        break;
                    case OpCode.JEQ:
                        if (StatusWord == 0)
                            ProgramCounter = calcaddr;
                        break;
                    case OpCode.STA:
                        StoreInt(calcaddr, RegisterA);
                        break;
                    case OpCode.STB:
                        StoreInt(calcaddr, RegisterB);
                        break;
                    case OpCode.STL:
                        StoreInt(calcaddr, RegisterL);
                        break;
                    case OpCode.STS:
                        StoreInt(calcaddr, RegisterS);
                        break;
                    case OpCode.STT:
                        StoreInt(calcaddr, RegisterT);
                        break;
                    case OpCode.STX:
                        StoreInt(calcaddr, RegisterX);
                        break;
                    case OpCode.LDB:
                        RegisterB = memval;
                        break;
                    case OpCode.LDX:
                        RegisterX = memval;
                        break;
                    case OpCode.LDA:
                        RegisterA = memval;
                        break;
                    case OpCode.LDL:
                        RegisterL = memval;
                        break;
                    case OpCode.LDS:
                        RegisterS = memval;
                        break;
                    case OpCode.LDT:
                        RegisterT = memval;
                        break;
                    case OpCode.TIX:
                        RegisterX++;
                        Comp(RegisterX, memval);
                        break;
                    case OpCode.JSUB:
                        RegisterL = ProgramCounter;
                        ProgramCounter = calcaddr;
                        break;
                    case OpCode.RSUB:
                        ProgramCounter = RegisterL;
                        break;
                    case OpCode.LDCH:
                        byte[] regA = BitConverter.GetBytes(RegisterA);
                        byte[] memChar = BitConverter.GetBytes(memval);
                        byte[] newVal = { memChar[2], regA[1], regA[2], regA[3] };
                        RegisterA = BitConverter.ToInt32(newVal, 0);
                        break;
                    case OpCode.STCH:
                        byte[] regiA = BitConverter.GetBytes(RegisterA);
                        memory[calcaddr] = regiA[0];
                        MemoryChangedHook(calcaddr, 1);
                        break;
                    case OpCode.RD:
                    case OpCode.TD:
                    case OpCode.WD:
                        devicewrite = true;
                        if (!DoDevice(current.opcode, memval))
                        {
                            ProgramCounter -= 3;
                            return false;
                        }
                        break;
                    case OpCode.AND:
                        RegisterA = RegisterA & memval;
                        break;
                    case OpCode.OR:
                        RegisterA = RegisterA | memval;
                        break;
                    default:
                        int location = ProgramCounter;
                        if (current.extended)
                            location -= 4;
                        else
                            location -= 3;
                        throw new ArgumentException(string.Format("Error: Instruction at 0x{0} not a recognized opcode.", !current.extended ? location.ToString("X3") : location.ToString("X4")));
                }
            }
            catch (IndexOutOfRangeException ex)
            {
                throw new IndexOutOfRangeException(string.Format("Error: Instruction at 0x{0:X3} references memory that's out of range (0x{1:X3}).", ProgramCounter - 3, calcaddr), ex);
            }

            lastInstruction = current;

            instEvent = new SICEvent(lastInstruction, ProgramCounter);
            PostInstructionHook(instEvent);
            if (!instEvent.Continue)
                return false;
            return true;
        }
Esempio n. 4
0
 public void IncrementPC(Instruction current)
 {
     if (current.twobyte)
         ProgramCounter += 2;
     else if (current.extended)
         ProgramCounter += 4;
     else
         ProgramCounter += 3;
 }
Esempio n. 5
0
        public int GetData(Instruction current)
        {
            int address = GetAddress(current);
            int memval;

            if (current.immediate && !current.indirect)
            {
                if (!current.pcrel)
                { // Immediate mode combined with an addressing mode gets you the address as data. See Beck, p61
                    memval = current.address;
                    if (current.extended)
                    {
                        if ((memval & 0x80000) > 0)
                            memval = unchecked((int)((memval & 0xFFFFF) + 0xFFF00000));
                    }
                    else
                    {
                        if ((memval & 0x800) > 0)
                            memval = unchecked((int)((memval & 0xFFF) + 0xFFFFF000));
                    }
                }
                else if (current.baserel)
                    memval = RegisterB + current.address;
                else
                    memval = ProgramCounter + current.address;
            }
            else
            {
                memval = GetMemoryValue(address);
            }

            return memval;
        }
Esempio n. 6
0
        public int GetAddress(Instruction current)
        {
            int calcaddr;
            if (current.baserel)
                calcaddr = RegisterB + current.address;
            else if (current.extended)
                calcaddr = current.address;
            else
                calcaddr = ProgramCounter + current.address;

            if (!current.immediate && current.indirect)
            {
                calcaddr = GetMemoryValue(calcaddr);
            }

            if (current.indexed)
            {
                calcaddr += RegisterX;
            }

            return calcaddr;
        }
Esempio n. 7
0
 public void DoTwoBye(Instruction current)
 {
     Register r1 = current.r1;
     Register r2 = current.r2;
     switch (current.opcode)
     {
         case OpCode.ADDR:
             SetRegisterValue(r2, (GetRegisterValue(r2) + GetRegisterValue(r1)));
             break;
         case OpCode.CLEAR:
             SetRegisterValue(r1, 0);
             break;
         case OpCode.COMPR:
             Comp(GetRegisterValue(r1), GetRegisterValue(r2));
             break;
         case OpCode.DIVR:
             SetRegisterValue(r2, (GetRegisterValue(r2) / GetRegisterValue(r1)));
             break;
         case OpCode.MULR:
             SetRegisterValue(r2, (GetRegisterValue(r2) * GetRegisterValue(r1)));
             break;
         case OpCode.RMO:
             SetRegisterValue(r2, GetRegisterValue(r1));
             break;
         case OpCode.SUBR:
             SetRegisterValue(r2, (GetRegisterValue(r2) - GetRegisterValue(r1)));
             break;
         case OpCode.TIXR:
             RegisterX++;
             Comp(RegisterX, GetRegisterValue(r1));
             break;
         case OpCode.SHIFTL:
             uint lshift = (uint)GetRegisterValue(r1);
             for (int i = 0; i < ((int)r2) + 1; i++)
             {
                 lshift = lshift << 1;
                 if ((lshift & 0x01000000) > 0)
                     lshift = (lshift | 0x01);
                 lshift = lshift & 0x00FFFFFF;
             }
             SetRegisterValue(r1, (int)lshift);
             break;
         case OpCode.SHIFTR:
             uint rshift = (uint)GetRegisterValue(r1);
             for (int i = 0; i < ((int)r2) + 1; i++)
             {
                 bool ones = (rshift & 0x1) > 0;
                 rshift = rshift >> 1;
                 if (ones)
                     rshift = (rshift | 0x800000);
             }
             SetRegisterValue(r1, (int)rshift);
             break;
     }
 }