Setzt den OpenSpec-Change phase-3-isam um (49/49 Aufgaben) und schliesst damit Phase 3 ab. Alle 22 ISAM-Elemente des Inventars sind implementiert; der Abdeckungsstand steigt auf 217 implementiert / 15 offen / 53 Non-Feature. Frontend - ISAM-Anweisungen als eigener Zweig im Parser: NAME [#]n [, arg ...], Sonderform ROLLBACK ALL ueber eine Sentinel-Kennung - 22 Signaturen in builtin_stmt/builtin_fn, neue Argumentart R (Satzvariable eines benutzerdefinierten Typs) - Satzargumente von INSERT/RETRIEVE/UPDATE werden gegen den Typ der Dateinummer geprueft, sofern beide literal bekannt sind - Die Unsupported-Absenkung von OPEN ... FOR ISAM entfaellt Speicherschicht (tb-runtime::isam, einziger Ort mit redb) - Je Tabelle eine Satztabelle satz-id -> Satzbytes, je Index eine Tabelle Schluesselbytes -> satz-id. Satz-IDs sind monoton und werden nie wiederverwendet: der Cursor merkt sich eine ID, eine neu vergebene koennte still auf einen fremden Satz zeigen - Satzbytes entstehen mit fileio::wert_schreiben/wert_lesen, also mit den Recordpuffern und der UTF-32-Festtextkodierung aus datei-eio - Ordnungserhaltende Schluesselkodierung je Spaltentyp; Text als UTF-8, dessen Bytereihenfolge die Codepoint-Reihenfolge ist und damit dieselbe Ordnung wie CmpStr der VM. Ein Eigenschaftstest ueber 5000 zufaellige Wertepaare je Typ haelt fest, dass der Bytevergleich dem fachlichen Vergleich entspricht -- eine Ordnungsverletzung faellt sonst erst bei bestimmten Datenwerten auf - Cursor als Wert (aktiver Index, letzte Satz-ID, unpositioniert), nicht als gehaltener Iterator: er ueberlebt Satzaenderungen und Transaktionsgrenzen - Sicherungspunkte ueber ein eigenes Ruecknahmeprotokoll; ROLLBACK ALL bricht die Bibliothekstransaktion direkt ab Semantik durchweg aus der Original-Hilfe - Die Argumentformen stammen erstmals aus den Einzelseiten, nicht nur aus der Themenliste. Das korrigierte eine Annahme des Entwurfs: die Spaltenliste von CREATEINDEX ist keine Zeichenkette mit Trennzeichen, sondern eine Folge einzelner Stringargumente - SEEKEQ mit unvollstaendigem Schluessel schlaegt immer fehl, SEEKGT mit Teilschluessel positioniert wie SEEKGE - Nach SETINDEX ist der erste Satz der neuen Ordnung aktuell, nach DELETE der folgende - Suche ueber den NULL-Index meldet 87, nicht 83; damit hat jeder Code von 81 bis 89 einen Ausloeser - Einzige Erweiterung: ein - vor dem Spaltennamen ordnet absteigend. Die Original-Hilfe kennt bei CREATEINDEX keine Sortierrichtung, die Anforderung verlangt sie. Kollisionsfrei, weil ein TYPE-Feldname nie mit - beginnen kann CLOSE beendet keine Transaktion - Erst schrieb es sie fest, womit das Schliessen irgendeiner Dateinummer die Transaktion aller anderen mit beendete und ein folgendes ROLLBACK ALL ins Leere lief. Ausstehende Aenderungen sind ohnehin festgeschrieben, weil jede Operation ausserhalb einer Transaktion fuer sich eine ist - Ueber das Ende entscheiden allein COMMITTRANS und ROLLBACK ALL; eine beim Programmende offene Transaktion verfaellt, in beiden Wegen gleich SETMEM und Fehler 89 - Ohne DOS-Speichermodell ist SETMEM die Obergrenze des ISAM-Puffers (Vorgabe 65536 Bytes); ohne echte Grenze waere Code 89 nie erreichbar und die Anweisung eine Attrappe Tests - 18 Einheitentests (Kodierung, Formatversion, Satz-IDs, Roundtrip ueber alle Feldtypen, Indexordnung, Cursor, Protokoll) - 6 Korpusprogramme: Tabellen, Indizes, Cursor, Saetze, Transaktionen, Puffer und Vergleichsordnung -- je in einem temporaeren Arbeits- verzeichnis, der Projektbaum bleibt sauber - Der VM-Test zu Fehler 73 prueft ISAM nicht mehr, sondern SETUEVENT; dafuer belegt ein neuer Test, dass OPEN ... FOR ISAM arbeitet Dokumentation: Datenbankdateiformat in dateiformate.md, Abschnitt 10a samt Sortierordnung und SETMEM-Abweichung in sprachreferenz.md, ISAM-Abschnitt in bibliothek.md, Inventar auf implementiert, PLAN.md schaerft die Leitplanke Referenzverhalten -- sie gilt auch gegenueber den eigenen Spezifikationen. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
383 lines
12 KiB
Markdown
383 lines
12 KiB
Markdown
# Bibliotheksreferenz
|
||
|
||
Die Laufzeitbibliothek **so wie implementiert**. Der Umfang wird von
|
||
[docs/inventar.md](inventar.md) bestimmt; dort steht auch, was noch offen
|
||
ist. Abweichungen vom Vorbild sind in
|
||
[docs/sprachreferenz.md](sprachreferenz.md) unter „Abweichungen"
|
||
gesammelt.
|
||
|
||
Ein automatischer Test hält das Inventar gegen den Code; diese Referenz
|
||
beschreibt das Verhalten dahinter.
|
||
|
||
|
||
## Bildschirm
|
||
|
||
| Element | Art |
|
||
|---|---|
|
||
| `CLS` | Anweisung |
|
||
| `COLOR` | Anweisung |
|
||
| `CSRLIN` | Funktion |
|
||
| `INPUT` | Anweisung |
|
||
| `LINE INPUT` | Anweisung |
|
||
| `LOCATE` | Anweisung |
|
||
| `POS` | Funktion |
|
||
| `PRINT` | Anweisung |
|
||
| `SCREEN` | Anweisung |
|
||
| `SCREEN` | Funktion |
|
||
| `SPC` | Funktion |
|
||
| `TAB` | Funktion |
|
||
| `VIEW PRINT` | Anweisung |
|
||
| `WIDTH` | Anweisung |
|
||
|
||
Alle Anweisungen wirken auf den Zellenpuffer der aktuellen
|
||
Bildschirmgröße — 80×25 ist nirgends eine feste Grenze. Ausgelassene
|
||
Argumente von `LOCATE` und `COLOR` lassen den bisherigen Wert stehen.
|
||
`LOCATE` außerhalb der Grenzen und `SCREEN(zeile, spalte)` außerhalb
|
||
lösen Fehler 5 aus. Die Funktionsform `SCREEN` liefert ohne drittes
|
||
Argument den Zeichencode, mit drittem das Farbattribut
|
||
(Hintergrund·16 + Vordergrund). `WIDTH` hebt den Puffer höchstens an.
|
||
`VIEW PRINT` ohne Argumente setzt den Scrollbereich auf den vollen
|
||
Bildschirm zurück.
|
||
|
||
## Datum/Zeit
|
||
|
||
| Element | Art |
|
||
|---|---|
|
||
| `DATE$` | Anweisung |
|
||
| `DATE$` | Funktion |
|
||
| `DATESERIAL` | Funktion |
|
||
| `DATEVALUE` | Funktion |
|
||
| `DAY` | Funktion |
|
||
| `HOUR` | Funktion |
|
||
| `MINUTE` | Funktion |
|
||
| `MONTH` | Funktion |
|
||
| `NOW` | Funktion |
|
||
| `SECOND` | Funktion |
|
||
| `TIME$` | Anweisung |
|
||
| `TIME$` | Funktion |
|
||
| `TIMER` | Funktion |
|
||
| `TIMESERIAL` | Funktion |
|
||
| `TIMEVALUE` | Funktion |
|
||
| `WEEKDAY` | Funktion |
|
||
| `YEAR` | Funktion |
|
||
|
||
Serielle Werte zählen Tage ab dem 30.12.1899 (Serie 2 = 1.1.1900);
|
||
der Nachkommaanteil ist die Tageszeit. `WEEKDAY` liefert 1 für Sonntag.
|
||
Ungültige Datums- oder Zeitangaben lösen Fehler 5 aus.
|
||
|
||
Die Uhr rechnet in der **Ortszeit** des Rechners; `TIMER` zählt ab der
|
||
lokalen Mitternacht. Der Versatz wird für den jeweils abgefragten
|
||
Zeitpunkt bestimmt, nicht einmal beim Programmstart — ein Programm, das
|
||
über eine Zeitumstellung hinweg läuft, folgt ihr.
|
||
|
||
Lässt sich die Zone nicht ermitteln, gilt UTC; das Programm läuft weiter
|
||
und der Runner meldet es einmal beim Start auf der Fehlerausgabe.
|
||
|
||
`DATE$ = …` und `TIME$ = …` stellen nicht die Systemuhr, sondern einen
|
||
programmeigenen Versatz auf die Ortszeit, den alle Zeitfunktionen
|
||
mitrechnen. `DATEVALUE` und `TIMEVALUE` lesen Wanduhrzeit und rechnen
|
||
nicht um.
|
||
|
||
## Deklaration
|
||
|
||
| Element | Art |
|
||
|---|---|
|
||
| `COMMON` | Anweisung |
|
||
| `CONST` | Anweisung |
|
||
| `DATA` | Anweisung |
|
||
| `DEFtype` | Anweisung |
|
||
| `DIM` | Anweisung |
|
||
| `ERASE` | Anweisung |
|
||
| `LBOUND` | Funktion |
|
||
| `LET` | Anweisung |
|
||
| `OPTION BASE` | Anweisung |
|
||
| `READ` | Anweisung |
|
||
| `REDIM` | Anweisung |
|
||
| `REM` | Anweisung |
|
||
| `RESTORE` | Anweisung |
|
||
| `SHARED` | Anweisung |
|
||
| `STATIC` | Anweisung |
|
||
| `SWAP` | Anweisung |
|
||
| `TYPE` | Anweisung |
|
||
| `UBOUND` | Funktion |
|
||
|
||
## Ereignisse
|
||
|
||
| Element | Art |
|
||
|---|---|
|
||
| `DOEVENTS` | Funktion |
|
||
|
||
## Fehlerbehandlung
|
||
|
||
| Element | Art |
|
||
|---|---|
|
||
| `ERL` | Funktion |
|
||
| `ERR` | Funktion |
|
||
| `ERROR` | Anweisung |
|
||
| `ON ERROR` | Anweisung |
|
||
| `RESUME` | Anweisung |
|
||
|
||
## Finanzen
|
||
|
||
| Element | Art |
|
||
|---|---|
|
||
| `DDB#` | Funktion |
|
||
| `FV#` | Funktion |
|
||
| `IPMT#` | Funktion |
|
||
| `IRR#` | Funktion |
|
||
| `MIRR#` | Funktion |
|
||
| `NPER#` | Funktion |
|
||
| `NPV#` | Funktion |
|
||
| `PMT#` | Funktion |
|
||
| `PPMT#` | Funktion |
|
||
| `PV#` | Funktion |
|
||
| `RATE#` | Funktion |
|
||
| `SLN#` | Funktion |
|
||
| `SYD#` | Funktion |
|
||
|
||
Alle Funktionen rechnen in DOUBLE. Vorzeichenkonvention wie beim
|
||
Vorbild: ausgehende Zahlungen sind negativ, eingehende positiv. Das
|
||
letzte Argument der Renten-Funktionen ist die Fälligkeit — 0
|
||
nachschüssig, 1 vorschüssig.
|
||
|
||
`Rate#` und `IRR#` nähern sich mit dem Sekantenverfahren.
|
||
**Abbruchbedingung:** höchstens 100 Schritte; erreicht wird die Lösung,
|
||
wenn der Betrag der Restabweichung unter 1e-9 fällt. Bleibt sie über
|
||
1e-6, gilt die Näherung als erfolglos und es tritt Fehler 5 auf —
|
||
ein stiller Ersatzwert wird nie geliefert. Eine Zahlungsreihe ohne
|
||
Vorzeichenwechsel weist `IRR#` sofort mit Fehler 5 ab.
|
||
|
||
Weitere Fehler 5: Periode außerhalb der Laufzeit bei
|
||
`IPmt#`/`PPmt#`/`SYD#`/`DDB#`, Nutzungsdauer null bei `SLN#`,
|
||
Perioden null bei `Pmt#`, Zinssatz ≤ −1.
|
||
|
||
## Formatierung
|
||
|
||
| Element | Art |
|
||
|---|---|
|
||
| `FORMAT$` | Funktion |
|
||
| `PRINT USING` | Anweisung |
|
||
| `SetFormatCC` | Routine |
|
||
|
||
`PRINT USING`, `LPRINT USING` und `FORMAT$` teilen dieselbe
|
||
Formatzeichenkette. Numerische Platzhalter: `#` Ziffernstelle,
|
||
`.` Dezimalpunkt, `,` Tausendertrennung, `+`/`-` Vorzeichenführung
|
||
(vorn oder hinten, mit eigener Stelle), `$$` mitlaufendes
|
||
Währungszeichen und `**` Sternfüllung (beide bringen zwei Stellen
|
||
mit), `^^^^` Exponentialform. String-Platzhalter: `!` erstes Zeichen,
|
||
`&` ganzer String, `\ \` feste Länge. `_` macht das Folgezeichen
|
||
literal.
|
||
|
||
Passt ein Wert nicht in sein Feld, wird er vollständig ausgegeben und
|
||
mit `%` gekennzeichnet. Die Formatzeichenkette wird wiederholt,
|
||
solange Werte übrig sind. Eine Zeichenkette ohne Feld bei vorhandenen
|
||
Werten löst Fehler 5 aus. `SetFormatCC` setzt das Währungszeichen
|
||
über einen Ländercode; nicht aufgeführte Codes behalten `$`.
|
||
|
||
## ISAM
|
||
|
||
| Element | Art |
|
||
|---|---|
|
||
| `BEGINTRANS` | Anweisung |
|
||
| `BOF` | Funktion |
|
||
| `COMMITTRANS` | Anweisung |
|
||
| `CREATEINDEX` | Anweisung |
|
||
| `DELETE` | Anweisung |
|
||
| `DELETEINDEX` | Anweisung |
|
||
| `DELETETABLE` | Anweisung |
|
||
| `GETINDEX$` | Funktion |
|
||
| `INSERT` | Anweisung |
|
||
| `MOVEFIRST` | Anweisung |
|
||
| `MOVELAST` | Anweisung |
|
||
| `MOVENEXT` | Anweisung |
|
||
| `MOVEPREVIOUS` | Anweisung |
|
||
| `RETRIEVE` | Anweisung |
|
||
| `ROLLBACK` | Anweisung |
|
||
| `SAVEPOINT` | Funktion |
|
||
| `SEEKEQ` | Anweisung |
|
||
| `SEEKGE` | Anweisung |
|
||
| `SEEKGT` | Anweisung |
|
||
| `SETINDEX` | Anweisung |
|
||
| `SETMEM` | Funktion |
|
||
| `UPDATE` | Anweisung |
|
||
|
||
Indizierter Satzzugriff auf Tabellen einer Datenbankdatei; die
|
||
Dateinummer kommt aus `OPEN datenbank$ FOR ISAM typname tabelle$ AS #n`.
|
||
Bei allen Anweisungen ist das `#` vor der Dateinummer optional.
|
||
|
||
`CREATEINDEX #n, name$, eindeutig%, spalte$[, spalte$]…` legt einen Index
|
||
über bis zu neun Spalten an; `eindeutig%` ungleich 0 verbietet doppelte
|
||
Schlüssel (Verstoß: Fehler 86, Satzbestand bleibt unverändert). Ein `-`
|
||
vor dem Spaltennamen ordnet absteigend — eine Erweiterung über die
|
||
Original-Hilfe hinaus. `SETINDEX #n` ohne Namen (oder mit `""`) wählt den
|
||
NULL-Index (Einfügereihenfolge), `GETINDEX$` liefert dafür einen leeren
|
||
String. Nach `SETINDEX` ist der erste Satz der neuen Ordnung der aktuelle.
|
||
Unbekannter Index: Fehler 83, unbekannte Spalte: Fehler 84.
|
||
|
||
`INSERT`, `RETRIEVE` und `UPDATE` erwarten als zweites Argument eine
|
||
Variable des Tabellentyps, `DELETE` nur die Dateinummer. Ohne
|
||
positionierten Cursor melden `RETRIEVE`, `UPDATE` und `DELETE` Fehler 85.
|
||
Nach `DELETE` wird der folgende Satz der aktuelle; war der gelöschte der
|
||
letzte, steht der Cursor am Ende der Tabelle ohne aktuellen Satz. Alle
|
||
Indizes werden nach jeder Satzoperation nachgeführt.
|
||
|
||
Die `MOVE`-Familie bewegt in der Ordnung des aktiven Index, ohne aktiven
|
||
Index in Einfügereihenfolge. Läuft der Cursor über das Ende hinaus, wird
|
||
`EOF(n)` wahr, über den Anfang hinaus `BOF(n)`; in beiden Fällen ist der
|
||
Cursor danach unpositioniert. Die `SEEK`-Familie sucht im aktiven Index
|
||
(über den NULL-Index: Fehler 87); eine erfolglose Suche setzt `EOF`. Ein
|
||
mehrspaltiger Index lässt sich mit einem Präfix seiner Spalten
|
||
durchsuchen, wobei `SEEKEQ` mit unvollständigem Schlüssel immer fehlschlägt.
|
||
|
||
`BEGINTRANS` eröffnet eine Transaktion, `COMMITTRANS` schreibt sie fest.
|
||
`CLOSE` beendet sie nicht; eine beim Programmende offene Transaktion
|
||
bleibt wirkungslos.
|
||
`SAVEPOINT` liefert die Kennung eines Sicherungspunkts; `ROLLBACK kennung`
|
||
setzt auf ihn zurück und lässt die Transaktion offen, `ROLLBACK` ohne
|
||
Argument auf den letzten Sicherungspunkt bzw. den Transaktionsbeginn.
|
||
`ROLLBACK ALL` nimmt alles seit `BEGINTRANS` zurück und beendet die
|
||
Transaktion. Nach jeder Rücknahme ist der Cursor unpositioniert.
|
||
|
||
`SETMEM(n&)` verändert die ISAM-Puffergrenze um `n` Bytes und liefert die
|
||
danach verfügbare Größe (Vorgabe 65536); ein Überschreiten meldet Fehler
|
||
89. Bedeutung und Abweichung vom DOS-Speichermodell des Vorbilds stehen
|
||
in der Sprachreferenz.
|
||
|
||
## Klang
|
||
|
||
| Element | Art |
|
||
|---|---|
|
||
| `BEEP` | Anweisung |
|
||
|
||
## Mathematik
|
||
|
||
| Element | Art |
|
||
|---|---|
|
||
| `ABS` | Funktion |
|
||
| `ATN` | Funktion |
|
||
| `CCUR` | Funktion |
|
||
| `CDBL` | Funktion |
|
||
| `CINT` | Funktion |
|
||
| `CLNG` | Funktion |
|
||
| `COS` | Funktion |
|
||
| `CSNG` | Funktion |
|
||
| `EXP` | Funktion |
|
||
| `FIX` | Funktion |
|
||
| `INT` | Funktion |
|
||
| `LOG` | Funktion |
|
||
| `RANDOMIZE` | Anweisung |
|
||
| `RND` | Funktion |
|
||
| `SGN` | Funktion |
|
||
| `SIN` | Funktion |
|
||
| `SQR` | Funktion |
|
||
| `TAN` | Funktion |
|
||
|
||
Rundung ist kaufmännisch-symmetrisch zur geraden Zahl
|
||
(`CINT(0.5)` = 0, `CINT(1.5)` = 2, `CINT(2.5)` = 2). `INT` rundet ab,
|
||
`FIX` in Richtung null. Überschreitet ein Ergebnis den Zieltyp, tritt
|
||
Fehler 6 auf; `SQR`/`LOG` mit unzulässigem Argument lösen Fehler 5
|
||
aus, Division durch null Fehler 11.
|
||
|
||
Der Zufallsgenerator ist der 24-Bit-LCG des Vorbilds
|
||
(`zustand = (zustand · &HFD43FD + &HC39EC3) MOD 2^24`). `RND(0)`
|
||
wiederholt den letzten Wert, `RND(n)` mit `n < 0` sät neu aus dem
|
||
Argument. `RANDOMIZE saat` liefert bei gleicher Saat stets dieselbe
|
||
Folge, unabhängig von vorherigen `RND`-Aufrufen; ohne Argument wird
|
||
der Startwert abgefragt.
|
||
|
||
## Metabefehl
|
||
|
||
| Element | Art |
|
||
|---|---|
|
||
| `$DYNAMIC` | Metabefehl |
|
||
| `$STATIC` | Metabefehl |
|
||
|
||
## Prozeduren
|
||
|
||
| Element | Art |
|
||
|---|---|
|
||
| `CALL` | Anweisung |
|
||
| `DECLARE` | Anweisung |
|
||
| `DEF FN` | Anweisung |
|
||
| `FUNCTION` | Anweisung |
|
||
| `SUB` | Anweisung |
|
||
|
||
## Steuerfluss
|
||
|
||
| Element | Art |
|
||
|---|---|
|
||
| `DO...LOOP` | Anweisung |
|
||
| `END` | Anweisung |
|
||
| `EXIT` | Anweisung |
|
||
| `FOR...NEXT` | Anweisung |
|
||
| `GOSUB` | Anweisung |
|
||
| `GOTO` | Anweisung |
|
||
| `IF...THEN...ELSE` | Anweisung |
|
||
| `ON...GOSUB` | Anweisung |
|
||
| `ON...GOTO` | Anweisung |
|
||
| `RETURN` | Anweisung |
|
||
| `SELECT CASE` | Anweisung |
|
||
| `STOP` | Anweisung |
|
||
| `WHILE...WEND` | Anweisung |
|
||
|
||
## Strings
|
||
|
||
| Element | Art |
|
||
|---|---|
|
||
| `ASC` | Funktion |
|
||
| `CHR$` | Funktion |
|
||
| `HEX$` | Funktion |
|
||
| `INSTR` | Funktion |
|
||
| `LCASE$` | Funktion |
|
||
| `LEFT$` | Funktion |
|
||
| `LEN` | Funktion |
|
||
| `LTRIM$` | Funktion |
|
||
| `MID$` | Anweisung |
|
||
| `MID$` | Funktion |
|
||
| `OCT$` | Funktion |
|
||
| `RIGHT$` | Funktion |
|
||
| `RTRIM$` | Funktion |
|
||
| `SPACE$` | Funktion |
|
||
| `STR$` | Funktion |
|
||
| `STRING$` | Funktion |
|
||
| `UCASE$` | Funktion |
|
||
| `VAL` | Funktion |
|
||
|
||
Zeichen sind Unicode-Codepoints; `LEN` zählt Zeichen, nicht Bytes
|
||
(dokumentierte Abweichung). Randfälle: `VAL` liest das führende
|
||
Zahlenpräfix und überspringt Leerraum, versteht `&H`/`&O`;
|
||
`STR$` stellt nicht-negativen Zahlen ein Leerzeichen voran;
|
||
`LEFT$`/`RIGHT$` mit Länge über der Stringlänge liefern den ganzen
|
||
String; `ASC("")` sowie eine Startposition kleiner 1 bei
|
||
`MID$`/`INSTR` lösen Fehler 5 aus. `STRING$` nimmt einen Zeichencode
|
||
oder einen String (dessen erstes Zeichen zählt).
|
||
|
||
## System
|
||
|
||
| Element | Art |
|
||
|---|---|
|
||
| `COMMAND$` | Funktion |
|
||
| `SLEEP` | Anweisung |
|
||
| `SYSTEM` | Anweisung |
|
||
|
||
`ENVIRON$` liest Umgebungsvariablen nach Namen, `COMMAND$` liefert die
|
||
Aufrufargumente ohne Programmnamen. Nicht abbildbare Größen liefern
|
||
einen dokumentierten Ersatzwert statt still zu variieren.
|
||
|
||
## Tastatur
|
||
|
||
| Element | Art |
|
||
|---|---|
|
||
| `INKEY$` | Funktion |
|
||
| `INPUT$` | Funktion |
|
||
| `KEY` | Anweisung |
|
||
|
||
`INKEY$` blockiert nicht: leerer String bei leerem Puffer, ein Zeichen
|
||
bei einer Zeichentaste, zwei Zeichen mit führendem Nullzeichen bei
|
||
einer Sondertaste. `INPUT$(n)` liest genau `n` Zeichen und blockiert
|
||
dabei, ohne sie am Bildschirm zu wiederholen.
|
||
|
||
`KEY n, text$` belegt ein Funktionstasten-Makro (n = 1–10 sowie 30/31,
|
||
höchstens 15 Zeichen), `KEY LIST` gibt alle zwölf untereinander aus,
|
||
`KEY ON`/`KEY OFF` blendet die Softkey-Zeile ein und aus.
|