コード例 #1
0
 public void set(BCD10 b)
 {
     for (int i = 0; i < DIGITS; i++)
     {
         digits[i] = b.digits[i];
     }
 }
コード例 #2
0
    private byte toTapeCode(BCD10 bcd10)
    {
        byte c     = 0;
        bool isOdd = false;

        switch (bcd10.digits[8])
        {
        default:
            break;

        case 4:
            c    += 1;
            isOdd = !isOdd;
            break;

        case 5:
        case 6:
        case 7:
        case 8:
            c    += 2;
            isOdd = !isOdd;
            break;

        case 9:
            c += 3;
            break;
        }
        switch (bcd10.digits[9])
        {
        default:
            break;

        case 1:
        case 6:
            c    += 4;
            isOdd = !isOdd;
            break;

        case 2:
        case 7:
            c    += 8;
            isOdd = !isOdd;
            break;

        case 3:
        case 8:
            c += 12;
            break;
        }

        if ((!isOdd && bcd10.digits[9] < 5) || (isOdd && bcd10.digits[9] >= 5))
        {
            c += 16;
        }
        return(c);
    }
コード例 #3
0
 public void setNumber(BCD10 b)
 {
     if (!b.isEqual(lastDisplayed))
     {
         for (int i = 0; i < 10; i++)
         {
             nixies[9 - i].setNumber(b.digits[i]);
         }
     }
     lastDisplayed.set(b);
 }
コード例 #4
0
 public bool isEqual(BCD10 bcd10)
 {
     for (int i = 0; i < DIGITS; i++)
     {
         if (digits[i] != bcd10.digits[i])
         {
             return(false);
         }
     }
     return(true);
 }
コード例 #5
0
 private void setPC(BCD10 addr)
 {
     if (isPrimaryInput)
     {
         primaryInputPC = (int)addr.toUInt64();
     }
     else
     {
         accumulators[controlRegister].set(addr);
     }
 }
コード例 #6
0
    private void processOrder0()
    {
        BCD10 b;

        if (accB > 0)
        {
            effectiveOperand.add(accumulators[accB]);
        }
        if (accA == 0)
        {
            accumulators[0].set(controlBoxScript.getKeyboard());
        }

        b = new BCD10(effectiveOperand);
        if (siriusOpcodeLow >= 5)
        {
            b.shiftLeft(4);
        }

        switch (siriusOpcodeLow)
        {
        case 0:
        case 5:
            accumulators[accA].add(b);
            flagOVR |= BCD10.flagOVR;
            break;

        case 1:
        case 6:
            accumulators[accA].sub(b);
            flagOVR |= BCD10.flagOVR;
            break;

        case 2:
        case 7:
            accumulators[accA].negSub(b);
            flagOVR |= BCD10.flagOVR;
            break;

        case 3:
        case 8:
            accumulators[accA].negAdd(b);
            flagOVR |= BCD10.flagOVR;
            break;

        case 4:
        case 9:
            accumulators[accA].set(b);
            break;
        }
    }
コード例 #7
0
    public void negSub(BCD10 b)
    {
        int  c           = 0;
        bool wasNegative = isNegative();

        for (int i = 0; i < DIGITS; i++)
        {
            int n = 20 - digits[i] - b.digits[i] - c;
            c         = 2 - n / 10;
            digits[i] = (byte)(n % 10);
        }
        flagOVR = ((!wasNegative && !b.isNegative() && !isNegative()) ||
                   (wasNegative && b.isNegative() && isNegative()));
    }
コード例 #8
0
    public void add(BCD10 b)
    {
        int  c           = 0;
        bool wasNegative = isNegative();

        for (int i = 0; i < DIGITS; i++)
        {
            int n = digits[i] + b.digits[i] + c;
            c         = n / 10;
            digits[i] = (byte)(n % 10);
        }
        flagOVR = ((wasNegative && b.isNegative() && !isNegative()) ||
                   (!wasNegative && !b.isNegative() && isNegative()));
    }
コード例 #9
0
    public BCD10 getKeyboard()
    {
        BCD10 result = new BCD10();

        for (int i = 0; i < 10; i++)
        {
            int n = pressed[i];
            if (n < 0)
            {
                n = 0;
            }
            result.digits[9 - i] = (byte)n;
        }
        return(result);
    }
コード例 #10
0
 // Start is called before the first frame update
 void Start()
 {
     nixies        = new NixieScript[10];
     nixies[0]     = nixieScript0;
     nixies[1]     = nixieScript1;
     nixies[2]     = nixieScript2;
     nixies[3]     = nixieScript3;
     nixies[4]     = nixieScript4;
     nixies[5]     = nixieScript5;
     nixies[6]     = nixieScript6;
     nixies[7]     = nixieScript7;
     nixies[8]     = nixieScript8;
     nixies[9]     = nixieScript9;
     lastDisplayed = new BCD10();
 }
コード例 #11
0
    private void updateDisplay()
    {
        indicatorPIScript.setState(isPrimaryInput);
        indicatorOVRScript.setState(flagOVR);
        indicator99WScript.setState(isStopped99);
        indicatorKSScript.setState(isStoppedKB);
        indicator6910Script.setState(isStopped6910);
        indicatorRBScript.setState(isRBusy);
        indicatorPBScript.setState(isPBusy);
        indicatorMSDScript.setState(accumulators[accA].digits[9] != 0);
        indicatorNZScript.setState(!accumulators[accA].isZero());
        indicatorSBScript.setState(accumulators[accA].isNegative());
        {
            int s = speedWheelScript.getValue();
            if (s > 5)
            {
                indicatorNFSScript.setSpecial();
            }
            else
            {
                indicatorNFSScript.setState(s < 5);
            }
        }

        int a = lastDisplayed;

        if (!isRetryingForFrame)
        {
            a             = controlBoxScript.selectedAccumulator();
            lastDisplayed = a;
        }

        BCD10 displayed = new BCD10();

        displayed.digits[0] = accB;
        displayed.digits[1] = accA;
        displayed.digits[2] = siriusOpcodeLow;
        displayed.digits[3] = siriusOpcodeHigh;
        for (int i = 0; i < 6; i++)
        {
            displayed.digits[i + 4] = effectiveOperand.digits[i];
        }

        displayScript0.setNumber(displayed);

        accumulators[0].set(accumulators[a]);
        displayScript1.setNumber(accumulators[0]);
    }
コード例 #12
0
    private bool division(BCD10 b, BCD10 c, BCD10 d) // Divide (b, c) by d. Return true if the quotient >= 1
    {
        div_remainder = new byte[20];
        div_quotient  = new byte[10];

        for (int i = 0; i < 10; i++)
        {
            div_remainder[i + 10] = b.digits[i];
        }
        for (int i = 0; i < 10; i++)
        {
            div_remainder[i] = c.digits[i];
        }
        for (int i = 0; i < 10; i++)
        {
            div_quotient[i] = 0;
        }

        multDivCycles = 22;

        if (sub20(div_remainder, d.digits, 10))
        {
            return(true);
        }

        for (int s = 9; s >= 0; s--)
        {
            for (int i = 0; i < 10; i++)
            {
                if (sub20(div_remainder, d.digits, s))
                {
                    div_quotient[s]++;
                }
                else
                {
                    break;
                }
            }
        }

        for (int i = 0; i < 10; i++)
        {
            multDivCycles += (uint)div_quotient[i] * 2;
        }

        return(false);
    }
コード例 #13
0
    private void mult(BCD10 b, BCD10 c, bool negate)
    {
        mult_result = new int[20];
        int carry;

        multDivCycles = 22;
        for (int i = 0; i < 10; i++)
        {
            multDivCycles += (uint)b.digits[i] * 2;
        }

        for (int i = 0; i < 10; i++)
        {
            for (int j = 0; j < 10; j++)
            {
                mult_result[i + j] += b.digits[i] * c.digits[j];
            }
        }

        carry = 0;
        for (int i = 0; i < 20; i++)
        {
            mult_result[i] += carry;
            carry           = mult_result[i] / 10;
            mult_result[i]  = mult_result[i] % 10;
        }
        if (negate)
        {
            carry = 0;
            for (int i = 0; i < 20; i++)
            {
                int n = 10 - mult_result[i] - carry;
                carry          = 1 - n / 10;
                mult_result[i] = n % 10;
            }
        }
    }
コード例 #14
0
    private void processOrder5()
    {
        BCD10 a = new BCD10();

        if (accA == 0)
        {
            a.set(controlBoxScript.getKeyboard());
        }
        else
        {
            a.set(accumulators[accA]);
        }

        if (accB > 0)
        {
            effectiveOperand.add(accumulators[accB]);
        }

        switch (siriusOpcodeLow)
        {
        case 0:     // DUMMY
            break;

        case 1:
            if (a.msd() != 0)
            {
                setPC(effectiveOperand);
            }
            break;

        case 2:
            if (!a.isZero())
            {
                setPC(effectiveOperand);
            }
            break;

        case 3:
            if (flagOVR)
            {
                setPC(effectiveOperand);
            }
            flagOVR = false;
            break;

        case 4:
            if (a.isNegative())
            {
                setPC(effectiveOperand);
            }
            break;

        case 5:
            setPC(effectiveOperand);
            break;

        case 6:
            if (a.msd() == 0)
            {
                setPC(effectiveOperand);
            }
            break;

        case 7:
            if (a.isZero())
            {
                setPC(effectiveOperand);
            }
            break;

        case 8:
            if (!flagOVR)
            {
                setPC(effectiveOperand);
            }
            flagOVR = false;
            break;

        case 9:
            if (!a.isNegative())
            {
                setPC(effectiveOperand);
            }
            break;
        }
    }
コード例 #15
0
 public BCD10(BCD10 b)
 {
     digits = new byte[DIGITS];
     set(b);
 }
コード例 #16
0
    private void processOrder3()
    {
        BCD10 b           = new BCD10();
        bool  wasNegative = accumulators[accA].isNegative();
        bool  shiftOVR;
        byte  msdB;

        shiftOVR = (accumulators[accA].digits[9] != 0 && accumulators[accA].digits[9] != 9);

        if (siriusOpcodeLow < 5)
        {
            if (accB > 0)
            {
                effectiveOperand.add(accumulators[accB]);
            }
            b.setHex64(getMainStore(effectiveOperand.toUInt64()));
            if (accA == 0)
            {
                accumulators[0].set(controlBoxScript.getKeyboard());
            }
            flagOVR |= shiftOVR | (wasNegative != accumulators[accA].isNegative());
        }
        else
        {
            if (accB == 0)
            {
                b.set(controlBoxScript.getKeyboard());
            }
            else
            {
                b.set(accumulators[accB]);
            }
        }

        msdB = b.msd(); // in case accA = accB ...

        for (int i = 9; i > 0; i--)
        {
            accumulators[accA].digits[i] = accumulators[accA].digits[i - 1];
        }
        accumulators[accA].digits[0] = 0;

        switch (siriusOpcodeLow)
        {
        case 0:
            accumulators[accA].add(b);
            flagOVR |= BCD10.flagOVR;
            break;

        case 1:
            accumulators[accA].sub(b);
            flagOVR |= BCD10.flagOVR;
            break;

        case 2:
            accumulators[accA].negSub(b);
            flagOVR |= BCD10.flagOVR;
            break;

        case 3:
            accumulators[accA].negAdd(b);
            flagOVR |= BCD10.flagOVR;
            break;

        case 4:
            accumulators[accA].digits[0] = msdB;
            break;

        case 5:
            accumulators[accA].add(b);
            break;

        case 6:
            accumulators[accA].sub(b);
            break;

        case 7:
            accumulators[accA].negSub(b);
            break;

        case 8:
            accumulators[accA].negAdd(b);
            break;

        case 9:
            accumulators[accA].digits[0] = msdB;
            break;
        }
    }
コード例 #17
0
    private void processOrder2()
    {
        BCD10 b;
        bool  wasNegative;

        if (accB > 0)
        {
            effectiveOperand.add(accumulators[accB]);
        }
        if (accA == 0)
        {
            accumulators[0].set(controlBoxScript.getKeyboard());
        }

        b = new BCD10(effectiveOperand);
        if (siriusOpcodeLow >= 5)
        {
            b.shiftLeft(4);
        }
        wasNegative = accumulators[accA].isNegative();

        flagOVR |= (accumulators[accA].digits[9] != 0 && accumulators[accA].digits[9] != 9);

        for (int i = 9; i > 0; i--)
        {
            accumulators[accA].digits[i] = accumulators[accA].digits[i - 1];
        }
        accumulators[accA].digits[0] = 0;

        flagOVR |= (wasNegative != accumulators[accA].isNegative());

        switch (siriusOpcodeLow)
        {
        case 0:
        case 5:
            accumulators[accA].add(b);
            flagOVR |= BCD10.flagOVR;
            break;

        case 1:
        case 6:
            accumulators[accA].sub(b);
            flagOVR |= BCD10.flagOVR;
            break;

        case 2:
        case 7:
            accumulators[accA].negSub(b);
            flagOVR |= BCD10.flagOVR;
            break;

        case 3:
        case 8:
            accumulators[accA].negAdd(b);
            flagOVR |= BCD10.flagOVR;
            break;

        case 4:
        case 9:
            accumulators[accA].digits[0] = b.digits[9];
            break;
        }
    }
コード例 #18
0
// Start is called before the first frame update
    void Start()
    {
        accumulators = new BCD10[10]; // accumulators[0] holds content to be displayed, not 0.
        for (int i = 0; i < 10; i++)
        {
            accumulators[i] = new BCD10();
        }

        currentOrder     = new BCD10();
        siriusOperand    = new BCD6();
        effectiveOperand = new BCD10();

        mainStore = new UInt64[mainStoreSize];

        primaryInputMicroProgram = new UInt64[] {
            0x0000007140L, 0x0000065440L, 0x0000001544L, 0x0000001544L, 0x0000003954L,
            0x0000005500L, 0x0000006051L, 0x0000010010L, 0x0000007140L, 0x0000025940L,
            0x0000009900L
        };

        mask66_68 = new byte[, ] // in the order: N+b, a
        {
            { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
            { 0, 0, 2, 2, 4, 5, 5, 7, 7, 9 },
            { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
            { 0, 0, 0, 0, 4, 5, 5, 5, 5, 9 },
            { 0, 0, 0, 0, 0, 5, 5, 5, 5, 5 },
            { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
            { 0, 0, 2, 2, 4, 5, 5, 7, 7, 9 },
            { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
            { 0, 0, 0, 0, 4, 5, 5, 5, 5, 9 }
        };
        mask65_67 = new byte[, ] // in the order: N+b, a
        {
            { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
            { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 1, 0, 1, 0, 0, 1, 0, 1, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 1, 2, 3, 0, 0, 1, 2, 3, 0 },
            { 0, 1, 2, 3, 4, 0, 1, 2, 3, 4 },
            { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 1, 0, 1, 0, 0, 1, 0, 1, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 1, 2, 3, 0, 0, 1, 2, 3, 0 }
        };

        cycleTimes = new float[]
        {
            0.00008f, 0.00008f, 0.00008f, 0.00008f, 0.00008f,
            0.00008f,
            0.00004f, 0.00002f, 0.00001f, 0.000005f, 0.0000025f
        };
        cycleFactors = new uint[]
        {
            4167, 2083, 1042, 100, 10,
            1,
            1, 1, 1, 1, 1
        };

        cycleTime          = cycleTimes[5];
        cycleFactor        = cycleFactors[5];
        isPrimaryInput     = false;
        isStopped99        = false;
        isStoppedByError   = false;
        isStoppedKB        = false;
        isStopped6910      = false;
        isRetrying         = false;
        isRetryingForFrame = false;
        isWaitingR         = false;
        isWaitingP         = false;
        isRBusy            = false; // only when no tape
        isPBusy            = false; // always false
        flagOVR            = false;

        flagInputAccepted = false;

        delayLinePos = 0;
        timeLeft     = 0.0f;
    }
コード例 #19
0
    private void processOrder1()
    {
        BCD10 b = new BCD10();

        if (siriusOpcodeLow < 5)
        {
            if (accB > 0)
            {
                effectiveOperand.add(accumulators[accB]);
            }
            b.setHex64(getMainStore(effectiveOperand.toUInt64()));
            if (accA == 0)
            {
                accumulators[0].set(controlBoxScript.getKeyboard());
            }
        }
        else
        {
            if (accB == 0)
            {
                b.set(controlBoxScript.getKeyboard());
            }
            else
            {
                b.set(accumulators[accB]);
            }
        }

        switch (siriusOpcodeLow)
        {
        case 0:
            accumulators[accA].add(b);
            flagOVR |= BCD10.flagOVR;
            break;

        case 1:
            accumulators[accA].sub(b);
            flagOVR |= BCD10.flagOVR;
            break;

        case 2:
            accumulators[accA].negSub(b);
            flagOVR |= BCD10.flagOVR;
            break;

        case 3:
            accumulators[accA].negAdd(b);
            flagOVR |= BCD10.flagOVR;
            break;

        case 4:
            accumulators[accA].set(b);
            break;

        case 5:
            accumulators[accA].add(b);
            break;

        case 6:
            accumulators[accA].sub(b);
            break;

        case 7:
            accumulators[accA].negSub(b);
            break;

        case 8:
            accumulators[accA].negAdd(b);
            break;

        case 9:
            accumulators[accA].set(b);
            break;
        }
    }
コード例 #20
0
    private void processOrder7()
    {
        BCD10 bcd0, bcd1;
        bool  negate;

        if (accB > 0)
        {
            effectiveOperand.add(accumulators[accB]);
        }

        switch (siriusOpcodeLow)
        {
        case 1:
        case 6:
            readInputChannel();
            break;

        case 2:
        case 7:
            writeOutputChannel();
            break;

        case 3:
        case 8:
            if (!isRetrying || isWaitingR)
            {
                readInputChannel();
            }
            if (!isWaitingR)
            {
                writeOutputChannel();
            }
            break;

        case 4:     // accB=0: KB
            // displayed operand: 0?
            negate = false;

            if (accB == 0)
            {
                accumulators[accB].set(controlBoxScript.getKeyboard());
            }
            if (accumulators[accB].isNegative())
            {
                bcd0   = new BCD10(0);
                negate = !negate;
                bcd0.sub(accumulators[accB]);
            }
            else
            {
                bcd0 = new BCD10(accumulators[accB]);
            }
            mult(bcd0, accumulators[9], negate);
            for (int i = 0; i < 10; i++)
            {
                accumulators[9].digits[i] = (byte)mult_result[i];
            }
            for (int i = 0; i < 10; i++)
            {
                accumulators[accA].digits[i] = (byte)mult_result[i + 10];
            }
            break;

        case 9:
            // displayed operand: 0?
            negate = false;

            if (accB == 0)
            {
                accumulators[accB].set(controlBoxScript.getKeyboard());
            }
            if (accumulators[accB].isNegative())
            {
                bcd0   = new BCD10(0);
                negate = !negate;
                bcd0.sub(accumulators[accB]);
            }
            else
            {
                bcd0 = new BCD10(accumulators[accB]);
            }
            if (accumulators[9].isNegative())
            {
                bcd1   = new BCD10(0);
                negate = !negate;
                bcd1.sub(accumulators[9]);
            }
            else
            {
                bcd1 = new BCD10(accumulators[9]);
            }
            mult(bcd0, bcd1, negate);
            for (int i = 0; i < 10; i++)
            {
                accumulators[9].digits[i] = (byte)mult_result[i];
            }
            for (int i = 0; i < 10; i++)
            {
                accumulators[accA].digits[i] = (byte)mult_result[i + 10];
            }
            break;

        case 0:
            flagOVR |= division(accumulators[accA], accumulators[9], accumulators[accB]);
            flagOVR |= (div_quotient[9] >= 5);
            for (int i = 0; i < 10; i++)
            {
                accumulators[9].digits[i] = div_quotient[i];
            }
            for (int i = 0; i < 10; i++)
            {
                accumulators[accA].digits[i] = div_remainder[i];
            }
            break;

        case 5:
            flagOVR |= division(accumulators[accA], accumulators[9], accumulators[accB]);
            for (int i = 0; i < 10; i++)
            {
                accumulators[9].digits[i] = div_quotient[i];
            }
            for (int i = 0; i < 10; i++)
            {
                accumulators[accA].digits[i] = div_remainder[i];
            }
            break;
        }
        if (siriusOpcodeLow == 0 || siriusOpcodeLow == 4 || siriusOpcodeLow == 5 || siriusOpcodeLow == 9)
        {
            addCycles(multDivCycles * cycleFactor);
        }
    }
コード例 #21
0
// Update is called once per frame
    void Update()
    {
        bool flagInterrupt = false;

        // flagContinue is not reset, as it might be from the end of Primary Input.

        kbValue = controlBoxScript.getKeyboard();

        cycleTime   = cycleTimes[speedWheelScript.getValue()];
        cycleFactor = cycleFactors[speedWheelScript.getValue()];

        if (isPrimaryInput)
        {
            timeLeft          += Time.deltaTime;
            isRetryingForFrame = isRetrying;

            while (isPrimaryInput && timeLeft > 0.0f)
            {
                processOneOrder();
            }
        }
        else
        {
            if (controlBoxScript.flagContinueKey)
            {
                flagContinue = true;
                controlBoxScript.flagContinueKey = false;
            }

            if (!isRetryingForFrame)
            {
                runPressed    = controlBoxScript.flagRun;
                manualPressed = controlBoxScript.flagManual;
                kbWaitPressed = controlBoxScript.flagKBWait;

                if (controlBoxScript.flagInterruptKey)
                {
                    flagInterrupt = true;
                    controlBoxScript.flagInterruptKey = false;
                }
                if (controlBoxScript.flagClearControlKey)
                {
                    controlBoxScript.flagClearControlKey = false;
                    if (!runPressed)
                    {
                        accumulators[controlRegister].setUInt64(0);
                    }
                }
            }

            if (manualPressed)
            {
                if (!isRetryingForFrame)
                {
                    if (controlBoxScript.flagPrimaryInputKey)
                    {
                        controlBoxScript.flagPrimaryInputKey = false;
                        isPrimaryInput = true;
                        primaryInputPC = 0;
                    }
                    if (controlBoxScript.flagAcceptInputKey)
                    {
                        controlBoxScript.flagAcceptInputKey = false;
                        flagInputAccepted = true;
                        acceptedInput     = new BCD10(kbValue);
                    }
                }

                isRetryingForFrame = isRetrying;

                if (flagContinue)
                {
                    flagContinue = false;
                    processOneOrder();
                }
                timeLeft = 0.0f;
            }
            else
            {
                isRetryingForFrame = isRetrying;

                if (flagInterrupt)
                {
                    setMainStore_forced(1, accumulators[controlRegister].toHex64());
                    accumulators[controlRegister].setUInt64(2);
                }
                else
                {
                    if (flagContinue)
                    {
                        flagContinue = false;
                        if (!runPressed)
                        {
                            processOneOrder();
                        }
                        isStopped99      = false;
                        isStoppedKB      = false;
                        isStopped6910    = false;
                        isStoppedByError = false;
                        timeLeft         = 0.0f;
                    }
                    else
                    {
                        if (runPressed)
                        {
                            timeLeft += Time.deltaTime;

                            while ((!isStopped99 && !isStoppedKB && !isStopped6910 && !isStoppedByError) &&
                                   timeLeft > 0.0f)
                            {
                                processOneOrder();
                            }
                        }
                        else
                        {
                            timeLeft = 0.0f;
                        }
                    }
                }
            }
        }

        updateDisplay();
    }