예제 #1
0
 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;
 }
예제 #2
0
    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;
        }
    }