Exemple #1
0
        public int Tick()
        {
            if (skipNext)
            {
                GetInstruction();
                this.skipNext = false;
            }

            #if DEBUG
            if (this.ram.Ram[this.registers.ProgramCounter] == 0) return 0;
            #endif

            var ins = GetInstruction();
            this.currentInstruction = ins;
            int cost = GetCost(ins);

            switch (ins.instruction)
            {
                case 0x0:
                    switch (ins.a)
                    {
                        case 0x01:
                            this.Jsr(ins.b);
                            break;
                        default:
                            break;
                    }
                    break;

                case 0x1:
                    this.Set(ins.a, ins.b);
                    break;

                case 0x2:
                    DoMathOp(ResolveSources(ins.a, ins.b), GetDestination(ins.a), (x, y) => (ushort) (x + y), (x, y) => (ushort) ((x + y) > 0xffff ? 0x0001 : 0x0000));
                    break;

                case 0x3:
                    DoMathOp(ResolveSources(ins.a, ins.b), GetDestination(ins.a), (x, y) => (ushort) (x - y), (x, y) => (ushort) (x < y ? 0xffff : 0x0000));
                    break;

                case 0x4:
                    DoMathOp(ResolveSources(ins.a, ins.b), GetDestination(ins.a), (x, y) => (ushort) (x*y), (x, y) => (ushort) (((x*y) >> 16) & 0xffff));
                    break;

                case 0x5:
                    DoMathOp(ResolveSources(ins.a, ins.b), GetDestination(ins.a), (x, y) => (ushort) (x/y), (x, y) => (ushort) (((x << 16)/y) & 0xffff), (y) => y != 0, () => this.registers.OverFlow = 0);
                    break;

                case 0x6:
                    DoMathOp(ResolveSources(ins.a, ins.b), GetDestination(ins.a), (x, y) => (ushort) (x%y), (x, y) => 0, (y) => y != 0, () => 0);
                    break;

                case 0x7:
                    DoMathOp(Tuple.Create(GetSource(ins.a)(), (ushort) ins.b), GetDestination(ins.a), (x, y) => (ushort) (x << y), (x, y) => (ushort) (((x << y) >> 16) & 0xffff));
                    break;

                case 0x8:
                    DoMathOp(Tuple.Create(GetSource(ins.a)(), (ushort) ins.b), GetDestination(ins.a), (x, y) => (ushort) (x >> y), (x, y) => (ushort) (((x << 16) >> y) & 0xffff));
                    break;

                case 0x9:
                    DoBinaryOp(ResolveSources(ins.a, ins.b), GetDestination(ins.a), (x, y) => (ushort) (x & y));
                    break;

                case 0xa:
                    DoBinaryOp(ResolveSources(ins.a, ins.b), GetDestination(ins.a), (x, y) => (ushort) (x | y));
                    break;

                case 0xb:
                    DoBinaryOp(ResolveSources(ins.a, ins.b), GetDestination(ins.a), (x, y) => (ushort) (x ^ y));
                    break;

                case 0xc:
                    ShouldSkipNextIf(ResolveSources(ins.a, ins.b), (x, y) => (x != y));
                    break;

                case 0xd:
                    ShouldSkipNextIf(ResolveSources(ins.a, ins.b), (x, y) => (x == y));
                    break;

                case 0xe:
                    ShouldSkipNextIf(ResolveSources(ins.a, ins.b), (x, y) => (x <= y));
                    break;

                case 0xf:
                    ShouldSkipNextIf(ResolveSources(ins.a, ins.b), (x, y) => (x & y) == 0);
                    break;

                default:
                    throw new NotImplementedException("Run");
            }

            return cost;
        }
        public Action<ushort> GetDestination(byte value, Instruction instruction)
        {
            ushort val;

            short offset = this.offsetProvider.GetOffset(instruction);

            switch (value)
            {
                case 0x0:
                    return v => this.registers.A = v;
                case 0x1:
                    return v => this.registers.B = v;
                case 0x2:
                    return v => this.registers.C = v;
                case 0x3:
                    return v => this.registers.X = v;
                case 0x4:
                    return v => this.registers.Y = v;
                case 0x5:
                    return v => this.registers.Z = v;
                case 0x6:
                    return v => this.registers.I = v;
                case 0x7:
                    return v => this.registers.J = v;

                case 0x08:
                    return v => this.ram.Ram[this.registers.A] = v;
                case 0x09:
                    return v => this.ram.Ram[this.registers.B] = v;
                case 0x0a:
                    return v => this.ram.Ram[this.registers.C] = v;
                case 0x0b:
                    return v => this.ram.Ram[this.registers.X] = v;
                case 0x0c:
                    return v => this.ram.Ram[this.registers.Y] = v;
                case 0x0d:
                    return v => this.ram.Ram[this.registers.Z] = v;
                case 0x0e:
                    return v => this.ram.Ram[this.registers.I] = v;
                case 0x0f:
                    return v => this.ram.Ram[this.registers.J] = v;

                case 0x10:
                    val = this.ram.Ram[this.registers.ProgramCounter + offset];
                    return v => this.ram.Ram[val + this.registers.A] = v;
                case 0x11:
                    val = this.ram.Ram[this.registers.ProgramCounter + offset];
                    return v => this.ram.Ram[val + this.registers.B] = v;
                case 0x12:
                    val = this.ram.Ram[this.registers.ProgramCounter + offset];
                    return v => this.ram.Ram[val + this.registers.C] = v;
                case 0x13:
                    val = this.ram.Ram[this.registers.ProgramCounter + offset];
                    return v => this.ram.Ram[val + this.registers.X] = v;
                case 0x14:
                    val = this.ram.Ram[this.registers.ProgramCounter + offset];
                    return v => this.ram.Ram[val + this.registers.Y] = v;
                case 0x15:
                    val = this.ram.Ram[this.registers.ProgramCounter + offset];
                    return v => this.ram.Ram[val + this.registers.Z] = v;
                case 0x16:
                    val = this.ram.Ram[this.registers.ProgramCounter + offset];
                    return v => this.ram.Ram[val + this.registers.I] = v;
                case 0x17:
                    val = this.ram.Ram[this.registers.ProgramCounter + offset];
                    return v => this.ram.Ram[val + this.registers.J] = v;

                case 0x1a:
                    return v => this.ram.Ram[--this.registers.StackPointer] = v;

                case 0x1b:
                    return v => this.registers.StackPointer = v;

                case 0x1c:
                    this.registers.ProgramCounterManipulated= true;
                    return v => this.registers.ProgramCounter = v;

                case 0x1d:
                    return v => this.registers.OverFlow = v;

                case 0x1e:
                    val = this.ram.Ram[this.registers.ProgramCounter + offset];
                    return v => this.ram.Ram[val] = v;

                case 0x1f:
                    return v => this.ram.Ram[this.registers.ProgramCounter + offset] = v;

                default:
                    throw new NotImplementedException("GetDestination");
            }
        }
Exemple #3
0
 private int GetCost(Instruction instruction)
 {
     return this.costCalculator.CalculateCost(instruction);
 }