PofoWiki

Die ultimative Informationsquelle zum ATARI Portfolio

Benutzer-Werkzeuge

Webseiten-Werkzeuge


software:diy:basic:tbc

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
software:diy:basic:tbc [03/03/2013 21:03] – Korrektur ebertsoftware:diy:basic:tbc [Unbekanntes Datum] (aktuell) – Externe Bearbeitung (Unbekanntes Datum) 127.0.0.1
Zeile 12: Zeile 12:
 Inzwischen existiert auch eine deutschsprachige Version des Handbuchs, die eine Übersetzung der englischen Version  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 [[http://www.kiezsoft.de/download/tbc_de.pdf|HIER]] abrufbar. mit einer Reihe von Ergänzungen und erklärenden Anmerkungen darstellt. Sie ist [[http://www.kiezsoft.de/download/tbc_de.pdf|HIER]] abrufbar.
 +
  
 ===== Besonderheiten von Tokiwa-Basic ===== ===== Besonderheiten von Tokiwa-Basic =====
Zeile 18: Zeile 19:
 Tokiwa-Basic nimmt sich (so der Autor) Standard-Basic als Ausgangspunkt und erweitert es um nützliche Eigenschaften: Tokiwa-Basic nimmt sich (so der Autor) Standard-Basic als Ausgangspunkt und erweitert es um nützliche Eigenschaften:
   * keine Angabe von Zeilennummern notwendig   * keine Angabe von Zeilennummern notwendig
-  * explizit destlegbare Datentypen für Variablen (integer, real, character) +  * explizit festlegbare Datentypen für Variablen (integer, real, character) 
-  * erweiterte Arrays (mir DIMX definierbar)+  * erweiterte Arrays (mit DIMX definierbar)
   * benutzerdefinierte benannte Unterprogramme und Funktionen mit formalen Parameterlisten   * benutzerdefinierte benannte Unterprogramme und Funktionen mit formalen Parameterlisten
   * lokale Variablen in Unterprogrammen und Funktionen   * lokale Variablen in Unterprogrammen und Funktionen
Zeile 152: Zeile 153:
  Programm einfügt und die dann die Verkleinerung automatisch erledigt.  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.  Ein Beispiel für die Verwendung findet sich im schon erwähnten Testprogramm test31.bas.
 +
  
  
Zeile 161: Zeile 163:
  
 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. 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 wen 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 in Programm hinein zu kopieren, anstatt die Bibliothek mit MERGE einzubinden.+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. 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 uber 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//.+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 ==== ==== Bibliothek CONTIME.LIB ====
Zeile 202: Zeile 204:
  
 Nach dem Aufruf steht die Uhrzeit in der Variablen time$.\\ Nach dem Aufruf steht die Uhrzeit in der Variablen time$.\\
-**Achtung:** Ein Programm, dass das Unterprogramm verwendet, sollte selbst keine Variable time$ zu einem anderen Zweck anlegen.+**Achtung:** Ein Programm, das das Unterprogramm verwendet, sollte selbst keine Variable time$ zu einem anderen Zweck anlegen.
  
 === date === === date ===
Zeile 212: Zeile 214:
  
 Nach dem Aufruf steht das Datum in der Variablen date$.\\ Nach dem Aufruf steht das Datum in der Variablen date$.\\
-**Achtung:** Ein Programm, dass das Unterprogramm verwendet, sollte selbt keine Variable date$ zu einem anderen Zweck anlegen.+**Achtung:** Ein Programm, das das Unterprogramm verwendet, sollte selbt keine Variable date$ zu einem anderen Zweck anlegen.
  
  
Zeile 219: Zeile 221:
  
 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. 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 rweiterten Feld (oder am Programmstart, falls es kein solches Feld gibt, eingebunden werden.+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: Mit dem Einbinden von MSHRINK.LTB sind außerdem folgende globale Variablen definiert:
Zeile 228: Zeile 230:
  
   * integer <nowiki>my__size</nowiki> : Größe des vom Programm belegten Speicherblocks  in Paragraphen    * integer <nowiki>my__size</nowiki> : Größe des vom Programm belegten Speicherblocks  in Paragraphen 
 +
  
 ==== Bibliothek ALLOC.LTB ==== ==== Bibliothek ALLOC.LTB ====
Zeile 233: Zeile 236:
 Die Bibliothek stellt Funktionen zur dynamischen Speicheranforderung über DOS-Systemaufrufe bereit. Die Bibliothek stellt Funktionen zur dynamischen Speicheranforderung über DOS-Systemaufrufe bereit.
  
-Da Tokiwa-Basic-Programme standardmäßig den gesamtn 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.+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. Alle Funktionen dieser Bibliothek legen im Falle eines Ausführungsfehlers den DOS-Fehlercode in der globalen (Integer-) Variablen ''**ALLOC_ERROR**'' ab.
Zeile 303: Zeile 306:
  
 Rückgabewert: keiner Rückgabewert: keiner
 +
  
 ==== Bibliothek STRINGS.LTB ==== ==== Bibliothek STRINGS.LTB ====
  
-Die Bibliothek enthällt eine Reihe von Funktionen zur erweiterten und schnelleren Verarbeitung von Zeichenketten.+Die Bibliothek enthält eine Reihe von Funktionen zur erweiterten und schnelleren Verarbeitung von Zeichenketten.
  
 **Enthaltene Unterprogramme/Funktionen:** **Enthaltene Unterprogramme/Funktionen:**
Zeile 321: Zeile 325:
   * Der Ergebnispuffer (adressiert durch resloc) muss eine String-Variable im Datensegment sein, deren Adresse sich mit Hilfe der LOC-Funktion bestimmen lässt.   * 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.   * Der Rückgabewert kann direkt an die ''strTok''-Funktion als Argument ''str'' übergeben werden.
 +
  
  
Zeile 337: Zeile 342:
 Hinweise: Hinweise:
   * Sowohl der Zielpuffer als auch die Datenquelle müssen vollständig im Datensegment liegen.   * Sowohl der Zielpuffer als auch die Datenquelle müssen vollständig im Datensegment liegen.
-  * Der Zielpuffer nuss mindestens eine kapazität von ''nbytes'' Bytes haben.+  * 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!    * 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.   * Das ''nbytes''-Argument wird als vorzeichenloser Integer-Wert interpretiert.
   * Achtung: Es wird keine Überprüfung auf Offset-Überlauf durchgeführt!   * Achtung: Es wird keine Überprüfung auf Offset-Überlauf durchgeführt!
      
 +
 +
 === memCpyFar(odest,sdest,osrc,ssrc,nbytes) === === memCpyFar(odest,sdest,osrc,ssrc,nbytes) ===
  
Zeile 356: Zeile 363:
  
 Hinweise: Hinweise:
-  * Der Zielpuffer nuss mindestens eine kapazität von ''nbytes'' Bytes haben.+  * 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!    * 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.   * Das ''nbytes''-Argument wird als vorzeichenloser Integer-Wert interpretiert, es können also theoretisch bis zu 64 KBytes auf einmal kopiert werden.
Zeile 396: Zeile 403:
   * Bei einem negativen Wert von ''length'' werden alle Zeichen ab ''pos'' bis zum Ende gelöscht.   * 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.   * 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) === === strDeleteChr(str, chr, pos, length) ===
Zeile 405: Zeile 413:
   * chr: Zeichencode (integer) des Zeichens, das gelöscht werden soll   * chr: Zeichencode (integer) des Zeichens, das gelöscht werden soll
   * pos: Start-Indexposition des Bereichs, in dem das Zeichen 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+  * length: Maximallänge des Bereichs, in dem das Zeichen gelöscht werden soll
  
 Rückgabewert: Anzahl tatsächlich gelöschter Zeichen Rückgabewert: Anzahl tatsächlich gelöschter Zeichen
  
 Hinweise: Hinweise:
-  * Bei einem negativen Wert von ''length'' recht der Löschbereich von ''pos'' bis zum Ende der Zichenkette.+  * 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.   * Das Löschen erfolgt "in place", d.h. es wird kein neuer String erzeugt, sondern die übergebene Zeichenkette selbst modifiziert.
  
Zeile 427: Zeile 435:
   * Die Adresse der Ziel-Zeichenkette (Argument ''str'') kann mit der ''LOC''-Funktion ermittelt werden.   * 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.   * 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) === === strLen(str) ===
Zeile 436: Zeile 445:
 Rückgabewert: Anzahl der Zeichen in ''str'' Rückgabewert: Anzahl der Zeichen in ''str''
  
-Hinweis: Die Funktion verhält sich wie die Standardfunktion LEN, akzeptiert jedoch als Argument auch statt einer Stringvariablen oder -konstanten auch einen Integer-Wert, der den Offset des ersten Zeichens eines Strings im Datensegment angibt.+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) === === strLower(str) ===
Zeile 486: Zeile 495:
  
 Rückgabewert: Position von ''search'' in ''str'' bei Erfolg, sonst -1 Rückgabewert: Position von ''search'' in ''str'' bei Erfolg, sonst -1
 +
  
 === strTok(str,resloc,delimit) === === strTok(str,resloc,delimit) ===
  
 Die Funktion erlaubt das schrittweise Zerlegen einer Zeichenkette in Token. 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 Teilzeichenkezze vor dem Trennzeichen im Ergebnispuffer abgelegt; ist kein Trennzeichen enthalten, wird als Ergebnis+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. die ganze Zeichenkette (als einzelnes Token gespeichert.
 Argumente:  Argumente: 
Zeile 503: Zeile 513:
 Hinweise: Hinweise:
   * Der Ergebnispuffer (adressiert durch resloc) muss eine String-Variable im Datensegment sein.   * 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.+  * Wenn der Rückgabewert der Funktion nicht 0 ist, so kann dieser Wert als Argument str für einen nachfolgenden Aufruf der Funktion verwendet werdenum ein weiters Token abzuspalten.
  
 Beispiel: Beispiel:
Zeile 642: Zeile 652:
   * 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.   * 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.   * 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) === === fwrite_f(fhandle,nbytes,bufoffs,bufseg) ===
Zeile 656: Zeile 667:
  
 Hinweise: Hinweise:
-  * ''nbytes'' wird als vorzeichenloser Integer-Wert repräsentiert. Somit können theoretisch Datenblöcke bis zu 64 KBytes geschriebenn werden.+  * ''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.   * 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.   * 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) === === fwrite(fhandle,nbytes,buf) ===
Zeile 672: Zeile 684:
  
 Hinweise: Hinweise:
-  * ''nbytes'' wird als vorzeichenloser Integer-Wert repräsentiert. Somit können theoretisch Datenblöcke von mehr als 32 KBytes geschriebenn werden.+  * ''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.   * 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.   * 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) === === fseek(fhandle,smode,offset) ===
Zeile 694: Zeile 707:
   * 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).   * 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.   * 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 für ''offset=0'' angegeben, so bewirkt+  * Wird ''offset=0'' angegeben, so bewirkt
     * ''smode=_fseek_st''art eine Positionierung auf den Dateianfang,     * ''smode=_fseek_st''art eine Positionierung auf den Dateianfang,
     * ''smode=_fseek_end'' eine Positionierung auf das Dateiende und     * ''smode=_fseek_end'' eine Positionierung auf das Dateiende und
-    * ''smode=_fseek_rel'' keine ositionsänderung.+    * ''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.   * 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.
  
Zeile 721: Zeile 734:
  
  
 +
 +
 +==== 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(pattern,attr,resloc)|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(pattern,attr,resloc)|findFirst]] und [[#findNext(resloc)|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(pattern,attr,resloc)|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.1362344325.txt.gz · Zuletzt geändert: 16/02/2024 17:02 (Externe Bearbeitung)