Files
TerminalBasic/docs/sprachreferenz.md
Chili Palmer a0fb41420e Ortszeit statt UTC
Setzt den OpenSpec-Change phase-3-ortszeit um (21/21 Aufgaben) und zieht
damit die in Phase 3 eingegangene Abweichung zurueck: DATE$, TIME$, TIMER
und NOW rechnen in der Zeitzone des Rechners, TIMER zaehlt ab der lokalen
Mitternacht.

Versatzermittlung
- jiff 0.2.35 als Abhaengigkeit von tb-runtime
- datetime::utc_versatz(zeitpunkt) ist der einzige Aufrufpunkt der
  Bibliothek; die Kalenderrechnung darunter bleibt Eigenimplementierung
  und sieht sie nie -- zwei Kalendermodelle nebeneinander waeren eine
  dauerhafte Fehlerquelle
- Der Versatz gilt je Zeitpunkt, nicht je Programmlauf: ein Programm, das
  ueber eine Zeitumstellung hinweg laeuft, folgt ihr

Zonenzustand
- Zeitzone { System, Fest(i32), Unbekannt } im RtState
- Fest(n) macht Tests und Korpusprogramme unabhaengig von der Zone des
  Testrechners; TZ waere prozessweit und set_var seit Rust 2024 unsafe

Rueckfallebene
- Ohne ermittelbare Zone gilt UTC, das Programm laeuft weiter
- tbc run meldet den Rueckfall einmal beim Start auf der Fehlerausgabe,
  nicht je Abfrage -- ein stiller Wechsel waere ein Verstoss gegen den
  Guiding Principle

Korpus
- Neue Direktive ' tb-tz: +-HH:MM im Harness
- zeitzone.bas prueft Ortszeit, TIMER ab lokaler Mitternacht und den
  Programmversatz gegen eine gesetzte Uhrzeit
- datumzeit.bas auf die Direktive umgestellt; Sollausgabe unveraendert

Nebenbefund
- TIMER trennt jetzt ganze Sekunden (Ortszeit) vom Bruchteil
  (Systemuhr). Ohne die Trennung waere TIMER in Zonen mit halbstuendigem
  Versatz gesprungen.

Dokumentation: die Abweichung "Uhr laeuft in UTC" entfaellt aus
sprachreferenz.md; bibliothek.md und PLAN.md nachgezogen, jiff steht im
Stufe-2-Ideenspeicher neben crossterm.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 07:01:53 +02:00

22 KiB
Raw Blame History

Sprachreferenz Terminal Basic

Rekonstruierte Referenz des Dialekts (DOS-BASIC, Stand 1992: prozedurale BASIC-Familie mit Forms-Erweiterung). Dieses Dokument ist die verbindliche Grundlage für Frontend und Runtime. Offene Detailfragen sind ausgeräumt (Stand 2026-09-04); wo die Original-Dokumentation schweigt, steht an Ort und Stelle eine datierte Entscheidung mit Begründung.

Primärquellen: Original-Hilfedateien des Vorbilds als HTML unter https://dos-help.soulsphere.org/ (qck.hlp Quick Reference, advr.hlp Details, ener.hlp Fehlermeldungen; Vergleich PDS 7.1: bas7qck.hlp) sowie das Original-README der Professional Edition. Aussagen ohne ausgewiesene Entscheidung sind daraus belegt; die Themenlisten von bas7advr.hlp und qb45advr.hlp bilden zusammen das Vollständigkeits-Inventar (docs/inventar.md).

Guiding Principle: Die Original-Dokumentation führt. Jedes dort dokumentierte Sprachelement wird unterstützt oder — nur nach expliziter Non-Feature-Entscheidung des Projektinhabers — mit einer klaren Fehlermeldung abgewiesen. Bewusste Abweichungen und Non-Features stehen am Ende dieses Dokuments; nur diese Liste rechtfertigt Abweisungen.


1. Lexik

  • Zeilenorientiert. Eine logische Zeile enthält eine oder mehrere Anweisungen, getrennt durch :. Zeilenfortsetzung: _ als letztes Zeichen (mit vorangehendem Leerzeichen/Tab) setzt die Zeile fort — im Vorbild für extern erstellten Code gedacht (der IDE-Editor fügt fortgesetzte Zeilen beim Laden zusammen); Terminal Basic akzeptiert es überall.
  • Zeilennummern sind optional und wirken als Labels. Alphanumerische Labels enden mit : am Zeilenanfang (Fehler:).
  • Kommentare: REM (ganze Anweisung) und ' (bis Zeilenende). REM/' am Zeilenanfang mit $STATIC/$DYNAMIC/$INCLUDE: 'datei' sind Metabefehle.
  • Bezeichner: Buchstabe, dann Buchstaben/Ziffern/./_, max. 40 Zeichen, case-insensitiv. Optionales Typ-Suffix als letztes Zeichen. (_ in Bezeichnern ist eine dokumentierte Neuerung des Vorbilds.)
  • Typ-Suffixe: % INTEGER · & LONG · ! SINGLE · # DOUBLE · $ STRING · @ CURRENCY. name, name%, name$ sind verschiedene Variablen.
  • Keywords sind reserviert und case-insensitiv; die IDE normalisiert auf Großschreibung.
  • Numerische Literale: dezimal (123, 1.5, 1.5E3, 1D3 für DOUBLE), hexadezimal &HFF, oktal &O777; Suffixe erzwingen den Typ (10%, 10&, 1.5!, 1.5#, 2.5@). Ohne Suffix gilt: Ganzzahl im INTEGER-Bereich → INTEGER; Hex/Oktal ohne &-Suffix → 16 Bit (INTEGER), mit & → LONG; E-Exponent → SINGLE, D-Exponent → DOUBLE; Dezimalpunkt-Wert: Entscheidung (2026-09-02): bis 7 signifikante Stellen → SINGLE, darüber → DOUBLE. (Die Original-Hilfe nennt widersprüchlich eine 15-Stellen-Schwelle, die SINGLE-Präzision verlöre; wir legen die Schwelle auf die SINGLE-Genauigkeit — präzisionserhaltende Auslegung.) Ganzzahl außerhalb des LONG-Bereichs wird Gleitkommawert (kein Fehler).
  • String-Literale: "…"; doppeltes "" ergibt ein Anführungszeichen.

2. Typsystem

Typ Suffix Repräsentation Wertebereich
INTEGER % i16 32 768 … 32 767
LONG & i32 2 147 483 648 … 2 147 483 647
SINGLE ! f32 ±3.4E38
DOUBLE # f64 ±1.8E308
STRING $ dynamischer Unicode-String Länge 0 … 32 767 Zeichen
STRING * n fester String, n Zeichen nur in TYPE/DIM
CURRENCY @ i64, Festkomma ×10 000 ±922 337 203 685 477.5807
  • Benutzerdefinierte Typen: TYPE name … END TYPE mit Elementen fester Größe (numerische Typen, STRING * n, verschachtelte TYPEs). Kein dynamischer STRING in TYPE.
  • Implizite Deklaration: Erstverwendung deklariert die Variable. Ohne Suffix gilt der Standardtyp SINGLE, änderbar per DEFINT/DEFLNG/DEFSNG/DEFDBL/DEFSTR/DEFCUR az (buchstabenbereichsweise, wirkt pro Modul/Prozedur ab Deklaration).
  • OPTION EXPLICIT existiert (Neuerung des Vorbilds gegenüber der QB/PDS-Familie): erzwingt Deklaration aller Variablen (über COMMON, CONST, DEF FN, DIM, FUNCTION, REDIM, SHARED, STATIC oder SUB); gilt auch für das Direktfenster.
  • Arrays: DIM a(10), DIM a(1 TO 10, 0 TO 5). Untergrenze standardmäßig 0, per OPTION BASE 1 änderbar. $STATIC/$DYNAMIC bzw. Kontext bestimmen statisch/dynamisch; REDIM (dynamisch, löscht Inhalt), ERASE (reinitialisiert statisch / gibt dynamisch frei). Max. 60 Dimensionen, Indizes 32 767 … 32 767 (mit TO). LBOUND/UBOUND liefern Grenzen. (DOS-Speichergrenzen der Arrays — 64K/128K-Regeln — übernehmen wir nicht.)
  • Konvertierung: implizit zwischen numerischen Typen mit Rundung (Banker's Rounding bei CINT/CLNG und Zuweisung an Ganzzahl); Überlauf → Fehler 6. Keine implizite Konvertierung Zahl ↔ String (Fehler 13, Type mismatch). Die vollständige Konvertierungsmatrix (Ergebnistypen der Operatoren, Rundungs- und Überlaufregeln, Textdarstellung) steht in docs/tbvm-design.md und ist über tests/compat/konvertierung.bas ausführbar verankert (Phase 2, 2026-09-02).

3. Deklarationen und Sichtbarkeit

  • DIM [SHARED] var[(dims)] [AS typ]AS-Klausel: INTEGER, LONG, SINGLE, DOUBLE, STRING, STRING * n, CURRENCY, benutzerdefinierter Typ.
  • COMMON [SHARED] [/blockname/] liste — modulübergreifend (Kette CHAIN-kompatibel im Vorbild; ohne CHAIN bleibt COMMON die Verknüpfung mehrerer Module eines Projekts — geklärt mit der Projektverwaltung in Phase 5).
  • SHARED (in Prozedur): Zugriff auf Modulebene-Variablen.
  • STATIC (in Prozedur): Variablen behalten Werte zwischen Aufrufen; STATIC-Attribut an SUB/FUNCTION macht alle lokalen Variablen statisch.
  • CONST name = ausdruck — Konstanten (konstante Ausdrücke zur Compilezeit).
  • DECLARE SUB/FUNCTION name (parameter) — Prototyp; die IDE erzeugt sie automatisch beim Speichern.

4. Operatoren (nach Priorität, hoch → niedrig)

  1. ^ (Potenz)
  2. unäres -
  3. *, / (Fließkommadivision)
  4. \ (Ganzzahldivision; Operanden werden gerundet auf INTEGER/LONG)
  5. MOD (Ganzzahlrest, Vorzeichen wie Dividend)
  6. +, - (+ auch String-Verkettung)
  7. Vergleiche = <> < > <= >= (Zahlen und Strings; Strings codepoint-weise — Abweichung, s. u.)
  8. NOT
  9. AND
  10. OR
  11. XOR
  12. EQV
  13. IMP

Logische Operatoren sind bitweise auf Ganzzahlen; Vergleichsergebnis ist INTEGER 1 (wahr) / 0 (falsch).

5. Kontrollfluss

  • IF b THEN … [ELSE …] (einzeilig) und Block-IF … THEN / ELSEIF / ELSE / END IF
  • SELECT CASE ausdruck mit CASE wert, CASE a TO b, CASE IS >= x, CASE ELSE
  • FOR i = a TO b [STEP s] … NEXT [i] (Grenzen werden einmal ausgewertet; Schleifenvariable numerisch)
  • DO [WHILE|UNTIL b] … LOOP [WHILE|UNTIL b], WHILE … WEND
  • EXIT FOR / EXIT DO / EXIT SUB / EXIT FUNCTION / EXIT DEF
  • GOTO ziel, GOSUB ziel / RETURN [ziel]
  • ON n GOTO liste, ON n GOSUB liste (berechneter Sprung, 1-basiert; 0 oder > Anzahl: kein Sprung; negativ/>255: Fehler 5)
  • END (Programmende), STOP (Unterbrechung → im IDE-Kontext Debugger), SYSTEM (Programmende, im Vorbild „zurück zu DOS"). Runner-Verhalten (Entscheidung 2026-09-02): außerhalb der IDE beendet STOP das Programm mit der Meldung STOP in line n und Exit-Code ≠ 0; END/SYSTEM/Programmende liefern Exit-Code 0. CONT existiert nur als Direktmodus-Befehl der IDE (Phase 5) und ist nicht kompilierbar.
  • SLEEP [sekunden], DO EVENTS/DOEVENTS (Ereignisse verarbeiten — zentral für Forms)

6. Prozeduren

  • SUB name (p1 AS t, p2(), …) [STATIC] … END SUB; Aufruf CALL name(args) oder name args (ohne Klammern).
  • FUNCTION name (…) [STATIC] … name = wert … END FUNCTION; Typ über Suffix oder DEF…-Regel.
  • Parameterübergabe standardmäßig BYREF. Klammern um ein Argument (CALL f((x))) erzwingen Wertübergabe. BYVAL nur in DECLARE für externe Routinen (entfällt bei uns; BYVAL allgemein zu erlauben wäre eine Erweiterung über den Kernstandard hinaus → Stufe 2, PLAN.md).
  • Arrays werden mit name() übergeben, TYPEs BYREF.
  • Rekursion erlaubt (außer bei STATIC-Semantik-Konflikten).
  • DEF FNname (args) = ausdruck und Block-DEF FN … END DEF (mit EXIT DEF); Aufruf FNname(…). Nur auf Modulebene definier- und nutzbar, nicht rekursiv, Argumente by value, keine Arrays/Records/ Fixed-Strings als Argumente.

7. Fehlerbehandlung

  • Vollständige Syntax: ON [LOCAL] ERROR {GOTO zeile/label | RESUME NEXT | GOTO 0}. LOCAL installiert einen prozedurlokalen Handler; ohne LOCAL gilt der Handler modulweit. GOTO 0 deaktiviert (in einem aktiven Handler: Fehler weiterreichen → Programmabbruch).
  • Im Handler: RESUME (fehlerauslösende Anweisung wiederholen), RESUME NEXT, RESUME zeile/label.
  • ERR (Code), ERL (Zeilennummer, nur numerische Zeilennummern!), ERROR n (Fehler auslösen). Fehlernummer 105 ist im Vorbild intern reserviert und sollte nicht via ERROR n verwendet werden.
  • Fehler im aktiven Handler → sofortiger Abbruch. Fehler ohne Handler → Abbruch mit Meldung „Fehlertext in Zeile n" bzw. Debugger in der IDE.
  • Fehlerkatalog: klassische Codes 176, ISAM-Codes 8089, Forms-Codes 260480 — vollständig implementiert in tb-runtime/src/errors.rs.

8. Ereignis-Traps (klassisch, ohne Forms)

Vorhanden im Vorbild: ON COM/KEY/PEN/PLAY/STRIG/TIMER/UEVENT(…) GOSUB label mit Steueranweisungen … ON/OFF/STOP, dazu das EVENT-Statement (auch für Forms-Ereignisse) und SetUEvent. Timer-Events und Trapping sind ausgesetzt, solange ein Menü-Control den Fokus hat. Für Terminal Basic relevant: TIMER, KEY, UEVENT; COM/PEN/PLAY/STRIG: Nicht-Ziel (Fehler 73).

9. Konsolen-E/A

  • PRINT [#n,] liste — Trennzeichen ; (direkt anschließend) und , (nächste 14-Zeichen-Druckzone). Zahlen: führendes Leerzeichen bzw. -, nachgestelltes Leerzeichen. Abschluss ohne ;/, → Zeilenumbruch.
  • PRINT USING "format"; liste — Formatzeichen (offizielle Liste): numerisch # Ziffer, . Dezimalpunkt, , Tausendertrennung, + Vorzeichen- position, - nachgestelltes Minus, $$ führendes $, ** Füllsterne, **$ kombiniert, ^^^^ Exponent; String & ganz, ! erstes Zeichen, \ \ n Zeichen (Leerzeichen + 2); _ Literal-Escape; alle anderen Zeichen literal.
    • Feldüberlauf (geklärt 2026-09-04): Passt ein Wert nicht in sein Feld, wird er vollständig ausgegeben und die Ausgabe mit % eingeleitet (PRINT USING "##"; 12345%12345). Die Original-Hilfe listet das nicht; wir übernehmen das Verhalten der QB-Familie, weil ein stilles Abschneiden Zahlen verfälschen würde.
    • Vorzeichenangaben (+ vorn, +/- hinten) belegen eine eigene Position neben den Ziffernstellen; $$ und ** bringen ihre Stellen dagegen mit.
    • Die Formatzeichenkette wird wiederholt, solange Werte übrig sind. Eine Zeichenkette ohne Feld bei vorhandenen Werten löst Fehler 5 aus.
    • SetFormatCC(ländercode) setzt das Zeichen für $$. Nur wenige Codes sind belegt (1 = $, 33 = F, 39 = L, 44 = £, 49 = DM, 81 = ¥); alle übrigen behalten $ — die Tabelle des Vorbilds ist nicht überliefert (dokumentierte Abweichung).
  • INPUT ["prompt"{;|,}] var, … (mit ; vor Prompt: kein „? "); LINE INPUT (ganze Zeile in String).
  • INKEY$ (nicht blockierend; "" wenn leer; erweiterte Tasten: 2-Zeichen-Sequenz CHR$(0)+code im Vorbild — Abweichung s. u.), INPUT$(n [,#f]).
  • LOCATE [zeile][,spalte][,cursor an/aus][,start,ende], CSRLIN, POS(0) — arbeiten auf der tatsächlichen Bildschirmgröße (dynamisch, s. Abweichungen).
  • COLOR [vg][,hg] (vg 031: 1631 = blinkend — bei uns als „hell" simuliert, Entscheidung 2026-09-02; hg 07), CLS, WIDTH (hebt den Puffer höchstens an, s. Abweichungen), VIEW PRINT oben TO unten (Scrollbereich).
  • TAB(n), SPC(n) in PRINT-Listen.
  • BEEP, SOUND freq, dauer (Terminal-Bell / Nicht-Ziel, s. Abweichungen), PLAY (Nicht-Ziel).
  • Funktionstasten-Makros (Umfang geklärt 2026-09-03 aus der Original-Hilfe):
    • KEY n, text$ belegt ein Makro. n ist 110 für F1F10 sowie 30 und 31 für F11/F12; andere Werte lösen Fehler 5 aus. text$ wird nach 15 Zeichen abgeschnitten.
    • KEY LIST gibt alle zwölf Makros untereinander aus.
    • KEY ON blendet die Softkey-Zeile in der untersten Bildschirmzeile ein (Tastennummer plus die ersten sechs Zeichen des Makros), KEY OFF blendet sie aus. Solange sie sichtbar ist, endet der Scrollbereich darüber, damit die Ausgabe sie nicht überschreibt; ein danach gesetztes VIEW PRINT hat Vorrang.
    • KEY(n) ON|OFF|STOP mit Index ist Ereignissteuerung und kommt mit der Forms-Engine (Phase 4).
    • Abweichung: ein kompiliertes Programm startet mit leeren Makros; die Vorbelegung des Vorbilds gehörte zu dessen Interpreter-Oberfläche.

10. Datei-E/A

  • OPEN datei$ [FOR modus] [ACCESS zugriff] [lock] AS [#]n [LEN=reclen] Modi: INPUT, OUTPUT, APPEND (sequenziell), RANDOM (Standard), BINARY.
  • CLOSE [#n, …], RESET (alle schließen).
  • Sequenziell: PRINT #, PRINT # USING, WRITE # (CSV-artig, Strings in "…"), INPUT #, LINE INPUT #, EOF(n).
  • Random: FIELD #n, breite AS var$… (klassisch) und GET/PUT #n [,satznr] [,var] mit TYPE-Variablen; LSET/RSET für Feldpuffer.
  • Binary: GET/PUT #n, [pos], var, SEEK #n, pos / SEEK(n), LOC(n), LOF(n).
  • Verwaltung: NAME alt$ AS neu$, KILL datei$, FILES [muster$], CHDIR, MKDIR, RMDIR, FILEATTR, FREEFILE.
  • ISAM (Professional-Edition des Vorbilds): wird unterstützt (Entscheidung 2026-09-02) — OPEN … FOR ISAM, Tabellen/Indizes, SEEKGT-Familie usw.; Umfang wird mit dem Inventar (Phase 3) erfasst.
  • Pfade: plattformneutral; / und \ werden akzeptiert.

11. Eingebaute Funktionen (Katalog)

Strings: LEN, LEFT$, RIGHT$, MID$ (Funktion und Anweisung), INSTR([start,] s$, such$), UCASE$, LCASE$, LTRIM$, RTRIM$, SPACE$, STRING$(n, zeichen|code), ASC, CHR$, STR$, VAL, HEX$, OCT$, LSET/RSET (Anweisungen).

Mathematik: ABS, SGN, INT (abrunden), FIX (Richtung 0), SQR, EXP, LOG, SIN, COS, TAN, ATN, RND[(n)], RANDOMIZE [saat], CINT, CLNG, CSNG, CDBL, CCUR.

Zufallszahlen. Der Generator ist der lineare Kongruenzgenerator des Vorbilds auf 24 Bit: zustand = (zustand · &H FD43FD + &H C39EC3) MOD 2^24, Ergebnis zustand / 2^24 als SINGLE im Bereich [0, 1). RND und RND(n) mit n > 0 liefern die nächste Zahl, RND(0) wiederholt die zuletzt gelieferte, RND(n) mit n < 0 setzt den Zustand aus dem Argument. RANDOMIZE saat bildet aus der Saat 16 Bit, die die Bits 823 des Zustands besetzen; das niederwertige Byte ist fest — damit liefert dieselbe Saat stets dieselbe Folge, unabhängig von vorherigen RND-Aufrufen. RANDOMIZE ohne Argument fragt den Startwert mit Random Number Seed (-32768 to 32767)? ab.

Datum/Zeit: DATE$ (Funktion und Anweisung — Setzen: Nicht-Ziel), TIME$, TIMER (Sekunden seit Mitternacht, SINGLE); dazu die nativen Schlüsselwörter des Vorbilds (Neuerung ggü. QB/PDS): NOW, DATESERIAL, DATEVALUE, TIMESERIAL, TIMEVALUE, DAY, MONTH, YEAR, WEEKDAY, HOUR, MINUTE, SECOND (serielle Datumswerte als DOUBLE) sowie FORMAT$ (Zahlen-, Datums-/Zeitformatierung).

Sonstiges: LBOUND, UBOUND, FRE(…) (freier Speicher — liefert bei uns Pseudowerte), VARPTR/VARSEG/SADD/PEEK/POKE → Nicht-Ziel (Fehler 73), ENVIRON$, COMMAND$, SHELL [cmd$].

DATA: DATA konstanten, READ var, …, RESTORE [label].

12. Forms-Anbindung (Details in forms-referenz.md)

form.eigenschaft = wert, form!steuerelement.eigenschaft, Ereignisprozeduren SUB name_Ereignis (…), LOAD/UNLOAD form, form.SHOW [style%] (0 = modeless, Standard; 1 = modal), form.HIDE, DOEVENTS(), SCREEN-Objekt, Datentypen FORM/CONTROL, IF TYPEOF, $FORM-Metabefehl, Include-Dateien (Konstanten-.BI).

Dialoge:

  • MSGBOX msg$ [,type% [,title$]] (Anweisung) bzw. Funktion → INTEGER. type% = Buttons (0 OK · 1 OK/Cancel · 2 Abort/Retry/Ignore · 3 Yes/No/Cancel · 4 Yes/No · 5 Retry/Cancel) + Default-Button (0/256/512). Rückgabe 1 OK · 2 Cancel/Esc · 3 Abort · 4 Retry · 5 Ignore · 6 Yes · 7 No. Keine Icon-Flags (Textmodus). msg$ max. 1024 Zeichen, modal.
  • INPUTBOX$(prompt$ [,title$ [,default$ [,xpos%, ypos%]]]) → STRING; Cancel liefert ""; Position in Zeichen, sonst zentriert; Dialog fest 46×16 Zeichen; prompt$ max. 255 Zeichen.

Abweichungen vom Vorbild (beschlossen)

  1. UTF-8/Unicode statt CP437 (2026-09-01). Konsequenzen:
    • STRING ist eine Folge von Unicode-Zeichen (Codepoints); LEN zählt Zeichen, nicht Bytes. ASC/CHR$ arbeiten auf Codepoints (CHR$(9731) = „☃"). ASC("") bleibt Fehler 5.
    • String-Vergleich codepoint-weise (keine CP437-Sortierung).
    • Der Bildschirmpuffer speichert Unicode-Zeichen; Rahmen werden mit Unicode-Box-Drawing gezeichnet.
    • Zeichen mit Darstellungsbreite 2 (Emoji, CJK) belegen zwei Zellen (Entscheidung 2026-09-02, umgesetzt): der Cursor rückt um zwei Spalten vor, POS nennt die Anfangsspalte, LOCATE auf die zweite Hälfte wirkt auf den Zeichenanfang. Passt ein breites Zeichen nicht mehr in die Zeile, wandert es als Ganzes in die nächste und die letzte Spalte bleibt leer. Wird eine Hälfte überschrieben, verschwindet die andere. Zeichen der Breite 0 (kombinierende Zeichen) belegen vorerst eine eigene Zelle.
    • GET/PUT-Records: feste Strings (STRING * n) werden als UTF-32 gespeichert (4 Bytes/Zeichen, feste Record-Länge) — Binärdateien sind dadurch bewusst inkompatibel zum Vorbild (Entscheidung 2026-09-02).
  2. Keine Hardware-Nähe (bestätigt 2026-09-02): PEEK/POKE/INP/ OUT/WAIT/BLOAD/BSAVE/VARPTR/VARSEG/SADD/CALL ABSOLUTE/ CALL INTERRUPT/IOCTL werden bereits zur Compile-Zeit mit der Meldung „Feature unavailable" abgewiesen (kein Laufzeitfehler). Ebenso abgewiesen: die Interlanguage-Schnittstelle (CALLS, SSEG, SSEGADD, StringAddress/StringAssign/StringLength/ StringRelease), die Eingabegeräte PEN, STRIG, STICK und die serielle Schnittstelle (COM, ON COM, OPEN "COMn:").
  3. INKEY$ für erweiterte Tasten liefert CHR$(0) + code-Sequenzen mit den klassischen Scancodes, damit bestehender Code funktioniert (festgelegt 2026-09-04): F1F10 = 5968, Pos1 = 71, ↑ = 72, Bild↑ = 73, ← = 75, → = 77, Ende = 79, ↓ = 80, Bild↓ = 81, Einfg = 82, Entf = 83. Zeichentasten liefern ein Zeichen, Eingabe CHR$(13), Rückschritt CHR$(8), Esc CHR$(27), Tabulator CHR$(9). Strg+C und Strg+Untbr sind Abbruch und erscheinen nicht in INKEY$. Tasten heutiger Tastaturen ohne Entsprechung im Vorbild (etwa F11/F12 oder Meta- Kombinationen) liefern nichts — eine eigene Kodierung dafür wäre eine Erweiterung und gehört in Stufe 2.
  4. Kein CHAIN/Overlay-Mechanismus; SHELL startet die System-Shell.
  5. Grafik-Anweisungen (SCREEN n>0, PSET, PRESET, LINE, CIRCLE, PAINT, DRAW, Grafik-GET/PUT, PALETTE, WINDOW, VIEW, PMAP, PCOPY, POINT) sind Nicht-Ziel und werden zur Compile-Zeit mit „Feature unavailable" abgewiesen. Die Formen, die sich ein Schlüsselwort mit einer unterstützten Anweisung teilen, erkennt der Compiler an ihrer Syntax: LINE ohne INPUT, GET/PUT mit (, VIEW ohne PRINT. Hinweis: das Vorbild hatte die Grafikmodi 013, aber nicht gleichzeitig mit Forms (dort Fehler 272 „Invalid when forms are showing") — wir übernehmen nur den Forms-/Textmodus-Zweig.
  6. PLAY/SOUND: BEEP = Terminal-Bell; Rest Nicht-Ziel (Fehler 73). 5a. LPRINT schreibt in eine Datei (2026-09-03): einen plattformübergreifenden Druckerkanal gibt es nicht. Der Druckerpuffer geht am Programmende in LPT1.TXT im aktuellen Verzeichnis; LPOS nennt die Spalte in diesem Puffer. 5b. Satzsperren (LOCK/UNLOCK) prüfen nur, ob die Datei offen ist; eine echte Sperre bietet die Plattform nicht einheitlich. FILEATTR liefert nur die Modus-Kennzahl (Argument 1); das Betriebssystem-Handle bildet der Dialekt nicht ab und liefert 0. 5c. CHDRIVE ist außerhalb von Windows folgenlos — Laufwerksbuchstaben gibt es dort nicht. 6a. Uhr in Ortszeit, mit Rückfall auf UTC (2026-09-04): DATE$, TIME$, TIMER und NOW rechnen in der Zeitzone des Rechners; TIMER zählt ab der lokalen Mitternacht. Der Versatz wird für den jeweils abgefragten Zeitpunkt bestimmt, nicht einmal beim Start — ein Programm, das über eine Zeitumstellung hinweg läuft, folgt ihr. Lässt sich die Zone des Rechners nicht ermitteln, gilt UTC; das Programm läuft weiter, und der Runner meldet es einmal beim Start auf der Fehlerausgabe („Zeitzone nicht ermittelbar …"). DATE$ = … und TIME$ = … stellen nicht die Systemuhr, sondern einen programmeigenen Versatz auf die Ortszeit; alle Zeitfunktionen rechnen ihn mit ein. 6b. Serielle Datumswerte zählen Tage ab dem 30.12.1899 (Serie 2 = 1.1.1900), der Nachkommaanteil ist die Tageszeit. WEEKDAY liefert 1 für Sonntag. Zweistellige Jahre gelten in DATESERIAL als 19xx, in DATEVALUE als 20xx unter 80 und sonst als 19xx.
  7. Dynamische Bildschirmgröße (2026-09-02): kein festes 80×25 — der Bildschirm folgt der Terminalgröße (Mindestgröße 80×25, darunter nur ein Hinweis). CSRLIN/POS/LOCATE/VIEW PRINT und das SCREEN-Objekt arbeiten auf der tatsächlichen Größe. WIDTH 40/80 wird akzeptiert, ändert aber nichts (die Größe bestimmt das Terminal). 80×25 ist überall nur die untere Schranke der Darstellung, nie eine Bildschirmgröße im Verhalten des Programms. Ändert sich die Größe während der Ausführung, wird das zugestellt: der Inhalt bleibt oben links erhalten, der Cursor wird in die neuen Grenzen geklemmt, und ein VIEW PRINT-Bereich wird am unteren Rand geklemmt bzw. — wenn er ganz vom Schirm fällt — auf den vollen Bildschirm zurückgesetzt.