private void writeOutputChannel() { if (effectiveOperand.toUInt64() % 10 == 0) { isWaitingP = !tapePunchScript.punch(toTapeCode(accumulators[accA])); } if (effectiveOperand.toUInt64() % 10 == 1) { isWaitingP = !printerScript.print(toTapeCode(accumulators[accA])); } isRetrying = isWaitingP; }
public void processOneOrder() { opCode = (byte)(currentOrder >> 12); isLongWord = ((currentOrder & 0x800) != 0); operand = (UInt16)(currentOrder & 0x7ff); switch (opCode) { case 1: // t if (isLongWord) { storeLongWord(operand, regA); } else { storeShortWord(operand, regA >> 18); } addCycles(8); break; case 3: // o { byte b = (byte)(regA >> 30); if (!printerScript.print(b)) { regK = operand; regX = readShortWord(regK); } addCycles(4); } break; case 6: // n loadWord(isLongWord, operand); regA = (((1L << 36) - regM) & 0xfffffffffL); addCycles(4); break; case 9: // l { UInt16 i; if (operand < 1024) { i = operand; if (i > 128) { i = 128; } if (isLongWord) { for (int j = 0; j < i; j++) { regA = ((regA << 1) & (bit_36 - 1)); regA |= ((regR & bit_34) >> 34); regR = regR - (regR & bit_34); regR = (regR << 1) - (regR & bit_35); } } else { regA = ((regA << i) & (bit_36 - 1)); } } else { i = (UInt16)(2048 - operand); if (i > 128) { i = 128; } if (isLongWord) { for (int j = 0; j < i; j++) { regR = (regR >> 1) + (regR & bit_35); regR |= ((regA & 1) << 34); regA = (regA >> 1); } } else { regA = (regA >> i); } } addCycles((UInt16)(6 + i)); } break; case 10: // r { UInt16 i; if (operand < 1024) { i = operand; if (i > 128) { i = 128; } if (isLongWord) { bool b = ((regA & bit_35) != 0); for (int j = 0; j < i; j++) { regR = (regR >> 1) + (regR & bit_35); regR |= ((regA & 1) << 34); regA = (regA >> 1); if (b) { regA |= bit_35; } } } else { bool b = ((regA & bit_35) != 0); for (int j = 0; j < i; j++) { regA = (regA >> 1); if (b) { regA |= bit_35; } } } } else { i = (UInt16)(2048 - operand); if (i > 128) { i = 128; } if (isLongWord) { for (int j = 0; j < i; j++) { regA = ((regA << 1) & (bit_36 - 1)); regA |= ((regR & bit_34) >> 34); regR = regR - (regR & bit_34); regR = (regR << 1) - (regR & bit_35); } } else { regA = ((regA << i) & (bit_36 - 1)); } } addCycles((UInt16)(6 + i)); } break; case 12: // i if (isLongWord) { Debug.Log("jl: Unused"); } else { byte b = printerScript.readTape(); if (b == 0xff) { regK = operand; regX = readShortWord(regK); addCycles(10); } else { regA = ((UInt64)b) << 30; addCycles(4); } } break; case 13: // p loadWord(isLongWord, operand); regA = regM; addCycles(4); break; case 14: // c loadWord(isLongWord, operand); regA = (regA & regM); addCycles(4); break; case 15: // v loadWord(isLongWord, operand); { UInt64 signOfM, signOfA; regR = regA; regA = 0; signOfM = ((regM & bit_35) << 1); signOfA = 0; for (int i = 0; i < 35; i++) { if ((regR & 1) != 0) { regA = (((regA | signOfA) + (regM | signOfM)) & 0x1fffffffffL); } else { regA = (regA | signOfA); } regR = (regR >> 1); regR |= ((regA & 1) << 35); signOfA = (regA & bit_36); regA = (regA >> 1); } if ((regR & 1) != 0) { regA = ((regA - regM) & 0xfffffffffL); } regR = (regR >> 1); } if (isLongWord) { addCycles(44); } else { addCycles(26); } break; case 17: // z if (isLongWord) { if (regA == 0) { regK = operand; regX = readShortWord(regK); } } else { if ((regA & (0x7ffL << 18)) == 0) { regK = operand; regX = readShortWord(regK); } } addCycles(11); break; case 18: // d loadWord(isLongWord, operand); { bool aWasNegative, mIsNegative; bool overflow = false; regR = (regR - (regR & bit_35)) << 1; aWasNegative = ((regA & bit_35) != 0); mIsNegative = ((regM & bit_35) != 0); for (int i = 0; i < 36; i++) { if (aWasNegative == mIsNegative) { regA = ((regA - regM) & 0xfffffffffL); regR |= 1; } else { regA = ((regA + regM) & 0xfffffffffL); } aWasNegative = ((regA & bit_35) != 0); regA = (regA << 1) & 0xfffffffffL; regA |= ((regR & bit_35) >> 35); regR = (regR - (regR & bit_35)) << 1; } overflow = (((regA & 1) != 0) == ((regR & bit_35) != 0)); regA = (regA >> 1); if (aWasNegative) { regA = regA | bit_35; } regR |= 1; // Debug.Log(Convert.ToString((long)regA, 2) + "," + Convert.ToString((long)regR, 2)); if (aWasNegative) { if (mIsNegative) { regA = ((regA - regM) & 0xfffffffffL); regR = ((regR + 1) & 0xfffffffffL); } else { regA = ((regA + regM) & 0xfffffffffL); regR = ((regR - 1) & 0xfffffffffL); } } UInt64 tmp = regA; regA = regR; regR = tmp; if (overflow) { isStopped = true; Debug.Log("Overflow"); } } addCycles(161); break; case 19: // b loadWord(isLongWord, operand); regA = (regA ^ regM); addCycles(4); break; case 20: // s loadWord(isLongWord, operand); regA = ((regA - regM) & 0xfffffffffL); addCycles(4); break; case 21: // y if (operand == 31 && playSound) { if (isLongWord) { audioPulses.Enqueue(new Tuple <uint, bool>(elapsedCycles, false)); } else { audioPulses.Enqueue(new Tuple <uint, bool>(elapsedCycles, true)); } } addCycles(4); break; case 23: // x if (isLongWord) { Debug.Log("xl: Unused"); } else { UInt64 w = readShortWord(operand); w = (w & 0x3f800L) | ((regA >> 18) & 0x7ffL); storeShortWord(operand, w); } addCycles(8); break; case 24: // a loadWord(isLongWord, operand); regA = ((regA + regM) & 0xfffffffffL); addCycles(4); break; case 25: // w loadWord(isLongWord, operand); if (isLongWord) { UInt64 tmp = regR; UInt64 signOfM, signOfA; regR = regA; regA = tmp; signOfM = ((regM & bit_35) << 1); signOfA = 0; for (int i = 0; i < 35; i++) { if ((regR & 1) != 0) { regA = (((regA | signOfA) + (regM | signOfM)) & 0x1fffffffffL); } else { regA = (regA | signOfA); } regR = (regR >> 1); regR |= ((regA & 1) << 35); signOfA = (regA & bit_36); regA = (regA >> 1); } if ((regR & 1) != 0) { regA = ((regA - regM) & 0xfffffffffL); } regR = (regR >> 1); addCycles(44); } else { UInt64 tmp = regR; UInt64 signOfM, signOfA; regR = regA; regA = tmp; signOfM = ((regM & bit_35) << 1); signOfA = 0; for (int i = 0; i < 17; i++) { if ((regR & bit_18) != 0) { regA = (((regA | signOfA) + (regM | signOfM)) & 0x1fffffffffL); } regR = (regR >> 1); regR |= ((regA & 1) << 35); signOfA = (regA & bit_36); regA = (regA >> 1); } if ((regR & bit_18) != 0) { regA = ((regA - regM) & 0xfffffffffL); } regR = ((regR >> 1) & (bit_35 - bit_18)); addCycles(26); } break; case 26: // j if (isLongWord) { regK = operand; regX = readShortWord(regK); } else { Debug.Log("Unused: j"); } addCycles(4); break; case 29: // q loadWord(isLongWord, operand); regA = regR; regR = regM; addCycles(4); break; case 30: // k if (isLongWord) { if ((regA & bit_35) == 0) { regK = operand; regX = readShortWord(regK); } } else { if ((regA & bit_35) != 0) { regK = operand; regX = readShortWord(regK); } } addCycles(8); break; default: Debug.Log("UnImplemented, K=" + regK); Debug.Log("op: " + opCode + ", long: " + isLongWord + ", operand: " + operand); isStopped = true; break; } }