USR

Aus C64-Wiki
Wechseln zu: Navigation, Suche
Begriffsklärung Der Titel dieses Artikels ist mehrdeutig. Weitere Bedeutungen finden sich unter USR (Begriffsklärung).
USR
Format: USR(<Parameter>)
Parameter
<Parameter>: mind. ein Parameter (Zeichenkette oder Zahl)
Einordnung
Typ: numerische Funktion
oder
String-Funktion
Kontext: System
Aufgabe: ruft eine Maschinensprache-Routine als Funktion auf
Abkürzung: uS
Verwandte Befehle
SYS

Anmerkung: Dieser Artikel beschreibt die numerische BASIC-Funktion USR unter BASIC V2 des Commodore 64.


Die BASIC-Funktion USR() ruft aus einem BASIC-Programm ein Maschinensprache-Routine als Funktion auf, wobei der Retourwert (Fließkomma oder Zeichenkette) vom aufgerufenen Ausdruck weiterverarbeitet werden kann.
Das aufgerufene Programm kann bis zur schließenden runden Klammer entsprechende Argumente verarbeiten und ist jedenfalls dafür auch selbst verantwortlich dies zu tun. Anzahl der Argumente und deren jeweilige Typ (Fließkomma, Zeichenkette) ist von der aufgerufenen Routine vorgegeben. Das Ergebnis wird der Ausdrucksauswertung zurück geliefert und kann ein numerischer Wert oder eine Zeichenkette sein. Passt der retourniert Typ nicht zu dem von der Auswertung erwarteten, bricht der Interpreter mit der Fehlermeldung ?TYPE MISMATCH ERROR ab.

Die Startadresse des Maschinenprogramms muss vor dem Aufruf von USR() im Vektor mit den Speicheradressen 785 und 786 (USR-Vektor an den hexadez. Adressen $311/$312) abgelegt werden, typischerweise mit Hilfe des BASIC-Befehls POKE. Der Rückgabewert wird im Fließkomma-Akkumulator #1 beginnend bei der Speicheradresse 97 ($61) erwartet, welcher vom BASIC-Programm als Funktionswert weiter verarbeitet werden kann. Dieser kann numerisch als Fließkommazahl vorliegen oder aber auch eine Zeichenkette sein, wobei dann in den Speicherstellen $64/$65 des Fließkomma-Akkumulators #1 der Zeiger auf einen String-Descriptor abgelegt ist.

Nach einem Systemneustart des C64 ist die Startadresse mit $B248 initialisiert, welche auf die Ausgaberoutine der BASIC-Fehlermeldung ?ILLEGAL QUANTITY ERROR verzweigt[1]. Dieser Fehler wird bei USR()-Aufruf auch geliefert, bis eine andere Adresse gesetzt wird.

In Bezug auf die Argumentsyntax, wird bei fehlenden Argumenten der Fehler ?SYNTAX ERROR ausgegeben. Weitere Fehlermeldungen hängen von der aufgerufenen Maschinenprogramm-Routine ab, die etwa zu einer Ausgabe der BASIC-Fehlermeldung ?TYPE MISMATCH ERROR führen kann, wenn ein Argument nicht den gewünschten Typ aufweist oder die nicht im erwarteten Wertebereich befindliche Argumente mit ?ILLEGAL QUANTITY ERROR ahndet. Auch andere Fehlermeldungen könnten hervorgerufen werden.

Adressen der Funktion in anderen BASIC-Varianten:

BASIC USR-Vektor Adresse nach Neustart Anmerkung
BASIC V2 (C64) 785/786
$0311/$0312
45640
$B248
-
BASIC 3.5 (264-Serie) 1281/1282
$0501/$0502
39196
$991C
-
BASIC 7.0 (C128) 4633/4634
$1219/$121A
32040
$7D28
bezogen auf Bank 15

Beispiele[Bearbeiten]

Schnelle Multiplikation mit 10[2]:

10 REM MULTIPLY BY 10 - $BAE2 ROUTINE
20 POKE 786,186: POKE 785,226
30 FOR I=1 TO 10
40 PRINT USR(1/I)
50 NEXT I

Die Ausgabe zeigt dann

 10
 5
 3.33333334
 2.5
 2
 1.66666667
 1.42857143
 1.25
 1.11111111
 1

Im Vergleich zu einer Multiplikation mit dem Ausdruck 1/I*10 ist die USR()-Variante deutlich (rund 40 %) schneller.

Mit den Zeilen

10 REM DIVIDE BY 10 - $BAFE ROUTINE
20 POKE 786,186: POKE 785,254

in obigem Beispiel hat man statt einer Mal-10-Funktion eine Durch-10-Funktion[3].

Beispiel für eine Zeichenkette als Argument

10 REM LEN()-FUNKTION - $B77C ROUTINE
20 POKE 786,183: POKE 785,124
30 PRINT USR("123")
 3

Variante der FRE()-Funktion, die dabei nicht die Garbage Collection auslöst:

10 POKE 786,179: POKE 785,135
20 PRINT USR(0),FRE(0)
-26665    -26665


Beispiel für eine Zeichenkette als Retourwert[4]

10 REM CHR$()-FUNKTION - $B6EC
20 POKE785,236: POKE786,182
30 A$=USR(49)
40 PRINT "<"+A$+">"
<1>


Referenzen[Bearbeiten]

  1. $E3BF/58303: Initialize BASIC RAM (auf AAY64) - Initialisierung des USR()-Vektors. Sprache:englisch
  2. $BAE2/47842: Multiply FAC#1 by 10 - Fließkommaakkumulator #1 mit Konstante 10 multiplizieren. Sprache:englisch
  3. $BAFE/47870: Divide FAC#1 by 10 - Fließkommaakkumulator #1 durch Konstante 10 dividieren. Sprache:englisch
  4. $B4D5/46293: Save String Descriptor - Zeichenkette in Fließkommaakkumulator #1 retournieren. Sprache:englisch