Esempio n. 1
0
        // Schrittweise Ausführung des Programms
        public bool Step(int frequenz)
        {
            if (PCCounter >= befehle.Count)
            {
                return(true);
            }

            PICBefehl aktueller_befehl = befehle[PCCounter];

            if (TaktgeberAktiviert)
            {
                TaktgeberZahler += frequenz;
                if (TaktgeberZahler >= TaktgeberFrequenz)
                {
                    if (TaktgeberAdresse == ADDR_PORT_A)
                    {
                        var wert = SetBit(GetRegisterOhneBank(TaktgeberAdresse), TaktgeberBitnummer, !GetRegisterOhneBank(TaktgeberAdresse, TaktgeberBitnummer));

                        var ta = Register[ADDR_TRIS_A];

                        if (GetBit(ta, TaktgeberBitnummer))
                        {
                            Latch_RA = (byte)(wert & 0xFF);
                            Register[ADDR_PORT_A] = wert;
                        }
                    }
                    else if (TaktgeberAdresse == ADDR_PORT_B)
                    {
                        var wert = SetBit(GetRegisterOhneBank(TaktgeberAdresse), TaktgeberBitnummer, !GetRegisterOhneBank(TaktgeberAdresse, TaktgeberBitnummer));

                        var tb = Register[ADDR_TRIS_B];

                        if (GetBit(tb, TaktgeberBitnummer))
                        {
                            Latch_RB = (byte)(wert & 0xFF);
                            Register[ADDR_PORT_B] = wert;
                        }
                    }
                    else
                    {
                        SetRegisterOhneBank(TaktgeberAdresse, TaktgeberBitnummer, !GetRegisterOhneBank(TaktgeberAdresse, TaktgeberBitnummer));
                    }

                    TaktgeberZahler = 0;
                }
            }

            if (IsSleeping)
            {
                WatchDog.Aktualisieren(1); return(false);
            }

            uint cycleCount = 1;

            if (aktueller_befehl.befehl == ADDWF)
            {
                // Add the contents of the W register with
                // register 'f'.If 'd' is 0 the result is stored
                // in the W register.If 'd' is 1 the result is
                // stored back in register 'f'.

                byte a = GetRegister(aktueller_befehl.parameter_f);
                byte b = Register_W;

                uint Result = (uint)(a + b);
                bool dc     = AdditionDigitCarry(a, b);

                SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_Z, (Result % 0x100) == 0);
                SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_DC, dc);
                SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_C, Result > 0xFF);

                Result %= 0x100;

                if (aktueller_befehl.parameter_d != 0)
                {
                    SetRegister(aktueller_befehl.parameter_f, (byte)Result);
                }
                else
                {
                    Register_W = (byte)Result;
                }
            }
            else if (aktueller_befehl.befehl == ANDWF)
            {
                // AND the W register with register 'f'.If 'd'
                // is 0 the result is stored in the W regis -
                // ter.If 'd' is 1 the result is stored back in
                // register 'f'

                byte Result = (byte)(Register_W & GetRegister(aktueller_befehl.parameter_f));

                SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_Z, Result == 0);

                if (aktueller_befehl.parameter_d != 0)
                {
                    SetRegister(aktueller_befehl.parameter_f, Result);
                }
                else
                {
                    Register_W = Result;
                }
            }
            else if (aktueller_befehl.befehl == CLRF)
            {
                // The contents of register 'f' are cleared
                // and the Z bit is set.

                SetRegister(aktueller_befehl.parameter_f, 0x00);
                SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_Z, true);
            }
            else if (aktueller_befehl.befehl == CLRW)
            {
                // W register is cleared.Zero bit (Z) is
                // set.

                Register_W = 0;
                SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_Z, true);
            }
            else if (aktueller_befehl.befehl == COMF)
            {
                // The contents of register 'f' are comple-
                // mented.If 'd' is 0 the result is stored in
                // W.If 'd' is 1 the result is stored back in
                // register 'f'.

                byte Result = (byte)~GetRegister(aktueller_befehl.parameter_f);

                SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_Z, Result == 0);

                if (aktueller_befehl.parameter_d != 0)
                {
                    SetRegister(aktueller_befehl.parameter_f, Result);
                }
                else
                {
                    Register_W = Result;
                }
            }
            else if (aktueller_befehl.befehl == DECF)
            {
                // Decrement register 'f'.If 'd' is 0 the
                // result is stored in the W register.If 'd' is
                // 1 the result is stored back in register 'f'.

                uint Result = GetRegister(aktueller_befehl.parameter_f);

                if (Result == 0)
                {
                    Result = 0xFF;
                }
                else
                {
                    Result -= 1;
                }

                SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_Z, Result == 0);

                if (aktueller_befehl.parameter_d != 0)
                {
                    SetRegister(aktueller_befehl.parameter_f, Result);
                }
                else
                {
                    Register_W = (byte)Result;
                }
            }
            else if (aktueller_befehl.befehl == DECFSZ)
            {
                // The contents of register 'f' are decre-
                // mented.If 'd' is 0 the result is placed in the
                // W register.If 'd' is 1 the result is placed
                // back in register 'f'.
                // If the result is 1, the next instruction, is
                // executed.If the result is 0, then a NOP is
                // executed instead making it a 2T CY instruc -
                // tion.

                bool Cond = GetRegister(aktueller_befehl.parameter_f) == 1;

                uint Result = GetRegister(aktueller_befehl.parameter_f);

                if (Result == 0)
                {
                    Result = 0xFF;
                }
                else
                {
                    Result -= 1;
                }

                if (aktueller_befehl.parameter_d != 0)
                {
                    SetRegister(aktueller_befehl.parameter_f, Result);
                }
                else
                {
                    Register_W = (byte)Result;
                }

                if (Cond)
                {
                    PCCounter++;                     // skip next
                    cycleCount = 2;
                }
            }
            else if (aktueller_befehl.befehl == INCF)
            {
                // The contents of register 'f' are incre-
                // mented.If 'd' is 0 the result is placed in
                // the W register.If 'd' is 1 the result is
                // placed back in register 'f'.

                uint Result = GetRegister(aktueller_befehl.parameter_f);

                Result += 1;

                Result %= 0x100;

                SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_Z, Result == 0);

                if (aktueller_befehl.parameter_d != 0)
                {
                    SetRegister(aktueller_befehl.parameter_f, Result);
                }
                else
                {
                    Register_W = (byte)Result;
                }
            }
            else if (aktueller_befehl.befehl == INCFSZ)
            {
                // The contents of register 'f' are incre-
                // mented.If 'd' is 0 the result is placed in
                // the W register.If 'd' is 1 the result is
                // placed back in register 'f'.
                // If the result is 1, the next instruction is
                // executed.If the result is 0, a NOP is exe -
                // cuted instead making it a 2T CY instruc -
                // tion

                bool Cond = GetRegister(aktueller_befehl.parameter_f) == 0xFF;

                uint Result = GetRegister(aktueller_befehl.parameter_f);

                Result += 1;

                Result %= 0x100;

                if (aktueller_befehl.parameter_d != 0)
                {
                    SetRegister(aktueller_befehl.parameter_f, Result);
                }
                else
                {
                    Register_W = (byte)Result;
                }

                if (Cond)
                {
                    PCCounter++;                     // skip next
                    cycleCount = 2;
                }
            }
            else if (aktueller_befehl.befehl == IORWF)
            {
                // Inclusive OR the W register with regis -
                // ter 'f'.If 'd' is 0 the result is placed in the
                // W register.If 'd' is 1 the result is placed
                // back in register 'f'.

                byte Result = (byte)(Register_W | GetRegister(aktueller_befehl.parameter_f));

                SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_Z, Result == 0);

                if (aktueller_befehl.parameter_d != 0)
                {
                    SetRegister(aktueller_befehl.parameter_f, Result);
                }
                else
                {
                    Register_W = Result;
                }
            }
            else if (aktueller_befehl.befehl == MOVF)
            {
                // The contents of register f is moved to a
                // destination dependant upon the status
                // of d. If d = 0, destination is W register. If
                // d = 1, the destination is file register f
                // itself.d = 1 is useful to test a file regis-
                // ter since status flag Z is affected.

                uint Result = GetRegister(aktueller_befehl.parameter_f);

                SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_Z, Result == 0);

                if (aktueller_befehl.parameter_d != 0)
                {
                    SetRegister(aktueller_befehl.parameter_f, Result);
                }
                else
                {
                    Register_W = (byte)Result;
                }
            }
            else if (aktueller_befehl.befehl == MOVWF)
            {
                // Move data from W register to register
                // 'f'

                SetRegister(aktueller_befehl.parameter_f, Register_W);
            }
            else if (aktueller_befehl.befehl == NOP)
            {
                //No operation.
            }
            else if (aktueller_befehl.befehl == RLF)
            {
                // The contents of register 'f' are rotated
                // one bit to the left through the Carry
                // Flag.If 'd' is 0 the result is placed in the
                // W register.If 'd' is 1 the result is stored
                // back in register 'f'.

                uint Result = GetRegister(aktueller_befehl.parameter_f);

                uint Carry_Old = GetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_C) ? 1u : 0u;
                uint Carry_New = (Result & 0x80) >> 7;

                Result  = Result << 1;
                Result &= 0xFF;

                Result |= Carry_Old;

                SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_C, Carry_New != 0);

                if (aktueller_befehl.parameter_d != 0)
                {
                    SetRegister(aktueller_befehl.parameter_f, Result);
                }
                else
                {
                    Register_W = (byte)Result;
                }
            }
            else if (aktueller_befehl.befehl == RRF)
            {
                // The contents of register 'f' are rotated
                // one bit to the right through the Carry
                // Flag.If 'd' is 0 the result is placed in the
                // W register.If 'd' is 1 the result is placed
                // back in register 'f'.

                uint Result = GetRegister(aktueller_befehl.parameter_f);

                uint Carry_Old = GetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_C) ? 0x80u : 0x00u;
                uint Carry_New = Result & 0x01;

                Result  = Result >> 1;
                Result &= 0xFF;

                Result |= Carry_Old;

                SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_C, Carry_New != 0);

                if (aktueller_befehl.parameter_d != 0)
                {
                    SetRegister(aktueller_befehl.parameter_f, Result);
                }
                else
                {
                    Register_W = (byte)Result;
                }
            }
            else if (aktueller_befehl.befehl == SUBWF)
            {
                // Subtract(2’s complement method) W reg-
                // ister from register 'f'.If 'd' is 0 the result is
                // stored in the W register.If 'd' is 1 the
                // result is stored back in register 'f'.

                uint a = GetRegister(aktueller_befehl.parameter_f);
                uint b = Register_W;

                bool carry = (a + ((~b) & 0xFF)) > 0xFF;

                bool dc = SubtractionDigitCarry((byte)a, (byte)b);

                if (a < b)
                {
                    a += 0x100;
                }

                uint Result = a - b;

                SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_Z, (Result % 0x100) == 0);
                SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_DC, dc);
                SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_C, carry);

                Result %= 0x100;

                if (aktueller_befehl.parameter_d != 0)
                {
                    SetRegister(aktueller_befehl.parameter_f, Result);
                }
                else
                {
                    Register_W = (byte)Result;
                }
            }
            else if (aktueller_befehl.befehl == SWAPF)
            {
                // The upper and lower nibbles of register
                // 'f' are exchanged. If 'd' is 0 the result is
                // placed in W register. If 'd' is 1 the result
                // is placed in register 'f'.

                uint Result = GetRegister(aktueller_befehl.parameter_f);

                uint Low  = Result & 0x0F;
                uint High = Result & 0xF0;

                Result = (Low << 4) | (High >> 4);

                if (aktueller_befehl.parameter_d != 0)
                {
                    SetRegister(aktueller_befehl.parameter_f, Result);
                }
                else
                {
                    Register_W = (byte)Result;
                }
            }
            else if (aktueller_befehl.befehl == XORWF)
            {
                // Exclusive OR the contents of the W
                // register with register 'f'.If 'd' is 0 the
                // result is stored in the W register.If 'd' is
                // 1 the result is stored back in register 'f'.

                byte Result = (byte)(Register_W ^ GetRegister(aktueller_befehl.parameter_f));

                SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_Z, Result == 0);

                if (aktueller_befehl.parameter_d != 0)
                {
                    SetRegister(aktueller_befehl.parameter_f, Result);
                }
                else
                {
                    Register_W = Result;
                }
            }
            else if (aktueller_befehl.befehl == BCF)
            {
                // Bit 'b' in register 'f' is cleared

                SetRegister(aktueller_befehl.parameter_f, aktueller_befehl.parameter_b, false);
            }
            else if (aktueller_befehl.befehl == BSF)
            {
                // Bit 'b' in register 'f' is set.

                SetRegister(aktueller_befehl.parameter_f, aktueller_befehl.parameter_b, true);
            }
            else if (aktueller_befehl.befehl == BTFSC)
            {
                // If bit 'b' in register 'f' is '1' then the next
                // instruction is executed.
                // If bit 'b', in register 'f', is '0' then the next
                // instruction is discarded, and a NOP is
                // executed instead, making this a 2T CY
                // instruction

                if (!GetBit(GetRegister(aktueller_befehl.parameter_f), aktueller_befehl.parameter_b))
                {
                    PCCounter++;
                    cycleCount = 2;
                }
            }
            else if (aktueller_befehl.befehl == BTFSS)
            {
                // If bit 'b' in register 'f' is '0' then the next
                // instruction is executed.
                // If bit 'b' is '1', then the next instruction is
                // discarded and a NOP is executed
                // instead, making this a 2T CY instruction.

                if (GetBit(GetRegister(aktueller_befehl.parameter_f), aktueller_befehl.parameter_b))
                {
                    PCCounter++;
                    cycleCount = 2;
                }
            }
            else if (aktueller_befehl.befehl == ADDLW)
            {
                // The contents of the W register are
                // added to the eight bit literal 'k' and the
                // result is placed in the W register

                uint a = Register_W;
                uint b = aktueller_befehl.parameter_k;

                uint Result = a + b;
                bool dc     = AdditionDigitCarry((byte)a, (byte)b);

                SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_Z, (Result % 0x100) == 0);
                SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_DC, dc);
                SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_C, Result > 0xFF);

                Result %= 0x100;

                Register_W = (byte)Result;
            }
            else if (aktueller_befehl.befehl == ANDLW)
            {
                // The contents of W register are
                // AND’ed with the eight bit literal 'k'.The
                // result is placed in the W register

                uint Result = Register_W & aktueller_befehl.parameter_k;

                SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_Z, Result == 0);

                Register_W = (byte)Result;
            }
            else if (aktueller_befehl.befehl == CALL)
            {
                // Call Subroutine. First, return address
                // (PC + 1) is pushed onto the stack. The
                // eleven bit immediate address is loaded
                // into PC bits<10:0 >.The upper bits of
                // the PC are loaded from PCLATH.CALL
                // is a two cycle instruction.

                Stack.Push((uint)PCCounter);
                PCCounter  = (int)(aktueller_befehl.parameter_k - 1);
                cycleCount = 2;
            }
            else if (aktueller_befehl.befehl == CLRWDT)
            {
                // CLRWDT instruction resets the Watch -
                // dog Timer.It also resets the prescaler
                // of the WDT. Status bits TO and PD are
                // set.

                WatchDog.Reset();

                if (GetRegisterOhneBank(ADDR_OPTION, OPTION_BIT_PSA))
                {
                    SetRegisterOhneBank(ADDR_OPTION, OPTION_BIT_PS0, false);
                    SetRegisterOhneBank(ADDR_OPTION, OPTION_BIT_PS1, false);
                    SetRegisterOhneBank(ADDR_OPTION, OPTION_BIT_PS2, false);
                }

                SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_TO, true);
                SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_PD, true);
            }
            else if (aktueller_befehl.befehl == GOTO)
            {
                // GOTO is an unconditional branch.The
                // eleven bit immediate value is loaded
                // into PC bits<10:0>.The upper bits of
                // PC are loaded from PCLATH<4:3>.
                // GOTO is a two cycle instruction.

                PCCounter  = befehle.FindIndex(b => b.labelnummer == aktueller_befehl.parameter_k) - 1;
                cycleCount = 2;
            }
            else if (aktueller_befehl.befehl == IORLW)
            {
                // The contents of the W register is
                // OR’ed with the eight bit literal 'k'.The
                // result is placed in the W register

                uint Result = Register_W | aktueller_befehl.parameter_k;

                SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_Z, Result == 0);

                Register_W = (byte)Result;
            }
            else if (aktueller_befehl.befehl == MOVLW)
            {
                // The eight bit literal 'k' is loaded into W
                // register.The don’t cares will assemble
                // as 0’s.

                Register_W = (byte)aktueller_befehl.parameter_k;
            }
            else if (aktueller_befehl.befehl == RETFIE)
            {
                // Return from Interrupt.Stack is POPed
                // and Top of Stack(TOS) is loaded in the
                // PC.Interrupts are enabled by setting
                // Global Interrupt Enable bit, GIE
                // (INTCON < 7 >).This is a two cycle
                // instruction.

                PCCounter = (int)Stack.Pop();
                SetRegisterOhneBank(ADDR_INTCON, INTCON_BIT_GIE, true);
                cycleCount = 2;
            }
            else if (aktueller_befehl.befehl == RETLW)
            {
                // The W register is loaded with the eight
                // bit literal 'k'.The program counter is
                // loaded from the top of the stack(the
                // return address). This is a two cycle
                // instruction.
                Register_W = (byte)aktueller_befehl.parameter_k;
                PCCounter  = (int)Stack.Pop();
                cycleCount = 2;
            }
            else if (aktueller_befehl.befehl == RETURN)
            {
                // Return from subroutine. The stack is
                // POPed and the top of the stack(TOS)
                // is loaded into the program counter.This
                // is a two cycle instruction.
                PCCounter  = (int)Stack.Pop();
                cycleCount = 2;
            }
            else if (aktueller_befehl.befehl == SLEEP)
            {
                // The power-down status bit, PD is
                // cleared.Time -out status bit, TO is
                // set.Watchdog Timer and its prescaler
                // are cleared.
                // The processor is put into SLEEP
                // mode with the oscillator stopped. See
                // Section 14.8 for more details.

                if (GetRegisterOhneBank(ADDR_OPTION, OPTION_BIT_PSA))
                {
                    SetRegisterOhneBank(ADDR_OPTION, OPTION_BIT_PS0, false);
                    SetRegisterOhneBank(ADDR_OPTION, OPTION_BIT_PS1, false);
                    SetRegisterOhneBank(ADDR_OPTION, OPTION_BIT_PS2, false);
                }

                SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_TO, true);
                SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_PD, false);

                IsSleeping = true;
            }
            else if (aktueller_befehl.befehl == SUBLW)
            {
                // The W register is subtracted (2’s comple-
                // ment method) from the eight bit literal 'k'.
                // The result is placed in the W register.

                uint a = aktueller_befehl.parameter_k;
                uint b = Register_W;

                bool carry;

                bool dc = SubtractionDigitCarry((byte)a, (byte)b);

                if (carry = a < b)
                {
                    a += 0x100;
                }

                uint Result = a - b;

                SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_Z, (Result % 0x100) == 0);
                SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_DC, dc);
                SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_C, !carry);

                Result %= 0x100;

                Register_W = (byte)Result;
            }
            else if (aktueller_befehl.befehl == XORLW)
            {
                // The contents of the W register are
                // XOR’ed with the eight bit literal 'k'.
                // The result is placed in the W regis -
                // ter.

                uint Result = Register_W ^ aktueller_befehl.parameter_k;

                SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_Z, Result == 0);

                Register_W = (byte)Result;;
            }

            PCCounter++;
            Stepcount++;

            Zaehler.TimerBerechnen(cycleCount);

            WatchDog.Aktualisieren(cycleCount);

            if (Merker_RB0 != Register[ADDR_PORT_B])
            {
                Interrupt_RB(Merker_RB0, Register[ADDR_PORT_B]);
                Merker_RB0 = Register[ADDR_PORT_B];
            }

            return(PCCounter >= befehle.Count);
        }
Esempio n. 2
0
        // Befehlserkunng anhand bitweisem Vergleich
        private PICBefehl FindeBefehl(string zeile, int zeilennummer)
        {
            foreach (var cmd in ALL_COMMANDS)
            {
                string bin = hex2binary(zeile.Substring(5, 4));

                uint p_d = 0;
                uint p_f = 0;
                uint p_x = 0;
                uint p_k = 0;
                uint p_b = 0;

                bool ok = true;

                for (int i = 0; i < 14; i++)                 //Jeder befehl wird durchgegangen und über AND wird geschaut ob der Befehl und der Code identisch sind
                {
                    if (cmd[i] == '0' && bin[i] == '0')
                    {
                        continue;
                    }
                    if (cmd[i] == '1' && bin[i] == '1')
                    {
                        continue;
                    }
                    if (cmd[i] == 'd' && bin[i] == '0')
                    {
                        p_d <<= 1; p_d |= 0; continue;
                    }
                    if (cmd[i] == 'd' && bin[i] == '1')
                    {
                        p_d <<= 1; p_d |= 1; continue;
                    }
                    if (cmd[i] == 'f' && bin[i] == '0')
                    {
                        p_f <<= 1; p_f |= 0; continue;
                    }
                    if (cmd[i] == 'f' && bin[i] == '1')
                    {
                        p_f <<= 1; p_f |= 1; continue;
                    }
                    if (cmd[i] == 'x' && bin[i] == '0')
                    {
                        p_x <<= 1; p_x |= 0; continue;
                    }
                    if (cmd[i] == 'x' && bin[i] == '1')
                    {
                        p_x <<= 1; p_x |= 1; continue;
                    }
                    if (cmd[i] == 'k' && bin[i] == '0')
                    {
                        p_k <<= 1; p_k |= 0; continue;
                    }
                    if (cmd[i] == 'k' && bin[i] == '1')
                    {
                        p_k <<= 1; p_k |= 1; continue;
                    }
                    if (cmd[i] == 'b' && bin[i] == '0')
                    {
                        p_b <<= 1; p_b |= 0; continue;
                    }
                    if (cmd[i] == 'b' && bin[i] == '1')
                    {
                        p_b <<= 1; p_b |= 1; continue;
                    }
                    if (cmd[i] == '0' && bin[i] == '1')
                    {
                        ok = false; break;
                    }
                    if (cmd[i] == '1' && bin[i] == '0')
                    {
                        ok = false; break;
                    }

                    throw new Exception("Falscher wert in cmd");
                }

                if (ok)
                {
                    PICBefehl b = new PICBefehl();
                    b.befehl       = cmd;
                    b.parameter_d  = p_d;
                    b.parameter_f  = p_f;
                    b.parameter_k  = p_k;
                    b.parameter_x  = p_x;
                    b.parameter_b  = p_b;
                    b.zeilennummer = zeilennummer;
                    b.labelnummer  = Convert.ToInt32(zeile.Substring(0, 4), 16);
                    return(b);
                }
            }

            throw new Exception("konnte befehl nicht finden: " + zeile);
        }