private void opMUL(operand b, operand a) { ushort _a = readValue(a); ushort _b = readValue(b); writeValue(b, (ushort)(_b * _a)); _EX = (ushort)(((_b * _a) >> 16) & 0xffff); }
private void opREAD(operand b, operand a) { var value = Executor.Read(); Console.WriteLine(value.ToString()); ushort _b = readValue(b); writeValue(b, (ushort) value); }
private void Tick() { //TODO _Cycles++; if (_state == ProcessorState.newInst) { Tick_inst = nextWord(); Tick_opcode = (ushort)(Tick_inst & (ushort)0x001fu); Tick_b = (ushort)((Tick_inst & (ushort)0x03e0u) >> 5); Tick_a = (ushort)((Tick_inst & (ushort)0xfc00u) >> 10); _state = ProcessorState.readOpA; _CycleDebt = operandCycles(Tick_a); if (_CycleDebt > 0) return; } if (_state == ProcessorState.readOpA) { Tick_opA = parseOperand(Tick_a); if (Tick_opcode == 0) // Non-basic opcodes { _state = ProcessorState.executeInst; } else { _CycleDebt = operandCycles(Tick_b); _state = ProcessorState.readOpB; } if (_CycleDebt > 0) return; } if (_state == ProcessorState.readOpB) { Tick_opB = parseOperand(Tick_b); _state = ProcessorState.executeInst; _CycleDebt = opcodeCycles(Tick_a, Tick_opcode); if (_CycleDebt > 0) return; } if (_state == ProcessorState.executeInst) { if (Tick_opcode == 0) // Non-basic opcodes { //TODO: DICTIONARY switch (Tick_b) { case 0x01: opJSR(Tick_opA); break; case 0x08: opINT(Tick_opA); break; case 0x09: opIAG(Tick_opA); break; case 0x0a: opIAS(Tick_opA); break; case 0x0b: opRFI(Tick_opA); break; case 0x0c: opIAQ(Tick_opA); break; } } else // Basic opcodes { new Operation(Actions[Tick_opcode]).Invoke(Tick_opB, Tick_opA); } _state = ProcessorState.newInst; return; } }
private void opASR(operand b, operand a) { short _a = (short)readValue(a); short _b = (short)readValue(b); writeValue(b, (ushort)(_b >> _a)); _EX = (ushort)(((_b << 16) >> _a) & 0xffff); }
//sets b to a, then increases I and J by 1 private void opSTI(operand b, operand a) { ushort _a = readValue(a); ushort _b = readValue(b); uint v = (uint)(_b - _a + _EX); writeValue(b, _a); _Register[_I] = (ushort)(_Register[_I] + 0x0001u); _Register[_J] = (ushort)(_Register[_J] + 0x0001u); }
private void opXOR(operand b, operand a) { ushort _a = readValue(a); ushort _b = readValue(b); writeValue(b, (ushort)(_b ^ _a)); }
//performs next instruction only if b!=a private void opIFN(operand b, operand a) { ushort _a = readValue(a); ushort _b = readValue(b); if (!(_b != _a)) skipNext(); }
private void opSET(operand b, operand a) { ushort _a = readValue(a); ushort _b = readValue(b); writeValue(b, _a); }
//sets IA to a private void opIAS(operand a) { ushort _a = readValue(a); _IA = _a; }
//performs next instruction only if (b&a)==0 private void opIFC(operand b, operand a) { ushort _a = readValue(a); ushort _b = readValue(b); if (!((_b & _a) == 0)) skipNext(); }
/* * if a is nonzero, interrupts will be added to the queue instead of triggered. if a is zero, interrupts will be triggered as normal again */ private void opIAQ(operand a) { ushort _a = readValue(a); _IntEnabled = (_a == 0); }
//sets a to IA private void opIAG(operand a) { ushort _a = readValue(a); writeValue(a, _IA); }
private void opDVI(operand b, operand a) { short _a = (short)readValue(a); short _b = (short)readValue(b); if (_a == 0) { writeValue(b, 0); } else { writeValue(b, (ushort)(_b / _a)); _EX = (ushort)(((_b << 16) / _a) & 0xffff); } }
//disables interrupt queueing, pops A from the stack, then pops PC from the stack private void opRFI(operand a) { ushort _a = readValue(a); _Register[_A] = stackPOP(); _PC = stackPOP(); _IntEnabled = true; }
//performs next instruction only if b<a (signed) private void opIFU(operand b, operand a) { short _a = (short)readValue(a); short _b = (short)readValue(b); if (!(_b < _a)) skipNext(); }
//sets b to b-a+EX, sets EX to 0xFFFF if there is an under flow, 0x0001 if there's an overflow, 0x0 otherwise private void opSBX(operand b, operand a) { ushort _a = readValue(a); ushort _b = readValue(b); uint v = (uint)(_b - _a + _EX); writeValue(b, (ushort)(v & 0xffffu)); if (v > 0x0000ffffu) _EX = (ushort)0xffffu; else _EX = (ushort)0x0000u; }
//triggers a software interrupt with message a private void opINT(operand a) { ushort _a = readValue(a); if (_IA == 0) return; _IntQueue.Enqueue(_a); }
private void opSHR(operand b, operand a) { ushort _a = readValue(a); ushort _b = readValue(b); writeValue(b, (ushort)(_b >> _a)); _EX = (ushort)(((_b << 16) >> _a) & 0xffff); }
/* * NON BASIC OPERATIONS */ //pushes the address of the next instruction to the stack, then sets PC to a private void opJSR(operand a) { ushort _a = readValue(a); stackPUSH(_PC); _PC = _a; }
private void opSUB(operand b, operand a) { ushort _a = readValue(a); ushort _b = readValue(b); writeValue(b, (ushort)(_b - _a)); if ((_b - _a) < 0) _EX = (ushort)0xffffu; }
private void opMLI(operand b, operand a) { short _a = (short)readValue(a); short _b = (short)readValue(b); writeValue(b, (ushort)(_b * _a)); _EX = (ushort)(((_b * _a) >> 16) & 0xffff); }
private ushort readValue(operand op) { if (op._type == operand.REG) return _Register[op._value]; if (op._type == operand.RAM) return _RAM[op._value]; if (op._type == operand.LIT) return op._value; if (op._type == operand.STK) return stackPOP(); switch (op._type) { case operand.PC: return _PC; case operand.SP: return _SP; case operand.EX: return _EX; } throw new Exception("Invalid op._type: " + op._type.ToString()); }
private void opMOD(operand b, operand a) { ushort _a = readValue(a); ushort _b = readValue(b); if (_a == 0) { writeValue(b, 0); } else { writeValue(b, (ushort)(_a % _b)); } }
private void writeValue(operand op, ushort data) { if (op._type == operand.REG) { _Register[op._value] = data; return; } if (op._type == operand.RAM) { _RAM[op._value] = data; return; } if (op._type == operand.LIT) { _RAM[op._value] = data; return; } if (op._type == operand.STK) { stackPUSH(data); return; } switch (op._type) { case operand.PC: _PC = data; return; case operand.SP: _SP = data; return; case operand.EX: _EX = data; return; } throw new Exception("Invalid op._type: " + op._type.ToString()); }
private void opADD(operand b, operand a) { ushort _a = readValue(a); ushort _b = readValue(b); writeValue(b, (ushort)(_b + _a)); if ((_b + _a) > 0xffff) _EX = (ushort)0x0001u; }