PofoWiki

Die ultimative Informationsquelle zum ATARI Portfolio

Benutzer-Werkzeuge

Webseiten-Werkzeuge


software:diy:basic:tbc

Tokiwa-Basic-Compiler

Der Tokiwa-Basic-Compiler (TBC) ist eigentlich nicht neu, stammt aber aus Japan und hatte lange Zeit nur eine japanische Dokumentation, so dass er außerhalb Japans relativ wenig Verbreitung fand.

Der Compiler wurde - vermutlich Anfang der 1990er Jahre - von Dr. Genji Okada entwickelt. Die bislang letzte Version (5.55e) stammt vom Dezember 2000 und bekam vom Autor eine, wenn auch sehr knappe, englischsprachige Beschreibung spendiert, was den Einsatz natürlich erleichtert, Neben der Freeware-Version, die man z.B. unter http://www.franksteinberg.de/psprach.htm#TokiwaBas herunterladen kann, gab es wohl noch eine kommerzielle Variante, die aber nirgends mehr auffindbar zu sein scheint.

Inzwischen existiert auch eine deutschsprachige Version des Handbuchs, die eine Übersetzung der englischen Version mit einer Reihe von Ergänzungen und erklärenden Anmerkungen darstellt. Sie ist HIER abrufbar.

Besonderheiten von Tokiwa-Basic

Tokiwa-Basic nimmt sich (so der Autor) Standard-Basic als Ausgangspunkt und erweitert es um nützliche Eigenschaften:

  • keine Angabe von Zeilennummern notwendig
  • explizit festlegbare Datentypen für Variablen (integer, real, character)
  • erweiterte Arrays (mit DIMX definierbar)
  • benutzerdefinierte benannte Unterprogramme und Funktionen mit formalen Parameterlisten
  • lokale Variablen in Unterprogrammen und Funktionen
  • integrierte Gleitpunkt-Arithmetik
  • integrierter Assembler für maschinennahe Routinen

Der Tokiwa-Basic-Cpmpiler ist tatsächlich ein „echter“ Compiler. Es wird also direkt Maschinencode erzeugt und folglich kein Runtime-Modul benötigt. Der Overhead ist dabei recht klein - er liegt bei etwa 400 Bytes, die für die Initialisierung benötigt werden. Werden Real-Zahlen verwendet und somit die Gleitpunkt-Arithmetik benötigt, kommen noch einmal ca. 3 KB dazu, was im Vergleich zu den 20KB, die z.B. die Gleitpunkt-Emulation von Turbo-C braucht, sehr sparsam ist.

Der Compiler kann wahlweise Programme im EXE- oder COM-Format erzeugen, wobei sich beide Varianten in ihrem Aufbau praktisch nicht unterscheiden. Die EXE-Dateien verwenden initial das Tiny-Speichermodell und belegen, wie die COM-Dateien, den gesamten freien Speicher. Die Initialisierung der Segmentregister erfolgt in beiden Varianten auf gleiche Weise zur Laufzeit.

Tokiwa-Basic erlaubt das Anlegen von Bibliotheken (Quelltext), die in Programme per MERGE-Anweisung integriert werden können. Dies ermöglicht die einfache Wiederverwendung benutzerdefinierter Funktionen und Unterprogramme.

Tokiwa-Basic auf dem Portfolio

Der Compiler ist nur etwa 36KB groß und passt damit bequem auf eine CCM-Karte. Weder der Compiler noch die von ihm erzeugten Programme benötigen Funktionen, die auf dem Portfolio nicht verfügbar sind. Bei der Übersetzung werden außerdem keine temporären Dateien erzeugt, die bei wenig Platz zu Problemen führen könnten.

Allerdings gibt es ein anderes Problem, das den Einsatz des Compilers auf einem Standard-Pofo verhindert: Er gönnt sich zu seinem Code zwei Datensegmente von jeweils 64K sowie einen Stack von 18K und benötigt damit mindestens ca. 180K RAM, was also eine Speichererweiterung erfordert.

Auch die erzeugten Programme gehen - für Portfolio-Verhältnisse - recht großzügig mit dem Speicher um. Sie verlangen normalerweise mindestens 69K RAM, was darauf zurückzuführen ist, dass standardmäßig ein Datensegment von 64K und ein Stack von 4K angelegt werden. Mit Hilfe von Compiler-Optionen und einem kleinen Patch-Programm lässt sich der Bedarf aber bis auf etwa 10K reduzieren. Damit sind mit dem TBC erzeugte Programme dann bestens für den Einsatz auf dem Portfolio geeignet. Der integrierte Assembler ermöglicht sehr einfach den direkten Zugriff auf Systemfunktionen.

Für die Pofo-Programmierung mit Tokiwa-Basic gibt es HIER eine erweiterte Distribution des Compilers, die folgende zusätzliche Dateien enthält:

  • tbc_de.pdf: die deutschprachige Dokumentation
  • tbcptch.com: Binary des Patch-Programms
  • tbcptch.bas: Quellcode des Patch-Programms (ja, in Tokiwa-Basic geschrieben :-D )
  • mshrink.ltb: Bibliothek zur Verkleinerung des verwendeten Speicherblocks
  • alloc.ltb: Bibliothek zur Verwaltung von dynamischen Speicherbereichen
  • strings.ltb: Bibliothek mit zusätzlichen String-Funktionen
  • files.ltb: Bibliothek mit erweiterten Funktionen zum Umgang mit Binärdateien
  • dirs.ltb: Bibliothek mit Verzeichnisfunktionen
  • test31.bas: Testprogramm für mshrink.ltb und alloc.ltb
  • strings.bas: Testprogramm für strings.ltb

Verwenden von TBCPTCH

Der Zweck von TBCPTCH besteht darin, den beim Programmstart benötigten Speicherplatz eines mit TBC übersetzten Programms zu reduzieren. Voraussetzung dafür ist es, die Maximalgröße des Datenbereichs zu reduzieren. Dies erfolgt mit Hilfe der Compiler-Optionen /wl (Obergrenze des Offsets im Datensegment), /wp (Maximalwert des Stack-Pointers) und /ws (Stack-Größe in Bytes).

Dabei gelten folgende Standardeinstellungen: /wl=&fff8 /wp=&fffe /ws=4096

Allerdings kann man diese Werte nicht beliebig verkleinern - folgendes ist zu beachten:

Das Datensegment braucht eine Mindestgröße, die sich etwa wie folgt abschätzen lässt:

   Anzahl aller globalen Integer-Variablen * 2
 + Anzahl aller globalen Real-Variablen * 5
 + Anzahl aller globalen String (Character)-Variablen * 2
 + Summe der Längen aller globalen String-Variablen
 + Summe der Längen aller mit DIM definierten Felder Länge = Anzahl Elemente * Elementgröße)
 + Anzahl der mit DINX definierten Felder * 2
 + Summe der Puffergrößen (Optionen /wt, /wi und /wb; Standard: 514 Bytes)
 + mindestens 1K für Stringoperationen und sonstigen Verwaltungs-Kleinkram
 = Minimalwert für /wl

Das Stacksegment liegt um die durch /ws gegebene Anzahl von Bytes oberhalb des Beginns des Datensegments. Damit sich Stack und Datenbereich nicht gegenseitig überschreiben können, darf der Wert von /wp nicht kleiner als der von /wl sein.

Die benötigte Stackgröße ergibt sich vor allem aus der Anzahl der in Unterprogrammen und Funktionen verwendeten Argumente und lokalen Variablen sowie der maximalen Tiefe rekursiver Aufrufe. Jedes Argument benötigt 2 Bytes auf dem Stäck, zusätzlich werden für jeden Unterprogramm-/Funktionsaufruf 2 Bytes für die Return-Adresse benötigt. Darüber hinaus fallen für jede lokale Integer-Variable 2 bytes an. Lokale Real- und String-Variablen werden dagegen im Datensegment angelegt und sind für dessen Größe zu berücksichtigen.

Für die Einstellung der Optionen bietet es sich an, in der ersten Zeile des Programm-Quelltextes die options-Anweisung zu verwenden.

z.B. options /wl=&1ff8 /wp=&1ffe /ws=1024

Nach dem Übersetzen mit TBC.COM kann nun TBCPTCH.COM mit folgender Syntax aufgerufen werden:

TBCPTCH file[.COM] [file2]

Dabei ist file der Name (ggf. mit Pfad) des zu patchenden Programms. Fehlt die Extension, so wird als Standard COM angenommen. Das optionale Argument file2 bezeichnet den Namen der Ausgabedatei. Ist das Argument angegeben, so wird eine Kopie von file angelegt und der Patch darauf ausgeführt; fehlt es, wird file selbst modifiziert. TBCPTCH erkennt den Dateityp an der Extension. Lautet sie „EXE“, wird eine EXE-Datei angenommen, andernfalls eine Datei im COM-Format.

Achtung: Der Patch bewirkt, dass man Programme auch bei weniger als 69K freiem Speicher starten kann. Falls in einem Programm mit DIMX definierte (erweiterte) Arrays verwendet werden, ist dies allerdings keine Garantie dafür, dass es auch läuft. Der Grund: Solche Felder werden oberhalb des Stacks angelegt und bei der Prüfung des freien Speichers beim Programmstart nicht berücksichtigt. Auf der sicheren Seite ist man also nur, wenn man keine DIMX-Felder verwendet oder weiß, dass der Speicher trotzdem reicht ;-).

Speicherbereich zur Laufzeit verkleinern

Sowohl die EXE- als auch die COM-Versionen (die sowieso) der mit TBC erzeugten Programme belegen beim Start den größtmöglichen Speicherblock (was oft dem gesamten freien Speicher entspricht). Die Folge davon ist, dass man weder die Möglichkeit hat, vom System weiteren Speicher dynamisch anzufordern noch weitere Programme als Kindprozesse zu starten. Weil im Normalfall aber nicht der gesamte Speicher benötigt wird, kann man den Speicherblock des Programms zur Laufzeit verkleinern.

Dabei ist der Ablauf folgender:

  1. ermittle die Adresse des eigenen PSP (= Startadresse des Speicherblocks)
  2. ermittle die höchstmögliche verwendete Adresse (Ende des als letztes definierten DIMX-Feldes)
  3. rechne die Gesamtgröße in Paragraphen aus
  4. verkleinere den Speicherbereich mit der DOS-Funktion 4AH (Set Block)

Da die Größe von Arrays leider nirgends abfragbar ist, bietet es sich an, zum Bestimmen der Endadresse mit DIMX ein Dummy-Feld anzulegen, das hinter allen anderen Feldern definiert wird. Seine Startadresse entspricht damit der Adresse des ersten freien Segments hinter dem Programm und die Blockgröße in Paragraphen ist einfach diese Adresse, vermindert um die PSP-Segmentadresse.

Weil der beschriebene Ablauf eigentlich immer gleich ist, gibt es in der erweiterten Distribution eine kleine Bibliothek, die man einfach mit MERGE hinter der letzten Felddefinition ins Programm einfügt und die dann die Verkleinerung automatisch erledigt. Ein Beispiel für die Verwendung findet sich im schon erwähnten Testprogramm test31.bas.

Bibliotheken

Tokiwa-Basic unterstützt mit der MERGE-Anweisung das Einbinden von Quelltextbibliotheken in ein Programm. Das erlaubt es grundsätzlich, wiederverwendbare Programmteile (typischerweise Unterprogramme und Funktionen) zu erstellen und bei Bedarf darauf zurückzugreifen.
Mit Hilfe von Bibliotheken lassen sich vor allem auch wichtige Funktionen „nachrüsten“, für die keine Standardfunktionen vorhanden sind.

Eine wesentliche Einschränkung ergibt sich allerdings daraus, dass die MERGE-Anweisung keine verschachtelten Bibliotheken zulässt (MERGE darf nicht in einer Bibliothek verwendet werden), was es z.B. unmöglich macht, an zentraler Stelle Konstantendefinitionen zusammenzufassen. Wenn Bibliotheken voneinander abhängen, lässt sich dies nicht im Quellcode ausdrücken - vielmehr muss man es wissen bzw. entsprechend dokumentieren. Wenn - wie bei unserem Pofo - der Platz recht knapp ist, kann es außerdem ein Problem darstellen, dass mit dem Einbinden einer Bibliothek deren gesamter Inhalt mit ins Programm aufgenommen wird - auch wenn man womöglich nur eine einzige Funktion aufruft. Deshalb kann es in manchen Fällen von Vorteil sein, nur einzelne Abschnitte aus einer Bibliothek direkt ins Programm hinein zu kopieren, anstatt die Bibliothek mit MERGE einzubinden.

Nachfolgend wird - ohne Anspruch auf Vollständigkeit - der Inhalt der einzelnen Bibliotheken als Kurzreferenz dargestellt. Diese Referenz soll bei der Verwendung helfen, ist aber keine umfassende Dokumentation. Es empfiehlt sich also in jedem Fall, auch die Kommentare in den Bibliotheken selbst und ggf. deren Quellen zu lesen.

Weil bei Tokiwa-Basic benutzerdefinierte Funktionen, die einen Integer-Wert zurückliefern, über das Schlüsselwort SUBROUTINE beschrieben werden, ist die Unterscheidung zwischen Unterprogrammen und Funktionen etwas verwirrend. Nachfolgend wird die Unterscheidung so vorgenommen, dass Unterprogramme keinen Rückgabewert haben (entsprechend etwa Prozeduren in Pascal), während Funktionen einen Wert zurückgeben.

Bibliothek CONTIME.LIB

Diese Bibliothek gehört zur Original-Distribution von Tokiwa-Basic und beinhaltet eine etwas eigenartige Mischung von Funktionen zur Konsoleneingabe, Lesen von Datum und Uhrzeit sowie Zeichenkettenbehandlung.

Enthaltene Unterprogramme/Funktionen:

conin

Die Funktion liest ein einzelnes Zeichen von der Konsole. Ein Bildschirmecho erfolgt dabei nicht. Ist kein Zeichen im Tastaturpuffer, so wird auf die Eingabe eines Zeichens gewartet.

Argumente: keine
Rückgabewert: ASCII-Code des gelesenen Zeichens

up_conin

Fie Funktion verhält sich wie conin, eingegebene Buchstaben werden jedoch in Großbuchstaben umgewandelt.

Argumente: keine
Rückgabewert: ASCII-Code des gelesenen Zeichens

to_upper(str)

Das Unterprogramm wandelt alle Kleinbuchstaben der übergebenen Zeichenkette in Großbuchstaben um.

Argument: zu modifizierende Zeichenkette
Rückgabewert: keiner

time

Das Unterprogramm trägt in die globale Variable time$ die aktuelle Uhrzeit in der Form hh:mm:ss ein.

Argumente: keine
Rückgabewert: keiner

Nach dem Aufruf steht die Uhrzeit in der Variablen time$.
Achtung: Ein Programm, das das Unterprogramm verwendet, sollte selbst keine Variable time$ zu einem anderen Zweck anlegen.

date

Das Unterprogramm trägt in die globale Variable date$ die aktuelle Uhrzeit in der Form yy-mm-dd ein.

Argumente: keine
Rückgabewert: keiner

Nach dem Aufruf steht das Datum in der Variablen date$.
Achtung: Ein Programm, das das Unterprogramm verwendet, sollte selbt keine Variable date$ zu einem anderen Zweck anlegen.

Bibliothek MSHRINK.LTB

Diese Bibliothek stellt keine Funktionen im eigentlichen Sinne bereit. Ihre Aufgabe besteht darin, den vom aktuellen Programm belegten Speicher auf die tatsächlich benötigte Größe zu beschränken, um so die dynamische Anforderung von Speicher zu ermöglichen. Dazu muss MSHRINK.LTB hinter dem letzten mit dimx definierten erweiterten Feld (oder am Programmstart, falls es kein solches Feld gibt, eingebunden werden.

Mit dem Einbinden von MSHRINK.LTB sind außerdem folgende globale Variablen definiert:

  • integer psp__seg : Segmentadresse des eigenen PSP
  • integer nxt__mcb : Segmentadresse des MCB für den nächsten Speicherbereich hinter dem Programm
  • integer my__size : Größe des vom Programm belegten Speicherblocks in Paragraphen

Bibliothek ALLOC.LTB

Die Bibliothek stellt Funktionen zur dynamischen Speicheranforderung über DOS-Systemaufrufe bereit.

Da Tokiwa-Basic-Programme standardmäßig den gesamten verfügbaren Speicher belegen, ist die Verwendung dynamischen Speichers nur dann möglich, wenn der belegte Speicher vorher (mit Hilfe der Bibliothek MSHRING.LTB) redutiert wurde.

Alle Funktionen dieser Bibliothek legen im Falle eines Ausführungsfehlers den DOS-Fehlercode in der globalen (Integer-) Variablen ALLOC_ERROR ab.

Darüber hinaus werden folgende Konstanten definiert:

  • DOS-Funktionen
    • _dos_malloc &48 (allocate memory block)
    • _dos_mfree &49 (free memory block)
    • _dos_mresize &4A (resize memory block)
    • _dos_setmstrat &5801 (set memory strategy)
    • _dos_getmstrat &5800 (get memory strategy)
  • Strategie-Konstanten für _dos_setmstrat
    • _mstrat_first 0 (allocate first block available)
    • _mstrat_best 1 (allocate best sized menory block)
    • _mstrat_last 2 (allocate last block available)

Enthaltene Unterprogramme/Funktionen:

allocMem(parSize)

Die Funktion fordert einen Speicherbereich der angegebenen Größe vom System an.

Argument: Größe des Speicherbereichs in Paragraphen
Rückgabewert: Segmentadresse des Bereichs bei Erfolg, sonst 0

Hinweis: Ein mit allocMem angelegter Speicherbereich sollte stets mit freeMem wieder freigegeben werden.

freeMem(handle)

Die Funktion gibt einen mit allocMem angeforderten Speicherbereich wieder frei.

Argument: Handle (Segmentadresse) des freizugebenden Speicherbereichs
Rückgabewert: 0 bei Erfolg, sonst Fehlernummer

resizeMem(handle, parSize)

Die Funktion ändert die Größe eines mit allocMem angelegten Speicherbereichs.

Argumente:

  • handle: Handle (Segmentadresse) des Speicherbereichs
  • parSize: neue Größe in Paragraphen

Rückgabewert: 0 bei Erfolg, sonst Fehlernummer

getMemAvail

Die Funktion ermittelt die Größe des größten noch freien Speicherbereichs.

Argumente: keine

Rückgabewert: Größe des größten freien Speicherblocks in Paragraphen

getAllocStrategy

Die Funktion gibt die aktuelle Einstellung für die Strategie der Speichervergabe zurück.

Argumente: keine

Rückgabewert: Speichervergabe-Strategie (_mstrat_first, _mstrat_best oder _mstrat_last)

setAllocStrategy(strategy)

Das Unterprogramm legt die Einstellung für die Strategie der Speichervergabe fest.

Argument: Speichervergabe-Strategie (_mstrat_first, _mstrat_best oder _mstrat_last)

Rückgabewert: keiner

Bibliothek STRINGS.LTB

Die Bibliothek enthält eine Reihe von Funktionen zur erweiterten und schnelleren Verarbeitung von Zeichenketten.

Enthaltene Unterprogramme/Funktionen:

getCmdLine(resloc)

Die Funktion speichert die Kommandozeile (Programmpfad mit übergebenen Argumenten) in einer String-Variablen.

Argument: Adresse der Puffervariablen, in der die Kommandozeile abgelegt werden soll.

Rückgabewert: Offset-Adresse des ersten Zeichens in der Puffervariablen

Hinweise:

  • Der Ergebnispuffer (adressiert durch resloc) muss eine String-Variable im Datensegment sein, deren Adresse sich mit Hilfe der LOC-Funktion bestimmen lässt.
  • Der Rückgabewert kann direkt an die strTok-Funktion als Argument str übergeben werden.

memCpy(dest,src,nbytes)

Die Funktion kopiert einen Datenbereich im Speicher unter Nutzung von NEAR-Adressen.

Argumente:

  • dest: Adresse des Zielpuffers
  • osrc: Adresse der Datenquelle
  • nbytes: Länge des zu kopierenden Speicherbereichs in Bytes

Rückgabewert: Adresse des Zielpuffers

Hinweise:

  • Sowohl der Zielpuffer als auch die Datenquelle müssen vollständig im Datensegment liegen.
  • Der Zielpuffer muss mindestens eine Kapazität von nbytes Bytes haben.
  • Ein Überlappen der Bereiche von Quelle und Zielpuffer ist zulässig, wenn die Zieladresse unterhalb der Quelladresse liegt - nicht umgekehrt!
  • Das nbytes-Argument wird als vorzeichenloser Integer-Wert interpretiert.
  • Achtung: Es wird keine Überprüfung auf Offset-Überlauf durchgeführt!

memCpyFar(odest,sdest,osrc,ssrc,nbytes)

Die Funktion kopiert einen Datenbereich im Speicher unter Nutzung von FAR-Adressen.

Argumente:

  • odest: Offset-Adresse des Zielpuffers
  • sdest: Segment-Adresse des Zielpuffers
  • osrc: Offset-Adresse der Datenquelle
  • ssrc: Segment-Adresse der Datenquelle
  • nbytes: Länge des zu kopierenden Speicherbereichs in Bytes

Rückgabewert: Offset-Adresse des Zielpuffers; die Segment-Adresse wird im Register DX abgelegt

Hinweise:

  • Der Zielpuffer muss mindestens eine Kapazität von nbytes Bytes haben.
  • Ein Überlappen der Bereiche von Quelle und Zielpuffer ist zulässig, wenn die Zieladresse unterhalb der Quelladresse liegt - nicht umgekehrt!
  • Das nbytes-Argument wird als vorzeichenloser Integer-Wert interpretiert, es können also theoretisch bis zu 64 KBytes auf einmal kopiert werden.
  • Achtung: Es wird weder eine Normalisierung der Zeiger noch eine Überprüfung auf Offset-Überlauf durchgeführt!

strChrPos(str, c)

Die Funktion ermittelt die Position eines Zeichens innerhalb einer Zeichenkette.

Argumente:

  • str: Zeichenkette, in der nach einem Zeichen gesucht werden soll
  • c: Zeichen, nach dem gesucht werden soll

Rückgabewert: Position des ersten Auftretens des Zeichens in str; -1, wenn das Zeichen nicht gefunden wurde

strCmp(str1,str2)

Die Funktion führt einen byteweisen Vergleich zweier Zeichenketten durch.

Argumente:

  • str1: linker Operand
  • str2: rechter Operand

Rückgabewert: -1 für str1 < str2, 1 für str1 > str2, 0 für str1 = str2

strDelete(str, pos, length)

Die Funktion löscht Zeichen aus einer Zeichenkette.

Argumente:

  • str: Zeichenkette, aus der Zeichen gelöscht werden sollen
  • pos: Indexposition des ersten zu löschenden Zeichens
  • length: maximale Anzahl zu löschender Zeichen

Rückgabewert: Anzahl tatsächlich gelöschter Zeichen

Hinweise:

  • Bei einem negativen Wert von length werden alle Zeichen ab pos bis zum Ende gelöscht.
  • Das Löschen erfolgt „in place“, d.h. es wird kein neuer String erzeugt, sondern die übergebene Zeichenkette selbst modifiziert.

strDeleteChr(str, chr, pos, length)

Die Funktion löscht alle Vorkommen des angegebenen Zeichens aus einer Zeichenkette oder Teilzeichenkette.

Argumente:

  • str: Zeichenkette, aus der Zeichen gelöscht werden sollen
  • chr: Zeichencode (integer) des Zeichens, das gelöscht werden soll
  • pos: Start-Indexposition des Bereichs, in dem das Zeichen gelöscht werden soll
  • length: Maximallänge des Bereichs, in dem das Zeichen gelöscht werden soll

Rückgabewert: Anzahl tatsächlich gelöschter Zeichen

Hinweise:

  • Bei einem negativen Wert von length reicht der Löschbereich von pos bis zum Ende der Zeichenkette.
  • Das Löschen erfolgt „in place“, d.h. es wird kein neuer String erzeugt, sondern die übergebene Zeichenkette selbst modifiziert.

strInsert(str,pos,insertion)

Die Funktion fügt eine Zeichenkette an der angegebenen Position in eine andere Zeichenkette ein.

Argumente:

  • str: Adresse der String-Variablen, die als Ziel der Einfügeoperation dient
  • pos: Indexposition, an der die Einfügung vorgenommen werden soll
  • insertion: einzufügende Zeichenkette

Rückgabewert: Adresse des ersten Zeichens der Ziel-Zeichenkette nach dem Einfügen

Hinweise:

  • Die Adresse der Ziel-Zeichenkette (Argument str) kann mit der LOC-Funktion ermittelt werden.
  • Wenn der Wert von pos kleiner als Null ist oder die Länge von str übersteigt, wird insertion an das Ende von str angehängt.

strLen(str)

Die Funktion bestimmt die Länge der übergebenen Zeichenkette.

Argument: Zeichenkette, deren Länge werden soll

Rückgabewert: Anzahl der Zeichen in str

Hinweis: Die Funktion verhält sich wie die Standardfunktion LEN, akzeptiert jedoch als Argument statt einer Stringvariablen oder -konstanten auch einen Integer-Wert, der den Offset des ersten Zeichens eines Strings im Datensegment angibt.

strLower(str)

Das Unterprogramm wandelt alle Großbuchstaben (A-Z) der übergebenen Zeichenkette in Kleinbuchstaben um.

Argument: Zeichenkette, die modifiziert werden soll.

Rückgabewert: keiner

Hinweis: Die Umwandlung erfolgt „in place“, d.h. es wird kein neuer String erzeugt, sondern die übergebene Zeichenkette selbst modifiziert.

strReplace(strloc,search,rep)

Die Funktion ersetzt alle Vorkommen einer Teilzeichenkette durch eine andere Zeichenkette.

Argumente:

  • strloc: Adresse der String-Variablen, die als Ziel der Operation dient
  • search: zu ersetzende Teilzeichenkette
  • rep: Ersatzzeichenkette

Rückgabewert: Anzahl der durchgeführten Ersetzungen

Hinweise:

  • Die Adresse der Ziel-Zeichenkette (Argument strloc) kann mit der LOC-Funktion ermittelt werden.
  • Wenn die Länge von rep nicht größer ist als die von search, so wird die Ersetzung „in place“ durchgeführt.

strReplaceChr(str,search,rep)

Die Funktion ersetzt alle Vorkommen eines Zeichens innerhalb einer Zeichenkette durch ein anderes Zeichen.

Argumente:

  • str: Zeichenkette, die modifiziert werden soll
  • search: Zeichencode des zu ersetzenden Zeichens (integer)
  • rep: Zeichencode des Ersatzzeichens (integer)

Rückgabewert: Anzahl der durchgeführten Ersetzungen

Hinweis: Das Ersetzen erfolgt „in place“, d.h. es wird kein neuer String erzeugt, sondern die übergebene Zeichenkette selbst modifiziert.

Die Funktion sucht innerhalb einer Zeichenkette nach einer Teilzeichenkette.

Argumente:

  • str: Zeichenkette, in der gesucht werden soll
  • search: zu suchende Teilzeichenkette

Rückgabewert: Position von search in str bei Erfolg, sonst -1

strTok(str,resloc,delimit)

Die Funktion erlaubt das schrittweise Zerlegen einer Zeichenkette in Token. Dazu wird die Zeichenkette nach dem ersten Vorkommen eines Trennzeichens durchsucht. Enthält sie ein Trennzeichen, wird die Teilzeichenkette vor dem Trennzeichen im Ergebnispuffer abgelegt; ist kein Trennzeichen enthalten, wird als Ergebnis die ganze Zeichenkette (als einzelnes Token gespeichert. Argumente:

  • str: Zeichenkette, die zerlegt werden soll
  • resloc: Adresse der Puffervariablen, in der das Ergebnis-Token abgelegt werden soll
  • delimit: Liste der zum Zerlegen verwendeten Trennzeichen (als Zeichenkette)

Rückgabewert:
Startadresse des hinter dem gefundenen Trennzeichen verleibenden Restes der Zeichen, falls ein Trennzeichen gefunden wurde; andernfalls 0.

Hinweise:

  • Der Ergebnispuffer (adressiert durch resloc) muss eine String-Variable im Datensegment sein.
  • Wenn der Rückgabewert der Funktion nicht 0 ist, so kann dieser Wert als Argument str für einen nachfolgenden Aufruf der Funktion verwendet werden, um ein weiters Token abzuspalten.

Beispiel:

txt$ = "This text consists of multiple words."  
buf$ = ""
delimit$ = " ."
integer s, bloc
bloc = loc(buf$);
s = call_StrTok(txt$,bloc,delimit$)
while s <> 0
  print buf$
  s = call_StrTok(s,bloc,delimit$)
wend
end

strUpper(str)

Das Unterprogramm wandelt alle Kleinbuchstaben (a-z) der übergebenen Zeichenkette in Großbuchstaben um.

Argument: Zeichenkette, die modifiziert werden soll.

Rückgabewert: keiner

Hinweis: Die Umwandlung erfolgt „in place“, d.h. es wird kein neuer String erzeugt, sondern die übergebene Zeichenkette selbst modifiziert.

Bibliothek FILES.LTB

Diese Bibliothek stellt zusätzliche Funktionen zum Umgang mit Binärdateien bereit, wobei Handle-basierte DOS-Aufrufe verwendet werden.

Alle Funktionen dieser Bibliothek legen im Falle eines Ausführungsfehlers den DOS-Fehlercode in der globalen (Integer-) Variablen FILE_ERROR ab.

Die Funktionen fseek und fseek_f belegen außerdem eine globale Variable seek_pos mit der Dateiposition. Diese Position ist 32 Bit breit und wird auf ein zweielementiges Integer-Feld abgebildet. Dabei beinhaltet seek_pos(0) den niederwertigen und seek_pos(1) den höherwertigen Teil des Wertes. Darüber hinaus werden folgende Konstanten definiert:

  • Dateiattribute (Bitflags, OR-kombinierbar)
    • _fattr_r 1 (read only)
    • _fattr_h 2 (hidden)
    • _fattr_s 4 (system)
    • _fattr_l 8 (volume label)
    • _fattr_a 16 (archive flag)
  • Datei-Fehlercodes
    • _fsuccess 0
    • _ferr_invalid_func 1
    • _ferr_no_file 2
    • _ferr_no_path 3
    • _ferr_no_handle 4
    • _ferr_acc_denied 5
    • _ferr_inv_handle 6
  • Modi zum Öffnen einer Datei
    • _fopen_r 0 (open for read)
    • _fopen_w 1 (open for write)
    • _fopen_rw 2 (open for read and write)
    • _ fopen_a 3 (open for append)
  • Modi für Seek-Funktionen
    • _fseek_start 0 (seek from start)
    • _fseek_rel 1 (seek relative to current position)
    • _fseek_end 2 (seek from end)
  • DOS-Funktionsnummern
    • _dos_fcreate &3c (create file)
    • _dos_fopen &3d (open file or device)
    • _dos_fclose &3e (close file)
    • _dos_fread &3f (read from file/device)
    • _dos_fwrite &40 (write to file/device)
    • _dos_fseek &42 (file seek)

Enthaltene Unterprogramme/Funktionen

fopen(fileName, mode)

Die Funktion öffnet eine Datei oder ein Gerät (Zeichentreiber).

Argumente:

  • fileName: Name (ggf. mit Pfad) der zu öffnenden Datei
  • mode: Modus, in dem die Datei geöffnet werden soll (_fopen_r, _fopen_rw, _fopen_w oder _fopen_a)

Rückgabewert: Bei Erfolg Datei-Handle (Kanalnummer), sonst -1.

Hinweis: Eine mit fopen geöffnete Datei sollte stets mit fclose explizit geschlossen werden.

fcreate(fileName, attributes)

Die Funktion legt eine neue Datei an oder schneidet eine bereits existierende auf die Länge Null ab.

Argumente:

  • fileName: Name (ggf. mit Pfad) der anzulegenden Datei
  • attributes: Bitmaske als OR-Verknüpfung der Dateiattribute (_fattr_?)

Rückgabewert: 0 bei Erfolg, sonst Fehlercode

Hinweise:

  • Die Funktion kann nicht mit dem Attribut _fattr_l (Volume Label) verwendet werden.
  • Die Anwendung auf eine existierende schreibgeschützte Datei führt zu einem Fehler.
  • Nach erfolgreicher Ausführung ist die angelegte Datei geschlossen und muss mit fopen für den Zugriff explizit geöffnet werden.

fclose(fhandle)

Die Funktion schließt eine zuvor mit fopen geöffnete Datei.

Argument: Handle (Kanalnummer) der zu schließenden Datei.

Rückgabewert: 0 bei Erfolg, sonst Fehlercode

fread_f(fhandle, nbytes, bufoffs, bufseg)

Die Funktion liest Daten aus einer geöffneten (Binär-)Datei in einen per FAR-Zeiger adressierten Puffer.

Argumente:

  • fhandle: Handle (Kanalnummer) einer geöffneten Datei oder eines Geräts
  • nbytes: maximale Anzahl der zu lesenden Bytes
  • bufoffs: Offset-Adresse des Datenpuffers
  • bufseg: Segment-Adresse des Datenpuffers

Rückgabewert: Anzahl der gelesenen Bytes (0 bei Fehler)

Hinweise:

  • nbytes wird als vorzeichenloser Integer-Wert repräsentiert. Somit können theoretisch Datenblöcke bis zu 64 KBytes gelesen werden.
  • Auch der Rückgabewert ist streng genommen vorzeichenlos. Bei Blockgrößen über 32 KBytes sollte er deshalb nicht als negativer Wert fehlinterpretiert werden.
  • Das aufrufende Programm ist dafür verantwortlich, einen hinreichend großen Datenpuffer bereitzustellen. Die Funktion selbst kann dessen tatsächliche Größe nicht überprüfen und überschreibt schlimmstenfalls andere Speicherbereiche.
  • Die Funktion schließt die Datei nach Ausführung nicht, sondern verschiebt lediglich deren internen Datenzeiger um die Anzahl der gelesenen Bytes. Sie kann also mehrfach hintereinander aufgerufen werden, um den Inhalt einer Datei stückweise zu lesen. Das Dateiende ist erreicht (die Datei vollständig gelesen), wenn der Rückgabewert kleiner als nbytes ist.

fread(fhandle, nbytes, buf)

Die Funktion liest Daten aus einer geöffneten (Binär-)Datei in einen per NEAR-Zeiger adressierten Puffer innerhalb des Datensegments.

Argumente:

  • fhandle: Handle (Kanalnummer) einer geöffneten Datei oder eines Geräts
  • nbytes: maximale Anzahl der zu lesenden Bytes
  • buf: Adresse des Datenpuffers

Rückgabewert: Anzahl der gelesenen Bytes (0 bei Fehler)

Hinweise:

  • nbytes wird als vorzeichenloser Integer-Wert repräsentiert. Somit können theoretisch Datenblöcke von mehr als 32 KBytes gelesen werden.
  • Auch der Rückgabewert ist streng genommen vorzeichenlos. Bei Blockgrößen über 32 KBytes sollte er deshalb nicht als negativer Wert fehlinterpretiert werden.
  • Das aufrufende Programm ist dafür verantwortlich, einen hinreichend großen Datenpuffer bereitzustellen. Die Funktion selbst kann dessen tatsächliche Größe nicht überprüfen und überschreibt schlimmstenfalls andere Speicherbereiche.
  • Die Funktion schließt die Datei nach Ausführung nicht, sondern verschiebt lediglich deren internen Datenzeiger um die Anzahl der gelesenen Bytes. Sie kann also mehrfach hintereinander aufgerufen werden, um den Inhalt einer Datei stückweise zu lesen. Das Dateiende ist erreicht (die Datei vollständig gelesen), wenn der Rückgabewert kleiner als nbytes ist.

fwrite_f(fhandle,nbytes,bufoffs,bufseg)

Die Funktion schreibt Daten aus einem per FAR-Zeiger adressierten Puffer in eine geöffnete (Binär-)Datei.

Argumente:

  • fhandle: Handle (Kanalnummer) einer geöffneten Datei oder eines Geräts
  • nbytes: maximale Anzahl der zu schreibenden Bytes
  • bufoffs: Offset-Adresse des Datenpuffers
  • bufseg: Segment-Adresse des Datenpuffers

Rückgabewert: Anzahl der geschriebenen Bytes (0 bei Fehler)

Hinweise:

  • nbytes wird als vorzeichenloser Integer-Wert repräsentiert. Somit können theoretisch Datenblöcke bis zu 64 KBytes geschrieben werden.
  • Auch der Rückgabewert ist streng genommen vorzeichenlos. Bei Blockgrößen über 32 KBytes sollte er deshalb nicht als negativer Wert fehlinterpretiert werden.
  • Die Funktion schließt die Datei nach Ausführung nicht, sondern verschiebt lediglich deren internen Datenzeiger um die Anzahl der geschriebenen Bytes. Sie kann also mehrfach hintereinander aufgerufen werden, um den Inhalt einer Datei stückweise zu schreiben.

fwrite(fhandle,nbytes,buf)

Die Funktion schreibt Daten aus einem per NEAR-Zeiger adressierten Puffer in eine geöffnete (Binär-)Datei.

Argumente:

  • fhandle: Handle (Kanalnummer) einer geöffneten Datei oder eines Geräts
  • nbytes: maximale Anzahl der zu schreibenden Bytes
  • buf: Adresse des Datenpuffers (Offset im Datensegment)

Rückgabewert: Anzahl der geschriebenen Bytes (0 bei Fehler)

Hinweise:

  • nbytes wird als vorzeichenloser Integer-Wert repräsentiert. Somit können theoretisch Datenblöcke von mehr als 32 KBytes geschrieben werden.
  • Auch der Rückgabewert ist streng genommen vorzeichenlos. Bei Blockgrößen über 32 KBytes sollte er deshalb nicht als negativer Wert fehlinterpretiert werden.
  • Die Funktion schließt die Datei nach Ausführung nicht, sondern verschiebt lediglich deren internen Datenzeiger um die Anzahl der geschriebenen Bytes. Sie kann also mehrfach hintereinander aufgerufen werden, um den Inhalt einer Datei stückweise zu schreiben.

fseek(fhandle,smode,offset)

Die Funktion ändert die Lese- bzw. Schreibposition in einer göffneten Datei.

Argumente:

  • fhandle: Handle (Kanalnummer) einer geöffneten Datei
  • smode: Modus
    • _fseek_start - Positionierung relativ zum Dateianfang
    • _fseek_rel - Positionierung relativ zur aktuellen Position
    • _fseek_end - Positionierung relativ zum Dateiende
  • offset: Anzahl von Bytes, um die die Position geändert werden soll

Rückgebewert: 0 bei Erfolg, sonst Fehlercode

Hinweise:

  • Der Wert von offset ist ein vorzeichenbehafteter Integer. Somit kann man die Position um maximal 32K ändern.
  • Im Modus _fseek_end wird die Position vom Dateiende um offset Bytes in Richtung Dateianfang verschoben. In den anderen Modi erfolgt die Verschiebung in Richtung Dateiende (bei einem positiven Offset, sonst umgekehrt).
  • Es erfolgt keine Prüfung, ob die Position über die Dateigrenze hinaus verschoben wird. Bei einer Verschiebung vor den Dateianfang können bei nachfolgenden Schreibzugriffen Fehler in der Dateistruktur entstehen. Bei einer Verschiebung hinter das Dateiende wird die Datei vergrößert und es entsteht ein Bereich, der mit zufälligem Inhalt gefüllt ist.
  • Wird offset=0 angegeben, so bewirkt
    • smode=_fseek_start eine Positionierung auf den Dateianfang,
    • smode=_fseek_end eine Positionierung auf das Dateiende und
    • smode=_fseek_rel keine Positionsänderung.
  • Bei erfolgreicher Ausführung wird die aktuelle Dateiposition in der globalen Variablen seek_pos abgelegt, wobei seek_pos(0) den niederwertigen und seek_pos(1) den höherwertigen Teil enthält (die Dateiposition ist ein 32-Bit-Integer). Somit kann man die Angabe von offset=0 auch nutzen, um die aktuelle Position (mit smode=_fseek_rel) bzw. die Dateilänge (mit smode=_fseek_end) zu ermitteln.

fseek_f(fhandle,smode,offslow,offshigh)

Die Funktion ändert die Lese- bzw. Schreibposition in einer göffneten Datei, wobei ein 32-Bit-Offset verwendet wird.

Argumente:

  • fhandle: Handle (Kanalnummer) einer geöffneten Datei
  • smode: Modus
    • _fseek_start - Positionierung relativ zum Dateianfang
    • _fseek_rel - Positionierung relativ zur aktuellen Position
    • _fseek_end - Positionierung relativ zum Dateiende
  • offslow: Anzahl von Bytes, um die die Position geändert werden soll (niederwertiger Teil)
  • offshigh: Anzahl von Bytes, um die die Position geändert werden soll (höherwertiger Teil)

Rückgebewert: 0 bei Erfolg, sonst Fehlercode

Hinweise:

  • Die Offset-Wert ist ein vorzeichenbehafteter 32-Bit-Integer. Somit kann man die Positionsverschiebunf theoretisch maximal +/-2^31 betragen. Weil Tokiwa-Basic keinen integralen 32-Bit-Integer kennt, ist eine Aufteilung auf zwei Argumente nötig.
  • Bis auf den größeren möglichen Offset entspricht das Verhalten der Funktion dem für fseek beschriebenen.

Bibliothek DIRS.LTB

Diese Bibliothek stellt Unterprogramme und Funktionen für DOS-basierte Dateisystem- und Verzeichnisoperationen zur Verfügung.

Für die Datei-Suchfunktionen wird eine globale Puffervariable dos_s_rec von 44 Bytes Länge angelegt.
Außerdem definiert die Bibliothek folgende globale Konstanten:

  • DOS-Funktionsnummern
    • _dos_set_drive &e (set current drive)
    • _dos_get_drive &19 (get current drive)
    • _dos_set_dta &1a (set DTA address)
    • _dos_get_dta &2f (get DTA address)
    • _dos_mkdir &39 (make directory)
    • _dos_rmdir &3a (remove directory)
    • _dos_chdir &3b (change directory)
    • _dos_del_file &41 (delete file)
    • _dos_get_dir &47 (get current directory)
    • _dos_find_first &4e (find first)
    • _dos_find_next &4f (find next)
    • _dos_get_attr &4300 (get file attributes)
    • _dos_set_attr &4301 (set file attributes)
    • _dos_rename_fd &56 (rename file or directory)
  • Fehlercodes (als Rückgebewerte von Funktionen)
    • _dsuccess 0 (kein Fehler)
    • _derr_no_file 2
    • _derr_no_path 3
    • _derr_acc_denied 5
    • _derr_inv_drive 15
    • _derr_cant_delete 16
    • _derr_cant_move 17
    • _derr_no_entries 18
  • Dateiattribute (Bitflags, OR-verknüpfbar)
    • _dfattr_r 1 (read only)
    • _dfattr_h 2 (hidden)
    • _dfattr_s 4 (system)
    • _dfattr_l 8 (volume label)
    • _dfattr_a 16 (archive flag)
  • Byte-Offsets der Elemente in dos_s_rec
    • _dos_srec_attr 21
    • _dos_srec_time 22
    • _dos_srec_date 24
    • _dos_srec_sizelo 26
    • _dos_srec_sizehi 28
    • _dos_srec_name 30
  • Dateiattribut-Flags zur Verwendung mit findFirst
    • _sattr_hidden 2
    • _sattr_system 4
    • _sattr_vlabel 8
    • _sattr_dir &10
    • _sattr_all &3f

Unterprogramme und Funktionen

setCurrentDrive(drv)

Die Funktion legt das aktive Laufwerk fest.

Argument: Laufwerk, das aktiv gesetzt werden soll (angegeben als Index oder Laufwerksbuchstabe)

Rückgabewert: aktives Laufwerk

Hinweise:

  • Der Argumenrwert ist eine Zahl (Laufwerksindex, wobei 0 für Laufwerk A, 1 für B usw. steht) oder ein Groß- bzw. Kleinbuchstabe (Laufwerksbuchstabe)
  • Der Rückgabewert ist eine Zahl, wenn als Argument ein Index (also ein Wert zwischen 0 und 25) angegeben wurde, oder ein Groß- bzw. Kleinbuchstabe, wenn das Argument als Buchstabe angegeben wurde.
  • Der Aufrufer kann den Erfolg der Operation prüfen, indem er den Rückgabewert mit dem übergebenen Argumentwert vergleicht.

getCurrentDrive

Die Funktion ermittelt das aktuell aktive Laufwerk.

Argumente: keine

Rückgabewert: aktives Laufwerk (als Großbuchstabe)

mkDir(path)

Die Funktion legt ein Verzeichnis entsprechend dem angegebenen Pfad an.

Argument: Name des anzulegenden Verzeichnisses (relativer oder absoluter Pfad)

Rückgabewert: 0 bei Erfolg, sonst Fehlercode

Hinweise:

  • Der als Argument übergebene Pfad kann absolut oder relativ zum aktuellen Verzeichnis angegeben werden.
  • Eine absolute Pfadangebe kann eine Laufwerksangabe enthalten, die nicht mit dem aktuellen (aktiven) Laufwerk übereinstimmen muss.
  • Es lässt sich (wie beim mkdir-Befehl von DOS) nur ein einzelnes Verzeichnis anlegen, d.h. alle übergeordneten Verzeichnisse müssen bereits existieren.

rmDir(path)

Die Funktion löscht ein (leeres) Verzeichnis.

Argument: Name des zu löschenden Verzeichnisses (relativer oder absoluter Pfad)

Rückgabewert: 0 bei Erfolg, sonst Fehlercode

Hinweise:

  • Der als Argument übergebene Pfad kann absolut oder relativ zum aktuellen Verzeichnis angegeben werden.
  • Eine absolute Pfadangebe kann eine Laufwerksangabe enthalten, die nicht mit dem aktuellen (aktiven) Laufwerk übereinstimmen muss.
  • Die Funktion kann (wie der rmdir-Befehl von DOS) nur einzelne Verzeichnisse, keine vollständigen Pfade löschen.
  • Das zu löschende Verzeichnis muss leer sein und darf nicht schreibgeschützt sein.

delFile(fpath)

Die Funktion löscht die angegebene Datei.

Argument: Name der zu löschenden Datei (relativer oder absoluter Pfad)

Rückgabewert: 0 bei Erfolg, sonst Fehlercode

Hinweise:

  • Der als Argument übergebene Pfad kann absolut oder relativ zum aktuellen Verzeichnis angegeben werden.
  • Eine absolute Pfadangebe kann eine Laufwerksangabe enthalten, die nicht mit dem aktuellen (aktiven) Laufwerk übereinstimmen muss.
  • Im Unterschied zum DOS-Befehl del kann nur eine einzelne Datei gelöscht wwrden; Wildchards (* oder ?) in der Pfadangabe sind nicht zulässig.
  • Die zu löschende Datei darf nicht schreibgeschützt und nicht geöffnet sein.

setCwd(path)

Die Funktion setzt das aktuelle Arbeitsverzeichnis.

Argument: Name des Verzeichnisses, das als Arbeitsverzeichnis gesetzt werden soll (relativer oder absoluter Verzeichnispfad)

Rückgabewert: 0 bei Erfolg, sonst Fehlercode

Hinweise:

  • Der als Argument übergebene Pfad kann absolut oder relativ zum aktuellen Verzeichnis angegeben werden.
  • Falls der Verzeichnispfad eine Laufwerksangabe enthält, wird auch das aktive Laufwerk entsprechend gesetzt.

getCwd(pathloc)

Die Funktion bestimmt das aktuelle Arbeitsverzeichnis.

Argument: Adresse der Puffervariablen (String), in der das aktuelle Arbeitsverzeichnis abgelegt werden soll.

Rückgabewert: 0 bei Erfolg, sonst Fehlercode

Hinweise:

  • Bei erfolgreicher Ausführung wird der vollständige Pfad des aktuellen Arbeitsverzeichnisses in der Puffervariablen abgelegt.
  • Als Parameter muss die Adresse (bestimmbar mit der LOC-Funktion) des Puffers angegeben werden.

setDTA(offs, seg)

Das Unterprogramm verlegt das DTA auf die angegebene Adresse.

Argumente:

  • offs: Offset-Adresse des DTA
  • seg: Segment-Adresse des DTA

Rückgabewert: keiner

Hinweis:
Das DTA (Disk Transfer Area) ist ein Pufferbereich, der von den „altem“ (CP/M-kompatiblen) DOS-Dateifunktionen sowie von den Suchfunktionen (find first / find next) verwendet wird. Standardmäßig befindet sich dieser Bereich ab Offset 80H im PSP und teilt sich damit den Speicherbereich mit den auf der Kommandozeile übergebenen Parametern. Das temporäre Verlegen dieses Bereichs kann sinnvoll sein, um beim Verwenden der genannten Funktionen die Parameter nicht zu überschreiben.
Die Funktionen findFirst und findNext dieser Bibliothek verlegen das DTA temporär und beeinträchtigen so die Kommandozeilenparameter nicht.

getDTA(locoffs, locseg)

Das Unterprogramm bestimmt die aktuell gesetzte DTA-Adresse.

Argumente:

  • locoffs: Adresse der Puffervariablen (Integer) für die Offset-Adresse des DTA
  • locseg: Adresse der Puffervariablen (Integer) für die Segment-Adresse des DTA

findFirst(pattern,attr,resloc)

Die Funktion sucht den ersten Verzeichniseintrag, der dem angegebenen Suchmuster entspricht.

Argumente:

  • pattern: Suchmuster (Zeichenkette); das Suchmuster kann eine relative oder absolute Pfadangabe (ggf. auch mit

Laufwerk) sowie im Dateinamens- und Erweiterungsteil die unter DOS üblichen Wildcards (* byw. ?) enthalten.

  • attr: Attribute für die Suche; OR-Kombination der _sattr_xx-Flags (siehe oben). Standardmäßig werden „normale“ Dateien gefunden, mit Hilfe der Flags lassen sich zusätzlich Verzeichnisse, Volume-Labels und versteckte Dateien in die Suche einbeziehen.
  • resloc: Adresse des Ergebnispuffers (Zeichenkettenvariable)

Rückgabewert: 0 bei Erfolg, sonst Fehlercode

Hinweise:

  • Der Ergebnispuffer (resloc) muss im Datensegment liegen, die Adresse kann mit der LOC-Funktion bestimmt werden.
  • Bei Erfolg (Rückgabewert 0, d.h. ein passender Eintrag wurde gefunden) wird der Eintragsname mit ggf. vorhandener Erweiterung, jedoch ohne Verzeichnispfad, in der durch resloc adressierten Variablen abgelegt.

findNext(resloc)

Die Funktion sucht den nächsten Verzeichniseintrag, der dem beim vorangegangenen Aufruf von findFirst angegebenen Suchmuster entspricht.

Argument: Adresse des Ergebnispuffers (Zeichenkettenvariable)

Rückgabewert: 0 bei Erfolg, sonst Fehlercode

Hinweise:

  • Der Ergebnispuffer (resloc) muss im Datensegment liegen, die Adresse kann mit der LOC-Funktion bestimmt werden.
  • Bei Erfolg (Rückgabewert 0, d.h. ein passender Eintrag wurde gefunden) wird der Eintragsname mit ggf. vorhandener Erweiterung,

jedoch ohne Verzeichnispfad, in der durch resloc adressierten Variablen abgelegt.

getFileSize

Die Funktion bestimmt die Größe der zuletzt mit findFirst bzw findNext gefundenen Datei.

Argumente: keine

Rückgabewert: Größe der Datei in Bytes

Hinweise:

  • Die Dateigröße wird aus der Pseudo-Struktur _dos_s_rec ausgelesen. Deshalb muss vor dem Aufruf der Funktion ein Aufruf von findFirst bzw. findNext erfolgt sein.
  • Weil der Rückgabewert vom Real-Typ ist, kann er wegen der begrenzten Genauigkeit der Zahldarstellung mit einem Fehler behaftet sein, falls die Dateigröße 1 GB überschreitet.

getFileAttr(fname)

Die Funktion bestimmt die Attribute einer Datei oder eines anderen Verzeichniseintrags.

Argument:
Name der Datei- bzw. des Eintrags, für die/den die Attribute bestimmt werden sollen. Der Name kann eine absolute oder relative Pfadangabe beinhalten.

Rückgabewert: Bitset der Attribute (OR-Kombination aus _sattr_xx-Flags)

Hinweis:
Im Falle eines Fehlers (z.B. wenn die Datei nicht existiert) ist der Rückgabewert größer als 255. Der um 256 verminderte Rückgabewert entspricht dann dem Fehlercode.

setFileAttr(fname,fattr)

Die Funktion legt die Attribute des angegebenen Verzeichniseintrags fest.

Argumente:

  • fname: Name der Datei- bzw. des Eintrags, für die/den die Attribute festgelegt werden sollen. Der Name kann eine absolute oder relative Pfadangabe beinhalten.
  • fattr: Bitset der Attribute (OR-Kombination aus _sattr_xx-Flags)

Rückgabewert: 0 bei Erfolg, sonst Fehlercode

Hinweise:

  • Das Setzen von Attributen ist nicht beliebig möglich. Welche Attribute gesetzt werden können, ist vom Typ des Verzeichniseintrags abhängig.
  • Vorsicht: Es ist mit dieser Funktion grundsätzlich möglich, Dateieinträge in Vezeichniseinträge umzuwandeln (und umgekehrt). Ein Anwendungsprogramm sollte dies abfangen, um Fehler im Dateisystem zu verhindern.

renDirEntry(name,newname)

Die Funktion benennt einen Verzeichniseintrag um.

Argumente:

  • name: Bisheriger Name des Verzeichniseintrags (ggf. einschließlich Pfadangabe)
  • newname: Neuer Name des Verzeichniseintrags (ggf. einschließlich Pfadangabe)

Rückgabewert: 0 bei Erfolg, sonst Fehlercode

Hinweis:
Die Funktion führt nur das Umbenennen eines Eintrags in der Verzeichnisstruktur durch, kein „echtes“ Kopieren oder Verschieben einer Datei. Deshalb dürfen name und newname nicht auf unterschiedliche Laufwerke verweisen.

software/diy/basic/tbc.txt · Zuletzt geändert: 02/04/2013 00:04 (Externe Bearbeitung)