Changes

Jump to: navigation, search

Technical information about Locomotive BASIC

13,293 bytes added, 18:11, 26 December 2022
/* BASIC tokens */ typo
The are two versions of Locomotive BASIC used in the Amstrad CPC and CPC+ computers. v1.0 is used by the CPC464, and v1.1 is used by the CPC664, CPC6128, CPC464+ and CPC6128+[[Category:Cpctech.org]]
== Passing parameters to a RSX (Resident System Extension) command or binary function =='''''This article originally came from Kevin Thackers' archive at [http://www.cpctech.org.uk http://www.cpctech.org.uk].'''''
A RSX (Resident System Extension) command is accessed through = Technical information about Locomotive BASIC with a "|" character prefix. e.g. The "DIR" RSX, is accessed by "|DIR". =
A binary function is accessed through The are two versions of Locomotive BASIC using used in the Amstrad CPC and CPC+ computers. v1.0 is used by the CPC464, and v1.1 is used by the "CALL" commandCPC664, CPC6128, CPC464+ and CPC6128+.
Passing a string parameter:== BASIC v1.0 only ==
BASIC v1.0 There is a$="A"region of memory between AC00-AC1B which is filled with RET instructions. The BASIC ROM calls the following locations:|DRIVEAC01,@a$AC04,AC07,AC0A,AC0D,AC10,AC13,AC16,AC19
BASIC v1It almost looks like these were used for debugging the ROM but were left in.1:
|DRIVE,"A"They can be used to implement new BASIC commands.
== Additional keywords and variables in BASIC v1.1 Passing parameters to a RSX (Resident System Extension) command or binary function ==
* A RSX (Resident System Extension) command is accessed through BASIC v1with a "|" character prefix.1 has e.g. The "DIR" RSX, is accessed by "|DIR". A binary function is accessed through BASIC using the following additional keywords:"CALL" command.
Both RSX and CALL commands work (are!) similar from the BASIC command line and invoke machine code - the only difference is:* COPYCHR$with the help of a RSX command you don't need to know the exact access address. You can pass up to 32 parameters with a CALL or RSX command. Possible parameters could be integer, floating points and strings. Just store the parameter into a variable:* CURSORPassing for integer:* DEC$:* FILL<pre>:* FRAMECALL &4000,32,34,&5E,&x10101010:* GRAPHICS|RSX-command,32,34,&5E,&x10101010:* MASK </pre>Passing for floating points<pre>@a!=43.375CALL or |RSX-command,@a!</pre>
* <br> Passing a string parameter: <br> BASIC v1.0 <pre>a$="A":|DRIVE,@a$</pre> BASIC v1.1 has the following additional predefined variables:<pre>|DRIVE,"A"</pre>or<pre>b$="test"CALL or |RSX-command,@b$</pre>
The parameters will be stored inside the range of Stack:* DERR <pre> A=n -------> MSB PARAM1 LSB PARAM1 MSB PARAM2 LSB PARAM2 ... ... ... MSB PARAMn IX+0 ------> LSB PARAMn</pre>with the help of that assembly code is it possible to find the parameters:<pre>ROUT1: CP x ;test register A if "x" parameters were given, e.g. x = 2 RET NZ ; if not exactly x parameters then do not execute RSX. LD L,(IX+0) LD H,(IX+1) ; HL = value of last parameter LD E,(IX+2) LD D,(IX+3) ; DE = value of next to last parameter ...</pre>A register holds the number of parameters. IX points to each parameter. IX+0/IX+1 is the last parameter. This happens because each parameter in order is pushed onto the stack and IX then points to the last parameter pushed. Each parameter is a 16-bit value.
If a parameter is a string, then IX holds the address of the string descriptor which point to a 3 byte block. The first byte of the string descriptor is the length. The next 2 bytes are an address that point to the string in memory. With the help of the variable container "@" it is also possible to get a result from an invoked mc-code back to basic.In this case the parameter contains the address of the integer, floating point or string. You can modify these to give the result.BASIC allocates the strings, so when you modify a string, do not write more characters than the original string. Hint: the first two bytes at the end of stack shows the internal return address from BASIC interpreter where it was executed. == Additional keywords and variables in BASIC v1.1 == #BASIC v1.1 has the following additional keywords: #*COPYCHR$ #*CURSOR #*DEC$ #*FILL #*FRAME #*GRAPHICS #*MASK #BASIC v1.1 has the following additional predefined variables: #*DERR <br> <br>  == Entering BASIC programs ==
A maximum of 255 characters can be entered for a single BASIC line.
This There are some rules for assigning names for variables:: - it is converted into not allowed to define a variable starting with a figure (the tokenised BASIC system expect then programming mode and interpret it as a program which is more compact than the line entered. The number): - no space (or 'under' as it is common today) between variable names are allowed: - BASIC keywords are converted into "tokens", or 1can't be used: -2 byte sequences different sign e.g.: a slash (doesn't depend which uniquely identify each keyworddirection), a 'minus' sign, a 'and' sign can't be used in a variable names: - after a dollar sign (for defining string variables) it is not allowed to use further signs: - different defining functions together are not allowed (e.g.use '%' together with '$')
== Structure of : - you can use 40 characters for a BASIC program ==variable name: - use ! for defining a REAL value variable (like the function DEFREAL but only for the assigned variable) > It's also possible to omit the exlamation mark because it's the default system declaration after powering on then CPC.: - use % for defining a INTEGER value variable (like the function DEFINT but only for the assigned variable): - use $ for defining a STRING variable (like the function DEFSTR but only for the assigned variable): - Minimum line number is 1. Maximum line number is 65535.
A This is converted into the tokenised BASIC program which is stored in a tokenised format. Here more compact than the line entered. The BASIC keywords are represented by 1 converted into "tokens", or 1-2 byte unique sequenceswhich uniquely identify each keyword.
Each line of the BASIC program has the form:<br>
Offset Size Description0 2 Length of line data in bytes (note 1)2 2 16-bit decimal integer line number (note 2)4 n == Speeding up BASIC line encoded into tokens (note 3)n+1 1 "0" the end of line marker (note 4)programs ==
NotesTo speed up BASIC programs following rules could help:: - Avoid loops or a branching program structure if possible. Internally the operating system searches for the right line number always from the beginning of the program 'listing'. Often recurring subroutines (if necessary) should be at the beginning of RAM to speed up things.: - Avoid the index variable after the <code>NEXT</code> command/statement (although it isn't a good program style): - Avoid spaces inside program code or remarks: - Put lots of statements as possible in ONE line: - Use variables instead of constants. A constand has always to be converted in a binary/digital format. A variable is already converted.: - Dimensioning at the beginning of the program: - Dimensioning your variables & pre-calculate: - Avoid AND/OR/XOR in IF-THEN statements. It's faster to write IF ... THEN (statement 1).. IF ... THEN (statement 2).
* This 16-bit value has two functions::* if "0" it signals the end == Structure of the BASIC program. In this case, there is no furthur BASIC program lines or data.:* otherwise, this value defines the length of the tokenised BASIC program line in bytes, and includes the 2 bytes defining this value, the 2 bytes defining the program line number, and the end of line marker. This number is stored in little endian notation with low byte followed by high byte. * This 16-bit value defines the line number and exists if the length of line data in bytes is not "0". A line number is a integer number in the range 1-65535. This number is stored in little endian notation with low byte followed by high byte.* This data defines the tokenised BASIC program line and exists if the length of line data in bytes is not "0". The length is dependant on the BASIC program line contents.* This value defines the end of the tokenised BASIC line data and exists if the length of line data in bytes is not "0". The BASIC interpreter looks for this token during the processing of this line, and if found, will stop execution and continue to the next line. ==
== A BASIC tokens ==program is stored in a tokenised format. Here the keywords are represented by 1 or 2 byte unique sequences. Each line of the BASIC program has the form:
This table list the BASIC tokens with no prefix byte.<br>
Code(hexidecimal) BASIC keyword&00 end of tokenised line marker&01 {| border=":1" statement seperator&02 integer variable definition (defined with "%" suffix)|-&03 string variable definition (defined with "$" suffix)! Offset &04 floating point variable definition (defined with "!" suffix)Size &05 var?! Description&06 var?|-&07 var?| 0 &08 var?| 2 &09 var?&0a var?&0b variable definition | Length of line data in bytes (no suffixnote 1)&0c variable definition (no suffix)|-&0d variable definition (no suffix)| 2 &0e number constant "0"&0f number constant "1"&10 number constant "| 2"&11 number constant "3"&12 number constant "4"&13 number constant "5"&14 number constant "6"&15 number constant "7"&| 16 number constant "8"&17 number constant "9"&18 number constant "10"&19 8-bit integer decimal value&1a 16-bit integer decimal value&1b 16-bit integer binary value line number (with "&X" prefixnote 2)&1c 16|-bit integer hexadecimal value (with "&H" or "&" prefix)&1d 16-bit BASIC program line memory address pointer| 4 &1e 16-bit integer | n | BASIC line number&1f floating point value&20 " " encoded into tokens (spacenote 3) symbol&21 ASCII "!" symbol&22 quoted string value&23|-7b ASCII printable symbols&7c "|" symbol; prefix for RSX commandsn+1 &80 AFTER| 1 &81 AUTO&82 BORDER&83 CALL&84 CAT&85 CHAIN&86 CLEAR&87 CLG&88 CLOSEIN&89 CLOSEOUT&8a CLS&8b CONT&8c DATA&8d DEF&8e DEFINT&8f DEFREAL&90 DEFSTR&91 DEG&92 DELETE&93 DIM&94 DRAW&95 DRAWR&96 EDIT&97 ELSE&98 END&99 ENT&9a ENV&9b ERASE&9c ERROR&9d EVERY&9e FOR&9f GOSUB, GO SUB&a0 GOTO, GO TO&a1 IF&a2 INK&a3 INPUT&a4 KEY&a5 LET&a6 LINE&a7 LIST&a8 LOAD&a9 LOCATE&aa MEMORY&ab MERGE&ac MID$&ad MODE&ae MOVE&af MOVER&b0 NEXT&b1 NEW&b2 ON&b3 ON BREAK&b4 ON ERROR GOTO, ON ERROR GO TO&b5 SQ&b6 OPENIN&b7 OPENOUT&b8 ORIGIN&b9 OUT&ba PAPER&bb PEN&bc PLOT&bd PLOTR&be POKE&bf PRINT&c0 | "'0" symbol (same function as REM keyword)&c1 RAD&c2 RANDOMIZE&c3 READ&c4 RELEASE&c5 REM&c6 RENUM&c7 RESTORE&c8 RESUME&c9 RETURN&ca RUN&cb SAVE&cc SOUND&cd SPEED&ce STOP&cf SYMBOL&d0 TAG&d1 TAGOFF&d2 TROFF&d3 TRON&d4 WAIT&d5 WEND&d6 WHILE&d7 WIDTH&d8 WINDOW&d9 WRITE&da ZONE&db DI&dc EI&dd FILL (v1.1)&de GRAPHICS (v1.1)&df MASK (v1.1)&e0 FRAME (v1.1)&e1 CURSOR (v1.1)&e2 (note 2)&e3 ERL&e4 FN&e5 SPC&e6 STEP&e7 SWAP&e8 (note 2)&e9 (note 2)&ea TAB&eb THEN&ec TO&ed USING&ee > (greater than)&ef = (equal)&f0 >=, > =, => (greater or equal)&f1 < (less than)&f2 <>, < > (not equal)&f3 =<, <=, < = (less than or equal)&f4 + (addition)&f5 - (subtraction or unary minus)&f6 * (multiplication)&f7 / (division)&f8 ^ (x to the power end of y)&f9 \ line marker (integer divisionnote 4)&fa AND&fb MOD&fc OR&fd XOR&fe NOT&ff (prefix for additional keywords)|}
<br> Notes:
* The &ff code is used as a prefix for more keywords. See #This 16-bit value has two functions: if "0" it signals the table below for end of the BASIC program. In this case, there is no furthur BASIC program lines or data, otherwise, this value defines the list length of keywords using the tokenised BASIC program line in bytes, and includes the 2 bytes defining this prefixvalue, the 2 bytes defining the program line number, and the end of line marker. This number is stored in little endian notation with low byte followed by high byte.* &e2,&e8 #This 16-bit value defines the line number and &e9 are exists if the length of line data in bytes is not used* &7c ("|0") . A line number is a character prefix used integer number in the range 1-65535. This number is stored in little endian notation with low byte followed by high byte. #This data defines the tokenised BASIC program line and exists if the length of line data in bytes is not "0". The length is dependant on the BASIC program line contents. #This value defines the end of the tokenised BASIC line data and exists if the length of line data in bytes is not "0". The BASIC interpreter looks for this token during the processing of this line, and if found, will stop execution and continue to identify a RSX commandthe next line.
e.g. "|DIR".== BASIC tokens ==
An RSX is encoded in a BASIC program using This table list the following structure:BASIC tokens with no prefix byte.
Offset Count Description 0 1 "|" character prefix 1 1 8-bit byte offset to tokens following RSX name. 2 x RSX name. (Last character of name has bit 7 set to "1", all other characters have bit 7 set to "0")* This token identifies a integer (16-bit) number. The two bytes following this token is the number, stored low byte then high byte. e.g. &19,&2d,&00 represents the integer number "&002d"="45".* This token (&0B) is changed at run-time to &0D* This token identifies a integer variable. 02,00,00,var name offset to number in program setup when program RUN. The variable name is stored directly, with bit 7 of the last character set.* This token identifies a string variable. offset to string in program string stored AS IS with quotes around it.* This token identifies a floating point number. Immediatly following the token are 5 bytes which define the number.<br>
Offset Count Description 0 {| border="1 "|-! Code<br>(hexidecimal) ! BASIC keyword|-| &1f amp;00 | end of tokenised line marker|-| &amp;01 | ":" statement seperator|-| &amp;02 | integer variable definition (note 1defined with "%" suffix) 1 5 Floating point number |-| &amp;03 | string variable definition (note 2defined with "$" suffix) 1. This byte is the BASIC token identifying a floating point number|- 2. These 5 bytes define the | &amp;04 | floating point number. variable definition (defined with "!" suffix) * The space symbol is used as a command seperator|- * Variable definitions:| &amp;05 o The | var?|-| &amp;06 | var?|-| &amp;07 | var?|-| &amp;08 | var?|-| &amp;09 | var?|-| &amp;0a | var?|-| &amp;0b | variable definition has the following structure:(no suffix) Offset Count Description|- | &amp;0c | variable definition (no suffix)|-| &amp;0d | variable definition (no suffix)|-| &amp;0e | number constant "0 "|-| &amp;0f | number constant "1 Token defining variable type" 2 |-| &amp;10 | number constant "2 "|-| &amp;11 | number constant "3"|-| &amp;12 | number constant "4"|-| &amp;13 | number constant "5"|-| &amp;14 | number constant "6"|-| &amp;15 | number constant "7"|-| &amp;16| number constant "8"|-| &amp;17 | number constant "9"|-| &amp;18 | number constant "10"|-| &amp;19 | 8-bit Byte offset to variable integer decimal value within tokenised |-| &amp;1a | 16-bit integer decimal value|-| &amp;1b | 16-bit integer binary value (with "&amp;X" prefix)|-| &amp;1c | 16-bit integer hexadecimal value (with "&amp;H" or "&amp;" prefix)|-| &amp;1d | 16-bit BASIC programline memory address pointer (see notes)|-| &amp;1e | 16-bit integer BASIC line number|-| &amp;1f | floating point value|-| &amp;20 | " " (space) symbol|-| &amp;21 | ASCII "!" symbol|-| &amp;22 | quoted string value|-| &amp;23-7b | ASCII printable symbols|-| &amp;7c | "&#124;" symbol; prefix for RSX commands|-| &amp;80 | AFTER|-| &amp;81 | AUTO|-| &amp;82 | BORDER|-| &amp;83 | CALL|-| &amp;84 | CAT|-| &amp;85 | CHAIN|-| &amp;86 | CLEAR|-| &amp;87 | CLG|-| &amp;88 | CLOSEIN|-| &amp;89 | CLOSEOUT|-| &amp;8a | CLS|-| &amp;8b | CONT|-| &amp;8c | DATA|-| &amp;8d | DEF|-| &amp;8e | DEFINT|-| &amp;8f | DEFREAL|-| &amp;90 | DEFSTR|-| &amp;91 | DEG|-| &amp;92 | DELETE|-| &amp;93 | DIM|-| &amp;94 | DRAW|-| &amp;95 | DRAWR|-| &amp;96 | EDIT|-| &amp;97 | ELSE|-| &amp;98 | END|-| &amp;99 | ENT|-| &amp;9a | ENV|-| &amp;9b | ERASE|-| &amp;9c | ERROR|-| &amp;9d | EVERY|-| &amp;9e | FOR|-| &amp;9f | GOSUB, GO SUB|-| &amp;a0 | GOTO, GO TO|-| &amp;a1 | IF|-| &amp;a2 | INK|-| &amp;a3 | INPUT|-| &amp;a4| KEY|-| &amp;a5 | LET|-| &amp;a6 | LINE|-| &amp;a7 | LIST|-| &amp;a8 | LOAD|-| &amp;a9 | LOCATE|-| &amp;aa | MEMORY|-| &amp;ab | MERGE|-| &amp;ac | MID$|-| &amp;ad | MODE|-| &amp;ae | MOVE|-| &amp;af | MOVER|-| &amp;b0 | NEXT|-| &amp;b1 | NEW|-| &amp;b2 | ON|-| &amp;b3 | ON BREAK|-| &amp;b4 | ON ERROR GOTO, ON ERROR GO TO|-| &amp;b5 | ON SQ|-| &amp;b6 | OPENIN|-| &amp;b7 | OPENOUT|-| &amp;b8 | ORIGIN|-| &amp;b9 | OUT|-| &amp;ba | PAPER|-| &amp;bb | PEN|-| &amp;bc | PLOT|-| &amp;bd | PLOTR|-| &amp;be | POKE|-| &amp;bf | PRINT|-| &amp;c0 | "'" symbol (same function as REM keyword)|-| &amp;c1 | RAD|-| &amp;c2 | RANDOMIZE|-| &amp;c3 | READ|-| &amp;c4 | RELEASE|-| &amp;c5 | REM|-| &amp;c6 | RENUM|-| &amp;c7 | RESTORE|-| &amp;c8 | RESUME|-| &amp;c9 | RETURN|-| &amp;ca | RUN|-| &amp;cb | SAVE|-| &amp;cc | SOUND|-| &amp;cd | SPEED|-| &amp;ce | STOP|-| &amp;cf | SYMBOL|-| &amp;d0 | TAG|-| &amp;d1 | TAGOFF|-| &amp;d2 | TROFF|-| &amp;d3 | TRON|-| &amp;d4 | WAIT|-| &amp;d5 | WEND|-| &amp;d6 | WHILE|-| &amp;d7 | WIDTH|-| &amp;d8 | WINDOW|-| &amp;d9 | WRITE|-| &amp;da | ZONE|-| &amp;db | DI|-| &amp;dc | EI|-| &amp;dd | FILL (v1.1) 4 |-| &amp;de | GRAPHICS (v1.1)|-| &amp;df | MASK (v1.1)|-| &amp;e0 | FRAME (v1.1)|-| &amp;e1 | CURSOR (v1.1)|-| &amp;e2 | (note 2)|-| &amp;e3 | ERL|-| &amp;e4 | FN|-| &amp;e5 | SPC|-| &amp;e6 | STEP|-| &amp;e7 | SWAP|-| &amp;e8 | (note 2)|-| &amp;e9 | (note 2)|-| &amp;ea | TAB|-| &amp;eb | THEN|-| &amp;ec | TO|-| &amp;ed | USING|-| &amp;ee | &gt; (greater than)|-| &amp;ef | = (equal)|-| &amp;f0 | &amp;gt=, &gt;&nbsp;=, =&gt; (greater or equal)|-| &amp;f1 | &lt; (less than)|-| &amp;f2 | &lt;&amp;gt, &lt;&nbsp;&gt; (not equal)|-| &amp;f3 | =&lt;, &lt;=, &lt;&nbsp;= (less than or equal)|-| &amp;f4 | + (addition)|-| &amp;f5 | - (subtraction or unary minus)|-| &amp;f6 | * (multiplication)|-| &amp;f7 | / (division)|-| &amp;f8 | ^ (x Variable nameto the power of y)|-| &amp;f9 | \ (integer division)|-| &amp;fa | AND|-| &amp;fb | MOD|-| &amp;fc | OR|-| &amp;fd | XOR|-| &amp;fe | NOT|-| &amp;ff | (prefix for additional keywords)|}
The 16-bit byte offset is initially set to 0, but is setup when the program is RUN. The offset is stored in little-endian format, with low byte followed by high byte. o The token byte defines the variable type (i.e. string, floating point, integer) and the suffix ("$", none and "%"). o The variable name is stored in the program, with bit 7 of the last character set to "1". e.g. The variable named "abc" will be encoded as 'a','b','c'+&80 * String values<br> Notes: o Each string value is prefixed with &22 token. o All strings must be enclosed by double quote symbols ("). This symbols define the start and end of the string value. o The string value can contain any symbol except the quote ("). i.e. 0-&21, and &23-&ff can be used. * After running a program, Tokens of "1d" with 16-bit BASIC program line pointers are changed to token "1e" with the 16-bit memory address of the BASIC line number in memory.
This *The &amp;ff code is used as a prefix for more keywords. See the table list below for the BASIC tokens with a list of keywords using this prefix. *&ff amp;e2,&amp;e8 and &amp;e9 are not used *&amp;7c ("|") is a character prefix byteused to identify an RSX command. e.g. "|DIR".
Code(hexidecimal) An RSX is encoded in a BASIC keyword&00 ABS&01 ASC&02 ATN&03 CHR$&04 CINT&05 COS&06 CREAL&07 EXP&08 FIX&09 FRE&0a INKEY&0b INP&0c INT&0d JOY&0e LEN&0f LOG&10 LOG10&11 LOWER$&12 PEEK&13 REMAIN&14 SGN&15 SIN&16 SPACE$&17 SQ&18 SQR&19 STR$&1a TAN&1b UNT&1c UPPER$&1d VAL (note 2)&40 EOF&41 ERR&42 HIMEM&43 INKEY$&44 PI&45 RND&46 TIME&47 XPOS&48 YPOS&49 DERR (v1.1) (note 3)&71 BIN$&72 DEC$ (v1.1)&73 HEX$&74 INSTR&75 LEFT$&76 MAX&77 MIN&78 POS&79 RIGHT$&7a ROUND&7b STRING$&7c TEST&7d TESTR&7e COPYCHR$ (v1.1)&7f VPOS (note 4)program using the following structure:
NOTES:{| border="1"|-! Offset ! Count ! Description|-| 0 | 1 | "&#124;" character prefix|-| 1 | 1 | 8-bit byte offset to tokens following RSX name.|-| 2 | x | RSX name. (Last character of name has bit 7 set to "1", all other characters have bit 7 set to "0")|}
* These codes are prefixed by &FFThis token identifies a integer (16-bit) number. The two bytes following this token is the number, stored low byte then high byte. e.g. The keyword &amp;1a,&amp;2d,&amp;00 represents the integer number "ABS&amp;002d" ="45". *This token (&amp;0B) is changed at run-time to &amp;0D *This token identifies a integer variable. 02,00,00,var name offset to number in program setup when program RUN. The variable name is stored as directly, with bit 7 of the last character set. *This token identifies a string variable. offset to string in program string stored AS IS with quotes around it. *This token identifies a floating point number. Immediatly following sequence:the token are 5 bytes which define the number.
{| border="1"|-! Offset ! Count ! Description|-| 0 | 1 | &FF,&00amp;1f (note 1)|-| 1 | 5 | Floating point number (note 2)|}
* Codes &1e#This byte is the BASIC token identifying a floating point number *#These 5 bytes define the floating point number...&3f inclusive are not used* Codes &4a...&6f inclusive are not The space symbol is usedas a command seperator * Codes &80...&ff inclusive are not usedVariable definitions: **The variable definition has the following structure:
{| border== Floating Point data definition =="1"|-! Offset ! Count ! Description|-| 0 | 1 | Token defining variable type|-| 2 | 2 | 16-bit Byte offset to variable value within tokenised BASIC program.|-| 4 | x | Variable name|}
A floating point number represents a number <br> The 16-bit byte offset is initially set to 0, but is setup when the program is RUN. The offset is stored in little-endian format, with both an integer and fractional partlow byte followed by high byte.
In Amstrad BASIC**The token byte defines the variable type (i.e. string, a floating point number , integer) and the suffix ("$", none and "%"). **The variable name is stored in base-2 in the program, with bit 7 of the last character set to "1". e.g. The variable named "abc" will be encoded as 'a normalized form','b','c'+&amp;80 *String values:**Each string value is prefixed with &amp;22 token. **All strings must be enclosed by double quote symbols (&amp;quot). This symbols define the start and end of the string value. **The string value can contain any symbol except the quote ("). i.e. 0-&amp;21, and &amp;23-&amp;ff can be used.
1 x 2<exponent>*After running a program, Tokens of "1d" with 16-bit BASIC program line pointers are changed to token "1e" with the 16-bit memory address of the BASIC line number in memory.
The representation uses 5 bytes and is stored using <br> This table list the following structure:BASIC tokens with a &amp;ff prefix byte.
Byte 0 1 2 3 4Bit 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0Function mantissa (bits 23-16) mantissa (bits 15-8) mantissa (bits 7-0) sign mantissa (bits 30-24) exponent<br>
{| border=== Sign ==="1"|-! Code<br>(hexidecimal) ! BASIC keyword|-| &amp;00 | ABS|-| &amp;01 | ASC|-| &amp;02 | ATN|-| &amp;03 | CHR$|-| &amp;04 | CINT|-| &amp;05 | COS|-| &amp;06 | CREAL|-| &amp;07 | EXP|-| &amp;08 | FIX|-| &amp;09 | FRE|-| &amp;0a | INKEY|-| &amp;0b | INP|-| &amp;0c | INT|-| &amp;0d | JOY|-| &amp;0e | LEN|-| &amp;0f | LOG|-| &amp;10 | LOG10|-| &amp;11 | LOWER$|-| &amp;12 | PEEK|-| &amp;13 | REMAIN|-| &amp;14 | SGN|-| &amp;15 | SIN|-| &amp;16 | SPACE$|-| &amp;17 | SQ|-| &amp;18 | SQR|-| &amp;19 | STR$|-| &amp;1a | TAN|-| &amp;1b | UNT|-| &amp;1c | UPPER$|-| &amp;1d | VAL|-| &nbsp; | (note 2)|-| &amp;40 | EOF|-| &amp;41 | ERR|-| &amp;42 | HIMEM|-| &amp;43 | INKEY$|-| &amp;44 | PI|-| &amp;45 | RND|-| &amp;46 | TIME|-| &amp;47 | XPOS|-| &amp;48 | YPOS|-| &amp;49 | DERR (v1.1)|-| &nbsp; | (note 3)|-| &amp;71 | BIN$|-| &amp;72 | DEC$ (v1.1)|-| &amp;73 | HEX$|-| &amp;74 | INSTR|-| &amp;75 | LEFT$|-| &amp;76 | MAX|-| &amp;77 | MIN|-| &amp;78 | POS|-| &amp;79 | RIGHT$|-| &amp;7a | ROUND|-| &amp;7b | STRING$|-| &amp;7c | TEST|-| &amp;7d | TESTR|-| &amp;7e | COPYCHR$ (v1.1)|-| &amp;7f | VPOS|-| &nbsp; | (note 4)|}
The sign is represented by bit 7 of byte 3.<br> NOTES:
*These codes are prefixed by &amp;FF. e.g. The value of keyword "ABS" is stored as the sign bit indicates the sign of the floating point numberfollowing sequence: <pre>&amp;FF,&amp;00</pre> *Codes &amp;1e...&amp;3f inclusive are not used *Codes &amp;4a...&amp;6f inclusive are not used *Codes &amp;80...&amp;ff inclusive are not used
* If When a BASIC program is in memory, the sign BASIC ROM can replace "16-bit is BASIC program line number"1tokens with ", then the number is negative.* If the sign 16-bit is BASIC program line memory address pointer"0", then the number is positive.
=== Mantissa ===When a program is loaded or saved, there will only be "16-bit BASIC program line number" tokens followed by a 16-bit number of the line.
The mantissa holds When a program is running, BASIC will replace the normalized "16-bit BASIC program line number. The exponent is manipulated so that " with the most significant "16-bit is always 1. Since it is always 1BASIC program line memory address pointer" token, it is not stored. It's value is implied by and replace the representation16-bit line number with the memory address of the start of that line.
=== Exponent ===It does this to avoid having to lookup the address of the line each time.
The exponent * When a REM or ' is 8-bit and seen, the characters following it are output directly (i.e. the bytes are not tokenized) until the end of line or a ':' is stored in byte 4seen.
It * When a BASIC program is stored with listed each line is converted to a bias string (this includes the line number and the tokens converted to their strings). There is a maximum length for this string of 128256 characters. This means that if the BASIC line is LISTed or EDITed, then the line will be displayed incorrectly with missing characters on the end. This is also noticed if you have a "10-liner" program that packs as much BASIC as possible into each line and renumber it so the line number has more digits.
* 128-255 are positive exponents,* 0-127 are negative exponents. == Floating Point data definition ==
To obtain the signed exponent, you must subtract 128 from the stored exponentA floating point number represents a number with both an integer and fractional part.
The minimum exponent is 0 and this describes <br> In Amstrad BASIC, a floating point number of 2^is stored in base-127.2 in a normalized form: 1 x 2<sup>&lt;exponent&gt;</sup> The representation uses 5 bytes and is stored using the following structure:
The maximum exponent is 255 and this describes a number of 2^128.<br>
{| border="1"|-! Byte ! colspan= BASIC floating"8" | 0 ! colspan="8" | 1 ! colspan="8" | 2 ! colspan="8" | 3 ! colspan="8" | 4|-point/real variables ! Bit ! 7 ! 6 ! 5 ! 4 ! 3 ! 2 ! 1 ! 0 ! 7 ! 6 ! 5 ! 4 ! 3 ! 2 ! 1 ! 0 ! 7 ! 6 ! 5 ! 4 ! 3 ! 2 ! 1 ! 0 ! 7 ! 6 ! 5 ! 4 ! 3 ! 2 ! 1 ! 0 ! 7 ! 6 ! 5 ! 4 ! 3 ! 2 ! 1 ! 0|-| Function | colspan="8" | (LSB) mantissa (bits 31-24) | colspan="8" | mantissa (bits 23-16) | colspan="8" | mantissa (bits 15-8) | colspan="1" | sign | colspan="7" | (MSB) mantissa (bits 7-0) | colspan="8" | exponent|}
A floating point (real) variable describes a number with integer and fractional parts.=== Sign ===
* A integer variable The sign is defined with a "!" character postfixrepresented by bit 7 of byte 3. The value of the sign bit indicates the sign of the floating point number.
e#*If the sign bit is "1", then the number is negative.g#*If the sign bit is "0", then the number is positive.
a! = 3.141592654== Mantissa ===
* A real The mantissa holds the normalized number uses 5 bytes of memory as storage. The format exponent is described abovemanipulated so that the most significant bit is always 1.* The address of a real variable can be found in BASIC Since it is always 1, it is not stored. It's value is implied by:the representation.
=== Exponent ===
 
The exponent is 8-bit and is stored in byte 4. It is stored with a bias of 128.
 
#*128-255 are positive exponents,
#*0-127 are negative exponents.
 
To obtain the signed exponent, you must subtract 128 from the stored exponent. The minimum exponent is 0 and this describes a number of 2^-127. The maximum exponent is 255 and this describes a number of 2^128.
 
=== BASIC Display of Floating point numbers ===
 
* Numbers are displayed to 9 decimal places.
* If the number doesn't have a fractional part (e.g. .0) then the fractional part is not displayed.
* Trailing zeros (zero digits after the last digit in the fraction) are not displayed
* The value is rounded in the following way for display:
 
If the 10th fractional digit is 5 or above, then the number is rounded up.
If the 10th fractional digit is 4 or below, then the number is rounded down.
e.g.
0.1234567891 is displayed as 0.123456789
0.1234567895 is displayed as 0.12345679
 
=== floating point example in RAM by MaV ===
 
The initial figure = 43.375.
An example in BASIC:
<pre>
a!=43.375
READY
PRINT a!
43.375
PRINT @a!
374
FOR I=0 TO 4:PRINT HEX$(PEEK(374+I),2);:NEXT I
0000802D86
</pre>
the result for better readability:<br>
'''00 00 80 2D 86'''<br>
The first byte contains the least significant bits of the mantissa, and every following byte up to the fourth byte contain the bits following the first in significance and in exactly that order!
 
That means that you have to turn around the first four bytes if you want to read the mantissa correctly:
2D800000
or
0010.1101.1000.0000.0000.0000.0000.0000
in binary (the stops are inserted for better readability).
 
Now the highest significant bit here is 0, so the number is positive.
What's more, you need to clear that bit and substitute the implied highest bit (see description in the link), which is always 1 (regardless of the deleted sign bit!!!).
Thus you get:
AD800000
or
1010.1101.1000.0000.0000.0000.0000.0000
in binary.
 
The mantissa has an implied decimal point before the number. Since the number is 2^32 bits (i.e. 4 bytes) long you have to divide by 2^32 to get the proper decimal representation.
 
AD800000 (hex) = 2910846976 (dec)
 
2910846976 / 2^32 = 0.677734375
 
The mantissa in a decimal representation is: 0.677734375
 
Now, the last byte contains the exponent: 86 (hex) or 134 (dec). You need to subtract 128 to get the real exponent, the highest bit tells you that the exponent is positive (1) or negative (0). Your exponent is 6.
 
0.677734375 * 2^6 = 43.375
 
'''Another example:'''<br>
PI is represented in memory as:<br>
'''A2 DA 0F 49 82'''<br>
The mantissa is<br>
490FDAA2 (highest significant bit is zero => number is positive)
The exponent is<br>
82 (=positive mantissa, value=2 thus multiply mantissa with 2^2)<br>
 
Delete the sign bit (which is 0 anyway), and then add the implied 1 bit:<br>
C90FDAA2 (hex) = 3373259426 (dec) = 1100.1001.0000.1111.1101.1010.1010.0010 (bin)<br><br>
 
Calculate the decimal representation of the mantissa:<br>
3373259426 / 2^32 = 0,7853981633670628070831298828125<br><br>
 
Then add the exponent (82h - 80h = 2 thus 2^2)<br>
0,7853981633670628070831298828125 * 2^2 = 3,14159265346825122833251953125<br><br>
 
Voilà! The internal representation of the number PI on the CPC is: 3,14159265346825122833251953125<br><br>
 
 
If you compare to a (more) correct representation of PI, you'll see that the CPC is correct up to the 9th decimal place:<br><br>
 
 
CPC:<br>
3.14159265346825122833251953125<br>
more correctly:<br>
3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986...
 
== BASIC floating-point/real variables ==
Where "A floating point (real) variable describes a" should be replaced number with the name of the integer and fractional parts. The biggest figure which can be stored correctly in RAM by a variableis 2^32-1 = 4294967295.
== BASIC #*A integer variables ==variable is defined with a "!" character postfix.
A integer variable describes a whole number. i.e. g. <pre>a ! = 3.141592654</pre> #*A real number without any fractional partuses 5 bytes of memory as storage.The format is described above. #*The address of a real variable can be found in BASIC by: <pre>PRINT @a!</pre>
NOTES:Where "a" should be replaced with the name of the variable.
* A integer variable is defined with a "%" character postfix.<br>
e.g.== BASIC integer variables ==
A integer variable describes a% = 3whole number. i.e. a number without any fractional part.
* A integer variable has a range of -32768 to 32767 * A integer variable always uses two bytes of memory as storage with the following format<br> NOTES:
Offset Length Description 0 2 Integer number #* The address of the A integer variable can be found in BASIC by:is defined with a "%" character postfix.
PRINT @e.g. <pre>a%= 3</pre> #*A integer variable has a range of -32768 to 32767 #*A integer variable always uses two bytes of memory as storage with the following format:
where {| border="a1" should be replaced with the name of the variable. |-! Offset ! Length ! Description|-| 0 | 2 | Integer number|}
== #*The address of the integer variable can be found in BASIC string variables ==by: <pre>PRINT @a%</pre>
A string is where "a " should be replaced with the name of the variable which contains a group of characters.
NOTES:== BASIC string variables ==
* A string variable is defined in BASIC with a "$" character postfixvariable which contains a group of characters.
e.g.<br> NOTES:
#**A string variable is defined in BASIC with a$ = "hello$"character postfix.
e.g. <pre>a$ = "hello"</pre> #** A string variable is described internally by a "string descriptor block" which has the following structure:
{| border="1"|-! Offset ! Length ! Description |-| 0 | 1 | Length of string in bytes/characters |-| 1 | 2 | Location of start of string|}
#** The address of the "string descriptor block" for the string variable can be found in BASIC by typing:<pre>PRINT @a$</pre>
PRINT @replacing "a$" with the name of the string variable.
replacing "#**A string uses a$minimum of 3 bytes of storage (a 0 character length string) and a maximum of 258 bytes of storage. 3 bytes are used by the " with string descriptor block") #**A string variable can contain any ASCII character code in the name range 0-255. #**A string variable can store a minimum of 0 characters and a maximum of 255 characters. #**The length of the string variablein characters is defined in the string descriptor block. The string does not have a termination character.
* A string uses a minimum of 3 bytes of storage (a 0 character length string) and a maximum of 258 bytes of storage. 3 bytes are used by the "string descriptor block")[[Category:Programming]]* A string variable can contain any ASCII character code in the range 0-255.[[Category:BASIC| ]]* A string variable can store a minimum of 0 characters and a maximum of 255 characters.[[Category:CPC Internal Components]]* The length of the string in characters is defined in the string descriptor block. The string does not have a termination character.[[Category:Operating System| ]][[Category:Software]][[Category:Programming software| ]]
897
edits