FUNCTION "FIFOSearch" : Void
TITLE = Fifo-Modul
{ S7_Optimized_Access := 'FALSE' }
AUTHOR : IBAE
FAMILY : FIFO
NAME : FifoIn
VERSION : 0.1
//COPYRIGHT by Ingenieurbüro A.Emmert
//Ortsstr.33, D-869925 Fuchstal (Germany)
//Tel.: 0049(0)8243-960629
//Version: KyungBang00 / 14.04.2009
//
//Datenblock in Fifo suchen
//SSDB:    FIFO-DB
//SSDW:    FIFO-1.DW
//SEARCHDATEN: Pointer, wo zu suchende Daten stehen (P#DB1.DBX0.0, P#M220.0) 
//RE_POS: Position an welcher sich Datensatz befindet
//RE_VAL:  Rückmeldungen:
//   Bit0: Kein Fifobereich / falscher Kopfinhalt / Endekennung
//   Bit1: SFC20-Aufruf mit Fehler
//   Bit2: Fifo ist leer
//   Bit3: Frei
//   Bit4: Frei
//   Bit5: Bringzeiger ist ausserhalb
//   Bit6: Holzeiger ist ausserhalb
//   Bit7: Versatz Bring-/Holzeiger
//
   VAR_INPUT 
      SSDB : Int;   // Schnittstellen-DB
      SSDW : Int;   // Schnittstellen-1.DW
      SEARCHDATEN : Pointer;   // SuchDaten-Schnittstelle
      Laenge : Int;   // Anzahl der DWs zum Vergleichen im Datensatz
   END_VAR

   VAR_OUTPUT 
      RE_POS : Int;   // Position des Eintrags, der gesuchten Daten
      RE_VAL : Byte;   // Rückmeldungen
   END_VAR

   VAR_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
      MinHolzeiger : Int;   // Minimum Holzeiger
      MaxHolzeiger : Int;   // Maximum Holzeiger
      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
      AR2_Speicher : DWord;   // Adress-Register 2 zwischenspeichern
      DBSuchdaten : Word;   // Solldaten-DB, falls angegeben
      SuchDaten_Startpunkt : Word;   // SuchDaten-Startpunkt: Adresse
      SuchZeiger : Word;   // Suchzeiger
      Schleife : Word;   // Loopzähler
      NixSave : Bool;   // Status nicht speichern
      SFC_WRITE_PROT : Bool;   // Rückmeldung SFC-Aufruf
      AR1Zeiger : DWord;   // Statt AR1 (ging nur bis DB-Länge <= 8191 Bytes)
      AR1Start : DInt;   // Startwert mit Offset 0
      sRE_POS : Int;   // Position des Eintrags, der gesuchten Daten
   END_VAR


BEGIN
NETWORK
TITLE = Schnittstellen-DB sinnvoll ?
      TAR2;
      T #AR2_Speicher;//AR2 zwischenspeichern

      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 "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;
      = #NixSave;//Status nicht speichern
      O #SFC_WRITE_PROT;
      SPB Err0;//kein Fifobereich

NETWORK
TITLE = Fifokopfdaten holen
//Quelle-Pointer erzeugen:
      L 16#1004;//Kennung 10 + Word=04
      T #sRE_POS;//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 BLKMOV//1.-6.DW FIFO holen
      {blk_type := 'Variant'}
      (  SRCBLK                      := #Quelle , 
         RET_VAL                     := #SFC_RET_VAL , 
         DSTBLK                      := P#L20.0 WORD 6
      );

      L #Status;
      L 2#0000_0000_1110_0000;
      UW;
      T #Err;
      SPP Err;//Kapitalfehler vorhanden

      L #SFC_RET_VAL;
      L 2#0000_0000_0000_0000;
      <>I;
      SPB Err1;

NETWORK
TITLE = Zeigerüberprüfung
      L #Kopf;//Fifo-Kopf
      L 16#FF;//= Fifokennung ?
      <>I;//Nein !
      = #NixSave;//Status nicht speichern
      SPB Err0;//kein Fifobereich

      L 1;
      L #Datensatzlaenge;//Datenblocklänge
      >I;
      SPB Err0;//kein Fifobereich

      L 128;
      >I;
      SPB Err0;//kein Fifobereich

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

      L #SSDW;
      + 40;//Speichern ab 20.DW
      T #MinHolzeiger;//Minimum Holzeiger

      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 #MaxHolzeiger;//Maximum Holzeiger

      L #Datensatzlaenge;//Datenblocklänge
      L 2;//DB byteorientiert
      *I;
      L #MaxHolzeiger;//Maximum Holzeiger
      +I;//Zeiger Endekennung
      T #Fifo_Ende;
      ITD;
      T #AR1Start;//Startwert mit Offset 0
      SLD 3;
      T #AR1Zeiger;///Statt Dyn.Bereichsstop (ging nur bis DB-Länge <= 8191 Bytes)

      AUF DB[ #DBFifo];

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

      L DBW[ #AR1Zeiger];
      L 16#FFEE;//Fifo-Endekennung ?
      <>I;//Nein !
      SPB Err0;//kein Fifobereich

      L #MinHolzeiger;//Minimum Holzeiger
      L #Holzeiger;//Holzeiger
      <=I;//Ok ?
      SPB W300;//Ja!

      L 0;//Grundstellung ?
      <>I;//Nein !
      SPB Err6;//Holzeiger ist ausserhalb

      L #Bringzeiger;//Bringzeiger Grundstellung ?
      <>I;//Nein !
      SPB Err6;//Holzeiger ist ausserhalb

      L #Anzahl;//Anzahl Datensätze
      L 0;//Grundstellung ?
      <>I;//Nein !
      SPB Err6;//Holzeiger ist ausserhalb

      L #MinHolzeiger;//Minimum Holzeiger
      T #Bringzeiger;//Bringzeiger
      T #Holzeiger;//Holzeiger

      SPA Err2;//Fifo ist leer

W300:      L #MaxHolzeiger;//Maximum Holzeiger
      <=I;//Ok ?
      SPB W301;//Ja!
      SPA Err6;//Holzeiger ist ausserhalb


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

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

      L #Anzahl;//Anzahl der gespeicherten Datensätze
      L 0;
      ==I;//Keine Datensätze vorhanden !
      SPB Err2;//Fifo ist leer

NETWORK
TITLE = Fifodaten suchen
      L 1;
      T #sRE_POS;//RET-POS

      L #Holzeiger;//Holzeiger
      T #SuchZeiger;//Suchzeiger
W400:      ITD;
      T #AR1Start;//Startwert mit Offset 0
      SLD 3;
      T #AR1Zeiger;///Statt Dyn.Bereichsstop (ging nur bis DB-Länge <= 8191 Bytes)

//DATEN-Pointer übernehmen:
      L P##SEARCHDATEN;
      LAR2;

      L W[ AR2, P#0.0];
      T #DBSuchdaten;//Solldaten-DB

      L #DBSuchdaten;//Solldaten-DB
      L 0;//Angegeben ?
      ==I;//Nein 
      SPB W401;

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

      CALL "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 !
      SPB Err1;//SFC20-Aufruf mit Fehler

      L D[ AR2, P#2.0];//Kennung, Adresse
      L 16#00FF_FFFF;//Ohne Kennung
      UW;
      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;//Indaten-DB ist zu kurz
      SPB Err1;//SFC20-Aufruf mit Fehler

W401:      L D[ AR2, P#2.0];//Kennung, Adresse
      LAR2;

      L #Laenge;//Anzahl der DWs zum Vergleichen im Datensatz
L400:      T #Schleife;

      L #DBSuchdaten;//Solldaten-DB
      L 0;//Angegeben ?
      ==I;//Nein 
      SPB W402;

      AUF DB[ #DBSuchdaten];

W402:      L W[ AR2, P#0.0];//Mit Solldaten überprüfen
      AUF DB[ #DBFifo];
      L DBW[ #AR1Zeiger];//Fifo-Daten lesen
      <>I;//nicht identisch !
      SPB W403;

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

      +AR2 P#2.0;

      L #Schleife;
      LOOP L400;

      SPA Ende;//Datensatz ist in Fifo enthalten

W403:      L #sRE_POS;//RET-POS 
      + 1;
      T #sRE_POS;//RET-POS 
      L #Anzahl;//Anzahl der Daten im Fifo
      >I;//Alle Datensätze sind durchsucht
      SPB Err2;

      L #Datensatzlaenge;//Datenblocklänge
      L 2;//DB byteorientiert
      *I;
      L #SuchZeiger;//Suchzeiger
      +I;
      T #SuchZeiger;//Suchzeiger
      L #MaxHolzeiger;//Maximum Holzeiger
      <=I;//Ende erreicht? Nein!
      SPB W404;

      L #MinHolzeiger;//Minimum Holzeiger
      T #SuchZeiger;

W404:      L #SuchZeiger;//Suchzeiger
      SPA W400;

NETWORK
TITLE = Fehlerausgabe / RET_VAL
Ende:      SET;//VKE = 1 ohne Fehler !!!
      SPA Ok;
Err0:      L 2#0000_0000_0000_0001;//Kein Fifobereich
      T #Err;
      SPA Err;
Err1:      S %L32.1;//SFC20-Aufruf mit Fehler
      SPA Err;
Err2:      S %L32.2;//Fifo ist leer
      SPA Err;
Err6:      S %L32.6;//Holzeiger außerhalb
      SPA Err;
Err7:      S %L32.7;//Versatz Bring-/Holzeiger

Err:      L 0;
      T #sRE_POS;//RET-POS  = 0

      CLR;//VKE = 0 bei Fehler !!!

Ok:      L #Err;
      T #RE_VAL;
      L #Status;
      OW;
      T #Status;

      SAVE;//VKE in BIE-Bit speichern  

NETWORK
TITLE = Fifokopfdaten speichern
      L #AR2_Speicher;//AR2 zurückspeichern
      LAR2;

      U %L32.0;//Falscher Parameter
      U #NixSave;//Status nicht speichern
      BEB;

      L #SSDW;
      + 10;//Status  
      ITD;
      T #AR1Start;//Startwert mit Offset 0
      SLD 3;
      T #AR1Zeiger;///Statt Dyn.Bereichsstop (ging nur bis DB-Länge <= 8191 Bytes)

      AUF DB[ #DBFifo];

      L #Err;
      T DBW[ #AR1Zeiger];

NETWORK
TITLE = 
      L #sRE_POS;
      T #RE_POS;
END_FUNCTION

