Beispiel #1
0
 /// <summary>
 /// Creates a new instance of the CPU with the given instruction memory.
 /// </summary>
 /// <param name="iMem">instruction memory, mapping memory location to instruction</param>
 public Cpu(Dictionary<ushort, uint> iMem)
 {
     this.instructionMemory = new uint[0x400];
     for (ushort i = 0; i < 0x400; i++)
     {
         if (iMem.ContainsKey(i))
             instructionMemory[i] = iMem[i];
     }
     this.state = new CpuState();
     this.SleepTickInterval = DefaultSleepTickInterval;
 }
        private void test(CpuState state, byte aVal, byte bVal)
        {
            state.ZeroFlag = (aVal & bVal) == 0;

            //odd parity for C flag
            var xor = aVal ^ bVal;
            int count = 0;
            int mask = 0x80;
            while (mask != 0)
            {
                if ((mask & xor) != 0)
                    count++;
                mask = mask >> 1;
            }
            state.CarryFlag = (count % 2) == 0;
        }
 private bool flowControlConditional(CpuState state, FlowControlCondition cond)
 {
     switch (cond)
     {
         case FlowControlCondition.Z:
             return state.ZeroFlag;
         case FlowControlCondition.NZ:
             return !state.ZeroFlag;
         case FlowControlCondition.C:
             return state.CarryFlag;
         case FlowControlCondition.NC:
             return !state.CarryFlag;
         default:
             throw new NotSupportedException("Invalid flag.");
     }
 }
 private void doShifter(CpuState state, byte reg, byte typeBits)
 {
     bool oldCarry;
     ShifterOps type = (ShifterOps)typeBits;
     byte val = state.RegisterFile[reg];
     switch (type)
     {
         case ShifterOps.RL:
             state.CarryFlag = (0x80 & val) != 0;
             val = (byte)(val << 1);
             if (state.CarryFlag)
                 val++;
             break;
         case ShifterOps.RR:
             state.CarryFlag = (0x01 & val) == 1;
             val = (byte)(val >> 1);
             val |= (byte)(state.CarryFlag ? 0x80 : 0x0);
             break;
         case ShifterOps.SL0:
             state.CarryFlag = (0x80 & val) != 0;
             val = (byte)(val << 1);
             break;
         case ShifterOps.SL1:
             state.CarryFlag = (0x80 & val) != 0;
             val = (byte)(val << 1);
             val |= 0x01;
             break;
         case ShifterOps.SLA:
             oldCarry = state.CarryFlag;
             state.CarryFlag = (0x80 & val) != 0;
             val = (byte)(val << 1);
             val |= (byte)(oldCarry ? 0x01 : 0x00);
             break;
         case ShifterOps.SLX:
             bool oldBottomBit = (0x01 & val) == 1;
             state.CarryFlag = (0x80 & val) != 0;
             val = (byte)(val << 1);
             val |= (byte)(oldBottomBit ? 0x01 : 0x00);
             break;
         case ShifterOps.SR0:
             state.CarryFlag = (0x01 & val) != 0;
             val = (byte)(val >> 1);
             break;
         case ShifterOps.SR1:
             state.CarryFlag = (0x01 & val) != 0;
             val = (byte)(val >> 1);
             val |= 0x80;
             break;
         case ShifterOps.SRA:
             oldCarry = state.CarryFlag;
             state.CarryFlag = (0x01 & val) != 0;
             val = (byte)(val >> 1);
             val |= (byte)(oldCarry ? 0x80 : 0x00);
             break;
         case ShifterOps.SRX:
             bool oldTopBit = (0x80 & val) == 1;
             state.CarryFlag = (0x01 & val) != 0;
             val = (byte)(val >> 1);
             val |= (byte)(oldTopBit ? 0x80 : 0x00);
             break;
         default:
             throw new NotSupportedException("Unsupported shifter operation.");
     }
     state.RegisterFile[reg] = val;
 }
 private byte doLogic(CpuState state, int value)
 {
     state.ZeroFlag = value == 0;
     state.CarryFlag = false;
     return (byte)value;
 }
 private void compare(CpuState state, byte aVal, byte bVal)
 {
     state.ZeroFlag = aVal == bVal;
     state.CarryFlag = aVal < bVal;
 }
 private ushort call(CpuState state, ushort addr)
 {
     state.CallStack.Push(++state.ProgramCounter);
     return addr;
 }
        private static byte sub(CpuState state, byte a, int b, bool cy)
        {
            int ret = a - b - (cy && state.CarryFlag ? 1 : 0);

            state.CarryFlag = ret < 0;
            state.ZeroFlag = (ret == 0) || (ret == -256);

            return (byte)(0xFF & ret);
        }
        private static byte add(CpuState state, byte a, int b, bool cy)
        {
            int ret = a + b + (cy && state.CarryFlag ? 1 : 0);

            state.CarryFlag = ret > 255;
            state.ZeroFlag = (ret == 0) || ((ret + (state.CarryFlag ? 1 : 0)) == 256);

            return (byte)(0xFF & ret);
        }
Beispiel #10
0
 /// <summary>
 /// Executes the operation on the given CPU state with the given arguments.
 /// </summary>
 /// <param name="state"></param>
 /// <param name="args"></param>
 public abstract void Do(CpuState state, ushort args);
Beispiel #11
0
 /// <summary>
 /// Stops and resets the processor.  
 /// </summary>
 /// <returns>The the instructions per second executed.</returns>
 public double Reset()
 {
     this.isRunning = false;
     runThread.Join();
     this.state = new CpuState();
     foreach (var dev in devices)
     {
         hookupDevice(dev);
     }
     return tickCount / (endTime.Subtract(startTime).TotalSeconds);
 }