
=============================================================================

              PowerBASIC-FAQ fr die Versionen 3.00, 3.10 & 3.20
                            deutsche Version (DOS)

             (c) 1995/96 von Thomas Gohel, Alle Rechte vorbehalten
                       Stand: 16.12.1996 - Version 0.79

     Tip's, Trick's, Bug's und andere mehr oder weniger wichtige Sachen

=============================================================================


    =====================
    Vorwort zu dieser FAQ
    =====================

    Die in dieser FAQ aufgefhrten Hinweise erfolgen ohne Bercksichtigung
    eventueller Copyright-Verletzung und ohne Rcksichtname eventuell einge-
    tragener Warenzeichen.
    Des weiteren garantiert der Autor nicht fr Richtigkeit der hier ange-
    fhrten Probleme, Tip's & Bug's etc. Sollten Sie Anregungen oder Ver-
    besserungsvorschlge haben, so stehe ich diesen Sachen offen gegenber
    und werde dies in zuknftigen Versionen der FAQ mit einfliessen lassen.
        Ich mchte weiter darauf hinweisen, das einige der hier unter dem
    Abschnitt 'Fehler' aufgefhrten Probleme im weiteren Sinne keine Bugs
    darstellen. Diese Ungereimtheiten bzw. verschwiegenen Einschrnkungen
    gilt es hier fr die Allgemeinheit zu dokumentieren (das es in Zukunft
    ein besseres PowerBASIC gibt).


    =======================
    Verbesserungsvorschlge
    =======================

    Verbesserungsvorschlge knnen Sie jederzeit an den Autor dieser FAQ
    richten, die aktuellen Netmail-Adressen lauten:

|           Thomas Gohel@2:2410/330.1  (FidoNet)
            pbfaq@pbsound.snafu.de     (InterNet und Unternetze)

    Des weiteren besteht die Mglichkeit sich OnLine in eine Mailbox einzu-
    loggen, in der der Autor dieser FAQ erreichbar ist:

|           Port 1: (030) 473 00 910 (PBSOUND HQ, Berlin - 64.0, X75, ISDNC)
|           Port 2: (030) 473 00 910 (PBSOUND HQ, Berlin - 28.8, VFC, V34)

    Hier knnen Sie Ihre Vorschlge und Probleme los werden. Bitte schreiben
    Sie dazu Ihre Nachricht in der PBSOUND-Nachrichten-Area. Eine Antwort
    sollten Sie sptestens nach 48 Stunden erhalten.


    ==================================
    Bezug der aktuellen PowerBASIC-FAQ
    ==================================

    Die aktuelle PowerBASIC-FAQ knnen Sie jederzeit aus meiner Stammbox
    Online downloaden. Die Telefonnummern lauten:

|           Port 1: (030) 473 00 910 (PBSOUND HQ, Berlin - 64.0, X75, ISDNC)
|           Port 2: (030) 473 00 910 (PBSOUND HQ, Berlin - 28.8, VFC, V34)

    Wechseln Sie nach dem Login in die 'PowerBASIC-FAQ'-Filearea.
    Des weiteren finden Sie hier noch 16 weitere 'PowerBASIC-Fileareas'

        PowerBASIC: PBSOUND
        PowerBASIC: Sound Blaster
        PowerBASIC: FAQ
        PowerBASIC: Sourcen (allgemein)
        PowerBASIC: Sourcen (Deutschland)
        PowerBASIC: Sourcen (Netherlands)
        PowerBASIC: Toolkits (allgemein)
        PowerBASIC: Toolkits (Deutschland)
        PowerBASIC: Toolkits (Netherlands)
        PowerBASIC: Grafik (allgemein)
        PowerBASIC: Grafik (Deutschland)
        PowerBASIC: Grafik (Netherlands)
        PowerBASIC: DF, BBS und FidoNet Sourcen
        PowerBASIC: allgemeine Pakete und Info's
        PowerBASIC: Demos
        PowerBASIC: User Uploads / Incoming

    Viele in dieser FAQ erwhnten Sourcen und Toolboxen knnen Sie hier
    Online oder auch per FidoNet downloaden.

    InterNet-Teilnehmer knnen die PowerBASIC-FAQ jederzeit via World
    Wide Web (WWW) unter:

            - http://www.snafu.de/~pbsound/

    erreichen.

    Ein Request der FAQ ber das FidoNet ist unter dem Magic 'PBFAQ'
    mglich!

|           Port 1: (030) 473 00 910 (PBSOUND HQ, Berlin - 64.0, X75, ISDNC)
|           Port 2: (030) 473 00 910 (PBSOUND HQ, Berlin - 28.8, VFC, V34)

    Weiter PowerBASIC-Magics sind: PBSOUND und PBFILES.


    ============
    Gesamtinhalt
    ============

    1.  Bezug, Toolboxen, Preise und Info's zu PowerBASIC
    2.  Fehler/Ungereimheiten in den PowerBASIC-Versionen 3.0, 3.1 & 3.2
    3.  PowerBASIC und der CoProzessor
    4.  Standard-Probleme
    5.  Tip's in Verbindung mit dem InLine-Assembler
    6.  Tip's in Verbindung mit Pointern
    7.  Tip's in Verbindung mit Turbo-C bzw. Borland C++
    8.  Tip's bei der Konvertierung von Sourcen von PDS nach PowerBASIC 3.x
    9.  vorhandene Shareware & Public Domain-Lsungen
    10. Die PowerBASIC-Leute



    ====================================================
    1. Bezug, Toolboxen, Preise und Info's zu PowerBASIC
    ====================================================

    1.1. Die aktuelle Version von PowerBASIC
    1.2. Der Originalhersteller von PowerBASIC
    1.3. Deutschsprachiger Raum
    1.4. deutsche PowerBASIC-Preise
    1.5. The Basic Network - BasNet
    1.6. Neuigkeiten in der PowerBASIC 3.1 Version
    1.7. Neuigkeiten in der PowerBASIC 3.2 Version
    1.8. PowerBASIC - The next Generation


    1.1. Die aktuelle Version von PowerBASIC
    ----------------------------------------
    Die aktuelle Version von PowerBASIC in Deutschland (seit Oktober 1995)
    ist die Version 3.20. In den USA und in anderen Staaten ist diese
    Version bereits seit September 1995 verfgbar.


    1.2. Der Originalhersteller von PowerBASIC
    ------------------------------------------
    PowerBASIC wird und wurde in den USA entwickelt und es befinden sich
    natrlich auch diverse Mglichkeiten mit diesen Leuten in Kontakt zu
    treten. Hier die aktuell bekannte Kontaktadresse von PowerBASIC Inc.:

    Addresse:
            PowerBASIC, Inc.
            316 Mid Valley Center
            Carmel, Ca  93923
    Verkauf:
            Bestellung    : (800) 780-7707
            Kundendienst  : (408) 659-8000
            Fax           : (408) 659-8008
    Technischer Support:
            Voice         : (408) 659-8000
            Fax           : (408) 659-8008
            BBS           : (408) 659-7401 (8-N-1, 2400-28.8k)
    CompuServe:
            GO POWERBASIC, Sektion 12
            Verkauf und Marketing         : 73621,2613
            Technischer Support           : 74431,3520
            Forschung & Entwicklung       : 75300,1742
    InterNet:
            World Wide Web                : www.powerbasic.com
            Liste der InterNet Addressen  : info@powerbasic.com
            Bestellung                    : order@powerbasic.com
            Produktlisten                 : products@powerbasic.com
            Produkte fr PowerBASIC       : third@powerbasic.com
            Verkauf und Marketing         : sales@powerbasic.com
            Technischer Support           : support@powerbasic.com
            Forschung und Entwicklung     : r&d@powerbasic.com
            100 Grnde warum PowerBASIC
            besser als QuickBASIC ist     : 100ways@powerbasic.com
            Anregungen fr zuknftige
            PowerBASIC Versionen          : suggest@powerbasic.com
    FTP- & WWW-Sites:
            http://www.snafu.de/~pbsound/
            http://145.89.78.151/~excel/pb.html
            http://www.webgeek.com/dave/
            http://www.scruz.net/~navarro/dave/programming/
            http://www.leo.org/pub/comp/platforms/pc/msdos/programming/pbasic/
            http://www.fys.ruu.nl/~bergmann/basic.html
|           http://www.zephyrsoftware.com
            http://www.blarg.net/~future/shareware.html
            http://www.cdrom.com/simtel.net/msdos/basic.html
            http://www.cyberbox.north.de/FILES/DOS/dos106.html


    1.3. Deutschsprachiger Raum
    ---------------------------
    In Deutschland wird PowerBASIC vom deutschen Distributor: "Kirschbaum
    Software GmbH" vertrieben. Die aktuelle Adresse lautet:

            Kirschbaum Software GmbH
            Kronau 15
            83550 Emmering
            Tel.: 08067/9038-0
            Fax.: 08067/903898

    Die derzeit aktuelle Version von PowerBASIC ist die Version 3.20. Als
    aktuelle Toolboxen bietet Kirschbaum fr PowerBASIC folgende Pakete an:

        PB/DLL      - PowerBASIC DLL-Compiler fr Windows
        PowerGRAPH  - fr grafische Menoberflchen (PCX, Fonts, etc.)
        PowerISAM   - Datenbanken (ebenfalls verfgbar in Englisch bei
                      PowerBASIC Inc.)
        PowerTOOLS  - SAA-Oberflche, Hilfesystem, ntzliche Routinen
        PB/xtra     - Sammlung von Sharewareprogrammen und Sourcecode

    Kischbaum besitzt keine Mailbox bzw. offizielle EMailadressen! Allerdings
    existieren fr die Mitarbeiter bzw. fr die Toolbox-Entwickler eigene
    EMail-Adressen und Support-Foren bzw. nicht ffentliche Newsgroup etc.
    In diesem Fall sehen Sie bitte in dem Handbuch der betreffenden Toolbox
    nach.


    1.4. deutsche PowerBASIC-Preise
    -------------------------------
    Alle hier genannten Preise sind nicht verbindlich! nderungen oder Ab-
    weichungen knnen jederzeit auftreten! Eine aktuelle und gltige Preis-
    liste kann jederzeit bei Kirschbaum Software per FAX angefordert werden.

|   Vollversion: 199,-DM
    Vollversion 3.2 fr Studenten, Schler: 150,-DM
    Update von VOBIS-Basisversion 2.10f auf V3.2: 149,-DM
    Update von V2.10 auf V3.2: 149,-DM
    Update einer 3.x-Version auf V3.2: 36,80DM
    PB/DLL: 299,-DM


    1.5. The Basic Network - BasNet
    -------------------------------
    Fr Leute mit Modem bietet sich zum Erfahrungsaustausch mit anderen
    PowerBASIC-Leuten das "BasNet" an. Hier knnen Sie mit anderen PB-
    Programmierern Ihre "Programmier"-Probleme klren und auch andere
    ntigen Informationen, Sourcen oder auch Toolboxen erhalten. Fr weitere
    Informationen zum "Basic Network" wenden Sie sich bitte an die nach-
    folgend angegebenen Adressen:

    - Post, Online-Zugang (ber Mailbox), Fido- & BasNet:

            performance Multimedia
            Rmerstr. 46
      63128 Dietzenbach
            Deutschland

            Fax: 06074-29749
            Mailbox: 06074-41307  (24h, ANSI, 2400-19200bps, 8N1)
                     06074-812355 (24h, ANSI, 2400-14400bps, 8N1)
                     06074-812356 (24h, ANSI, ISDN)
            E-Mail-Adresse: Christian Wendler@2:244/1490


    1.6. Neuigkeiten in der PowerBASIC 3.1 Version
    ----------------------------------------------
    - Benutzerdefinierte TYPE- und UNION-Variablen knnen nun direkt
      verglichen werden.
    - Konstanten im Binaer-, Hex- oder Oktalformat (&B, &H, &O) knnen
      einem bestimmten Datentyp zugeordnet werden, indem man den ent-
      sprechenden Identifier anhngt.

      Beispiel:
              A?? = &HFFFF??   '= 65535
              B%  = &HFFFF%    '= -1

    - Konstanten (%Test) knnen ab dieser PowerBASIC-Version Werte im
      64-Bit-Wertebereich (vorzeichenbehaftet) annehmen.

      Beispiele :
              %MaxAnzahl = 500000
              %Konst1    = &HFFFF   '= -1 (Integer)
              %Konst2    = &H0FFFF  '= 65535 (Long)

      Bei Angaben Binaer-, Hexadezimal oder Oktalformat kann man durch
      Angeben oder Weglassen einer fhrenden Null festlegen, ob der
      erzeugte Wert vorzeichenbehaftet ist oder nicht.

    - BIN$, HEX$ und OCT$ knnen jetzt Werte bis zu 32bit Long-Integer
      ausgeben.

    - Ab PB 3.10 knnen Sie alternative Namen fr SUBs oder FUNCTIONs
      vergeben, unter denen Sie dann diese Unterroutinen aus OBJ-Routinen
      (mit Assenbler oder C erzeugt) aufrufen koennen.

      Beispiel:
              SUB MySub ALIAS "_my_sub" (Var1%,Var2$) PUBLIC
                      PRINT "Hallo", Var1%, Var2$
              END SUB

    - Das Schlsselwort ANY in einer Prozedurdefinition erlaubt die
      bergabe eines Parameters beliebigen Typs. Der Parameter wird
      per REFERENCE als 32bit-Adresse bergeben. Damit das aufgerufene
      Programm weiss um welchen Typ es sich handelt sollten Sie einen
      Typecode als ersten Parameter mit bergeben. Wird die Routine
      in PowerBASIC codiert so muss zur bernahme des Parameters der
      Inline-Assembler genutzt werden.

      Beispiel:
              i% = 11
              CALL TestAny(0,i%)      'die freien Parameter mssen
                                      'Variablen sein
              s$ = "Hallo"
              CALL TestAny(1,s$)

              SUB TestAny(ParamType AS INTEGER, ANY)
                  DIM Int.Param    AS INTEGER
                  DIM String.Param AS STRING
                  SELECT CASE ParamType
                      CASE 0                  'Integer
                          ! les bx, [bp+6]    :Offset der Var. in BX laden
                          ! mov ax, es:[bx]   ;Wert der Var. in AX laden
                          ! mov Int.Param, ax ;Variable mit AX (Wert) laden
                          PRINT Int.Param
                      CASE 1                  'String
                                              ;Offset der  Stringkennung
                          ! les bx, [bp+6]    ;in BX laden
                          ! mov ax, es:[bx]   ;Stringkennung in AX laden
                          ! mov String.Param,AX
                          PRINT String.Param
                  END SELECT
              END SUB

    - Rckgabewerte von FUNCTIONs die mit dem Inline-Assembler geschrieben
      wurden, knnen jetzt auch ohne eine Zwischenvariable mit einem Wert
      belegt werden. Dazu dient das Schlsselwort FUNCTION.

      Beispiel:

              PRINT AsmTest(2)
              FUNCTION AsmTest(BYVAL int.param AS INTEGER) AS INTEGER
                      ! mov ax, int.param
                      ! inc ax
                      ! mov FUNCTION, ax  ;der Wert wird zurckgeliefert
              END FUNCTION

      (siehe auch Tips mit dem Inline-Assembler)

    - Die Verwendung von FUNCTION anstelle des Funktions-Namens ist auch
      bei BASIC-Codierten FUNCTIONs mglich.

      Beispiel:
              PRINT FuTest(2)
              FUNCTION FuTest(BYVAL int.param AS INTEGER) AS INTEGER
                     FUNCTION = int.param + 1
              END FUNCTION

    - Die Funktion FRE() wurde erweitert :
      FRE(-3) gibt den freien Speicherplatz fr den Stack zurck
      FRE(-4) gibt die maximale Laenge fr dynamische Strings zurck, die
              mit $STRING gesetzt wurde
      FRE(-5) gibt die Anzahl der belegten Stringsegmente zurck
      FRE(-6) gibt die Anzahl der unbenutzten Bloecke im aktuellen String-
              segment zurck
      FRE(-7) gibt die Groesse des unbenutzten Speichers im aktuellen
              Stringsegment zurck


    1.7. Neuigkeiten in der PowerBASIC 3.2 Version
    ----------------------------------------------
    - Data Pointers
    - Code Pointers
      Es knnen nun folgende Sprnge direkt in Basic ausgefhrt werden:
      "CALL DWORD x", "GOTO DWORD x" und "GOSUB DWORD x" . "x" ist in
      diesem Fall der 32bit Zeiger auf die SUB/FUNCTION oder das Label.
      (Zu den neuen Pointer-Funktionen existiert ein DIR$-Demo)

    - 32-Bit Umsetzung von:
      STRPTR32, VARPTR32 und CODEPTR32

    - Zeiger/Pointer auf Strukturen knnen an eine SUB/FUNCTION mit dem
      Schlsselwort "BYVAL" bergeben werden.

      Beispiel:
              DECLARE SUB MySUB(x AS INTEGER)
              DIM z AS INTEGER PTR
              z = &HB8000000
              CALL MySUB(BYVAL z)

    - 16550 UART Untersttzung

    - Die LEN() Funktion liefert nun auch die Lnge von User-definierten
      Strukturen zurck.

    - Label und Varibalen knnen nun zur besseren Unterscheidung auch so-
      genannte Underlines '_' enthalten.


    1.8. PowerBASIC - The next Generation
    -------------------------------------
    Normalerweise wollte ich dieses Thema in der FAQ nicht anfassen. Da es
    aber in dieser Richtung immer wieder zu heftigen und dann in der Folge
    zu vielen Gerchten kommt, hier der nach meinem Wissen aktuelle Stand:

    Laut diverser und auch verllicher Quellen (unter anderem PowerBASIC
    Inc. selbst) arbeiten PowerBASIC Inc. derzeit an der folgenden Versionen
    Ihrer PowerBASIC Software:
    - Der PB/DLL Compiler wird als nchstes ebenfalls (vermutlich noch
      dieses Jahr) in einer Windows95/WindowsNT Version, also fr die
      32bit-Umgebung vorliegen. Als erstes wird eine Kommandozeilen verfg-
      bar sein, ber eine IDE liegen keine Aussagen vor.
    - eine zuknftige PB OS/2 Version wird nicht bestritten, allerdings
      steht diese deutlich in den Plnen hinter den DOS/WIN-Versionen
      zurck.
    - Die nchste DOS-Version soll einen 32bit Inline-Assembler beinhalten,
      Arrays innerhalb der TYPE-Strukturen erlauben, eine berarbeitete
      IDE besitzen und das Verwalten von mehr als 65535 Strings erlauben,
      denn die Breite der Handles wird von 16bit auf 32bit erweitert.

    Wie gesagt, das ist so der aktuelle Blick in die glserne PowerBASIC-
    Kugel.
    Es wre brigend sehr schn, wenn der Dave Navarro in Zukunft selber
    diesen Abschnitt pflegen wrde, immerhin sitzt er an der Quelle ;^)




    ====================================================================
    2. Fehler/Ungereimtheiten in den PowerBASIC-Versionen 3.0, 3.1 & 3.2
    ====================================================================

    Kurzbersicht:
    2.0.  PowerBASIC-Fehlerbibliotheken
    2.1.  Das NUMERIC/OVERFLOW-Problem in PowerBASIC 3.0
    2.2.  Das NUMERIC/OVERFLOW-Problem in PowerBASIC 3.1/3.2
    2.3.  Kein Overflow-Fehler beim Doubleword
    2.4.  Absturz der PowerBASIC IDE und fertiger EXE's beim Laden
    2.5.  unterschiedlich groe EXE-File beim Komplieren mit PB/PBC
    2.6.  unterschiedliche EXE-Files bei gleicher Kompilation
    2.7   Probleme mit der Maus innerhalb der IDE
    2.8.  Das Fixup Overflow Syndrom
    2.9.  Die Sache mit dem ASCII-154 nach einen REMARK im Inline-ASM
    2.10. Fehler 454: END FUNCTION expected
    2.11. Noch ein REMARK-Problem bei $ALIAS
    2.12. Der Fehler CDWRD in der OnLine-Hilfe
    2.13. Der Fehler CVDWRD in der OnLine-Hilfe
    2.14. Absturz bei Bettigen von CNTRL-C
    2.15. Fehler bei Verwenden der Ausgabe ber "CONS:" und CNTRL-C
    2.16. Die Sache mit dem Fehler 244 in einer Stand Alone EXE-Datei
    2.17. Probleme bei Verkettung mehrerer Zeilen Sourcecode
    2.18. Probleme mit dem WATCH-Fenster und mehrdimensionalen Arrays
    2.19. Fehlerhafte interne Funktion/Variable: pbvScrnCols
    2.20. unkorrekte interne Funktion/Variable: pbvHost
    2.21. Ein kleiner Unterschied im neuen InLine-Assembler der V3.1/3.2
    2.22. Das dd-Problem bei PowerBASIC 3.1/3.2
    2.23. undokumentierte interne Variablen in PowerBASIC 3.0/3.1/3.2
    2.24. Der PRINT-Bug in PowerBASIC 3.2
    2.25. Der Fehler "File not found" nach Verwendung von NAME
    2.26. Rechenfehler bei der Verwendung von Konstanten
    2.27. falsches "Bit schieben" bei ROTATE
    2.28. Overflow bei Verwendung von FOR/NEXT-Schleifen
    2.29. Overflow bei Verwendung von STEP -1 in FOR/NEXT-Schleifen
    2.30. Der Bug im VARPTR32-Befehl
    2.31. Der "KEY ON" Bug
    2.32. Absturz der PowerBASIC IDE im Pick-Men
    2.33. Absturz der PowerBASIC IDE bei fehlerhaften Syntax
    2.34. falsches Vertauschen der Variablen bei Verwendung von SWAP
    2.35. Der Multiplexer Interrupt Fehler im REG-Befehl
    2.36. Laufzeitfehler im PowerBASIC Helpcompiler
    2.37. Der Fehler Truncating im PowerBASIC Helpcompiler
    2.38. Absturz der PowerBASIC-IDE nach Aufruf der eigenen Hilfe


    2.0. PowerBASIC-Fehlerbibliotheken
    ----------------------------------
    Zur besseren Sicherheit Ihrer eigenen Programme empfehle ich prinzipiell
    die Einbindung aller Fehlerbibliotheken. Nur so knnen Sie sicher sein,
    das PowerBASIC auch den wahren Fehler anzeigt und z.B. nicht bei:

            SELECT CASE pbvrevision

    mit einem unerklrlichen Fehler aussteigt. Im fertigen Programm knnnen
    Sie die Bibliotheken wieder entfernen, da sie eigentlich nur whrend der
    Programmentwicklung wirklich bentigt werden.
    Die $ERROR-Bibliotheken knnen Sie innerhalb der IDE stndig einbinden
    oder direkt in Ihrem Sourcecode definieren. Die Einstellungen im
    Sourcecode haben gegenber den Einstellungen der IDE Vorrang!

    Die $ERROR-Bibliotheken binden Sie wie folgt ein:

            $ERROR NUMERIC ON
            $ERROR OVERFLOW ON
            $ERROR BOUNDS ON
            $ERROR STACK ON

    Achtung: Einige der hier aufgezeigten Ungereimtheiten knnen nur mit
             diesen Bibliotheken aufgedeckt werden!




    2.1. Das NUMERIC/OVERFLOW-Problem in PowerBASIC 3.0
    ---------------------------------------------------
    Versionen: 3.0
    bekannt  : teilweise in Version 3.10 beseitigt

    Die hier aufgefhrten Probleme beziehen sich nur auf die Verwendung von
    vorzeichenlosen Variablen und werden an Variablen vom Typ WORD
    aufgefhrt:

    Beispiel 1:
            Demo?? = &hA000

    fhrt zu einem Overflow, da PowerBASIC dies als vorzeichenbehaftete
    Variable versucht zu interpretieren. Dieser Fehler kann nur durch Angabe
    einer Realzahl umgangen werden.
    hnliche Effekte lassen sich im $NUMERIC-System auch bei Verwendung des
    REG()-Befehles nachvollziehen:

    Beispiel 2:
            Demo?? = REG(1)

    kann unter Umstnden ebenfalls zu einem berlauf fhren, sofern der
    bergebene Wert als INTEGER negativ wre. Den Fehler knnen Sie um-
    schiffen, sofern sie bei der Verwendung von REG() nur Variablen vom Typ
    INTEGER verwenden, die NUMERIC-Bibliothek beim Kompilieren entfernen.
    Noch viel besser ist es allerdings, den alten BASIC-Unsinn ber Bord zu
    werfen und die Geschichte gleich im InLine-Assembler sauber zu pro-
    grammieren! ;-)

    Interessant ist auch das 'Verschleppen' von Fehlern bei ausgeschalteter
    $ERROR NUMERIC Bibliothek. Der Fehler tritt dann etwas spter im
    Programm auf, komischerweise aber ebenfalls bei Variablen vom Typ WORD.
    Eigenartigerweise lt sich dies am besten mit den internen PowerBASIC-
    Variablen vom Typ WORD nachvollziehen.

    Ein weiterer Overflow-Effekt verbirgt sich in den PowerBASIC-Funktionen
    STRSEG/STRPTR, VARSEG/VARPTR, CODESEG/CODEPTR. Im Gegensatz zum REG()
    Befehl mssen die Variablen definitiv vom Typ WORD sein, ansonsten
    droht wiederum ein berlauf in greren Programmen.


    2.2. Das NUMERIC/OVERFLOW-Problem in PowerBASIC 3.1/3.2
    -------------------------------------------------------
    Versionen: 3.1/3.2
    bekannt  : Nachbesserung bei PowerBASIC Inc. verlangt

    Man soll nicht denken, das eine neue Version auch die ganzen alten Fehler
    in Vergessenheit geraten lt ;-).

    Beispiel 1:
            Demo?? = &hA000

    kann weiterhin zu einem berlauf fhren. Leider lt sich dieser Fehler
    nicht mehr in einer Zeile demonstrieren, da er gelegentlich in sehr
    komplexen Programmen weiterhin auftritt. Das hat sich mit PowerBASIC
    in der Version 3.20 leider immer noch nicht gendert.
    Im Gegensatz zur Version 3.00 kann der Fehler aber durch explizente
    Unsigned-Angabe beseitigt werden:

            Demo?? = &h0A000

    Sollten Sie Toolbox-Entwickler sein und auf Nummer sicher gehen wollen,
    dann geben Sie in folgene Zeile ein, sofern Ihre Sourcen auch unter
    PowerBASIC 3.0 laufen sollen:

            ! mov ax, &hA000
            ! mov Demo??, ax

    Beispiel 2:
            Demo?? = REG(1)

    fhrt meines Erachtens nicht mehr zu einem Overflow, ganz ausschliessen
    kann ich dies aber nicht. Trotzdem sollte man bei der Verwendung von REG
    weiterhin nur Variablen vom Typ INTEGER verwenden. Viele PowerBASIC-
    Funktionen funktionieren jetzt besser, andere bereiten trotzdem Probleme.
    Dies betrifft wieder diverse spezielle Routinen welche nur fr Integer-
    Variablen ausgelegt sind, aber trotzdem mit Variablen vom Typ WORD
    funktionieren.

    Das Overflow-Problem bei STRSEG/STRPTR, VARSEG/VARPTR und CODESEG/CODEPTR
    ist weiterhin existent.


    2.3.  Kein OVERFLOW-Fehler beim Doubleword
    ------------------------------------------
    Versionen: 3.0/3.1/3.2
    bekannt  : nein

    Fr Variablen vom Typ Doubleword ist in PowerBASIC kein Overflowtest
    integriert. Dies knnen Sie an einem kleinen Besipiel testen.

    Beispiel:
            i??? = -1
            PRINT i???

    Wie Sie sehen interpretiert PowerBASIC den negativen Wert immer als sein
    nicht vorzeichenbehaftetes Gegenstck. Normalerweise ist dies nicht so
    wichtig, aber im Zusammenspiel mit dem REG-Befehl kann es zu Rechen-
    fehlern kommen. Wie in den beiden vorherigen Abschnitten beschrieben,
    neigt der REG-Befehl dazu vorzugsweise vorzeichenbehaftete Werte zu
    bergeben.


    2.4. Absturz der PowerBASIC IDE und fertiger EXE's beim Laden
    -------------------------------------------------------------
    Versionen: 3.0/3.1 (3.2 nicht getestet)
    bekannt  : nein (teilweise)

    Ein Absturz der IDE beim Laden tritt eigentlich recht selten auf und ist
    im Prinzip immer auf folgende Ursachen zurckzufhren:

        - QEMM Speicherverwaltungsmanager (bis Version 7.03)
        - extrem wenig verfgbarer Arbeitsspeicher
        - Sie haben versucht die IDE mit dem Befehl LOADHIGH zu laden
        - 4DOS

    In den meisten Fllen wird die IDE whrend des Ladevorganges mit einem
    Grafikfehler (Cursor innerhalb der IDE) auf die Kommandozeile zurck-
    kehren.
    Ebenfalls betroffen von diesem Effekt sind alle fertigen PowerBASIC-EXE
    Files. Wollen Sie diesen Effekt auf alle Flle umgehen, so mssen Sie
    die PowerBASIC-EXE mit einem EXE-Packer wie PKLITE komprimieren.


    2.5. unterschiedlich groe EXE-File beim Komplieren mit PB/PBC
    --------------------------------------------------------------
    Eigentlich ist dies kein Fehler, da es nur einen kleinen Unterschied in
    der Wirkungsweise des IDE-Compilers zu dem Kommandozeilencompiler gibt,
    welche die unterschiedlich groen EXE-File erklrt.
    Die IDE compiliert die EXE-Datei immer nach den Einstellungen in der IDE,
    das heit wenn Sie dort zum Beispiel die VGA-Lib nicht mit compilieren
    wollen, so geben sie das als Standard in der IDE an. Der PBC compiliert
    dagegen die VGA-Lib immer mit, sofern sie das nicht als Metastatment
    anderweitig deklariert haben.
    Die Metastatment-Einstellung haben immer Vorrang vor den Einstellungen
    in der IDE!


    2.6.  unterschiedliche EXE-Files bei gleicher Kompilation
    ---------------------------------------------------------
    Versionen: 3.0/3.1
    bekannt  : anscheinend

    Einen netten Effekt gibt es zu berichten, sofern Sie Sourcen mehrmals
    compilieren und diese dann mit einem Filevergleich-Utility einer genauen
    Betrachtung unterziehen. Sofern sich Ihr verfgbarer freier Speicher
    gendert hat, werden die erstellten EXE-Files unterschiedlich sein.

    Meines Erachtens speichern die beiden PowerBASIC Compiler auch
    Ursprungsinformationen mit ab, welche vom Typ Integer/Word sind und sich
    immer an den Offset's &h9C/&hA0 befinden (PB3.1). Dieser Effekt lt
    sich mit der PB-IDE und auch dem PBC nachvollziehen.

    Nach einigen Ausknften sollen PB-EXE-Files, welche unter einer
    PowerBASIC-SHELL mit PBC compiliert wurden zum Abstrzen neigen.

    Da ich aber selbst seit ca 2 Jahren alle meine Projekte auf hnliche
    Weise compiliere, kann ich diesen Effekt nicht nachvollziehen oder
    besttigen. In Version 3.0 des PowerBASIC-Compilers schien allerdings
    der SHELL-Befehl anderweitige Effekte bei groen EXE-File auszulsen.
    Die Probleme lsten sich damals mit der Verwendung eines alternativen
    PBSHELL-Befehls.


    2.7  Probleme mit der Maus innerhalb der IDE
    --------------------------------------------
    Versionen: 3.0
    bekannt  : anscheinend in Version 3.1 behoben

    Sollten Sie innerhalb der IDE mit der Maus arbeiten damit Sie komfortabel
    Sourcecode Einfgen und Ausschneiden knnen, so kann dies beim Markieren
    lngerer Texte (welche den rechten Bildschirmrand berschreiten) zu einem
    Teilabsturz fhren. Des weiteren markiert der Maus-Cursor die Texte nicht
    richtig. Sie erkennen das daran, das Sie in der Regel eine lngere Zeile
    nicht markieren knnen.
    Des weiteren scheint es vereinzelt Probleme mit der Mausuntersttzung zu
    geben, Sofern sie den 80*43/50'er Textmodus verwenden.


    2.8. Das Fixup Overflow Syndrom
    -------------------------------
    Versionen: 3.0/3.1/3.2
    bekannt  : Nachbesserung bei PowerBASIC Inc. verlangt

    So jetzt kommen wir zu meinem Lieblingsfehler, zumal er eigentlich durch
    einen ernsthaften Programmierfehler seitens des PowerBASIC Anwenders
    ausgelst wird. Die Beschreibung im Handbuch, sowie der OnLine-Hilfe,
    ist leicht irrefhrend dennoch prinzipiell richtig.

    Ich persnlich wrde den Fehler wie folgt beschreiben:

    <neue Fehlerbeschreibung>
    PowerBASIC konnte die angegebene Sprungadresse nicht finden. Eine
    mgliche Ursache ist ein SHORT-Sprung zu einem Label der nicht im
    gltigen Bereich fr einen SHORT-Sprung liegt. Bitte berprfen Sie alle
    Sprungbefehle auf Ihren Gltigkeitsbereich.
    <Ende>

    Leider hat sich gerade bei dieser Fehlermeldung in beiden PowerBASIC
    Versionen ein Fehler eingeschlichen. Da die menschliche Natur prinzipiell
    nicht so recht glauben will was da so steht, wird die Source eben
    nochmals (ohne nderung) kompiliert. Die IDE quittiert das sofort mit
    einem Absturz.

    Eine genauere Beschreibung des Zusammenspiels der einzelnen Assembler-
    Befehle, vor allem die verschiedenen Adressierungsarten in Abhngigkeit
    von der CPU, erspare ich mir hier. Dafr gibt es jede Menge Assembler-
    Bcher, meines Erachtens eh eine Voraussetzung zur sinnvollen
    Programmierung mit dem InLine-Assembler.


    2.9. Die Sache mit dem ASCII-154 nach einen REMARK
    --------------------------------------------------
    Versionen: 3.0/3.1/3.2
    bekannt  : nein

    Eine nette Sache kann Sie zum Beispiel in Verbindung mit einer guten
    Kommentierung Ihrer InLine-Assembler Source schlichtweg zum Wahnsinn
    treiben: Die Sache mit dem Sonderzeichen ASCII-154 nach einem REMARK
    (REM bzw. ; ):

    Beispiel:
            CLS
            PRINT "1"
            ! nop                ;    <- (ASCII-154)
            PRINT "2"

    PowerBASIC wird in diesem Fall die Programmausfhrung bis zu der Zeile
    mit dem Sonderzeichen (nach dem REM) fortsetzen und dann stoppen. Die
    hartgesottenen knnen diese Sache auch einmal mit dem Debuger verfolgen.
    In diesem Fall werden Sie feststellen, das PowerBASIC nach dem REMARK
    einfach nur noch sieben ASCII-Nullen an den Code anhngt und das weitere
    Compilieren einstellt.


    2.10.  Fehler 454: END FUNCTION expected
    ----------------------------------------
    Versionen: 3.0/3.1/3.2
    bekannt  : nein

    Diese Fehler kann auftreten, sofern der kommentierte Text einer Inline-
    Assemblerzeile das ASCII-154 Zeichen enthlt. Lesen Sie sich bitte auch
    den vorherigen Absatz durch.


    2.11. Noch ein REMARK-Problem bei $ALIAS
    ----------------------------------------
    Versionen: 3.0/3.1/3.2
    bekannt  : nein

    Der Fehler ist wieder recht einfach zu beschreiben. Sie drfen bei der
    Verwendung von $ALIAS kein ':' (ASCII 58) nach einem REMARK verwenden,
    da dies PowerBASIC mit einem Fehler 462 (nicht definierte SUB/FUNCTION)
    interpretiert.

    Beispiel:
            $ALIAS DATA AS "_DATA"  ': C-Segmente an PowerBASIC anpassen
                                     ^
                                     fhrt zum Fehler 462


    2.12. Der Fehler CDWRD in der OnLine-Hilfe
    ------------------------------------------
    Versionen: 3.0 (vermutlich nur deutsche Version)
    bekannt  : Fehler in deutscher Version 3.0 beseitigt?

    In der OnLine-Hilfe hat sich ein Tipfehler eingeschlichen, statt dem
    richtigen Befehl 'CDWD' wird der Befehl mit 'CDWRD' beschrieben. In den
    Handbchern ist der Syntax aber korrekt erklrt.

    Beispiel:
            i??? = 1
            PRINT CDWRD(i???)        : 'falscher  Syntax
            PRINT CDWD(i???)         : 'richtiger Syntax


    2.13. Der Fehler CVDWRD in der OnLine-Hilfe
    -------------------------------------------
    Versionen: 3.0 (vermutlich nur deutsche Version)
    bekannt  : Fehler in deutscher Version 3.0 beseitigt?

    Analog wir bei dem Syntaxfehler 'CDWRD' hat sich auch hierbei ein Fehler
    in der OnLine-Hilfe eingeschlichen, der Syntax lautet wie im Handbuch
    korrekt beschrieben 'CVDWD'.



    2.14. Absturz bei Bettigen von CNTRL-C
    ---------------------------------------
    Versionen: 3.0
    bekannt  : Fehler in Version 3.10 beseitigt

    Dieser Fehler ist im allgemeinen bekannt und tritt nur auf wenn Sie die
    Compileroption $OPTION CNTLBREAK OFF verwenden, whrend das BREAK-Flag
    auf DOS-Ebene auf ON gesetzt ist (normalerweise ist dies aber von MS-DOS
    eh auf OFF gesetzt). Bettigen Sie unter diesen Vorrausetzungen nun die
    Tastenkombination CNTL-C, dann sttzt Ihr fertiges Programm gelinde
    gesagt ab.
    Abhilfe schafft das Sperren des BREAK-Flag's per eigener PowerBASIC-
    Funktion. Dies knnen Sie zum Beispiel durch folgende Routinen erreichen:

            SHARED BreakFlag%
            FUNCTION BreakAus public
                    'Controll-Break-Interrupt sichern und abschalten
                    ! mov ax, &h3300
                    ! int &h21
                    ! mov BreakFlag%, dx
                    ! mov ax, &h3301
                    ! mov dx, 0
                    ! int &h21
            END FUNCTION

            FUNCTION BreakReset public
                    'Control-Break-Interrupt restaurieren
                    ! mov ax, &h3301
                    ! mov dx, BreakFlag%
                    ! int &h21
            END FUNCTION

    In einigen Mailboxen befindet sich auch eine Datei namens CNTL.ZIP,
    welche den offiziellen BugFixed darstellt.


    2.15. Fehler bei Verwenden der Ausgabe ber "CONS:" und CNTRL-C
    ---------------------------------------------------------------
    Versionen: 3.0
    bekannt  : Fehler in Version 3.10 beseitigt

    Dieser Fehler ist ebenfalls eine Auswirkung des CNTRL-C Bugs, whrend
    der Ausgabe ber "CONS:" kann es zu Nebeneffekten kommen. Nheres ist
    mir pesnlich nicht bekannt.


    2.16. Die Sache mit dem Fehler 244 in einer Stand Alone EXE-Datei
    -----------------------------------------------------------------
    Versionen: 3.0
    bekannt  : Fehler in Version 3.10 beseitigt

    Sollten Sie PowerBASIC 3.0 nutzen und fters im InLine-Assembler
    programmieren, so kann es in Verbindung mit den beiden internen
    PowerBASIC-Funktionen:

            GetStrLoc
            GetStrAlloc

    zu dem oben genannten Fehler 244 (Bibliothek nicht vorhanden) kommen.
    Dieser Fehler tritt nur in einer Stand-Alone-EXE Datei auf und nicht
    innerhalb der PowerBASIC-IDE. Als Voraussetzung mssen sich die beiden
    internen PowerBASIC-Funktionen innerhalb einer PowerBASIC Unit (PBU)
    befinden. Als Abhilfe mssen Sie die beiden PowerBASIC-Funktionen
    STRSEG/STRPTR benutzen, die Werte dann zwischenspeichern und danach auf
    die betreffenden Prozessorregister schieben.


    2.17. Probleme bei Verkettung mehrerer Zeilen Sourcecode
    --------------------------------------------------------
    Versionen: 3.0/3.1
    bekannt  : ???????

    Die PowerBASIC-IDE, sowie der Kommandozeilen-Compiler, haben allgemeine
    Probleme, wenn Sie Sourcecode ber mehrere Zeilen verteilen, welcher
    normalerweise in eine Zeile gehrt.

    Beispiel:
            C$ = CHR$( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)+_
                 CHR$( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)

    Gerade in Verbindung mit groen Projekten hat sich gezeigt, das der
    Compiler zu einer falschen Interpretation neigt, sprich: An irgendeiner
    Stelle im Sourcecode meldet der Compiler einen fr Sie unerklrlichen
    Fehler. In vielen Fllen bleibt der Cursor aber an richtigen Stelle
    stehen.


    2.18. Probleme mit dem WATCH-Fenster und mehrdimensionalen Arrays
    -----------------------------------------------------------------
    Versionen: 3.0/3.1
    bekannt  : Fehler in Version 3.2 beseitigt

    Das WATCH-Fenster kann keine mehrdimensionalen Arrays korrekt dar-
    stellen.


    2.19. Fehlerhafte interne Funktion/Variable: pbvScrnCols
    --------------------------------------------------------
    Versionen: 3.0/3.1/3.2
    bekannt  : nein

    Diese interne Variable soll Ihnen die Anzahl der angezeigten Bildschirm-
    spalten zurckliefern. In Verbindung mit allen Modies welche nicht die
    40'er bzw. 80'er Spaltenanzahl verwenden, wird nicht die korrekte Anzahl
    der Bildschirmspalten zurck geliefert. Solche Modies knnen Sie auf
    jeder VGA-Karte einstellen und diverse Tools (u.a. Disk Command Center)
    untersttzen dies sogar!
    Abhilfe schafft hierbei wieder eine eigene Funktion:

            DIM fixScrnCols AS BYTE
            ! mov  ah, &h0f
            ! int  &h10
            ! mov fixScrnCols, ah


    2.20. unkorrekte interne Funktion/Variable: pbvHost
    ---------------------------------------------------
    Versionen: 3.0/3.1/3.2
    bekannt  : nein

    Das Bit 8 ist unter Microsoft Windows(NT) 3.x nicht gesetzt.


    2.21. Ein kleiner Unterschied im neuen InLine-ASM der V3.1/3.2
    --------------------------------------------------------------
    Versionen: 3.1/3.2
    bekannt  : Nachbesserung bei PowerBASIC Inc. verlangt

    Dieser Fehler ist recht einfach erklrt, whrend PowerBASIC 3.0 im
    Inline-Assembler folgende Zeile zult:

            ! mov ax, &h0A000

    verweigert PowerBASIC 3.1/3.2 an dieser Stelle die Zusammenarbeit,
    obwohl das Feature in der Version 3.1/3.2 neu ist.


    2.22. Das dd-Problem bei PowerBASIC 3.1/3.2
    -------------------------------------------
    Versionen: 3.1/3.2
    bekannt  : Nachbesserung bei PowerBASIC Inc. verlangt

    Dieser Fehler ist recht schnell beschrieben, da die neuen 32Bit
    &h...., &o.... &b Anweisungen als bekannt vorrausgesetzt werden.
    PowerBASIC Inc. hat in Verbindung mit dem InLine-Assembler einfach die
    Umsetzung vergessen!! Sie glauben mir nicht, dann probieren Sie doch
    einfach folgendes:

            ! dd &h12345678

    Geklrt werden muss jetzt natrlich warum es den Befehl 'dd' berhaupt
    in PowerBASIC 3.0/3.1 & 3.2 gibt ;-).


    2.23. undokumentierte interne Variablen in PowerBASIC 3.0/3.1/3.2
    -----------------------------------------------------------------
    Folgende interne Variablen sind in PowerBASIC 3.0 bereits vorhanden,
    aber nicht dokumentiert:

    pbvBinBase
    pbvDefSeg
    pbvHost
    pbvScrnBuff
    pbvSwitch
    pbvVTxtX1
    pbvVtxtX2
    pbvVTxtY1
    pbvVtxtY2

    Folgende internen Varibalen sind ab V3.1 nicht mehr dokumentiert, aber
    noch in Version 3.2 vorhanden:

    pbvRestore

    Die Lage im Datensegment ist bei PowerBASIC 3.0 mit der Lage in
    PowerBASIC 3.1/3.2 identisch.


    2.24. Der PRINT-Bug in PowerBASIC 3.2
    -------------------------------------
    bekannt  : ????

    In der Version 3.2 werden Variablen vom Typ DWORD nicht mehr korrekt
    beim PRINT-Befehl dargestellt:

    Beispiel:
            Demo??? = 1234567890
            PRINT Demo???

    fhrt zu folgender Ausgabe:

    PowerBASIC 3.0/3.1: 1234567890
    PowerBASIC 3.2    : 1.234568+E

    Abhilfe schafft das Verwenden von PRINT USING ...


    2.25. Der Fehler "File not found" nach Verwendung von NAME
    ----------------------------------------------------------
    Versionen: 3.0/3.1/3.2
    bekannt  : nein

    Ein sehr merkwrdiger Fehler in der Behandlung PowerBASIC-interner
    Filehandles hat sich bei der Verwendung des Befehles "NAME" einge-
    schlichen.

    Beispiel:
           OPEN "B",1,"DATEI1.TMP"       ' ffnen der 1. Datei
           OPEN "B",2,"DATEI2.$$$"       ' ffnen
           CLOSE 2                       ' ... und sofort schliessen
           OPEN "B",3,"DATEI3.TMP"       ' ffnen
           CLOSE 3                       ' ... und sofort schliessen
           KILL "DATEI2.$$$"             ' 2. Datei lschen
           NAME "DATEI3.TMP" AS "DATEI2.$$$"
                                         ' 3. Datei -> 2. Datei umbenennen
           CLOSE 1                       ' ... Schliessen der 1. Datei
           END


    2.26. Rechenfehler bei der Verwendung von Konstanten
    ----------------------------------------------------
    Versionen: 3.0/3.1/3.2
    bekannt  : nein

    PowerBASIC rechnet bei der Verwendung von Konstanten gelegentlich
    nicht korrekt. Es sei natrlich die Frage in den Raum gestellt, warum
    man nicht gleich das Rechenergebnis einsetzt, da es sich hierbei um
    eine reine Formsache handelt.

    Beispiel:
           i% = -20-4   : %k= -20-4
           PRINT i%     , %k


    2.27. falsches "Bit schieben" bei ROTATE
    ----------------------------------------
    Versionen: 3.0/3.1
    bekannt  : Fehler in Version 3.20 beseitigt

    Der ROTATE-Befehl hat in PowerBASIC 3.0/3.1 einen Fehler sofern Variablen
    vom Type QUAD verwendet werden.

    Beispiel:
           i&& = 1
           ROTATE RIGHT i&&, 1
           ROTATE LEFT i&&, 1
           PRINT i&&


    2.28. Overflow bei Verwendung von FOR/NEXT-Schleifen
    ----------------------------------------------------
    Versionen: 3.0/3.1/3.2
    bekannt  : nein

    PowerBASIC erlaubt es nicht in FOR/NEXT-Schleifen den maximal gltigen
    Wertebereich einer Variablen auszuschpfen. Der maximal mgliche Wert
    wird intern von PowerBASIC verwendet, da PowerBASIC m.E. erst intern
    die Variable erhht und dann abfragt. Logischerweise kommt es dabei
    zu einem berlauf, sofern Ihr Wert bereits den maximal mglichen
    Wert erreicht hat.
    Der Fehler betrifft m.E. alle Variablentypen.

    Beispiel:
           FOR Demo? = 1 TO 255
               PRINT Demo?
           NEXT Demo?

    Sollten Sie nicht die "$ERROR NUMERIC" Bibliothek verwenden, so befindet
    sich diese FOR/NEXT Konstruktion in einer Endlosschleife.


    2.29. Overflow bei Verwendung von STEP -1 in FOR/NEXT-Schleifen
    ---------------------------------------------------------------
    Versionen: 3.0/3.1/3.2
    bekannt  : nein

    PowerBASIC gestattet kein Herunterzhlen im gltigen Variablenbereich
    von Variablen vom Typ unsigned. Whrend bei Variablen vom Typ BYTE
    oder WORD ein Overflow kommt, wurde wie bereits erwhnt der Overflow-
    test bei DWORD weggelasssen. Eine FOR/NEXT-Schleife mit 'STEP -1' wird
    also auch hierbei nicht korrekt abgearbeitet!

    Beispiel:
           FOR Demo?? = 10 TO 2 STEP -1
           NEXT Demo??

    oder
           FOR Demo??? = 10 TO 2 STEP -1
               PRINT Demo???
           NEXT Demo???

    Sollten Sie nicht die "$ERROR NUMERIC" Bibliothek verwenden, so befindet
    sich diese FOR/NEXT Konstruktion in einer Endlosschleife.


    2.30. Der Bug im VARPTR32-Befehl
    --------------------------------
    Versionen: ab 3.2
    bekannt  : nein

    Im Gegensatz zu den Befehlen STRPTR32 und CODEPTR32 hat sich im
    VARPTR32-Befehl ein Bug eingeschlichen. Leider ist es mit diesem
    Befehl nicht mglich gleichzeitig eine mathematische Operation
    auszufhren.

    Beispiel:
           DIM Demo AS STRING * 10
           Wert1??? = VARPTR32(Demo) + 1
           Wert2??? = VARPTR32(Demo)
           Wert2??? = Wert2??? + 1
           PRINT  Wert1???, Wert2???


    2.31. Der 'KEY ON' Bug
    ----------------------
    Versionen: 3.0/3.1/3.2
    bekannt  : nein

    Laut PowerBASIC Benutzerhandbuch und BASIC Spezifikation des KEY-Befehls
    stellt der 'KEY ON'-Befehl in Zeile 25 die aktuelle KEY-Tastaturbelegung
    in 'Norton Commander' hnlicher Form dar. Ist dieses der Fall, sollte
    PowerBASIC jeden Zugriff des Programmierers auf die Zeile 25 durch
    LOCATE mit einem 'Error 5: Illegal Function' unterbinden. Ebenso sollte
    die Zeile 25 durch ein versehentliches Scrollen geschtzt sein.
    Seit PowerBASIC V3.x (im Gegensatz zur V2.10) ist dieses nicht mehr der
    Fall!

    Beispiel:
            KEY OFF
            FOR i% = 1 TO 10
                READ A$
                KEY i%, A$ + CHR$(13)
            NEXT i%
            KEY LIST
            COLOR 3, 0
            KEY ON
            COLOR 7, 0
            LOCATE 25, 1: PRINT " Dieser Text sollte abgefangen werden!! ";
            WHILE NOT INSTAT
            WEND
            KEY OFF
            END
            DATA "Hilfe", "Return"', "Edit", "Wechseln", "Report"
            DATA "PRINT", "Setup", "DOS", "Kopie", "Quit"

    Mir stellt sich nun die Frage ob dieses ein Fehler im PowerBASIC-Handbuch
    oder ein Bug im Compiler ist. Auf alle Flle knnen Sie diesen Effekt
    aber durch die Verwendung von:

            VIEW TEXT (1,1)-(80,24)

    umgehen.


    2.32. Absturz der PowerBASIC IDE im Pick-Men
    ---------------------------------------------
    Versionen: 3.0/3.1/3.2
    bekannt  : nein

    Die PowerBASIC IDE strzt ab, wenn sie zum ersten Mal nach dem Start
    der IDE im Men "File\Pick", anstatt der RETURN-Taste die DEL-Taste
    bettigen. Sollten Sie bereits whrend der Sitzung das Men "Pick" einmal
    mit RETURN geffnet haben, so wirkt sich der Fehler nicht mehr aus.
    Ich persnlich halte den Fehler fr sehr ernsthaft, liegen doch die
    beiden Tasten auf der Tastatur eng zusammen.


    2.33. Absturz der PowerBASIC IDE bei fehlerhaften Syntax
    --------------------------------------------------------
    Versionen: 3.0/3.1/3.2
    bekannt  : nein

    Die PowerBASIC IDE strzt ab, sofern Sie versuchen folgende Zeile
    zu compilieren:

            PRINT Test1$ XOR Test2$ XOR Test3$

    ber den Sinn der Zeile mchte ich lieber nicht diskutieren. <g>


|   2.34. falsches Vertauschen der Variablen bei Verwendung von SWAP
|   ----------------------------------------------------------------
|   Versionen: 3.0/3.1/3.2
|   bekannt  : nein
|
|   Bei Verwendung des SWAP-Befehl in Verbindung mit TYPE-Strukturen und der
|   Indizierung des Feldes ber eine Variable (im Beispiel "a(c%).x") werden
|   die Felder falsch miteinander getauscht (geswappt). Wird das Feld ber
|   einen fest definierten Wert (z.B. "a(1).x") indiziert, dann arbeitet der
|   SWAP-Befehl korrekt.
|
|   Beispiel:
|           TYPE SwapTest                 ' Benutzerdefinierter Datentyp
|               x AS INTEGER
|               y AS INTEGER
|           END TYPE
|
|           DIM a(1 TO 2) AS SwapTest     ' Array anlegen
|
|           c%     = 1
|           d%     = 2
|           a(1).x = 1                    ' Felder initialisieren
|           a(1).y = 2
|           a(2).x = 3
|           a(2).y = 4
|           CLS
|           PRINT "vor  SWAP: "; a(c%).y, a(d%).y
|           SWAP                 a(c%).y, a(d%).y
|           PRINT "nach SWAP: "; a(c%).y, a(d%).y
|
|
|   2.35. Der Multiplexer Interrupt Fehler im REG-Befehl
|   ----------------------------------------------------
|   Versionen: 2.x/3.0/3.1/3.2
|   bekannt  : nein
|
|   Erstaunlicherweise gibt es selbst einige Ungereimtheiten sofern Sie
|   mit dem REG-Befehl den Multiplexer-Interrupt &h2F aufrufen. In der
|   Regel hat es den Anschein das der Aufruf vom System abgewiesen wird.
|   Ein Gegentest beweist aber das es mit dem Inline-Assembler funktioniert!
|   Beobachtet wurde dieser Effekt bei der Programmierung des MSCDEX, der
|   Abfrage der Windows-Version und der Timeslice-Funktion des Multiplexer-
|   Interrupts.
|   Abhilfe schafft nur konsequentes Programmieren mit dem Inline-Assembler.
|
|   Beispiel:
|           ! mov ax, &h1680
|           ! int &h2F
|           ! mov Taskfreigabe%, ax
|           Taskfreigabe% = Taskfreigabe% AND 255
|           SELECT CASE Taskfreigabe%
|               CASE &h80 : PRINT "Taskfreigabe nicht untersttzt"
|               CASE &h0  : PRINT "Taskfreigabe wird untersttzt"
|               CASE ELSE : PRINT "unerwarteter Wert"
|           END SELECT
|
|           REG 1, &h1680
|           CALL INTERRUPT &h2F
|           Taskfreigabe% = REG(1)
|           Taskfreigabe% = Taskfreigabe% AND 255
|           SELECT CASE Taskfreigabe%
|               CASE &h80 : PRINT "Taskfreigabe nicht untersttzt"
|               CASE &h0  : PRINT "Taskfreigabe wird untersttzt"
|               CASE ELSE : PRINT "unerwarteter Wert"
|           END SELECT


    2.36. Laufzeitfehler im PowerBASIC Helpcompiler
    -----------------------------------------------
    Versionen: 3.0 (Helpcompiler)
    bekannt  : nein

    Der Helpcompiler (bzw. Encoder) scheint irgendwie reichlich Fehler zu
    enthalten. Vor allem Anfngern bereit der Laufzeitfehler 9 an der
    Adresse 10095 bestimmt viel rger. Dies ist ein interner Fehler des
    Helpcompilers, der durch das Nichtvorhandensein des Befehls '/LOOKUP'
    ausgelst wird.


    2.37. Der Fehler Truncating im PowerBASIC Helpcompiler
    ------------------------------------------------------
    Versionen: 3.0 (Helpcompiler)

    Der Fehler 'Truncating ... to 76 characters' wird des fteren irrtmlich
    angezeigt, da die Steuerzeichen nicht bercksichtigt werden.


    2.38. Absturz der PowerBASIC-IDE nach Aufruf der eigenen Hilfe
    --------------------------------------------------------------
    Versionen: 3.0 (Helpcompiler)

    Bei der Programmierung bzw. eigentlich dem Schreiben der Hilfe mssen
    Sie aufpassen, das die effektive Lnge der darzustellenden Textzeile
    nicht grer als die wirklich vorhandene Zeilenbreite des PowerBASIC-
    Hilfefensters ist, da die PowerBASIC-IDE in diesem Fall mit einem
    Grafikfehler abstrzt.
    Dieser Fehler tritt nur in der Endwicklungsphase einer selber
    geschriebenen Hilfedatei (*.PBH) auf!


    =================================
    3. PowerBASIC und der CoProzessor
    =================================

    3.1. Untersttzt PowerBASIC einen CoProzessor?
    3.2. Welche Fliekommabibliothek ist fr mich die optimale?
    3.3. Macht sich der CoProzessor auch bei $FLOAT PROCEDURE bemerkbar?
    3.4. Welche PowerBASIC-Funktionen sind betroffen?
    3.5. mgliche Ursachen fr den CoProzessor-Effekt
    3.6. PowerBASIC-Benchmark Source


    3.1. Untersttzt PowerBASIC einen CoProzessor?
    ----------------------------------------------
    Die Antwort lautet ganz einfach JA. Bereits in den Compiler-Optionen
    haben Sie die Mglichkeit drei verschiedene Fliekommabibliotheken
    auszuwhlen. Aber mit dieser Untersttzung des CoProzessors sind unter
    PowerBASIC einige Haken verbunden, die es hier aufzuzeigen geht damit
    sie schnellere und hoffentlich nur sauber funktionierende Programme
    entwickeln.


    3.2. Welche Fliekommabibliothek ist fr mich die optimale?
    -----------------------------------------------------------
    PowerBASIC bietet insgesamt drei Fliekommabibliotheken an:

    a) $FLOAT EMULATE
       Dieses ist die DEFAULT-Bibiothek und dadurch in der Regel bei ca 95%
       der Anwender im Einsatz. Sie zeichnet sich durch automatische Unter-
       sttzung des i87 aus, sofern ein solcher CoProzessor gefunden wurde.
       Der enorme Nachteil liegt aber sofort auf der Hand. PowerBASIC
       testet stndig auf einen CoProzessor und wird dadurch erheblich
       langsamer sofern wirklich kein i87 installiert ist.

    b) $FLOAT PROCEDURE
       Diese Bibliothek ist mit Abstand die schnellste, sofern kein Co-
       Prozessor installiert ist.

    c) $FLOAT NPX
       Mit Abstand liegt diese Bibliothek vorne, sofern jedenfalls ein
       i87 vorhanden ist.


    3.3. Macht sich der Coprozessor auch bei $FLOAT PROCEDURE bemerkbar?
    --------------------------------------------------------------------
    Auch hier ist die Antwort ganz klar: JA. Obwohl PowerBASIC keine
    Coprozessoruntersttzende Fliekommabibliothek eingebunden hat, lt
    sich dies anhand der beiliegenden Source sehr deutlich beweisen.
    Des Rtsels Ursache liegt in der PowerBASIC-Runtime-Bibliothek, diese
    untersttzt schon von Hause aus einen i87. Deshalb lassen sich auch die
    Geschwindigkeitsauswirkungen der verschiedenen Fliekommabibliotheken
    nicht verallgemeinern.


    3.4. Welche PowerBASIC-Funktionen sind betroffen?
    -------------------------------------------------
    Als betroffende internen PowerBASIC-Funktionen wre da vorallem
    SELECT CASE zu nennen. Messungen haben gezeigt das SELECT CASE mit i87
    5 Sekunden braucht. Unter den gleichen Voraussetzungen (aber ohne i87)
    bis zu 200 Sekunden bentigen kann ($FLOAT EMULATE). Enorme Ver-
    besserungen waren bereit mit $FLOAT PROCEDURE zu erreichen (jetzt
    nur noch 35 Sekunden).
    Im allgemeinen kann gesagt werden: SELECT CASE hat nichts in zeit-
    kritischen Routinen zu suchen.
    Ebenso, aber bei weitem nicht so extrem, ist die PRINT-Ausgabe von
    nummerischen Ausdrcken betroffen.


    3.5. mgliche Ursachen fr den CoProzessor-Effekt
    -------------------------------------------------
    Meines Erachtens hat dieser Effekt recht natrliche Ursachen, da alle
    betroffenden Befehle mit dem neuen 80-stelligen Zahlensystem umgehen
    knnen mssen. Anscheinend haben die Programmierer von PowerBASIC ver-
    sucht den zustzlichen Rechenaufwand durch Einsatz des CoProzessors
    wieder wettzumachen. Wobei Ihnen dies bei vorhandenem CoProzessor
    auch recht gut gelungen ist.
    Andererseits kann man sich fragen, warum der Compiler dies nicht besser
    optimiert sofern nur normale 16/32bit Zahlen eingesetzt werden.


    3.6. PowerBASIC-Benchmark Source
    --------------------------------
    Die hier beigefgte Source soll Ihnen die Zusammenhnge der vorherigen
    Abschnitte besser demonstrieren. Am besten Sie compilieren die Source
    und testen einfach ein wenig herum.

    Source:
        REM *****************************************************************
        REM
        REM   PBBENCH.EXE - Performance-Meprogramm fr PowerBASIC
        REM
        REM   Zum Feststellen der Geschwindigkeitsunterschiede einzelner
        REM   PowerBASIC-Befehle in Verbindung der verwendeten Fliekomma-
        REM   bibiothek bei vorhanden bzw. nichtvorhandensein eines
        REM   Coprozessors.
        REM
        REM   Copyright: Thomas Gohel & Andras Hoeffken         Version 2.10
        REM   Alle Rechte vorbehalten
        REM
        REM -----------------------------------------------------------------
        REM
        REM   Wichtige Hinweise:
        REM   Fr halbwegs reale Meungen mu sich der Prozessor im REAL-
        REM   Mode befinden. Es drfen keine TSR-Treiber installiert sein,
        REM   also kein KEYB.COM, SMARTDRV.EXE oder hnliches.
        REM   Wichtig:
        REM   Fr eine halbwegs genaue Meung mu das Programm mehrmals
        REM   aufgerufen und dann Mittelwerte gebildet werden.
        REM
        REM   Besitzer von 486'er/586'ern bzw. 286/386'ern mit
        REM   installiertem x87'er Prozessor knnen den CoProzessor fr
        REM   PowerBASIC mit dem in dieser Source beigefgtem Listing
        REM   Ein/Aus schalten. Das mu allerdings die IDE bzw. das fertige
        REM   EXE-File erneut gestartet werden!
        REM
        REM   *************************************************************
        REM
        $COMPILE EXE "PBBENCH.EXE"
        $CPU 80386
        $LIB ALL OFF
        REM $FLOAT NPX              ' fr Rechner mit CoProzeor (am
                                    ' schnellsten)
        REM $FLOAT PROCEDURE        ' fr Rechner ohne CoProzeor (von mir
                                    ' empfohlen)
        REM $FLOAT EMULATE          ' automatisch untersttzen (ohne
                                    ' Coprozessor extrem langsam!!
        REM $DEBUG MAP OFF

        PRINT
        PRINT "Performance-Messprogramm fuer PowerBASIC";:
        PRINT TAB(58); "(c) A.Hoeffken/Th.Gohel";:
        PRINT TAB(68); "Version 2.10";:
        PRINT STRING$(80,"-");
        PRINT
        a% = 1                           ' diverse Variablen
        i% = 1234                        '       -"-
        e& = 12345678                    '       -"-

        REM Zc1! fr 5000000-Schleifen   ; zum Herausrechnen der Zeiten
        REM Zc2! fr 2000000-Schleifen   ; fr die FOR/NEXT-Schleifen
        REM Zc3! fr 100000-Schleifen
        REM Zc4! fr 2000-Schleifen

        IF pbvnpx > 0 THEN
            PRINT "CoProzessor " + CHR$(pbvnpx+48) + "87 gefunden!"
            PRINT
            PRINT "Soll der CoProzessor fr die nchste Messung ";
            PRINT "ausgeschaltet werden (J/N)?"
            BEEP
            A$ = UCASE$(INPUT$(1))
            IF A$ = "J" THEN CoPro "AUS"
        ELSE
            PRINT "kein CoProzessor gefunden!"
            PRINT
            PRINT "Soll der CoProzessor fr die nchste Messung ";
            PRINT "wieder eingeschaltet werden (J/N)?"
            PRINT
            PRINT "Hinweis: Einschalten dieses Testes bei nicht ";
            PRINT "installiertem Coprozessor fhrt"
            PRINT "         zum Absturz!"
            BEEP
            A$ = UCASE$(INPUT$(1))
            IF A$ = "J" THEN CoPro "EIN"
        END IF

        PRINT
        GOSUB HoleZeitKonstanten
        GOSUB MesseFORNEXT
        GOSUB MesseIFTHEN
        GOSUB MesseSELECTCASE
        GOSUB MesseMATHEMATIK
        GOSUB MesseSTRING
        GOSUB MesseNUMPRINT
        GOSUB MesseSTRPRINT
        PRINT
        END

        '********************************************************************
        '  Holen der einzelen Zeitkonstanten fr die einzelnen Messungen
        '********************************************************************

        HoleZeitKonstanten:
        PRINT "Messung der Zeitkonstanten ";

        t1! = TIMER
        FOR i& = 1 TO 2000           ' Zeit fr 2000-Schleifen ausmessen
        NEXT i&
        t2! = TIMER
        Zc4! = t2! - t1!

        PRINT ".";
        t1! = TIMER
        FOR i& = 1 TO 5000000        ' Zeit fr 5-Mio-Schleifen ausmessen
        NEXT i&
        t2! = TIMER
        Zc1! = t2! - t1!

        PRINT ".";
        t1! = TIMER
        FOR i& = 1 TO 100000         ' Zeit fr 100000-Schleifen ausmessen
        NEXT i&
        t2! = TIMER
        Zc3! = t2! - t1!

        PRINT "."
        t1! = TIMER
        FOR i& = 1 TO 2000000        ' Zeit fr 2-Mio-Schleifen ausmessen
        NEXT i&
        t2! = TIMER
        Zc2! = t2! - t1!

        RETURN


        '********************************************************************
        '
        ' Hier nun die einzelnen Routinen zur Zeitmessung der einzelnen
        ' Befehle. Im Prinzip ist die Messung immer abhngig vom verwendeten
        ' Computersystem und dem installiertem Betriebssytem. Gerade aber in
        ' Verbindung mit PowerBASIC, der verwendeten Fliekommabibiliothek
        ' und dem Vorhandensein eines CoProzessors lassen sich erhebliche
        ' Unterschiede bei der Performance einzelner Befehle ermitteln.
        '
        '********************************************************************

        MesseFORNEXT:
            PRINT "Messe FOR/NEXT   : ";
            t1! = TIMER
            FOR i& = 1 TO 5000000        '5-Millionen-Schleife ausmessen,
            NEXT i&                      'i = long integer
            t2! = TIMER
            PRINT t2! - t1!; "sec "
            RETURN

        MesseIFTHEN:
            PRINT "Messe IF/THEN    : ";
            t1! = TIMER
            FOR i& = 1 TO 5000000
                IF a% = 0 THEN           'IF THEN Methode
                ELSEIF a% = 2 THEN
                ELSE
                END IF
            NEXT i&
            t2! = TIMER
            PRINT t2! - t1! - Zc1!; "sec "
            RETURN

        MesseSELECTCASE:
            PRINT "Messe SELECT CASE: ";
            t1! = TIMER
            FOR i& = 1 TO 2000000
                SELECT CASE A%           'SELECT CASE Methode
                    CASE 0
                    CASE 1
                    CASE ELSE
                END SELECT
            NEXT i&
            t2! = TIMER
            PRINT t2! - t1! - Zc2!; "sec "
            RETURN

        MesseMATHEMATIK:
            PRINT "Messe MATHEMATIK : ";
            t1! = TIMER
            FOR i& = 1 TO 2000000
                i% = i% + 100            'extrem einfache Aufgaben
                e& = e& * 2
                e& = e& \ 2
                i% = i% - 100
            NEXT i&
            t2! = TIMER
            PRINT t2! - t1! - Zc2!; "sec "
            RETURN

        MesseSTRING:
            PRINT "Messe STRING's   : ";
            t1! = TIMER
            FOR i& = 1 TO 2000
                A$ = STRING$(20000, 32)
                A$ = RIGHT$(A$, 10000) + "Test"
                e% = INSTR(A$, "Test")
               A$ = ""
            NEXT i&
            t2! = TIMER
            PRINT t2! - t1! - Zc4!; "sec "
            RETURN

        MesseNUMPRINT:
            PRINT "Messe NUM-PRINT's  ";
            t1! = TIMER
            FOR i& = 1 TO 100000
                LOCATE , 1
                PRINT "Messe NUM-PRINT's: "; i&;
            NEXT i&
            t2! = TIMER
            LOCATE , 20
            PRINT t2! - t1! - Zc3!; "sec "
            RETURN

        MesseSTRPRINT:
            PRINT "Messe $$$-PRINT's  ";
            t1! = TIMER
            FOR i& = 1 TO 100000
                LOCATE , 1
                PRINT "Messe $$$-PRINT's: ";
            NEXT i&
            t2! = TIMER
            LOCATE , 20
            PRINT t2! - t1! - Zc3!; "sec "
            RETURN

        '*****************************************************************
        ' Hier nun die Routine zum Ausschalten des Coprozessors
        '*****************************************************************

        SUB Copro(Switch$)
                SELECT CASE UCASE$(Switch$)
                     CASE "AUS", "OFF", "-"
                         ! mov ax, &h0040
                         ! mov es, ax
                         ! mov ax, word ptr es:[&h10]
                         ! and ax, &b1111111111111101
                         ! mov word ptr es:[&h10], ax
                     CASE "EIN", "ON", "+"
                         ! mov ax, &h0040
                         ! mov es, ax
                         ! mov ax, word ptr es:[&h10]
                         ! or  ax, &b0000000000000010
                         ! mov word ptr es:[&h10], ax
                END SELECT
        END SUB


    ====================
    4. Standard-Probleme
    ====================

    4.1.  Kompatibilitt der PBU's & LIB's zwischen den 3'er Versionen
    4.2.  Zu wenig Speicherplatz innerhalb der PowerBASIC-IDE
    4.3.  Ermitteln des eigenen Dateinamens und dem Pfad zum Dateinamen
    4.4.  Kein Speicherplatz verfgbar bei ENVIRON$
    4.5.  Keine Errorcode-Zurckgabe bei SHELL
    4.6.  Krzen von Files
    4.7.  Fehler 502/514 bei Verwendung von C-OBJ-Files
    4.8.  Warmboot ber STRG-ALT-ENTF verhindern
    4.9.  ffnen von mehr als 15 Files mit PowerBASIC und/oder mit DOS
    4.10. HEX$-DWORD Routine fr PowerBASIC 3.1/3.2

    <Hier fallen mir einfach keine mehr ein>


    4.1. Kompatibilitt der PBU's & LIB's zwischen den 3'er Versionen
    -----------------------------------------------------------------
    Im Gegensatz zum PowerBASIC-Update von der V2.10 auf die V3.00 sind
    die PBU/LIB's der PowerBASIC 3'er Versionen untereinander abwrt-
    kompatibel. Das heit, sie knnen eine mit PowerBASIC 3.0 erstellte
    PBU/LIB unter den beiden hheren PowerBASIC Versionen weiterverwenden.
    Eine mit PowerBASIC 3.1 erstellte PBU/LIB knnen Sie dagegen allerdings
    nicht mehr in der lteren Version nutzen.
    Zwischen den Versionen 3.0-3.1 gibt es aber Aufgrund des erweiterten
    Zahlensystems eventuell Unterschiede beim Austausch von Sourcen unter-
    einander. In diesem Fall lesen Sie sich bitte auch den Abschnitt
    'Fehler ...' durch.


    4.2. Zu wenig Speicherplatz innerhalb der PowerBASIC-IDE
    --------------------------------------------------------
    Fr das 'stndig vorhandene' Speicherplatzproblem innerhalb der
    integrierten Entwicklungsumgebung wurde von Bob Zale selbst ein Tool
    entwickelt, welches die Bereiche des VGA-Grafik-RAM's, sowie den Bereich
    der monochromen Herculeskarte fr PowerBASIC erschliesst. Obwohl das
    Tool 'PBPLUS96' (96kByte mehr RAM) fr die PowerBASIC Version 2.00
    entwickelt wurde, funktioniert es ebenso unter PowerBASIC Version 3.10.


    4.3. Ermitteln des eigenen Dateinamens und dem Pfad zum Dateinamen
    ------------------------------------------------------------------
    Oft stehen Sie vor dem Problem das Sie zwar Ihr Programm ber einen
    Pfad-Befehl aufrufen knnen, dieses dann aber die eigenen Daten und
    INI-Files nicht mehr findet. Die Lsung ist recht einfach: DOS
    speichert diese Informationen im PSP bzw. im zum PSP gehrigen
    Environmentblock.

    --- Cut --------------------------------------------------------------
    '*********************************************************************
    '
    '   Pfad und Dateiname des aktuellen Programm ermitteln in
    '   PowerBASIC 3.0/3.2
    '
    '   von Thomas Gohel
    '
    '*********************************************************************

    $COMPILE EXE

        ! mov ax, &h6200
        ! int &h21
        ! mov es, bx
        ! mov ax, word ptr es:[&h2C]
        ! mov pbvDefSeg, ax           ; undokumentiert in PowerBASIC 3.0
        FOR i% = 0 TO 1024
            IF PEEK$(i%, 4) = CHR$(0,0,1,0) THEN EXIT FOR
        NEXT i%
        WHILE PEEK(i% + 4) <> 0
            Temp$ = Temp$ + CHR$(PEEK(i% + 4))
            i% = i% + 1
        WEND
        DEF SEG
        FOR i%=LEN(Temp$) TO 1 STEP -1
            IF RIGHT$(MID$(Temp$,1,i%),1) = "\" THEN EXIT FOR
        NEXT i%
        ExeDir$ = MID$(Temp$,1,i%)
        ExeName$ = MID$(Temp$,i%+1)
        PRINT ExeDir$; "  "; ExeName$
    --- Cut End ----------------------------------------------------------


    4.4. Kein Speicherplatz verfgbar bei ENVIRON$
    ----------------------------------------------
    Dieser Absatz ist zwar teilweise im Handbuch beschrieben, doch mchte
    ich einige weiterfhrende Tips geben, da dieses Thema immer wieder zu
    Miverstndnissen fhrt. Der Aufbau des Environmentblockes in Verbindung
    mit dem Programm Segment Prefix wird nicht weiter beschrieben, ist
    allerdings von enormer Bedeutung zum besseren Verstndnis dieses Fehlers.

    Zusammenfassend sei gesagt, das Sie nur das vorhandene Environment
    modifizieren und nicht durch neue Eintrge erweitern knnen!! Wollen Sie
    nun trotzdem Eintrge hinzufgen, so knnen Sie 3 Wege beschreiten:

    a) Teile des Environment lschen und dann den neuen Eintrag hinzufgen
       oder bereits vorher einen Dummy-Environmenteintrag anlegen und diesen
       dann per ENVlRON-Befehl lschen bzw. modifizieren.

    b) Wenn Sie z.B. eine DOS-SHELL mit einer Information starten wollen:

           OldEnv$ = ENVIRON$("PROMPT")
           SHELL "COMMAND.COM /K SET PROMPT=PowerBASIC " + OldEnv$

       Der Trick hierbei ist, das bei einer SHELL automatisch ein neuer PSP
       erstellt wird und somit auch der Speicher passend angefordert wird.

    c) Die Adresse des PSP ermitteln, dann den Zeiger auf den aktuellen
       Environmentblock holen und jetzt das Environment komplett in einen
       String packen wo es modifiziert werden kann. Abschliessend einen
       passenden DOS-Speicherblock per INT21 anfordern, das modifizierte
       Environment dorthin kopieren und den Zeiger zum Environmentblock
       innerhalb des Programm Segment Prefix anpassen.
       (siehe auch: bereits vorhandene PD-Lsungen)


    4.5. Keine Errorcode-Zurckgabe bei SHELL
    -----------------------------------------
    Vielfach ist es erforderlich, wenn nach einem SHELL-Aufruf der Errorcode
    des beendeten Programms abgefragt werden kann. Dies ist in PowerBASIC
    nicht direkt mglich, da PowerBASIC das Programm immer ber COMMAND.COM
    ausfhrt und deshalb der Errorcode nicht zurckgeben werden kann (dies
    ist eine Eigenart von MS-DOS!!).

    Bespiel:
            SHELL "C:\DOS\COMMAND.COM /C MEINDEMO.EXE"

    Fr die Lsung dieses Problems gibt es zum einen einen alternativen
    SHELL-Befehl in Form einer FUNCTION (also Sourcecode):

    --- Cut ---------------------------------------------------------------
    '**********************************************************************
    '
    '   Errorlevel in PowerBASIC 3.0/3.2
    '
    '   von Thomas Gohel (nach einer Vorlage aus PDS, von Bernd Hohmann)
    '
    '***********************************************************************

    $COMPILE EXE
    DECLARE FUNCTION PBShell% (FileName$)

    CLS
    PRINT
    PRINT "Fehlercode ist: "; PBShell%("c:\dos\command.com")
    END

    FUNCTION PBShell% (FileName$)
        LOCAL Dummy%

        Datei$ = FileName$                  ' Dateiname umkopieren.
        Datei$ = LTRIM$(Datei$)             ' Filename trimmen.
        i% = INSTR(Datei$, " ")             ' Kommando bergeben ?
        IF i% > 0 THEN                      '
           Cmd$ = MID$(Datei$, i%)          ' Kommando abtrennen
           Datei$ = LEFT$(Datei$, i% - 1)   ' Filename abtrennen
        END IF                              '
        Datei$ = UCASE$(Datei$)
        i% = INSTR(Datei$, ".")             ' Ist ein Punkt drin ?
        IF i% > 0 THEN                      '
           Ext$ = MID$(Datei$, i%)          ' Extension holen.
        ELSE                                '
           Ext$ = ""                        ' Extension ist leer.
        END IF                              '
        SELECT CASE Ext$                    ' Extensions abtesten.
            CASE ".BAT"                     ' Batch ber COMMAND.COM
                                            ' ausfhren.
                Cmd$ = "/C " + Datei$ + " " + Cmd$
                Datei$ = ENVIRON$("COMSPEC")
            CASE ".COM"                     ' Frei
            CASE ".EXE"                     ' Frei
            CASE ELSE                       ' Keine Extension,
                Datei$ = Datei$ + ".EXE"    ' .EXE anhngen.
        END SELECT                          '

        Datei$ = Datei$ + CHR$(0)           ' ASCIIZ-String erzeugen.
        dNul$ = CHR$(0) + CHR$(0)           ' Doppelnull fuer Parameter-Block

        nul$ = SPACE$(127)                   ' 127 bytes fuer Strings retten.
        MemFree& = SETMEM(0)                 ' Freien Speicherplatz holen.
        x& = SETMEM(-MemFree&)               ' Speicherplatz komplett
                                             ' freigeben.
        nul$ = ""                            ' 127 bytes wieder freigeben.
        IF Cmd$ > "" THEN                    ' Kommandozeile ?
            CmdLen$ = CHR$(LEN(Cmd$))        ' Lnge des Cmd$ als String
            Cmd$ = CmdLen$ + Cmd$ + CHR$(13) ' Lnge + Cmd$ + '13'
            segm$ = MKI$(STRSEG(Cmd$))       ' Einzeln die Teile des
                                             ' Parameter-Blocks
            Offs$ = MKI$(STRPTR(Cmd$))       ' erzeugen ( MID$(....)
                                             ' = segm$ geht nicht. )
            Param$ = dNul$ + Offs$ + segm$   ' Parameterblock machen.
        ELSE                                 '
            Cmd$ = CHR$(13)                  ' Start of Bug-Fixed
            segm$ = MKI$(STRSEG(Cmd$))       ' Segment des Terminator (Dummy)
            Offs$ = MKI$(STRPTR(Cmd$))       ' Offset         -"-
            Param$ = dNul$ + Offs$ + segm$   ' Parameterblock machen.
        END IF                               ' End of Bugfixed
        DateiSeg% = STRSEG(Datei$)           ' Adressen holen
        DateiOff% = STRPTR(Datei$)
        ParamSeg% = STRSEG(Param$)
        ParamOff% = STRPTR(Param$)
        ! push ds                            ; DS sichern
        ! mov  ax, &h4B00                    ; EXEC-Funktion 4Bh / INT 21h
        ! mov  es, ParamSeg%                 ; Segment des Parameterblocks
        ! mov  bx, ParamOff%                 ; Offset des Parameterblocks
        ! mov  dx, DateiOff%                 ; Offset des Dateinamens
        ! mov  ds, DateiSeg%                 ; Segment des Dateinamens
        ! int  &h21                          ; Interrupt &h21
        ! pop  ds
        ! jc   ExecError
        ! jmp  ExecOk
        ExecError:
        ! mov Dummy%, ax
        SELECT CASE Dummy%                   ' Fehler auswerten.
            CASE 1   : PRINT "illegaler Funktionsaufruf!"
            CASE 2,3 : PRINT "Datei nicht gefunden: " + FileName$
            CASE 4   : PRINT "zu viele Dateien geffnet"
            CASE 5   : PRINT "Zugriff verweigert " + Filename$
            CASE 8   : PRINT "Zuwenig freier Speicher fr " + FileName$
            CASE 10  : PRINT "falscher Environmentblock"
            CASE 11  : PRINT "falsches Format"
            CASE ELSE: PRINT "Problem meim Ausfhren von " + FileName$
        END SELECT
        ExecOk:

        Mem2& = SETMEM(MemFree&)             ' Speicher komplett freigeben.
        IF MemFree& <> Mem2& THEN            ' Speicher stimmt nicht mehr ??
            PRINT "Achtung: vermutlich wurde ein TSR installiert!!"
        END IF

        ! mov  ah, &h4d                      ; Exit-Code ermitteln
        ! int &h21                           ; Interrupt &h21
        ! mov Dummy%, al
        PBShell% = Dummy%

        ! mov  ah, &h03                      ; Aktuelle Cursorposition
        ! mov  bh, &h00                      ; bergeben
        ! int &h10                           ; Interrupt &h10
        ! inc dh                             ; Umrechnen auf Basis 1
        ! inc dl
        ! mov NewZeile?, dh
        ! mov NewSpalte?, dl
        LOCATE NewZeile?, NewSpalte?         ' Cursor setzen
    END FUNCTION
    - Cut End -------------------------------------------------------------

    Des weiteren knnen Sie die COMSPEC-Variable in Ihrem Environment
    modifizieren und Ihr Programm ohne Umwege ber COMMAND.COM direkt
    ausfhren.
    Beispiel:
            Comspec$ = ENVIRON$("COMSPEC")  'Sichern von COMSPEC
            ENVIRON "COMSPEC=MEINDEMO.EXE"
            SHELL                           'Ausfhren von MEINDEMO.EXE
            ENVIRON "COMSPEC="+Comspec$     'Restaurieren von COMSPEC

    Beachten Sie allerdings, das die SHELL-Funktion immer automatisch
    den Parameter '/C' dem ausfhrendem Programm bergibt, sofern Sie
    zum Beispiel Kommandozeilenparameter bergeben wollen.


    4.6 Krzen von Files
    --------------------
    Oft stehen Sie vor dem Problem das Sie Ihr Datenfile aufgerumt haben,
    dieses aber immer noch viel zu gro ist. In diesem Fall hilft wie so
    oft ein kleiner aber effektiver Kniff:

    Beispiel:
            OPEN "DEMO.DAT" FOR BINARY AS #1
            SEEK #1, 20
            PUT$ #1, ""
            CLOSE #1

    Verkrzt die Datei 'DEMO.DAT' auf 20Bytes Lnge.


    4.7. Fehler 502/514 bei Verwendung von C-OBJ-Files
    --------------------------------------------------
    Bei der Verwendung von C-OBJ-Files ist darauf zu achten, das in der
    OBJ-Datei nicht mehrere Anweisungen fr das Datensegment zu finden sind,
    da PowerBASIC nur ein Datensegment pro OBJ-File untersttzt.
    Da mir zu Zeit auch keine Lsung zu diesem Problem bekannt ist und es
    vermutlich keine seitens PowerBASIC gibt, bleibt meines Erachtens nur
    das Anpassen Ihrer C-Source brig.


    4.8. Warmboot ber STRG-ALT-ENTF verhindern
    -------------------------------------------
    Folgende Source verhindert einen mglichen Warmboot:

    Beispiel:
            KEY 15, CHR$(&h0C, &h53, &h73)
            ON KEY(15) GOSUB NoBoot
            KEY(15) ON

            DO
               IF INKEY$ <> "" THEN EXIT LOOP
            LOOP
            PRINT "Fertig"
            END

            NoBoot:
            PRINT "Warmstart nicht erwnscht!"
            RETURN


    4.9. ffnen von mehr als 15 Files mit PowerBASIC und/oder mit DOS
    -----------------------------------------------------------------
    Oft scheint man an die Grenzen von PowerBASIC zu stoen, sofern man
    mehr als 15 Files ffnen will. Dabei ist dieses Problem berhaupt nicht
    ein Mangel des Compilers, sondern eher ein genetischer Geburtsfehler
    von MS-DOS.
    Um diesen Effekt zu erklren mu ich leider ein wenig in die Untiefen
    von DOS Licht bringen, denn dort finden wir auch des Rtsels Lsung.
    Vielen ist bestimmt bekannt, das nach dem ffnen von Dateien ein
    Handel zurckgeliefert wird. Nur wo speichert DOS dieses Handle und
    die Informationen die zu diesem Handle gehren?

    Vielen ist bestimmt der Begriff PSP (Programm Segment Prefix) ein
    Begriff (bereits kurz erwhnt bei der Ermittlung des Dateinamens), wenn
    nicht sollten Sie die folgenden Ausfhrungen besser berlesen und die
    Source testen.
    Dieses PSP enthlt jedenfalls eine Tabelle, welche durch Microsoft
    zwar als reserviert gilt, deren Bedeutung aber lngst klar ist. Diese
    Tabelle nennt sich 'Job File Table' (kurz JFT) und befindet sich ab
    DOS 2.0 am Offset 18Hex und umfasst ein 20 Felder groes BYTE-Array.
    Zieht man jetzt die stndig belegten Handles fr: NUL, $CLOCK, CON
    AUX und PRN ab, so verbleiben unsere magischen verfgbaren 15 Handles.
    Die Aufgabe der JFT ist es allerdings lediglich, einen Zeiger auf die
    'System File Table' kurz SFT zu verwalten.
    Die SFT wiederum ist eine MCB (Memory Controll Block) hnlich verkettete
    Struktur, welche wichtige Daten wie Startcluster und Sharingattribute
    verwaltet. Eine solche SFT kann nur eine bestimmte Anzahl von Handles
    beinhalten, um diese zu Erhhen mu in der CONFIG.SYS ein hherer Wert bei
    FILES angegeben werden. Nach dem Neustart des System reserviert MS-DOS
    nun mehr als SFT markierte MCB's. Sie knnten also nun theoretisch mehr
    als 20 Files ffnen, denn der Defaultwert bei FILES ist '8'.
    Leider stoen wir hierbei wiederum auf die begrenzte Anzahl der Eintrge
    in der JFT innerhalb des PSP. Ab MS-DOS 3.3 gibt es hierbei aber Abhilfe,
    da der INT &h21, Funktion &h67 ermglicht die Anzahl der verfgbaren
    Handles zu erhhen. Nur wie geht das genau, wo doch der Platz innerhalb
    des PSP begrenzt ist??
    Dazu erinnern wir uns wieder an die undokumentierten Felder innerhalb
    des PSP. Interessant wird jetzt der Offset &h32, dieser entht die neue
    Gre der JFT in WORD. Darauf folgt der neue Pointer zur Extendet JFT.
    Interessant ist hierbei nur, das dieses neue Array ein Array vom Typ
    WORD ist. Es knnen also theoretisch 65535 Handles verwaltet werden,
    was allerdings rein Hypothetisch ist, da die SFT weiterhin nur 255 Ein-
    trge verwalten kann.
    Wichtig bei der Neuzuweisung einer JFT sind eigentlich nur zwei Dinge:
        - Die neuen JFT bentigt Speicher, das heit sie mssen den Heap
          des aktuellen PowerBASIC Programms herunterschrauben!
        - Eine Extendet JFT wird bei SHELL/EXECUTE nicht an das Child-
          Programm vererbt! Fr das Child-Programm gilt also wieder die
          15 Files Grenze.

     Ok, jetzt aber die Source:

    '***********************************************************************
    '
    '  Erhhen der verfgbaren Handles in PowerBASIC 3.2
    '
    '  entwickelt von Th.Gohel  Fido:      2:2410/301.12
    '                           InterNet:  support@pbsound.snafu.de
    '                           Homepage:  http://www.snafu.de/~pbsound/
    '
    '***********************************************************************

    MaxFiles% = 30                       ' entspricht FILES = 30
    PBFiles MaxFiles%                    ' anpassen der verfgbaren Files

    FOR i% = 1 TO MaxFiles%              ' Testen der verfgbaren Files
        PRINT "ffne File:  PBFILES." + STR$(i%)
        OPEN "PBFILES." + STR$(i%) FOR BINARY AS i%
        PUT$ i%, "Testdatei" + STR$(i%) + " fr PBFILES, bitte lschen!"
    NEXT i%
    FOR i% = 1 TO MaxFiles%              ' und wieder schliessen
        CLOSE i%
    NEXT i%

    SUB PBFiles(BYVAL MoreFiles%)
        x& = SETMEM(-255)                ' sollte Ausreichen fr alle Flle
        ! mov ah, &h67                   ; Anzahl der verfgbaren Handles
        ! mov bx, MoreFiles%             ; festlegen
        ! add bx, 6                      ; die Standard-Handles fr PB
        ! int &h21
        ! jnc PBFiles_Ok
        PRINT "Fehler beim Einrichten der verfgbaren Handles!!"
        PBFiles_Ok:
    END SUB


    4.10. HEX$-DWORD Routine fr PowerBASIC 3.1/3.2
    -----------------------------------------------
    Nachfolgende Routine soll, den fr mich unverstndlicherweise fehlenden
    HEX$-Support fr Variablen vom Typ DWORD, ermglichen.

    Beispiel:
            d??? = &h1234ABCD

            PRINT DHex$(d???)

            FUNCTION DHex(HexDWord???) AS STRING
                    DIM Lo AS WORD
                    DIM Hi AS WORD
                    ! les  bx, [bp+6]
                    ! mov  ax, es:[bx+0]
                    ! mov  Lo??, ax
                    ! mov  ax, es:[bx+2]
                    ! mov  Hi??, ax
                    DHex = RIGHT$("000" + HEX$(Hi??), 4) + RIGHT$("000" + _
                    HEX$(Lo??), 4)
            END FUNCTION

    ===============================================
    5. Tip's in Verbindung mit dem Inline-Assembler
    ===============================================

    Kurzbersicht:
    5.1.  Funktionsprinzip des PowerBASIC Inline-Assemblers
    5.2.  Assembler Syntax Error
    5.3.  Fehlerhafte Variablenbergabe im Inline-Assembler
    5.4.  Probleme mit LDS/LES
    5.5.  Absturz nach Aufruf einiger INT-Funktionen
    5.6.  Fixup Overflow
    5.7.  Variablen zerlegen von WORD nach BYTE
    5.8.  Variablen zerlegen von DWORD nach WORD
    5.9.  Zugriff mit dem Inline-ASM auf Array's/Strukturen
    5.10. Parameterrckgabe mit dem Inline-ASM
    5.11. Variablenbergabe in Interrupt-Prozeduren
    5.12. Erstellen von 32bit-Zeigern
    5.13. Konvertierung von REG nach Inline-ASM
    5.14. Konvertierung von A86 nach Inline-ASM

    Die hier beschriebenen Tip's sollen keinen Grundlehrgang im Inline-
    Assembler darstellen, sondern nur die wichtigsten Anfngerprobleme
    umschiffen zu helfen. Auf eine genauere Beschreibung der Zusammenhnge
    wird deshalb verzichtet, es sei es gehrt zum Problem selber.


    5.1. Funktionsprinzip des PowerBASIC Inline-Assemblers
    ------------------------------------------------------
    Der PowerBASIC Inline-Assembler besitzt den Funktionsumfang der Intel
    8086 CPU. Das heit, da Sie Inline-Assembler-Code anderer Hochsprachen-
    Compiler bzw. reinen Assembler-Code leicht an den PowerBASIC Inline-
    Assembler anpassen mssen, da diese recht oft bereits 80286'er Befehle
    enthalten. In der Regel fallen immer wieder folgende Befehle auf, welche
    Sie wie folgt konvertieren knnen:
    <Listing>
        Quell-Source       - >      PowerBASIC
        shr ax, 2                   ! shr  ax, 1
                                    ! shr  ax, 1
                                    oder hnlich wie folgt:
        -----------------------------------------------------------
        shl ax, 3                   ! push cx
                                    ! mov  cl, 3
                                    ! shl  ax, cl
                                    ! pop  cx
        -----------------------------------------------------------
        pusha                       ! push ax
                                    ! push bx
                                    und so weiter bis alle Register ge-
                                    sichert sind
        -----------------------------------------------------------
        popa                        analog, nur Register wieder restaurieren.
    <Ende>


    5.2. Assembler Syntax Error
    ---------------------------
    Wenn wir von einem richtigen Syntaxfehler absehen, der in der Regel auf-
    tritt wenn Sie noch nicht so recht mit den Assemblerbefehlen vertraut
    sind, kann der Inline-Assembler von PowerBASIC auch einen 'scheinbaren'
    Syntax Error erzeugen. Dies ist dann immer der Fall, wenn der Compiler
    eine Variable im Inline-Assembler nicht auflsen kann, da Sie nicht in
    irgendeiner Form definiert ist.
    PowerBASIC legt normalerweise die verwendeten Variablen innerhalb einer
    reinen BASIC-Source selbststndig an und weist dieser Variablen Ihren
    Speicherplatz zu. Innerhalb des Inline-Assemblers mssen Sie dafr
    selber sorgen.
    Beispiel:
            ! mov ax, Demo%
    fhrt automatisch zu einem Syntax-Error, da der Compiler nichts mit der
    Variablen 'Demo%' anfangen kann. Sollten Sie der Variablen vorher einen
    Wert zuweisen:
            Demo% = 1
            ! mov ax, Demo%
    dann akzeptiert der Compiler nun die Assemblerzeile. Sie mssen aber
    nicht jedesmal die Variable speziell mit einem Wert laden, ein bloes
    DIM oder auch SHARED, PUBLIC, LOCAL etc. reicht hierbei vllig aus und
    initialisiert 'Demo%'.


    5.3. Fehlerhafte Variablenbergabe im Inline-Assembler
    ------------------------------------------------------
    Oft haben Sie bestimmt schon geflucht, da eine funktionierende Routine
    mit REG(x) nach der Umsetzung in den Inline-Assembler nicht mehr sauber
    funktioniert oder wenn ebenso Ihre Testroutine nicht mehr in einer
    SUB/FUNCTION ihre Arbeit verrichten will.
    Des Rtsels Lsung ist relativ einfach: Sie mssen Variablen fr den
    Inline-Assembler immer BYVAL bergeben.
    Beispiel:
            Demo 1
            FUNCTION Demo(BYVAL i%) public
                    ! mov ax, i%
                    ! inc ax
                    ! mov i%, ax
                    PRINT i%
            END FUNCTION
    Dieses kleine Demo addiert per Inline-Assembler einfach den Wert '1'
    und gibt diesen dann auf den Bildschirm aus. Lassen Sei einfach das
    BYVAL in der Parameterbergabe weg und testen Sie das Demo erneut!


    5.4. Probleme mit LDS/LES
    -------------------------
    hnlich wie bei der Parameterbergabe fr den Inline-Assembler verhlt
    sich das Funktionsprinzip der Assemblerbefehle LDS/LES. Von ent-
    scheidener Bedeutung ist hierbei ebenfalls ob Sie die Variable
    'BY COPY', 'BY REFERENCE' oder auch 'BY VALUE' bergeben. Als Faustregel
    knnen Sie sich merken:

    BY REFERENCE: - eigentlich als default im Hautprogramm
                  - bzw. wenn Sie die Variable als SHARED/PUBLIC etc.
                    deklariert haben.
    BY COPY:      - default immer in einer SUB/FUNCTION, sofern Sie
                    die Variable nicht BY VALUE bergeben.
    BY VALUE:     - interpretiert der Inline-Assembler immer als BY
                    REFERENCE.

    LDS/LES sollten Sie nur Variablen vom Typ BY COPY bergeben, da nur
    hierbei in DS/ES die Segmentadresse geladen wird und im anderen Register
    dann die Offsetadresse der Variablen.
    Bei der bergabe BY REFERENCE wird in DS/ES der hherwertige Inhalt der
    Variablen geladen, sofern vom Typ Long/DWord, ansonsten enthlt das
    DS/ES-Register einen irrelevanten Wert. Im anderen Register befindet
    sich dann der niederwertige Inhalt der Variablen.
    Beispiel:

            SHARED DemoSeg%, DemoOff%

            i& = &h12345678
            Demo1 i&
            Demo2 i&
            Demo3 i&

            FUNCTION Demo1(i&) public
                    PRINT "PB-Adresse   : ";:
                    PRINT HEX$(VARSEG(i&));":"; HEX$(VARPTR(i&))
            END FUNCTION

            FUNCTION Demo2(i&) public
                    ! les bx, i&
                    ! mov DemoSeg%, es
                    ! mov DemoOff%, bx
                    PRINT "LES /BY COPY : ";:
                    PRINT HEX$(DemoSeg%);":"; HEX$(DemoOff%)
            END FUNCTION

            FUNCTION Demo3(BYVAL i&) public
                    ! les bx, i&
                    ! mov DemoSeg%, es
                    ! mov DemoOff%, bx
                    PRINT "LES /BY VALUE: ";:
                    PRINT HEX$(DemoSeg%);":"; HEX$(DemoOff%)
            END FUNCTION


    5.5. Absturz nach Aufruf einiger INT-Funktionen
    -----------------------------------------------
    Warum dieser Abschnitt werden Sie sich fragen, hat der PowerBASIC
    Inline-Assembler irgendwelche Fehler? Die Antwort lautet definitiv:

    NEIN.

    Trotzdem sind viel Aufrufe ber INT-Funktionen des BIOS/DOS mit einiger
    Tcke verbunden, da Sie wichtige Segmente verbiegen bzw. speziell
    zuweisen mssen. Viele Buffer, die einer Funktion bergeben werden
    mssen, erwarten speziell im Datensegment-Register (DS) Ihren Zeiger.
    PowerBASIC selbst addressiert aber seine Variablen ebenfalls ber DS,
    sodas hier Konflikte vorprogrammiert sein knnen. So sollte es zum
    Beispiel nicht sein:

            ! mov ax, &h3D90        ; Funktion Datei ffnen
            ! mov ds, FileSeg??     ; Segment des Dateinamens laden,
            ! mov dx, FileOff??     ; jetzt kommt der erste Fehler, da
                                    ; FileOff?? nicht mehr ber DS
                                    ; addressiert werden kann. DS zeigt
                                    ; bereits woanders hin ...
            ! int &h21              ; INT-Aufruf
            ! mov Handle%, ax       ; da DS immernoch fr PowerBASIC ins
                                    ; Nirwana zeigt, schlgt diese Zeile
                                    ; ebenfalls fehl und PowerBASIC
                                    ; strzt ber kurz oder lang ab.

    Ein sauberes Listing sollte wie folgt aussehen:

            ! push ds               ; DS sichern
            ! mov  ax, &h3D90
            ! mov  dx, FileOff??    ; Offset des Dateinamens laden
            ! mov  ds, fileSeg??    ; Segment des Dateinamens laden,
                                    ; fr PowerBASIC brauchen wir es
                                    ; auch nicht mehr
            ! int &h21              ; INT-Aufruf
            ! pop ds                ; PowerBASIC Segment restaurieren
            ! mov Handle%, ax       ; Handle% (bzw. Fehlercode) zuweisen
            ! jnc ...               ; Carry-Flag abfragen


    5.6. Fixup Overflow
    -------------------
    Das Problem ist recht einfach und simpel: Die 8086'er CPU lt nur
    bedingte Sprnge vom Typ SHORT zu, das heit sie knnen direkt nur
    Labels im Bereich von -127/+128 Opcodes Entfernung anspringen.
    Folgendes Beispiel erzeugt also einen Fehler:

            DemoLabel:
            <mehr als 128 Bytes Opcode>
            ! jc DemoLabel

    Um der Sache aus dem Weg zu gehen, mssen Sie die ganze Sache nur etwas
    anders adressieren. Das ist im Prinzip kein Problem, man muss es nur
    einmal wissen:

            DemoLabel:
            <mehr als 128 Bytes Opcode>
            ! jnc DemoWeiter
            ! jmp near DemoLabel
            DemoWeiter:

    Das steht allerdings auch in jedem Assembler-Buch ...


    5.7. Variablen zerlegen von WORD nach BYTE
    ------------------------------------------
    Sollten Sie immer noch Ihre 16bit Variablen mit mathematischen Aufwand
    in Ihre 8bit Bestandteile zerlegen, so wird es Zeit das Sie endlich
    damit aufhren. Das kann die CPU von ganz alleine erledigen:
    Beispiel:
            DIM Demo     AS WORD
            DIM DemoHigh AS BYTE
            DIM DemoLow  AS BYTE

            Demo?? = &H1234

            ! mov  ax, Demo??
            ! mov DemoLow? , al
            ! mov DemoHigh?, ah


    5.8. Variablen zerlegen von DWORD nach WORD
    -------------------------------------------
    fters steht man vor dem Problem, das man zwar Zeiger und Variablen vom
    Typ DWORD in PowerBASIC hat, allerdings nicht weis wie man diese im
    Inline-Assembler bergeben kann oder je nach Bedarf auch in WORD zer-
    legen. Im Prinzip ist auch diese recht einfach (gewut wie):
    Beispiel:

            DIM Demo     AS DWORD
            DIM DemoHigh AS WORD
            DIM DemoLow  AS WORD

            Demo??? = &H12345678

            ! mov  ax, Demo???[00]
            ! mov  bx, Demo???[02]
            ! mov DemoLow??,  ax
            ! mov DemoHigh??, bx


    5.9. Zugriff mit dem Inline-ASM auf Array's/Strukturen
    ------------------------------------------------------
    Relativ einfach ist der Zugriff mit dem Inline-Assembler auf feste
    Datenstrukturen, sofern sie bereits vorher die genauen Offsetadressen
    Adressen wissen.
    PowerBASIC erlaubt Ihnen folgenden Syntax:

    Beispiel:
            ! mov ah, byte ptr es:[di][22]

    Kopiert den Wert zum Offset 22 der Adresse ES:DI in das AH-Register.


    5.10. Parameterrckgabe mit dem Inline-ASM
    -------------------------------------------
    Im Gegensatz zum reinem Assembler luft die Rckgabe einer Variablen
    im PowerBASIC Inline-Assembler leicht anders ab. PowerBASIC 3.0 ge-
    stattet z.B. nicht die direkte bergabe aus dem Inline-Assembler an
    die FUNCTION, dies ist nur ber einen kleinen Trick mglich.

    Beispiel:
            High% = &h1234
            Low%  = &h4578
            PRINT HEX$(Demo1&(High%, Low%))

            FUNCTION Demo1&(BYVAL High%, BYVAL Low%)
                    LOCAL Dummy&
                    ! mov dx, High%
                    ! mov ax, Low%
                    ! mov Dummy&[02], dx
                    ! mov Dummy&[00], ax
                    Demo1& = Dummy&
            END FUNCTION

    Ab PowerBASIC 3.1 knnen Sie den Rckgabewert aber direkt an die
    FUNCTION bergeben, nur bei 32bit (und greren) Werten mssen Sie
    wieder einen kleinen Kniff anwenden:

    Beispiel:
            High% = &h1234
            Low%  = &h4578
            PRINT HEX$(Demo2&(High%, Low%))

            FUNCTION Demo2&(BYVAL High%, BYVAL Low%)
                    ! mov dx, High%
                    ! mov ax, Low%
                    ! mov FUNCTION[02], dx
                    ! mov FUNCTION[00], ax
            END FUNCTION


    5.11. Variablenbergabe in Interrupt-Prozeduren
    ------------------------------------------------
    Sehr schwierig ist die bergabe von Variablen innerhalb einer eigenen
    Interruptroutine, da sie davon ausgehen knnen, das das Datensegment
    mit hoher Sicherheit nicht dem bentigtem Datensegment von PowerBASIC
    entspricht. Allerdings auch hier haben uns die Entwickler von PowerBASIC
    eine groe Hintertr offen gelassen. Die Adressierung ber das Code-
    segment, welches in der Regel immer gleich ist! Allerdings klappt dieser
    Trick nur im Inline-Assembler, zur bergabe von/zu reinen PowerBASIC
    Routinen mssen sie diese Variable umkopieren.

    Beispiel:
            ! mov ax, &h1234
            ! mov Demo, ax
            ! mov bx, Demo
            ! retn

            Demo:
            ! dw 0

    Sollten Sie sich diese Sache unter einem Debuger ansehen, so werden sie
    feststellen das PowerBASIC vor dem Variablenzugriff das Prfix &h2E
    (Adressierung ber das Codesegment) voranstellt und das '! dw 0'-Feld
    den Wert &h1234 angenommen hat.


    5.12. Erstellen von 32bit-Zeigern
    ----------------------------------
    Oft werden 32bit Zeiger bentigt um eigene Interrupt-Prozeduren, alte
    Interrupt-Handler oder auch Gertetreiber wie CTVDSK/CT-VOICE und
    HIMEM/MSCDEX aufzurufen. Da die Erstellung des 32bit Zeigers in einem
    der vorangegangenden Abstze beschrieben wurde, hier nur noch der
    eigentliche Syntax:

    Beispiel:
            ! jmp dword Demo&
            ! jmp dword ptr Demo&
            ! call dword Demo&
            ! call dword ptr Demo&

    Die Zeiger knnen ebenfalls dem Codesegment entnommen werden!


    5.13. Konvertierung von REG nach Inline-ASM
    -------------------------------------------
    Ebenfalls recht einfach luft die Umsetzung von REG- nach Inline-
    Assemblersourcen ab. Im Gegensatz zum REG-Befehl, welcher die Inhalte
    der Prozessorregister in einem internen REG-Array zwischenpuffert, be-
    wirkt ein Zugriff ber den Inline-Assembler sofort eine direkte Mani-
    pulierung der Prozessorregister. Der REG-Befehl bergibt die REG-Werte
    erst beim Aufruf von CALL INTERRUPT. Bitte beachten Sie diesen Unter-
    schied und Sie werden weniger Probleme haben.
    Ansonsten knnen Sie zum Beispiel folgende Befehle 1:1 umsetzen:

    Beispiele:
            REG 1, &h12345           -> ! mov ax, &h1234
            REG 2, &hFF              -> ! mov bl, &hFF
            REG 3, &h22 * 256        -> ! mov ch, &h22
            REG 4, &hAABB            -> ! mov dh, &hAA
                                        ! mov dl, &hBB
            REG 9, Demo%             -> ! mov es, Demo%
            CALL INTERRUPT &h21      -> ! int &h21
            Low?? = REG(1) AND 255   -> ! mov low??, al
            High?? = REG(1) \ 256    -> ! mov High??, ah


    5.14. Konvertierung von A86 nach Inline-ASM
    -------------------------------------------
    Prinzipiell ohne Probleme luft eine Umsetzung von A86-Sourcen ab. Ent-
    fernen Sie einfach den Stackrahmen und binden Sie die Assemblerzeilen
    einfach in Ihren Inline-Assembler ein. Am besten ist es, wenn Sie dazu
    einen Funktionsaufruf erstellen, der die Variablen immer BYVAL bergibt,
    den Rest erledigt PowerBASIC.


    ======================================================
    6. Tip's in Verbindung mit Pointern und PowerBASIC 3.2
    ======================================================

    Krzbersicht:
    6.1. Allgemeines ber Pointer
    6.2. Was sind Pointer und was knnen sie leisten?
    6.3. PowerBASIC-Pointer und dynamische Strings
    6.4. PowerBASIC-Pointer und feste Strings
    6.5. PowerBASIC-Pointer und Flex Strings
    6.6. PowerBASIC-Pointer und Type Strukturen
    6.7. Demonstrations-Source


    6.1. Allgemeines ber PowerBASIC-Pointer
    ----------------------------------------
    Pointer in Verbindung BASIC haben bereits zahlreiche Diskussionen ent-
    facht, die dynamische Speicherverwaltung von PowerBASIC wird hierbei
    immer als 'Geburtsfehler' ins Feld gefhrt.
    Das sich dieser elementare Vorteil der BASIC-Programmiersprache auch
    ohne Probleme beim Einsatz von Pointern ausspielen lt, soll Ihnen
    dieser Abschnitt erlutern, denn der Einsatz von Pointern in PowerBASIC
    ist mit keinerlei Einschrnkungen verbunden!
    Allerdings sollten Sie fr das Lesen folgender Artikel bereits Wissen
    ber die interne Wirkungsweise von BASIC und auch DOS haben.


    6.2. Was sind Pointer und was knnen sie leisten?
    -------------------------------------------------
    Pointer (auch Zeiger genannt) bieten die Mglichkeit, Datenstrukturen
    an einer beliebigen Stelle des DOS-Speichers zu interpretieren. Dazu
    mssen Sie dem Pointer nur eine beliebige Adresse bergeben.
    Pointer dienen vor allem dazu Speicherbereiche zu nutzen, welche auer-
    halb der dynamischen Speicherverwaltung von PowerBASIC liegen. Sie
    knnen mit Pointern z.B. direkt Strukturen interpretieren, auf die von
    DOS-Funktionen Zeiger zurckgeliefert werden, wie z.B.:
        - Directory Table Area
        - Drive Parameter Block
        - DOS Info Block
        - PSP
        - Environment Block
        - und und und ...
    Das bisher notwendige Umkopieren mit DEF SEG/POKE/PEEK entfllt ab sofort
    und auch das leidige DEF SEG = PEEKI(...) sollten Sie in einem solchem
    Falle sofort vergessen.


    6.3. PowerBASIC-Pointer und dynamische Strings
    ----------------------------------------------
    String-Pointer auf feste Strings mssen in PowerBASIC wie folgt definiert
    werden:

        DIM Pointer AS STRING PTR

     Der Pointer selber ist wie folgt zu initialisieren:

        Pointer = VARPTR32(Demo1$)

    Beispiel:
            '***************************************************************
            '
            ' Demo zum korrekten Umgang mit Pointern und dynamische Strings
            '
            '***************************************************************

            DIM Pointer1 AS STRING PTR   ' String Pointer fr dynamische
                                         ' Strings definieren
            Pointer1 = VARPTR32(Demo1$)  ' Zeiger auf Stringhandle holen

            CLS
            PRINT "Adresse:      Demo1$:       Pointer1:"

            Demo1$ = "123456"
            PRINT HEX$(VARPTR32(Demo1$)), Demo1$, @Pointer1

            Demo1$ = "654321"
            PRINT HEX$(VARPTR32(Demo1$)), Demo1$, @Pointer1

            Demo1$ = "!Test!"
            PRINT HEX$(VARPTR32(Demo1$)), Demo1$, @Pointer1


    6.4. PowerBASIC-Pointer und feste Strings
    -----------------------------------------
    String-Pointer auf feste Strings mssen in PowerBASIC wie folgt definiert
    werden:

        DIM Demo AS STRING * 6
        DIM Pointer AS STRING PTR * 6

    Der Pointer selber ist wie folgt zu initialisieren:

        Pointer = VARPTR32(Demo$)

    Beispiel:
            '***************************************************************
            '
            ' Demo zum korrekten Umgang mit Pointern und festen Strings
            '
            '***************************************************************

            DIM Demo2 AS STRING * 6      ' String mit konstanter Lnge
                                         ' definieren!
            DIM Pointer2 AS STRING PTR * 6
                                         ' String Pointer definieren
            Pointer2 = VARPTR32(Demo2$)  ' Zeiger auf String holen

            PRINT
            PRINT
            PRINT "Adresse:      Demo2$:       Pointer2:"

            Demo2$ = "123456"
            PRINT HEX$(VARPTR32(Demo2$)), Demo2$, @Pointer2

            Demo2$ = "654321"
            PRINT HEX$(VARPTR32(Demo2$)), Demo2$, @Pointer2

            Demo2$ = "!Test!"
            PRINT HEX$(VARPTR32(Demo2$)), Demo2$, @Pointer2


    6.5. PowerBASIC-Pointer und FLEX-Strings
    ----------------------------------------
    Pointer auf FLEX-Strings mssen in PowerBASIC wie folgt definiert
    werden:

        DIM Demo AS FLEX
        DIM Pointer AS FLEX PTR

    Der Pointer selber ist wie folgt zu initialisieren:

        Pointer1 = VARPTR32(Demo1$)

    Um mit FLEX-Strings korrekt arbeiten zu knnen, mssen diese vor dem
    Erstellen des Pointers mit MAP gebildet werden!

    Beispiel:
            '***************************************************************
            '
            ' Demo zum korrekten Umgang mit Pointern und FLEX Strings
            '
            '***************************************************************

            DIM Demo3 AS FLEX            ' String als FLEX definieren!
            DIM Pointer AS FLEX PTR
            MAP Demo3$$ * 10             '
            FLEXCHR$ = "."

            Pointer = VARPTR32(Demo3$$)  ' Zeiger auf FLEX$-Handle holen

            PRINT
            PRINT
            PRINT "Adresse:      Demo3$$:      Pointer:"

            Demo3$$ = "123456"
            PRINT HEX$(VARPTR32(Demo3$$)), Demo3$$, @Pointer

            Demo3$$ = "654321"
            PRINT HEX$(VARPTR32(Demo3$$)), Demo3$$, @Pointer

            Demo3$$ = "!Test!"
            PRINT HEX$(VARPTR32(Demo3$$)), Demo3$$, @Pointer


    6.6. PowerBASIC-Pointer und TYPE Strukturen
    -------------------------------------------
    Pointer auf TYPE Strukturen mssen in PowerBASIC wie folgt definiert
    werden:

    TYPE Demo4_Struc                          ' TYPE definieren
            Demo5  AS BYTE
            Demo6 AS BYTE
    END TYPE

    Der Pointer selber ist wie folgt zu initialisieren:

    DIM TypeDemo AS SHARED Demo4_Struc PTR

    Ein Beispiel zu Pointern und TYPE Strukturen finden sie eine Source
    im folgenden Abschnitt.


    6.7. Demonstrations-Source
    --------------------------
    '************************************************************************
    '
    ' Zugriff auf den Videoram ber Pointer in PowerBASIC 3.2
    '
    ' (c) Thomas Gohel
    '
    ' Eine kleine Demonstration, das Pointer wirklich nichts (!!) mit der
    ' internen Speicherverwaltung zu tun haben und der erfolgreiche Einsatz
    ' von Pointern sehr gute interne Kenntnisse von PowerBASIC vorraussetzt.
    '
    ' In diesem Demo wird der Videoram als Speicher mibraucht und gezeigt,
    ' wie PRINT-Ausgaben den Inhalt der beiden Pointer VIDEORAM und ZEICHEN
    ' modifizieren.
    '
    ' Als sinnvolle Erweiterung knnte man diese Routine zum schnellen
    ' Sichern und Restaurieren des kompletten Videorams nutzen:
    '
    '         @Videoram.Page2 = @Videoram.Page1
    '
    ' wrde den kompletten Inhalt der ersten Page in die zweite Seite retten
    ' um spter wieder restauriert werden zu knnen
    '
    '************************************************************************

    TYPE Zeichen_Struc                       ' Aufbau eines einzelnen Zeichens
            Wert  AS BYTE
            Farbe AS BYTE
    END TYPE

    TYPE Screen_Struc                        ' Aufbau der Seiten im Videoram
            Page1 AS STRING * 4096           ' Seite 1
            Page2 AS STRING * 4096           ' Seite 2
            Page3 AS STRING * 4096           ' Seite 3
            Page4 AS STRING * 4096           ' Seite 4
    END TYPE

    DIM Zeichen AS SHARED Zeichen_Struc PTR
    DIM Videoram AS SHARED Screen_Struc PTR  ' TYPE-Strukturen erzeugen

    Videoram = pbvScrnBuff                   ' Type-Struktur auf den Anfang
                                             ' des aktuellen Video-Ram
                                             ' schieben,
                                             ' PowerBASIC nutzt und verwaltet
                                             ' den Videoram ab sofort als
                                             ' festen Stringspeicher!  :-)))
    Zeichen  = pbvScrnBuff                   ' TYPE-Struktur soll gleichen
                                             ' Speicherbereich wie PRINT und
                                             ' VIDEORAM nutzen

    SCREEN 0                                 ' Screen-Mode setzen
    CLS                                      ' alles lschen

    PRINT "Dies ist ein Test"                ' normales PRINT auf den
                                             ' Bildschirm
    A$=INPUT$(1)

    PRINT LEFT$(@Videoram.Page1,34)          ' Anzeigen der PRINT-Befehl
                                             ' automatisch auch unsere
                                             ' Struktur gefllt wird
    A$=INPUT$(1)

    @Videoram.Page2 = @Videoram.Page1        ' Videoram in Page 2 retten

    @Zeichen.Wert  = 76                      ' Jetzt wird die Zeichen-
                                             ' Struktur mit einem Wert
    @Zeichen.Farbe = 14                      ' gefllt. Hierbei erfolgt
                                             ' gleichzeitig die Ausgabe
                                             ' auf den Bildschirm und das
                                             ' aktualiseren von der Video-
                                             ' RAM-Struktur
    PRINT LEFT$(@Videoram.Page1,34)
    A$=INPUT$(1)

    @Videoram.Page1 = @Videoram.Page2        ' Videoram von Page 1
                                             ' restaurieren

    Pointer_Speed_Test:

            PRINT STRING$(25*80,178);        ' Bildschirm fllen
            LOCATE 1, 9
            COLOR 11, 1
            PRINT "  -= STRING-Manipulation innerhalb des";
            PRINT " Bildschirmspeichers! =-  "
            @Videoram.Page2 = @Videoram.Page1

            COLOR 14, 1
            LOCATE 8,20: PRINT "Ŀ"
            FOR i% = 9 TO 18
                LOCATE i%, 20
                PRINT          "                                        "
            NEXT i%
            LOCATE 10, 22: PRINT "Bildschirmspeicher wird als STRING"
            LOCATE 11, 22: PRINT "verwaltet!"
            LOCATE 13, 22: PRINT "  -= Ein Demo zur PowerBASIC-FAQ =- "
            LOCATE 19, 20
            PRINT              ""

            @Videoram.Page3 = @Videoram.Page1

            FOR i% = 1 to 1000
                @Videoram.Page1 = @Videoram.Page2
                @Videoram.Page1 = @Videoram.Page3
            NEXT i%

            FOR i% = 1 TO 10
                FOR Durchlauf% = 1 TO 256
                    Zeichen = pbvScrnBuff
                    FOR Offset% = 1 TO 2048
                        IF @Zeichen.Wert > 32 THEN
                            DECR @Zeichen.Wert
                        END IF
                        Zeichen = Zeichen + 2
                    NEXT Offset%
                NEXT Druchlauf%
                @Videoram.Page1 = @Videoram.Page3
            NEXT i%
    '************************************************************************


    ===================================================
    7. Tip's in Verbindung mit Turbo-C bzw. Borland C++
    ===================================================

    Kurzbersicht:
    7.1.  Autor
    7.2.  Warum externe Routinen fr PB3 in C schreiben/verwenden
    7.3.  Speicher-Modell angleichen
    7.4.  Einschrnkungen durch den PowerBASIC 3.x Compiler/-Linker
    7.5.  Parameterbergabe
    7.6.  PowerBasic-Beispiel
    7.7.  Zugehriger C-Modul
    7.8.  Der zur C-Routine gehrige Assembler-Code
    7.9.  Verwendung von Routinen fremder C-Bibliotheken
    7.10. Massnahmen bei Verwendung von PB V2.1


    7.1. Autor
    ----------
    Die Tip's fr PowerBASIC in Verbindung mit C-Compilern wie Turbo-C bzw.
    Borland C++ wurden freundlicherweise von:

                Andras Hoeffken <ah@confusion.rmc.de>
                Andras Hoeffken <2:2480/13.34 @ fidonet>
                Andras Hoeffken <130:1316/103 @ basnet-Germany>

    fr diese FAQ zur Verfgung gestellt.

    Sehr ntzliche Hinweise sind auch in der Datei CTOPB.FAQ enthalten, diese
    gehrt zum Lieferumfang von PB Vs. 3.2.


    7.2. Warum externe Routinen fr PB3 in C schreiben/verwenden
    ------------------------------------------------------------
    - C-Routinen ergeben schnell laufenden Code
    - fr extrem schnellen Code: C-Source schreiben und in ASM-Source
      bersetzen lassen (geht VIEL schneller als ASM-Source direkt
      zu schreiben), dann den ASM-Quellcode optimieren (Beispiel: s.u.)
    - Routinen fremder C-Bibliothen knnen mit PB verwendet werden


    7.3. Speicher-Modell angleichen
    -------------------------------
    Fr das Linken von *.EXE-Files knnen (z.B. bei MASM oder C) verschiedene
    Speichermodelle vorgegeben werden, z.B. Tiny, Small, Medium, Compact,
    Large, Huge, ...

    Fr die von PowerBASIC erzeugten *.EXE gilt nur:
            PowerBASIC 3.x - Speichermodell = LARGE
            (PB benutzt fr Code- und Datensegmente 32-bit FAR Pointer)

    Der C-Compiler mu daher in seinem Men:
            Options / Compiler / Code Generation / Model
    auf das Modell LARGE eingestellt werden.


    7.4. Einschraenkungen durch den PowerBASIC 3.x Compiler/-Linker
    ---------------------------------------------------------------
    a) Der PB3-Linker kann nur .OBJ-Module mit EINEM Datensegment einbinden,
       bei einem 2. Datensegment oder einer DGROUP streikt der PB3-Linker
       und erzeugt Errors. - C-Compiler verwenden in der Grundeinstellung
       zunaechst immer mehrere Datensegmentnamen, die in der Datengruppe
       DGROUP zusammengefasst sind (das hat bestimmte Vorteile). Die IDE
       des C-Compilers muss daher in ihrem Men:
                   Options / Compiler / Names
       wie folgt eingestellt werden:

           Code Segment: _TEXT          Bss Segment:      _DATA
           Code Group:                  Bss Group:
           Code Class:   TEXT           Bss Class:        DATA
           Data Segment: _DATA          Far Data Segment:
           Data Group:                  Far Data Group:
           Data Class:   DATA           Far Data Class:
           (die noch vorhandenen Sternchen MUESSEN gelscht werden)

       Jetzt erzeugt der C-Compiler nur noch EINEN Daten-Segmentnamen
           und keine DGROUP mehr!

    b) Der PB3-Linker (< Vs. 3.2) akzeptiert keine "_" bei Segmentnamen (ist
       bei C ein Standard), daher: In der $LINK-Zeile "$ALIAS" verwenden
       (s.u.)!

    c) Der PB3-Compiler (< Vs. 3.2) akzeptiert keine "_" in Namen von
       Funktionen und SUB's (ist bei C ein Standard), daher: In den DECLARE-
       Zeilen "$ALIAS" verwenden (s.u.)!

    d) Der PB3-Compiler bergibt bei Funktionen und Subs die Parameter in der
       Reihenfolge "von rechts nach links" (Pascal Konvention) und er-
       wartet, da die externe Routine den Stack selbst aufrumt, C-
       Compiler arbeiten umgekehrt. Daher: In den DECLARE-Zeilen "CDECL"
       verwenden (s.u.)!


    7.5. Parameterbergabe
    -----------------------
    PB3 uebergibt Parameter an externe Routinen auf 2 Arten:
        - mit 'far pointern' ('by reference' bzw. 'by copy')
        - direkt auf dem Stack (BYVAL)

    Entsprechend mssen die Deklarationen in den C-Routinen angepat werden.


    7.6. PowerBASIC-Beispiel
    ------------------------
    Im nachfolgenden .BAS-Programm zeigen 2 Routinen die Mechanismen:
    - A: in der Addier-Funktion "addab" (integer) wird "c=a+b" berechnet, der
         Funktionswert wird mit "x=c+1" zurckgegeben.
    - B: in der String-Routine "chst" wird das erste Zeichen eines Strings
         durch "*" ersetzt.

    --- Cut ------------------------------------------------------------
    'PB3_TBC.BAS - Turbo-C-Routinen in PB3.x einlinken

    $ALIAS DATA AS "_DATA"  'Zuordnung eines(!) Segmentnamens
    $LINK "pb3_tbc.obj"     'C-Spezialeinstellung ohne DGROUP!

    DEFINT A-Z
    DECLARE FUNCTION addab CDECL ALIAS "_addab" (a, BYVAL b, c)
    DECLARE SUB chst CDECL ALIAS "_chst" (word, word, integer)

    CLS: a = 7: b = 1: c = 0
    PRINT "c_vorher                =";c         'c=0
    x = addab (a, b, c)                         'A: c=a+b
    PRINT "c_nachher = a(7) + b(1) =";c         'c=8
    PRINT "x = c_nachher + 1       =";x         'x=9

    a$ = "hallo"
    CALL chst (strseg(a$), strptr(a$), len(a$)) 'B: Change String
    PRINT "Geaenderter String      = ";a$       'druckt "*allo"
    END
    --- Cut End --------------------------------------------------------


    7.7. Zugehriger C-Modul
    ------------------------
    --- Cut ------------------------------------------------------------
    /* Modul PB3_TBC.C  */

    #include <dos.h>  /* C-Bibliotheksfunk. (f. Strings) einbinden */

    static int d = 1;          /* d und e kommen ins Datensegment */
    static int e;              /* d und e sind KEINE Basic-Variablen */

    int addab(int far *a, int b, int far *c)
    {
        *c = *a + b;
         e = *c + d;
         return e;
    }

    void chst(unsigned far *stseg, unsigned far *stofs, int far *stlen)
    {
        char far *stdata;      /* Pointer auf den 1. String Char */

        if (*stlen)            /* falls Stringlaenge > 0 */
        {
        stdata = (char far *) MK_FP(*stseg, *stofs); /* Pointer holen */
        if (stdata)            /* falls gueltiger String */
            *stdata = '*';     /* 1. Char austauschen */
        }                      /* (Stringlaenge NICHT ueberschreiben !! */
    }
    --- Cut End --------------------------------------------------------


    7.8. Der zur C-Routine gehoerige Assembler-Code:
    ------------------------------------------------
    Fr alle, die C nicht so genau kennen: Der ASM-Code gibt einen Eindruck,
    wie kompakt und schnell der vom C-Compiler erzeugte Code ist.

    Zur Gewinnung des nachstehenden Codes wurde zuerst der obige Modul
    PB3_TBC.C als PB3_TBC.OBJ compiliert, dann wurde mit einem Dis-
    assembler fr .OBJ-Files (OBJ2ASM.EXE) das nachstehende File PB3_TBC.ASM
    erzeugt (da weiss man was man hat).

    (Man kann auch die IDE des C-Compilers beauftragen, den C-Modul in einen
    ASM-Modul zu uebersetzen und abzuspeichern.)

    --- Cut ------------------------------------------------------------
    ;File PB3_TBC.ASM (disassembliert von PB3_TBC.OBJ)

    _TEXT  SEGMENT BYTE PUBLIC 'CODE'
    _TEXT  ENDS

    _DATA  SEGMENT WORD PUBLIC 'DATA'
                                ;Achtung: kein BSS-Segment, keine DGROUP !!
    _DATA  ENDS

    PUBLIC _addab
    PUBLIC _chst

    _TEXT   SEGMENT
    assume cs: _TEXT
    assume ds: _DATA

    _addab:
    push   bp
    mov    bp,sp
    ; c = a + b:
    les    bx,dword ptr [bp+006h] ; a
    mov    ax,es:[bx]
    add    ax,[bp+00Ah]           ;   + b
    les    bx,dword ptr [bp+00Ch]
    mov    es:[bx],ax             ; c
    ;e = c + d:
    mov    ax,es:[bx]             ;c (Zeile kann beim Optimieren entfallen)
    add    ax,$S1                 ;   + d
    mov    dx,seg _DATA
    mov    es,dx
    mov    es:$S2,ax              ; e
    ;return e:
    mov    ax,seg _DATA           ; (Zeile kann beim Optimieren entfallen)
    mov    es,ax                  ; (Zeile kann beim Optimieren entfallen)
    mov    ax,es:$S2              ; ax = e
    pop    bp
    retf

    _chst:
    push   bp
    mov    bp,sp
    sub    sp,+004h
    les    bx,dword ptr [bp+00Eh] ; len(a$)
    cmp    word ptr es:[bx],+000h ; null?
    jz     $L3                    ; ja
    les    bx,dword ptr [bp+006h] ; strseg(a$) - Segment
    mov    ax,es:[bx]
    les    bx,dword ptr [bp+00Ah] ; strptr(a$) - Offset
    mov    dx,es:[bx]
    mov    [bp-002h],ax           ; eigener (echter) Pointer
    mov    [bp-004h],dx
    mov    ax,[bp-004h]
    or     ax,[bp-002h]           ; Pointer = 0?
    jz     $L3                    ; ja
    les    bx,dword ptr [bp-004h] ; Zeiger auf 1. String-Char
    mov    byte ptr es:[bx],2Ah   ; Char mit '*' ueberschreiben
    $L3:
    mov    sp,bp
    pop    bp
    retf

    _TEXT        ENDS

    _DATA        SEGMENT
    $S1     dw     00001h  ; initialisierte Daten
    $S2     dw     00000h  ; nicht initialisierte Daten (hier NICHT im
                           ; BSS-Segment!)
   _DATA        ENDS

    END
    --- Cut End --------------------------------------------------------


    7.9. Verwendung von Routinen fremder C-Bibliotheken:
    ----------------------------------------------------
    Obwohl PB V3.x schon viel besser an die C-Konventionen angepat
    ist als PB V2.1, ist es meist immer noch nicht mglich, .OBJ
    Files, die dem normalen C-Standard entsprechen, sofort einzubinden.
    Grund: C generiert mehrere Datensegmente zusammen mit DGROUP. Als Abhilfe
    bietet sich wohl nur der Umweg ber den Quellcode an, der dann nach
    den Gesichtspunkten von Abschn. 7.3 + 7.4a neu compiliert/assembliert
    werden mu. Es gibt 2 Mglichkeiten:

    - Bei Borland C++ Vs. 3.1 wird fr die meisten Runtime-Bibliotheken der
      ges. Quellcode mitgeliefert einschlielich einer Anleitung und Make-
      Files, wie man Bibliotheksmodule abwandeln und dann neu generieren
      kann.
    - Liegt fr ein .OBJ Modul kein Quellcode vor, gelingt es bei kleineren
      Modulen mit einem .OBJ-Disassembler oft, den zugehoerigen .ASM-Quell-
      code zu generieren. Dieser kann dann nach Anpassung der Datensegment-
      Definitionen neu assembliert werden.


    7.10. Manahmen bei Verwendung von PB V2.1:
    -------------------------------------------
    Der Unterschied zwischen PB V3.x und V2.1 besteht hier in folgendem:
    PB V2.1 kennt keine "$ALIAS"-Anweisungen. Da PB keine "_" (underscores)
    verarbeiten kann, mssen in der IDE des C-Compilers weitere
    nderungen eingestellt werden:
    - Bei den Segmentnamen (vergl. Abschn. 7.4a) sind die "_" zu entfernen
    - Im Men "Options / Compiler / Advanced Code Generation" ist der
      Punkt "Generate underbars" zu deaktivieren.

    PB V2.1 kennt die CDECL-Anweisung nicht. Man mu daher im C-Quellcode die
    Anweisung hineineditieren, dass die C-Funktionen nach der PASCAL-
    Convention (dies entspricht der PB-Convention) zu compilieren sind. In
    den Beispielen aus Abschn. 7.6 und 7.7 sind dann die nachstehend ge-
    nderten Zeilen zu verwenden:

        DECLARE FUNCTION addab (a, BYVAL b, c)
        DECLARE SUB chst (word, word, integer)

        int pascal addab(int far *a, int b, int far *c)
        void pascal chst(unsigned far *stseg, unsigned far *stofs,
                                                       int far *stlen)


    ======================================================================
    8. Tip's bei der Konvertierung von Sourcen von PDS nach PowerBASIC 3.x
    ======================================================================
    (von Mark Junker@2:2437/47.21 / M.Junker@take-off.flightsim.de)

    Generell kann man sagen, da PDS-Sourcen in PB3-Sourcen konvertiert
    werden knnen. Ausnahmen sind z.B. Sourcen, die auf Fremd-Bibliotheken
    zurckgreifen oder in einer TYPE-Struktur dimensionierte Elemente be-
    nutzen.

    Also, folgendes verhindert eine Umsetzung:
        - Fremd-Bibliotheken
          (wie z.B. die VESA-LIB und was es sonst noch so gibt ...)

        - In einer TYPE-Struktur dimensionierte Elemente
          Beispiel:
                  TYPE tTest
                          TestElement1         AS LONG
                          TestElement2(2 to 7) AS INTEGER
                          TestElement3         AS LONG
                  END TYPE

        - Es darf kein COMMON vorkommen, wohl aber alle Varianten des
          COMMON SHARED- Befehls.
          Ausnahmen:
                  - Wenn COMMON benutzt wird, um Parameter an eine mit CHAIN
                    aufgerufene Datei zu uebergeben.
                  - Wenn es egal ist, wenn die hinter COMMON angegebenen
                    Variablen in allen Prozeduren verfgbar sind.

        - Arrays mit mehr als 8 Dimensionen
        - es gibt noch kein ausreichend flexibles REDIM PRESERVE
        - Mehr als 16 Parameter bei Aufruf einer Prozedur


    Wenn diese Bedingungen erfllt sind, dann sind folgende Dinge bei einer
    Konvertierung zu beachten:

    Basic PDS:                       PowerBASIC 3:
    
    SSEG                             STRSEG
    SADD                             STRPTR
    SSEGADD                          STRPTR32
                                     STRPTR32 gibt es erst ab PB3.2
    VARSEG/VARPTR                    ACHTUNG: PB3 liefert VORZEICHENLOSE
                                     Werte zurck, PDS dagegen VORZEICHEN-
                                     BEHAFTETE.
                                     Dies kann per $OPTION SIGNED OFF
                                     gendert werden.
    
    Offset bei einer per OPEN ge-    In PB fngt eine Datei - je nach
    ffneten Datei fngt bei '1' an! Wahl - bei Null (Standard) oder bei
                                     Eins an. Dieses kann mit folgendem
                                     Befehl eingestellt werden:
                                     OPTION BINARY BASE 1
                                     fr den Anfang bei '1'
    
    DIM SHARED VarName%              Dieser Befehl kann auf zweifache
                                     Art und Weise umgesetzt werden:
                                     - DIM VarName%
                                       SHARED VarName%
                                     - DIM VarName AS SHARED INTEGER
    
    SHARED VarName() AS STRING*3     Hier tritt das Problem
                                     mit den Strings fester Laenge auf, wenn
                                     sie nicht im Haupt-Programm geSHARED
                                     werden koennen.
                                     Hinter SHARED drfen zu Variablen
                                     keine Typen-Angaben ('AS xxx') stehen.
                                     Also:    SHARED VarName as string
                                     Wird zu: SHARED VarName$
                                        oder: SHARED VarName :'in SUBs !
                                     
                                     Bei FIXED-LENGTH-STRING-Arrays kann
                                     man sie SHAREn, indem man folgenden
                                     Befehl benutzt:
                                     DIM VarName(MIN,DimNum) AS STRING*3
                                     oder
                                     DIM VarName(MAX,DimNum) AS STRING*3
                                     wobei 'DimNum' die Anzahl der
                                     Dimensionen des Arrays ist und im
                                     Source direkt eine Zahl eingetragen
                                     sein mu.
    
    COMMON SHARED /Block/ VarN%      Alle drei Varianten des COMMON-
    COMMON SHARED VarN%              Befehls muessen leider im Haupt-
                                     Programm durch ein PUBLIC und in dem
                                     externen Modul (unter PB: UNIT) durch
                                     ein EXTERNAL ersetzt werden. Dabei mu
                                     beachtet werden, da die Variablen-
                                     Namen eindeutig sein MSSEN. Sie sind
                                     also UNABHNGIG vom DATENTYP !!!
                                     Alle Typen-Angaben 'AS xxx' sind in
                                     PB3 unzulig.
                                     Die Block-Angabe (/Block/) fllt bei
                                     PB weg, da hier alles Namens-Abhngig
                                     ist. (-> Inkompatibilitt !)
    
    COMMON VarN%                     Kann nur dann umgesetzt werden, wenn
                                     die hinter COMMON angegebene Variable
                                     an ein, mit dem CHAIN-Befehl,
                                     aufgerufenes Programm uebergeben werden
                                     soll oder aber das COMMON i.E. auch
                                     ein COMMON SHARED sein knnte.
                                     Es sind hier, wie auch bei COMMON
                                     SHARED alle Typen-Angaben ('AS xxx')
                                     zu einer Variable zu entfernen.
    
    '$INCLUDE: 'filename.ext'        $INCLUDE "filename.ext"
    '$DYNAMIC                        $DYNAMIC
    '$STATIC                         $STATIC
    
    CONST VarName$ = "xyz"           Hier mu im Programm direkt
    CONST VarName# = 1.23            berall der Variablen-Name
    CONST VarName! = 1.23            durch den dazugehrigen Wert er-
    CONST VarName@ = 1.23            setzt werden.
    
    CONST VarName% = 123             Wird beidemale zu:
    CONST VarName& = 123             %VarName = 123
                                     Wird ein Konstanten-Name doppelt, aber
                                     mit unterschiedlichem Datentypen
                                     verwendet so ist im gesamten Source
                                     einer der beiden Namen zu ndern.
                                     Im Programm muss dann auch ueberall
                                     'VarName%' oder 'VarName&' durch
                                     '%VarName' ersetzt werden.
    
    IF x THEN : ' Test               In PB braucht nur der ':' entfernt zu
     irgendwas                       werden und schon lt es sich hier
    END IF                           problemlos kompilieren.
    
    DIM x AS STRING*3                Dieser FIXED-LENGTH-STRING kann
    CALL Test(x)                     in PB nicht problemlos an eine
    END                              Prozedur uebergeben werden, da
    SUB Test(x$)                     PB hier einen VARIABLE-LENGTH-
    END SUB                          STRING erwartet oder im Kopf der
                                     SUB-Prozedur anstelle des 'x$'
                                     ein 'x AS STRING*3'. Man mu
                                     hier bei PB also ggf. den Umweg
                                     ber einen temporaeren String gehen:
                                     dummy$=x
                                     CALL Test(dummy$)
                                     x=dummy$
    

    Ideal ist es, fr das Problem der Konstanten-Konvertierung einen
    Konverter zu schreiben, denn dies drfte den Lwen-Anteil bei der
    Konvertierung groer Programme ausmachen. Im gleichen Zuge kann man
    natrlich auch die Sache mit den COMMON SHAREDs und den DIM SHAREDs und
    natrlich auch den META-Statements, sowie SSEG/SADD/SSEGADD ersetzen.

    Wenn Interrupt-Aufrufe mit einem CALL INTERRUPT oder CALL INTERRUPTX
    gemacht werden, so kann man entweder in ASM die Routine 'INTERRUPTX'
    nachbilden und alle Aufrufe von 'INTERRUPT' nach 'INTERRUPTX'
    konvertieren oder man setzt es direkt in INLINE-ASM um oder aber man
    benutzt die PowerBASIC-eigene 'CALL INTERRUPT'-Routine, wobei man dann
    alle Registerzuweisungen konvertieren mu ...




    =================================================
    9. vorhandene Shareware & Public Domain-Loesungen
    =================================================
    Es existieren zwar noch unzhlige weitere Toolboxen, aber ich mchte
    hier nur auf die wesentlichsten Toolkits eingehen.

    9.1.  PBSOUND fr PowerBASIC 3.0/3.2
    9.2.  HiVGA fr PowerBASIC 2.1/3.2
    9.3.  PBVISION fr PowerBASIC 3.0/3.1
    9.4.  PBCompress fr PowerBASIC 3.1
    9.5.  Personal Protocol/Communication Library fr PowerBASIC
    9.6.  POW! - Sound Blaster Toolkit
    9.7.  PBGUI Toolkit fr PowerBASIC 3.0
    9.8.  PBWizard
    9.9.  SVGA fr PowerBASIC
    9.10. MAXLIB for PowerBASIC v1.2
    9.11. DWDOOR for PowerBASIC 3.x
    9.12. Special-Power / Spezialtools fr PowerBASIC 2.1/3.0
    9.13. BWSB - Bells, Whistles and Sound Boards
    9.14. Public Domain Sourcen von deutschen Programmierern
    9.15. Public Domain Sourcen welche oft bentigt werden


    9.1. PBSOUND fr PowerBASIC 3.0/3.2
    -----------------------------------
    Sprache: Deutsch / Englisch
    Autor  : Thomas Gohel
    Version: V1.80
    Preis  : 40,-DM/80,-DM bzw. $40/$80 (privat/gewerblich)
|   Bezug  : PowerBASIC-Filearea: PBSOUND
|            Fido-Request mit Magic 'PBSOUND' bei 2:2410/330 (28.8, ISDN)
             InterNet: http://www.snafu.de/~pbsound/
    File   : PBSOUND.ZIP
    Betriebssystem (empfohlen): MS-DOS ab V5.0 oder Windows 95
    Inhalt :
             - Untersttzung aller Creative Labs Sound Blaster Modelle,
               incl. SB16 und SB32AWE
             - Upgradeboards wie WaveBlaster I+II, sowie Roland SoundCanvas
               SCD10/15, Yamaha DB-50XG
             - Untersttzung des internen PC-Speakers
             - Wiedergabe von MIDI und VOC-Files im Hintergrund und innerhalb
               der IDE
             - keine Lngenbegrenzung bei VOC-Files
             - Wiedergabe/Aufnahme bis zu 44100, Stereo und 16bit mit einer
               SB16 bzw. SB32AWE
             - Untersttzung des SBPro/SB16 Mixers
             - Sprachsynthese via SBTALKER.EXE
             - Online-Hilfe fr PowerBASIC-IDE
             - PBPLAY, MIDI/VOC-Player Tool
             - PBREC, VOC-Aufnahme Tool
             - PBSPEAK, VOC/WAV Player fr Speaker
             - PBW2V, VOC<->WAV Konvertierungstool
             - mit brandneuem PBSOUND-Library Konzept!!!!!
               Linken von Files in eine Library und zuknftigem Erstellen
               von ausfhrbaren PowerBASIC EXE-Dateien bis zu 4GByte!!!
             - Demo & Einfhrungsprogramme
             - Komplett mit INSTALL & SETUP-Programme
             - beigefgter Sourcen:
               Ansteuerung des CT-VOICE.DRV & SBPro Mixerchips


    9.2. HiVGA fr PowerBASIC 2.1/3.2
    ---------------------------------
    Sprache: Deutsch / Englisch
    Autor  : Matthus Stadler
    Version: V1.95
    Preis  : 40,-DM
|   Bezug  : PowerBASIC-Filearea: Toolkits (Deutschland)
|            Fido-Request mit Magic 'PBHIVGA' bei 2:2410/330 (28.8, ISDN)
|            InterNet: http://www.snafu.de/~pbsound/
    File   : HIVGA195.ZIP
    Inhalt :
             - Automatische Erkennung der verwendeten SVGA-Karte
             - 320x200 - 1600x1200 auf VESA-, allen gngigen und vielen
               exotischen SVGA-Karten (mit entsprechendem Grafik-Speicher)
             - Ausser 256 Farben auch HiColor (32k) und RealColor (64k)
             - Schnelle Zeichenfunktionen (Rechtecke, Ellipsen, Fllen,
               Skalieren...)
             - Palettenmanipulation (Ein/Ausblenden, Farben definieren...)
             - Grafiken laden/speichern (PCX, TGA und ein eigenes Grafik-
               format)
             - Komfortables Einlinken von Grafikfiles in die EXE
             - Einbinden benutzerdefinierter Fonts (bis 16x32)
             - Skalierbare Textausgabe, Leistungsfhige Sprite-Routinen,
               Scrolling
             - Mausuntersttzung (inkl. anwenderdefiniertem Cursor)
             - Mehrere Bildschirmseiten auch in SVGA; die Anzahl der Bild-
               schirmseiten in den SVGA-Modi ist nur durch den Grafikkarten-
               speicher begrenzt
             - Virtuelle Verdoppelung der Bildschirmbreite
             - Luft ab 386 mit (S)VGA-Karte und PowerBASIC
             - Keine funktionellen Einschrnkungen in der Sharewareversion.


    9.3.  PBVISION fr PowerBASIC 3.0/3.1
    --------------------------------------
    Sprache: Englisch
    Autor  : Daniel Stasinski (DSE Software Publishing)
    Version:
    Preis  : $24.95/$49.95/$69.95 (Light/Standard/Professional Version)
    Bezug  : PowerBASIC-Filearea: Toolkits (allgemein)
             Fido-Request mit Magic 'VISION' bei 1:125/123
    File   : PBVLITE.ZIP
    Inhalt :
             - Erstellen SAA-Oberflaechen mit allen was so dazu gehoert
             - mit Workshop zum Erstellen der Oberflaechen
             - PC-Tools/Norton Utilities Look moeglich


    9.4.  PBCompress fr PowerBASIC 3.1
    ------------------------------------
    Sprache: Englisch
    Autor  : Greg Turgeon
    Version: V1.1
    Preis  : $39.00/$69.00 (ohne bzw. mit Sourcecodes)
    Bezug  : PowerBASIC-Filearea: Toolkits (allgemeim)
|   File   : PBCOMP.ZIP
    Inhalt :
             - Filecompressions- und Entpackutility
             - Fortschrittsanzeige
             - packt auf dem Niveau wie MS Compress
             - recht schnell


    9.5.  Personal Protocol/Communication Library fr PowerBASIC
    ------------------------------------------------------------
    Sprache: Englisch
    Autor  : MarshallSoft Computing
    Version: V4.3 (Communication)
             V1.0 (Protocol)
    Preis  : $65 (Communication) / $40 (Protocol)
|   Bezug  : PowerBASIC-Filearea: DF, BBS & FidoNet
             diverse Mailboxen/Filenetze (BasNet) in Deutschland
    File   : PCL4PB43.ZIP
             PPL4PB10.ZIP
    Inhalt :
             a) Personal Protocol Library V1.0 fr PowerBASIC:
                - XMODEM, XMODEM-CRC, XMODEM-1K, YMODEM, YMODEM-G und
                  ZMODEM Protokolle.
             b) Personal Comm Library V4.3 fr PowerBASIC:
                - COM1-COM20, 115,200 Baud, 4 bis 20 Ports, 16550 UARTs,
                  und vieles mehr


    9.6.  POW! - Sound Blaster Toolkit
    ----------------------------------
    Sprache: Englisch
    Autor  : Tim Gerchmez
    Version: V1.0
    Preis  : $39,95
|   Bezug  : PowerBASIC-Filearea: Sound Blaster
             ftp.eskimo.com/u/f/future (Tim's Homepage)
    File   : POW!1_0.ZIP
    Inhalt :
             - Wiedergabe von 8bit Samples via DMA
             - CMF-Wiedergabe via SBFMDRV.COM
             - Sprachwiedergabe via SBTALKER.EXE
             - POW-Library Konzept fr Samples


    9.7.  PBGUI Toolkit fr PowerBASIC 3.0
    ---------------------------------------
    Sprache: Englisch
    Autor  : James C. Fuller
    Version: V2.00f
    Preis  : $40.00 + Versandkosten
|   Bezug  : PowerBASIC-Filearea: Toolkits (allgemein)
|   File   : PBGUI.ZIP
    Inhalt : Erstellen von PowerBASIC-Oberflchen im Windows-Look


    9.8.  PBWizard
    --------------
    Sprache: Englisch
    Autor  : Thomas G. Hanlin
    Version: V2.1
    Preis  : $99.95 (keine Shareware-Version)
|   Bezug  : PowerBASIC-Filearea: Toolkits (allgemein)
|   File   : PBWIZ21.ZIP
    Inhalt :
             - Bereitstellung vieler Zusatzfunktionen
             - Ersatz einiger PowerBASIC-Routinen
             - Sound Blaster via SBSIM (TSR-Treiber bentigt)
             - XMS/EMS Untersttzung
             - CRC16
             - und und und ...


    9.9.  SVGA fr PowerBASIC
    -------------------------
    Sprache: Englisch
    Autor  : Stephen L. Balkum und Daniel A. Sill (Zephyr Software)
    Version: V2.4
    Preis  : $35.00
|   Bezug  : PowerBASIC-Filearea: Grafik (allgemein)
|            http://www.zephyrsoftware.com
    File   : SVGAPB24.ZIP
    Inhalt :
             - Nutzung von nahezu allen VGA/SVGA-Modies
             - sehr zuverlaessig in allen Modies (echt zu empfehlen)
             - Laden von PCX-Bildern (in aelteren Versionen GIF)
             - viele ntzliche Grafikroutinen
             - Sprites und vieles mehr


    9.10. MAXLIB fr PowerBASIC v1.2
    --------------------------------
    Sprache: Englisch
    Autor  : Brian McLaughlin
    Version: 1.2
    Preis  : $35.00/$70.00 (privat/gewerblich) + Versandkosten
|   Bezug  : CompuServe PowerBASIC Forum  (PCVENB, Library 12)
|            PowerBASIC-Filearea: Toolkit (allgemein)
|   File   : MAXPB10B.ZIP
    Inhalt :
             - Nutzung des EMS/XMS-Speichers zum Speichern von Array's
             - I/O-Funktionen


    9.11. DWDOOR fr PowerBASIC 3.x
    -------------------------------
    Sprache: Englisch
    Autor  : James R. Davis
    Version: 3.1
    Preis  : $35.00/$65.00 (mit gedrucktem Manual)
|   Bezug  : PowerBASIC-Filearea: DF, BBS und FidoNet
|   File   : DWDOOR31.ZIP
    Inhalt :
             - Schreiben von DOORS fr Mailboxsysteme
             - untersttzt PCBoard, RBBS, QBBS, GAP, Wildcat v2+3, WWIV,
               SPITFIRE, Ultra BBS und andere BBS Systeme
             - voller ANSI und FOSSIL-Support


    9.12. Special-Power / Spezialtools fr PowerBASIC 2.1/3.0
    ---------------------------------------------------------
    Sprache: Deutsch/Englisch
    Autor  : Stefan Machwirth
    Version: 1.10
    Preis  : 38,- DM/36,- US$
|   Bezug  : Mailboxen, BasNet
|            PowerBASIC-Filearea: Toolkits (Deutschland)
             InterNet: http://www.snafu.de/~pbsound/
    File   : SPPOWGER.ZIP
    Inhalt :
        * DDESWAP 2.0:
           - erweiterter SHELL-Befehl entfernt ein Programm bis auf < 2kB
             und startet beliebig groe andere Programme
           - gibt Errorlevel zurck
           - untersttzt rekursiven Aufruf beliebig vieler EXEs
           - DDE-Routinen fr den Datenaustausch unter DOS
           - wahlweise TSR- und Runtime-Konfiguration
        * DLZV 1.0:
           - Datenkompression mit Source-Schnittstelle fr eigene Programme
        * CRYPT 1.0:
           - Pawortschutz mit Falltralgorithmus.
           - codiert Strings und ganze Files
           - keine aufwendigen Debug-Sperren ntig
           - nur mit extrem aufwendigen Brute-Force-Methoden zu ent-
             schlsseln
        * BASXREF 1.32:
           - Frei konfigurierbares Crossreference-Tool
        * Merge-N-Sort:
           - High-End-Sortierroutine im Source
           - Random- und sequentielle Files
           - Kriterien in auf- und absteigender Folge mischbar


    9.13. BWSB - Bells, Whistles and Sound Boards
    ----------------------------------------------
    Sprache: Englisch
    Autor  : Edward T. Schlunder
    Version: 1.20
    Preis  : $30/$50 (normal/mit ASM Sourcecode)
|   Bezug  : PowerBASIC-Filearea: Sound Blaster
             Internet: http://earthvision.asu.edu/~edward/
    File   : BWSB120A.ZIP
             BWSB120B.ZIP
    Inhalt :
             - Modulplayer (S3M, MOD, 669, ULT, MED, FAR & STM) fr
               PowerBASIC
             - untersttzt GUS, SB1.x, SB2.x, SBPRO, SB16 & PAS
             - alle Routinen im 386'er Code (OBJ-Files)
             - ebenso geeignet fr QB, PDS, TP, C, C++ und ASM



    9.14. Public Domain Sourcen von deutschen Programmierern
    --------------------------------------------------------
    Diese Routinen wurden bereits in diversen Computernetzen verbreitet und
    knnen im Prinzip angefordert werden oder auch Online aus dem
    'PowerBASIC-Filearea: Sourcen' bezogen werden.
    Eine komplette Liste erhalten Sie mit dem Magic 'PBFILES' (Requestzeiten
    beachten!).

    Hier einen kleine Auswahl oft bentigter Sourcen. CrossPoint-User knnen
    mit 'M' und 'F3' sofort einen Request auslsen <g>:

    Name:          Beschreibung:
    ANSI.BAS     - ANSI-Detect
    BLOAD.BAS    - BLOAD/BSAVE Demonstration
    CHKFILE.BAS  - Check ob File vorhanden ist
    COPPER.BAS   - Copper Demo (Source zum BasNet-Intro)
    DATUM.BAS    - aktuellen Wochentag ermitteln
    DIR.BAS      - Erweiterte Directory Funktionen (incl. Zeit etc.)
    DIR32.BAS    - Erweiterte Directory Funktionen fr PowerBASIC 3.2
                   (mit Pointern)
    DIR95.BAS    - Directory Routinen fr Windows 95
    DISKFREE.BAS - Festplattengre ermitteln
    DOS-SYS.BAS  - alle installierten Laufwerke ermitteln
    DOSXMLIB.ZIP - XMS/Disk Routinen
    ENV.BAS      - Environment veraendern (Error 7 umgehen)
    FILECOPY.BAS - Filecopy incl. Datumsattribute
    FIRE.BAS     - Fire (Feuersimulation)
    HIMEM.BAS    - XMS (Extendet Memory)
    LADEFONT.BAS - 15 spezielle ASCII-Zeichen fr den Textmode
    LUPE.BAS     - Lupe Demonstration
    PBCPU.BAS    - CPU-Erkennung im 'nacktem' PowerBASIC (8088-Pentium Pro)
    PBCRC32.ZIP  - sehr schnelle CRC32 Routinen
    PBSHELL.BAS  - Alternativer SHELL-Befehl (mit ERROR-Level)
    PBSOUND.ZIP  - Programmierung des CT-VOICE.DRV
    PBSOUND.ZIP  - Programmierung des SBPro Mixers
    PBUNIX.ZIP   - Berechnen von UNIX-Zeiten
    PFAD.BAS     - Ermitteln des Pfades, in dem das aufgerufene Programm
                   steht
    PSL-FLI.ZIP  - FLI-Player Extension fr PBSOUND Librarys
    SCROLL.BAS   - Scrollen des Bildschirmes (VGA-BIOS)
    SETDATE.BAS  - Datum und Uhrzeit modifizieren bei Dateien
    STARWARS.BAS - Ein Scroller im Star Wars Look
    TEXTMAP.BAS  - Texture Mapping in PowerBASIC
    TEXTMAUS.BAS - ndert den Mauscursor im Textmode
    TIMEDATE.BAS - Routinen fr Datum und Zeitbearbeitung
    UHR-TSR.BAS  - TSR-Uhr via Timerinterrupt &h1C
    WINTOOLS.BAS - Erkennen ob Programm unter Windows laeuft, Taskfreigabe
    WOCHE.BAS    - Wochentagsroutinen
    XMAS.ZIP     - DMA-Kanal Programmierung (8bit), hier in Form eines
                   Weihnachtsgeschenkes


    9.15. Public Domain Sourcen welche oft bentigt werden
    ------------------------------------------------------
    Oft wird in den einschlgigen Programmierecho's immer und immer wieder
    nach den gleichen Sourcen gefragt. Hier also eine kleine Hitliste der
    internationalen Sourcen:

    Name:          Beschreibung:
    BARCODE*.BAS - Routinen fr Barcodes
    CMDPARSE.BAS - Kommandozeile bzw. Environ$ auswerten
    DBASE.BAS    - dBASE-Routinen
    EDIT$U.ZIP   - String-Editor Routine
    EDITBOX$.BAS - String-Editor Routine
    EDITOR.BAS   - String-Editor Routine
    GIF-LOAD.BAS - Laden von GIF-Bildern
    LANSI_31.BAS - Routinen zur Darstellung von ANSI-Bildern
    NET41.ZIP    - Fido-Netmails erstellen
    PARSECMD.BAS - Kommandozeile bzw. Environ$ auswerten
    PB3-DBF.BAS  - dBASE III Interface
    PBFOSSIL.ZIP - Unit zur Ansteuerung des Fossiltreibers
    PBGIF.ZIP    - Laden und Konvertieren eines 320*200*256 GIF-Bildes in
                   das BSAVE Format
    PBLANT.BAS   - LANTastic Function Calls
    PBNET.BAS    - Netzwerkfunktionen fr INT &h21, Funktion &h5F
    PCX320.ZIP   - PCX-Laderoutine fr 320*200 & 256 Farben
    PCXVGA.BAS   - PCX-Laderoutine fr 640*480 & 16 Farben


    ==========================
    10. Die PowerBASIC - Leute
    ==========================

    Natrlich hat jede Programmiersprache bestimmte Leute hervorgebracht,
    welche durch besondere Taten bzw. Tools der Oeffentlichkeit bekannt sind.

    10.1. USA - Vereinigte Staaten von Amerkia
    10.2. BRD - Deutschland, deutschsprachiger Raum
    10.3. Fido/InterNet - die PowerBASIC Leute


    10.1. USA - Vereinigte Staaten von Amerkia
    ------------------------------------------
    In den USA betrifft das natrlich die beiden PowerBASIC-Leute ber-
    haupt:

    Bob Zale            - entwickelte eigentlich PowerBASIC und bezeichnet
                          PowerBASIC als sein Lebenswerk
                          bob@powerbasic.com (Bob Zale)
    Dave Navarro        - Chef-Entwickler bei PowerBASIC Inc.
                          sysop@powerbasic.com (Dave Navarro)

    Des weiteren sind folgende Leute in den USA recht bekannt:

    James C. Fuller     - PBGUI
    Daniel Stasinski    - PB/Vision (grafische SAA-Oberflaechen)
    Tom G. Hanlin       - PB Wizard (jede Menge Zusatzfunktionen)
    Tim Gerchmez        - POW! (Sound Blaster Routinen)
    Greg Turgeon        - PBCompress (Pack/Entpacker Unit, sowie diverse
                          PD-Sourcen)
    Stephen L. Balkum   - SVGA fr PowerBASIC (Zephyr Software)
    Daniel A. Sill      - SVGA fr PowerBASIC (Zephyr Software)


    10.2. BRD - Deutschland, deutschsprachiger Raum
    -----------------------------------------------
    In Deutschland haben sich natrlich auch einige Leute durch besondere
    Leistungen hervor gehoben, hier speziell bei Kirschbaum:

    Patrick Biercher    - PowerGRAPH
    Dirk Hilger         - PowerTOOLS
    Thomas Reichardt    - PowerISAM

    Des weiteren gibt es einige Leute auf dem PD bzw. Shareware-Markt welche
    durch ihre Tools recht bekannt sind:

    Thomas Gohel        - PBSOUND
    Matthaeus Stadler   - HiVGA


    10.3. Fido/InterNet - die PowerBASIC Leute
    ------------------------------------------
    Ohne die zahlreichen Zuschriften oder die Ideen wre diese FAQ bei weitem
    nicht das was sie heute ist.
    Darum mchte ich hiermit die Gelegenheit nutzen diesen Leuten persnlich
    zu danken:

    Thomas Gohel        - Autor von PBSOUND fr PowerBASIC, Autor dieser
                          PowerBASIC-FAQ und vieler anderer Sachen ...
                          Nebenbei scheine ich hier fr den PowerBASIC-
                          Support auch zustndig zu sein ;)
    Andras Hoeffken     - Messgertesteuerung mit PowerBASIC
                        - Kapitel 'C++ und PowerBASIC'
    Stephan Gnther     - grafische Umsetzung smtlicher Bilder mit Highlight
                          Professional V1.0 fr "Windows New Technology"
                        - incl. aller gerenderten Grafiken und Animationen
                          zu PBSOUND
    Thomas Geiger       - englische Version der FAQ
                        - fr einige Anregungen zu dieser FAQ
    Mark Junker         - Kapitel 'Konvertierung PDS zu PB'
                        - fr einige Anregungen zu dieser FAQ
    Wolfgang Bruske     - englische Version des Kapitel 'Pointer'
    Bernd Richter       - fr die Richtigkeit diverser Informationen
    Peter Cooper        - fr die grammatische Richtigkeit der englischen
                          Version
    Marc van den Dikkenberg
                        - fr einige Anregungen zu dieser FAQ
    Roland Arendes      - fr einige Anregungen zu dieser FAQ
    Roland Osen         - dito
    Wolfram Sang        - dito
    Dr.P.Jennewein      - dito
    Martin Kiewitz      - dito

=============================================================================
<EOF> -  End of the PowerBASIC-FAQ
                                        (c) Thomas Gohel, all rights reserved
=============================================================================

