=== FC 91: DatenFindOffsetSort  [STL] ===
INTERFACE:
  Input:
    SSDB : Int                                          // Datenlisten-DB
    SSDW : Int                                          // Datenlisten-1.DW
    PARA : Word                                         // Aufrufparameter (Auftrag / Anzahl Zusatzdaten)
    SEARCHDATEN : Pointer                               // Such-Daten-Schnittstelle
  Output:
    RE_VAL : Byte                                       // Rückmeldung
    OUTDATEN : Pointer                                  // OutDaten-Schnittstelle
    Position : Int                                      // Daten stehen an angegebener Position in Datenbank
  InOut:
  Temp:
    Quelle : Any                                        // Zeiger, wo Rein-Daten sind
    Ziel : Any                                          // Zeiger, FIFO-Stelle
    Kopf : Byte                                         // Datenliste-Kennnung (DA)
    Datensatzlaenge : Byte                              // Datensatzlänge in Word (01 - F0) F0=128
    Listenlaenge : Int                                  // Länge der Datenliste (maximale Anzahl der Datensätze)
    Stammdaten : Int                                    // Stammdatenlänge in Word (1 - 9)
    Belegt06 : Int                                      // reserviert von Datenliste
    Belegt08 : Int                                      // reserviert von Datenliste
    Belegt10 : Int                                      // reserviert von Datenliste
    Belegt12 : Int                                      // reserviert von Datenliste
    AnzahlEintraege : Int                               // Anzahl der eingetragenen Datensätze
    Reserve16 : Int                                     // Reserve
    Reserve18 : Int                                     // Reserve
    Para1 : Byte                                        // 1.Aufrufparameter
    Para2 : Byte                                        // 2.Aufrufparameter
    Suchzeiger : Int                                    // Suchzeiger
    DBDatenliste : Word                                 // Datenlisten-DB
    OffsetDaten_1 : Int                                 // Stammdaten beginnen ab hier
    SFC_RET_VAL : Int                                   // Rückmeldung SFC-Aufruf
    SFC_DB_LENGTH : Word                                // Rückmeldung SFC-Aufruf
    Datenlisten_Ende : Word                             // Ende der Datenliste
    AR2_Speicher : DWord                                // Adress-Register 2 zwischenspeichern
    Schleife : Word                                     // Loopzähler
    DBSuchDaten : Word                                  // Such-Daten-DB, falls angegeben
    SuchDaten_Pointer : DWord                           // Such-Daten-Pointer: Kennung, Adresse
    SuchDaten_Startpunkt : Word                         // Such-Daten-Startpunkt: Adresse
    DBOutDaten : Word                                   // Out-Daten-DB, falls angegeben
    OutDaten_Pointer : DWord                            // Out-Daten-Pointer: Kennung, Adresse
    OutDaten_Startpunkt : Word                          // Out-Daten-Startpunkt: Adresse
    IndPointer : DWord                                  // Zeiger für IndDB
    Daten_1 : Word                                      // 1.Datenwort der Indaten
    Datenblock_inBytes : Word                           // Datenblocklänge in Bytes
    Suchstelle : Word                                   // Bei angegebenen Datensatz suchen
    SFC_WRITE_PROT : Bool                               // Rückmeldung SFC-Aufruf
    Weitersuchen : Bool                                 // Weitersuchen ist aktiv
    Offsetsuchen : Bool                                 // Offsetsuchen ist aktiv
    AR1Zeiger : DWord                                   // Statt AR1 (ging nur bis DB-Länge <= 8191 Bytes)
    tRE_VAL : Byte                                      // Rückmeldung
  Constant:
  Return:
    Ret_Val : Void

--- NW 1: Schnittstellen-DB sinnvoll ? ---
      TAR2
      T      AR2_Speicher                                    // AR2 zwischenspeichern

      L      SSDB
      T      DBDatenliste

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

CALL FC "TEST_DB_TO_ATTR_DB" (DB_Number:=DBDatenliste, 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                                  // schreibgeschützt
      JC     Err0                                            // kein Datenlisten-Bereich


--- NW 2: Quelle-Pointer erzeugen: ---
      L      16#1004                                         // Kennung 10 + Word=04
      T      LW0                                             // Any-Kennung, Datentyp
      L      16#000A                                         // 10 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 10)   // 1.-10.DW Datenliste holen

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


--- NW 3: Zeigerüberprüfung ---
      L      Kopf                                            // Datenliste-Kopf
      L      16#DB                                           // = Sort-Datenlistekennung ?
      <>I                                                    // Nein !
      JC     Err0                                            // kein Datenlistebereich

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

      L      128
      >I
      JC     Err0                                            // kein Datenlistebereich

      L      1
      L      Listenlaenge                                    // Max.Anzahl von Datenblöcken
      >I
      JC     Err0                                            // kein Datenlistebereich

      L      1
      L      Stammdaten                                      // Anzahl der Stammdaten
      >I
      JC     Err0                                            // kein Datenlistebereich

      L      9
      >I
      JC     Err0                                            // kein Datenlistebereich

      L      Stammdaten                                      // Anzahl der Stammdaten
      L      Datensatzlaenge                                 // Datenblocklänge
      >I
      JC     Err0                                            // kein Datenlistebereich

      L      Listenlaenge                                    // Länge der Datenliste
      L      Datensatzlaenge                                 // Datenblocklänge
      *I
      L      2                                               // DB byteorientiert
      *I
      +      20                                              // Speichern ab 10.DW
      L      SSDW
      +I
      T      Datenlisten_Ende
      ITD
      SLD    3
      T      AR1Zeiger                                       // /Statt AR1 (ging nur bis DB-Länge <= 8191 Bytes)

      OPN    DB[DBDatenliste]

      L      Datenlisten_Ende
      L      SFC_DB_LENGTH
      >I                                                     // Datenlisten-DB ist zu kurz!
      JC     Err0                                            // kein Datenlisten-Bereich

      L      DBW [AR1Zeiger]
      L      16#DAEE                                         // Datenliste-Endekennung ?
      <>I                                                    // Nein !
      A(
      CAC
      L      16#DBEE                                         // Sort-Datenliste-Endekennung ?
      <>I                                                    // Nein !
      )
      JC     Err0                                            // kein Datenlisten-Bereich

      L      Datensatzlaenge                                 // Datenblocklänge
      L      2
      *I
      T      Datenblock_inBytes                              // Datenblocklänge in Bytes


--- NW 4: Auftrag kontrollieren ---
      SET
      R      Weitersuchen                                    // Weitersuchen ist aktiv
      R      Offsetsuchen                                    // Offsetsuchen ist aktiv
      L      0                                               // Vorerst kein Offset
      T      OffsetDaten_1

      L      PARA
      T      LW40                                            // Aufrufparameter zwischenspeichern

      L      16#00                                           // XX = 00 ?
      L      Para1
      ==I                                                    // Ja!
      JC     W401

      L      16#E1                                           // XX = E1 ?
      ==I                                                    // Ja!
      JC     Err3                                            // Falscher Aufrufparameter

      L      16#F1                                           // XX = F1 ?
      L      Para1
      <>I                                                    // Nein !
      JC     W400

      L      Para2
      L      16#00
      <>I
      JC     Err3                                            // Falscher Aufrufparameter

      SET
      S      Weitersuchen

      L      SSDW
      +      20
      T      Suchzeiger

      JU     Nw08                                            // OutDaten ok ?

W400: L      16#FF                                           // XX = FF ?
      <>I                                                    // Nein !
      JC     W403

      L      Para2
      L      16#00
      <>I
      JC     Err3                                            // Falscher Aufrufparameter

      SET
      S      Weitersuchen

      L      Suchzeiger                                      // Alter Suchzeiger
      L      Datenblock_inBytes                              // Datenblocklänge in bytes
      +I                                                     // Nächsten Datensatz suchen
      T      Suchzeiger                                      // Neuer Suchzeiger

      L      Datenblock_inBytes                              // Datenblocklänge in bytes
      L      Listenlaenge                                    // Alle möglichen Einträge
      *I                                                     // Gesamtlänge
      L      SSDW                                            // Startpunkt
      +I
      +      20                                              // Offset 1.Daten
      L      Suchzeiger                                      // Schreibzeiger
      >I                                                     // Noch nicht am Ende !
      JC     Nw08                                            // OutDaten ok ?

      JU     Err2                                            // Listenende erreicht

W403: L      16#02                                           // XX < 02 ?
      L      Para1
      >I                                                     // Ja!
      JC     Err3                                            // Falscher Aufrufparameter

      L      16#80                                           // XX > 80 ?
      >I                                                     // Ja!
      JC     Err3                                            // Falscher Aufrufparameter

      CAC
      L      Datensatzlaenge                                 // XX > Datensatzlänge
      >I                                                     // Ja!
      JC     Err3                                            // Falscher Aufrufparameter

      CAC
      +      -1                                              // Angegebener Offset -1
      L      2                                               // DB byteorientiert
      *I
      T      OffsetDaten_1                                   // Richtiger Offset der 1.Stammdaten

      L      0
      T      Suchzeiger                                      // Suche ab Anfang

      SET
      S      Offsetsuchen

W401: L      16#00                                           // =0 ?
      L      Para2                                           // 2.Aufrufparameter
      ==I                                                    // Ja !
      JC     W402

      T      Stammdaten                                      // Anzahl der Stammdaten
      L      Datensatzlaenge                                 // Datenblocklänge
      >I
      JC     Err3                                            // Falscher Aufrufparameter

      L      1
      L      Stammdaten                                      // Anzahl der Stammdaten
      >I
      JC     Err3                                            // Falscher Aufrufparameter

      L      9
      >I
      JC     Err3                                            // Falscher Aufrufparameter

W402: AN     Offsetsuchen
      JC     Nw05

      L      Para1                                           // Offset
      +      -1
      L      Stammdaten
      +I                                                     // Letzte Stammdaten zu groß ?
      L      Datensatzlaenge
      >I                                                     // Ja!
      JC     Err3                                            // Falscher Aufrufparameter


--- NW 5: Such-DATEN-Pointer übernehmen: ---
Nw05: L      AnzahlEintraege                                 // Anzahl der eingetragenen Datensätze
      L      0                                               // Eintrag vorhanden ?
      ==I                                                    // Nein !
      JC     Err6                                            // Datensatz ist nicht vorhanden

      L      0
      T      Suchzeiger                                      // Suchzeiger

      L      P#
      LAR2

      L      NoneW [AR2,]
      T      DBSuchDaten                                     // Suchdaten-DB
      L      NoneD [AR2,]                                    // Kennung, Adresse
      T      SuchDaten_Pointer

      L      DBSuchDaten                                     // Suchdaten-DB
      L      0                                               // Angegeben ?
      ==I                                                    // Nein
      JC     W501

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

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


      L      SFC_RET_VAL
      L      2#0000_0000_0000_0000                           // Fehler vorhanden ?
      <>I                                                    // Ja !
      JC     Err4                                            // Undefinierte Stammdaten

      L      NoneD [AR2,]                                    // Kennung, Adresse
      L      16#00FF_FFFF                                    // Ohne Kennung
      AW
      SRW    3                                               // Ohne Bit
      T      SuchDaten_Startpunkt

      L      Datensatzlaenge                                 // Datenblocklänge
      L      2                                               // DB byteorientiert
      *I
      L      SuchDaten_Startpunkt
      +I
      L      SFC_DB_LENGTH
      >I                                                     // Suchdaten-DB ist zu kurz
      JC     Err4                                            // Undefinierte Stammdaten

W501: L      SuchDaten_Pointer
      LAR2

      L      DBSuchDaten                                     // Suchdaten-DB
      L      0                                               // Angegeben ?
      ==I                                                    // Nein
      JC     W502

      OPN    DB[DBSuchDaten]

W502: L      NoneW [AR2,]                                    // Suchdaten überprüfen
      T      Daten_1                                         // 1.Suchdaten speichern

      L      Stammdaten
L500: T      Schleife

      L      DBSuchDaten                                     // Suchdaten-DB
      L      0                                               // Angegeben ?
      ==I                                                    // Nein
      JC     W503

      OPN    DB[DBSuchDaten]

W503: L      NoneW [AR2,]                                    // Suchdaten überprüfen
      L      0                                               // Etwas angegeben ?
      <>I                                                    // Ja !
      JC     Nw07                                            // Weiter

      ADDAR2 P#2.0

      L      Schleife
      LOOP   L500

      JU     Err4                                            // Undefinierte Stammdaten


--- NW 6: Kontrolle auf gleiche Stammdaten ---
Nw07: L      Suchzeiger                                      // Suchzeiger
      L      0                                               // Angegeben ?
      ==I                                                    // Nein !
      JC     W700                                            // Suche bei 1.Datensatz beginnen

      L      Suchzeiger                                      // Suchzeiger
      +      -20                                             // Zeiger 1.Daten
      L      Datenblock_inBytes                              // Datenblocklänge in Bytes
      /I                                                     // Ermittlung der wievielten Daten -1
      SRD    16                                              // Rest ermitteln
      L      0                                               // = 0 ?
      <>I                                                    // Suchzeiger nicht im Raster !
      JC     W700                                            // Suche bei 1.Datensatz beginnen

      L      0                                               // Bei angegebener Stelle suchen
      T      Suchstelle                                      // Such bei X-ten Datensatz

      JU     W701

W700: L      1                                               // Suche bei 1.Datensatz beginnen
      T      Suchstelle                                      // Such bei X-ten Datensatz
      L      SSDW
      +      20                                              // Offset für 1.Daten
      T      Suchzeiger                                      // Suchzeiger

W701: L      Suchzeiger                                      // Suchzeiger
      L      OffsetDaten_1                                   // Richtiger Offset der 1.Stammdaten
      +I
      ITD
      SLD    3
      T      AR1Zeiger                                       // /Statt AR1 (ging nur bis DB-Länge <= 8191 Bytes)

      L      SuchDaten_Pointer
      LAR2

      L      Stammdaten                                      // Anzahl der Stammdaten
L700: T      Schleife

      L      DBSuchDaten                                     // Suchdaten-DB
      L      0                                               // Angegeben ?
      ==I                                                    // Nein
      JC     W702

      OPN    DB[DBSuchDaten]

W702: L      NoneW [AR2,]                                    // Suchdaten überprüfen mit
      OPN    DB[DBDatenliste]
      L      DBW [AR1Zeiger]                                 // Datenliste-Daten lesen
      <>I                                                    // nicht identisch !
      JC     W703

      L      AR1Zeiger
      SRD    3
      L      2
      +D
      SLD    3
      T      AR1Zeiger

      ADDAR2 P#2.0

      L      Schleife
      LOOP   L700

      L      2#0000_0000_1000_0000                           // Daten sind vorhanden
      T      tRE_VAL                                         // Ok-Status

      JU     Nw08                                            // Datensatz ist in Liste enthalten

W703: L      0                                               // Suche bei 1.Datensatz  begonnen
      L      Suchstelle                                      // Such bei X-ten Datensatz
      ==I                                                    // Nein !
      JC     W700

      L      Suchstelle                                      // Such bei X-ten Datensatz
      +      1
      T      Suchstelle                                      // Such bei X-ten Datensatz
      L      AnzahlEintraege                                 // Anzahl der eingetragenen Datensätze
      <=I                                                    // Alle Datensätze sind durchsucht
      JC     W705                                            // Nein !

      JU     Err6                                            // Datensatz ist nicht vorhanden

W705: L      Datenblock_inBytes                              // Datenblocklänge in bytes
      L      Suchzeiger                                      // Suchzeiger
      +I
      T      Suchzeiger                                      // Suchzeiger
      JU     W701


--- NW 7: Out-DATEN-Pointer übernehmen: ---
Nw08: L      P#
      LAR2

      L      NoneW [AR2,]
      T      DBOutDaten                                      // Outdaten-DB
      L      NoneD [AR2,]                                    // Kennung, Adresse
      T      OutDaten_Pointer

      L      DBOutDaten                                      // Outdaten-DB
      L      0                                               // Angegeben ?
      ==I                                                    // Nein
      JC     Nw09

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

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


      L      SFC_RET_VAL
      L      2#0000_0000_0000_0000                           // Fehler vorhanden ?
      <>I                                                    // Ja !
      JC     Err5                                            // Undefinierte Outdaten

      L      NoneD [AR2,]                                    // Kennung, Adresse
      L      16#00FF_FFFF                                    // Ohne Kennung
      AW
      SRW    3                                               // Ohne Bit
      T      OutDaten_Startpunkt

      L      OutDaten_Startpunkt
      L      SFC_DB_LENGTH
      >I                                                     // Outdaten-DB ist zu kurz
      JC     Err5                                            // Undefinierte Outdaten


--- NW 8: Quelle-Pointer erzeugen: ---
Nw09: L      16#1004                                         // Kennung 10 + Word=04
      T      LW0
      T      LW10                                            // Any-Kennung, Datentyp
      L      Datensatzlaenge                                 // Datenwords speichern
      T      LW2
      T      LW12                                            // Wiederholungen

// DATEN-Pointer übernehmen:
      L      SSDB
      T      LW4                                             // DB_Nummer
      L      Suchzeiger                                      // Adresse
      SLD    3
      L      16#8400_0000                                    // Kennung: Daten
      OD
      T      LD6                                             // Kennung, Adresse

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

      L      DBOutDaten
      T      LW14                                            // DB_Nummer
      L      OutDaten_Pointer
      T      LD16                                            // Kennung, Adresse

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

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

      L      SSDW
      +      12                                              // im 12.DW speichern
      ITD
      SLD    3
      T      AR1Zeiger                                       // /Statt AR1 (ging nur bis DB-Länge <= 8191 Bytes)

      L      Suchzeiger                                      // Suchzeiger
      OPN    DB[DBDatenliste]
      T      DBW [AR1Zeiger]                                 // Speicherung letzter Zugriff

      L      Suchzeiger                                      // Suchzeiger
      +      -20                                             // Offeset 1.DS
      L      Datenblock_inBytes                              // Datenblocklänge in Bytes
      /I
      +      1                                               // Position errechnen
      T      Position                                        // Daten stehen an angegebener Position in Datenbank


--- NW 9: Weitersuchen aktiv ? Datensatz vorhanden oder 0 ? ---
      AN     Weitersuchen
      JC     Ende

      L      OutDaten_Pointer
      LAR2

      L      Datensatzlaenge
L110: T      Schleife

      L      DBOutDaten                                      // Outdaten-DB
      L      0                                               // Angegeben ?
      ==I                                                    // Nein
      JC     W111

      OPN    DB[DBOutDaten]

W111: L      NoneW [AR2,]                                    // Outdaten überprüfen
      L      0                                               // Etwas angegeben ?
      <>I                                                    // Ja !
      JC     W112                                            // Ok

      ADDAR2 P#2.0

      L      Schleife
      LOOP   L110

      L      2#0000_0000_0100_0000                           // Daten sind nicht vorhanden
      T      tRE_VAL                                         // Ok-Status
      JU     Ende

W112: L      2#0000_0000_1000_0000                           // Daten sind vorhanden
      T      tRE_VAL                                         // Ok-Status
      JU     Ende


--- NW 10: Fehlerausgabe / RET_VAL ---
Ende: SET                                                    // VKE = 1 ohne Fehler !!!
      L      tRE_VAL                                         // Ok-Status
      JU     Ok
Err0: L      2#0000_0000_0000_0001                           // Kein Datenlistebereich
      JU     Err
Err1: L      2#0000_0000_0000_0010                           // SFC20-Aufruf mit Fehler
      JU     Err
Err2: L      2#0000_0000_0000_0100                           // Listenende ist erreicht
      JU     Err
Err3: L      2#0000_0000_0000_1000                           // Falscher Parameter bei Aufruf
      JU     Err
Err4: L      2#0000_0000_0001_0000                           // Undefinierte Suchdaten
      JU     Err
Err5: L      2#0000_0000_0010_0000                           // Undefinierte OUTDaten
      JU     Err
Err6: L      2#0000_0000_0100_0000                           // Datensatz nicht vorhanden

Err:  CLR                                                    // VKE = 0 bei Fehler !!!

Ok:   T      tRE_VAL
      SAVE                                                   // VKE in BIE-Bit speichern

      L      AR2_Speicher                                    // AR2 zurückspeichern
      LAR2


--- NW 11:  ---
      L      tRE_VAL
      T      RE_VAL


