Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

PowerBASIC-FAQ, deutsche Ausgabe

19 views
Skip to first unread message

Thomas Gohel

unread,
Dec 1, 1996, 3:00:00 AM12/1/96
to

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

PowerBASIC-FAQ für die Versionen 3.00, 3.10 & 3.20
deutsche Version (DOS)

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

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

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


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

Die in dieser FAQ aufgeführten Hinweise erfolgen ohne Berücksichtigung
eventueller Copyright-Verletzung und ohne Rücksichtname eventuell einge-
tragener Warenzeichen.
Des weiteren garantiert der Autor nicht für Richtigkeit der hier ange-
führten Probleme, Tip's & Bug's etc. Sollten Sie Anregungen oder Ver-
besserungsvorschläge haben, so stehe ich diesen Sachen offen gegenüber
und werde dies in zukünftigen Versionen der FAQ mit einfliessen lassen.
Ich möchte weiter darauf hinweisen, das einige der hier unter dem
Abschnitt 'Fehler' aufgeführten Probleme im weiteren Sinne keine Bugs
darstellen. Diese Ungereimtheiten bzw. verschwiegenen Einschränkungen
gilt es hier für die Allgemeinheit zu dokumentieren (das es in Zukunft
ein besseres PowerBASIC gibt).


=======================
Verbesserungsvorschläge
=======================

Verbesserungsvorschläge können Sie jederzeit an den Autor dieser FAQ
richten, die aktuellen Netmail-Adressen lauten:

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

Des weiteren besteht die Möglichkeit 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 können Sie Ihre Vorschläge und Probleme los werden. Bitte schreiben
Sie dazu Ihre Nachricht in der PBSOUND-Nachrichten-Area. Eine Antwort
sollten Sie spätestens nach 48 Stunden erhalten.


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

Die aktuelle PowerBASIC-FAQ können 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-Sourcen'-Filearea.
Des weiteren finden Sie hier noch zwei weitere 'PowerBASIC-Fileareas'
(Toolboxen und PBSOUND). Viele in dieser FAQ erwähnten Sourcen und
Toolboxen können Sie hier Online oder auch per FidoNet downloaden.

InterNet-Teilnehmer können 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'
möglich!

| 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 (Bug's) 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-Lösungen
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 verfügbar.


1.2. Der Originalhersteller von PowerBASIC
------------------------------------------
PowerBASIC wird und wurde in den USA entwickelt und es befinden sich
natürlich auch diverse Möglichkeiten 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 : in...@powerbasic.com
Bestellung : or...@powerbasic.com
Produktlisten : prod...@powerbasic.com
Produkte für PowerBASIC : th...@powerbasic.com
Verkauf und Marketing : sa...@powerbasic.com
Technischer Support : sup...@powerbasic.com
Forschung und Entwicklung : r&d...@powerbasic.com
100 Gründe warum PowerBASIC
besser als QuickBASIC ist : 100...@powerbasic.com
Anregungen für zukünftige
PowerBASIC Versionen : sug...@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.phoenix.net/~balkum/
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 für PowerBASIC folgende Pakete an:

PB/DLL - PowerBASIC DLL-Compiler für Windows
PowerGRAPH - für grafische Menüoberflächen (PCX, Fonts, etc.)
PowerISAM - Datenbanken (ebenfalls verfügbar in Englisch bei
PowerBASIC Inc.)
PowerTOOLS - SAA-Oberfläche, Hilfesystem, nützliche Routinen
PB/xtra - Sammlung von Sharewareprogrammen und Sourcecode

Kischbaum besitzt keine Mailbox bzw. offizielle EMailadressen! Allerdings
existieren für die Mitarbeiter bzw. für 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 können jederzeit auftreten! Eine aktuelle und gültige Preis-
liste kann jederzeit bei Kirschbaum Software per FAX angefordert werden.

| Vollversion: 199,-DM
Vollversion 3.2 für Studenten, Schüler: 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
-------------------------------
Für Leute mit Modem bietet sich zum Erfahrungsaustausch mit anderen
PowerBASIC-Leuten das "BasNet" an. Hier können Sie mit anderen PB-
Programmierern Ihre "Programmier"-Probleme klären und auch andere
nötigen Informationen, Sourcen oder auch Toolboxen erhalten. Für weitere
Informationen zum "Basic Network" wenden Sie sich bitte an die nach-
folgend angegebenen Adressen:

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

performance Multimedia
Römerstr. 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 können nun direkt
verglichen werden.
- Konstanten im Binaer-, Hex- oder Oktalformat (&B, &H, &O) können
einem bestimmten Datentyp zugeordnet werden, indem man den ent-
sprechenden Identifier anhängt.

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

- Konstanten (%Test) können 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 führenden Null festlegen, ob der
erzeugte Wert vorzeichenbehaftet ist oder nicht.

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

- Ab PB 3.10 können Sie alternative Namen für 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 Schlüsselwort 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 müssen
'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

- Rückgabewerte von FUNCTIONs die mit dem Inline-Assembler geschrieben
wurden, können jetzt auch ohne eine Zwischenvariable mit einem Wert
belegt werden. Dazu dient das Schlüsselwort 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 zurückgeliefert
END FUNCTION

(siehe auch Tips mit dem Inline-Assembler)

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

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 für den Stack zurück
FRE(-4) gibt die maximale Laenge für dynamische Strings zurück, die
mit $STRING gesetzt wurde
FRE(-5) gibt die Anzahl der belegten Stringsegmente zurück
FRE(-6) gibt die Anzahl der unbenutzten Bloecke im aktuellen String-
segment zurück
FRE(-7) gibt die Groesse des unbenutzten Speichers im aktuellen
Stringsegment zurück


1.7. Neuigkeiten in der PowerBASIC 3.2 Version
----------------------------------------------
- Data Pointers
- Code Pointers
Es können nun folgende Sprünge direkt in Basic ausgeführt 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 können an eine SUB/FUNCTION mit dem
Schlüsselwort "BYVAL" übergeben werden.

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

- 16550 UART Unterstützung

- Die LEN() Funktion liefert nun auch die Länge von User-definierten
Strukturen zurück.

- Label und Varibalen können 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 Gerüchten kommt, hier der nach meinem Wissen aktuelle Stand:

Laut diverser und auch verläßlicher Quellen (unter anderem PowerBASIC
Inc. selbst) arbeiten PowerBASIC Inc. derzeit an der folgenden Versionen
Ihrer PowerBASIC Software:
- Der PB/DLL Compiler wird als nächstes ebenfalls (vermutlich noch
dieses Jahr) in einer Windows95/WindowsNT Version, also für die
32bit-Umgebung vorliegen. Als erstes wird eine Kommandozeilen verfüg-
bar sein, über eine IDE liegen keine Aussagen vor.
- eine zukünftige PB OS/2 Version wird nicht bestritten, allerdings
steht diese deutlich in den Plänen hinter den DOS/WIN-Versionen
zurück.
- Die nächste 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 gläserne PowerBASIC-
Kugel.
Es wäre übrigend sehr schön, wenn der Dave Navarro in Zukunft selber
diesen Abschnitt pflegen würde, immerhin sitzt er an der Quelle ;^)


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

Kurzübersicht:
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 große 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 Betätigen 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 können Sie sicher sein,
das PowerBASIC auch den wahren Fehler anzeigt und z.B. nicht bei:

SELECT CASE pbvrevision

mit einem unerklärlichen Fehler aussteigt. Im fertigen Programm könnnen
Sie die Bibliotheken wieder entfernen, da sie eigentlich nur während der
Programmentwicklung wirklich benötigt werden.
Die $ERROR-Bibliotheken können Sie innerhalb der IDE ständig einbinden
oder direkt in Ihrem Sourcecode definieren. Die Einstellungen im
Sourcecode haben gegenüber 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 können 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 aufgeführten Probleme beziehen sich nur auf die Verwendung von
vorzeichenlosen Variablen und werden an Variablen vom Typ WORD
aufgeführt:

Beispiel 1:
Demo?? = &hA000

führt 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 Umständen ebenfalls zu einem Überlauf führen, sofern der
übergebene Wert als INTEGER negativ wäre. Den Fehler können 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 später im
Programm auf, komischerweise aber ebenfalls bei Variablen vom Typ WORD.
Eigenartigerweise läßt 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 müssen die Variablen definitiv vom Typ WORD sein, ansonsten
droht wiederum ein Überlauf in größeren 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 läßt ;-).

Beispiel 1:
Demo?? = &hA000

kann weiterhin zu einem Überlauf führen. Leider läßt 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 geändert.
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)

führt 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 für 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

Für Variablen vom Typ Doubleword ist in PowerBASIC kein Overflowtest
integriert. Dies können Sie an einem kleinen Besipiel testen.

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

Wie Sie sehen interpretiert PowerBASIC den negativen Wert immer als sein
nicht vorzeichenbehaftetes Gegenstück. 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 zurückzuführen:

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

In den meisten Fällen wird die IDE während des Ladevorganges mit einem
Grafikfehler (Cursor innerhalb der IDE) auf die Kommandozeile zurück-
kehren.
Ebenfalls betroffen von diesem Effekt sind alle fertigen PowerBASIC-EXE
Files. Wollen Sie diesen Effekt auf alle Fälle umgehen, so müssen Sie
die PowerBASIC-EXE mit einem EXE-Packer wie PKLITE komprimieren.


2.5. unterschiedlich große 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 großen EXE-File erklärt.
Die IDE compiliert die EXE-Datei immer nach den Einstellungen in der IDE,
das heißt 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 verfügbarer freier Speicher
geändert 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 läßt
sich mit der PB-IDE und auch dem PBC nachvollziehen.

Nach einigen Auskünften sollen PB-EXE-Files, welche unter einer
PowerBASIC-SHELL mit PBC compiliert wurden zum Abstürzen neigen.

Da ich aber selbst seit ca 2 Jahren alle meine Projekte auf ähnliche
Weise compiliere, kann ich diesen Effekt nicht nachvollziehen oder
bestätigen. In Version 3.0 des PowerBASIC-Compilers schien allerdings
der SHELL-Befehl anderweitige Effekte bei großen EXE-File auszulösen.
Die Probleme lösten 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 Einfügen und Ausschneiden können, so kann dies beim Markieren
längerer Texte (welche den rechten Bildschirmrand überschreiten) zu einem
Teilabsturz führen. Des weiteren markiert der Maus-Cursor die Texte nicht
richtig. Sie erkennen das daran, das Sie in der Regel eine längere Zeile
nicht markieren können.
Des weiteren scheint es vereinzelt Probleme mit der Mausunterstützung 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
ausgelöst wird. Die Beschreibung im Handbuch, sowie der OnLine-Hilfe,
ist leicht irreführend dennoch prinzipiell richtig.

Ich persönlich würde den Fehler wie folgt beschreiben:

<neue Fehlerbeschreibung>
PowerBASIC konnte die angegebene Sprungadresse nicht finden. Eine
mögliche Ursache ist ein SHORT-Sprung zu einem Label der nicht im
gültigen Bereich für einen SHORT-Sprung liegt. Bitte Überprüfen Sie alle
Sprungbefehle auf Ihren Gültigkeitsbereich.
<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 Abhängigkeit
von der CPU, erspare ich mir hier. Dafür gibt es jede Menge Assembler-
Bücher, 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 Programmausführung bis zu der Zeile
mit dem Sonderzeichen (nach dem REM) fortsetzen und dann stoppen. Die
hartgesottenen können 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 anhängt 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 enthält. 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 dürfen 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
^
führt 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
Handbüchern ist der Syntax aber korrekt erklärt.

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 Betätigen 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, während das BREAK-Flag
auf DOS-Ebene auf ON gesetzt ist (normalerweise ist dies aber von MS-DOS
eh auf OFF gesetzt). Betätigen Sie unter diesen Vorrausetzungen nun die
Tastenkombination CNTL-C, dann stützt Ihr fertiges Programm gelinde
gesagt ab.
Abhilfe schafft das Sperren des BREAK-Flag's per eigener PowerBASIC-
Funktion. Dies können 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, während
der Ausgabe über "CONS:" kann es zu Nebeneffekten kommen. Näheres ist
mir pesönlich 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 müssen sich die beiden
internen PowerBASIC-Funktionen innerhalb einer PowerBASIC Unit (PBU)
befinden. Als Abhilfe müssen 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 gehört.

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 großen Projekten hat sich gezeigt, das der
Compiler zu einer falschen Interpretation neigt, sprich: An irgendeiner
Stelle im Sourcecode meldet der Compiler einen für Sie unerklärlichen
Fehler. In vielen Fällen 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 zurückliefern. In Verbindung mit allen Modies welche nicht die
40'er bzw. 80'er Spaltenanzahl verwenden, wird nicht die korrekte Anzahl
der Bildschirmspalten zurück geliefert. Solche Modies können Sie auf
jeder VGA-Karte einstellen und diverse Tools (u.a. Disk Command Center)
unterstützen 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 erklärt, während PowerBASIC 3.0 im
Inline-Assembler folgende Zeile zuläßt:

! 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

Geklärt werden muss jetzt natürlich 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???

führt 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 merkwürdiger 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 löschen
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 natürlich 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 gültigen
Wertebereich einer Variablen auszuschöpfen. Der maximal mögliche Wert
wird intern von PowerBASIC verwendet, da PowerBASIC m.E. erst intern
die Variable erhöht und dann abfragt. Logischerweise kommt es dabei
zu einem Überlauf, sofern Ihr Wert bereits den maximal möglichen
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 Herunterzählen im gültigen Variablenbereich
von Variablen vom Typ unsigned. Während bei Variablen vom Typ BYTE
oder WORD ein Overflow kommt, wurde wie bereits erwähnt 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 möglich gleichzeitig eine mathematische Operation
auszuführen.

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 geschützt 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 Fälle können 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 stürzt ab, wenn sie zum ersten Mal nach dem Start
der IDE im Menü "File\Pick", anstatt der RETURN-Taste die DEL-Taste
betätigen. Sollten Sie bereits während der Sitzung das Menü "Pick" einmal
mit RETURN geöffnet haben, so wirkt sich der Fehler nicht mehr aus.
Ich persönlich halte den Fehler für 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 stürzt ab, sofern Sie versuchen folgende Zeile
zu compilieren:

PRINT Test1$ XOR Test2$ XOR Test3$

Über den Sinn der Zeile möchte 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 unterstützt"
| CASE &h0 : PRINT "Taskfreigabe wird unterstützt"
| 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 unterstützt"
| CASE &h0 : PRINT "Taskfreigabe wird unterstützt"
| 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 Anfängern 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'
ausgelöst wird.


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

Der Fehler 'Truncating ... to 76 characters' wird des öfteren irrtümlich
angezeigt, da die Steuerzeichen nicht berücksichtigt 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 müssen
Sie aufpassen, das die effektive Länge der darzustellenden Textzeile
nicht größer als die wirklich vorhandene Zeilenbreite des PowerBASIC-
Hilfefensters ist, da die PowerBASIC-IDE in diesem Fall mit einem
Grafikfehler abstürzt.
Dieser Fehler tritt nur in der Endwicklungsphase einer selber
geschriebenen Hilfedatei (*.PBH) auf!


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

3.1. Unterstützt PowerBASIC einen CoProzessor?
3.2. Welche Fließkommabibliothek ist für mich die optimale?
3.3. Macht sich der CoProzessor auch bei $FLOAT PROCEDURE bemerkbar?
3.4. Welche PowerBASIC-Funktionen sind betroffen?
3.5. mögliche Ursachen für den CoProzessor-Effekt
3.6. PowerBASIC-Benchmark Source


3.1. Unterstützt PowerBASIC einen CoProzessor?
----------------------------------------------
Die Antwort lautet ganz einfach JA. Bereits in den Compiler-Optionen
haben Sie die Möglichkeit drei verschiedene Fließkommabibliotheken
auszuwählen. Aber mit dieser Unterstützung 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 Fließkommabibliothek ist für mich die optimale?
-----------------------------------------------------------
PowerBASIC bietet insgesamt drei Fließkommabibliotheken 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-
stützung des i87 aus, sofern ein solcher CoProzessor gefunden wurde.
Der enorme Nachteil liegt aber sofort auf der Hand. PowerBASIC
testet ständig 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
Coprozessorunterstützende Fließkommabibliothek eingebunden hat, läßt
sich dies anhand der beiliegenden Source sehr deutlich beweisen.
Des Rätsels Ursache liegt in der PowerBASIC-Runtime-Bibliothek, diese
unterstützt schon von Hause aus einen i87. Deshalb lassen sich auch die
Geschwindigkeitsauswirkungen der verschiedenen Fließkommabibliotheken
nicht verallgemeinern.


3.4. Welche PowerBASIC-Funktionen sind betroffen?
-------------------------------------------------
Als betroffende internen PowerBASIC-Funktionen wäre 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 benötigen 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 Ausdrücken betroffen.


3.5. mögliche Ursachen für den CoProzessor-Effekt
-------------------------------------------------
Meines Erachtens hat dieser Effekt recht natürliche Ursachen, da alle
betroffenden Befehle mit dem neuen 80-stelligen Zahlensystem umgehen
können müssen. Anscheinend haben die Programmierer von PowerBASIC ver-
sucht den zusätzlichen 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 beigefügte Source soll Ihnen die Zusammenhänge der vorherigen
Abschnitte besser demonstrieren. Am besten Sie compilieren die Source
und testen einfach ein wenig herum.

Source:
REM *****************************************************************
REM
REM PBBENCH.EXE - Performance-Meßprogramm für PowerBASIC
REM
REM Zum Feststellen der Geschwindigkeitsunterschiede einzelner
REM PowerBASIC-Befehle in Verbindung der verwendeten Fließkomma-
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 Für halbwegs reale Meßungen muß sich der Prozessor im REAL-
REM Mode befinden. Es dürfen keine TSR-Treiber installiert sein,
REM also kein KEYB.COM, SMARTDRV.EXE oder ähnliches.
REM Wichtig:
REM Für eine halbwegs genaue Meßung 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 können den CoProzessor für
REM PowerBASIC mit dem in dieser Source beigefügtem 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 ' für Rechner mit CoProzeßor (am
' schnellsten)
REM $FLOAT PROCEDURE ' für Rechner ohne CoProzeßor (von mir
' empfohlen)
REM $FLOAT EMULATE ' automatisch unterstützen (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! für 5000000-Schleifen ; zum Herausrechnen der Zeiten
REM Zc2! für 2000000-Schleifen ; für die FOR/NEXT-Schleifen
REM Zc3! für 100000-Schleifen
REM Zc4! für 2000-Schleifen

IF pbvnpx > 0 THEN
PRINT "CoProzessor " + CHR$(pbvnpx+48) + "87 gefunden!"
PRINT
PRINT "Soll der CoProzessor für die nächste 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 für die nächste Messung ";
PRINT "wieder eingeschaltet werden (J/N)?"
PRINT
PRINT "Hinweis: Einschalten dieses Testes bei nicht ";
PRINT "installiertem Coprozessor führt"
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 für die einzelnen Messungen
'********************************************************************

HoleZeitKonstanten:
PRINT "Messung der Zeitkonstanten ";

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

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

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

PRINT "."
t1! = TIMER
FOR i& = 1 TO 2000000 ' Zeit für 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 abhängig vom verwendeten
' Computersystem und dem installiertem Betriebssytem. Gerade aber in
' Verbindung mit PowerBASIC, der verwendeten Fließkommabibiliothek
' 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. Kompatibilität 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 verfügbar bei ENVIRON$
4.5. Keine Errorcode-Zurückgabe bei SHELL
4.6. Kürzen 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 für PowerBASIC 3.1/3.2

<Hier fallen mir einfach keine mehr ein>


4.1. Kompatibilität 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 abwärt-
kompatibel. Das heißt, sie können eine mit PowerBASIC 3.0 erstellte
PBU/LIB unter den beiden höheren PowerBASIC Versionen weiterverwenden.
Eine mit PowerBASIC 3.1 erstellte PBU/LIB können 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
--------------------------------------------------------
Für das 'ständig 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 für PowerBASIC erschliesst. Obwohl das
Tool 'PBPLUS96' (96kByte mehr RAM) für 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 können, dieses dann aber die eigenen Daten und
INI-Files nicht mehr findet. Die Lösung ist recht einfach: DOS
speichert diese Informationen im PSP bzw. im zum PSP gehörigen
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 verfügbar bei ENVIRON$
----------------------------------------------
Dieser Absatz ist zwar teilweise im Handbuch beschrieben, doch möchte
ich einige weiterführende Tips geben, da dieses Thema immer wieder zu
Mißverständnissen führt. Der Aufbau des Environmentblockes in Verbindung
mit dem Programm Segment Prefix wird nicht weiter beschrieben, ist
allerdings von enormer Bedeutung zum besseren Verständnis dieses Fehlers.

Zusammenfassend sei gesagt, das Sie nur das vorhandene Environment
modifizieren und nicht durch neue Einträge erweitern können!! Wollen Sie
nun trotzdem Einträge hinzufügen, so können Sie 3 Wege beschreiten:

a) Teile des Environment löschen und dann den neuen Eintrag hinzufügen
oder bereits vorher einen Dummy-Environmenteintrag anlegen und diesen
dann per ENVlRON-Befehl löschen 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-Lösungen)


4.5. Keine Errorcode-Zurückgabe 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 möglich, da PowerBASIC das Programm immer über COMMAND.COM
ausführt und deshalb der Errorcode nicht zurückgeben werden kann (dies
ist eine Eigenart von MS-DOS!!).

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

Für die Lösung 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
' ausführen.
Cmd$ = "/C " + Datei$ + " " + Cmd$
Datei$ = ENVIRON$("COMSPEC")
CASE ".COM" ' Frei
CASE ".EXE" ' Frei
CASE ELSE ' Keine Extension,
Datei$ = Datei$ + ".EXE" ' .EXE anhängen.
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$)) ' Länge des Cmd$ als String
Cmd$ = CmdLen$ + Cmd$ + CHR$(13) ' Länge + 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 geöffnet"
CASE 5 : PRINT "Zugriff verweigert " + Filename$
CASE 8 : PRINT "Zuwenig freier Speicher für " + FileName$
CASE 10 : PRINT "falscher Environmentblock"
CASE 11 : PRINT "falsches Format"
CASE ELSE: PRINT "Problem meim Ausführen 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 können Sie die COMSPEC-Variable in Ihrem Environment
modifizieren und Ihr Programm ohne Umwege über COMMAND.COM direkt
ausführen.
Beispiel:
Comspec$ = ENVIRON$("COMSPEC") 'Sichern von COMSPEC
ENVIRON "COMSPEC=MEINDEMO.EXE"
SHELL 'Ausführen von MEINDEMO.EXE
ENVIRON "COMSPEC="+Comspec$ 'Restaurieren von COMSPEC

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


4.6 Kürzen von Files
--------------------
Oft stehen Sie vor dem Problem das Sie Ihr Datenfile aufgeräumt 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

Verkürzt die Datei 'DEMO.DAT' auf 20Bytes Länge.


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 für das Datensegment zu finden sind,
da PowerBASIC nur ein Datensegment pro OBJ-File unterstützt.
Da mir zu Zeit auch keine Lösung 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 möglichen 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 erwünscht!"
RETURN


4.9. Öffnen von mehr als 15 Files mit PowerBASIC und/oder mit DOS
-----------------------------------------------------------------
Oft scheint man an die Grenzen von PowerBASIC zu stoßen, 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 erklären muß ich leider ein wenig in die Untiefen
von DOS Licht bringen, denn dort finden wir auch des Rätsels Lösung.
Vielen ist bestimmt bekannt, das nach dem Öffnen von Dateien ein
Handel zurückgeliefert wird. Nur wo speichert DOS dieses Handle und
die Informationen die zu diesem Handle gehören?

Vielen ist bestimmt der Begriff PSP (Programm Segment Prefix) ein
Begriff (bereits kurz erwähnt bei der Ermittlung des Dateinamens), wenn
nicht sollten Sie die folgenden Ausführungen besser überlesen und die
Source testen.
Dieses PSP enthält jedenfalls eine Tabelle, welche durch Microsoft
zwar als reserviert gilt, deren Bedeutung aber längst 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 großes BYTE-Array.
Zieht man jetzt die ständig belegten Handles für: NUL, $CLOCK, CON
AUX und PRN ab, so verbleiben unsere magischen verfügbaren 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 Erhöhen muß in der CONFIG.SYS ein höherer Wert bei
FILES angegeben werden. Nach dem Neustart des System reserviert MS-DOS
nun mehr als SFT markierte MCB's. Sie könnten also nun theoretisch mehr
als 20 Files öffnen, denn der Defaultwert bei FILES ist '8'.
Leider stoßen wir hierbei wiederum auf die begrenzte Anzahl der Einträge
in der JFT innerhalb des PSP. Ab MS-DOS 3.3 gibt es hierbei aber Abhilfe,
da der INT &h21, Funktion &h67 ermöglicht die Anzahl der verfügbaren
Handles zu erhöhen. 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 enthät die neue
Größe 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 können also theoretisch 65535 Handles verwaltet werden,
was allerdings rein Hypothetisch ist, da die SFT weiterhin nur 255 Ein-
träge verwalten kann.
Wichtig bei der Neuzuweisung einer JFT sind eigentlich nur zwei Dinge:
- Die neuen JFT benötigt Speicher, das heißt sie müssen den Heap
des aktuellen PowerBASIC Programms herunterschrauben!
- Eine Extendet JFT wird bei SHELL/EXECUTE nicht an das Child-
Programm vererbt! Für das Child-Programm gilt also wieder die
15 Files Grenze.

Ok, jetzt aber die Source:

'***********************************************************************
'
' Erhöhen der verfügbaren Handles in PowerBASIC 3.2
'
' entwickelt von Th.Gohel Fido: 2:2410/301.12
' InterNet: sup...@pbsound.snafu.de
' Homepage: http://www.snafu.de/~pbsound/
'
'***********************************************************************

MaxFiles% = 30 ' entspricht FILES = 30
PBFiles MaxFiles% ' anpassen der verfügbaren Files

FOR i% = 1 TO MaxFiles% ' Testen der verfügbaren Files
PRINT "Öffne File: PBFILES." + STR$(i%)
OPEN "PBFILES." + STR$(i%) FOR BINARY AS i%
PUT$ i%, "Testdatei" + STR$(i%) + " für PBFILES, bitte löschen!"
NEXT i%
FOR i% = 1 TO MaxFiles% ' und wieder schliessen
CLOSE i%
NEXT i%

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


4.10. HEX$-DWORD Routine für PowerBASIC 3.1/3.2
-----------------------------------------------
Nachfolgende Routine soll, den für mich unverständlicherweise fehlenden
HEX$-Support für Variablen vom Typ DWORD, ermöglichen.

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
===============================================

Kurzübersicht:
5.1. Funktionsprinzip des PowerBASIC Inline-Assemblers
5.2. Assembler Syntax Error
5.3. Fehlerhafte Variablenübergabe 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. Parameterrückgabe mit dem Inline-ASM
5.11. Variablenübergabe 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 Anfängerprobleme
umschiffen zu helfen. Auf eine genauere Beschreibung der Zusammenhänge
wird deshalb verzichtet, es sei es gehört zum Problem selber.


5.1. Funktionsprinzip des PowerBASIC Inline-Assemblers
------------------------------------------------------
Der PowerBASIC Inline-Assembler besitzt den Funktionsumfang der Intel
8086 CPU. Das heißt, da Sie Inline-Assembler-Code anderer Hochsprachen-
Compiler bzw. reinen Assembler-Code leicht an den PowerBASIC Inline-
Assembler anpassen müssen, da diese recht oft bereits 80286'er Befehle
enthalten. In der Regel fallen immer wieder folgende Befehle auf, welche
Sie wie folgt konvertieren können:
<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 auflösen kann, da Sie nicht in
irgendeiner Form definiert ist.
PowerBASIC legt normalerweise die verwendeten Variablen innerhalb einer
reinen BASIC-Source selbstständig an und weist dieser Variablen Ihren
Speicherplatz zu. Innerhalb des Inline-Assemblers müssen Sie dafür
selber sorgen.
Beispiel:
! mov ax, Demo%
führt 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 müssen aber
nicht jedesmal die Variable speziell mit einem Wert laden, ein bloßes
DIM oder auch SHARED, PUBLIC, LOCAL etc. reicht hierbei völlig aus und
initialisiert 'Demo%'.


5.3. Fehlerhafte Variablenübergabe 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 Rätsels Lösung ist relativ einfach: Sie müssen Variablen für 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 Parameterübergabe weg und testen Sie das Demo erneut!


5.4. Probleme mit LDS/LES
-------------------------
Ähnlich wie bei der Parameterübergabe für den Inline-Assembler verhält
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
können 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 höherwertige Inhalt der
Variablen geladen, sofern vom Typ Long/DWord, ansonsten enthält 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
Tücke verbunden, da Sie wichtige Segmente verbiegen bzw. speziell
zuweisen müssen. Viele Buffer, die einer Funktion übergeben werden
müssen, erwarten speziell im Datensegment-Register (DS) Ihren Zeiger.
PowerBASIC selbst addressiert aber seine Variablen ebenfalls über DS,
sodas hier Konflikte vorprogrammiert sein können. 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 für PowerBASIC ins
; Nirwana zeigt, schlägt diese Zeile
; ebenfalls fehl und PowerBASIC
; stürzt ü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,
; für 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 läßt nur
bedingte Sprünge vom Typ SHORT zu, das heißt sie können 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, müssen 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 aufhören. 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 (gewußt 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. Parameterrückgabe mit dem Inline-ASM
-------------------------------------------
Im Gegensatz zum reinem Assembler läuft die Rückgabe 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 möglich.

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 können Sie den Rückgabewert aber direkt an die
FUNCTION übergeben, nur bei 32bit (und größeren) Werten müssen 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. Variablenübergabe in Interrupt-Prozeduren
------------------------------------------------
Sehr schwierig ist die Übergabe von Variablen innerhalb einer eigenen
Interruptroutine, da sie davon ausgehen können, das das Datensegment
mit hoher Sicherheit nicht dem benötigtem Datensegment von PowerBASIC
entspricht. Allerdings auch hier haben uns die Entwickler von PowerBASIC
eine große Hintertür 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 müssen 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 Präfix &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 benötigt um eigene Interrupt-Prozeduren, alte
Interrupt-Handler oder auch Gerätetreiber wie CTVDSK/CT-VOICE und
HIMEM/MSCDEX aufzurufen. Da die Erstellung des 32bit Zeigers in einem
der vorangegangenden Absätze 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 können ebenfalls dem Codesegment entnommen werden!


5.13. Konvertierung von REG nach Inline-ASM
-------------------------------------------
Ebenfalls recht einfach läuft 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 können 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 läuft 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
======================================================

Kürzübersicht:
6.1. Allgemeines über Pointer
6.2. Was sind Pointer und was können 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 geführt.
Das sich dieser elementare Vorteil der BASIC-Programmiersprache auch
ohne Probleme beim Einsatz von Pointern ausspielen läßt, soll Ihnen
dieser Abschnitt erläutern, denn der Einsatz von Pointern in PowerBASIC
ist mit keinerlei Einschränkungen verbunden!
Allerdings sollten Sie für das Lesen folgender Artikel bereits Wissen
über die interen Wirkungsweise von BASIC und auch DOS haben.


6.2. Was sind Pointer und was können sie leisten?
-------------------------------------------------
Pointer (auch Zeiger genannt) bieten die Möglichkeit, Datenstrukturen
an einer beliebigen Stelle des DOS-Speichers zu interpretieren. Dazu
müssen Sie dem Pointer nur eine beliebige Adresse übergeben.
Pointer dienen vor allem dazu Speicherbereiche zu nutzen, welche außer-
halb der dynamischen Speicherverwaltung von PowerBASIC liegen. Sie
können mit Pointern z.B. direkt Strukturen interpretieren, auf die von
DOS-Funktionen Zeiger zurückgeliefert 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 entfällt 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 müssen 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 für 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 müssen 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 Länge
' 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 müssen 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 können, müssen 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 müssen 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 mißbraucht und gezeigt,
' wie PRINT-Ausgaben den Inhalt der beiden Pointer VIDEORAM und ZEICHEN
' modifizieren.
'
' Als sinnvolle Erweiterung könnte man diese Routine zum schnellen
' Sichern und Restaurieren des kompletten Videorams nutzen:
'
' @Videoram.Page2 = @Videoram.Page1
'
' würde den kompletten Inhalt der ersten Page in die zweite Seite retten
' um später wieder restauriert werden zu können
'
'************************************************************************

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 löschen

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 gefüllt 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 ' gefüllt. 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 füllen
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++
===================================================

Kurzübersicht:
7.1. Autor
7.2. Warum externe Routinen für PB3 in C schreiben/verwenden
7.3. Speicher-Modell angleichen
7.4. Einschränkungen durch den PowerBASIC 3.x Compiler/-Linker
7.5. Parameterübergabe
7.6. PowerBasic-Beispiel
7.7. Zugehöriger C-Modul
7.8. Der zur C-Routine gehörige 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 für PowerBASIC in Verbindung mit C-Compilern wie Turbo-C bzw.
Borland C++ wurden freundlicherweise von:

Andras Hoeffken <a...@confusion.rmc.de>
Andras Hoeffken <2:2480/13.34 @ fidonet>
Andras Hoeffken <130:1322/302 @ basnet-Germany>

für diese FAQ zur Verfügung gestellt.

Sehr nützliche Hinweise sind auch in der Datei CTOPB.FAQ enthalten, diese
gehört zum Lieferumfang von PB Vs. 3.2.


7.2. Warum externe Routinen für PB3 in C schreiben/verwenden
------------------------------------------------------------
- C-Routinen ergeben schnell laufenden Code
- für 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 können mit PB verwendet werden


7.3. Speicher-Modell angleichen
-------------------------------
Für das Linken von *.EXE-Files können (z.B. bei MASM oder C) verschiedene
Speichermodelle vorgegeben werden, z.B. Tiny, Small, Medium, Compact,
Large, Huge, ...

Für die von PowerBASIC erzeugten *.EXE gilt nur:
PowerBASIC 3.x - Speichermodell = LARGE
(PB benutzt für 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 gelöscht 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 aufräumt, C-
Compiler arbeiten umgekehrt. Daher: In den DECLARE-Zeilen "CDECL"
verwenden (s.u.)!


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

Entsprechend müssen die Deklarationen in den C-Routinen angepaßt 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" zurückgegeben.
- 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. Zugehöriger 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:
------------------------------------------------
Für 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 für .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 angepaßt
ist als PB V2.1, ist es meist immer noch nicht möglich, .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 Möglichkeiten:

- Bei Borland C++ Vs. 3.1 wird für die meisten Runtime-Bibliotheken der
ges. Quellcode mitgeliefert einschließlich einer Anleitung und Make-
Files, wie man Bibliotheksmodule abwandeln und dann neu generieren
kann.
- Liegt für 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. Maßnahmen 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, müssen 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.Ju...@take-off.flightsim.de)

Generell kann man sagen, daß PDS-Sourcen in PB3-Sourcen konvertiert
werden können. Ausnahmen sind z.B. Sourcen, die auf Fremd-Bibliotheken
zurückgreifen 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 verfügbar 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 erfüllt 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 zurück, PDS dagegen VORZEICHEN-
|BEHAFTETE.
|Dies kann per $OPTION SIGNED OFF
|geändert werden.
---------------------------------+---------------------------------------
Offset bei einer per OPEN ge- |In PB fängt eine Datei - je nach
öffneten Datei fängt bei '1' an! |Wahl - bei Null (Standard) oder bei
|Eins an. Dieses kann mit folgendem
|Befehl eingestellt werden:
|OPTION BINARY BASE 1
|für 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 dürfen 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 MÜSSEN. Sie sind
|also UNABHÄNGIG vom DATENTYP !!!
|Alle Typen-Angaben 'AS xxx' sind in
|PB3 unzuläßig.
|Die Block-Angabe (/Block/) fällt bei
|PB weg, da hier alles Namens-Abhängig
|ist. (-> Inkompatibilität !)
---------------------------------+---------------------------------------
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 könnte.
|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 dazugehörigen 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 läßt 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, für das Problem der Konstanten-Konvertierung einen
Konverter zu schreiben, denn dies dürfte den Löwen-Anteil bei der
Konvertierung großer Programme ausmachen. Im gleichen Zuge kann man
natürlich auch die Sache mit den COMMON SHAREDs und den DIM SHAREDs und
natürlich 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 unzählige weitere Toolboxen, aber ich möchte
hier nur auf die wesentlichsten Toolkits eingehen.

9.1. PBSOUND für PowerBASIC 3.0/3.2
9.2. HiVGA für PowerBASIC 2.1/3.2
9.3. PBVISION für PowerBASIC 3.0/3.1
9.4. PBCompress für PowerBASIC 3.1
9.5. Personal Protocol/Communication Library für PowerBASIC
9.6. POW! - Sound Blaster Toolkit
9.7. PBGUI Toolkit für PowerBASIC 3.0
9.8. PBWizard
9.9. SVGA für PowerBASIC
9.10. MAXLIB for PowerBASIC v1.2
9.11. DWDOOR for PowerBASIC 3.x
9.12. Special-Power / Spezialtools für 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 benötigt werden


9.1. PBSOUND für 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 :
- Unterstützung aller Creative Labs Sound Blaster Modelle,
incl. SB16 und SB32AWE
- Upgradeboards wie WaveBlaster I+II, sowie Roland SoundCanvas
SCD10/15, Yamaha DB-50XG
- Unterstützung des internen PC-Speakers
- Wiedergabe von MIDI und VOC-Files im Hintergrund und innerhalb
der IDE
- keine Längenbegrenzung bei VOC-Files
- Wiedergabe/Aufnahme bis zu 44100, Stereo und 16bit mit einer
SB16 bzw. SB32AWE
- Unterstützung des SBPro/SB16 Mixers
- Sprachsynthese via SBTALKER.EXE
- Online-Hilfe für PowerBASIC-IDE
- PBPLAY, MIDI/VOC-Player Tool
- PBREC, VOC-Aufnahme Tool
- PBSPEAK, VOC/WAV Player für Speaker
- PBW2V, VOC<->WAV Konvertierungstool
- mit brandneuem PBSOUND-Library Konzept!!!!!
Linken von Files in eine Library und zukünftigem Erstellen
von ausführbaren PowerBASIC EXE-Dateien bis zu 4GByte!!!
- Demo & Einführungsprogramme
- Komplett mit INSTALL & SETUP-Programme
- beigefügter Sourcen:
Ansteuerung des CT-VOICE.DRV & SBPro Mixerchips


9.2. HiVGA für PowerBASIC 2.1/3.2
---------------------------------
Sprache: Deutsch / Englisch
Autor : Matthäus Stadler
Version: V1.95
Preis : 40,-DM
Bezug : PowerBASIC-Filearea: Toolboxen
Fido-Request mit Magic 'HIVGAPB' bei 2:2476/400-403
Online bei der MUSIC-BBS Karlsruhe: 0721/688834
oder bei: Gogodot-Systems Freiburg 2:2476/834 auch
mit dem Magic 'HIVGAPB'
File : HIVGA195.ZIP
Inhalt :
- Automatische Erkennung der verwendeten SVGA-Karte
- 320x200 - 1600x1200 auf VESA-, allen gängigen und vielen
exotischen SVGA-Karten (mit entsprechendem Grafik-Speicher)
- Ausser 256 Farben auch HiColor (32k) und RealColor (64k)
- Schnelle Zeichenfunktionen (Rechtecke, Ellipsen, Füllen,
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, Leistungsfähige Sprite-Routinen,
Scrolling
- Mausunterstützung (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
- Läuft ab 386 mit (S)VGA-Karte und PowerBASIC
- Keine funktionellen Einschränkungen in der Sharewareversion.


9.3. PBVISION für 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: Toolboxen
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 für PowerBASIC 3.1
------------------------------------
Sprache: Englisch
Autor : Greg Turgeon
Version: V1.1
Preis : $39.00/$69.00 (ohne bzw. mit Sourcecodes)
Bezug : PowerBASIC-Filearea: Toolboxen
File :
Inhalt :
- Filecompressions- und Entpackutility
- Fortschrittsanzeige
- packt auf dem Niveau wie MS Compress
- recht schnell


9.5. Personal Protocol/Communication Library für PowerBASIC
------------------------------------------------------------
Sprache: Englisch
Autor : MarshallSoft Computing
Version: V4.3 (Communication)
V1.0 (Protocol)
Preis : $65 (Communication) / $40 (Protocol)
Bezug : PowerBASIC-Filearea: Toolboxen
diverse Mailboxen/Filenetze (BasNet) in Deutschland
File : PCL4PB43.ZIP
PPL4PB10.ZIP
Inhalt :
a) Personal Protocol Library V1.0 für PowerBASIC:
- XMODEM, XMODEM-CRC, XMODEM-1K, YMODEM, YMODEM-G und
ZMODEM Protokolle.
b) Personal Comm Library V4.3 für 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: Toolboxen
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 für Samples


9.7. PBGUI Toolkit für PowerBASIC 3.0
---------------------------------------
Sprache: Englisch
Autor : James C. Fuller
Version: V2.00f
Preis : $40.00 + Versandkosten
Bezug : PowerBASIC-Filearea: Toolboxen
File :
Inhalt : Erstellen von PowerBASIC-Oberflächen im Windows-Look


9.8. PBWizard
--------------
Sprache: Englisch
Autor : Thomas G. Hanlin
Version: V2.1
Preis : $99.95 (keine Shareware-Version)
Bezug : PowerBASIC-Filearea: Toolboxen (ältere Shareware-Version)
| File :
Inhalt :
- Bereitstellung vieler Zusatzfunktionen
- Ersatz einiger PowerBASIC-Routinen
- Sound Blaster via SBSIM (TSR-Treiber benötigt)
- XMS/EMS Unterstützung
- CRC16
- und und und ...


9.9. SVGA für PowerBASIC
-------------------------
Sprache: Englisch
Autor : Stephen L. Balkum und Daniel A. Sill (Zephyr Software)
Version: V2.4
Preis : $35.00
Bezug : PowerBASIC-Filearea: Toolboxen
http://www.phoenix.net/~balkum/
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 nützliche Grafikroutinen
- Sprites und vieles mehr


9.10. MAXLIB für 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: Toolboxen
File : MAX12A.ZIP
Inhalt :
- Nutzung des EMS/XMS-Speichers zum Speichern von Array's
- I/O-Funktionen


9.11. DWDOOR für PowerBASIC 3.x
-------------------------------
Sprache: Englisch
Autor : James R. Davis
Version: 3.1
Preis : $35.00/$65.00 (mit gedrucktem Manual)
Bezug : PowerBASIC-Filearea: Toolboxen
File :
Inhalt :
- Schreiben von DOORS für Mailboxsysteme
- unterstützt 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 für PowerBASIC 2.1/3.0
---------------------------------------------------------
Sprache: Deutsch/Englisch
Autor : Stefan Machwirth
Version: 1.10
Preis : 38,- DM/36,- US$
Bezug : Mailboxen, BasNet
PowerBASIC-Filearea: Toolboxen
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 große andere Programme
- gibt Errorlevel zurück
- unterstützt rekursiven Aufruf beliebig vieler EXEs
- DDE-Routinen für den Datenaustausch unter DOS
- wahlweise TSR- und Runtime-Konfiguration
* DLZV 1.0:
- Datenkompression mit Source-Schnittstelle für eigene Programme
* CRYPT 1.0:
- Paßwortschutz mit Falltüralgorithmus.
- codiert Strings und ganze Files
- keine aufwendigen Debug-Sperren nötig
- nur mit extrem aufwendigen Brute-Force-Methoden zu ent-
schlüsseln
* 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: PBSOUND
Internet: http://earthvision.asu.edu/~edward/
File : BWSB120A.ZIP
BWSB120B.ZIP
Inhalt :
- Modulplayer (S3M, MOD, 669, ULT, MED, FAR & STM) für
PowerBASIC
- unterstützt GUS, SB1.x, SB2.x, SBPRO, SB16 & PAS
- alle Routinen im 386'er Code (OBJ-Files)
- ebenso geeignet für QB, PDS, TP, C, C++ und ASM

9.14. Public Domain Sourcen von deutschen Programmierern
--------------------------------------------------------
Diese Routinen wurden bereits in diversen Computernetzen verbreitet und
können 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 benötigter Sourcen. CrossPoint-User können
mit 'M' und 'F3' sofort einen Request auslösen <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 für PowerBASIC 3.2
(mit Pointern)
DIR95.BAS - Directory Routinen für Windows 95
DISKFREE.BAS - Festplattengröße 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 für 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 für 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 für 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 benötigt werden
------------------------------------------------------
Oft wird in den einschlägigen Programmierecho's immer und immer wieder
nach den gleichen Sourcen gefragt. Hier also eine kleine Hitliste der
internationalen Sourcen:

Name: Beschreibung:
BARCODE*.BAS - Routinen für 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 für INT &h21, Funktion &h5F
PCX320.ZIP - PCX-Laderoutine für 320*200 & 256 Farben
PCXVGA.BAS - PCX-Laderoutine für 640*480 & 16 Farben


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

Natürlich 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 natürlich die beiden PowerBASIC-Leute über-
haupt:

Bob Zale - entwickelte eigentlich PowerBASIC und bezeichnet
PowerBASIC als sein Lebenswerk
b...@powerbasic.com (Bob Zale)
Dave Navarro - Chef-Entwickler bei PowerBASIC Inc.
sy...@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 für PowerBASIC (Zephyr Software)
Daniel A. Sill - SVGA für PowerBASIC (Zephyr Software)


10.2. BRD - Deutschland, deutschsprachiger Raum
-----------------------------------------------
In Deutschland haben sich natürlich 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 wäre diese FAQ bei weitem
nicht das was sie heute ist.
Darum möchte ich hiermit die Gelegenheit nutzen diesen Leuten persönlich
zu danken:

Thomas Gohel - Autor von PBSOUND für PowerBASIC, Autor dieser
PowerBASIC-FAQ und vieler anderer Sachen ...
Nebenbei scheine ich hier für den PowerBASIC-
Support auch zuständig zu sein ;)
Andras Hoeffken - Messgerätesteuerung mit PowerBASIC
- Kapitel 'C++ und PowerBASIC'
Stephan Günther - grafische Umsetzung sämtlicher Bilder mit Highlight
Professional V1.0 für "Windows New Technology"
- incl. aller gerenderten Grafiken und Animationen
zu PBSOUND
Thomas Geiger - englische Version der FAQ
- für einige Anregungen zu dieser FAQ
Mark Junker - Kapitel 'Konvertierung PDS zu PB'
- für einige Anregungen zu dieser FAQ
Wolfgang Bruske - englische Version des Kapitel 'Pointer'
Bernd Richter - für die Richtigkeit diverser Informationen
Peter Cooper - für die grammatische Richtigkeit der englischen
Version
Marc van den Dikkenberg
- für einige Anregungen zu dieser FAQ
Roland Arendes - für 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
=============================================================================


0 new messages