Code:
' ┌────────────────────┬───&#947 2;──────────┬───────┬──────&#9 472;───┬─────────────────────& #9488;
' │                    │ XINPUT2.PBL  │ 1.1.0 │ 09.09.94 │ UNIT                │
' │ IDENTIFIKATION     ├──────────────┴───────┴─&#947 2;────────┴────────────────&#9 472;────┤
' │                    │ Vorwärts- und rückwärts in sequentiellen Dateien lesen│
' ├────────────────────┼───&#947 2;─────────────────────────&#9 472;─────────────────────────& #9508;
' │ AUTOR              │ M.Hoffmann, Friedensallee 105, 2000 Hamburg 50        │
' ├────────────────────┼───&#947 2;─────────────────────────&#9 472;─────────────────────────& #9508;
' │ FUNKTION           │ LESEN von sequentiellen ASCII-Dateien vorwärts UND    │
' │                    │ rückwärts (satz- oder blockweise).                    │
' │                    │ Es kann nur eine Datei zur Zeit in diesem Modus       │
' │                    │ bearbeitet werden.                                    │
' ├────────────────────┼───&#947 2;─────────────────────────&#9 472;─────────────────────────& #9508;
' │ HISTORIE           │ XINPUT1 - Vorgängerversion, in bestimmten Kontexten   │
' │                    │           fehlerhaft                                  │
' │                    │ XINPUT2 - Fehler in LastRec$ behoben                  │
' │                    │         - OPEN READONLY, daher Attributhandling       │
' │                    │           entfallen                                   │
' │                    │         - OPEN im SHARE-Modus für Netzwerke           │
' │                    │ 1.1.0   - Zusätzliche Funktion NextAvail              │
' ├────────────────────┼───&#947 2;─────────────────────────&#9 472;─────────────────────────& #9508;
' │ ENTWICKLUNGSSYSTEM │ PowerBasic 2.10a                                      │
' ├────────────────────┼───&#947 2;─────────────────────────&#9 472;─────────────────────────& #9508;
' │ VORAUSSETZUNGEN    │ -                                                     │
' ├────────────────────┼───&#947 2;─────────────────────────&#9 472;─────────────────────────& #9508;
' │ DATEIEN            │ Beliebige sequentielle Datei als EINGABE              │
' ├────────────────────┴───&#947 2;─────────────────────────&#9 472;─────────────────────────& #9508;
' │ IMPLEMENTATION                                                             │
' ├────────────────────┬───&#947 2;─────────────────────────&#9 472;─────────────────────────& #9508;
' │ Routine            │ Parameter und Erläuterung                             │
' ã════════════════════Ï═════&#9 552;═════════════════════════& #9552;═══════════════════════Á
' │ FUNCTION XOpen     │ (Dateiname$,MaximalePufferLänge,Modus)                │
' │                    │                                                       │
' │                    │ Modus 0: CRLF berücksichtigen                         │
' │                    │ Modus 1: HexModus                                     │
' │                    │                                                       │
' │                    │ XOpen( 0):  ok                                        │
' │                    │ XOpen(-1):  XOpen ist bereits aktiv                   │
' │                    │ XOpen(-2):  Datei nicht gefunden                      │
' ├────────────────────┼───&#947 2;─────────────────────────&#9 472;─────────────────────────& #9508;
' │ FUNCTION XClose    │ ()                                                    │
' │                    │                                                       │
' │                    │ XClose( 0): ok                                        │
' │                    │ XClose(-1): XOpen ist nicht aktiv                     │
' ├────────────────────┼───&#947 2;─────────────────────────&#9 472;─────────────────────────& #9508;
' │ FUNCTION NextRec$  │ (Rc)                                                  │
' │                    │                                                       │
' │                    │ RC( 0):     ok                                        │
' │                    │ RC(-1):     XOpen ist nicht aktiv                     │
' │                    │ RC(-2):     End_of_File erreicht                      │
' │                    │ RC(-3):     Puffer zu klein                           │
' ├────────────────────┼───&#947 2;─────────────────────────&#9 472;─────────────────────────& #9508;
' │ FUNCTION PrevRec$  │ (Rc)                                                  │
' │                    │                                                       │
' │                    │ RC( 0):     ok                                        │
' │                    │ RC(-1):     XOpen ist nicht aktiv                     │
' │                    │ RC(-2):     Begin_of_File erreicht                    │
' │                    │ RC(-3):     Puffer zu klein                           │
' ├────────────────────┼───&#947 2;─────────────────────────&#9 472;─────────────────────────& #9508;
' │ FUNCTION FirstRec$ │ (Rc)                                                  │
' │                    │                                                       │
' │                    │ RC( 0):     ok                                        │
' │                    │ RC(-1):     XOpen ist nicht aktiv                     │
' ├────────────────────┼───&#947 2;─────────────────────────&#9 472;─────────────────────────& #9508;
' │ FUNCTION LastRec$  │ (Rc)                                                  │
' │                    │                                                       │
' │                    │ RC( 0):     ok                                        │
' │                    │ RC(-1):     XOpen ist nicht aktiv                     │
' ├────────────────────┼───&#947 2;─────────────────────────&#9 472;─────────────────────────& #9508;
' │ FUNCTION NextAvail │  0:         weiterer Satz verfügbar                   │
' │                    │ -1:         bei nächstem Lesen EOF                    │
' ├────────────────────┼───&#947 2;─────────────────────────&#9 472;─────────────────────────& #9508;
' │ SONSTIGES          │ Hinweise zur Puffergröße                              │
' │                    │ ------------------------                              │
' │                    │                                                       │
' │                    │  Eine zu große Puffergröße erniedrigt drastisch      │
' │                    │   die Performance.                                    │
' │                    │  Zu kleine Puffer führen dazu, daß die Sätze der     │
' │                    │   ASCII-Datei nicht in einem Stück, sondern blockweise│
' │                    │   zurückgeliefert werden.                             │
' │                    │   Hierbei können Fehler auftreten.                    │
' └────────────────────┴───&#947 2;─────────────────────────&#9 472;─────────────────────────& #9496;

' ┌────────────────────────&#947 2;─────────────────────────&#9 472;─────────────────────────& #9488;
' │ COMPILEROPTIONEN                                                           │
' └────────────────────────&#947 2;─────────────────────────&#9 472;─────────────────────────& #9496;

$COM      0
$COMPILE  UNIT
$CPU      80386
$DEBUG    MAP-,PBDEBUG-,PATH-,UNIT-
$DIM      ARRAY
$ERROR    BOUNDS-,NUMERIC-,OVERFLOW-,STACK-
$EVENT    OFF
$FLOAT    EMULATE
$LIB      COM-,LPT-,CGA-,EGA-,VGA-,FULLFLOAT-,IPRINT-
$OPTIMIZE SIZE
$OPTION   CNTLBREAK-,GOSUB-,SIGNED-
$SOUND    0
$STACK    &H800
$STATIC
$STRING   1

DEFINT A-Z

' ┌────────────────────────&#947 2;─────────────────────────&#9 472;─────────────────────────& #9488;
' │ UNITGLOBALS UND DEKLARATIONEN                                              │
' └────────────────────────&#947 2;─────────────────────────&#9 472;─────────────────────────& #9496;

   SHARED   XFile$        ' Name der geöffneten Datei
   SHARED   MaxBufferLen  ' Pufferlänge für Leseoperationen (‗ größte Recordlänge)
   SHARED   FileHandle    ' Dateinummer der geöffneten Datei
   EXTERNAL ActualRecPos& ' Offset des aktuellen Satzes in der Datei
   SHARED   Modus         ' Bearbeitungsmodus ASCII/HEX

' ┌────────────────────────&#947 2;─────────────────────────&#9 472;─────────────────────────& #9488;
' │ FUNKTIONEN                                                                 │
' └────────────────────────&#947 2;─────────────────────────&#9 472;─────────────────────────& #9496;

FUNCTION XOpen (File$,MaxLen,Mods) LOCAL PUBLIC

  '
  ' Es kann nur EINE Datei zugleich mit XOpen geöffnet werden!
  '
  ' Modus 0: CRLF berücksichtigen
  ' Modus 1: CRLF ignorieren
  '

   IF MaxBufferLen THEN

     ' already in use

      XOpen        = -1

   ELSEIF LEN(DIR$(File$,55)) THEN

      ' SHARED's setzen

      XFile$       = File$
      MaxBufferLen = MaxLen
      FileHandle   = FREEFILE
      XOpen        = 0
      Modus        = Mods

      OPEN XFile$ FOR BINARY ACCESS READ SHARED AS #FileHandle

   ELSE

     ' file not found

      XOpen        = -2

  END IF

END FUNCTION

' ------------------------------------------------------------------------------

FUNCTION XClose LOCAL PUBLIC

   IF MaxBufferLen THEN

      CLOSE #FileHandle
      MaxBufferLen = 0
      FileHandle   = 0
      XFile$       = ""
      XClose       = 0
      Modus        = 0

   ELSE

      ' no file in use

      XClose       = -1

   END IF

END FUNCTION

' ------------------------------------------------------------------------------

FUNCTION NextRec$ (Rc) LOCAL PUBLIC

   NextRec$ = ""

   IF MaxBufferLen THEN

      IF SEEK(FileHandle) < LOF(FileHandle) THEN

         ActualRecPos& = SEEK(FileHandle)
         GET$ #FileHandle,MaxBufferLen,Buf$

         IF TALLY(Buf$,CHR$(13,10)) > 0 AND Modus = 0 THEN

            Ad = 2
            Rc = 0
            Buf$     = EXTRACT$(Buf$,CHR$(13,10))

         ELSE

            IF Modus = 0 THEN
               ' buffer too short in ASCII-Mode, ignore crlf
               Rc = -3
            ELSE
               Rc = 0
            END IF
            Ad = 0

         END IF

         SEEK #FileHandle,ActualRecPos&+LEN(Buf$)+Ad
         NextRec$ = Buf$

      ELSE

         ' end of file reached
         Rc = -2

      END IF

   ELSE

      ' no file in use
      Rc = -1

   END IF

END FUNCTION

' ------------------------------------------------------------------------------

FUNCTION NextAvail LOCAL PUBLIC
   IF SEEK(FileHandle) < LOF(FileHandle) THEN
      NextAvail =  0
   ELSE
      NextAvail = -1
   END IF
END FUNCTION

' ------------------------------------------------------------------------------

FUNCTION PrevRec$ (Rc) LOCAL PUBLIC

   PrevRec$      = ""

   IF MaxBufferLen THEN

      IF ActualRecPos& THEN

         BlockSub&   = ActualRecPos&-MaxBufferLen
         IF BlockSub& < 0 THEN
            BlockSub& = ABS(BlockSub&)
         ELSE
            BlockSub& = 0
         END IF

         SEEK #FileHandle,ActualRecPos&-MaxBufferLen+BlockSub&
         GET$ #FileHandle,MaxBufferLen-BlockSub&,Buf$

         IF TALLY(Buf$,CHR$(13,10)) > 0 AND Modus = 0 THEN

            Ad = 2
            Rc = 0
            DO UNTIL TALLY(Buf$,CHR$(13,10)) = 1
               Buf$ = MID$(Buf$,INSTR(Buf$,CHR$(13,10))+2)
            LOOP
            Buf$ = EXTRACT$(Buf$,CHR$(13,10))

         ELSE

            IF Modus = 0 THEN
               ' buffer too short in ASCII-Mode, ignore crlf
               Rc = -3
            ELSE
               Rc = 0
            END IF
            Ad = 0

         END IF

         Temp&         = SEEK(FileHandle)
         SEEK #FileHandle,ActualRecPos&
         ActualRecPos& = Temp&-LEN(Buf$)-Ad
         PrevRec$      = Buf$

      ELSE

         ' top of file reached
         Rc            = -4

      END IF

   ELSE

      ' no file in use
      Rc       = -1

   END IF

END FUNCTION

' ------------------------------------------------------------------------------

FUNCTION FirstRec$ (Rc) LOCAL PUBLIC

   IF MaxBufferLen THEN

      SEEK(FileHandle),0
      ActualRecPos& =  0
      Rc = 0
      FirstRec$ = NextRec$ (Rc)

   ELSE

      ' no file in use
      Rc = -1

   END IF

END FUNCTION

' ------------------------------------------------------------------------------

FUNCTION LastRec$ (Rc) LOCAL PUBLIC

   IF MaxBufferLen THEN

      ActualRecPos& = LOF(FileHandle)
      Rc = 0
      LastRec$ = PrevRec$ (Rc)

   ELSE

      ' no file in use
      Rc = -1

   END IF

END FUNCTION

'===============================================================================
------------------