📄 basbits.html
字号:
It is recommended that you only call CREATE after a failed LVBLNK, with code such as:<br><code> STMFD R13!, {R14}<br> BL LVBLNK ; look up name<br> LDMNEFD R13!, {PC} ; return if found<br> LDMCSFD R13!, {PC} ; return if invalid name<br> BL CREATE ; create new variable<br> LDMFD R13!, {PC}</code><br> <br>Returns same result as LVBLNK when l-value found.<br>Uses all registers. <tr> <td valign=top>&44 <td valign=top>EXPR <td>Evaluates an expression pointed to by R11.<br> <br>On entry:<br><code> R8 </code>= ARGP<br><code> R11 </code>= Pointer to start of string<br><code> R12 </code>= LINE<br><code> R13 </code>= Stack pointer<br> <br>EXPR stops after reading one expression (like those in a PRINT statement).<br> <br>Returns with R0 - R3 as the value (or F0 in BASIC VI), R9 the type.<br><code>R9 = 0 </code>- String; STRACC is start, R2 is end, [R2]-STRACC is the length<br><code>R9 = &40000000 </code>- Interger; in R0<br><code>R9 = &80000000 </code>- Float; in R0...R3<br><code>R10 = </code>First character of the expression<br><code>R11 = </code>Pointer to next character after R10. <br>Additionally:<br><code>Z</code> set means expression was a string, else expression was a number<br>If <code>Z</code> clear, then <code>N</code> set means expression was a floating point number,else expression was an integer.<br> <br>A useful thing about EXPR is that it can call BASIC functions. You do this as you would in anEVAL statement, by evaluating a string containing the name of a user-defined function. Forexample <code>"FNget_next_directory_entry"</code>. This allows you to call routineswhich perform a task that would be tedious in assembler - such as input a floating point numberfrom the user.<br> <br>Unfortunately, there is a complication. The string to be evaluated should be tokenised. So youcan either call MATCH, or (possibly preferably) store the string pre-tokenised. The token forFN is &A4. <tr> <td valign=top>&48 <td valign=top>MATCH <td>Takes a text string and tokenises it to another string.<br> <br>On entry:<br><code> R1 </code>= Points to source string (ASCII 10 or 13 terminated)<br><code> R2 </code>= Points to destination string<br><code> R3 </code>= MODE<br><code> R4 </code>= CONSTA<br><code> R13 </code>= Stack pointer<br> <br><code>MODE</code> is 0 for left mode, which is for a statement at the start of a line, or beforean equals; and 1 for right-mode, in an expression.<br>This is important, consider the following:<br><code> var = TIME<br> TIME = var</code><br>It's the same word - <code>TIME</code> - but there are two different tokens for TIME, one forreading time and one for writing it.<br> <br><code>CONSTA</code> is 0 if you do not want BASIC to convert numbers which could be line numbers(0 to 65279) to internal format; and 1 if you do.<br>Internal format is the token &8D followed by three bytes containing the encoded line number.The advantage of the encoded numbering is the bytes lie in the range 64-127, so do not containany tokens or control codes. These tokens are used after GOTO, GOSUB, RESTORE, THEN and ELSE.They are fixed length, so the program can be RENUMBERed without shuffling lines around.<br> <br>Both MODE and CONSTA may be updated during the use of this function. For example,<code>PRINT</code> will change MODE to 1 to read an expression.<br> <br>Corrupts R0-R5.<br>On exit, R1 and R2 are left pointing one byte beyond the terminating control CR codes of thestrings.<br>Additionally, R5 contains status information. Typically, values larger than &1000 implymismatched brackets; and ( (R5 AND 255)=1 ) means mismatched quotes. <tr> <td valign=top>&4C <td valign=top>TOKENADDR <td>This converts a token value to a pointer to the text string that represents it.<br> <br>On entry:<br><code> R0 </code>= Token value (ie, &A4 for FN)<br><code> R12 </code>= Pointer to next byte of token<br> <br>Returns in R1 a pointer to the first character of the string, terminated by a value &7F orgreater. R0 is updated to point to the base of the token table.<br> <br>The value of R12 is only used when matching a two-byte token.<br>No other registers are used or required. <tr> <td colspan = 3> <br>If you are using BASIC V, additional floating point operationsare available. R0...R3 contain an expanded floating point value, and R9 points to a packedfloating point value (as accessed with the | operator).<br> <br> <tr> <td valign=top>&54 <td valign=top>9 <td>This is a word giving the number of additional routines that are available. <tr> <td valign=top>&58 <td valign=top>FSTA <td>Store a four-word FP value into a five-byte variable.<br> <br>On entry:<br><code> R0...R3 </code>= Source FP value<br><code> R9 </code>= Pointer destination value<br> <br>On exit, R2 may be altered, but this doesn't affect the FP value. <tr> <td valign=top>&5C <td valign=top>FLDA <td>Load a five-byte variable into a four-word FP value.<br> <br>On entry:<br><code> R9 </code>= Pointer source value<br> <br>On exit, R0...R3 contain the loaded value. <tr> <td valign=top>&60 <td valign=top>FADD <td>Add the four-word FP value in R0...R3 by the variable pointed to by R9.<br>Notically: <code>(R0...R3) + [R9]</code> <br>On entry:<br><code> R0...R3 </code>= Source FP value<br><code> R9 </code>= Pointer five-byte value<br> <br>On exit, R0...R3 is the result, and R4...R7 are corrupted.<br>Overflow errors are possible. <tr> <td valign=top>&64 <td valign=top>FSUB <td>Subtract R0...R3 from value pointed to by R9.<br>Notically: <code>[R9] - (R0...R3)</code> <br>On entry:<br><code> R0...R3 </code>= FP value<br><code> R9 </code>= Pointer five-byte value<br> <br>On exit, R0...R3 is the result, and R4...R7 are corrupted.<br>Overflow errors possible. <tr> <td valign=top>&68 <td valign=top>FMULL <td>Multiply the four-word FP value in R0...R3 by the variable pointed to by R9.<br>Notically: <code>(R0...R3) * [R9]</code> <br>On entry:<br><code> R0...R3 </code>= Source FP value<br><code> R9 </code>= Pointer five-byte value<br> <br>On exit, R0...R3 is the result, and R4...R7 are corrupted.<br>Overflow errors possible. <tr> <td valign=top>&6C <td valign=top>FDIV <td>Divide the the variable pointed to by R9 by the four-word FP value in R0...R3.<br>Notically: <code>[R9] / (R0...R3)</code> <br>On entry:<br><code> R0...R3 </code>= Source FP value<br><code> R9 </code>= Pointer five-byte value<br> <br>On exit, R0...R3 is the result, and R4...R7 are corrupted.<br>Overflow errors and divide by zero are possible. <tr> <td valign=top>&70 <td valign=top>FLOAT <td>Convert an integer to a four-word floating point value. <br>On entry:<br><code> R9 </code>= Integer<br> <br>On exit, R0...R3 is the floated version, and R9 is &80000000 (float type code). <tr> <td valign=top>&74 <td valign=top>FIX <td>Convert a four-word FP value into an integer.<br> <br>On entry:<br><code> R0...R3 </code>= Floating point value<br> <br>On exit, R0 is the fixed version (rounded towards zero), and R9 is &40000000 (integer typecode). <tr> <td valign=top>&78 <td valign=top>FSQRT <td>Take the square root of the floating point number in R0...R3. <br>On entry:<br><code> R0...R3 </code>= Floating point value<br> <br>On exit, R0...R3 is the result, and R4...R7 are corrupted.<br>Negative root error possible.</table><p>The floating point values in R0...R3 are given as follows:<br><pre>R0 = 32 bit mantissa, normalised (so bit 31 = 1)R1 = Exponent in excess-128 formR2 = UndefinedR3 = Sign, 0 is positive and &80000000 is negative</pre>This is informational only, and the developers reserve the right to change the format. You areasked to treat R0...R3 as a single item, without worrying about the constituent parts.<p> <p>Here is an example program which will list all of the tokens recognised by BASIC. It iscompletely written in assembler, so could be saved as a utility. Note, however, that it must beloaded and executed from within BASIC as the extended environment is only available from BASIC.<p>Note also, that passing invalid token values replies with junk. You can see this for yourselfif you alter the secnd token set to end at a number higher than 183.<p><pre><font size = "-1">REM >listtokensREMREM Lists the tokens recognised by BASICDIM code% 396FOR pass = 8 TO 10 STEP 2 P% = code% L% = code% + 396 [ OPT pass .begin STMFD R13!, {R14} MOV R5, R14 ; for token print routine ADR R0, starttitle SWI "OS_Write0" BL firstset SWI "OS_NewLine" BL secondset ADR R0, endtitle SWI "OS_Write0" LDMFD R13!, {PC} .token \ This prints a token using BASIC's internal routine. \ Call with R0 set to the token number. STMFD R13!, {R14} CMP R0, #255 ADRHI R12, tokenbuffer SUBHI R0, R0, #256 STRHI R0, tokenbuffer MOVHI R0, #200 ADR R14, back ADD PC, R5, #&4C .back .tokenloop LDRB R0, [R1], #1 CMP R0, #&7F SWICC "OS_WriteC" BCC tokenloop LDMFD R13!, {PC} .tokenbuffer EQUD 0 .firstset \ These are the first tokens, 127 to 255 (but not 200) STMFD R13!, {R14} MOV R10, #127 .firstloop SWI "OS_WriteS" EQUS "Token "+CHR$0 ALIGN MOV R0, R10 BL print_number SWI "OS_WriteS" EQUS " is "+CHR$0 MOV R0, R10 CMP R0, #200 BLEQ special BLNE token SWI "OS_NewLine" ADD R10, R10, #1 CMP R10, #256 BLT firstloop LDMFD R13!, {PC} .special SWI "OS_WriteS" EQUS "extension token"+CHR$0 MOV PC, R14 .secondset \ These are the first tokens, 127 to 183 STMFD R13!, {R14} MOV R10, #127 .secondloop SWI "OS_WriteS" EQUS "Token 200+"+CHR$0 ALIGN MOV R0, R10 BL print_number SWI "OS_WriteS" EQUS " is "+CHR$0 MOV R0, R10 ADD R0, R0, #256 BL token SWI "OS_NewLine" ADD R10, R10, #1 CMP R10, #184 BLT secondloop LDMFD R13!, {PC} .print_number ADR R1, number_buffer MOV R2, #8 SWI "OS_BinaryToDecimal" ADR R0, number_buffer SWI "OS_Write0" MOV PC, R14 .number_buffer EQUD 0 EQUD 0 .starttitle EQUS "BASIC: tokens and their keywords"+CHR$13+CHR$10 EQUS "--------------------------------"+CHR$13+CHR$10+CHR$13+CHR$10+CHR$0 ALIGN .endtitle EQUS CHR$13+CHR$10+"Finished."+CHR$13+CHR$10+CHR$13+CHR$10+CHR$0 ALIGN ]NEXTCALL beginEND</font></pre><div align = right><a href="sw/listtokens.basic"><i>Download this example</i></a></div><p> <p><hr size = 3><a href="index.html#04">Return to assembler index</a><hr size = 3><address>Copyright © 2001 Richard Murray</address></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -