USR
From C64-Wiki
| BASIC keyword | |
| Keyword: | USR |
| Abbreviation: | U Shift+S |
| Type: | Function |
| Token code: | 183/$B7 |
| Handling routine in BASIC ROM: | 784–786 $0310–0312 |
| List of all BASIC keywords | |
Remark: This article describes the BASIC-Command USR in BASIC V2 at the Commodore 64.
Type: Floating Point Function General Programming-Syntax: USR(<Number>)
USR is a user-defined function in the built-in BASIC interpreter: It accepts a floating point real number, calls a user-defined machine language routine, and returns a resulting real number.
The addresses 785–786/$0311–$0312 form a pointer to the routine. Right after a cold start (power-on or reset), this pointer is set to 45640/$B248, where a short routine sends the system right into the BASIC error handler to report an ?ILLEGAL QUANTITY ERROR — not a particular useful function...!
To make USR "do something useful", one must first provide a machine language routine that "does the useful part": This routine should "expect" it's input value to be in FAC, and must "deposit" it's resulting output value in FAC, before ending in an RTS.
USR allows "mixing" calculations performed in machine language and BASIC, like e.g.
B=X+40*USR(SQR(X)*1.667)
As with any floating point argument, the size limits are ±2.93873588·10−38 to ±1.70141183·1038 — exceeding them yields an ?OVERFLOW ERROR IN line. Likewise the argument is not optional, so omitting it will result in a ?SYNTAX ERROR IN line. USR also accepts an integer arument, but if called with a string argument, a ?TYPE MISMATCH ERROR IN line will occur.
[edit] Example
To demonstrate the USR function, try these POKE's to re-direct the USR function to the ROM routine called DIV10 at 47870/$BAFE, which divides the given floating point real numer by 10:
POKE 785,254:POKE 786,186
This turns the USR function into a "divide-by-ten function". You can test it by typing e.g.:
PRINT USR(64) 6.4 READY.
In this example, the argument in the parenthesis (the "64") was converted to a floating point number located in FAC (97–102/$61–$66), before the routine was called: In this example, the 64 was divided by 10, yielding 6.4. When the routine has done its job and returned control to the system, the result is parsed in the BASIC expression.
- Another example
10 S1 = USR(123) 20 PRINT S1 30 PRINT USR(S1)
ABS | AND | ASC | ATN | CHR$ | CLOSE | CLR | CMD | CONT | COS | DATA | DEF | DIM | END | EXP | FN | FOR | FRE | GET | GET# | GOSUB | GOTO | IF | INPUT | INPUT# | INT | LEFT$ | LEN | LET | LIST | LOAD | LOG | MID$ | NEW | NEXT | NOT | ON | OPEN | OR | PEEK | POKE | POS | PRINT | PRINT# | READ | REM | RESTORE | RETURN | RIGHT$ | RND | RUN | SAVE | SGN | SIN | SPC( | SQR | STATUS/ST | STEP | STOP | STR$ | SYS | TAB( | TAN | THEN | TIME/TI | TIME$/TI$ | TO | USR | VAL | VERIFY | WAIT