P-Charme interpreter Frans van Hoesel ============================================================================= An interpreter for structured BASIC. Statements and functions ------------------------ AUTO Automatic line-numbering and indentation A. Examples: AUTO - first line 10, each next one 10 higher. AUTO 40 - first line 40, each next one 10 higher. AUTO ,20 - first line 10, each next one 20 higher. AUTO 100,100 - first line 100, each next one 100 higher. BEEP Generate sound BE. Emits a tone of a specific pitch and duration. The syntaxis is: BEEP , BSAVE Basic save BS. The command is the same as the normal SAVE statement. The program, however, gets another execution address (#AFAF inside the P-Charme). This effectively makes it possible to *RUN basic programs, that require stack, free space pointer etc. to be initialized. On the Atom Emulator, however, it only works if P-Charme is selected. CASE Case ... Of CA. Examples: 10 CASE J-48 OF 20<2> PRINT "THIS IS EVEN"' 30<3> PRINT "THIS IS " 40 PRINT "ODD"' 50<1> PRINT "J = 49"' 60 CEND 10 CASE $A OF 20<"SWEET"> PRINT "NICE"' 30<"BORING"> PRINT "DULL"' 40<$A> PRINT "NO IDEA"' 50 CEND If a case expression does not equal a case label, program execution is resumed right behind CEND. In the second example, the case label at line 40 always satisfies, and is therefore executed if the others do not. CASE statements may not be nested. CAT Catalog This statement shows a list with all the programs that are resident in the memory area #1000 to #9FFFF, starting with PROGRAM. CONT Continue May be used to resume program execution after a STOP. COPY Copy memory areas The syntaxis is as follows: COPY ,, The first expression is the start address, the second is the end address of the area that is to be copied. The last expression is the destination memory address. If this one is within the boundaries of the source area, the COPY statement effectively is a FILL command. For example COPY 32000,33000,32004 The result of this command is the the area between 32000 and 33004 repeatedly contains the same four bytes. COS Casette operation system Example: COS 0 - 300 baud COS 1 - 1200 baud DATA See READ and RESTORE. DEL Delete line Examples: DEL 200,300 - Delete lines 200 to 300. DEL /REM/,300L - Lines 0 to 300, containing the text 'REM'. DEL /STOP/V - All lines that contain the text 'STOP'. DEL - Delete all lines (be careful!). If the Veto option (V) is selected, a line is printed on screen first and a query will be made Y/N? There are several possible answers: Y - YES proceed with the operation, N - NO do not execute the operation, C - CONTINUE proceed with the operation and disable the veto option, L - LIST execute the operation and go on without the veto option, however, do list all the lines that are changed, S - SKIP do not execute the operation and go on to the next line, ESC do not proceed with the operation and go back to direct mode. ELSE This is the alternative for the XIF statement. The line behind ELSE is executed only if the expression behind XIF is false. EVEN EV. This function has the value TRUE (1) if the argument is even. Syntaxis: EVEN (factor) FALSE FA. Always results in the value 0. 'A=0' and 'A=FALSE' are completely equal. FEND Function end This statement delimits the end of a FUNCTION block. FUNCTION Function declaration FUNC. Function can be used to calculate one value, which on its turn is to be used in an expression. Functions begin with the FUNCTION statement and end with the FEND statement. Example: 10 PROGRAM FTEST 20 30 FUNCTION ADD(A,B) 40 ADD=A+B 50 FEND 60 70 PRINT 2*ADD(5,6) 80 END Recursive functions are allowed as well: FUNCTION GCD(M,N) XIF N=0 THEN GCD=M ELSE GCD=GCD(N,M%N) FEND It is NOT allowed to used DIM inside functions and procedures. HEX Hexadecimal / ASCII dump Hexdump is started from the specified address. The syntaxis is: HEX HTAB Horizontal tabulation HT. This statement is especially useful when creating tables. Example: HTAB 16 ICOPY Intelligent copy IC. This is almost the same as the COPY statement. However, the fill effect cannot occur with this statement. INKEY Input key INK. The INKEY statement waits until a key is pressed, and then assigns an ASCII value to the specified variable. Example: DO INKEY A PRINT $A UNTIL A=CH"." INSTR In string I. With this integer function a string can be saught in another string. The syntaxis is: INSTR (,) The brackets ( and ) are obligatory. The functions starts seaching in the first string for the second string. If found, INSTR is assigned the value of the position, otherwise it's zero. INSTR may also be used in a logical expression. Examples: P=INSTR($A,"HALLO") R=INSTR($B+6,$C); REM search from 6th position in $B onwards. IF INSTR($D,$E) THEN PRINT "FOUND"' KEY Single keyboard scanner K. The keyboard is scanned through once and an ASCII value is assigned to the specified variable. NOT N. This function equals a logical negation. The values of NOT are exclusively FALSE or TRUE (0 or 1). ODD O. This function has the value TRUE (1) if the argument is odd. Syntaxis: ODD (factor) ON ERROR O. For trapping BASIC errors. ON ... GOSUB Gosub selector This statement is used to choose from a number of possibilities. Example: 10 INPUT S 20 ON S GOSUB 100,110,50,a,70 30 PRINT"*"' 40 GOTO 10 50 PRINT "THREE";RETURN 70 PRINT "FIVE";RETURN 80aPRINT "FOUR";RETURN 100 PRINT "ONE";RETURN 110 PRINT "TWO";RETURN ON ... GOTO This statement is the same as ON ... GOSUB, except for the fact that GOSUB is replaced by GOTO. PAUSE Delay program execution PA. PAUSE is followed by an expression. PAUSE 60 waits for one second. PEND Procedure end This statement delimits the end of a PROC block. POP This statement gets one return address from the GOSUB stack. It cannot cause an error. PROC Procedure declaration Within a procedure there are three types of variables: -Local variables -Value parameters -Output variables Examples: 10 PROGRAM EXAMPLE 20 30 PROC FIX-PRINT (%A),Z,@ 40 Z=%(%A*1000+5)/10;PRINT Z/100 50 @=0;Z=Z%100 60 PRINT "."Z/10,Z%10 70 PEND 80 90 @=11 100 FOR I=1 TO 5 110 READ %F 120 FPRINT %F;FIX-PRINT(%F) 130 PRINT' 140 NEXT I 150 END 160 170 DATA 10,1/3,2/3,10.9999,0 Herein %A is a value parameter. Z and @ are local variables. 10 PROGRAM EXTREME 20 30 PROC MINMAX (A,B:G,S) 40 XIF A>B THEN G=A 50 ELSE G=B 60 XIF A1 PRINT "*";STAR(N-1) IF N=1 PRINT "*" PEND It is NOT allowed to used DIM inside functions and procedures. PROGRAM Program heading Behind this statement there is room for a name. The rest of the line is regarded as comment. Besides giving a name to a program, the following features are supported: 1-Automatical RESTORE at the start of the program, 2-Initialization of procedures and functions, 3-Initialization of built-in functions (INSTR, EVEN etc), 4-Initialization of error pointer routines, 5-Initialization of multi-dimensional arrays, 6-Initialization of WHILE loops, 7-Recognition for the CAT statement. Item 2 effectively fills the area #28DD-#28FF with #00. This area is NOT used by the floating point ROM. For Item 3, 4 and 5 the BRKVEC is changed for the duration of the program. A correct program name begins with two different characters. Here are some examples: 10 PROGRAM TEST VERSIE IV - the name here is 'TEST' 10 PROGRAM CRC-TEST - the name here is 'CRC-TEST' 10 PROGRAM QS(QUICK START) - the name here is 'QS' 10 PROGRAM -A Anemometer - the name here is '-A' If the program is resident in the memory area #1000-#9FFF and if there's one space between the NOT abreviated statement PROGRAM and the line number the program name is automatically promoted to a statement. Typing a program name results in searching the memory for that program, initializing the labels, clearing the FOR-NEXT, DO-UNTIL and GOSUB-stacks, setting the value of TOP and starting the program. READ Read data With the READ statement integer, floating point variables, arrays and multi-dimensional arrays, and string variables can be read. Example: READ A,B,%A,%B,$T,DD(12),%FF(3,4) RENUM Renumber program REN. This command renumbers the program accoring to the specified expressions. RESTORE Restore data RES. With this statement the data-pointer can be set to a specific line. Examples: RESTORE RESTORE 160 RESTORE a STOP Stop execution This statement is ment for trapping errors. If a program is stopped, the text 'STOPPED AT LINE ...' is printed. Execution can be resumed by typing CONT. TRUE TR. Always results in the value 1. 'A=1' and 'A=TRUE' are completely equal. VAR Variable dump This statement shows the values of the variables A to Z. VTAB Vertical tabulation V. The syntaxis for this stament is: VTAB WEND End of WHILE loop This statement delimits the end of the WHILE loop. WHILE WHILE loop A WHILE block is executed until the expression behind WHILE is FALSE. The WHILE statement can be nested up to 10 levels deep. XIF Expanded IF The XIF statement must be used together with ELSE. If the expression behind XIF is TRUE, the block behind it is executed and the line behind ELSE not. And vice versa, if the expression behind XIF is FALSE. The ELSE statement may not be abreviated and must be at the beginning of a line. XIF...THEN...ELSE constructions may be nested unlimited. Example: 10 XIF A+9=B-2 THEN I=1 20 Z=S?I 30 S?I=S?J 40 XIF %X=PI THEN PRINT '"PI=" 60 PRINT "3.1415"' 70 ELSE PRINT'"NO PI"' 80 ELSE I=2 90 PRINT I' Note that the THEN part may be spread over more than one line, and the ELSE part can take no more than one line. ZERO Clear variables Z. Fills the BASIC variables A to Z with the value 0. / Find text With the FIND command a certain text can be saught in a program. Line numbers are not a part of the text. Examples: /REM/ - searches for the text 'REM' in the entire program, /STOP/200, - searches 'STOP' from line 200 onwards, /$A/,1000 - searches '$A' until line 1000. / Change text With this command text can be saught and replaced. Examples: /A$/$A/ - replace 'A$' by '$A', /STEP -1/STEP 1/V - replace 'STEP -1' by 'STEP 1' with veto, / //L - remove all spaces with the list option /DIM/FDIM/,100V - replace 'DIM' by 'FDIM' in the lines 0 to 100 with the veto option. Multi-dimensional arrays ------------------------ With P-Charme it is possible to use multi-dimensional arrays. Example: 10 PROGRAM ARRAY 20 30 DIM TT(5,4,2) 40 A=0 50 FOR I=0 TO 5 60 FOR J=0 TO 4 70 FOR K=0 TO 2 80 TT(I,J,K)=A 90 A=A+1 100 NEXT K 110 NEXT J 120 NEXT I 130 PRINT TT(1,1,2)' 140 END All indices are checked. If, for example, line 130 is changed into 130 PRINT TT(1,5,2)' error 134 (Array subscript out of range) is generated. Multi-dimensional arrays can only be used in programs, and only if it begins with the PROGRAM header. If you would like to know the value of TT(5,3,1) in direct mode, the following must be entered: PRINT TT((5*(4+1)+3)*(2+1)+1) Herein (4+1) is one more than the second dimension and (2+1) is one more than the third dimension of the array TT. A statement like DIM SS(7) has (7+1) elements also. Multi-dimensional floating point arrays are possible as well. Note that brackets ( and ) are obligatory. The maximum number of dimensions is 9. String functions ---------------- With exception of INSTR, no new string-handling functions have been added. The following examples, however, show that it is very easy to implement them yourself: FUNCTION LEFT(S,L) IF L<1 OR LEN(S)>64 THEN ERROR $#140=$S;L?#141=13 LEFT=#140 FEND FUNCTION RIGHT(S,L) IF L<1 OR LEN(S)>64 THEN ERROR $#140=$S;IF L64 THEN ERROR ?#140=13;IF L<=LEN(S) $#140=$S+L-1;M?#140=13 MID=#140 FEND Since the word ERROR is not a statement, the interpreter will produce error 94 on an attempt to interpret ERROR. Note that, although functions (and procedures) don't "know" string variables it is very well possible to handle strings by passing the string's address. If the strings are no longer than 64 characters, the string buffer at #140 can safely be used. For longer strings, a buffer must be dimensioned first outside the functions. Example: $S="THIS IS A STRING" PRINT $LEFT(S,6) - THIS IS PRINT $RIGHT(S,10) - S A STRING PRINT $MID(S,2,6) - HIS IS Expanding the P-Charme interpreter ---------------------------------- There are three ways to expand the interpreter. The first one is the easiest and most obvious way: Just writing it in BASIC. See the PROGRAM statement. Example: 10 PROGRAM HELP 20 30 DIM S64 40 $S=$#100 50 K=INSTR(S,"HELP") 60 IF K=0 THEN PRINT '"SORRY, NO HELP."';GOTO e 70 E=VAL(#100+K+3) 80 CASE E OF 90<2> PRINT "TOO MANY GOSUBS" 100<6> PRINT "CHECKSUM ERROR" 110<18> PRINT "TOO MANY DO STATEMENTS" 120<29> PRINT "UNKNOWN OR MISSING FUNCTION" 130 REM etc. 140 CEND 150 PRINT ' 160e?18=#29 170 END Try typing HELP 29 The second way offers a lot more possibilities, but require more skill. It must be written in machine code and is preceded by a table. A table must always start on a new page (low byte #00). The P-Charme interpreter will check the table if the second byte on the page equals #E3 and the third byte equals #C6. It is wise to put #FF in the first byte. The rest of the table is followed by subsequently the name of a statement and its address. The high byte of the address comes first, and the MSB is always set. This results is address which are always higher than or equal to #8000. If, however, the table is in the memory area lower than #8000, the P-Charme interpreter substracts #8000 from the address. The table must be ended with a byte equal to #80. The table may not be larger than 256 bytes. Example: 3B00 FF (page extension byte) 3B01 E3 3B02 C6 3B03 43 C 3B04 4C L 3B05 53 S 3B06 BB (=3B+80) 3B07 10 3B08 53 S 3B09 54 T 3B0A 41 A 3B0B 52 R 3B0C BB (=3B+80) 3B0D 19 3B0E 80 (end of table) CLS 3B10 JSR C4E4 3B13 JSR FD6D 3B16 JMP C55B STAR 3B19 JSR C4E1 3B1C LDX 04 3B1E DEX 3B1F STX 04 3B21 LDA 16,X 3B23 TAY 3B24 LDA @2A 3B26 JSR FFF4 3B29 DEY 3B2A BNE 3B26 3B2C JMP C55B To tell the interpreter where the table is, the page number must be POKEd into memory address #3FE (here it is #3B). It is possible to use more than one table. The first byte in a table (the page extension byte) must point to the following page. The page extenstion byte of the last table should be #FF. Please note the following notes: 1. Almost all the statements end with JMP #C55B 2. Statements without parameters always begin with JSR #C4E4 to test whether or not the statement is followed by ';' or CR. 3. Statements with one expression as parameter, begin with JSR #C4E1. The expression is read, and then the routine at #C4E4 is done. The third way to expand the P-Charme is somewhat difficult. During program execution, the P-Charme interpreter uses the BRK-vector. If during program execution an error occurs and memory address #3FB contains the value #B3 and memory address #3EE is zero, the instruction JMP (#03EE) is executed. This test is done before the built-in functions and multi- dimensional arrays are handled. This last method is for experienced programmers only. Error messages -------------- 22 Out of data A read is being commited when there are no more DATA lines. 38 Stack error in PROC or FUNCTION block The control byte, stored during the call of the procedure or function in the free space, has changed on executing PEND or FEND. This could have been caused by a DIM statement within a procedure or function. 84 Illegal function 120 '(' expected 129 Division by zero; Missing CEND; Protected RAM 132 WEND without WHILE 133 Variable expected after KEY or INKEY 135 Out of memory; SYNtax error Not enough memory to execute a function or procedure. SYNtax error in the COS statement. 137 Error in parameterlist; paremeter expression too complicated. 163 Illegal or too many names 166 Missing PEND or FEND 182 Line not found in RESTORE 200 Malformed string An odd number of quotes was used, or a '/' is missing. 210 Missing CEND 222 Variable expected 237 Can't continue; Illegal STOP in direct mode 242 Too many WHILE statements 249 Missing WEND, missing ELSE Memory usage ------------ The P-Charme interpreter only uses zero page addresses #90-#99. The memory area #28BD-#28FF is used to keep the addresses of functions and procedures.