=== FC 80: FifoIn  [STL] ===
INTERFACE:
  Input:
    SSDB : Int                                          // Schnittstellen-DB
    SSDW : Int                                          // Schnittstellen-1.DW
    PARA : Word                                         // Aufrufparameter (Auftrag / Anzahl Zusatzdaten)
    INDATEN : Pointer                                   // InDaten-Schnittstelle
  Output:
    RE_VAL : Byte                                       // Rückmeldung
  InOut:
  Temp:
    Quelle : Any                                        // Zeiger, wo Rein-Daten sind
    Ziel : Any                                          // Zeiger, FIFO-Stelle
    Kopf : Byte                                         // Fifo-Kennung (FF)
    Datensatzlaenge : Byte                              // Datensatzlänge in Word (1 - 128)
    FifoLaenge : Int                                    // Länge des Fifo (maximale Anzahl der Datensätze)
    Bringzeiger : Int                                   // Zeiger, wohin nächster Eintrag gespeichert wird
    Holzeiger : Int                                     // Zeiger, woher nächste Daten geholt werden
    Anzahl : Int                                        // Anzahl der Datensätze (eingetragene)
    Status : Word                                       // Status des Fifo
    Err : Byte                                          // Fehlerbits
    Para1 : Byte                                        // 1.Aufrufparameter
    Para2 : Byte                                        // 2.Aufrufparameter
    Para21 : Byte                                       // 2.Aufrufparameter 1.Stelle
    Para22 : Byte                                       // 2.Aufrufparameter 2.Stelle
    MinBringzeiger : Int                                // Minimum Bringzeiger
    MaxBringzeiger : Int                                // Maximum Bringzeiger
    DBFifo : Word                                       // FIFO-DB
    SFC_RET_VAL : Int                                   // Rückmeldung SFC-Aufruf
    SFC_DB_LENGTH : Word                                // Rückmeldung SFC-Aufruf
    Fifo_Ende : Word                                    // Ende des Fifo
    Schleife : Word                                     // Loopzähler
    Offset : Byte                                       // Offset 1. zu speicherndes Zusatzwort
    SFC_WRITE_PROT : Bool                               // Rückmeldung SFC-Aufruf
    NixSave : Bool                                      // Status nicht speichern
    BieSpeicher : Bool                                  // Bie-Bit zwischenspeichern
  Constant:
  Return:
    Ret_Val : Void

--- NW 1: Schnittstellen-DB sinnvoll ? ---
      L      SSDB
      T      DBFifo

//      CALL  TEST_DB
//          DB_NUMBER  :=#DBFifo
//          RET_VAL    :=#SFC_RET_VAL
//          DB_LENGTH  :=#SFC_DB_LENGTH
//          WRITE_PROT :=#SFC_WRITE_PROT

CALL FC "TEST_DB_TO_ATTR_DB" (DB_Number:=DBFifo, RetVal:=SFC_RET_VAL, DB_Length:=SFC_DB_LENGTH, Write_Prot:=SFC_WRITE_PROT)

      L      SFC_RET_VAL
      L      2#0000_0000_0000_0000
      <>I
      O      SFC_WRITE_PROT
      =      NixSave                                         // Status nicht speichern
      JC     Err0                                            // kein Fifobereich


--- NW 2: Quelle-Pointer erzeugen: ---
      L      16#1004                                         // Kennung 10 + Word=04
      T      LW0                                             // Any-Kennung, Datentyp
      L      16#0006                                         // 6 Dw´s holen
      T      LW2                                             // Wiederholungen
      L      SSDB
      T      LW4                                             // DB_Nummer
      L      SSDW                                            // Adresse
      SLD    3
      L      16#8400_0000                                    // Kennung: Daten
      OD
      T      LD6                                             // Kennung, Adresse

CALL SYS "BLKMOV" (SRCBLK:=Quelle, RET_VAL:=SFC_RET_VAL, DSTBLK:=P#L20.0 WORD 6)   // 1.-6.DW FIFO holen

      L      Status
      L      2#0000_0000_1110_0000
      AW
      T      Err
      JP     Err                                             // Kapitalfehler vorhanden

      L      SFC_RET_VAL
      L      2#0000_0000_0000_0000
      <>I
      JC     Err1


--- NW 3: Zeigerüberprüfung ---
      L      Kopf                                            // Fifo-Kopf
      L      16#FF                                           // = Fifokennung ?
      <>I                                                    // Nein !
      =      NixSave                                         // Status nicht speichern
      JC     Err0                                            // kein Fifobereich

      L      1
      L      Datensatzlaenge                                 // Datenblocklänge
      >I
      JC     Err0                                            // kein Fifobereich

      L      128
      >I
      JC     Err0                                            // kein Fifobereich

      L      1
      L      FifoLaenge                                      // Max.Anzahl von Datenblöcken
      >I
      JC     Err0                                            // kein Fifobereich

      L      SSDW
      +      40                                              // Speichern ab 20.DW
      T      MinBringzeiger                                  // Minimum Bringzeiger

      L      FifoLaenge                                      // Länge FIFO (in Word)
      +      -1
      L      Datensatzlaenge                                 // Datenblocklänge
      *I
      L      2                                               // DB byteorientiert
      *I
      +      40                                              // Speichern ab 20.DW
      L      SSDW
      +I
      T      MaxBringzeiger                                  // Maximum Bringzeiger

      L      Datensatzlaenge                                 // Datenblocklänge
      L      2                                               // DB byteorientiert
      *I
      L      MaxBringzeiger                                  // Maximum Bringzeiger
      +I                                                     // Zeiger Endekennung
      T      Fifo_Ende
      SLW    3                                               // Pointer erzeugen
      LAR1

      OPN    DB[DBFifo]

      L      Fifo_Ende
      L      SFC_DB_LENGTH
      >I                                                     // Fifo-DB ist zu kurz!
      JC     Err0                                            // kein Fifo-Bereich

      L      DBW [AR1,]
      L      16#FFEE                                         // Fifo-Endekennung ?
      <>I                                                    // Nein !
      JC     Err0                                            // kein Fifobereich

      L      MinBringzeiger                                  // Minimum Bringzeiger
      L      Bringzeiger                                     // Bringzeiger
      <=I                                                    // Ok ?
      JC     W300                                            // Ja!

      L      0                                               // Grundstellung ?
      <>I                                                    // Nein !
      JC     Err5                                            // Bringzeiger ist ausserhalb

      L      Holzeiger                                       // Holzeiger Grundstellung ?
      <>I                                                    // Nein !
      JC     Err5                                            // Bringzeiger ist ausserhalb

      L      Anzahl                                          // Anzahl Datensätze
      L      0                                               // Grundstellung ?
      <>I                                                    // Nein !
      JC     Err5                                            // Bringzeiger ist ausserhalb

      L      MinBringzeiger                                  // Minimum Bringzeiger
      T      Bringzeiger                                     // Bringzeiger
      T      Holzeiger                                       // Holzeiger

W300: L      MaxBringzeiger                                  // Maximum Bringzeiger
      <=I                                                    // Ok ?
      JC     W301                                            // Ja!
      JU     Err5                                            // Bringzeiger ist ausserhalb


W301: L      Bringzeiger                                     // Bringzeiger
      L      Holzeiger                                       // Holzeiger
      ==I                                                    // Identisch !
      A(
      L      FifoLaenge
      L      Anzahl                                          // Anzahl der gespeicherten Datensätze
      <>I                                                    // Fifo noch nicht voll !
      )
      A(
      L      0
      <>I                                                    // Datensätze aber noch vorhanden !
      )
      JC     Err7                                            // Versatz Bring-/Holzeiger

      L      Bringzeiger                                     // Bringzeiger
      L      Holzeiger                                       // Holzeiger
      <>I                                                    // Ungleich !
      A(
      L      FifoLaenge
      L      Anzahl                                          // Anzahl der gespeicherten Datensätze
      ==I                                                    // Aber Fifo ist voll !
      O(
      L      0
      ==I                                                    // Aber keine Datensätze vorhanden !
      )
      )
      JC     Err7                                            // Versatz Bring-/Holzeiger


--- NW 4: Nur Zusatzdaten / als 1.Datensatz speichern ? ---
      L      PARA
      T      LW33                                            // Aufrufparameter zwischenspeichern

      L      16#02                                           // Nur Zusatzdaten speichern ?
      L      Para1                                           // 1.Aufrufparameter
      <>I                                                    // Nein !
      JC     W400

      L      Para2                                           // 2.Aufrufparameter
      L      16#00                                           // =0 ?
      ==I                                                    // Ja !
      JC     Err3                                            // Falscher Aufrufparameter

      JU     Nw06                                            // Zusatzdaten speichern

W400: L      16#01                                           // Als 1.Datensatz speichern ?
      <>I                                                    // Nein !
      JC     Nw05

      L      MinBringzeiger                                  // Minimum Bringzeiger
      T      Bringzeiger                                     // Bringzeiger
      T      Holzeiger                                       // Holzeiger
      L      0
      T      Anzahl                                          // Anzahl Datensätze

      JU     Nw06                                            // Zusatz-Daten speichern?


--- NW 5: Hat Fifo Platz / Datenbereich leer ? ---
Nw05: L      Anzahl                                          // Anzahl der gespeicherten Datensätze
      L      FifoLaenge                                      // Max. Anzahl von Datenblöcken
      <I
      JC     W500

      ==I                                                    // Identisch !
      JC     Err2                                            // Fifo ist voll

      JU     Err7                                            // Versatz Bring-/Holzeiger

W500: L      Bringzeiger                                     // Bringzeiger
      SLW    3                                               // Pointer erzeugen
      LAR1

      OPN    DB[DBFifo]

      L      Datensatzlaenge
L500: T      Schleife

      L      DBW [AR1,]
      L      0
      <>I
      JC     Err4                                            // Speicherzelle ist belegt

      ADDAR1 P#2.0

      L      Schleife
      LOOP   L500


--- NW 6: Zusatzdaten schreiben ---
Nw06: L      16#00                                           // =0 ?
      L      Para2                                           // 2.Aufrufparameter
      ==I                                                    // Ja !
      JC     Nw07

      L      16#00F0
      AW
      SRW    4
      T      Para21                                          // 1.Stelle isolieren

      L      Para2                                           // 2.Aufrufparameter
      L      16#000F
      AW
      T      Para22                                          // 2.Stelle isolieren

      L      Para21
      L      Para22
      >I                                                     // 1.Stelle > 2.Stelle !
      JC     Err3                                            // Falscher Aufrufparameter

      L      16#04
      >I                                                     // 2.Stelle > 4 !
      JC     Err3                                            // Falscher Aufrufparameter

      L      Para21
      L      16#00
      ==I                                                    // 1.Stelle = 0 !
      JC     Err3                                            // Falscher Aufrufparameter

// Quelle-Pointer erzeugen:
      L      16#1004                                         // Kennung 10 + Word=04
      T      LW0                                             // Any-Kennung, Datentyp
      T      LW10                                            // Any-Kennung, Datentyp
      L      Para22                                          // bis
      L      Para21                                          // von
      -I
      +      1
      T      LW2                                             // Wiederholungen
      T      LW12                                            // Wiederholungen
      L      0
      T      LW4                                             // DB_Nummer

      L      Para21                                          // Beginn ab X.Zusatzwort
      +      -1
      L      2                                               // byteorientiert
      *I
      T      Offset                                          // Offset 1. zu speicherndes Zusatzwort

      L      16#00F0                                         // Adresse (ab MW240)
      L      Offset                                          // falls nicht ab 1.Zusatzwort
      +I
      SLD    3
      L      16#8300_0000                                    // Kennung: Merker
      OD
      T      LD6                                             // Kennung, Adresse

// Ziel-Pointer erzeugen:
// Kennung + Datenbytes s.o.
      L      SSDB
      T      LW14                                            // DB_Nummer
      L      SSDW
      +      12                                              // ab 6.Dw speichern
      L      Offset                                          // falls nicht ab 1.Zusatzwort
      +I
      SLD    3
      L      16#8400_0000                                    // Kennung: Daten
      OD
      T      LD16                                            // Kennung, Adresse

CALL SYS "BLKMOV" (SRCBLK:=Quelle, RET_VAL:=SFC_RET_VAL, DSTBLK:=Ziel)   // Zusatz-Daten speichern

      L      SFC_RET_VAL
      L      2#0000_0000_0000_0000
      <>I
      JC     Err1


--- NW 7: Fifodaten schreiben ---
Nw07: L      16#FF                                           // Testsendung ?
      L      Para1                                           // 1.Aufrufparameter
      ==I                                                    // Ja !
      JC     Nw08                                            // Zeiger testweise verändern

      L      16#02                                           // Nur Zusatzdaten speichern ?
      ==I                                                    // Ja !
      JC     Ende                                            // Fertig !

// Quelle-Pointer erzeugen:

      L      16#1004                                         // Kennung 10 + Word=04
      T      LW0
      T      LW10                                            // Any-Kennung, Datentyp
      L      Datensatzlaenge                                 // Datenbytes speichern
      T      LW2
      T      LW12                                            // Wiederholungen

// DATEN-Pointer übernehmen:
      L      P#
      LAR1

      L      NoneW [AR1,]
      T      LW4                                             // DB_Nummer
      L      NoneD [AR1,]
      T      LD6                                             // Kennung, Adresse

// Ziel-Pointer erzeugen:
// Kennung + Datenbytes s.o.

      L      SSDB
      T      LW14                                            // DB_Nummer
      L      Bringzeiger                                     // Adresse
      SLD    3
      L      16#8400_0000                                    // Kennung: Daten
      OD
      T      LD16                                            // Kennung, Adresse

CALL SYS "BLKMOV" (SRCBLK:=Quelle, RET_VAL:=SFC_RET_VAL, DSTBLK:=Ziel)   // FIFO-Daten speichern

      L      SFC_RET_VAL
      L      2#0000_0000_0000_0000
      <>I
      JC     Err1


--- NW 8: Bringzeiger, Anzahl erhöhen ---
Nw08: L      Datensatzlaenge                                 // Datenblocklänge
      L      2                                               // 1 word = 2 bytes
      *I
      L      Bringzeiger                                     // Bringzeiger
      +I
      T      Bringzeiger                                     // Bringzeiger
      L      MaxBringzeiger                                  // Maximum Bringzeiger
      <=I                                                    // Erreicht ?
      JC     W800                                            // Nein !

      L      MinBringzeiger                                  // Minimum Bringzeiger
      T      Bringzeiger                                     // Bringzeiger

W800: L      Anzahl                                          // Anzahl der gespeicherten Datensätze
      +      1
      T      Anzahl                                          // Anzahl der gespeicherten Datensätze


--- NW 9: Versatz Bring-/Holzeiger ---
      L      Bringzeiger                                     // Bringzeiger
      L      Holzeiger                                       // Holzeiger
      ==I                                                    // Identisch !
      A(
      L      FifoLaenge
      L      Anzahl                                          // Anzahl der gespeicherten Datensätze
      <>I                                                    // Fifo noch nicht voll !
      )
      JC     Err7                                            // Versatz Bring-/Holzeiger

      L      Bringzeiger                                     // Bringzeiger
      L      Holzeiger                                       // Holzeiger
      <>I                                                    // Ungleich !
      A(
      L      FifoLaenge
      L      Anzahl                                          // Anzahl der gespeicherten Datensätze
      ==I                                                    // Aber Fifo ist voll !
      )
      JC     Err7                                            // Versatz Bring-/Holzeiger


--- NW 10: Fehlerausgabe / RET_VAL ---
Ende: SET                                                    // VKE = 1 ohne Fehler !!!
      JU     Ok
Err0: L      2#0000_0000_0000_0001                           // Kein Fifobereich
      T      Err
      JU     Err
Err1: S      L32.1                                           // SFC20-Aufruf mit Fehler
      JU     Err
Err2: S      L32.2                                           // Fifo ist voll
      JU     Err
Err3: S      L32.3                                           // Falscher Parameter
      JU     Err
Err4: S      L32.4                                           // Speicherzelle ist belegt
      JU     Err
Err5: S      L32.5                                           // Bringzeiger außerhalb
      JU     Err
Err7: S      L32.7                                           // Versatz Bring-/Holzeiger

Err:  CLR                                                    // VKE = 0 bei Fehler !!!
Ok:   L      Err
      T      RE_VAL
      L      Status
      OW
      T      Status

      SAVE                                                   // VKE in BIE-Bit speichern
      A      ?SW?
      =      BieSpeicher

--- NW 11: Fifokopfdaten speichern ---
      A      L32.0                                           // Falscher Parameter
      A      NixSave                                         // Status nicht speichern
      BEC

      L      Anzahl                                          // Anzahl der Datensätze (eingetragene)
      +      -1                                              // da vorher zum Test erhöht wurde
      T      "MW254"                                         // Übergabe an FC+1 (für FIFO-FÖBE)

      L      16#FF                                           // Testsendung ?
      L      Para1                                           // 1.Aufrufparameter
      ==I                                                    // Ja !
      BEC                                                    // Weil Zeiger testweise geändert!

// Ziel-Pointer erzeugen:

      L      16#1004                                         // Kennung 10 + Word=04
      T      LW10                                            // Any-Kennung, Datentyp
      L      16#0004                                         // 4Dw´s speichern
      T      LW12                                            // Wiederholungen
      L      SSDB
      T      LW14                                            // DB_Nummer
      L      SSDW                                            // Adresse
      L      4
      +I
      SLD    3
      L      16#8400_0000                                    // Kennung: Daten
      OD
      T      LD16                                            // Kennung, Adresse

CALL SYS "BLKMOV" (SRCBLK:=P#L24.0 WORD 4, RET_VAL:=SFC_RET_VAL, DSTBLK:=Ziel)   // Ab Bringzeiger sichern!

      A      BieSpeicher
      SAVE                                                   // VKE in BIE-Bit speichern

      L      FifoLaenge                                      // Länge des Fifo (maximale Anzahl der Datensätze)
      T      "MW248"                                         // Übergabe an FC+1 (für Durchlaufspeicher)
      L      Bringzeiger                                     // Zeiger, wohin nächster Eintrag gespeichert wird
      T      "MW250"                                         // Übergabe an FC+1 (für Durchlaufspeicher)
      L      Holzeiger                                       // Zeiger, woher nächste Daten geholt werden
      T      "MW252"                                         // Übergabe an FC+1 (für Durchlaufspeicher)
      L      Anzahl                                          // Anzahl der Datensätze (eingetragene)
      T      "MW254"                                         // Übergabe an FC+1 (für Durchlaufspeicher)

