TeleBASIC Reference Guide +*#+=. -=++==-:.:- :@@@@@@%-. +@@@%##@@@@@@#. .******###+. :-: #@@%###*:=*+*#%@@@@@@@@@@@@@@%#+=:. *@@@%+ .@@@@#-=#@@@@@@@@@@@@@@@@@@@@*=--+@@#+-. -@@@%#*: ..-#@@@@@@@@@@@@@@@@@@@@%-=**:-@@@= :@@%*: +@@%%%+*. :=#@@@@@@@@@@@@@@@@%@@@@@+ *@@:=%@@@@#%*#+-**. #@@@*=.*@@@@@@@@@@@@%#*****=***##@:=-@@.**@@@+:=#-#@= #@##++@@@@@#####***#%%@@@@ =@%#%#+:#:#=**#%*=@#:@@# #@*+:=+**#@@@@@@@@@@@@@@@%--#%++-.=@:-:+#####%%#**-+# @#+=+=+=:*++++**#@@@@@@@@@@**==*@+=@#=. .=+*###*=. =@*@* -@@@@@@@@*-+%@@@@@%+#@@#**#=+#@@%%#*+-: :@@= .@@@@@#%*. ....=@@@@#+- @= ...==. -#++++## : =+- Dartmouth DTSS TeleBASIC (c) 1964,1966,1969,1970,1971,1979,2023 > What is TeleBASIC? TeleBASIC is the flavour of BASIC (Beginners' All-purpose Symbolic Instruction Code), used on Telehack (https://telehack.com/). TeleBASIC is based on the original Dartmouth BASIC, but with a large number of additional features, such as support for regular expressions, UNIX timestamps, many common hashing/encoding algorithms, multi-dimensional arrays, and the ability to use alphanumeric indices. Features from other types of BASIC such as HP2000 Access BASIC and Commodore BASIC have been added for increased compatibility and functionality. TeleBASIC has a wide user-base and is actively maintained by members of The Telehack Foundation (https://github.com/orgs/telehack-foundation/people/). > Table of Contents 1. Set Up Your Editor for BASIC Programming 2. Comparing/Logical Operators 3. Variables and Data Types 4. Arrays & Hashes 5. Command Overview 6. FAQ 7. ANSI Escape Sequences > 1. Set Up Your Editor for BASIC Programming -> Using External Text Editors There are currently four user-made plugins, which enable syntax-highlighting in various editors: * Atom (https://telehack.com/r/tg9sD) * Nova (https://telehack.com/r/gDAbA) * Sublime Text 3 (https://telehack.com/r/lP7iz) * Visual Studio Code (https://telehack.com/r/vxEjh) -> Using PED You can also use the text editor PED within Telehack - a massively augmented version of the original program by Niek Albers. Extra features include syntax highlighting, and the ability to run programs without closing the editor. These features are accessible via emacs-style meta-key shortcuts. To see a list of features type M-x list-packages RET. --> What does that mean? The "M" refers to the "meta" key on your keyboard (most often, this is the escape key) and "RET" refers to the "return" key. For example, to enable BASIC syntax highlighting, you would press escape, then x, then type "basic" and hit return. Thus, the shorthand would be M-x basic RET. Additionally, you do not need to type the full name of the command. It is sufficient to simply type M-x ba RET. To run a BASIC program within PED type M-x run RET. Command-line options ==================== ped /nomouse disables mouse input support ped /noexpand disables tab expansion ped /basic enables BASIC syntax highlighting ped /tablen=<n> set tab length to <n> > 2. Comparing / Logical Operators -> Comparing Operators * = (equal to) 10 A% = 0 : IF A% = 0 THEN PRINT "It is equal!" * > (greater than) 10 A% = 5 : IF A% > 0 THEN PRINT "It is greater!" * >= (greater than or equal to) 10 A% = 0 : IF A% >= 0 THEN PRINT "It is greater or equal!" * < (less than) 10 A% = -1 : IF A% < 0 THEN PRINT "It is less!" * <= (less than or equal to) 10 A% = 0 : IF A% <= 0 THEN PRINT "It is less or equal!" * <> (not equal to) 10 A% = 1 : IF A% <> 0 THEN PRINT "It is not equal!" -> Logical Operators * AND (bitwise "and" operation) * OR (bitwise "or" operation) * XOR (exclusive "or" operation) * NOT (negation) * EQV (material equivalence) * IMP (implication) --> Results Returned by Logical Operations OPERATION | VALUE | VALUE | RESULT ------------+-------+-------+--------- NOT | X | | NOT X NOT | True | | False NOT | False | | True OPERATION | VALUE | VALUE | RESULT ------------+-------+-------+---------- AND | X | Y | X AND Y AND | True | True | True AND | True | False | False AND | False | True | False AND | False | False | False OPERATION | VALUE | VALUE | RESULT ------------+-------+-------+--------- OR | X | Y | X OR Y OR | True | True | True OR | True | False | True OR | False | True | True OR | False | False | False OPERATION | VALUE | VALUE | RESULT ------------+-------+-------+---------- XOR | X | Y | X XOR Y XOR | True | True | False XOR | True | False | True XOR | False | True | True XOR | False | False | False OPERATION | VALUE | VALUE | RESULT ------------+-------+-------+---------- EQV | X | Y | X EQV Y EQV | True | True | True EQV | True | False | False EQV | False | True | False EQV | False | False | True OPERATION | VALUE | VALUE | RESULT ------------+-------+-------+---------- IMP | X | Y | X IMP Y IMP | True | True | True IMP | True | False | False IMP | False | True | True IMP | False | False | True -> Arithmetic Operators TeleBASIC supports the following standard mathematical operators: (), ^, **, mod, /, *, +, and -. > 3. Variables and Data Types You can store either text or numeric values in variables. Variable names can contain letters and digits, but they have to start with a letter (e.g FOO, BAR123$). You cannot use reserved keywords (e.g FOR, IF) as variable names. Variable names are most often suffixed with a type definition character (called a "sigil"): * $ represents a text (string) value * % represents a numeric (integer) value * ! represents a numeric (single-precision) value Strings MUST include the $ sigil. If a variable is missing a sigil, then it is a number. For example: 10 NAME$ = "some name" would represent a string variable NAME$, but 10 NAME = "some name" ...would throw a TYPE MISMATCH ERROR, since you cannot assign a string to a numeric variable. > 4. Arrays and Hashes An array variable is basically a list of values. These can be accessed by specifying an index number. In traditional Dartmouth BASIC, we define a string array of size 10: 10 DIM MYLIST$(10) Now we can modify the 5th Entry (note that the array index usually starts at 0, and can also be negative): 20 MYLIST$(4) = "some text" TeleBASIC, however, does not require you to define the array's size before accessing it, so DIM is not necessary. In addition to this, TeleBASIC allows for creation of multi-dimensional arrays, such as: 10 MYSTUFF( X, Y ) = 42 ... and indices do not need to be numeric. Thus, you can create unordered lists (hashes) such as: 10 FAV$("fruit") = "Apple" 20 FAV$("vehicle") = "Bicycle" 30 FAV$("language") = "TeleBASIC" > 5. Command Overview -> Index --> A * ACCESS Currently not implemented, does nothing * ARG$ A string containing all command line arguments * ARGC% The number of arguments passed to the program * ARGV$(n) An array containing all of the arguments passed to the program * ASC(s$) Returns the ASCII value of the first character in the string s$ * ATN(n) Returns the arctangent of the specified value n --> B * BIN$(n) Returns the binary representation of the integer n as a string * BRK(n) Currently not implemented, does nothing --> C * CALL Currently not implemented, does nothing * CHR$(n) Convert an ASCII code n to its equivalent character * CINT(n) Returns the nearest integer of the specified value * CIRCLE Currently not implemented, does nothing * COLOR(a, b) Changes the colours of the terminal * COS(n) Returns the cosinus of a specified value n in radians * CSNG(n) Convert a specified value n to a single precision number --> D * D2R(n) Convert degrees to radians * DATA n... Store variables accessed by the program READ statements * DEF FNname(Argument) = Expression Define a function * DEFDBL (Variable) Currently not implemented, does nothing * DEFINT (Variable) Currently not implemented, does nothing * DEFSNG (Variable) Currently not implemented, does nothing * DEFSTR (Variable) Currently not implemented, does nothing * DIM (Variable) Currently not implemented, does nothing * DIR$ Returns the filenames in your local directory, separated by spaces * DO Currently not implemented, does nothing * DRAW Currently not implemented, does nothing --> E * END End program execution silently, without additional output * EOF(n) Returns file pointer information * ERASE (arrays) To eliminate arrays from a program * EXP(n) Return base of natural logarithms to the power of n --> F * FOR x = startValue TO maxValue [STEP n] Execute a series of instructions * FRE Return available memory --> G * GOSUB (LineNumber) Branch to a subroutine and return * GOTO (LineNumber) Branch unconditionally to a specified line number --> H * HEIGHT Returns your terminal height * HEX$(n) Returns hexadecimal value of the specified number n --> I * IF expression THEN statements Make a decision regarding program flow * INKEY$ Returns one character read from the terminal * INPUT FileNo, var$ Reads a line from an open file * INPUT var$ Read user input * INPUT "prompt", var$ Read user input * INPUT varA$, varB$, ... Read user input * INPUT "prompt", varA$, varB$, ... Read user input * INSTR(string$, search$, startPos) Returns the position of a substring * INT (n) Truncate a value to a whole number * ITM(fileNumber) Returns the number of a data item --> L * LEFT$(s$, n) Returns the leftmost n characters of the specified string s$ * LEN(s$) Returns the number of characters in the specified string * LET Variable = Value Assigns a value to a variable * LIN(n) Returns n newlines * LOCATE y, x Change the cursor position to y, x * LOG(n) Returns the natural logarithm of n * LOG10(n) Returns the natural logarithm of n (base 10) --> M * MID$(s$, n, [l]) Returns a string of l characters from s$ --> N * NINT(n) Returns the nearest integer of the specified value * NUM(s$) Returns the ASCII value of the first character in the string s$ --> O * OCT$(n) Returns the octal value of n * ON NUMBER% Jump conditionally to a line number based on value given * OPEN filename$, AS fileNumber Opens a file --> P * PCLEAR0 Currently not implemented, does nothing * PCLEAR1 Currently not implemented, does nothing * PEEK(n) Read a value from the specified memory location n * PLAY Currently not implemented, does nothing * PMODE0 Currently not implemented, does nothing * POKE n, m Write a byte of data m into the specified memory location n * POLKEY$(n) Returns one character read from the terminal * PORT% Returns the port from the currently logged in user * POS(s1$,s2$) Returns the position of a substring * PRINT expression Prints an expression to the screen * PUT Currently not implemented, does nothing --> R * R2D(n) Converts n radians to degrees * READ n... or a file and assign to variable * REC(n) in the specified file * RENUMBER [start,[inc] Renumbers the statements of the current program * RESTORE statements to be reread * RETURN Return from a subroutine * RIGHT$(s$, n) Returns the rightmost n characters of s$ * RND(n) Returns a random number --> S * SCRATCH Delete a file from the disk * SCREEN Currently not implemented, does nothing * SGN(n) Returns the sign of the specified value n * SIN(n) Returns the trigonometric sine of the specified value n in radians * SLEEP n Pauses the program for n seconds * SOUND Currently not implemented, does nothing * SOUNDRND Currently not implemented, does nothing * SPACE$(n), SPC$(n), SPA(n) Returns n spaces * SQR(n) Returns the square root of n * STOP Halts the program and prints the current line * STR$(n) Returns n as a string value * STRING$(n, s$) Repeats the string s$ n times * SYSTEM End program execution silently, without additional output --> T * TAB(n), TAB$(n) Returns n spaces (not tabs!) * TAN(n) Returns trigonometric tangent of n in radians * TH_B64D$ Returns argument decoded from base64 * TH_B64E$ Returns argument encoded to base64 * TH_DEFGROUP$ Returns the user's defgroup, separated by spaces * TH_EXEC Executes a shell command and returns to the program * TH_GMTIME[$] Returns a human-readable UTC time for a timestamp * TH_HASADMIN(sat$) Returns 1 if the user has admin on sat$ * TH_HASBADGE(badge$) Returns when the user earned badge$ * TH_HASLOGIN(host$) Returns 1 if the user has login on host$ * TH_HASROOT(host$) Returns 1 if the user has root on host$ * TH_HASSYSOP(bbs$) Returns 1 if the user has sysop on bbs$ * TH_HOSTNAME$ Returns current hostname or hostname of argument passed * TH_LOCALTIME[$] Returns a human-readable local time for a timestamp * TH_MD5BASE64$ Returns md5 hex of argument passed as base64 * TH_MD5HEX$ Returns md5 hex of argument passed as hex * TH_MODEM$ Returns modem information depending on option passed * TH_NETSTAT$ Returns a netstat, separated by spaces * TH_PLAN$ Returns the user's .plan as a string * TH_RE(txt$,pat$,count,case) Returns regex matches * TH_RE$(txt$,pat$,ind$,case) Returns regex matches * TH_REV$(s$) Returns the string s$ in reverse order * TH_SED$(txt$,find$,replace$,opt$) Substitute matched substring * TH_SPRINTF$(fmt$,[...]) Returns a formatted string * TH_STATUS$ Returns the user's status as a string * TH_SYSLEVEL Returns the user's Telehack system level * TH_TIME Returns the current UNIX timestamp * TH_UUD$(s$) Decodes a uuencoded string * TH_UUE$(s$) Returns uuencoded form of input string * TIM(n) Returns values of time and date depending on n * TIME$ Returns the local system time * TIMER Returns the number of seconds since midnight * TROFF Stops tracing of program statements * TRON Starts tracing of program statements * TYP(n) Returns the type of the next record in a file --> U * UPS$(string) Returns the uppercase value of the given string * USER$ Returns the current logged in user --> V * VAL(s$) Returns the numeric value of s$ --> W * WIDTH Returns your terminal width > Detailed Overview -> ABS(n) Returns the absolute value of the specified value n 10 PRINT ABS(-40) 40 -> ACCESS Currently not implemented, does nothing -> ARG$ A string variable this is populated with a string containing the command line arguments when a BASIC program is run from the shell command prompt. 10 PRINT ARG$ @program foo bar foo bar -> ARGV$(n) An array containing all of the arguments passed to the program (see example for ARGC% below) -> ARGC% The number of arguments passed to the program 10 FOR I = 0 TO ARGC%-1 20 PRINT ARGV$(I) 30 NEXT I @program foo "hello world" bar [run program.bas foo "hello world" bar] program.bas foo hello world bar -> ASC(s$) Returns the ASCII value of the first character in the string s$ 10 PRINT ASC("A") 65 See also NUM -> ATN(n) Returns the arctangent of the specified value n 10 PRINT ATN(40) 1.546 -> BIN$(n) Returns the binary representation of the integer n as a string 10 PRINT BIN$(123) 1111011 -> BRK(n) Currently not implemented, does nothing -> CALL Currently not implemented, does nothing -> CHR$(n) Convert an ASCII code n to its equivalent character 10 PRINT CHR$(42) * -> CINT(n) Returns the nearest integer of the specified value (9.5 becomes 10) 10 PRINT CINT(5.7) 6 -> CIRCLE Currently not implemented, does nothing -> COLOR(a, b) Changes the background b and/or foreground a colour of the terminal 10 COLOR 3, 4 20 PRINT "Hello" Prints Hello with blue b background and yellow a foreground text. A list of possible colours can be found with the command SHOW COLORS. -> COS(n) Returns the cosinus of a specified value n in radians 10 PRINT COS(67) -0.517769799789505 -> CSNG(n) Convert a specified value n to a single precision number 10 PRINT CSNG("3.45") 3.450 -> D2R(n) Convert degrees to radians 10 PRINT D2R( 90 ) 1.571 -> DATA n... Store the numeric and string constants that are accessed by the program READ statements 10 DATA 4.1, 5.6, 9.98 20 READ A, B, C 30 PRINT A, B, C 4.100 5.600 9.980 -> DEF FNname(Argument) = Expression Define a function with the name FNname which accepts an Argument and returns the defined Expression. The function name must always begin with FN, followed by an optional space. 10 DEF FN square(x) = x^2 20 DEF FNcube(x) = x^3 30 DEF FNtood$(s$) = s$ + "tood" 40 PRINT FNsquare(5),FNcube(5),FNtood$("foo") 25 125 footood -> DEFDBL (Variable) Declare a variable as double precision number (currently not implemented, does nothing) -> DEFINT (Variable) Declare a variable as integer number (currently not implemented, does nothing) -> DEFSNG (Variable) Declare a variable as single precision number (currently not implemented, does nothing) -> DEFSTR (Variable) Declare a variable as string (currently not implemented, does nothing) -> DIM (Variable) Define an array of a fixed size (currently not implemented, does nothing) -> DIR$ Returns the filenames in your local directory, separated by spaces 10 PRINT DIR$ advent.gam againstip.txt basic15.a2 bbslist.txt c8test.c8 changelog.txt colossus.txt command.txt crackdown.txt do-well.txt etewaf.txt finger.txt fireworks.vt fnord.txt future.txt hammurabi.bas hckr_hnd.txt ien137.txt jfet.a2 johnnycode.txt k-rad.txt learncode.txt leaves.txt lem.bas lostpig.gam mastermind.bas notes.txt orange-book.txt oregon.bas porthack.exe privacy.txt rogue.gam rootkit.exe satcom.man smile.c8 starwars.txt sysmon.txt telehack.txt ttest.vt underground.txt unix.txt valentin.vt wardial.exe wumpus.bas xmodem.exe zork.gam -> DO Currently not implemented, does nothing -> DRAW Currently not implemented, does nothing -> END End execution of the program silently, without additional output (in contrast to STOP). Note that SYSTEM is an alias for END. 10 PRINT "hello" 20 GOSUB 100 30 END 40 PRINT "WORLD" 50 RETURN -> EOF(n) Returns -1 if the file pointer in file number n is currently at the end of the document, otherwise returns 0. The reason for -1 being used to denote truth is that -1 is 11111111 in binary, and conversely, 0 is 00000000. See also TYP. -> ERASE arrays Eliminate an array from the program. Accepts a list of arrays. 10 A(1) = 123 20 A(2) = 456 30 B$( "foo" ) = "bar" 40 B$( "bar" ) = "baz" 50 ERASE A, B$ 60 PRINT A(1) A(2) "'" B$( "foo" ) "' '" B$( "bar" ) "'" 0 0 '' '' -> EXP(n) Return the base of natural logarithms to the power of the specified value n 10 PRINT EXP(13) 442413.392 -> FOR x = startValue TO maxValue [STEP n] Execute a series of instructions a specified number of times in a loop, optionally incrementing x by n each time. Note that FOR I=A TO B STEP S: ... : NEXT I works like I=A; do { ... } while ((I+=S) < B); (in the C programming language), so the last NEXT I increases I one step beyond B. 10 FOR I = 1 TO 40 20 PRINT I 30 NEXT I 40 REM the I variable is now 41 This would run 40 times and output every time the current counter, incrementing I by 1 each time. 10 FOR I = 1 TO 40 STEP 2 20 PRINT I 30 NEXT I This would run 40 times and output the current counter in each iteration, and would increase I by 2 each time. 10 FOR I = 1 TO 0 STEP 0 20 PRINT I 30 NEXT I This would create an endless loop, printing 1 over and over until terminated. -> FRE Return the available system memory in bytes 10 PRINT FRE 1048576 -> GOSUB (LineNumber) Branch to a subroutine and return 10 GOSUB 100 20 PRINT "Now I'm back from the subroutine" 30 END 100 REM Subroutine starts here 110 PRINT "I am now in the subroutine" 120 RETURN I am now in the subroutine Now I'm back from the subroutine -> GOTO (LineNumber) Branch unconditionally out of the normal program sequence to a specified line number 10 PRINT "Hello World!" 20 GOTO 10 Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! [...] You might want to use a SLEEP statement here! -> HEIGHT Returns your terminal height -> HEX$(n) Returns a string which represents the hexadecimal value of the specified number n 10 PRINT HEX$(127) 7F -> IF expression THEN statements Make a decision regarding program flow based on the result of a returned expression 10 K = 3 20 J = 10 30 IF J > K THEN PRINT "J is bigger than K" J is bigger than K See section 2. Comparing/Logical Operators -> INKEY$ Returns one character read from the terminal. It will wait until a character is typed. For a non-blocking alternative, see POLKEY$ 10 A$ = INKEY$ 20 PRINT A$ -> INPUT var$ Shows the default prompt and reads input from the user and saves it into var$. 10 INPUT A$ 20 PRINT A$ -> INPUT "prompt", var$ Shows prompt$ and reads input from the user and saves it into var$. Note that the prompt must be a string literal, not a variable. 10 INPUT "Enter something>", A$ 20 PRINT A$ -> INPUT varA$, varB$, ... Shows the default prompt and reads input from the user, splits it at commas, and saves it into varA$, varB$, ... 10 INPUT A$, B$, C$ 20 PRINT A$, B$, C$ -> INPUT "prompt", varA$, varB$, ... Shows prompt$ and reads input from the user, splits it at commas, and saves it into varA$, varB$, ... Note that the prompt must be a string literal, not a variable. 10 INPUT "Enter something>", A$, B$, C$ 20 PRINT A$, B$, C$ -> INPUT FileNo, var$ Reads a line from an open file and saves it into var$ 10 INPUT# 1, A 20 PRINT A -> INSTR(string$, search$, startPos) Returns the position (starting with 0) of a substring within a string 10 TEXT$ = "Hello World" 20 SEARCHFOR$ = "W" 30 PRINT INSTR(TEXT$, SEARCHFOR$, 0) 6 -> INT (n) Truncate a value to a whole number 10 PRINT INT(5.6) 5 -> ITM(fileNumber) Returns the number of the data item currently pointed to in the current record of file fileNumber. In TeleBASIC this will almost always be 1. 10 PRINT #1;A,B,C 20 READ #1,1;A 30 PRINT REC(1),ITM(1) 1 2 -> LEFT$(s$, n) Returns the leftmost n characters of the specified string s$ 10 A$ = "Hello World" 20 B$ = LEFT$(A$, 5) 30 PRINT B$ Hello -> LEN(s$) Returns the number of characters in the specified string 10 A$ = "Hello World" 20 PRINT LEN(A$) 11 -> LET Variable = Value Assigns a value to a variable. Traditionally this is for use with constants, which are not supported in TeleBASIC, and so LET is superfluous. 10 LET A = 12345 20 PRINT A 12345 -> LIN(n) Returns n newlines 10 PRINT "A" LIN(2) "B" A B -> LOCATE y, x Change the cursor position to y, x 10 LOCATE 5, 5 -> LOG(n) Returns the natural logarithm of n using Euler's Number (https://en.wikipedia.org/wiki/E_(mathematical_constant)) as the base 10 PRINT LOG(6) 1.792 -> LOG10(n) Returns the natural logarithm of n using 10 as the base (decimal). 10 PRINT LOG10(6) 0.778 -> MID$(s$, n, [l]) Returns a string of l characters from s$ beginning with the nth character 10 A$ = "Hello World" 20 PRINT MID$(A$,3,3) llo -> NINT(n) Returns the nearest integer of the specified value (9.5 becomes 9) 10 PRINT NINT(5.6) 6 -> NUM(s$) Returns the ASCII value of the first character in the string s$ 10 PRINT NUM("A") 65 See also ASC -> OCT$(n) Returns the octal value of n 10 PRINT OCT$(66) 102 -> OPEN filename$, AS fileNumber Opens a file 10 OPEN "filename.txt", AS #1 -> ON NUMBER% Jump conditionally with GOTO/GOSUB, based on value given 10 NUMBER% = 2 20 ON NUMBER% GOTO 100,200,300 100 PRINT "Goto 100, will NOT jump here" : END 200 PRINT "Goto 200, will jump here" : END 300 PRINT "Goto 300, will NOT jump here" : END Goto 200, will jump here -> PCLEAR0 Currently not implemented, does nothing -> PCLEAR1 Currently not implemented, does nothing -> PEEK(n) Read a value from the specified memory location n 10 PRINT PEEK(1300) 83 -> PLAY Currently not implemented, does nothing -> PMODE0 Currently not implemented, does nothing -> POKE n, m Write a byte of data m into the specified memory location n 10 POKE 1300, 255 -> POLKEY$(n) Returns one character read from the terminal. When no key is hit within n seconds, it returns the empty string 10 A$ = POLKEY$(5) 20 REM This will wait 5 seconds, waiting for user input 30 PRINT A$ -> PORT% Returns the port from the currently logged in user. Not to be confused with the current socket (e.g 23 for telnet) 10 PRINT USER$ + " is logged in on port: " + STR$(PORT%) -> POS(s1$,s2$) Returns the position of s2$ in s1$ indexed from 1, or 0 if not found 10 A$="ABCDE" 20 PRINT POS(A$,"CD") 3 -> PRINT expression Prints an expression to the screen 10 A = 5 20 B = 10 30 PRINT A + B 15 10 A$ = "Hello " 20 B$ = "World" 30 PRINT A$; 40 PRINT B$ 50 PRINT A$ + B$ 60 PRINT A$ B$ Hello World Hello World Hello World & and ? are available aliases for PRINT Adding a ; at the end of PRINT will suppress the newline -> PRINT #fileNumber[,recordNumber]; expression Prints a expression into an open file, with optional record (line) number 10 OPEN "myfile.txt", AS #1 20 PRINT# 1, "Hello world" 30 CLOSE #1 -> PRINT #fileNumber[,recordNumber];END Prints an EOF mark to a file, truncating the file at that record 10 PRINT #1;A$ 20 PRINT #1,1;"Overwriting A$ in record 1" 30 PRINT #1,1;END : REM Truncates file at record 1 Observe the placement of the # in PRINT, AS, and CLOSE statements in the above examples -> PUT Currently not implemented, does nothing -> R2D(n) Converts n radians to degrees 10 PRINT R2D(1.2) 68.755 -> READ n... Read a value from DATA or a file and assign them to variables 10 DATA 4.1, 5.6, 9.98 20 READ A, B, C 30 PRINT A, B, C 4.100 5.600 9.980 -> READ #fileNumber[,recordNumber];variables Read a value from DATA or a file and assign them to variables 10 READ #1;A$ 20 READ #1,4;B$ -> REC(n) Returns the current record number (line number) in the specified file. Starts at 1 10 OPEN "telehack.txt", AS #1 20 INPUT# 1, DUMP$ 30 INPUT# 1, DUMP$ 40 INPUT# 1, DUMP$ 50 PRINT REC(1) 60 CLOSE #1 3 -> RENUMBER [start,[inc]] Renumbers the statements of the current program in memory. When optional parameters are not specified, number starts at 10 and increments by 10 for each line. Can be abbrieviated to REN or RENUM. Useful if you want to add more lines between existing statements >1 GOTO 2 >2 END >REN >LIST 10 GOTO 20 20 END -> RESTORE Allow DATA statements to be reread 10 DATA 4.1, 5.6, 9.98 20 READ A, B, C 30 PRINT A, B, C 40 RESTORE 50 READ A, B, C 60 PRINT A, B, C 4.100 5.600 9.980 4.100 5.600 9.980 -> RETURN Return from a subroutine, for use with GOSUB. 10 GOSUB 30 20 END 30 PRINT "Hello" 40 RETURN Hello -> RIGHT$(s$, n) Returns the rightmost n characters of the specified string s$ 10 A$ = "Hello World" 20 PRINT RIGHT$(A$, 5) World -> RND(n) If n < 0, returns a random number in the interval [0, 1] seeded by n If n = 0, returns a random number in the interval [0, 1] If n > 0, returns a random number in the interval [0, n] 10 PRINT RND(-5) 20 PRINT RND(0) 30 PRINT RND(5) 0.249 0.912 2.376 -> SCRATCH Delete a file from the disk 10 SCRATCH "FOOBAR.TXT" ARE YOU SURE? Y/n y FOOBAR.TXT removed. Any input that is not Y (case insensitive) will cancel the operation. Runs silently when run with variable assignment, i.e will not prompt for confirmation 10 PRINT "HELLO" 20 SCRATCH "FOOBAR.TXT" ; FOO$ 30 PRINT "WORLD" HELLO WORLD -> SCREEN Currently not implemented, does nothing -> SGN(n) Returns the sign of the specified value n 10 PRINT SGN(5) 20 PRINT SGN(0) 30 PRINT SGN(-7) 1 0 -1 -> SIN(n) Returns the trigonometric sine of the specified value n in radians 10 PRINT SIN(36) -0.991778853443116 -> SLEEP n Pauses the program for n seconds 10 SLEEP 5 -> SOUND Currently not implemented, does nothing -> SOUNDRND Currently not implemented, does nothing -> SPACE$(n), SPC$(n), SPA(n) Returns n spaces 10 PRINT "ABC" SPACE$(10) "ABC" abc abc -> SQR(n) Returns the square root of n 10 PRINT SQR(36) 6 -> STOP Halts the program and prints the current line. Useful for debugging programs -> STR$(n) Returns n as a string value 10 PRINT STR$(12345) 12345 -> STRING$(n, s$) Repeats the string s$ n times 10 PRINT STRING$(10, "A") AAAAAAAAAA -> TAB(n), TAB$(n) Returns n spaces (not tabs!) 10 PRINT "ABC" TAB$(10) "ABC" abc abc -> TAN(n) Returns the trigonometric tangent of the specified value n in radians 10 PRINT TAN(38) 0.310 -> TH_SYSLEVEL Returns the user's Telehack system level. Optionally takes a username as argument. 10 PRINT TH_SYSLEVEL 20 PRINT TH_SYSLEVEL("quantx") 12 81 The user executing the above code would evidently have 12 badges. -> TH_HASBADGE(badge$) Returns a UNIX timestamp of when the user earned badge$, or 0 10 PRINT TH_HASBADGE("ACCT") 1559673339 10 PRINT TH_HASBADGE("ACCT", "doesntexist") 0 -> TH_HASLOGIN(host$) Returns 1 if the user has login on host$, otherwise 0 10 PRINT TH_HASLOGIN("mimsy") 1 10 PRINT TH_HASLOGIN("ames") 0 -> TH_HASROOT(host$) Returns 1 if the user has root on host$, otherwise 0 10 PRINT TH_HASROOT("mimsy") 1 10 PRINT TH_HASROOT("ames") 0 -> TH_HASSYSOP(bbs$) Returns 1 if the user has sysop on bbs$, otherwise 0 10 PRINT TH_HASSYSOP("maccavern") 1 10 PRINT TH_HASSYSOP("illuminati") 0 -> TH_HASADMIN(sat$) Returns 1 if the user has admin on sat$, otherwise 0 10 PRINT TH_HASADMIN("sat_BT 5") 1 -> TH_DEFGROUP$ Returns the user's defgroup, separated by spaces 10 PRINT TH_DEFGROUP$ archer lorelei -> TH_PLAN$ Returns the user's .plan as a string 10 PRINT TH_PLAN$ To write a BASIC program <3 -> TH_TIME Returns the current UNIX timestamp 10 PRINT TH_TIME 1675018633.67413 -> TH_LOCALTIME[$] Returns a human-readable local time for the given UNIX timestamp. 10 PRINT TH_LOCALTIME$(TH_TIME) Wednesday, December 9, 2020 6:40:49 PM PST Returns values of time and date if options are supplied, and no sigil: * 0 - sec * 1 - min * 2 - hour * 3 - mday * 4 - mon * 5 - year * 6 - wday * 7 - yday * 8 - isdst 10 FOR I = 0 TO 8 : PRINT TH_LOCALTIME(I,0) : NEXT I 0 0 16 31 11 69 3 364 0 -> TH_GMTIME[$] Returns a human-readable UTC time for the given UNIX timestamp with the same options as TH_LOCALTIME[$] -> TH_MODEM$ Returns modem information depending on option passed: * 0 number * 1 filename * 2 hostname * 3 description * 4 baud rate * 5 administrator * 6 location -> TH_HOSTNAME$ Returns current hostname or hostname of argument passed. Supports OSPROBER plugin. 10 PRINT TH_HOSTNAME$ telehack -> TH_NETSTAT$ Returns current netstat, or netstat of hostname passed as argument, separated by spaces adaptex cotds mimsy oddjob oracle tandem veritas -> TH_MD5HEX$ Returns md5 hex of argument passed as hex 10 PRINT TH_MD5HEX$("FOO") 901890a8e9c8cf6d5a1a542b229febff -> TH_MD5BASE64$ Returns md5 hex of argument passed as base64 10 PRINT TH_MD5BASE64$("FOO") kBiQqOnIz21aGlQrIp/r/w -> TH_B64E$ Returns argument encoded to base64 10 PRINT TH_B64E$("Telehack") VGVsZWhhY2s= -> TH_B64D$ Returns argument decoded from base64 10 PRINT TH_B64D$("VGVsZWhhY2s=") Telehack -> TH_EXEC Executes a shell command and returns to the current BASIC program 10 TH_EXEC "echo foo" : TH_EXEC "echo bar" foo bar 10 TH_EXEC "fnord", OUT$ : PRINT OUT$ The iguana from Austin will go to Austin. Note: variables assigned with TH_EXEC will have trailing CRLF characters, much like back-ticks in bash scripts. -> TH_RE(txt$,pat$,countmode,ignorecase) Number context, returns a boolean (1 or 0) depending on regex match 10 IF TH_RE( "hello", "l{2}" ) THEN PRINT "it matches" it matches If countmode is true, returns number of matches: 10 PRINT TH_RE( "HELLO", "L", 1 ) 2 -> TH_RE$(txt$,pat$,ind,ignorecase) String context, returns single captured group of match 10 PRINT TH_RE$( "hello world", "he\w+" ) hello If an index n is provided, the string returned will be the nth captured group: 10 PRINT TH_RE$( "FOO BAR BAZ BINGO BANGO", "BA...", 2 ) BANGO In the above example, the match returned is not "BAZ B", since the "B" in "BAZ" has already been consumed by the first match. If the index supplied is 0, it will return the final match. If no index is supplied, it will return the first match. -> TH_REV$(s$) Returns the string s$ in reverse order 10 PRINT TH_REV$( "deliver" ) reviled -> TH_SED$(txt$,find$,replace$,opt$) Stream editor, replaces matched substring with substitution Available options: * "i" = case insensitive * "g" = global mode 10 PRINT TH_SED$( "foo bAR", "oo|ar", "izz", "gi" ) fizz bizz -> TH_SPRINTF$(fmt$,[...]) Returns a formatted string based on given parameters: * %% - A percent sign * %c - A character with the given decimal number * %s - A string of characters * %S - A string of characters, left aligned * %d - A signed integer, in decimal * %b - An unsigned integer, in binary * %u - An unsigned integer, in decimal * %o - An unsigned integer, in octal * %x - An unsigned integer, in hexadecimal * %a - Hexadecimal floating point * %n - Interprets width as positional index (see example 2) * %r - Returns a random value from the list as a string * %e - A floating-point number, in scientific notation * %f - A floating-point number, in fixed decimal notation * %g - A floating-point number, in %e or %f notation * %h - A floating-point number, in IEEE-754 notation * %i - Exactly like %d, for compatibility, or something * %y - Returns the decimal form of a hexadecimal unsigned int value * %z - Returns decimal form of IEEE-754 input value * %D - Like %d, but longer * %U - Like %u, but longer * %O - Like %o, but longer * %F - Like %f, but longer * %B - Like %b, but LOUDER * %R - Like %r, but left-aligned * %X - Like %x, but using upper-case letters * %E - Like %e, but using an upper-case "E" * %G - Like %g, but with an upper-case "E" (if applicable) * %H - Like %h, but using upper-case letters * %A - Like %a, but using upper-case letters --> Example 1: 10 F$ = "%s likes to %s while %sing" 20 PRINT TH_SPRINTF$( F$, "Sam", "sing", "cook" ) 30 PRINT TH_SPRINTF$( F$, "Izumi", "read", "relax" ) 40 PRINT TH_SPRINTF$( F$, "Wumpus", "tood", "tood" ) Sam likes to sing while cooking Izumi likes to read while relaxing Wumpus likes to tood while tooding --> Example 2: 10 PRINT TH_SPRINTF$( "%2n%1n%1n", "na", "Ba" ) Banana --> Example 3: 10 PRINT TH_SPRINTF$("%42R...YOU LOSE","HEADS","TAILS") TAILS ...YOU LOSE --> Example 4: 10 F$ = "I got %08b problems but leading zeros ain't %08b." 20 PRINT TH_SPRINTF$( F$, 99, 1 ) I got 01100011 problems but leading zeros ain't 00000001. --> Example 5: 10 DATA "Name", "Car", "Country" 20 DATA "----", "---", "-------" 30 DATA "Bill", "Volvo", "New Zealand" 40 DATA "Alex", "Ferrari", "Italy" 50 DATA "Wumpus", "Tesla", "United States" 60 FOR I = 1 TO 5 70 READ A$, B$, C$ 80 PRINT TH_SPRINTF$("%10S%12S%12S", A$, B$, C$) 90 NEXT I Name Car Country ---- --- ------- Bill Volvo New Zealand Alex Ferrari Italy Wumpus Tesla United States -> TH_STATUS$ Returns the user's status as a string -> TH_UUD$(s$) Decodes a uuencoded string 10 PRINT TH_UUD$("#9F]O") foo -> TH_UUE$(s$) Returns uuencoded form of input string 10 PRINT TH_UUE$("foo") #9F]O -> TIM(n) Returns values of time and date depending on n * 0 - Current minute (0-59) * 1 - Current hour (0-23) * 2 - Current day (1-366) * 3 - Current year (0-99) * 4 - Current second (0-59) 10 PRINT TIM(0) 29 -> TIME$ Returns the local system time 10 PRINT TIME$ 07:49:38 -> TIMER Returns the number of seconds since midnight 10 PRINT TIMER 28210 -> TYP(n) Returns the type of the next record in a file Return values: * 1 - Numeric data (not currently working) * 2 - String data * 3 - End of file 10 REM CREATE A FILE FOR TESTING 20 FILENAME$ = "TEST" + STR$(INT(RND(1)*128*2)) + ".TXT" 30 OPEN FILENAME$, AS #1 40 REM POPULATE FILE WITH TEST DATA 50 PRINT# 1, "some text" 60 REM SAVE FILE 70 CLOSE #1 80 REM TEST TYP() COMMAND 90 OPEN FILENAME$, AS #1 100 PRINT TYP(1) 110 REM ADVANCE ONE RECORD 120 INPUT# 1, DUMP$ 130 PRINT TYP(1) 140 CLOSE #1 2 3 See also EOF. -> TROFF Stops tracing of program statements. Useful for debugging -> TRON Starts tracing of program statements. Useful for debugging -> UPS$(string) Returns the uppercase value of the given string 10 PRINT UPS$("hello") HELLO -> USER$ Returns the current logged in user 10 PRINT USER$ archer -> VAL(s$) Returns the numeric value of s$ 10 PRINT VAL("12345") 12345 -> WIDTH Returns your terminal width > 6. FAQ -> Q: I need a NAND function, but there is none. A: Create the function with: DEF FNNAND( A, B ) = NOT ( A AND B ) Now you can call it with: 10 PRINT FNNAND( 0, 0 ) 1 -> Q: How do I read from a file? A: Like this: 10 OPEN "filename.txt", AS #1 20 IF EOF(1) THEN GOTO 60 30 INPUT# 1, A$ 40 PRINT A$ 50 GOTO 20 60 CLOSE #1 -> Q: How do I write to a file? A: Like this: 10 OPEN "filename.txt", AS #1 20 PRINT# 1, "Hello World!" 30 CLOSE #1 -> Q: How do I append a file? A: You have to open the file and put the file-pointer at the end of file, like this: 10 OPEN "filename.txt", AS #1 20 IF EOF(1) THEN GOTO 50 30 INPUT# 1, DUMP$ 40 GOTO 20 50 PRINT# 1, "We are now at the EOF, and appending stuff" 60 CLOSE #1 A2: The solution above (linear search) is somewhat slow for large files. Exponential search (https://en.wikipedia.org/wiki/Exponential_search) is more complicated, but finds the end of a 10000-line file in ~0.03 seconds instead of ~31.6 seconds (1000x faster). Below is an example subroutine: 10 OPEN "filename.txt", AS #1 20 GOSUB 250 : 'probe now points to the last line, but file pointer DOES NOT NECESSARILY. 30 READ #1, probe; lastline$ : 'advance file pointer to probe 40 PRINT# 1, "We are now at EOF, and appending stuff" 50 PRINT "The previous last line", lastline$ 60 CLOSE 1 200 END 250 probe=2 : DIM last(2) : last(0)=0 : last(-1)=2^52-1 255 '(0) is last good line , (-1) is last bad line (EOF), initialized to max int 260 READ #1, probe 265 ' read record at index (probe) from file #1, but not into any variables. 266 ' this is slightly faster than input#. 270 last(EOF(1)) = probe 275 'store the probed offset as either good or bad, depending on whether we hit EOF or not. 280 x = probe*2 : y = last(0) + INT((last(-1)-last(0))/2) : 'Exponential search for EOF 285 'halfway between last known good and last EOF (binary search) 290 probe = y XOR ((x XOR y) AND -(x < y)) 295 ' probe = min(x,y); picks binary search when probe overshoots 300 IF probe > last(0) GOTO 260 305 ' probe>good implies (bad-good)/2>=1 implies EOF may lie beyond good+1; keep probing. 310 RETURN -> Q: How do I create a BBS? A: You can create a BBS by running PPPD.EXE, and pointing it at your BASIC program file. Your BBS will then appear in bbslist.txt. Your BBS baud-rate must be 115200 (11.520 kbps) in order for it to appear in the Telehack netstat. To gain access to faster baud-rates requires you to upgrade your modem firmware (both SYSADM and BLUEBOX badges are required.) -> Q: How do I split a string into an array? A: There are two methods. The Traditional "Pure BASIC" Method, and the Modern RegEx Method. Both methods are detailed below. --> Traditional "Pure BASIC" Method This method involves iterating through your string YOURSTRING$ and looking for a delimiter DELIMITER$. For every iteration put the actual character at that position in the string YOURSTRING$ in a temporary variable TSTR$. Once you have found the delimiter DELIMITER$, save the result of the temporary variable TSTR$ into an array. MAXSTACK tells you how many items are actually in the array. See the example below: 10 DIM ARRAY$(2) 20 DELIMITER$ = " " 30 YOURSTRING$ = "Hello World" 40 MAXSTACK = 0 45 REM PUT YOUR PROGRAM LOGIC HERE 50 GOSUB 100 55 REM PUT YOUR PROGRAM LOGIC HERE 60 END 100 REM split 110 TSTR$ = "" 120 FOR I = 1 TO LEN(YOURSTRING$) 130 IF MID$(YOURSTRING, I, 1) = DELIMITER$ THEN GOTO 200 140 TSTR$ = TSTR$ + MID$(YOURSTRING$, I, 1) 150 IF I = LEN(YOURSTRING$) THEN GOTO 200 160 NEXT I 170 RETURN 200 REM We have found a delimiter and are pushing it into the array 210 MAXSTACK = MAXSTACK + 1 220 ARRAY$(MAXSTACK) = TSTR$ 230 TSTR$ = "" 240 GOTO 160 --> Modern RegEx Method Let's say, for this example, you have the string NAMES$ which is a list of names separated by a comma ,. To access this as an array is very straightforward using Telehack language extentions: 10 NAMES$ = "Tom,Dick,Harry,Bob,Steve,Imhotep" 20 PATTERN$ = "[^\,]+" 30 FOR I = 1 TO TH_RE(NAMES$,PATTERN$,1) 40 PRINT TH_RE$(NAMES$,PATTERN$,I) 50 NEXT I Tom Dick Harry Bob Steve Imhotep The above example uses both TH_RE (number context), and TH_RE$ (string context). -> Q: How can I learn how to write regular expressions? A: The executable GOLF.EXE contains multiple lessons on regular expressions. You can also find many RegEx-related challenges in the DOJO. -> Q: How do I generate a random number? A: Like this: 10 RANDOMIZE TIMER 20 MAXNR = 10 20 RNR = INT(RND(1)*MAXNR) 30 PRINT RNR The above example is a pseudorandom number generator, with TIMER being the seed. -> Q: I would like to code in BASIC, but all those line numbers are messy! A: You don't actually have to use line numbers at all in TeleBASIC! They are only necessary for when using GOTO or GOSUB. You also don't have to put everything in uppercase, but doing so means your code will be more compatible with other historical flavours of BASIC. Here is an example of a modern TeleBASIC program: 1 ' begin input "What is your name? " n$ print "Hello, " n$ "! There are" len( n$ ) "characters in your name:" for l = 1 to len( n$ ) ? l ": " mid$( n$, l, 1 ) next : ? input "Again? [y/n] " ; yn$ if yn$ = "y" then goto 1 ? "Goodbye!" end What is your name? bob Hello, bob! There are 3 characters in your name: 1 : b 2 : o 3 : b Again? [y/n] y What is your name? steve Hello, steve! There are 5 characters in your name: 1 : s 2 : t 3 : e 4 : v 5 : e Again? [y/n] n Goodbye! Additionally, there is a script written by archer which allows you to use labels instead of numbers. Find it on archer's GitHub (https://p85.github.io/renumber/renumber.html). -> Q: How do I use COMM.EXE via BASIC? A: Refer to this guide by archer (https://telehack.com/r/pvELT). -> Q: What's with the fish? A: That's our mascot, Bassy the dart-mouthed bass. > 7. ANSI Escape Sequences -> General Info An ANSI escape sequence is a sequence of ASCII characters, the first two of which are the ASCII "escape" character (chr$(27)) and the left-bracket character [ (chr$(91)). The character or characters following the escape and left-bracket characters specify an alphanumeric code that controls a keyboard or display function. For example, these can be used instead of, or in addition to LOCATE (for locating the cursor in the window); COLOR (for setting text and background colours) and getting the user's arrow-key input. Using escape sequences can give you greater control over how your program displays its output. Be aware that not all terminal types support some of these sequences, and your terminal must support 256-bit colours in order to display such colours. Standard escape codes are prefixed with Escape, which is represented in the following ways: FORMAT | VALUE --------------+--------- Ctrl-Key | ^[ Octal | \033 Unicode | \u001b Hexadecimal | \x1b Decimal | 27 This is then followed by the command, somtimes delimited by opening square bracket [ known as a Control Sequence Introducer (CSI), optionally followed by arguments and the command itself. Arguments are delimeted by semi colon (;). For example boldred$ = chr$(27) + "[1;31m". -> General ASCII Codes NAME | DECIMAL | OCTAL | HEX | C-ESCAPE | CTRL-KEY | DESCRIPTION -------+---------+-------+------+----------+----------+------------------- BEL | 7 | 007 | 0x07 | \a | ^G | Terminal bell BS | 8 | 010 | 0x08 | \b | ^H | Backspace HT | 9 | 011 | 0x09 | \t | ^I | Horizontal TAB LF | 10 | 012 | 0x0A | \n | ^J | Linefeed VT | 11 | 013 | 0x0B | \v | ^K | Vertical TAB FF | 12 | 014 | 0x0C | \f | ^L | Formfeed CR | 13 | 015 | 0x0D | \r | ^M | Carriage return ESC | 27 | 033 | 0x1B | \e | ^[ | Escape character DEL | 127 | 177 | 0x7F | <none> | <none> | Delete character Note: Some control escape sequences, like \e for ESC, are not guaranteed to work in all languages and compilers. It is recommended to use the decimal, octal or hex representation as escape code. The Ctrl-Key representation is simply associating the non-printable characters from ASCII code 1 with the printable characters from ASCII code 65 ("A"). ASCII code 1 would be ^A (Ctrl-A), while ASCII code 7 (BEL) would be ^G (Ctrl- G). This is a common representation (and input method) and historically comes from one of the VT series of terminals. -> Cursor Controls SEQUENCE | DESCRIPTION -----------------------+--------------------------------- ESC[H | Moves cursor to home position | (0, 0) ESC[{line};{column}H | Moves cursor to line #, column | # ESC[{line};{column}f | Moves cursor to line #, column | # ESC[#A | Moves cursor up # lines ESC[#B | Moves cursor down # lines ESC[#C | Moves cursor right # columns ESC[#D | Moves cursor left # columns ESC[#E | Moves cursor to start of next | line, # lines down ESC[#F | Moves cursor to start of | previous line, # lines up ESC[#G | Moves cursor to column # ESC[6n | Request cursor position | (reports as ESC[#;#R) ESC7 | Save cursor position (DEC) ESC8 | Restores the cursor to the | last saved position (DEC) ESC[s | Save cursor position (SCO) ESC[u | Restores the cursor to the | last saved position (SCO) ESC[?25h | Show cursor ESC[?25l | Hide cursor Note: Some sequences, like saving and restoring cursors, are private sequences and are not standardized. While some terminal emulators (i.e. xterm and derived) support both SCO and DEC sequences, they are likely to have different functionality. It is therefore recommended to use DEC sequences. -> Erase Functions SEQUENCE | DESCRIPTION -----------+--------------------------------- ESC[J | Clears the screen ESC[0J | Clears from cursor until end | of screen ESC[1J | Clears from cursor to | beginning of screen ESC[2J | Clears entire screen ESC[K | Clears the current line ESC[0K | Clears from cursor to end of | line ESC[1K | Clears from cursor to start of | line ESC[2K | Clears entire line -> Colours / Graphics Mode / Character Attributes SEQUENCE | RESET SEQUENCE | DESCRIPTION ------------------+----------------+--------------------------------- ESC[1;34;{...}m | | Set graphics modes for cell ESC[m | | Reset all modes (styles and | | colours) ESC[0m | | Same as above ESC[1m | ESC[22m | Set bold mode. ESC[2m | ESC[22m | Set dim/faint mode. ESC[3m | ESC[23m | Set italic mode. ESC[4m | ESC[24m | Set underline mode. ESC[5m | ESC[25m | Set blinking mode ESC[7m | ESC[27m | Set inverse/reverse mode ESC[8m | ESC[28m | Set hidden/invisible mode ESC[9m | ESC[29m | Set strikethrough mode. Note: Some terminals may not support some of the graphic mode sequences listed above. Both dim and bold modes are reset with the ESC[22m sequence. The ESC[21m sequence is a non-specified sequence for double underline mode and only works in some terminals and is reset with ESC[24m. -> Colour Codes Most terminals support 8 and 16 colours, as well as 256 (8-bit) colours. These colours are set by the user, but have commonly defined meanings. --> 8-16 Colours COLOUR | FOREGROUND | BACKGROUND ----------+------------+------------- Black | 30 | 40 Red | 31 | 41 Green | 32 | 42 Yellow | 33 | 43 Blue | 34 | 44 Magenta | 35 | 45 Cyan | 36 | 46 White | 37 | 47 Default | 39 | 49 Reset | 0 | 0 Note: the Reset colour is the reset code that resets all colours and text effects, Use Default colour to reset colours only. Most terminals, apart from the set of 8 regular colours, also support the "bright" or "bold" colours. These have their own set of codes, mirroring the normal colours, but with an additional ;1 in their codes: e$ = chr$(27) ' Set style to bold, red foreground hello$ = e$ + "[1;31m" + "Hello" ' Set style to dimmed white foreground with red background world$ = e$ + "[2;37;41m" + "World" Terminals that support the aixterm specification provide bright versions of the ISO colours, without the need to use the bold modifier: COLOUR | FOREGROUND | BACKGROUND -----------------+------------+------------- Bright Black | 90 | 100 Bright Red | 91 | 101 Bright Green | 92 | 102 Bright Yellow | 93 | 103 Bright Blue | 94 | 104 Bright Magenta | 95 | 105 Bright Cyan | 96 | 106 Bright White | 97 | 107 --> 256 Colours The following escape codes tells the terminal to use the given colour: SEQUENCE | DESCRIPTION -----------------+------------------------ ESC[38;5;{ID}m | Set foreground colour ESC[48;5;{ID}m | Set background colour Where ID should be replaced with the colour index from 0 to 255 of the following colour chart: Generate this table with the following BASIC code: 10 FOR I = 0 TO 255 20 S$ = TH_SPRINTF$( "%4S", I ) 30 ? CHR$(27) "[38;5;" STR$(I) "m" S$ ; 40 IF NOT (I+1) MOD 16 THEN ? 50 NEXT This table starts with the original 16 colours (0-15). The proceeding 216 colours (16-231) are formed by a 3bpc RGB value offset by 16, packed into a single value. The final 24 colours (232-255) are grayscale starting from a shade slighly lighter than black, ranging up to shade slightly darker than white. Some emulators interpret these steps as linear increments (256 / 24) on all three channels, although some emulators may explicitly define these values. --> RGB Colours More modern terminals supports Truecolor (24-bit RGB), which allows you to set foreground and background colours using RGB values. These escape sequences are usually documented poorly, if at all. SEQUENCE | DESCRIPTION ------------------------+-------------------------------- ESC[38;2;{r};{g};{b}m | Set foreground colour as RGB. ESC[48;2;{r};{g};{b}m | Set background colour as RGB. Note: ;38 and ;48 corresponds to the 16 colour sequence and is interpreted by the terminal to set the foreground and background colour respectively, whereas ;2 and ;5 sets the colour format. -> Common Private Modes These are some examples of private modes, which are not defined by the specification, but are implemented in most terminals. SEQUENCE | DESCRIPTION -------------+--------------------------------- ESC[?25l | Make cursor invisible ESC[?25h | Make cursor visible ESC[?47l | Restore screen ESC[?47h | Save screen ESC[?1049h | Enables the alternative buffer ESC[?1049l | Disables the alternative | buffer -> DEC Special Graphics DEC Special Graphics is a 7-bit character set developed by Digital Equipment Corporation. This was used very often to draw boxes on the VT100 video terminal and the many emulators, and used by bulletin board software. SEQUENCE | DESCRIPTION -----------+------------------------------- ESC(0 | Enable DEC special graphics ESC(B | Disable DEC special graphics -> Colour Examples (8-bit) 10 PRINT CHR$(27) + "[92mThe foreground is green" CHR$(27) "[m" 20 PRINT CHR$(27) + "[103mThe background is yellow" CHR$(27) "[m" -> Colour Examples (16-bit) 10 PRINT CHR$(27) + "[38;5;134mThe foreground is purple" CHR$(27) "[m" 20 PRINT CHR$(27) + "[48;5;117mThe background is sky blue" CHR$(27) "[m" -> Get Arrow Key Input 10 KEY$ = INKEY$ 20 IF KEY$ = CHR$(27) THEN KEY$ = INKEY$ : IF KEY$ = "[" THEN GOTO 40 30 GOTO 10 40 KEY$ = INKEY$ 50 IF KEY$ = "A" THEN PRINT "UP" 60 IF KEY$ = "B" THEN PRINT "DOWN" 70 IF KEY$ = "C" THEN PRINT "RIGHT" 80 IF KEY$ = "D" THEN PRINT "LEFT" 90 GOTO 10