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"); } }
private int GetCost(Instruction instruction) { return this.costCalculator.CalculateCost(instruction); }