# NanoBasic ## Reference Manual ## Table of Contents - [Introduction](#introduction) - [Line Numbers](#line-numbers) - [Character Set](#character-set) - [Constants](#constants) - [NIL](#nil) - [Variables](#variables) - [Array Variables](#array-variables) - [Expressions and Operators](#expressions-and-operators) - [Functional Operators](#functional-operators) - [String Operations](#string-operations) - [Commands and Statements](#commands-and-statements) - [CONST](#const) - [DATA](#data) - [DIM](#dim) - [END](#end) - [ERASE](#erase) - [FOR...NEXT](#fornext) - [FREE](#free) - [GOSUB...RETURN](#gosubreturn) - [GOTO](#goto) - [IF...THEN](#ifthen) - [LET](#let) - [ON...GOSUB and ON...GOTO](#ongosub-and-ongoto) - [PRINT](#print) - [READ](#read) - [REM](#rem) - [RESTORE](#restore) - [TRON and TROFF](#tron-and-troff) - [WHILE...LOOP](#whileloop) - [Internal Functions](#internal-functions) - [CLRLINE](#clrline) - [CLRSCR](#clrscr) - [GETCURX](#getcurx) - [GETCURY](#getcury) - [HEX$](#hex) - [INPUT](#input) - [INPUT$](#input-1) - [INSTR](#instr) - [LEFT$](#left) - [LEN](#len) - [MID$](#mid) - [PARAM](#param) - [PARAM$](#param-1) - [RESET](#reset) - [RIGHT$](#right) - [RND](#rnd) - [SERCUR](#sercur) - [SLEEP](#sleep) - [SPC](#spc) - [STR$](#str) - [STRING$](#string) - [TIME](#time) - [VAL](#val) - [Techage Functions](#techage-functions) - [Error Handling](#error-handling) - [Mapblock Loading](#mapblock-loading) - [CMD](#cmd) - [CMD$](#cmd-1) - [CHAT](#chat) - [DCLR](#dclr) - [DPUTS](#dputs) - [DOOR](#door) - [INAME$](#iname) - [TA3 Terminal Operating Instructions](#ta3-terminal-operating-instructions) - [Debugging of NanoBasic Programs](#debugging-of-nanobasic-programs) - [Appendix A: Techage Commands](#appendix-a-techage-commands) - [CMD Commands without Response](#cmd-commands-without-response) - [CMD Commands with Response as Numeric Value](#cmd-commands-with-response-as-numeric-value) - [CMD$ Commands with Response as String Value](#cmd-commands-with-response-as-string-value) ## Introduction NanoBasic is a simple BASIC interpreter that runs on the NanoVM. It is based on the Microsoft (TM) BASIC interpreter, which is available on the Commodore 64 and other computers of the 1980s. Information to the Microsoft (TM) BASIC interpreter can be found [here](https://vtda.org/docs/computing/Microsoft/MS-BASIC/8101-530-11-00F14RM_MSBasic8086XenixReference_1982.pdf). NanoBasic is available on the Techage TA3 Terminal as part of the techage mod for Minetest/Luanti. It allows you to monitor and control the Techage machines and devices. It works similar to the Lua Controller of the Techage mod, but fits more into the era of TA3 machines. NanoBasic is normally not visible on the Techage Terminal. But it can be activated by means of the Techage Info Tool (open-ended wrench). ### Line Numbers Every BASIC program line begins with a line number. Line numbers must be ordered in ascending sequence. Line numbers are mainly used as references for branches (jump targets) and as line references for compiler error messages. The terminal has a convenient text editor that allows you to edit and copy entire BASIC programs. Lines do not have to be entered or edited individually via a command line. Line numbers must be in the range 1 to 65535. ### Character Set NanoBasic supports the ASCII character set, which includes the upper and lower case letters of the alphabet, the digits 0 through 9, and special characters such as punctuation marks and mathematical symbols. NanoBasic distinguishes not between upper and lower case letters. Variable names and BASIC keywords are not case-sensitive. ### Constants NanoBasic supports integer and string constants. Integer constants are numbers without a decimal point. String constants are enclosed in double quotes. Examples: ```text "Hello" 1234 ``` Numeric constants are positive numbers in the range -2,147,483,648 to 2,147,483,647 (32 bit signed integer). NanoBasic does not support floating point numbers! #### NIL NIL is a special constant that represents the absence of a value. It is used to pass a null value to a function where an array argument is expected. ### Variables Variables are names used to represent values used in the program. The value of a variable may be assigned by the programmer, or it may be assigned by the calculations in the program. Before a variable is assigned a value, its value is assumed to be zero. Variable names must begin with a letter and may contain letters and digits. Variable names can have any length, but only the first 9 characters are significant. If 2 variables differ only after the 9th digit, they are considered equal. A variable name may not be the same as a reserved word. Reserved words include all commands, statements, function names, and operator names. Variables may represent either a numeric value or a string. String variable names are written with a dollar sign ($) as the last character. For example: ```text A$ = "SALES REPORT" ``` The dollar sign is a variable type declaration character; that is, it "declares" that the variable will represent a string. ### Array Variables An array is a group or table of values referenced by the same variable name. Each element in an array is referenced by an array variable that is subscripted with an integer or an integer expression. An array variable name has as many subscripts as there are dimensions in the array. For example: ```text DIM A(10) ``` This statement creates an array named A with 11 elements, A(0) through A(10). The maximum number of elements in limited by the available heap memory. Heaps are shared between arrays and strings. The heap size is 8KB. NanoBasic supports only one-dimensional arrays. ### Expressions and Operators An expression is a combination of variables, constants, and operators that the interpreter evaluates to produce a value. Expressions can be used in statements that require a value, such as assignment statements, PRINT statements, and IF statements. Operators perform mathematical or logical values. The Microsoft BASIC operators may be divided into four categories: 1. Arithmetic 2. Relational 3. Logical 4. Functional The following table lists the operators in each category: | Category | Operator | Description | |-------------|----------|-------------| | Arithmetic | + | Addition | | | - | Subtraction | | | * | Multiplication | | | / | Division | | | MOD | Modulus | | | ^ | Exponentiation | | Relational | = | Equal | | | <> | Not equal | | | < | Less than | | | <= | Less than or equal | | | > | Greater than | | | >= | Greater than or equal | | Logical | AND | Logical AND | | | OR | Logical OR | | | NOT | Logical NOT | | Functional | RND | Random number | | | LEN | Length of string | | | MID | Substring | | | LEFT$ | Left part of string | | | RIGHT$ | Right part of string | | | STR$ | Convert to string | | | VAL | Convert to number | | | INSTR | Find substring | | | CHR$ | Convert to character | | | ASC | Convert to ASCII code | | | SPC | Print spaces | The precedence of operators is as follows: 1. Multiplication (*), Division (/), Modulus (MOD) 2. Addition (+), Subtraction (-) 3. Relational operators (=, <>, <, <=, >, >=) 4. Logical NOT operator 5. Logical AND operator 6. Logical OR operator If, during the evaluation of an expression, division by zero is encountered, the "Division by zero" error message is displayed and the program is terminated. Relational operators are used to compare two values. The result of the comparison is either "true" (1) or "false" (0). This result may then be used to make a decision regarding program flow. (See "IF" statements) Examples: ```text IF RND(100)<1O GOTO 1000 IF I MOD J<>O THEN K=K+1 ``` #### Functional Operators The functional operators are used to manipulate strings and numbers. They are used in expressions to convert between numbers and strings, to extract substrings, to find substrings, and to convert between ASCII codes and characters. NanoBasic has "intrinsic" functions that reside in the interpreter. In addition, NanoBasic allows to define "external" functions that are written in Lua to extend the functionality of the interpreter. All these functions are called by name and are followed by a list of arguments enclosed in parentheses. The arguments are separated by commas. NanoBasic has a strong type system. The type of the arguments and the return value of a function is determined by the function name. If, for example, the function name is "STR$", the argument is converted to a string and the return value is a string. #### String Operations Strings may be concatenated by using +. Example: ```text 10 A$="FILE" : B$="NAME" 20 PRINT A$+B$ 30 PRINT "NEW "+A$+B$ >> FILENAME >> NEW FILENAME ``` Strings may be compared using the same relational operators that are used with numbers: ```text = <> < > <= >= ``` String comparisons are made by taking one character at a time from each string and comparing the ASCII codes. If all the ASCII codes are the same, the strings are equal. If the ASCII codes differ, the lower code number precedes the higher. If during string comparison the end of one string is reached, the shorter string is said to be smaller. Leading and trailing blanks are significant. ## Commands and Statements This section describes the commands and statements that are available in NanoBasic in alphabetical order. ### CONST The CONST statement is used to define constants that are used in the program. The CONST statement is nonexecutable and can be placed anywhere in the program. Example: ```text 10 CONST MAX=100 20 DIM A(MAX) ``` ### DATA The DATA statement is used to define data that is used by the READ statement. DATA statements are nonexecutable and must be placed at the end of the program. A DATA statement may contain as many constants as will fit on a line (separated by commas). Up to 200 DATA statements may be used in a program. This list of constants may contain numeric or string constants. String constants must be enclosed in double quotes. READ statements access DATA statements in the order in which they are encountered. The variable type (numeric or string) in the READ statement must correspond to the corresponding constant in the DATA statement. ### DIM The DIM statement is used to dimension arrays. The DIM statement must be used before the array is referenced in the program. For instance, DIM A(5) defines a single-dimension array A. In standard BASIC, the lower bound of any array was normally 1, so in this case, the variable A has five "slots", numbered 1 though 5. In NanoBasic, the lower bound is always 0, so the variable A has six "slots", numbered 0 through 5. If a subscript is used that is greater than the maximum specified, a "Array index out of bounds" error occurs. The minimum value for a subscript is always 0. Example: ```text 10 DIM A(20) 20 FOR I=O TO 20 30 READ A(I) 40 NEXT I DATA 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 ``` ### END The END statement is used to terminate the program. END statements may be placed anywhere in the program to terminate execution. Unlike the BREAK statement, END does not cause a "Break in line nnnnn" message to be printed. An END statement at the end of a program is optional. ### ERASE The ERASE statement is used to delete an array. Arrays may be redimensioned after they are ERASEd, or the previously allocated array space in memory may be used for other purposes. Example: ```text 10 DIM A(20) 20 ERASE A 30 DIM A(10) 40 END ``` ### FOR...NEXT Format: ```text FOR variable = start TO end [STEP increment] statements NEXT variable ``` `start`, `end`, and `increment` are numeric expressions. The `STEP` clause is optional. The FOR statement is used to set up a loop that will execute a specified number of times. The variable is assigned the value of `start` and is incremented by `increment` each time through the loop. The loop continues until the variable is greater than `end`. If the `STEP` clause is omitted, the increment is assumed to be 1. Example: ```text 10 FOR I=1 TO 10 20 PRINT I 30 NEXT I ``` The program lines following the FOR statement are executed until the NEXT statement is encountered. Then the counter is adjusted by the amount specified by STEP. A check is performed to see if the value of the counter is now greater than the final value (y). If it is not greater, NanoBasic branches back to the statement after the FOR statement and the process is repeated. If it is greater, execution continues with the statement following the NEXT statement. ### FREE The FREE statement outputs the number of free bytes in the code, variable, and heap areas of the NanoBasic interpreter to the terminal. Example: ``` FREE >> 16345/1020/8192 bytes free (code/data/heap) ``` ### GOSUB...RETURN Format: ```text GOSUB line . . . RETURN ``` The GOSUB statement is used to branch to a subroutine. The RETURN statement is used to return to the statement following the GOSUB statement. A subroutine may be called any number of times in a program. A subroutine also may be called from within another subroutine. Up to 8 levels of subroutine nesting are allowed. If the limit is exceeded, an "Call stack overflow" error occurs. Example: ```text 10 GOSUB 100 20 PRINT "END" 30 END 100 PRINT "SUBROUTINE" 110 RETURN ``` ### GOTO The GOTO statement is used to branch to a specified line number. If the line number is not found, a "Line number not found" error occurs. Example: ```text 10 GOTO 100 20 PRINT "END" 30 END 100 PRINT "GOTO" 110 END ``` ### IF...THEN Format: ```text IF expression THEN statement [ELSE statement] ``` Or: ```text IF expression GOT0 line [ELSE statement] ``` Or: ```text IF expression THEN statement . . [ELSE statement . .] ENDIF ``` The IF statement is used to make a decision based on the value of an expression. If the expression is true (nonzero), the THEN or GOTO clause is executed. If the expression is false (zero), the statement following the ELSE keyword is executed. The ELSE clause is optional. Example: ```text 10 IF A=0 THEN 100 20 PRINT "A<>0" 30 END 100 PRINT "A=0" 110 END ``` ### LET The LET statement is used to assign a value to a variable. Notice the word LET is optional. The equal sign is sufficient for assigning an expression to a variable name. Example: ```text 10 LET A=10 20 LET B$="STRING" 20 PRINT A,B$ 30 END ``` Or: ```text 10 A=10 20 B$="STRING" 20 PRINT A,B$ 30 END ``` ### ON...GOSUB and ON...GOTO Format: ```text ON expression GOSUB line1, line2, line3, ... ON expression GOTO line1, line2, line3, ... ``` The ON statement is used to branch to a specified line number based on the value of the expression. The expression must be an integer value. For example, if the value is three, the program branches to the line number given as the third item in the list (line3). In the ON...GOSUB statement, each line number in the list must be' the first line number of a subroutine. If the value of expression is zero or greater than the number of items in the list NanoBasic continues with the next executable statement. Example: ```text 10 ON A GOSUB 100,200,300 20 PRINT "END" 30 END 100 PRINT "GOSUB 100" 110 RETURN 200 PRINT "GOSUB 200" 210 RETURN 300 PRINT "GOSUB 300" 310 RETURN ``` ### PRINT The PRINT statement is used to display output on the screen. Format: ```text PRINT [] ``` If \ is omitted, a blank line is printed. If \ is included, the values of the expressions are printed at the terminal. The expressions in the list may be numeric and/or string expressions. (Strings must be enclosed in quotation marks.) The position of each printed item is determined by the punctuation used to separate the items in the list. NanoBasic divides the line into print zones of 10 spaces each (tabs). In the list of expressions, a comma causes the next value to be printed at the beginning of the next tab. A semicolon causes the next value to be printed immediately after the last value. Typing one or more spaces between expressions causes the next value to be printed with one space between it and the last value. If a comma or a semicolon terminates the list of expressions, the next PRINT statement begins printing on the same line, spacing accordingly. If the list of expressions terminates without a comma or a semicolon, a carriage return is printed at the end of the line. Printed numbers are always followed by a space. Strings are printed without a space. If the printed line is longer than the terminal width, the line is wrapped to the next line. Example: ```text 10 PRINT "HELLO", 20 PRINT "WORLD" 30 END >> HELLO WORLD ``` ### READ The READ statement is used to read data from a DATA statement and assign them to variables. Format: ```text READ variable1, variable2, ... ``` A READ statement must always be used in conjunction with a DATA statement. READ statements assign variables to DATA statement values on a one-to-one basis. READ statement variables may be numeric or string, and the values read must agree with the variable types specified. If they do not agree, a "Data type mismatch" will result. A single READ statement may access one or more DATA statements (they will be accessed in order), or several READ statements may access the same DATA statement. If the number of variables the list of variables exceeds the number of elements in the DATA statement(s), an "Out of data" error message is printed. If the number of variables specified is fewer than the number of elements in the DATA statement(s), subsequent READ statements will begin reading data at the first unread element. If there are no subsequent READ statements, the extra data is ignored. To reread DATA statements from the start, use the RESTORE statement. Example: ```text 10 READ A,B$ 20 PRINT A,B$ 30 END 40 DATA 10,"STRING" ``` ### REM The REM statement is used to insert comments in a program. REM statements are nonexecutable and may be placed anywhere in the program. Example: ```text 10 REM THIS IS A COMMENT 20 PRINT "END" 30 END ``` ### RESTORE Format: ```text RESTORE [offset] ``` To allow DATA statements to be reread from a specified offset. After a RESTORE statement is executed, the next READ statement accesses the first item in the first DATA statement in the program. If offset is specified, the next READ statement accesses the item at the given offset. Offset is a value from 0 (first DATA statement) to the offset of the last DATA statement. Example: ```text 110 READ A,B$ 20 RESTORE 30 READ C,D$ 40 PRINT A B$ C D$ 50 END 60 DATA 10,"STRING" >> 10 STRING 10 STRING ``` ### TRON and TROFF The TRON and TROFF statements are used to turn on and off the trace mode. When trace mode is on, the line number of each executed statement is printed. This is useful for debugging programs. Example: ```text 10 TRON 20 FOR I=1 TO 4 30 PRINT "HELLO" 40 NEXT I 50 PRINT "WORLD" 60 END >> [20] [30] HELLO >> [30] HELLO >> [30] HELLO >> [30] HELLO >> [50] WORLD >> [60] Ready. ``` ### WHILE...LOOP Format: ```text WHILE expression statements LOOP ``` The WHILE statement is used to set up a loop that will execute as long as the expression is true (nonzero). The loop continues until the expression is false (zero). WHILE/LOOP loops may be nested to any level. Each LOOP will match the most recent WHILE. Example: ```text 10 LET I = 0 20 WHILE I < 10 30 PRINT "I =" I 40 I = I + 1 50 LOOP 60 END ``` ## Internal Functions This section describes the functions that are available in NanoBasic in alphabetical order. ### CLRLINE Format: ```text CLRLINE(y-position) ``` The CLRLINE function is used to clear a line on the terminal. The cursor is positioned at the beginning of the line. `y-position` is the vertical position (1-20). If `y-position` is 0, the current line is cleared. Example: ```text 10 CLRLINE(10) 20 PRINT "HELLO" 30 END ``` ### CLRSCR Format: ```text CLRSCR() ``` The CLRSCR function is used to clear the screen. ### GETCURX Format: ```text GETCURX() ``` The `GETCURX` function is used to return the current horizontal cursor position (1-60). Example: ```text 10 PRINT GETCURX() 20 END >> 10 ``` ### GETCURY Format: ```text GETCURY() ``` The `GETCURY` function is used to return the current vertical cursor position (1-20). Example: ```text 10 PRINT GETCURY() 20 END >> 10 ``` ### HEX$ Format: ```text HEX$(number) ``` The HEX$ function is used to convert a number to a hexadecimal string. Example: ```text 10 PRINT HEX$(255) >> FF ``` ### INPUT Format: ```text variable = INPUT("prompt") ``` The INPUT function is used to accept input from the user. This input accepts numeric values only. The input is terminated by pressing the Enter key. When an INPUT function is encountered, program execution pauses and a question mark is printed to indicate the program is waiting for data. The data that is entered is returned as the value of the INPUT function. Example: ```text 10 A = INPUT("ENTER A NUMBER") 20 PRINT A 30 END ``` ### INPUT$ Format: ```text variable$ = INPUT$("prompt") ``` The INPUT$ function is used to accept input from the user. This input is returned as string value. The input is terminated by pressing the Enter key. When an INPUT$ function is encountered, program execution pauses and a question mark is printed to indicate the program is waiting for data. The data that is entered is returned as the value of the INPUT$ function. Example: ```text 10 A$ = INPUT$("ENTER A STRING") 20 PRINT A$ 30 END ``` ### INSTR Format: ```text INSTR(string1, string2) ``` The INSTR function is used to find the position of a substring within a string. The function returns the position of the first occurrence of string2 in string1. If string2 is not found in string1, the function returns 0. Example: ```text 10 PRINT INSTR("HELLO","L") >> 3 ``` ### LEFT$ Format: ```text LEFT$(string, length) ``` The LEFT$ function is used to extract the left part of a string. Example: ```text 10 A$="HELLO" 20 PRINT LEFT$(A$,2) 30 END >> HE ``` ### LEN Format: ```text LEN(string) ``` The LEN function is used to determine the length of a string. Example: ```text 10 A$="HELLO" 20 PRINT LEN(A$) 30 END >> 5 ``` ### MID$ Format: ```text MID$(string, start, length) ``` The MID$ function is used to extract a substring from a string. `string` is the string from which the substring is to be extracted. `start` is the starting position of the substring (1-n). `length` is the length of the substring (1-n). Example: ```text 10 A$="HELLO" 20 PRINT MID$(A$,3,2) 30 END >> LL ``` ### PARAM Format: ```text PARAM() ``` The PARAM function is used to obtain a numeric value from an external subroutine call. This is used, for example, when an error occurs in an external function. Example: ```text 10 val = PARAM() ``` ### PARAM$ Format: ```text PARAM$() ``` The PARAM$ function is used to obtain a string value from an external subroutine call. This is used, for example, when an error occurs in an external function. Example: ```text 10 val$ = PARAM$() ``` ### RESET Format: ```text RESET() ``` The RESET function is used to reset the program to the first line. The function can be called at any time in the program. But the main use is to restart the program after the mapblock is loaded. See [Mapblock Loading](#mapblock-loading). ### RIGHT$ Format: ```text RIGHT$(string, length) ``` The RIGHT$ function is used to extract the right part of a string. Example: ```text 10 A$="HELLO" 20 PRINT RIGHT$(A$,2) 30 END >> LO ``` ### RND Format: ```text RND(number) ``` The RND function is used to generate a random number between 0 and number-1. Example: ```text 10 PRINT RND(100) 20 END ``` ### SERCUR Format: ```text SERCUR(x-position, y-position) ``` The SERCUR function is used to set the cursor position on the terminal. `x-position` is the horizontal position (1-60). `y-position` is the vertical position (1-20). Example: ```text 10 SERCUR(10,10) 20 PRINT "HELLO" 30 END ``` ### SLEEP Format: ```text SLEEP(seconds) ``` The SLEEP function is used to pause program execution for a specified number of seconds. If the number of seconds is 0, the program pauses one time slice (0.2 seconds). ### SPC Format: ```text SPC(number) ``` The SPC function is used to print a number of spaces. Example: ```text 10 PRINT "HELLO";SPC(5);"WORLD" 20 END >> HELLO WORLD ``` ### STR$ Format: ```text STR$(number) ``` The STR$ function is used to convert a number to a string. Example: ```text 10 PRINT STR$(100) 20 END >> 100 ``` ### STRING$ Format: ```text STRING$(number, character) ``` The STRING$ function is used to create a string of a specified length filled with a specified character. Example: ```text 10 PRINT STRING$(5,"*") 20 END >> ***** ``` ### TIME Format: ```text TIME() ``` The TIME function is used to return the current time in seconds since start of the Minetest server. ### VAL Format: ```text VAL(string) ``` The VAL function is used to convert a string to a number. Example: ```text 10 PRINT VAL("100") 20 END >> 100 ``` ## Techage Functions This section describes the functions that are available in NanoBasic to interact with the Techage machines and devices. NanoBasic provides two command functions: - `CMD` to send commands and receive responses as numeric values. - `CMD$` to send commands and receive responses as strings. Both functions can send numeric commands to Techage devices and both functions support a flexible number of arguments: - For commands without payload data: `CMD(node_number, cmnd)` - For commands with one payload value: `CMD(node_number, cmnd, payload1)` - For commands with two payload values: `CMD(node_number, cmnd, payload1, payload2)` - For commands with three payload values: `CMD(node_number, cmnd, payload1, payload2, payload3)` `payload1` can be a numeric value or a string value. All Techage commands are described in [Appendix A: Techage Commands](#appendix-a-techage-commands) ### Error Handling `CMD` and `CMD$` throw an error if the command cannot be executed properly. In NanoBasic, the subroutine starting at line 65000 is called. This subroutine can be used to handle errors. The error message and the node number are passed as external parameters to the subroutine. In the easiest case, the error subroutine can be defined as follows: ```text 65000 err$ = PARAM$() 65010 num = PARAM() 65020 PRINT "Error:" err$ "in" num 65030 RETURN ``` `PARAM` and `PARAM$` are used to get the error message and the error number. `PARAM$` has always be used in combination with the `PARAM` function, in that order and only in the error subroutine. After this subroutine is called, the program returns to the `CMD` or `CMD$` function. ### Mapblock Loading When the world around the Techage Terminal is loaded and NanoBasic is active, the program is continued from the line where the program was interrupted. By means of the NanoBasic subroutine starting at line 64000, it is possible to define what should happen when the mapblock is loaded. This subroutine can be used to initialize the program and/or initialize connected Techage devices. In the easiest case, the on-load subroutine can be defined as follows: ```text 64000 PRINT "Mapblock loaded" 64010 RETURN ``` To restart the program from the beginning, call the `RESET` function. The `RESET` function is used to reset the program to the first line. ```text 64000 PRINT "Mapblock loaded" 64010 RESET() ``` ### CMD Format: ```text CMD(node_number, cmnd[, payload1[, payload2[, payload3]]]) ``` The `CMD` function is used to send numeric commands to a Techage device and return the response as a numeric value. - `node_number` is the number of the device. - `cmnd` is the numeric command to be sent. - `payload1` is an optional numeric value or string used as payload data. - `payload2` is an optional numeric value used as payload data. - `payload3` is an optional numeric value used as payload data. All Techage commands are described in [Appendix A: Techage Commands](#appendix-a-techage-commands) If the `cmnd` value is larger then 127 The return value of the `CMD` function is the response value from the device. If the `cmnd` value is smaller then 128 the return value is the status of the command execution: - 0 = success - 1 = error: Invalid node number or machine has no command interface - 2 = error: Invalid command or command not supported - 3 = error: command execution failed - 4 = error: Machine is protected (access denied) - 5 = error: Invalid command response type (e.g. string) - 6 = error: Wrong number of function parameters In case of an error, the subroutine at line 65000 is called in addition to the return value. Example: ```text 10 PRINT CMD(1234, 2, 1) ' Set Signal Tower color to green 20 END >> 0 ``` ### CMD$ Format: ```text CMD$(node_number, cmnd[, payload1[, payload2[, payload3]]]) ``` The `CMD$` function is used to send numeric commands to a Techage device and return the response as a string. - `node_number` is the number of the device. - `cmnd` is the numeric command to be sent. - `payload1` is an optional numeric value or string used as payload data. - `payload2` is an optional numeric value used as payload data. - `payload3` is an optional numeric value used as payload data. All Techage commands are described in [Appendix A: Techage Commands](#appendix-a-techage-commands) The return value of the `CMD$` function is the response string from the device. In case of an error, the subroutine at line 65000 is called. The error message: - "Node not found" = 1 - "Command not supported" = 2 - "Command failed" = 3 - "Access denied" = 4 - "Wrong response type" = 5 - "Wrong number of parameters" = 6 Example: ```text 10 DIM arr(2) 20 arr(0)=1 30 PRINT CMD$(1234, 128) 40 END >> running ``` ### CHAT Format: ```text CHAT("message") ``` The CHAT function is used to send a chat message to the owner of the Techage Terminal. The message is displayed in the chat area of the Minetest client. `message` is the text to be displayed. Example: ```text 10 CHAT("Hello, World!") 20 END ``` ### DCLR Format: ```text DCLR(node_number) ``` The DCLR function is used to clear the display of a display device. - `node_number` is the number of the display device. Example: ```text 10 DCLR(1234) 20 END ``` ### DPUTS Format: ```text DPUTS(node_number, row_number, "text message") ``` The DPUTS function is used to display a text message on a display device. - `node_number` is the number of the display device. - `row_number` is the row number (1-5) of the display. The display has 5 rows. If `row_number` is 0, the message is added at the end of the display. - `text message` is the text to be displayed. Example: ```text 10 DPUTS(1234, 1, "Hello, World!") 20 END ``` ### DOOR Format: ```text DOOR("door_position", "state") ``` The DOOR function is used to open/close a door. - `door_position` is the position of the door, e.g. "-127,2,2004" - `state` is the state of the door, either "open" or "close". Hint: Use the Techage Info Tool to determine the door position. Example: ```text 10 DOOR("-127,2,2004", "open") 20 END ``` ### INAME$ Format: ```text INAME$("node_name") ``` Read the description (item name) for a specified itemstring. `node_name` is the technical name of the item. Example: ```text 10 A$ = CMD$(1234, 128) 20 PRINT INAME$(A$) 30 END ``` ## TA3 Terminal Operating Instructions The TA3 Terminal is a Techage device that allows you to run NanoBasic programs to control Techage machines and devices. To activate the TA3 Terminal Basic mode, right-click on the TA3 Terminal with the Techage Info Tool (open-end wrench) and select "Basic" from the menu. The TA3 Terminal Basic mode has the following buttons: - "Edit" to edit the program. The editor allows you to write Basic programs and also copy/paste complete programs. - "Save" to save changes to the program. The program is saved inside the TA3 Terminal. The "Save" button also sorts the program lines according to the line numbers. - "Renum" to renumber the program lines from the complete program, starting from 10 with a step of 10. The "Renum" button also sorts the program lines according to the line numbers. - "Cancel" to cancel the editing of the program (changes are lost). - "Run" to run the program. - "Stop" to stop a running program. - "Continue" to continue a breaked program. - "List" to list the program lines while the program is in the break mode. - "*" / "-" to change the font size of the screen. Depending on the terminal state, only the appropriate buttons are displayed and can be used. Terminal states: - "init" - The terminal is initialized. The screen shows the free memory. - "edit" - The terminal is in the edit mode. The screen shows the program lines. - "stopped" - After pressing the "Stop" button, the terminal is in the stop mode. - "running" - The terminal is running a program. The screen shows the output of the program. - "error" - An error occurred when when compiling the program or during the execution. - "input_str" - The terminal is waiting for a string input. - "input_num" - The terminal is waiting for a numeric input. - "break" - The program reached a break point. ## Debugging of NanoBasic Programs The NanoBasic interpreter provides simple debugging features to help you find errors in your programs. The "TRON" statement turns on the trace mode. When trace mode is on, the line number of each executed statement is printed. Enter the "TRON" statement in your program to activate the trace mode. The "BREAK" statement is used to set a breakpoint in the program. When the program reaches the breakpoint, the program execution is stopped and the terminal is in the "break" mode. The "BREAK" statement is used to set a breakpoint at a specific line number. When the program is in the "break" mode, the "List" button can be used to list the program lines. The input field at the bottom of the screen can be used to read variable values. Enter the variable name and press the "Enter" key to read the value. In case of arrays, enter the array name and the index, separated by a comma. (e.g. "A,1") The "Continue" button is used to continue the program execution after a breakpoint. ## Appendix A: Techage Commands NanoBasic supports the numeric Techage commands known from the Beduino mod. These commands are also described in [BEP 005: Techage Commands](https://github.com/joe7575/beduino/blob/main/manual/techage.md) ### CMD Commands without Response The following table lists the numeric Techage commands that can be used with the `CMD` function. These commands do not return a response value from the device. The return value of the `CMD` function is the status of the command execution: - 0 = success - 1 = error: Invalid node number or machine has no command interface - 2 = error: Invalid command or command not supported - 3 = error: command execution failed - 4 = error: Machine is protected (access denied) - 5 = error: Invalid command response type (e.g. string) - 6 = error: Wrong number of function parameters As payload data, these commands may require numeric values or a string value. | Command | cmnd (num) | Payload | Remarks | | ------------------------ | ----------- | ---------------------- | ------------------------------------------------------------ | | Turn on/off | 1 | state | Turn device (lamp, machine, button...) on/off.
`state`: 0 = "off", 1 = "on" | | Turn on/off Signs Bot | 1 | state | Turn device (lamp, machine, button...) on/off.
`state`: 0 = "off", 1 = "on" | | Signal Tower | 2 | color | Set Signal Tower color
`color`: 0 = "off", 1 = "green", 2 = "amber", 3 = "red" | | Traffic Light | 2 | color | Set Traffic Light color
`color`: 0 = "off", 1 = "green", 2 = "amber", 3 = "red" | | Signal Lamp | 3 | idx, color | Set the lamp color for "TA4 2x" and "TA4 4x" Signal Lamps
`idx` is the lamp number (1..4)
`color`: 0 = "off", 1 = "green", 2 = "amber", 3 = "red" | | Distri. Filter Slot | 4 | idx, state | Enable/disable a Distributor filter slot.
`idx` is the slot number: 1 = "red", 2 = "green", 3 = "blue", 4 = "yellow"
`state`: 0 = "off", 1 = "on" | | Detector Block Countdown | 5 | counter | Set countdown counter of the TA4 Item Detector block to the given value and start countdown mode. | | Detector Block Reset | 6 | - | Reset the item counter of the TA4 Item Detector block | | TA3 Sequenzer | 7 | state | Turn the TA3 Sequencer on/off
`state`: 0 = "off", 1 = "on", 2 = "pause" | | DC2 Exchange Block | 9 | 0, idx | TA3 Door Controller II (techage:ta3_doorcontroller2). Exchange a block
`idx` is the inventory slot number (1..n) | | DC2 Set Block | 9 | 1, idx | TA3 Door Controller II (techage:ta3_doorcontroller2). Set/add a block
`idx` is the inventory slot number (1..n) with the block to be set | | DC2 Dig Block | 9 | 2, idx | TA3 Door Controller II (techage:ta3_doorcontroller2). Dig/remove a block
`idx` is the empty inventory slot number (1..n) for the block | | DC2 Reset | 9 | 3 | TA3 Door Controller II (techage:ta3_doorcontroller2). Reset the door controller | | Autocrafter | 10 | num, idx | Set the TA4 Autocrafter recipe with a recipe from a TA4 Recipe Block.
`num` is the TA4 Recipe Block number
`idx` is the number of the recipe in the TA4 Recipe Block | | Autocrafter | 11 | - | Move all items from input inventory to output inventory. Returns 1 if the input inventory was emptied in the process. Otherwise return 0 | | Move Contr. 1 | 11 | 1 | TA4 Move Controller command to move the block(s) from position A to B | | Move Contr. 2 | 11 | 2 | TA4 Move Controller command to move the block(s) from position B to A | | Move Contr. 3 | 11 | 3 | TA4 Move Controller command to move the block(s) to the opposite position | | Move Contr. `move xyz` | 18 | x, y, z | TA4 Move Controller command to move the block(s) by the given
x/y/z-distance. Valid ranges for x, y, and z are -100 to 100 | | Move Contr. `moveto` | 24 | x, y, z | TA4 Move Controller command to move the block(s) to the given absolute x/y/z-position. | | Move Contr. reset | 19 | - | Reset TA4 Move Controller (move block(s) to start position) | | Turn Contr. 1 | 12 | 1 | TA4 Turn Controller command to turn the block(s) to the left | | Turn Contr. 2 | 12 | 2 | TA4 Turn Controller command to turn the block(s) to the right | | Turn Contr. 3 | 12 | 3 | TA4 Turn Controller command to turn the block(s) 180 degrees | | TA4 Sequenzer 1 | 13 | slot | Start/goto command for the TA4 Sequencer.
`slot` is the time slot (1..n) where the execution starts. | | TA4 Sequenzer 2 | 13 | 0 | Stop command for the TA4 Sequencer. | | Sound 1 | 14 | 1, volume | Set volume of the sound block
`volume` is a value from 1 to 5 | | Sound 2 | 14 | 2, index | Select sound sample of the sound block
`index` is the sound sample number | | TA4 Pusher Limit | 20 | limit | Configure a TA4 Pusher with the number of items that are allowed to be pushed ("flow limiter" mode)
`limit` = 0 turns off the "flow limiter" mode | | TA4 Pump Limit | 21 | limit | Configure a TA4 Pump with the number of liquid units that are allowed to be pumped ("flow limiter" mode)
`limit` = 0 turns off the "flow limiter" mode | | Color | 22 | color | Set the color of the TechAge Color Lamp and TechAge Color Lamp 2 (`color` = 0..255) | | Multi Button | 23 | num, state | Turn button (TA4 2x Button, TA4 4x Button) on/off
`num` is the button number (1..4)
`state` is the state: 0 = "off", 1 = "on" | | | 25 is next | | | | Config TA4 Pusher | 65 | "\" | Configure the TA4 pusher.
Example: `wool:blue` | | Sensor Chest Text | 66 | "text string" | Text to be used for the Sensor Chest menu | | Distri. Filter Config | 67 | "\ \" | Configure a Distributor filter slot, like: "red default:dirt dye:blue" | ### CMD Commands with Response as Numeric Value The following table lists the numeric Techage commands that can be used with the `CMD` function. These commands return a numeric response value from the device. In case of an error, the error subroutine is called and the response value corresponds to the error from previous chapter. | Command | Topic (num) | Payload (number(s)) | Response (number) | Remarks to the response | | -------------------------- | ----------- | ------------------- | ----------------------- | ------------------------------------------------------------ | | Signs Bot State | 128 | - | state | Returns: 1 = RUNNING, 2 = BLOCKED, 3 = STOPPED, 4 = NO_POPWER, 5 = ERROR, 6 = FULL, 7 = CHARGING | | State for Techage Machines | 129 | - | state | RUNNING = 1, BLOCKED = 2, STANDBY = 3, NOPOWER = 4, FAULT = 5, STOPPED = 6, UNLOADED = 7, INACTIVE = 8 | | Minecart State (Cart Terminal) | 129 | cart-id | state | Returns 0 = UNKNOWN, 1 = STOPPED, 2 = RUNNING | | Minecart Distance (Cart Terminal)| 130 | cart-id | distance | Returns the distance from the cart to the Cart Terminal in meters | | Signal Tower Color | 130 | - | color | OFF = 0, GREEN = 1, AMBER = 2, RED = 3 | | Traffic Light Color | 130 | - | color | OFF = 0, GREEN = 1, AMBER = 2, RED = 3 | | Chest State | 131 | - | state | State of a TA3/TA4 chest or Sensor Chest: EMPTY = 0, LOADED = 1, FULL = 2 | | TA3/TA4 Button State | 131 | - | state | OFF = 0, ON = 1 | | Fuel Level | 132 | - | level | Fuel level of a fuel consuming block (0..65535) | | Quarry Depth | 133 | - | depth | Current depth value of a quarry block (1..80) | | Load Percent | 134 | 1 | load | Load value in percent (0..100) of a tank, silo, accu, fuelcell, or battery block. | | Load Absolute | 134 | 2 | load | Absolute value in units for silos and tanks | | Storage Percent | 134 | - | value | Read the grid storage amount (state of charge) in percent (0..100) from a TA3 Power Terminal. | | Consumer Current | 135 | - | current | TA3 Power Terminal: Total power consumption (current) of all consumers | | Delivered Power | 135 | - | power | Current providing power value of a generator block | | Total Flow Rate | 137 | - | rate | Total flow rate in liquid units for TA4 Pumps (0..65535) | | Sensor Chests State 1 | 138 | 1 | state | Last action: NONE = 0 PUT = 1, TAKE = 2 | | Sensor Chests State 4 | 138 | 4, idx | state | Number of inventory stack items (0..n)
`idx` is the inventory stack number (1..n) | | Item Counter | 139 | - | count | Item counter of the TA4 Item Detector block (0..n) | | Inventory Item Count | 140 | 1, idx| count | Amount of TA4 8x2000 Chest items
`idx` is the inventory slot number (1..8 from left to right, or 0 for the total number) | | Inventory Store Size | 140 | 3 | size | Size of one of the eight stores of the TA4 8x2000 Chest. Returns e.g. 6000 | | Binary State | 142 | - | state | Current block state: OFF = 0, ON = 1 | | Light Level | 143 | - | level | Light level value between 0 and 15 (15 is high) | | Solar Cell State | 145 | - | state | 0 = UNUSED, 1 = CHARGING, 2 = UNCHARGING | | Consumption | 146 | 0 | value | TA4 Electric Meter: Amount of electrical energy passed through | | Countdown | 146 | 1 | value | TA4 Electric Meter: Countdown value for the amount of electrical energy passed through | | Current | 146 | 2 | value | TA4 Electric Meter: Current flow of electricity (current) | | Time Stamp | 149 | - | time | Time in system ticks (norm. 100 ms) when the TA4 Button is clicked | | TA4 Pusher Counter | 150 | - | number | Read the number of pushed items for a TA4 Pusher in "flow limiter" mode | | TA4 Pump Counter | 151 | - | number | Read the number of pumped liquid units for a TA4 Pump in "flow limiter" mode | | Multi Button State | 152 | num | state | Read the button state (TA4 2x Button, TA4 4x Button)
`num` is the button number (1..4), `state`: 0 = "off", 1 = "on" | | Water Remover Depth | 153 | - | depth | Current depth value of a remover (1..80) | ### CMD$ Commands with Response as String Value The following table lists the numeric Techage commands that can be used with the `CMD$` function. These commands return a string response value from the device. In case of an error, the error subroutine is called and the response string is "". | Command | Topic (num) | Payload (numbers) | Response (string) | Remarks to the response | | ----------------------| ----------- | ---------------------- | ----------------------- | ------------------------------------------------------------ | | Identify | 128 | - | "\" | Node name as string like "techage:ta3_akku" | | Sensor Chests State 2 | 138 | 2 | "\" | Player name of last action | | Sensor Chests State 3 | 138 | 3, idx | "\" | Inventory Stack node name, or "none".
`idx` is the inventory stack number (1..n) | | Inventory Item Name | 140 | 2, idx | "\" | Name of TA4 8x2000 Chest items
`idx` is the inventory slot number (1..8 from left to right) | | Furnace Output | 141 | - | "\" | Node name of the Industrial Furnace output.
Returns "none", if no recipe is active | | Player Name | 144 | - | "\" | Player name of the TA3/TA4 Player Detector or TA4 Button | | DC2 Block Name | 147 | idx | "\" | Name of the placed block
`idx` is the inventory slot number (1..n) of the related the block position | | Distri. Filter Get | 148 | idx | "\" | `idx` is the slot number: 1 = "red", 2 = "green", 3 = "blue", 4 = "yellow"
Returns a string like: "default:dirt dye:blue" |