Beispiel #1
0
        private void doInstr(byte command, uint target, out CPUBasic.eCPUErrors err)
        {
            err = eCPUError.NONE;

            bool isMemLocation = (CPUBasic.FLAG_MEM_OR_NUM & target) > 0;
            bool isJump = (CPUBasic.FLAG_JUMP_ADDRESS & target) > 0;
            bool isBitAccess = (CPUBasic.FLAG_BIT_ACCESS & target) > 0;
            uint len = (CPUBasic.FLAG_BITFIELD_VAL & target) >> 20;
            eMemRange witchMem = (CPUBasic.FLAG_MEM_MARKER & target) > 0 ? eMemRange.MARKER : eMemRange.NONE;
            witchMem = (CPUBasic.FLAG_MEM_OUTPUT & target) > 0 ? eMemRange.OUTPUT : witchMem;
            witchMem = (CPUBasic.FLAG_MEM_INPUT & target) > 0 ? eMemRange.INPUT : witchMem;

            if (isJump && witchMem != eMemRange.NONE)
                err = eCPUError.JUMP_AND_MEMORY;

            if (isMemLocation && isBitAccess && len > 15 || isMemLocation && isBitAccess && len < 0)
                err = eCPUError.BIT_OUT_OF_RANGE;

            if (isMemLocation && !isJump && !isBitAccess && len > 4 || isMemLocation && !isJump && !isBitAccess && len < 1) 
                err = eCPUError.MEM_LEN_OUT_OF_RANGE;

            if (isBitAccess && isJump)
                err = eCPUError.JUMP_AND_BITACCESS;

            if (err != eCPUError.NONE)
                return;

            int value = 0;
            if (isMemLocation)
                value = (int)(CPUBasic.FLAG_MEMADR & target);
            else
                value = (int)(CPUBasic.FLAG_CONSTVAL & target);

            eCPUCommands cmd = (eCPUCommands)command;
            switch (cmd)
            {
                case eCPUCommands.L:
                    m_iAkku1 = getValue(isMemLocation, isBitAccess, witchMem, value, (int)len);
                    break;

                case eCPUCommands.T:
                    setValue(isBitAccess, witchMem, value, (int)len, m_iAkku1);
                    break;

                case eCPUCommands.LN:
                    if (isBitAccess)
                    {
                        m_iAkku1 = 1 - getValue(isMemLocation, isBitAccess, witchMem, value, (int)len);
                    }
                    break;

                case eCPUCommands.R:
                    if (isBitAccess && m_iAkku1 == 1)
                    {
                        setValue(isBitAccess, witchMem, value, (int)len, 0);
                    }
                    break;

                case eCPUCommands.S:
                    if (isBitAccess && m_iAkku1 == 1)
                    {
                        setValue(isBitAccess, witchMem, value, (int)len, 1);
                    }
                    break;

                case eCPUCommands.E:
                    if (isBitAccess)
                    {
                        setValue(isBitAccess, witchMem, value, (int)len, m_iAkku1);
                    }
                    break;

                case eCPUCommands.EN:
                    if (isBitAccess)
                    {
                        setValue(isBitAccess, witchMem, value, (int)len, 1 - m_iAkku1);
                    }
                    break;

                case eCPUCommands.A:
                    if (isBitAccess)
                    {
                        m_iAkku2 = m_iAkku1;
                        m_iAkku1 = getValue(isMemLocation, isBitAccess, witchMem, value, (int)len);
                        m_iAkku1 = m_iAkku1 & m_iAkku2;
                    }
                    break;

                case eCPUCommands.O:
                    if (isBitAccess)
                    {
                        m_iAkku2 = m_iAkku1;
                        m_iAkku1 = getValue(isMemLocation, isBitAccess, witchMem, value, (int)len);
                        m_iAkku1 = m_iAkku1 | m_iAkku2;
                    }
                    break;

                case eCPUCommands.AN:
                    if (isBitAccess)
                    {
                        m_iAkku2 = m_iAkku1;
                        m_iAkku1 = 1 - getValue(isMemLocation, isBitAccess, witchMem, value, (int)len);
                        m_iAkku1 = m_iAkku1 & m_iAkku2;
                    }
                    break;

                case eCPUCommands.ON:
                    if (isBitAccess)
                    {
                        m_iAkku2 = m_iAkku1;
                        m_iAkku1 = 1 - getValue(isMemLocation, isBitAccess, witchMem, value, (int)len);
                        m_iAkku1 = m_iAkku1 | m_iAkku2;
                    }
                    break;

                case eCPUCommands.XOR:
                    if (isBitAccess)
                    {
                        m_iAkku2 = m_iAkku1;
                        m_iAkku1 = 1 - getValue(isMemLocation, isBitAccess, witchMem, value, (int)len);
                        m_iAkku1 = m_iAkku1 ^ m_iAkku2;
                    }
                    break;

                case eCPUCommands.JA:
                    if (isJump)
                    {
                        if (len == 1)
                        {
                            m_iLoopInstrAddress = value * CPUBasic.INSTR_SIZE + (m_iInstrBase);
                            m_iInstrPointer = m_byaInstrMemory.Length - 1;
                            m_bLoop = true;
                            break;
                        }
                        m_iInstrPointer = value * CPUBasic.INSTR_SIZE + (m_iInstrBase - CPUBasic.INSTR_SIZE);
                    }
                    break;

                case eCPUCommands.JC:
                    if (isJump && m_iAkku1 == 1)
                    {
                        if (len == 1)
                        {
                            m_iLoopInstrAddress = value * CPUBasic.INSTR_SIZE + (m_iInstrBase);
                            m_iInstrPointer = m_byaInstrMemory.Length - 1;
                            m_bLoop = true;
                            break;
                        }
                        m_iInstrPointer = value * CPUBasic.INSTR_SIZE + (m_iInstrBase - CPUBasic.INSTR_SIZE);
                    }
                    break;

                case eCPUCommands.JCN:
                    if (isJump && m_iAkku1 == 0)
                    {
                        if (len == 1)
                        {
                            m_iLoopInstrAddress = value * CPUBasic.INSTR_SIZE + (m_iInstrBase);
                            m_iInstrPointer = m_byaInstrMemory.Length - 1;
                            m_bLoop = true;
                            break;
                        }
                        m_iInstrPointer = value * CPUBasic.INSTR_SIZE + (m_iInstrBase - CPUBasic.INSTR_SIZE);
                    }
                    break;

                case eCPUCommands.SET:
                    m_iAkku1 = 1;
                    break;

                case eCPUCommands.NOP:
                    // nothing to do empty command
                    break;

                default:
                    err = eCPUError.UNKOWN_CMD;
                    break;
            }

            m_iInstrPointer += CPUBasic.INSTR_SIZE;
        }
Beispiel #2
0
        private int getValueMem(bool isBit, CPUBasic.eMemRange range, int targetVal, int bitfield)
        {
            int akkuVal = 0;
            switch (range)
            {
                case CPUBasic.eMemRange.MARKER:
                    if (isBit)
                    {
                        akkuVal = m_byaMarkerMemory[targetVal] & CPUBasic.BITVALUES[bitfield];
                    }
                    else
                    {
                        for (int i = 0; i < bitfield; i++)
                        {
                            akkuVal |= m_byaMarkerMemory[targetVal + i] << (i * 8);
                        }
                    }
                    break;

                case CPUBasic.eMemRange.OUTPUT:
                    if (isBit)
                    {
                        akkuVal = m_byaOutputMemory[targetVal] & CPUBasic.BITVALUES[bitfield];
                    }
                    else
                    {
                        for (int i = 0; i < bitfield; i++)
                        {
                            akkuVal |= m_byaOutputMemory[targetVal + i] << (i * 8);
                        }
                    }
                    break;

                case CPUBasic.eMemRange.INPUT:
                    if (isBit)
                    {
                        akkuVal = m_byaInputMemory[targetVal] & CPUBasic.BITVALUES[bitfield];
                    }
                    else
                    {
                        for (int i = 0; i < bitfield; i++)
                        {
                            akkuVal |= m_byaInputMemory[targetVal + i] << (i * 8);
                        }
                    }
                    break;
            }

            return akkuVal;
        }