+--------------------------------------------------------------------+ | | | T I P I version 1.0 | | X X | | / \ / \ | | / \ Copyright (c) 1993 / \ | | / + \ by / + \ | | / + \ Kent P. Peterson / + \ | | / O \ / O \ | | All Rights Reserved | +--------------------------------------------------------------------+ | TIPI 1.0 is provided as shareware. Under the shareware | | concept, you can test a program before you buy it. If you find | | it suitable for your needs and make use of this program, you are | | expected to send a $25 registration fee. | | | | Feel free to distribute this software to others. However, you | | may not charge for the distribution of this software to others | | nor may you alter the software or this documentation. | | | | Registered users of any version of TIPI will receive a diskette | | containing the current version of TIPI, plus may purchase future | | updates at half of the normal registration price. A printed | | manual is available to registered users for an additional $10.00. | | | | For further ordering information, please see the file ORDER.FRM, | | included with TIPI. | +--------------------------------------------------------------------+ | | | Please send registration fees and suggestions to: | | | | Kent P. Peterson | | 360 NW Dogwood #A-201 | | Issaquah, WA 98027-3272 | | | | Please mention the version of TIPI in any correspondence | | (This is TIPI Version 1.0) | +--------------------------------------------------------------------+ | You can also send questions/comments via Internet or Compuserve | | | | Internet tipi@prostar.com | | | | Compuserve 72310,2174 | | | +--------------------------------------------------------------------+ | | | DISCLAIMER: This software is provided "as is" without warranty | | of any kind, either expressed or implied. | | | | Your registration fee entitles you to distribute TIPI.COM together| | with any TIPI programs you write. If you profit from working with | | TIPI, please register it. Thank you. | +--------------------------------------------------------------------+ page 1 Contents Introduction..................................................2 History.......................................................2 Installing TIPI...............................................2 Running TIPI..................................................3 The TIPI Programmer's Workbench...............................3 TIPI Programming..............................................5 Instruction Descriptions......................................7 Errors and the TIPI Debugger..................................8 Defining New Instructions....................................10 Working with Stacks..........................................11 Defining and Using Variables and Tables......................11 Common mistakes of new TIPI Programmers......................13 Notes and Limits.............................................13 Math Instructions............................................14 String Instructions..........................................16 Stack Instructions...........................................20 I/O Instructions.............................................23 DOS Instructions.............................................30 Defining Instructions........................................33 Data Instructions............................................35 Control Instructions.........................................36 Debugging Instructions.......................................40 Miscellaneous Instructions...................................41 page 2 Introduction TIPI is a small, structured programming language for MS-DOS computers. The TIPI interpreter takes up less than 10K bytes of disk space and TIPI programs are similarly small. TIPI requires only 120K bytes of RAM and is thus well-suited for palmtop computers such as the Atari Portfolio, the Poquet or the HP-95LX. TIPI contains over 100 instructions and control structures including Do..Loop, While..Wend and Begin..Until Loops. TIPI also includes If..Then..Else and Case statements and an integrated debugger. TIPI is an extensible language, so programmers may add to the language as they see fit. History TIPI is a new language, but it incorporates elements from various earlier languages. The languages Forth and BASIC most stongly influenced the development of TIPI, but some of TIPI's features may be traced back to C, Pascal or AWK. TIPI was invented by Kent P. Peterson in 1993. The TIPI language and the TIPI interpreter are copyright (c) 1993 by Kent P. Peterson. The name TIPI is an acronym standing for "Threaded Instruction Processing Interpreter". While interpreted programs tend to run slower than compiled programs, interpreters do not require a seperate compile and link stage and thus programs can be quickly tested and changed. Also, interpreters can be very small, as evidenced by TIPI's tiny size. TIPI was written in ASIC, an excellent shareware compiler and compacted using COMPACK, a shareware file compressor. Installing TIPI TIPI is distributed as a single compressed EXE file named TIPIV1.EXE. Place this file in an empty DOS directory or onto a floppy. When you run TIPIV1 from the DOS prompt, it will extract the TIPI interpreter, various sample TIPI programs, a few utilities and the TIPI documentation. To install TIPI on a palmtop computer, you really only need TIPI.COM and whatever TIPI programs you care to run. To get the full use of TIPI, however, I suggest that you install the TIPI Programmer's Workbench, described on the next page. Also, if you have an Atari Portfolio, you will need to set the FDISK to 8 to allow TIPI to have the 120K of RAM it needs to run. See your Portfolio manual for details. page 3 Running TIPI TIPI programs are ASCII text files that are interpreted by the TIPI interpreter. All of the sample TIPI programs included in this release have the file extension .TPI The simplest way to run a tipi program is to type the word TIPI followed by the name of the tipi program. Thus TIPI HANGMAN.TPI will run the hangman program. If you want to modify a TIPI program or create a new TIPI program, you may edit the .TPI files with any ASCII text editor. A more integrated approach is to use the TIPI Programmer's Workbench. The TIPI Programmer's Workbench The TIPI Programmer's Workbench is a tiny integrated environment for TIPI development. The files that make up the workbench are: T.BAT The bat file that runs the whole show. T.TPI The TIPI menu file. TIPI.COM The TIPI interpreter. TIPI.ADR An alphabetic list of all the predefined TIPI instructions. SETAPP.COM (only needed for the Atari Portfolio) To get familiar with the workbench, start the workbench with the sample program HANGMAN.TPI. You do this by typing: T HANGMAN.TPI You will see a screen that looks like this: +----------------------------------------+ | [E]dit, [L]ookup, [R]un or [Q]uit | | | | TIPI Programmer's Workbench X | | Version 1.0 / \ | | / \ | | Current File: HANGMAN.TPI / + \ | | / + \ | | / O \ | +----------------------------------------+ Now you may press E, L, R, or Q to select on of the functions. Selecting [E]dit will let you edit the HANGMAN.TPI file. If you are using an Atari Portfolio, the workbench will use the Portfolio's editor. If you are on a PC or another palmtop, the DOS editor will be used. (Please note, if you have a preference for another editor, you can change the T.BAT file to use that editor. If you don't know how to change a bat file, give up on TIPI right now and learn the fundamentals of DOS!) page 4 TIPI programs are simple ASCII files that consists of INSTRUCTIONS separated by WHITESPACE. The TIPI instructions are described in detail later in this document. WHITESPACE characters are spaces, tabs and carriage returns For starters, it is probably best to just look at the sample programs and not change them. Once you have gotten familiar with TIPI and written some small programs of your own, you can go back and use the sample programs to give you ideas for kind of things TIPI can do. [L]ookup will let you browse through the documentation for each of the predefined TIPI instructions. On the Atari Portfolio, the Porfolio's Address Book is used as the browser. On other computers, the DOS editor is used. Again, you may edit the bat file to make the workbench use you own favorite browser. [R]un will run your program and [Q]uit will quit the workbench. page 5 TIPI Programming While many of the instructions in TIPI look very much like BASIC statements, TIPI is in fact very different than BASIC. Probably the greatest difference between TIPI and BASIC is the fact that TIPI uses a syntax known as RPN. RPN stands for Reverse Polish Notation (no, it's not an ethnic slur. It refers to the nation of origin of the mathemeticians who originated this notation.) RPN is used in many Hewlett-Packard calculators, in the display language PostScript, in some CPUs, in Forth and now in TIPI. To most people, RPN looks backwards, but RPN has many advantages. To add two plus two in BASIC and print out the result, your program would look something like this: X=2+2 PRINT X To do the same thing in TIPI, your program would look like this: 2 2 + print It may seem weird, but once you get used to RPN, it really does make things easier. For example, when you want to do more complex math, you have to use parentheses in BASIC to make sure that everything gets done in just the order you want, like this: X=(6+3)*4/3 PRINT X In TIPI you do it like this 6 3 + 4 * 3 / print ( parentheses mark comments in TIPI ) ( just like they do in English. ) RPN works by using something called a STACK. The best way to think of a stack is to think of a pile of data. TIPI has several of these stacks and the most commonly used one of these is called simply the stack or sometimes the data stack. Here is the key to TIPI programming: EVERY TIPI INSTRUCTION DOES SOMETHING TO ONE OR MORE OF TIPI'S STACKS. TO PROGRAM IN TIPI, YOU MUST KNOW WHAT THE INSTRUCTIONS DO TO THE STACKS. page 6 Let's return to our simple example to see what is going on in TIPI. Here is our "two plus two" example expanded out and explained. Once you understand this, you'll be well on your way to understanding TIPI! 2 # This places the number two on the stack. 2 # This also places a two on the the stack. + # This removes the top two numbers from the # stack, adds them together and places the # result on the stack. print # This takes the top number from the stack # and prints it out. Now is a good time to talk about program comments. Comments are program instructions that are ignored by the computer but are intended to be read by people. Even if you think you are going to be the only person ever to look at your program, it is almost always worth it to put some comments in it. In TIPI you have your choice of two types of comments. The following illustrates both comment methods. # Everything following a "pound" sign # on a line in a TIPI program is taken # to be a comment. 2 2 + ( add up two and two ) print ( and print the result ) The "#" sign tells TIPI to ignore the rest of the line and the "(" tells TIPI to ignore everything until it finds a matching ")". TIPI does all it's math in integer values. That means you can work with numbers like 6, -584, 47789329 and 0 but you can't have 3.14159 or 6.02^23. Forth purists will tell you that you don't need floating point math. I'll tell you that TIPI doesn't have it because it would make TIPI too big and too slow for what I wanted. And the Forth guys are basically right. I have seen 3-D animation engines written using only integer math and two friends of mine have coded an entire hockey game (including player physics and AI) using only integer math. The TIPI data stack and all it's math instructions work with long (32 bit) signed values. This means that TIPI can handle integers from -2,147,483,648 to 2,147,483,647. This is a very wide range and with some creative scaling, you should be able to handle almost any problem that you might have thought would require floating point math. In addition to the data stack, TIPI has a string stack and a return stack. The string stack is used to store strings and the return stack is used internally by TIPI. The return stack may also be used as a temporary place to put a number that you don't want to place on the regular data stack. See the PUSH and POP instructions for more details. page 7 Instruction Descriptions The bulk of this manual consists of descriptions of each of the hundred-odd built-in TIPI instructions. These descriptions consist of the name of the instruction, a STACK DIAGRAM which explains what the instruction does to the Data and String stacks, and a sentence or two describing what the instruction does. Here is an example: MID$ <-- This is the name of the instruction. Data ( s l -- ) <-- These are the stack String ( a$ -- b$ ) <-- diagrams Returns b$, a string of l <-- This is the description characters starting at position s from a$. What the stack diagrams do is describe what the data and string stacks look like before the instruction executes and right after the instruction executes. In these diagrams the "--" separates the "before" from the "after" and the top of the stack is the right most entry. Thus 6 2 "TIPI is not BASIC" MID$ would extract 2 characters starting at position 6 in "TIPI is not BASIC". The result would be the string "is" left on the string stack. TIPI has a wide range of instructions dealing with Math, Strings Stacks, I/O, DOS, Definitions, Data, Control, Debugging and Miscellanous functions. All of these instructions are detailed in later sections of this manual. page 8 Errors and the TIPI Debugger It would be great if we all could write perfect programs and never had programs bugs. Unfortunately, that's not the way programming works. Because programs can have bugs, TIPI has a built-in debugger. The debugger is actually a program tracer and it will help you track down bugs and give you a view of what is happening as TIPI runs your program. First off, let's run ERROR.TPI a sample program that contains (gasp) a BUG. Start the TIPI Programmer's Workbench by typing: T ERROR.TPI and pick [R]un from the menu. BAM! TIPI will display this error message: ERROR! 1 Too few stack values with + Pressing any key will show you the debugger screen, which looks like this: +- Data Depth 1 -+- String Depth 0-+ | 2| ----| | ----| ----| | ----| ----| | ----| ----| |+ | |3 = | +------------------------------------+ This is what's known in the programming biz as a "post-mortem" dump. This means that you program is dead and you can't really do anything to fix it right now. This screen is just giving you more info about what went wrong. In this case what went wrong was the program tried to add with only one value on the stack. The error message told you that, and the debugger came up to show you just what you had on the stacks. The debugger displays the data stack on the left, the string stack on the right and the instruction just executed below the data stack. Below that are the instructions it was about to execute. In a post-mortem dump, pressing any key will return you to the Workbench. Now let's use the editor to change the program to fix the bug. Here is the program: # ERROR.TPI # This simple program has a # bug in it to show you how # to use the TIPI debugger 3 + 2 = "The sum is " print$ print page 9 The problem may be fixed by changing the program to read: # ERROR.TPI # This simple program had a # bug in it to show you how # to use the TIPI debugger 3 2 + "The sum is " print$ print By moving the "+" after the 2 and getting rid of the unneeded "=" the program is fixed. Running the program again will show that all is well and our program can perform the amazing (well maybe not amazing!) feat of adding two integers. But wait, what if we wanted to see more of what's going on? You can do this by invoking the debugger at any point in your code by simply adding the instruction "TRACEON". For example, if you change our little program to look like this: # ERROR.TPI # This simple program had a # bug in it to show you how # to use the TIPI debugger traceon 3 2 + "The sum is " print$ print The debugger will be displayed from the start. You may step through the program by pressing the [SPACEBAR]. You will see each instuction execute and you can watch what it does to the stacks. By watching a program in this way, you can usually track down bugs in just a few minutes. While tracing a program, the following keys are active: [SPACEBAR] Steps to the next instruction. [ESC] Quits the debugger until another TRACEON command is executed. [END] Ends the program. In addition to TRACEON there are instructions for turning the trace window off, placing the trace window elsewhere on the screen and for tracing the contents of variables. See the section "Debugging Instructions" for more details. ` page 10 Defining New Instructions For several pages now, I've been refering to TIPI's "built-in" instructions. I use that phrase because TIPI lets you add your own instructions to the language. This is a VERY powerful concept. YOU CAN MAKE TIPI INTO WHAT YOU WANT. You can add your own features to it. Once you get the hang of this, you are playing with power. Most languages make you conform to the way the language works. With TIPI, you mold the language to the problem at hand and the way you work. The sample programs are filled with examples of ways to extend the language, but here is a simple sample: # POWERS.TPI # by Kent Peterson # This is a simple program to demonstrate # how easy it is to add new instructions # to TIPI. define square ( n -- n*n ) # Squares a number dup * enddef define cube ( n -- n*n*n ) # Cubes a number dup square * enddef define quad ( n -- n*n*n*n ) # raises a number to the fourth power square dup * enddef "Enter a number" print$ getnum dup square print cr dup cube print cr quad print cr begin key until Notice that the definition "square" is used in the definitions of "cube" and "quad". Once you define an instruction in your program, you can use it just like a built-in TIPI instruction. When your code executes, TIPI will jump back to where the new instruction was defined. If you are running the debugger, you can watch this happen. The main idea in TIPI programming is to break your problem up into little chunks and create instructions to solve the sub problems. In this way, you not only create a program to solve this particular problem, but a language that is useful for solving similar problems. page 11 Working with Stacks Because stacks are such a vital part of TIPI programming, TIPI has a wide range of instructions to manipulate the contents of the stacks. The section titled, "Stack Instructions" later in this manual details the use of these instructions. Defining and Using Variables and Tables In addition to the data and string stacks, TIPI lets you create integer variables, integer arrays and strings. To use a variable in your program you must first define it. TIPI also has a data structure called a TABLE. The proper use of variables and tables are illustrated in the program VARSAMPLE listed below. More information can be found in the manual sections describing Defining Instructions and Data Instructions. # VARSAMPLE.TPI # by Kent Peterson # This program demonstrates the three # types of variables in TIPI along with # the table data structure. defvar price 3 defarray zipcode defstr Man$ deftable kid$ # This sets the "Bart" "Lisa" "Maggie" # table kid$ to endtable # to hold the names # of three kids. 100 price store # This stores 100 in # the variable price. 10605 1 zipcode store # This stores 60609 2 zipcode store # different zipcodes 90210 3 zipcode store # in each of the # three zipcode # slots. "Homer" Man$ store # This stores the # word "Homer" in # the variable Man$. # Now let's use these variables # and the table "Hi, I'm " print$ Man$ fetch print$ # You have to fetch # the contents of # a variable before # you can print it out. "." print$ cr page 12 "My kids are named " print$ 1 kid$ print$ # Tables are initialized # when they are defined # and they auto-fetch. # DO NOT USE A FETCH # with a table. ", " print$ 2 kid$ print$ " and " print$ 3 kid$ print$ "." print$ cr cr "My car cost $" print$ price fetch print "." print$ cr cr "My zipcode is " print$ 1 zipcode fetch print # Array values # are fetched and # and stored using # their names and # their index values. " but I wish it was " print$ 3 zipcode fetch print "." print$ cr begin key until # This sequence of # instructions waits # until you press # a key. page 13 Common mistakes of new TIPI Programmers The number one mistake would have to be stack errors. Study the samples and learn RPN. IT IS WORTH IT. Your code won't be cluttered with parentheses and the instructions will flow in a logical order. The debugger will help a lot. Another common mistake is confusing the name of a variable with the contents of a variable. If you have a variable named FRED, FRED is just it's name. FRED FETCH is how you fetch a value and FRED STORE is how you store a value. Forgetting to end a DEFINE. When TIPI sees a DEFINE, it looks for the matching ENDDEF. If you don't have a match ENDDEF (or you misspell it) TIPI gets very confused. Forgetting to leave white space around TIPI instructions. The one that is most commonly screwed up is the "(". In TIPI make your comments ( Look like this. ) (Not like this.) Notes and Limits TIPI is case insensitive. This means that MAX, max and Max all refer to the same instruction. TIPI uses vectored I/O. This means that all of the I/O commands can be directed to/from files, the console, printers, etc. See the commands ISINPUT and ISOUTPUT for details. Strings are limited to a maximum of 80 characters. The maximum depths for the data and return stacks are 80. The maximum depth of the string stack is 32. The maximum number of named variables is 100. The maximum number of array elements is a total of 1000. The maximum number of trace variables is 10. The maximum number of user-defined instructions is 100. TIPI always searches it's internal dictionary first, then searches for new instructions in the order in which they were defined. An instruction must be defined before it is used. page 14 Math Instructions ABS ABS Data ( n -- abs(n) ) String ( -- ) Replaces the top value on the data stack with its absolute value. MAX MAX Data ( A B -- MAX ) String ( -- ) Places the greater of A or B on the data stack. MIN MIN Data ( A B -- MIN ) String ( -- ) Places the lesser of A or B on the data stack. MOD MOD Data ( A B -- C ) String ( -- ) Returns A modulo B. * * Data ( A B -- C ) String ( -- ) Multiplies A times B. + + Data ( A B -- C ) String ( -- ) Adds A and B. page 15 - - Data ( A B -- C ) String ( -- ) Subtracts B from A. / / Data ( A B -- C ) String ( -- ) Divides A by B. < < Data ( A B -- C ) String ( -- ) C is TRUE if A is less than B, FALSE otherwise. = = Data ( A B -- C ) String ( -- ) C is TRUE if A equals B, FALSE otherwise. > > Data ( A B -- C ) String ( -- ) C is TRUE if A is greater than B, FALSE otherwise. page 16 String Instructions ASC ASC Data ( -- N ) String ( A$ -- A$ ) Places a number N on the data stack, where N is the ASCII value of the first character of the string on the top of the string stack. CHR$ CHR$ Data ( N -- ) String ( -- M$ ) CHR$ converts an integer N from the data stack to an ASCII character and places the single character string on the top of the string stack. DATE$ DATE$ Data ( -- ) String ( -- D$ ) Places the current date on the string stack in the form "MM-DD-YYYY". INSTR INSTR Data ( -- n ) String ( a$ b$ -- a$ b$ ) Searches a$ for the first occurrence of b$. If b$ is in a$, n is the location where b$ starts in a$. If b$ is not in a$, n is zero. LCASE$ LCASE$ Data ( -- ) String ( A$ -- a$ ) Converts any uppercase characters in A$ to lower case. page 17 LEFT$ LEFT$ Data ( n -- ) String ( a$ -- l$ ) Returns a string consisting of the n leftmost characters of a$. For example, "This is a test" 7 LEFT$ would return "This is". LEN LEN Data ( -- len ) String ( a$ -- a$ ) Places the length of a$ on the data stack. LTRIM$ LTRIM$ Data ( -- ) String ( a$ -- b$ ) Trims any leading blanks from a$. MID$ MID$ Data ( s l -- ) String ( a$ -- b$ ) Returns b$, a string of l characters starting at position s from a$. PARSE$ PARSE$ Data ( -- ) String ( TEXT$ -- NEWTEXT$ WORD$ ) Parses the first word from TEXT$. REPLACE$ REPLACE$ Data ( -- ) String ( TEXT$ OLD$ NEW$ -- NEWTEXT$ ) Replaces any occurences of OLD$ in TEXT$ with NEW$. page 18 RIGHT$ RIGHT$ Data ( n -- ) String ( A$ -- B$ ) Returns a string consisting of the n rightmost characters of a$. For example, "This is a test" 6 RIGHT$ would return "a test". RTRIM$ RTRIM$ Data ( -- ) String ( A$ -- B$ ) Removes any trailing blanks from A$. STR$ STR$ Data ( N -- ) String ( -- N$ ) Converts an integer from the data stack to a string. For example, 123 STR$ would place the string "123" on the string stack. TIME$ TIME$ Data ( -- ) String ( -- T$ ) Places the current time (in the form "HH:MM:SS") on the string stack. UCASE$ UCASE$ Data ( -- ) String ( a$ -- A$ ) Converts all the characters in a string to uppercase. VAL VAL Data ( -- N ) String ( S$ -- ) Converts a string to a number. page 19 " " Data ( -- ) String ( -- ) Begins and ends a text string. +$ +$ Data ( -- ) String ( A$ B$ -- C$ ) Combines A$ and B$ into one string. =$ =$ Data ( -- C ) String ( A$ B$ -- ) C is TRUE if A$ equals B$, FALSE otherwise. page 20 Stack Instructions DEPTH DEPTH Data ( -- N ) String ( -- ) Places N on the data stack, where N is the depth of the data stack. DEPTH$ DEPTH$ Data ( -- N ) String ( -- ) Places N on the data stack, where N is the depth of the string stack. DROP DROP Data ( N -- ) String ( -- ) Removes the top value from the data stack. DROP$ DROP$ Data ( -- ) String ( A$ -- ) Removes the top value from the string stack. DUP DUP Data ( N -- N N ) String ( -- ) Duplicates the top value on the data stack. DUP$ DUP$ Data ( -- ) String ( A$ -- A$ A$ ) Duplicates the top value on the string stack. page 21 OVER OVER Data ( a b -- a b a ) String ( -- ) Copies the second item on the data stack to the top. OVER$ OVER$ Data ( -- ) String ( a$ b$ -- a$ b$ a $ ) Copies the second item on the data stack to the top. PICK PICK Data ( n -- m ) String ( -- ) Places a copy of the nth item on the top of the data stack. PICK$ PICK$ Data ( n -- ) String ( -- m$ ) Places a copy of the nth item on the top of the string stack. POP POP Data ( -- n ) String ( -- ) Pops a value off the return stack. PUSH PUSH Data ( n -- ) String ( -- ) Pushes a value to the return stack. page 22 ROT ROT Data ( A B C -- B C A ) String ( -- ) Rotates the top three values on the data stack. ROT$ ROT$ Data ( -- ) String ( a$ b$ c$ -- b$ c$ a$ ) Rotates the top three values on the string stack. SWAP SWAP Data ( A B -- B A ) String ( -- ) Swaps the top two values on the data stack. SWAP$ SWAP$ Data ( -- ) String ( A$ B$ -- B$ A$ ) Swaps the top two values on the string stack. page 23 I/O Instructions BEEP BEEP Data ( -- ) String ( -- ) Produces a short beep. CLOSE CLOSE Data ( N -- ) String ( -- ) Closes file N. N should be either a 1 or a 2. CLS CLS Data ( -- ) String ( -- ) Clears the screen and places the cursor in the upper left corner. COLOR COLOR Data ( Foreground Background -- ) String ( -- ) Sets the foreground and background colors of the screen for subsequent prints. Colors are as follows: 0 Black, 1 Blue, 2 Green, 3 Cyan, 4 Red, 5 Magenta, 6 Brown, 7 Gray, 8 Dark Gray, 9 Lt. Blue, 10 Lt. Green, 11 Lt. Cyan, 12 Lt. Red, 13 Lt. Magenta, 14 Yellow, 15 White. Notes -- 1) Background colors 8 to 15 result in blinking text. 2) The COLOR command has no effect on the Atari Portfolio. COLOR? COLOR? Data ( -- flag ) String ( -- ) Returns TRUE if a color card is detected, FALSE if a monochrome card is detected page 24 COLUMN COLUMN Data ( -- col ) String ( -- ) Places the column of the current cursor position on the data stack. CONSOLE CONSOLE Data ( -- 0 ) String ( -- ) Places the constant 0 on the data stack. The CONSOLE instruction is used for clarity. For example, the sequence CONSOLE ISINPUT is much clearer than 0 ISINPUT. CR CR Data ( -- ) String ( -- ) Sends a carriage return to the current output device. CURRENT CURRENT Data ( -- -2 ) String ( -- ) Places the constant -2 on the data stack. CURRENT is used for clarity. For example, 1 CURRENT FILEPOS is much clearer than 1 -2 FILEPOS. CURSOR CURSOR Data ( N -- ) String ( -- ) If N is zero, the cursor will be made invisible. If N is non-zero, the cursor will be made visible. WARNING! Don't execute a 1 CURSOR unless you have already executed at least one 0 CURSOR. page 25 DEFSEG DEFSEG Data ( N -- ) String ( -- ) DEFSEG is used to define the data segment used in subsequent PEEK and POKE instructions. If N is -1, the data segment will be set back to TIPI's default data segment address. EOF EOF Data ( -- -1 ) String ( -- ) Places the constant -1 on the data stack. EOF is used for clarity. For example, 1 EOF FILEPOS is much clearer than 1 -1 FILEPOS. EXTENDED EXTENDED Data ( -- n ) String ( -- ) Returns the contents of the system variable EXTENDED. This is used in conjuction with INKEY$. Extended will be 0 if a "normal" key is pressed, 1 if an "extended" key is pressed. FILEPOS FILEPOS Data ( filenum action -- loc ) String ( -- ) FILEPOS is used to position and read the value of a file pointer. The filenum is a previously opened file number (1 or 2) and the action is either EOF, CURRENT or a specific location. The number loc returned on the data stack is the location in the file where the next action will occur. EOF moves the pointer to the end of the file, CURRENT keeps it at its current position and any other number moves the pointer to that location in the file. page 26 GETBYTE GETBYTE Data ( filenum -- byte ) String ( -- ) Gets a single byte from a file whose filenumber is filenum. The file must have been previously opened and filenum must be either 1 or 2. GETNUM GETNUM Data ( -- n ) String ( -- ) Gets a number from the current input device. GET$ GET$ Data ( -- ) String ( -- string$ ) Gets a string from the current input device. INKEY$ INKEY$ Data ( -- ) String ( -- k$ ) Scans the keyboard and returns a one character string. If no key is pressed, k$ is null (""), otherwise k$ is the character whose key was pressed. If an extended key was pressed, the system variable EXTENDED is set to TRUE. ISINPUT ISINPUT Data ( n -- ) String ( -- ) Sets the current input device to n, where n is either file number 1 or 2 or the CONSOLE. The CONSOLE is device 0. page 27 ISOUTPUT ISOUTPUT Data ( n -- ) String ( -- ) Sets the current output device to n, where n is either file number 1 or 2, the PRINTER or the CONSOLE. The CONSOLE is device 0 and the PRINTER is device 3. KEY KEY Data ( -- k ) String ( -- ) Scans the keyboard and returns a keycode. If no key is pressed, k is 0. LF LF Data ( -- ) String ( -- ) Sends a line feed to the current output device. LOCATE LOCATE Data ( row col -- ) String ( -- ) Places the cursor at row, col. MOUSE MOUSE Data ( AX BX CX DX -- AX BX CX DX ) String ( -- ) Calls the low-level mouse interupt. See MOUSE.TPI for examples. Note: This instruction has no effect on the Atari Portfolio. page 28 OPEN OPEN Data ( N -- ) String ( T$ F$ -- ) Opens a file. N is the file number and N may be either a 1 or a 2. T$ is the type of open and T$ may be either "I", "O", "A" or "R" which stand for Input, Output, Append or Random respectively. F$ is the name of the file to open. PEEK PEEK Data ( Addr -- Byte ) String ( -- ) Places the contents of Addr on the stack. Addr is an address in the current segment. To change the current segment, use DEFSEG. POKE POKE Data ( Addr Byte -- ) String ( -- ) Pokes Byte into Addr. Addr is an address in the current segment. To change the current segment, use DEFSEG. PRINT PRINT Data ( n -- ) String ( -- ) Prints the number n on the current output device. PRINTCHR PRINTCHR Data ( c -- ) String ( -- ) Prints the character whose ASCII code is c on the current output device. page 29 PRINTER PRINTER Data ( -- 3 ) String ( -- ) Places the constant 3 on the data stack. The PRINTER instruction is used for clarity. For example, the sequence PRINTER ISOUTPUT is much clearer than 3 ISOUTPUT. PRINT$ PRINT$ Data ( -- ) String ( a$ -- ) Prints the string a$ on the current output device. PUTBYTE PUTBYTE Data ( B F -- ) String ( -- ) Outputs byte B to file F. ROW ROW Data ( -- row ) String ( -- ) Places the row of the current cursor position on the data stack. SOUND SOUND Data ( freq dur -- ) String ( -- ) Plays a sound of a given freq and dur. 0 is the highest freq and 32767 is the lowest. VARPTR VARPTR Data ( V -- A ) String ( -- ) Places the address of a variable onto the data stack. This may be used to PEEK and POKE values directly into a variable. page 30 DOS Instructions CALL CALL Data ( -- ) String ( program$ param$ -- ) Return ( -- ) Calls a DOS program (program$) with parameters given in param$. Sets ERROR to 255 if the call is unsuccessful. Otherwise ERROR is set to zero unless the called DOS program returns it's own error code. CHDIR CHDIR Data ( -- ) String ( dir$ -- ) Changes the current DOS directory to the one specified by the top string on the string stack. COMMAND$ COMMAND$ Data ( -- ) String ( -- Command$ ) Places a string on the string stack consisting of what followed the word TIPI on the DOS command line when TIPI was invoked. FIRSTFILE FIRSTFILE Data ( -- ) String ( filespec -- fname$ ) Finds the first file that matches filespec. Filespec follows the standard DOS wildcard rules (ie the filespec can contain "*" or "?" characters). page 31 GETDIR GETDIR Data ( num -- ) String ( -- dir$ ) GETDIR is used to get the current directory. If num = 0 then GETDIR returns the directory of the current drive. If num is 1 GETDIR uses the A drive, 2 uses the B drive, etc. The directory returned does NOT contain the drive letter or the first "\". Thus, if the current directory is the root directory, 0 GETDIR will return a null string (""). KILL KILL Data ( -- ) String ( filespec$ -- ) Kills the specified file. MAKEDIR MAKEDIR Data ( -- ) String ( dirspec$ -- ) Makes the directory specified in dirspec$. If there is an error, the system variable ERROR will be set. NEXTFILE NEXTFILE Data ( -- ) String ( -- file$ ) Returns the next file that matches the filespec set by a previous FIRSTFILE command. If there are no more files matching the filespec, the null string ("") is returned. page 32 REMDIR REMDIR Data ( -- ) String ( dir$ -- ) Removes the directory dir$. The directory should be empty before you delete it. If REMDIR fails, the system variable ERROR will be set. RENAME RENAME Data ( -- ) String ( oldname$ newname$ -- ) Renames a file. page 33 Defining Instructions DEFARRAY DEFARRAY Data ( N -- ) String ( -- ) Creates an integer array of N elements. The word after DEFARRAY is used as the name of the array. For example, 10 DEFARRAY BOB would create a 10 element array named BOB. When using STORE or FETCH with ARRAY variables, you must precede the ARRAY name with a number indicating the element to which you are refering. For example, 3 BOB FETCH will fetch the contents of the third element of BOB, while 77 5 BOB STORE will store the number 77 in the fifth element of BOB. TIPI has enough array space for a total of up to 1000 array elements in a TIPI program. TIPI also has a limit of 100 distinct named variables per program. DEFINE..ENDDEF DEFINE Data ( -- ) String ( -- ) DEFINE is used to define new TIPI instructions. The word following DEFINE is the name of the new TIPI instruction. Following this will be a sequence of TIPI instructions followed by the word ENDDEF. Once a new TIPI instruction has been defined, it may be used just like any of the built-in TIPI instuctions. For example, DEFINE SQUARED DUP * ENDDEF DEFINE CUBED DUP SQUARED * ENDDEF will create two new TIPI instructions, SQUARED and CUBED which will respectively square and cube a value on the stack. Up to 100 new TIPI instuctions may be defined in a TIPI program. ENDDEF Data ( -- ) String ( -- ) Ends an instruction definition. page 34 DEFTABLE..ENDTABLE DEFTABLE Data ( -- ) String ( -- ) Creates a new data table. The word after DEFTABLE is used as the name of the table. For example, DEFTABLE FRED will create a new table called FRED. Following the name will be a series of numbers or TIPI instructions followed by the instruction ENDTABLE. After a table has been defined, any instruction in the table may be executed by preceding the table name with the number of the instruction to execute. For example, 4 FRED would execute the fourth instruction in FRED. ENDTABLE Data ( -- ) String ( -- ) Ends a table structure. DEFSTR DEFSTR Data ( -- ) String ( -- ) Creates a new string variable. The word after DEFSTR is used as the name of the string. For example, DEFSTR MARY will create a new string variable called MARY. STORE and FETCH are used to place values into variables and retrieve them respectively. DEFVAR DEFVAR Data ( -- ) String ( -- ) Creates a new numeric variable. The word after DEFVAR is used as the name of the variable. For example, DEFVAR HERB will create a new variable called HERB. STORE and FETCH are used to place values into variables and retrieve them respectively. page 35 Data Instructions FETCH FETCH Data ( v -- x ) or String ( -- x$ ) Returns the contents of variable v. The type of v (numeric or string) determines if the contents of the fetch is placed on the data or the string stack. STORE STORE Data ( n v -- ) ( v -- ) String ( -- ) or ( s$ -- ) Stores a value into a variable. The type of v (numeric or string) determines if the contents of the store is taken from the data or the string stack. page 36 Control Instructions BEGIN..UNTIL BEGIN Data ( -- ) String ( -- ) Starts a BEGIN UNTIL loop. When TIPI encounters an UNTIL, it will branch back to the BEGIN if the value on the data stack is FALSE. UNTIL Data ( N -- ) String ( -- ) Branches back to BEGIN if N is FALSE, otherwise continues. DO..LOOP DO Data ( N -- ) String ( -- ) Begins a DO loop. Processing continues until a LOOP instruction is encountered. The loop will be executed N times. LOOP Data ( -- ) String ( -- ) Closes a DO LOOP construct. Decrements INDEX and loops back to the DO if INDEX > 0, otherwise exits the loop. INDEX INDEX Data ( -- INDEX ) String ( -- ) Copies the current DO LOOP index value to the data stack. LEAVE LEAVE Data ( -- ) String ( -- ) Sets the current INDEX value to one, thus ensuring the current DO LOOP will be ended on this itteration. page 37 CASE..OF..ENDOF..DEFAULT..ENDCASE CASE Data ( -- ) String ( -- ) Begins a CASE structure. OF Data ( m n -- ) String ( -- ) Must be used within a CASE structure. If m is equal to n, the instructions following the OF will be executed until an ENDOF is encountered. ENDOF Data ( -- ) String ( -- ) Ends an OF clause in a CASE structure. DEFAULT Data ( n -- ) String ( -- ) Used within a CASE structure to cover any cases not dealt with by previous OF clauses. ENDCASE Data ( -- ) String ( -- ) Ends a CASE structure. page 38 CASE$..OF$..ENDOF$..DEFAULT$..ENDCASE$ CASE$ Data ( -- ) String ( -- ) Begins a CASE$ structure. OF$ Data ( -- ) String ( a$ b$ -- ) Must be used within a CASE$ structure. If a$ is equal to b$, the instructions following the OF$ will be executed until an ENDOF$ is encountered. ENDOF$ Data ( -- ) String ( -- ) Ends an OF$ clause in a CASE$ structure. DEFAULT$ Data ( -- ) String ( a$ -- ) Used within a CASE$ structure to cover any cases not dealt with by previous OF$ clauses. ENDCASE$ Data ( -- ) String ( -- ) Ends a CASE$ structure. page 39 IF..ELSE..ENDIF IF Data ( n -- ) String ( -- ) If n is non-zero, statements up to the next ELSE or ENDIF will be executed. If N is zero, statements up to the next ELSE or ENDIF will be skipped. ELSE Data ( -- ) String ( -- ) Used within IF ELSE ENDIF constructs. ENDIF Data ( -- ) String ( -- ) Ends an IF ELSE ENDIF construct. WHILE..WEND WHILE Data ( N -- ) String ( -- ) If N is not equal to zero, instructions between the WHILE and WEND will be executed. WEND will branch back to the WHILE. If N is equal to zero, the instructions between the WHILE and the WEND will will be skipped. WEND Data ( -- ) String ( -- ) WEND branches back to a previous WHILE. page 40 Debugging Instructions TRACEON TRACEON Data ( -- ) String ( -- ) Turns word tracing on. When instruction tracing is on, TIPI displays an informational window showing the stacks and the instructions being executed. TRACEOFF TRACEOFF Data ( -- ) String ( -- ) Turns instruction tracing off TRACEVAR TRACEVAR Data ( var -- ) String ( -- ) Adds a var to the trace window. TRACEROW TRACEROW Data ( row -- ) String ( -- ) Sets the row that the trace window will be shown on. TRACECOL TRACECOL Data ( col -- ) String ( -- ) Sets the column that the trace window will be shown on. page 41 Miscellaneous Instructions BYE BYE Data ( n -- ) String ( -- ) Exits a TIPI program and returns to DOS. BYE returns the top value from the data stack as an error level to DOS. ERROR ERROR Data ( -- n ) String ( -- ) Places the number of the current error on the data stack. EVAL EVAL Data ( -- ? ) String ( I$ -- ? ) Evaluates the instruction I$ from the string stack. FALSE FALSE Data ( -- 0 ) String ( -- ) Places the value of FALSE (0) on the top of the data stack. NOT NOT Data ( n -- m ) String ( -- ) Negates the truth value of a flag. If n is non-zero, m is zero. If n is zero, m is one. OFF OFF Data ( -- ) String ( -- ) Shuts off an Atari Portfolio. OFF has no effect on a PC. page 42 PORT? PORT? Data ( -- flag ) String ( -- ) Returns TRUE if TIPI is running on an Atari Portfolio, FALSE otherwise. RANDOM RANDOM Data ( N -- R ) String ( -- ) Replaces N on the data stack with R, a random integer selected from the range 1 to N (inclusive). RANDOMIZE RANDOMIZE Data ( -- ) String ( -- ) Initializes the random number generator. TICKS TICKS Data ( -- t ) String ( -- ) Places the current PC tick count on the data stack. A PC ticks 18.2 times per second, while a Portfolio ticks either once every 128 seconds or once every second. TRUE TRUE Data ( -- 1 ) String ( -- ) Places the constant 1 on the top of the data stack. page 43 VERSION VERSION Data ( -- N ) String ( -- ) VERSION leaves an integer N on the data stack. N is equal to the version number times ten (ie if N is 23 then the TIPI version number is 2.3). # # Data ( -- ) String ( -- ) Identifies a comment. Anything after the # on a line is ignored. ( ( Data ( -- ) String ( -- ) Begins a comment. ) ) Data ( -- ) String ( -- ) Ends a comment.