=== FB 1178: MWeiche_Sorter_EP  [STL] ===
INTERFACE:
  Input:
    Weichen_Nr : Int                                    // Aufruf für Weiche
    KorrekturFaktor : Real
    ErrQuit : Bool                                      // Ablaufstörung quittieren
    Stau_Ausfahrtbereich : Bool                         // Ausfahrtsbereich hat Stau
    B_Gerade : Bool                                     // Kontroll-Sensor nach Weiche Gerade
    B_Ausfahrt : Bool                                   // Kontroll-Sensor nach Weiche Ausfahrt
    Antrieb_aktiv : Bool                                // Kreisel-Antrieb aktiv
  Output:
    Y_Weiche_abzweigen : Bool                           // Weiche auf Abzweig schalten
    Y_Weiche_geradeaus : Bool                           // Weiche auf Gerade schalten
    Error : Word                                        // Störungen übergeben
  InOut:
    Antrieb_start : Bool                                // Kreiselantrieb starten
    Antrieb_stoppen : Bool                              // Kreiselantrieb stoppen
    hStOk : Bool                                        // Anzeige Start n. Störung aktivieren
  Static:
    SAVE : Struct
      IDX_Flag : Bool                                   // Hauptstrang_DL +1 durchsuchen
      Kontroll_Flag : Bool                              // Hauptstrang_DL +1 durchsuchen
      Teil_IDX_Old : DInt                               // BT/MT-IDX (wurde bei Auslagerung gemeldet)
    Para : Struct                                       // Parameter
      Weichen_DL_DB : Int                               // Einsprung Weichen-Datenliste-DB
      Weichen_DL_DW : Int                               // Einsprung Weichen-Datenliste-DW
      Res : Array[1..3] of Int                          // Reserve
    Weiche : "UDLWeiche_Sorter"                         // Fahrbereichs Daten
    Dyn : Struct                                        // Dynamische Daten fürs Einfahren
      Status : Struct                                   // Status
        Schalttakte : DInt                              // Anzahl der getätigten Umschaltungen
        Strecke_gesperrt : Bool                         // Gefällestrecke ist gesperrt
        Strecke_voll : Bool                             // Gefällestrecke ist voll
        Weiche_abzweigen : Bool                         // Weiche auf Abzweig schalten
        Weiche_geradeaus : Bool                         // Weiche auf Gerade schalten
        TeachModus_aktiv : Bool                         // Teach-Modus ist aktiv
        Res45 : Bool
        Weichentest_aktiv : Bool                        // Testschaltung für Einfahrweiche aktiviert
        Reset : Bool := TRUE                            // Reset Einfahrseite starten
        Ziel_unbekannt : Bool                           // Ziel des BT ist unbekannt
      Rueckmld : Struct
        RET_VAL_BLKMOV_Weiche : Int                     // Rückmeldung nach BLKMOV-Aufruf
        RET_VAL_DL_Weichen : Byte                       // Rückmeldung nach DatenOut-Aufruf
        RET_VAL_Sortliste_Out : Byte                    // Rückmeldung nach Sortdaten-Out-Aufruf
        RET_VAL_SendFIFO : Byte                         // Rückmeldung nach SendPC_FIFO-Aufruf
      Error : "UErrWeiche_Sorter"
      Ink_Wert : DInt                                   // Aktueller Inkrementalwert
      Max_Wert : DInt                                   // Maximal erlaubter Zählwert
      Lauf_Flag : Bool                                  // Zähl-Lauf mit Flag ist aktiv
      Flag_Lauf_fertig : Bool                           // Flag-Lauf wurde beendet
      Ohne_Lauf_fertig : Bool                           // Ohne Flag-Lauf wurde beendet
      Hauptstrang_Flag : Bool                           // Flag zum Weiche schalten (vom Hauptstrang)
      Last_Flag : Bool                                  // Flag des letzten durchfahrenden Teils
      GSTschalt_Flag : Bool                             // Flag bei Weiche auf GST schalten
      Carr : Bool                                       // CARR-Telegramm muss noch gesendet werden
      Puffer_IDX : Bool                                 // Trolley-ID in Puffer eintragen
      Ohne_VerklemmKontrolle : Bool                     // Verklemmkontrolle ausschalten
      BM_raus : Bool                                    // BM wurde ausgeschleußt (1 Zyklus)
      BM_gerade : Bool                                  // BM wurde gerade gefahren (1 Zyklus)
      Max_raus : Bool                                   // Max_Wert wurde schon übertragen
      Hauptstrang_Ink : DInt                            // Inkremente zum Weiche schalten (vom Hauptstrang)
      Hauptstrang_Sortliste : Int                       // Sortliste aus welcher Hauptstrangdaten sind
      Hauptstrang_Search_Ink : DInt                     // Inkremente zum Daten auslesen (Start-Ink)
      Hauptstrang_Pos : Int                             // Aktuelle Position der Daten in Datenliste
      GSTschalt_Ink : DInt                              // Inkremente zum Weiche auf GST schalten
      Last_Ink : DInt                                   // Inkremente des letzten durchfahrenden Teils
      Last_IDX : DInt                                   // IDX des letzten durchfahrenden Teils
      FahrKontrolle : Struct
        Ohne_VerklemmKontrolle : Bool                   // Verklemmkontrolle ausschalten
        BT_Gerade : Bool                                // BM fährt geradeaus durch Weichenbereich
        BT_Ausfahrt : Bool                              // BM fährt aus Weichenbereich
        BM_Gerade_erkannt : Bool                        // Geradeausfahrendes BM wurde erkannt
        Gerade_Neg : Bool                               // Geradeaus: Kontroll-Time ist negativ
        BM_Ausfahrt_erkannt : Bool                      // Ausfahrendes BM wurde erkannt
        Ausfahrt_Neg : Bool                             // Ausfahrend: Kontroll-Time ist negativ
        Kontroll_Time_Gerade : Int                      // Innerhalb dieser Zeit muss BM Weiche gerade verlassen haben [100ms]
        Kontroll_Time_Ausfahrt : Int                    // Innerhalb dieser Zeit muss BM Weiche ausgefahren haben [100ms]
        Time_Ausfahrt : Int                             // Diese Zeit benötigt BM zum Ausfahren [100ms]
      Res128 : Array[1..1] of Int                       // Reserve
    Daten : "UBT_Daten"
    Kontroll_IDX : DInt                                 // IDX des zu kontollierenden Teils
    Res200 : Array[1..23] of Int                        // Reserve
  Temp:
    Quelle : Any                                        // Zeiger, wo Rein-Daten sind
    Ziel : Any                                          // Zeiger, FIFO-Stelle
    Del : Bool                                          // Nur Sortdaten löschen
    Error_SendFIFO : Bool
    FC86_Para : Word                                    // Parameter-Übergabe
    Hauptstrang_Ink : DInt                              // Inkremente zum Weiche schalten (vom Hauptstrang)
    Parameter : Word                                    // Parameter
    Freigabe : Int
    Carr_Ziel : Int                                     // Ziel, das bei Carr-Telegramm gemeldet wird
    DatenDB : Int                                       // DB öffnen
    sKorrekturFaktor : Real                             // Korrektur-Faktor wegen Kettenlängung
    AR1Start : DInt                                     // Startwert mit Offset 0
    AR1Zeiger : DWord                                   // Statt AR1 (ging nur bis DB-Länge <= 8191 Bytes)
  Constant:

--- NW 1: Parameter-Übergabe ---
      L      Weichen_Nr                                      // Aufruf-Parameter (für Baustein beobachten)

      L      "MW178"                                         // Einsprung Weichen-DL
      T      Para.Weichen_DL_DB                              // vor Aufruf übergeben!
      L      0
      T      Para.Weichen_DL_DW


--- NW 2: Eingangsvariablen einlesen ---
      L      KorrekturFaktor
      T      sKorrekturFaktor


--- NW 3: Für Inbetriebnahme ---
// Beim Teachen Weiche auf gerade:
      A      Dyn.Status.TeachModus_aktiv
      S      Y_Weiche_geradeaus                              // Weiche auf gerade schalten
      R      Y_Weiche_abzweigen
      R      Dyn.Status.Weiche_abzweigen                     // Weiche auf Abzweig schalten
      R      Dyn.Status.Weiche_geradeaus                     // Weiche auf Gerade schalten
      BEC

// Weichentest:
      AN     Dyn.Status.Weichentest_aktiv
      JC     en01

      A      "Clock_1Hz"
      =      Y_Weiche_abzweigen                              // Weiche zyklisch umschalten
      NEG
      =      Y_Weiche_geradeaus

      SET
      R      Dyn.Status.Weiche_abzweigen                     // Weiche auf Abzweig schalten
      R      Dyn.Status.Weiche_geradeaus                     // Weiche auf Gerade schalten

      BEU

en01: NOP 0


--- NW 4: Gesamt: Out-Bits zum Zurücksetzen ---
      SET
      R      Y_Weiche_abzweigen                              // Weiche auf Abzweig schalten
      R      Y_Weiche_geradeaus                              // Weiche auf gerade schalten
      R      Dyn.BM_raus                                     // BM wurde ausgeschleußt (1 Zyklus)
      R      Dyn.BM_gerade                                   // BM wurde gerade gefahren (1 Zyklus)


--- NW 5: Statische Weichen-Parameter holen ---
      L      Weiche.Weichen_Nr                               // Nummer der Weiche
      L      Weichen_Nr                                      // Aufruf-Parameter
      ==I                                                    // Identisch ?
      R      Dyn.Error.Weichen_DL                            // Weichendatenbank fehlerhaft
      R      Dyn.Error.Undef_Weiche                          // undefinierte Weiche
      JC     en06                                            // Ja !

      T      "MW200"                                         // Search-Daten

CALL FC "DatenOut" (SSDB:=Para.Weichen_DL_DB, SSDW:=Para.Weichen_DL_DW, PARA:=WORD#16#0000, SEARCHDATEN:=P#M200.0, RE_VAL:="MB199", OUTDATEN:=P#M220.0, Position:="MW196")

      L      "MB199"
      T      Dyn.Rueckmld.RET_VAL_DL_Weichen                 // Rückmeldung bei Datenbank-Zugriff (Gefälle-DL)

      JBI    G_Ok

      A      "M199.0"
      =      Dyn.Error.Weichen_DL                            // Weichendatenbank fehlerhaft
      BEC

      SET
      S      Dyn.Error.Undef_Weiche                          // undefinierte Weiche

      BEU

// Kennung + Datenbytes
G_Ok: SET
      R      Dyn.Error.Weichen_DL                            // Weichendatenbank fehlerhaft
      R      Dyn.Error.Undef_Weiche                          // undefinierte Weiche

      L      16#1004                                         // Kennung 10 + Word=04
      T      LW0                                             // Any-Kennung, Datentyp
      L      40                                              // Datenwords speichern
      T      LW2                                             // Wiederholungen

// Quelle-Pointer erzeugen:
      L      0                                               // Bei Merker = 0 !
      T      LW4                                             // DB_Nummer
      L      220                                             // Adresse
      SLD    3
      L      16#8300_0000                                    // Kennung: Merker
      OD
      T      LD6                                             // Kennung, Adresse

CALL SYS "BLKMOV" (SRCBLK:=Quelle, RET_VAL:=Dyn.Rueckmld.RET_VAL_BLKMOV_Weiche, DSTBLK:=Weiche)   // Datenliste-Daten speichern | #Ziel

      L      Dyn.Rueckmld.RET_VAL_BLKMOV_Weiche              // Rückmeldung
      L      0                                               // Fehler vorhanden ?
      <>I                                                    // Ja !
      =      Dyn.Error.BLKMov                                // Error bei Block kopieren
      BEC

      L      Weiche.Weichen_Typ                              // Weichentyp = 178 (Weiche)
      L      178                                             // Dieser Aufruf-FB ?
      ==I                                                    // Ja !
      JC     en06

      SET
      S      Dyn.Error.Undef_Weiche                          // undefinierte Weiche

      L      0                                               // Weiche ungültig !
      T      Weiche.Weichen_Nr                               // Nummer der Weiche

      BEU

en06: NOP 0


--- NW 6: 
 ---
      AN     Dyn.Status.Reset
      JC     En06_Mig

// Dyn.Daten löschen:
      SET
      R      Dyn.Status.Reset
      R      Dyn.Status.Strecke_voll
      R      Y_Weiche_abzweigen                              // Weiche auf Abzweig schalten
      S      Y_Weiche_geradeaus                              // Weiche auf gerade schalten
      R      Dyn.Status.Weichentest_aktiv
      R      Dyn.Hauptstrang_Flag
      R      Dyn.Last_Flag
      R      Dyn.FahrKontrolle.BT_Gerade                     // BM fährt geradeaus durch Weichenbereich
      R      Dyn.FahrKontrolle.BT_Ausfahrt                   // BM fährt aus Weichenbereich
      R      Dyn.FahrKontrolle.Gerade_Neg                    // Geradeaus: Kontroll-Time ist negativ
      R      Dyn.FahrKontrolle.Ausfahrt_Neg                  // Ausfahrend: Kontroll-Time ist negativ
// /      R     #Dyn.Ohne_VerklemmKontrolle //Verklemmkontrolle ausschalten
      R      Dyn.Max_raus                                    // Max_Wert wurde schon übertragen

      A      Weiche.Parameter.Weichen_GST_gerade
      =      Dyn.Status.Weiche_geradeaus
      A      Weiche.Parameter.Weichen_GST_abzweig
      AN     Weiche.Parameter.Weichen_GST_gerade
      =      Dyn.Status.Weiche_abzweigen

      L      0
      T      Dyn.Hauptstrang_Ink
      T      Dyn.Hauptstrang_Search_Ink
      T      Dyn.Last_Ink

      L      0
      T      Dyn.Hauptstrang_Sortliste
      T      Dyn.FahrKontrolle.Kontroll_Time_Gerade          // Innerhalb dieser Zeit muss BM Weiche verlassen haben [100ms]
      T      Dyn.FahrKontrolle.Kontroll_Time_Ausfahrt        // Innerhalb dieser Zeit muss BM Weiche ausgefahren haben [100ms]

      L      DINT#0
      T      Kontroll_IDX
      T      Dyn.Last_IDX

// Rückmeldungen löschen:
      L      0
      T      Dyn.Rueckmld.RET_VAL_DL_Weichen
      T      Dyn.Rueckmld.RET_VAL_BLKMOV_Weiche
      T      Dyn.Rueckmld.RET_VAL_Sortliste_Out

// Störungen löschen:
      SET
      R      Dyn.Error.Weichen_DL
      R      Dyn.Error.Undef_Weiche
      R      Dyn.Error.BLKMov
      R      Dyn.Error.Haupstrang_DL
      R      Dyn.Error.Haupstrang_DL_voll
      R      Dyn.Error.Keine_HSDaten
      R      Dyn.Error.Rein_FIFO
      R      Dyn.Error.Keine_FIFODaten
      R      Dyn.Error.Stau_AusfahrBereich
      R      Dyn.Error.BM_verklemmt_Gerade
      R      Dyn.Error.BM_verklemmt_Ausfahrt
      R      Dyn.Error.BM_undef_Gerade
      R      Dyn.Error.Frei14
      R      Dyn.Error.Send_FIFO_fehlerhaft                  // Send-FIFO zum PC ist fehlerhaft
      R      Dyn.Error.Send_FIFO_voll                        // Send-FIFO zu PC ist voll
      R      Dyn.Error.Reset_aktiv                           // Reset ist aktiv

      L      0                                               // Damit statische Werte neu aus Datenbank geholt werden !
      T      Weiche.Weichen_Nr                               // Nummer der Weiche

      BEU

En06_Mig: NOP 0


--- NW 7: Störungen nach Außen übergeben ---
      L      0
      T      "MB200"

      A      Dyn.Error.Weichen_DL                            // Weichen-Datenliste fehlerhaft
      =      "M200.0"
      A      Dyn.Error.Undef_Weiche                          // undefinierte Weiche
      =      "M200.1"
      A      Dyn.Error.BLKMov                                // Fehler bei Block kopieren
      =      "M200.2"
      A      Dyn.Error.Haupstrang_DL                         // Haupstrang-Datenliste fehlerhaft
      =      "M200.3"
      A      Dyn.Error.Haupstrang_DL_voll                    // Haupstrang-Datenliste ist voll
      =      "M200.4"
      A      Dyn.Error.Keine_HSDaten                         // Keine Hauptstrang-Daten mehr vorhanden
      =      "M200.5"
      A      Dyn.Error.Rein_FIFO                             // Rein-FIFO fehlerhaft
      =      "M200.6"
      A      Dyn.Error.Keine_FIFODaten                       // Keine Rein-Daten mehr vorhanden
      =      "M200.7"
      A      Dyn.Error.Stau_AusfahrBereich                   // Stau im Ausfahrbereich (-> Antrieb stoppen)
      =      "M201.0"
      A      Dyn.Error.BM_verklemmt_Gerade                   // BM bei Weiterfahrt in Weiche verklemmt (-> Antrieb stoppen)
      =      "M201.1"
      A      Dyn.Error.BM_verklemmt_Ausfahrt                 // BM bei Ausfahrt in Weiche verklemmt (-> Antrieb stoppen)
      =      "M201.2"
      A      Dyn.Error.BM_undef_Gerade                       // undefiniertes BM bei Weiterfahrt erkannt
      =      "M201.3"
      A      Dyn.Error.Frei14
      =      "M201.4"
      A      Dyn.Error.Send_FIFO_fehlerhaft                  // Send-FIFO zum PC ist fehlerhaft
      =      "M201.5"
      A      Dyn.Error.Send_FIFO_voll                        // Send-FIFO zu PC ist voll
      =      "M201.6"
      CLR                                                    // Reset ist aktiv (gibts nicht!)
      =      Dyn.Error.Reset_aktiv
      =      "M201.7"

      L      "MW200"
      T      Error                                           // Schnittstelle nach Außen

// Kreiselantrieb stoppen:
      AN     Stau_Ausfahrtbereich                            // Ausfahrtsbereich hat Stau
      R      Dyn.Error.Stau_AusfahrBereich                   // Stau im Ausfahrbereich (-> Antrieb stoppen)

// Antrieb stoppen:
      A(
      O      Dyn.Error.BM_verklemmt_Ausfahrt                 // BM bei Ausfahrt in Weiche verklemmt (-> Antrieb stoppen)
      O      Dyn.Error.BM_verklemmt_Gerade                   // BM bei Weiterfahrt in Weiche verklemmt (-> Antrieb stoppen)
      )
      AN     ErrQuit
      O      Dyn.Error.Stau_AusfahrBereich                   // Stau im Ausfahrbereich (-> Antrieb stoppen)
      O      Dyn.Error.Send_FIFO_fehlerhaft                  // Send-FIFO zum PC ist fehlerhaft
      O      Dyn.Error.Send_FIFO_voll                        // Send-FIFO zu PC ist voll
      S      Antrieb_stoppen                                 // Kreiselantrieb stoppen

// Anzeige Start n. Störung aktivieren:
      A      Dyn.Error.BM_verklemmt_Ausfahrt                 // BM bei Ausfahrt in Weiche verklemmt (-> Antrieb stoppen)
      O      Dyn.Error.BM_verklemmt_Gerade                   // BM bei Weiterfahrt in Weiche verklemmt (-> Antrieb stoppen)
      O      Dyn.Error.Stau_AusfahrBereich                   // Stau im Ausfahrbereich (-> Antrieb stoppen)
      S      hStOk


--- NW 8: Daten des Inkremental-Gebers holen / Zeit-Inkremente ---
      L      Weiche.Ink_DB                                   // DB-Nr des Inkremental-Geber
      L      0                                               // angegeben ?
      <=I                                                    // Nein !
      JC     w040

      CAC
      T      "MW200"
      OPN    DB["MW200"]                                     // Zähler-DB öffnen
      L      DBD80
      T      Dyn.Ink_Wert
      L      DBD76
      T      Dyn.Max_Wert
      A      DBX74.3
      =      Dyn.Lauf_Flag
      A      DBX74.4
      =      Dyn.Flag_Lauf_fertig
      A      DBX74.5
      =      Dyn.Ohne_Lauf_fertig

      JU     en04

// Zeit-Inkremente erzeugen:
w040: AN     Antrieb_aktiv
      JC     w041

      L      "MW4"                                           // 10ms-Takte
      ITD
      L      Dyn.Ink_Wert
      +D                                                     // Aktueller Zählerwert +100ms-Takte
      T      Dyn.Ink_Wert

w041: L      DINT#10000                                      // Festwert: 10000 (100s)
      T      Dyn.Max_Wert

      L      Dyn.Ink_Wert                                    // Aktueller Zählerwert
      L      Dyn.Max_Wert                                    // Max. Wert erreicht ?
      <=D                                                    // Nein !
      R      Dyn.Ohne_Lauf_fertig                            // Ohne Flag-Lauf wurde beendet
      R      Dyn.Flag_Lauf_fertig                            // Flag-Lauf wurde beendet
      JC     en04

      -D                                                     // Restwert als Startwert nehmen !
      T      Dyn.Ink_Wert

      AN     Dyn.Lauf_Flag                                   // Umschaltung Zähl-Lauf ohne-mit-ohne Flag
      =      Dyn.Ohne_Lauf_fertig                            // Ohne Flag-Lauf wurde beendet
      A      Dyn.Lauf_Flag                                   // Umschaltung Zähl-Lauf ohne-mit-ohne Flag
      =      Dyn.Flag_Lauf_fertig                            // Flag-Lauf wurde beendet

      AN     Dyn.Lauf_Flag                                   // Umschaltung Zähl-Lauf ohne-mit-ohne Flag
      =      Dyn.Lauf_Flag

en04: NOP 0


--- NW 9: 
 ---
      A      "Hauptstrang_leer"                              // Keine Haupstrangdaten vorhanden -> Verklemm-Errors löschen
      AN     B_Gerade
      R      Dyn.Error.BM_undef_Gerade                       // undefiniertes BM bei Weiterfahrt erkannt

      AN     ErrQuit
      JC     En08

// Störungen löschen:
      SET
      R      Dyn.Error.BM_undef_Gerade
      R      Dyn.Error.Frei14

      A      "Hauptstrang_leer"                              // Keine Haupstrangdaten vorhanden -> Verklemm-Errors löschen
      A      Dyn.Error.BM_verklemmt_Gerade
      CLR                                                    // Nie da große Trolleys
      R      Dyn.Error.BM_verklemmt_Gerade
      R      Dyn.FahrKontrolle.BT_Gerade

      A      "Hauptstrang_leer"                              // Keine Haupstrangdaten vorhanden -> Verklemm-Errors löschen
      A      Dyn.Error.BM_verklemmt_Ausfahrt
      CLR                                                    // Nie da große Trolleys
      R      Dyn.Error.BM_verklemmt_Ausfahrt
      R      Dyn.FahrKontrolle.BT_Ausfahrt

// Kann nur über Reset zurückgesetzt werden:
//     R     #Dyn.Error.Weichen_DL
//     R     #Dyn.Error.Undef_Weiche
//     R     #Dyn.Error.BLKMov
//     R     #Dyn.Error.Haupstrang_DL
//     R     #Dyn.Error.Haupstrang_DL_voll
//     R     #Dyn.Error.Keine_HSDaten
//     R     #Dyn.Error.Rein_FIFO
//     R     #Dyn.Error.Keine_FIFODaten
//     R     #Dyn.Error.Stau_AusfahrBereich
//     R     #Dyn.Error.BM_verklemmt_Gerade
//     R     #Dyn.Error.BM_verklemmt_Ausfahrt
//     R     #Dyn.Error.Send_FIFO_fehlerhaft    //Send-FIFO zum PC ist fehlerhaft
//     R     #Dyn.Error.Send_FIFO_voll   //Send-FIFO zu PC ist voll
//     R     #Dyn.Error.Reset_aktiv      //Reset ist aktiv

En08: NOP 0


--- NW 10: Schaltpunkt aufgrund von Hauptstrangdaten suchen ---
      L      Dyn.Hauptstrang_Ink                             // Inkremente zum Weiche schalten (vom Hauptstrang)
      L      DINT#0                                          // schon bekannt ?
      >D                                                     // Ja !
      S      Antrieb_start                                   // Kreiselantrieb starten
      JC     Nw09

// Nach neuen Daten suchen:
      AN     "Weiche_NewData"                                // Im Weichenbereich nach neuen Daten suchen
      JC     w076

      L      Dyn.Ink_Wert                                    // Aktueller Inkrementalwert
      L      Weiche.Off_Ink                                  // Inkremente zum Weiche schalten
      >D                                                     // Gleiches Flag/Flag wie Inkgeber zum Suchen
      JC     w071

// Anders Flag/Liste wie Inkgeber zum Suchen:
      L      Weiche.Hauptstrang_DL_DB

      A      Dyn.Lauf_Flag                                   // Inkgeber schon mit Lauf-Flag
      R      SAVE.IDX_Flag                                   // Hauptstrang_DL +1 durchsuchen
      JC     w070

      SET
      S      SAVE.IDX_Flag                                   // Hauptstrang_DL +1 durchsuchen

      +      1

w070: T      Dyn.Hauptstrang_Sortliste                       // Sortliste aus welcher Hauptstrangdaten sind

      JU     w073

// Gleiches Flag/Liste wie Inkgeber zum Suchen:
w071: L      Weiche.Hauptstrang_DL_DB

      AN     Dyn.Lauf_Flag                                   // Inkgebeer ohne Lauf-Flag
      R      SAVE.IDX_Flag                                   // Hauptstrang_DL +1 durchsuchen
      JC     w072

      SET
      S      SAVE.IDX_Flag                                   // Hauptstrang_DL +1 durchsuchen

      +      1

w072: T      Dyn.Hauptstrang_Sortliste                       // Sortliste aus welcher Hauptstrangdaten sind

// Hauptstrang Sortliste nach Position -1 durchsuchen:
w073: CALL FC "DatenFindOffsetSort" (SSDB:=Dyn.Hauptstrang_Sortliste, SSDW:=Weiche.Hauptstrang_DL_DW, PARA:=WORD#16#0B01, SEARCHDATEN:=Weiche.Position_minus, RE_VAL:="MB199", OUTDATEN:=Daten, Position:="MW196")   // nach 11.DW (letzte Position) suchen

      L      "MB199"
      T      Dyn.Rueckmld.RET_VAL_Sortliste_Out

      A      "M199.7"                                        // Datensatz ist vorhanden
      R      Dyn.Error.Haupstrang_DL                         // Sortliste fehlerhaft
      JC     w074

      A      "M199.6"                                        // Datensatz ist nicht vorhanden
      R      Dyn.Error.Haupstrang_DL                         // Sortliste fehlerhaft
      JC     Nw09                                            // Warten, da noch keine Daten vorhanden

      SET
      S      Dyn.Error.Haupstrang_DL                         // Sortliste fehlerhaft

w076: L      0                                               // Keine Daten auf Hauptstrang vorhanden
      T      Dyn.Hauptstrang_Ink                             // Inkremente zum Weiche schalten (vom Hauptstrang)

      JU     Nw09

// Search-Ink speichern:
w074: L      Daten.Start_Ink                                 // Stamm-Daten speichern
      T      Dyn.Hauptstrang_Search_Ink                      // Inkremente zum Daten auslesen (Start-Ink)

// Hauptstrang-Schaltdaten errechnen/speichern:
// Kettenlängungs-Korrektur:
      L      sKorrekturFaktor                                // Korrektur-Faktor wegen Kettenlängung
      L      0.995                                           // sinnvoller Wert ? (maximal 0,5% Abweichung erlaubt)
      >=R                                                    // Ja !
      A(
      CAC
      L      1.005
      <=R
      )
      JC     w075

      L      1.0                                             // dann ohne Korrektur !
      T      sKorrekturFaktor                                // Korrektur-Faktor wegen Kettenlängung

// Schaltdaten errechnen:
w075: A      Daten.Start_Flag                                // Lauf-Flag bei Start-Inkremente
      =      Dyn.Hauptstrang_Flag                            // Flag zum Weiche schalten (vom Hauptstrang)

      L      Weiche.Off_Ink                                  // Inkremente zum Weiche schalten
      DTR
      L      sKorrekturFaktor                                // Korrektur-Faktor wegen Kettenlängung
      *R
      RND
      L      Daten.Start_Ink                                 // Daten aus Sortliste dazuaddieren
      +D
      T      Dyn.Hauptstrang_Ink                             // Inkremente zum Weiche schalten (vom Hauptstrang)
      L      Dyn.Max_Wert                                    // Maximal erlaubter Zählwert
      >D
      JCN    Nw09

      -D                                                     // Restwert übernehmen
      T      Dyn.Hauptstrang_Ink                             // Inkremente zum Weiche schalten (vom Hauptstrang)

      AN     Daten.Start_Flag                                // Lauf-Flag bei Start-Inkremente (invertieren)
      =      Dyn.Hauptstrang_Flag                            // Flag zum Weiche schalten (vom Hauptstrang)


--- NW 11: Weiche aufgrund der Hauptstrangdaten schalten ---
Nw09: L      Dyn.Hauptstrang_Ink                             // Inkremente zum Weiche schalten (vom Hauptstrang)
      L      DINT#0                                          // angegeben ?
      <=D                                                    // Nein !
      JC     w08E

      A      Dyn.Hauptstrang_Flag                            // Flag zum Weiche schalten (vom Hauptstrang)
      A      Dyn.Flag_Lauf_fertig                            // Flag-Lauf wurde beendet
      O
      AN     Dyn.Hauptstrang_Flag                            // Flag zum Weiche schalten (vom Hauptstrang)
      A      Dyn.Ohne_Lauf_fertig                            // Flag-Lauf wurde beendet
      JC     w080                                            // beim Ende des Lauf sind Inkremente uninteressant

      A      Dyn.Hauptstrang_Flag                            // Flag zum Weiche schalten (vom Hauptstrang)
      A      Dyn.Lauf_Flag                                   // Zähl-Lauf mit Flag ist aktiv
      O
      AN     Dyn.Hauptstrang_Flag                            // Flag zum Weiche schalten (vom Hauptstrang)
      AN     Dyn.Lauf_Flag                                   // Zähl-Lauf mit Flag ist aktiv
      JCN    en08_Mig

      L      Dyn.Ink_Wert                                    // Aktuelle Inkrementalwert
      L      Dyn.Hauptstrang_Ink                             // Inkremente zum Weiche schalten (vom Hauptstrang)
      <D
      JC     en08_Mig

// Ziel kontrollieren:
w080: L      Dyn.Ink_Wert                                    // Aktueller Inkrementalwert
      T      Dyn.Last_Ink                                    // Inkremente des letzten durchfahrenden Teils
      A      Dyn.Lauf_Flag                                   // Zähl-Lauf mit Flag ist aktiv
      =      Dyn.Last_Flag                                   // Flag des letzten durchfahrenden Teils

      L      DINT#0                                          // Löschen, da ausgewertet
      T      Dyn.Hauptstrang_Ink                             // Inkremente zum Weiche schalten (vom Hauptstrang)

// Fahrendes Teil auslesen:
CALL FC "DatenOut" (SSDB:=Dyn.Hauptstrang_Sortliste, SSDW:=Weiche.Hauptstrang_DL_DW, PARA:=WORD#16#0000, SEARCHDATEN:=Dyn.Hauptstrang_Search_Ink, RE_VAL:="MB199", OUTDATEN:=Daten, Position:=Dyn.Hauptstrang_Pos)   // Inkremente zum Daten auslesen (Start-Ink) | Aktuelle Position der Daten in Datenliste

      L      "MB199"
      T      Dyn.Rueckmld.RET_VAL_Sortliste_Out

      A      "M199.7"                                        // Datensatz ist vorhanden
      JC     w081

      L      Weiche.Hauptstrang_DL_DB
      T      DatenDB
      OPN    DB[DatenDB]

      SET
      S      Dyn.Error.Keine_HSDaten                         // Keine Hauptstrang-Daten mehr vorhanden
      JU     w08E

// Fahrendes Teil speichern: (für Fehlersuche)
w081: L      Daten.Sort_Info.Teil_IDX                        // BM-IDX (wird bei Auslagerung gemeldet)
      T      Dyn.Last_IDX                                    // IDX des letzten durchfahrenden Teils

// /Ersatz-Ziel anfahren bei Ausfahrziel und Stau ?:
      L      Daten.Sort_Info.Teil_Ziel                       // Ziel des BT (aufgrund vom Hauptstrang)
      L      Weiche.AbzweigZiel                              // Bei diesem Ziel Weiche auf Abzweig schalten + Carl
      <>I                                                    // BM soll nicht ausfahren !
      ON     Weiche.Parameter.ErsatzZiel_bei_Stau            // Bei Stau soll Ersatz-Ziel angefahren werden
      ON     Stau_Ausfahrtbereich
      JC     x081

      L      Weiche.ErsatzZiel                               // Ersatz-Ziel übergeben
      T      Daten.Sort_Info.Teil_Ziel

x081: L      Daten.Sort_Info.Teil_Ziel                       // Ziel des BT (aufgrund vom Hauptstrang)
      L      0
      <=I
      =      Dyn.Status.Ziel_unbekannt                       // Ziel des BT ist unbekannt

      A      Dyn.Status.Ziel_unbekannt                       // Ziel des BT ist unbekannt
      A      Weiche.Parameter.Weichen_GST_gerade
      AN     Weiche.Parameter.Weichen_GST_abzweig
      JC     x100                                            // BT mit unbekanntem Ziel geradeaus fahren

      A      Dyn.Status.Ziel_unbekannt                       // Ziel des BT ist unbekannt
      AN     Weiche.Parameter.Weichen_GST_gerade
      A      Weiche.Parameter.Weichen_GST_abzweig
      JC     w082                                            // BT mit unbekanntem Ziel ausfahren

      L      Daten.Sort_Info.Teil_Ziel                       // Ziel des BT (aufgrund vom Hauptstrang)
      L      Weiche.AbzweigZiel                              // Bei diesem Ziel Weiche auf Abzweig schalten + Carl
      T      Carr_Ziel                                       // Ziel, das bei Carr-Telegramm gemeldet wird
      ==I                                                    // BM soll ausfahren
      S      Dyn.Carr                                        // CARR-Telegramm muss noch gesendet werden
      S      Dyn.Puffer_IDX                                  // Trolley-ID in Puffer eintragen
      JC     w082                                            // Teil ausfahren

      L      Daten.Sort_Info.Teil_Ziel                       // Ziel des BT (aufgrund vom Hauptstrang)
      L      Weiche.GeradeZiel                               // Bei diesem Ziel Weiche auf Gerade schalten + Carl
      <>I                                                    // BM soll also ausfahren, da nicht das GeradeZiel!
      A(
      L      0                                               // sinnvolle Angabe ?
      >I                                                     // Ja !
      )
      JC     w082                                            // Teil ausfahren (ohne CARR, da undef. rausfahren!)

// Teile geradeaus fahren:******************************************************************************************************
x100: SET
      S      Dyn.Status.Weiche_geradeaus                     // Weiche auf Gerade schalten
      R      Dyn.Status.Weiche_abzweigen
      S      Dyn.BM_gerade                                   // BM wurde gerade gefahren (1 Zyklus)

// Verklemm-Kontroll-Info speichern:
      AN     Weiche.Parameter.Kontroll_B_Gerade              // Kontroll-Sensor bei Weiterfahrt (gerade)
      JC     k100                                            // Letzter BM noch nicht kontrolliert

      A      Dyn.FahrKontrolle.BT_Gerade                     // BM fährt geradeaus durch Weichenbereich
      JC     k100                                            // Letzter BM noch nicht kontrolliert

      L      Dyn.Last_IDX                                    // IDX des letzten durchfahrenden Teils
      T      Kontroll_IDX                                    // IDX des zu kontollierenden Teils
      A      SAVE.IDX_Flag                                   // Hauptstrang_DL +1 durchsuchen
      =      SAVE.Kontroll_Flag                              // Hauptstrang_DL +1 durchsuchen

      L      Weiche.Kontroll_Zeit_gerade                     // Nach dieser Zeit muss BM Weichenbereich verlassen haben [100ms]
      T      Dyn.FahrKontrolle.Kontroll_Time_Gerade          // Innerhalb dieser Zeit muss BM Weiche gerade verlassen haben [100ms]

      SET
      S      Dyn.FahrKontrolle.BT_Gerade                     // BM fährt geradeaus durch Weichenbereich
      R      Dyn.FahrKontrolle.Gerade_Neg                    // Geradeaus: Kontroll-Time ist negativ

// CARR-Telegramm erwünscht ?:
k100: L      Daten.Sort_Info.Teil_Ziel                       // Ziel des BT (aufgrund vom Hauptstrang)
      L      Weiche.GeradeZiel                               // Bei diesem Ziel Weiche auf Gerade schalten + Carl
      T      Carr_Ziel                                       // Ziel, das bei Carr-Telegramm gemeldet wird
      ==I                                                    // BM soll ausfahren
      S      Dyn.Carr                                        // CARR-Telegramm muss noch gesendet werden

      A      Weiche.Parameter.Letzte_Weiche                  // Letzte Weiche im Verbund
      S      Del                                             // Nur Sortdaten löschen
      JC     w084                                            // Daten aus Sortliste löschen

// Letzte Position neu speichern:
New:  L      Weiche.Weichen_Nr                               // Nummer der Weiche
      T      Daten.letzte_Position                           // Letzte Position, wo Teil vorbeigefahren ist

CALL FC "DatenIn" (SSDB:=Dyn.Hauptstrang_Sortliste, SSDW:=Weiche.Hauptstrang_DL_DW, INDATEN:=Daten, RE_VAL:="MB199")

      L      "MB199"
      T      Dyn.Rueckmld.RET_VAL_Sortliste_Out

      A      "M199.7"                                        // Datensatz ist vorhanden /Alles Ok)
      JC     GST

      SET
      S      Dyn.Error.Haupstrang_DL                         // Sortliste fehlerhaft
      JU     GST

// Teile ausfahren:************************************************************************************************************
w082: A      Dyn.Status.Weiche_abzweigen                     // Weiche war schon auf Abzweig
      JC     w083

      L      Dyn.Status.Schalttakte
      +      DINT#1                                          // Auf Abzweig umgeschaltet +1
      T      Dyn.Status.Schalttakte

w083: SET
      S      Dyn.Status.Weiche_abzweigen                     // Weiche auf Abzweig schalten
      R      Dyn.Status.Weiche_geradeaus
      R      Del                                             // Nur Sortdaten löschen
      S      Dyn.BM_raus                                     // BM wurde ausgeschleußt (1 Zyklus)

      L      300                                             // Nach dieser Zeit ist BM ausgefahren [300*100ms]
      T      Dyn.FahrKontrolle.Time_Ausfahrt                 // Diese Zeit benötigt BM zum Ausfahren [100ms]

// Verklemm-Kontroll-Info speichern:
      AN     Weiche.Parameter.Kontroll_B_Ausfahrt            // Kontroll-Sensor bei Ausfahrt (abzweig)
      JC     k101                                            // Letzter BM noch nicht kontrolliert

      A      Dyn.FahrKontrolle.BT_Ausfahrt                   // BM fährt aus Weichenbereich
      JC     k101                                            // Letzter BM noch nicht kontrolliert

      L      Dyn.Last_IDX                                    // IDX des letzten durchfahrenden Teils
      T      Kontroll_IDX                                    // IDX des zu kontollierenden Teils
      A      SAVE.IDX_Flag                                   // Hauptstrang_DL +1 durchsuchen
      =      SAVE.Kontroll_Flag                              // Hauptstrang_DL +1 durchsuchen

      L      Weiche.Kontroll_Zeit_abzweigen                  // Nach dieser Zeit muss BM Weichenbereich verlassen haben [100ms]
      T      Dyn.FahrKontrolle.Kontroll_Time_Ausfahrt        // Innerhalb dieser Zeit muss BM Weiche ausgefahren haben [100ms]

      SET
      S      Dyn.FahrKontrolle.BT_Ausfahrt                   // BM fährt aus Weichenbereich
      R      Dyn.FahrKontrolle.Ausfahrt_Neg                  // Ausfahrend: Kontroll-Time ist negativ

k101: A      Stau_Ausfahrtbereich                            // Ausfahrtsbereich hat Stau
      AN     Weiche.Parameter.ErsatzZiel_bei_Stau            // Bei Stau soll Ersatz-Ziel angefahren werden
      S      Dyn.Error.Stau_AusfahrBereich                   // Stau im Ausfahrbereich (-> Antrieb stoppen)

// Falls Entlade-Weiche neues Leer-Ziel übergeben:
      AN     Weiche.Parameter.Entlade_Weiche                 // BM wird entladen -> Leerziel übergeben
      O      Weiche.Parameter.Letzte_Weiche                  // Letzte Weiche im Verbund
      JC     w084

      L      Weiche.LeerZiel                                 // Nach Entladen des BM dieses Ziel übergeben
      T      Daten.Sort_Info.Teil_Ziel                       // BM bei diesem Abwurf-Ziel ausfahren/entladen
      L      0                                               // Sinnvolle Angabe ?
      >I                                                     // Ja !
      JC     New                                             // Daten mit neuem Ziel an Hauptstrang übergeben !

// Daten aus Sortliste löschen
w084: L      Dyn.Hauptstrang_Pos                             // Aktuelle Position der Daten in Datenliste
      L      16#0E00                                         // 0EYY: DS YY löschen
      OW
      T      FC86_Para

CALL FC "DatenOutSort" (SSDB:=Dyn.Hauptstrang_Sortliste, SSDW:=Weiche.Hauptstrang_DL_DW, PARA:=FC86_Para, OUTDATEN:=Daten, RE_VAL:="MB199")   // DS YY löschen

// GST-Schalt-Inks speichern:
GST:  AN     Weiche.Parameter.Weichen_GST_gerade
      AN     Weiche.Parameter.Weichen_GST_abzweig
      JC     w08E

      L      Weiche.Ink_Schaltdauer                          // Inkremente (Fenster), danach wird Weiche in GST geschaltet
      L      0                                               // sinnvoller Wert ?
      <=I                                                    // Nein !
      JC     w08E

      L      Weiche.Ink_Schaltdauer                          // Inkremente (Fenster), danach wird Weiche in GST geschaltet
      ITD
      L      Dyn.Ink_Wert                                    // Aktueller Inkrementalwert
      +D
      T      Dyn.GSTschalt_Ink                               // Inkremente bei Weiche auf GST schalten
      A      Dyn.Lauf_Flag                                   // Zähl-Lauf mit Flag ist aktiv
      =      Dyn.GSTschalt_Flag                              // Flag bei Weiche auf GST schalten

      L      Dyn.Max_Wert                                    // Maximal erlaubter Zählwert überschritten ?
      <=D                                                    // Nein !
      JC     w08E

      -D                                                     // Restwert übernehmen
      T      Dyn.GSTschalt_Ink                               // Inkremente bei Weiche auf GST schalten
      AN     Dyn.Lauf_Flag                                   // Zähl-Lauf mit Flag ist aktiv (invertieren, da Überlauf!)
      =      Dyn.GSTschalt_Flag                              // Flag bei Weiche auf GST schalten

w08E: L      DINT#0
      T      Dyn.Hauptstrang_Ink                             // Inkremente zum Weiche schalten (vom Hauptstrang)

en08_Mig: NOP 0


--- NW 12: Weiche auf GST zurückschalten ---
      L      Dyn.GSTschalt_Ink                               // Inkremente bei Weiche auf GST schalten
      L      0                                               // sinnvolle Angabe ?
      <=D                                                    // Nein !
      JC     X111

      A      Dyn.GSTschalt_Flag                              // Flag bei Weiche auf GST schalten
      A      Dyn.Flag_Lauf_fertig                            // Flag-Lauf wurde beendet
      O
      AN     Dyn.GSTschalt_Flag                              // Flag bei Weiche auf GST schalten
      A      Dyn.Ohne_Lauf_fertig                            // Flag-Lauf wurde beendet
      JC     w110                                            // beim Ende des Lauf sind Inkremente uninteressant

      A      Dyn.GSTschalt_Flag                              // Flag bei Weiche auf GST schalten
      A      Dyn.Lauf_Flag                                   // Zähl-Lauf mit Flag ist aktiv
      O
      AN     Dyn.GSTschalt_Flag                              // Flag bei Weiche auf GST schalten
      AN     Dyn.Lauf_Flag                                   // Zähl-Lauf mit Flag ist aktiv
      JCN    en11

      L      Dyn.Ink_Wert                                    // Aktuelle Inkrementalwert
      L      Dyn.GSTschalt_Ink                               // Inkremente bei Weiche auf GST schalten
      <D
      JC     en11

w110: L      Weiche.Ink_Schaltdauer                          // Inkremente (Fenster), danach wird Weiche in GST geschaltet
      ITD
      L      Dyn.GSTschalt_Ink                               // Inkremente bei Weiche auf GST schalten
      +D                                                     // dazuaddieren, um zu ermitteln, ob nächste Daten schon früher kommen
      L      Dyn.Hauptstrang_Ink                             // Inkremente zum Weiche schalten (vom Hauptstrang)
      >D                                                     // Haupstrangdaten sind kleiner
      A(
      L      0                                               // sinnvolle Hauptstrang-Daten ?
      <>D                                                    // Ja !
      )
      JC     X111                                            // Nicht auf GST schalten, da nächste Daten schon kommen !

// Weiche auf GST schalten:
      A      Weiche.Parameter.Weichen_GST_gerade
      AN     Weiche.Parameter.Weichen_GST_abzweig
      JCN    W110_Mig                                        // Negierter Sprung !

      A      Dyn.FahrKontrolle.BT_Ausfahrt                   // BM fährt aus Weichenbereich
      O      Dyn.Error.BM_verklemmt_Ausfahrt                 // BM bei Ausfahrt in Weiche verklemmt (-> Antrieb stoppen)
      JC     en11                                            // Warten

      SET
      S      Dyn.Status.Weiche_geradeaus                     // Weiche auf Gerade schalten
      R      Dyn.Status.Weiche_abzweigen
      JU     X111

W110_Mig: A      Weiche.Parameter.Weichen_GST_abzweig
      AN     Weiche.Parameter.Weichen_GST_gerade
      JCN    X111                                            // Negierter Sprung !

      A      Dyn.FahrKontrolle.BT_Gerade                     // BM fährt geradeaus durch Weichenbereich
      O      Dyn.Error.BM_verklemmt_Gerade                   // BM bei Weiterfahrt in Weiche verklemmt (-> Antrieb stoppen)
      JC     en11                                            // Warten

      SET
      S      Dyn.Status.Weiche_abzweigen                     // Weiche auf Abzweig schalten
      R      Dyn.Status.Weiche_geradeaus

X111: L      DINT#0
      T      Dyn.GSTschalt_Ink                               // Inkremente bei Weiche auf GST schalten
      SET
      R      Dyn.GSTschalt_Flag                              // Flag bei Weiche auf GST schalten

en11: NOP 0


--- NW 13: Weichenbereich auf verklemmte gerade fahrende BM kontrollieren ---
      AN     Weiche.Parameter.Kontroll_B_Gerade              // Kontroll-Sensor bei Weiterfahrt (gerade)
      O      Dyn.Ohne_VerklemmKontrolle                      // Verklemmkontrolle ausschalten
      O      "Hauptstrang_leer"
      R      Dyn.FahrKontrolle.BT_Gerade                     // BM fährt geradeaus durch Weichenbereich
      R      Dyn.FahrKontrolle.BM_Gerade_erkannt             // Geradeausfahrendes BM wurde erkannt
      R      Dyn.Error.BM_verklemmt_Gerade                   // BM bei Weiterfahrt in Weiche verklemmt (-> Antrieb stoppen)
      R      Dyn.Error.BM_undef_Gerade                       // undefiniertes BM bei Weiterfahrt erkannt
      S      Dyn.FahrKontrolle.Gerade_Neg                    // Geradeaus: Kontroll-Time ist negativ
      JC     Nw17

// BM fährt geradeaus:
      A      B_Gerade                                        // Kontroll-Sensor nach Weiche Gerade
      AN     Dyn.FahrKontrolle.BM_Gerade_erkannt             // Geradeausfahrendes BM wurde erkannt
      A      Dyn.FahrKontrolle.BT_Gerade                     // BM fährt geradeaus durch Weichenbereich
      R      Dyn.FahrKontrolle.BT_Gerade
      S      Dyn.FahrKontrolle.BM_Gerade_erkannt             // Geradeausfahrendes BM wurde erkannt

      AN     B_Gerade                                        // Kontroll-Sensor nach Weiche Gerade
      R      Dyn.FahrKontrolle.BM_Gerade_erkannt             // Geradeausfahrendes BM wurde erkannt

      L      Dyn.Last_IDX                                    // IDX des letzten durchfahrenden Teils
      T      Kontroll_IDX                                    // IDX des zu kontollierenden Teils
      A      SAVE.IDX_Flag                                   // Hauptstrang_DL +1 durchsuchen
      =      SAVE.Kontroll_Flag                              // Hauptstrang_DL +1 durchsuchen

      JU     Q_G

N_G:  L      Weiche.Kontroll_Zeit_gerade                     // Nach dieser Zeit muss BM Weichenbereich verlassen haben [100ms]
      T      Dyn.FahrKontrolle.Kontroll_Time_Gerade          // Innerhalb dieser Zeit muss BM Weiche gerade verlassen haben [100ms]

Q_G:  A      ErrQuit
      AN     Dyn.FahrKontrolle.BT_Gerade                     // BM fährt geradeaus durch Weichenbereich
      R      Dyn.Error.BM_verklemmt_Gerade                   // BM bei Weiterfahrt in Weiche verklemmt (-> Antrieb stoppen)

// Zeit verändern:
      AN     Antrieb_aktiv                                   // Band ist aktiv
      ON     "100ms-Impuls"
      O      Dyn.Error.BM_verklemmt_Gerade                   // BM bei Weiterfahrt in Weiche verklemmt (-> Antrieb stoppen)
      JC     Un_G

      L      Dyn.FahrKontrolle.Kontroll_Time_Gerade          // Innerhalb dieser Zeit muss BM Weiche gerade verlassen haben [100ms]
      L      "MW2"                                           // Anzahl der 100ms-Takte
      -I
      T      Dyn.FahrKontrolle.Kontroll_Time_Gerade          // Innerhalb dieser Zeit muss BM Weiche gerade verlassen haben [100ms]
      L      0                                               // Kontroll-Zeit abgelaufen ?
      >I                                                     // Nein !
      R      Dyn.FahrKontrolle.Gerade_Neg                    // Geradeaus: Kontroll-Time ist negativ
      JC     en16

// BM verklemmt ?:
      A      Dyn.FahrKontrolle.Gerade_Neg                    // Geradeaus: Kontroll-Time ist negativ
      JC     Un_G

      SET
      S      Dyn.FahrKontrolle.Gerade_Neg                    // Geradeaus: Kontroll-Time ist negativ

      A      Dyn.FahrKontrolle.BT_Gerade                     // BM fährt geradeaus durch Weichenbereich
      S      Dyn.Error.BM_verklemmt_Gerade                   // BM bei Weiterfahrt in Weiche verklemmt (-> Antrieb stoppen)
      JC     N_G                                             // Zeit neu laden

// BM undefiniert ?:
Un_G: L      Dyn.FahrKontrolle.Kontroll_Time_Gerade          // Innerhalb dieser Zeit muss BM Weiche gerade verlassen haben [100ms]
      L      Weiche.DraussenZeit_gerade                      // Nach dieser neg. Zeit [100ms] Error undef.BM, falls Kontroll-Sensor aktiv
      >I                                                     // Muss BM draussen sein ? Nein !
      JC     en16

      T      Dyn.FahrKontrolle.Kontroll_Time_Gerade          // Innerhalb dieser Zeit muss BM Weiche gerade verlassen haben [100ms]

      AN     B_Gerade                                        // Kontroll-Sensor nach Weiche Gerade
      JC     en16

      SET
      S      Dyn.Error.BM_undef_Gerade                       // undefiniertes BM bei Weiterfahrt erkannt

en16: NOP 0


--- NW 14: Weichenbereich auf verklemmte ausfahrende BM kontrollieren ---
Nw17: AN     Weiche.Parameter.Kontroll_B_Ausfahrt            // Kontroll-Sensor bei Ausfahrt (abzweig)
      O      Dyn.Ohne_VerklemmKontrolle                      // Verklemmkontrolle ausschalten
      R      Dyn.FahrKontrolle.BT_Ausfahrt                   // BM fährt aus Weichenbereich
      R      Dyn.FahrKontrolle.BM_Ausfahrt_erkannt           // Ausfahrendes BM wurde erkannt
      R      Dyn.Error.BM_verklemmt_Ausfahrt                 // BM bei Ausfahrt in Weiche verklemmt (-> Antrieb gestoppt)
      S      Dyn.FahrKontrolle.Ausfahrt_Neg                  // Ausfahrend: Kontroll-Time ist negativ
      JC     Nw18

// BM fährt aus:
      A      B_Ausfahrt                                      // Kontroll-Sensor nach Weiche Ausfahrt
      AN     Stau_Ausfahrtbereich                            // Bei Stau Einzelerkennung nicht mehr möglich!
      AN     Dyn.FahrKontrolle.BM_Ausfahrt_erkannt           // Ausfahrendes BM wurde erkannt
      A      Dyn.FahrKontrolle.BT_Ausfahrt                   // BM fährt aus Weichenbereich
      R      Dyn.FahrKontrolle.BT_Ausfahrt
      S      Dyn.FahrKontrolle.BM_Ausfahrt_erkannt           // Ausfahrendes BM wurde erkannt

      AN     B_Ausfahrt                                      // Kontroll-Sensor nach Weiche Ausfahrt
      O      Stau_Ausfahrtbereich                            // Bei Stau auch !
      R      Dyn.FahrKontrolle.BM_Ausfahrt_erkannt           // Ausfahrendes BM wurde erkannt

      JU     Q_A

N_A:  L      Weiche.Kontroll_Zeit_abzweigen                  // Nach dieser Zeit muss BM Weichenbereich verlassen haben [100ms]
      T      Dyn.FahrKontrolle.Kontroll_Time_Ausfahrt        // Innerhalb dieser Zeit muss BM Weiche ausgefahren haben [100ms]

Q_A:  A      ErrQuit                                         // s.u.
      SET                                                    // Ohne Quittierung
      AN     Dyn.FahrKontrolle.BT_Ausfahrt                   // BM fährt aus Weichenbereich
      R      Dyn.Error.BM_verklemmt_Ausfahrt                 // BM bei Ausfahrt in Weiche verklemmt (-> Antrieb gestoppt)

// Zeit verändern:
      AN     Antrieb_aktiv                                   // Band ist aktiv
      ON     "100ms-Impuls"
      O      Dyn.Error.BM_verklemmt_Ausfahrt                 // BM bei Ausfahrt in Weiche verklemmt (-> Antrieb gestoppt)
      JC     en17

      L      Dyn.FahrKontrolle.Kontroll_Time_Ausfahrt        // Innerhalb dieser Zeit muss BM Weiche ausgefahren haben [100ms]
      L      "MW2"                                           // Anzahl der 100ms-Takte
      -I
      T      Dyn.FahrKontrolle.Kontroll_Time_Ausfahrt        // Innerhalb dieser Zeit muss BM Weiche ausgefahren haben [100ms]
      L      0                                               // Kontroll-Zeit abgelaufen ?
      >I                                                     // Nein !
      R      Dyn.FahrKontrolle.Ausfahrt_Neg                  // Ausfahrend: Kontroll-Time ist negativ
      JC     en17

// BM verklemmt ?:
      A      Dyn.FahrKontrolle.Ausfahrt_Neg                  // Ausfahrend: Kontroll-Time ist negativ
      JC     Un_A

      SET
      S      Dyn.FahrKontrolle.Ausfahrt_Neg                  // Ausfahrend: Kontroll-Time ist negativ

      A      Dyn.FahrKontrolle.BT_Ausfahrt                   // BM fährt aus Weichenbereich
      S      Dyn.Error.BM_verklemmt_Ausfahrt                 // BM bei Ausfahrt in Weiche verklemmt (-> Antrieb gestoppt)
      JC     N_A                                             // Zeit neu laden

Un_A: L      0
      T      Dyn.FahrKontrolle.Kontroll_Time_Ausfahrt        // Innerhalb dieser Zeit muss BM Weiche ausgefahren haben [100ms]

en17: NOP 0

// BM fährt aus:
// Zeit verändern:
      AN     Antrieb_aktiv                                   // Band ist aktiv
      ON     "100ms-Impuls"
      JC     En17_Mig

      L      Dyn.FahrKontrolle.Time_Ausfahrt                 // Diese Zeit benötigt BM zum Ausfahren [100ms]
      L      "MW2"                                           // Anzahl der 100ms-Takte
      -I
      T      Dyn.FahrKontrolle.Time_Ausfahrt                 // Diese Zeit benötigt BM zum Ausfahren [100ms]
      L      0                                               // Ausfahr-Zeit abgelaufen ?
      >I                                                     // Nein !
      JC     En17_Mig

      T      Dyn.FahrKontrolle.Time_Ausfahrt                 // Minimum übergeben

En17_Mig: NOP 0


--- NW 15: CARR-Telegramm an PC senden ---
Nw18: AN     Weiche.Parameter.PC_Komm_aktiv
      ON     Dyn.Carr                                        // CARR-Telegramm muss noch gesendet werden
      O      "SGes".Ohne_PC_Fahren
      R      Dyn.Carr                                        // CARR-Telegramm muss noch gesendet werden
      JC     en13

// CARR mit dieser IDX schon gesendet?: (wegen Travel-FIFO leer) 
      L      Daten.Sort_Info.Teil_IDX                        // IDX des BT
      T      "MD220"
      L      SAVE.Teil_IDX_Old                               // BT/MT-IDX (wurde bei Auslagerung gemeldet)
      ==D
      JC     X130

// GOHDUM an Host senden: oder beim Verlaasen vom Sep4503?
// Puffer ermitteln:
      L      Weiche.AbzweigZiel
      +      -200
      T      "Daten_für_SendFIFO".Puffer_LinienNr

// Pufferstatus (Stau) ermitteln:
      A      "DEP_Sensoren".Stau_EP1.Stat.B_Akt
      =      "Daten_für_SendFIFO"."Status_2_Bit[0]"
      A      "DEP_Sensoren".Stau_EP2.Stat.B_Akt
      =      "Daten_für_SendFIFO"."Status_2_Bit[1]"
      A      "DEP_Sensoren".Stau_EP3.Stat.B_Akt
      =      "Daten_für_SendFIFO"."Status_2_Bit[2]"
      A      "DEP_Sensoren".Stau_EP4.Stat.B_Akt
      =      "Daten_für_SendFIFO"."Status_2_Bit[3]"

CALL FB "Daten_in_SendFIFO_speichern" ,  (TelegrammKennung[1]:='G', TelegrammKennung[2]:='O', TelegrammKennung[3]:='H', TelegrammKennung[4]:='D', TelegrammKennung[5]:='U', TelegrammKennung[6]:='M', TelegrammKennung[7]:=?, TelegrammKennung[8]:=?, TelegrammKennung[9]:=?, TelegrammKennung[10]:=?, TrolleyID:=Daten.Sort_Info.Teil_IDX, StationsNr:=4503, Puffer_LinienNr:=?, StoreGroup:=?, Status_1_Int:=?, Status_2_Bit[0]:=?, Status_2_Bit[1]:=?, Status_2_Bit[2]:=?, Status_2_Bit[3]:=?, Status_2_Bit[4]:=?, Status_2_Bit[5]:=?, Status_2_Bit[6]:=?, Status_2_Bit[7]:=?, Reserve[1]_Int:=?, Reserve[2]_Int:=?, Port:=2, Ret_Val_FIFO_IN:="MB199", Error:=Error_SendFIFO)   // s.o. | s.o. | s.o. | s.o. | s.o.

      A      Error_SendFIFO
      JC     en13

X130: SET
      R      Dyn.Carr                                        // CARR-Telegramm muss noch gesendet werden

      L      Daten.Sort_Info.Teil_IDX                        // IDX des BT
      T      SAVE.Teil_IDX_Old                               // BT/MT-IDX (wurde bei Auslagerung gemeldet)

en13: NOP 0


--- NW 16: Trolley-ID in Puffer eintragen ---
      AN     Weiche.Parameter.IDX_an_Puffer
      ON     Dyn.Puffer_IDX                                  // Trolley-ID in Puffer eintragen
      R      Dyn.Puffer_IDX                                  // CARR-Telegramm muss noch gesendet werden
      JC     xn16

      A      Dyn.Status.Ziel_unbekannt                       // Ziel des BT ist unbekannt
      JC     X160

      L      Carr_Ziel                                       // Ziel, das bei Carr-Telegramm gemeldet wird (1-20)
      T      "MW220"

CALL FC "DatenOut" (SSDB:=275, SSDW:=0, PARA:=16#0000, SEARCHDATEN:=P#M220.0, RE_VAL:="MB199", OUTDATEN:=DB1275.DBX0.0, Position:="MW196")   // Eintrag lesen

      L      "MB199"
      L      2#1111111                                       // Bit 7 ausblenden
      AW
      L      0                                               // Fehler vorhanden?
      <>I                                                    // Ja
      JC     X160

      L      "LagerDL_OutDaten".OUTDaten.Puffer_Dyn_DB
      T      DatenDB                                         // s.u.

      L      "LagerDL_OutDaten".OUTDaten.Puffer_Dyn_DW
      ITD
      T      AR1Start                                        // Startwert mit Offset 0

      L      AR1Start                                        // Startwert mit Offset 0
      +      DINT#72                                         // Offset TrolleyID_Einfahrt
      SLD    3
      T      AR1Zeiger                                       // Statt Dyn.Bereichsstop (ging nur bis DB-Länge <= 8191 Bytes)

      OPN    DB[DatenDB]

      L      Daten.Sort_Info.Teil_IDX                        // IDX des Trolleys an Omnipuffer melden
      T      DBD [AR1Zeiger]                                 // Lager +1 (DBW 72)

X160: SET
      R      Dyn.Puffer_IDX                                  // CARR-Telegramm muss noch gesendet werden

xn16: NOP 0


--- NW 17: Weiche schalten ---
      A      Dyn.Status.Weiche_abzweigen                     // Weiche auf Abzweig schalten
      R      Dyn.Status.Weiche_geradeaus
      =      Y_Weiche_abzweigen

      A      Dyn.Status.Weiche_geradeaus                     // Weiche auf Gerade schalten
      =      Y_Weiche_geradeaus


--- NW 18: Ende ---
      BE

