These routines also call the VDI so change the LIBRARY statement at the start of the program to be LIBRARY "GEMAES","GEMVDI" Try running this version of the program and click on items in the Style menu after hitting a few keys. You should find that clicking on the menu items changes the text output, but that you get what can only be $dscribed as a mess. this is because the PRINT command 'knows' the width and height of the normal characters so it can print on the screen quickly. We now need to call the GEM VDI directly to output the text. Change the print_string routine to be: SUB print_string(x$) SHARED curx, cury, maxy, topx, botx, d(1) vqt_extent x$, d() IF curx+d(4)>botx THEN ' newline required curx=topx: cury=cury+maxy: maxy=0 END IF IF d(5)> maxy THEN maxy=d(5) v_gtext curx, cury, x$ curx=curx+d(4) END SUB This uses a number of variables that we haven't used before. curx and cury are used to store the current position that we are printing from. topx, topy, botx, boty give the co-ordinates of the working area of our window in the VDI form. i.e. topx, topy is the top left and botx and boty is the bottom right. (curx, cury) is the position where we are going to print text next. maxy is used to store the height of the tallest character in this line, so that we know how many pixels down to move after printing this line. d() is an array which is just used to store the distance information that is given by the vqt_extent call. It is declared in the main program to avoid it being dimensioned each time the procedure is called. to initialze most of these variables we will have a sub-program that asks the GEM AES the dimensions of the window and sets them accordingly: _______________ÿ__________________________________________________ Advanced Libraries Page 373 SUB moved_window SHARED topx, topy, botx, boty, curx, cury, maxy WINDOW GET our_window, 0, topx, topy, botx, boty botx=botx+topx+1 boty=boty+topy+1 maxy=0 curx=topx: cury=topy END SUB __________________________________________________________________ Advanced Libraries Page 374 Notice the transformation of botx and boty from AES to VDI co- ordinates. The addition of one is essential. the parameter of 0 to WINDOW GET specifies the usable area of the window. our_window is a constant equal to 2 that we are going to use to identify which window we are writing to using the HiSoft BASIC Professional WINDOW commands. we are using a constant rather than 2 explicitly so that the program is easier to modify if we wanted to make it handle more than one window at once. The code for print_string above is designed to pass the top left corner of the string to be printed to v_gtext. This is not the default, but we can use vst_alignment to change it. We also need to call the moved_window subprogram and dimension the d() array before our main DO loop at the front of the program so add the followint there: CONST our_window = 2 DIM d(9) moved_window vst_alignment 0,5 You should now run the program and find that the text will be printed in the proper style and size although it may seem a little strange because of the alignment of the text to the top left of each character position Note that the text moves to a new line but that the window does not scroll if you fill it up. Redrawing Windows In order to be able to redraw windows, if say our window changes size, we need to store enough information to redraw the whole screen. Thus the first thing to do is to design the data structures to hold the keys that have been pressed and the styles of the text. The modifications to do this are too numerous to describe here, but the design of the data structures is described below. The finished program is in the file DEMOS\AESDEMO.BAS on your master disk. __________________________________________________________________ Advanced Libraries Page 375 Our example holds the characters in an array of strings, strings$(), together with a two-dimensional array, types(), to hold the size and style corresponding to each string. The code uses the variable topstr to store the index of newest string that we are adding to. If there have been no style changes then the character is simply added to strings$(topstr). Otherwise topstr is increased by one and the appropriate element of types() is modified. The flag variable text is used to indicate if there are already some characters in this string, in which case further style changes will need a new string. There are two sorts of redraw that our program needs to perform, one is a re-draw of the entire screen, for example, when the user clicks on the program window to make it the front one. the other sort of redraw is when the program receives an AES redraw message. This occurs for example if you move the window of a desk accessory, such as the Control Panel. The AES can then supply the program with a list of rectangles that need updating. These rectangles do not take account of the size and position of our window so we need to find the intersection of the rectangles supplied with our window and only update this area. Fortunately, this is reasonably easy because there is a sub-program INTERSECTION built into the GEM AES library and we can ensure that the rectangle we require is updated using the GEM VDI vs_clip routine. This is handled by the redraw and base_redraw routines in the AESDEMO.BAS program. We hope that this example program gives you a starting point for writing your own menu and window-driven programs in HiSoft BASIC Professional. Loading and Using Resource Files Unlike most languages for the ST, HiSoft BASIC Professional will let you create menus without using a resource editor. However the easiet way to create dialog boxes or your won icons is using such a program. We recommend the HiSoft Resource Construction Set, WERCS. The following is an example of how to load the resource file that comes with the ST BASIC supplied with your machine. __________________________________________________________________ Advanced Libraries Page 376 DEFINT A-Z LIBRARY "GEMAES" REM $OPTION L8 IF FNrsrc_load("BASIC.RSC")=0 THEN PRINT "Can't load resource file": STOP END IF The REM $OPTION L8 command is used to "leave" 8k of RAM for the operating system so that it has plenty of room to load the resource file. In this resource file the object tree with index 2 is the Display BASIC line number dialog box. To find out where this has been loaded we use the FNrsrc_gaddr routine. This can then be centered on the screen using form_center. When preparing to display a dialog box it is a good idea to call the form_dial sub-program with a parameter 0. Then you draw the object tree using FNobjc_draw and let the user type and click with FNform_do. finally call form_dial with a parameter of 3; this makes the operating system send messages to update windows. __________________________________________________________________ Advanced Libraries Page 377 So a complete program to display and let the user interact with this dialog box is: DEFING A-Z LIBRARY "GEMAES" REM $OPTION L8 IF FNrsrc_load("BASIC.RSC")=0 THEN PRINT "Can't load resource file": STOP END IF junk=FNrsrc_gaddr(0, 2, form&) ' 0 for object tree ' 2 item number ' form& now contains the address of the object in memory. form_center form&, x, y, w, h ' x, y, w, h gives centered position form_dial 0,0,0,0,0,x,y,w,h a=FNobjc_draw(form&, 0, 3, x, y, w, h) a=FNform_do(form&, 2) form_dial 3, 0, 0, 0, 0, x, y, w, h PRINT a This will print out the number corresponding to the final button clicked on. The number that is entered in the dialog box is stored within the object tree. Note the use of 3 in the call to FNobjc_draw to draw 3 levels of the tree structure so that it is all printed. The 2 in the FNform_do command is number of the text object where the cursor appears initially. How do we know that this dialog box is object number 2 in the tree? It was created using a resource editor, which had the ability to write a file with constant definitions in it to give the numbers of the items. __________________________________________________________________ Advanced Libraries Page 378 The C Header File Converter HiSoft WERCS will produce .BH files for use with HiSoft BASIC Professional directly. However if you have another resource editor which produces header files of constants in the C language, we provide a tool to convert C header files to HiSoft BASIC Professional header files. the only C constructs supported are #define and comments. To run the converter program double click on CTOBAS.TTP and type the name of the C file. You can leave out the .H if you like. This will produce a file in the same directory as the source file but with an extension of .BH (for BASIC Header). The AES Constant File To make your AES programs more readable we suggest that you use the constants in the GEMAES.BH; these include most of the constants in the Digital Research documentation and the byte offsets for the data structures used for object trees. __________________________________________________________________ Advanced Libraries Page 379 __________________________________________________________________ Advanced Libraries Page 380 APPENDIX A Compiler Options __________________________________________________________________ Meta-Commands Meta_commands are special compiler commands that cause things to happen during the compilation - they do not produce instructions directly in the compiled code. Meta-commands are specified by following a REM statement (or quote ') with a dollar sign. REM $INCLUDE filename This command lets you include another BASIC source file within the current compilation, just as if it were there in the source. This can be uced for using common modules between different programs, or for breaking up larger programs into modules. REM $OPTION option_list This command lets you specify the various compiler options. Each option is denoted by a letter then, optionally, a + sign to indicate on, or a - sign to indicate off, or a number in the case of some options. Individual options should be separated by commas. For example the line REM $OPTION o+, a- turns overflow checks on and array checks off. Options contained within programs like this override any chosen at the time of compilation, via the Options dialog box. The available options are diskussed below. __________________________________________________________________ Options Page 381 Compiler Options HiSoft BASIC Professional has a large range of options that can be used to control various features in compiled programs. There are two ways these options can be specified: in the program itself, using the $OPTION meta-command; and at compile time, by clicking on the various radio buttons in the large dialog box. Array Checks (A) With array checks on all array accesses are checked to have the correct number of dimensions, and subscripts are checked to ensure they are within the range specified in the DIM statement. In addition any reference to an un-dimensioned array will dimension it. For example the program segment DIM a%(10) a%(20)=10 with checks on produce a subscript out of range error. With array checks off there are no checks at all, even on the existence of arrays. If you use an invalid subscript you are likely to destroy something else in memory, and if you try to use un-dimmed arrays you will get unpredictable results, normally bus errors (2 bombs). There is an appreciable speed improvement (though an increase in program size) with checks off, particularly with one-dimensional integer arrays, but this should only be done when your are confident your program works perfectly. destroying random areas of memory may not be immediately noticable and may manifest itself some time later in unexpected ways. If you turn array checks off then OPTION BASE 0 is forced throughout your program. Break Checks (B) This option allows a user to break out of a compiled program at certain times. With the option on Ctrl-C will abort a running program. Checks are made by the following actions: PRINT statements to the screen, regardless of the setting of pause checks; INPUT statements; and the INKEY$ function. If you want to allow the program user to break out at other times include a line such as __________________________________________________________________ Options Page 382 dummy$=INKEY$ at suitable places in your program. There is no noticable speed degradation or program size difference with this option on. Error Messages (E) This option tells the compiler to include within the compiled program a list of textual error messages to be produces after a run-time error occurs. With the option off just a number will be printed in the event of a run-time error, which can be looked up in Appendix B. When the option is on the program size is increased, but there is no speed penalty GEM Mode (G) This option forces a compiled program to be a GEM program, with all input and output occurring in a window. This will automatically happen if any graphics commands are used but it is sometimes necessary to force GEM mode. See Chapter 5 for more details of the commands that force GEM mode. Line Numbers (N) This option adds line number information into your program, which can be very useful while debugging your program. With the option on then after a run-time error the physical line number will be printed and ERL will contain the logical line number. With the option on program size is increased by 6 bytes for each non-blank line and there is a resulting degradation in program speed. Output Filename (F) When compiling to disk the compiler will normally create a file based on the name of the source file, or NONAME if the source has yet to be saved. This option allows an explicit output filename to be specified. It is recommended that no extension is specified, as the compiler will use a suitable extension based on the source code. This option has no effect if compiling to memory. Unlike other options this must be the last on a line, for example: rem $OPTION O+, FC:\TEST __________________________________________________________________ Options Page 383 Overflow Checks (O) An overflow normally occurs when a numeric value exceeds its specified range. These ranges are shown in the following table: % integer -32768 to 32767 & long -2147483648 to 2147483647 ! single -9.2E18 to +9.2E18 # double -1.8D308 o 1.8D308 For example, the statement i%=32000+10000 will produce an overflow as 42000 is too large to fit into an integer. With this option on an extra 2 bytes are used for each maths operator and some I/O operations and there is a slight speed degradation. The option should be turned off only after you are sure your program is bug free. Note with checks off the results of calculations that result in overflow are not defined. Pause Checks (P) This option allows a program's output via PRINT statements to be paused in a similar way to MS-DOS and CP/M. With the option on pressing Ctrl-S will pause output, and Ctrl-Q will resume it. This works for both TOS and GEM programs. There is no noticable speed degradation or program size difference with this option on. Return Stack Size (R) The return stack is that used for return addresses after GOSUBs, function calls and sub-program calls. It is also used for local numeric variables and by the run-time system. If it should ever run out it will hit the maths stack, which will result in various forms of crashes. The minimum is 200 bytes, and the default is 4096. If you have a heavily recursive program you may need to increase the return stack size. __________________________________________________________________ Options Page 384 Stack Checks (X) With this option on, checks are made before a RETURN statement is executed to ensure that it is sensible to do so; if not the error RETURN without GOSUB will occur. With the option off, no checks are made and a RETURN done out of context will cause unpredictable results. Underlines (U) This is an option to maintain compatibility with Microsoft BASIC. With this option on, HiSoft BASIC Professional allows underlines in variables and procedure names. With the option off, underlines can be used immediately after a reserved word or identifier, Microsoft style. See Chapter 5 for more information. Variable Checks (V) This option makes the compiler look for undeclared variables, a common source of bugs in BASIC programs. this only works for variables referenced within sub-programs or functions. For example, this program was mis-typed and with variable checks on the programmer will be alerted: SUB initialize(mem%) SHARED values%() LOCAL i% DIM values%(mem%) FOR i%=1 TO mum% ' deliberate mistake values%(i%)=i% NEXT i% END SUB Checks should be normally be on if you are compiling structured programs, but old fashioned BASIC programs should have the option off. Warnings (W) If the W+ option is specified then the warning messages normally produced by the compiler will be suppressed. __________________________________________________________________ Options Page 385 Window Defeat (Y) If the Y+ option is specified then the default window will not be produced at the beginning of a GEM program. It is then the programmer's responsibility to open window 2 before trying to output anything to it. Startup Options There are two different versions of the startup code, determined by the use of the following meta-commands: Leave (L) This allows the programmer to determine the amount of memory returned to the system at startup, the remainder being used by the running program. this option is mainly useful for GEM programs as the system memory area is used for the following things: o Resource files loaded with FNrsrc_load o Window titles and status lines o Menus created with fnMENU function o Windows opened o Desk Accessory workspace o Other programs loaded with GEMDOS pexec call o Fonts and printer drivers loaded using GDOS The default is 4k bytes, but can be made bigger or smaller as required. For example if you are loading a large resource file you will need to make it larger. The compiled program will itself use the rest of the available memory. For example rem $option L40 would leave 40k bytes free. __________________________________________________________________ Options Page 386 Keep (K) This option specifies that a program will use a particular amount of memory, the rest being returned to the system. If you try to keep more memory than there is in the machine an error message will appear during program initialisation and execution aborted. This would be useful for a menu program which in turn loads other programs, for example and has a low memory requirement itself, e.g. rem $option K10 which would keep 10k bytes, returning the rest to the system. Option Summary The following tables summarise the compiler options and the letter used to describe them, in the $OPTION meta-command. Once-only Options Array checks A Error messages E GEM Mode G Keep size K Kbytes Leave size L Kbytes Output filename F filename Return stack size R bytes Desk Accessory Keep size J Kbytes See Appendix K. Stack checks X Variable checks V window Defeat Y Changable Options Break checks B Line numbers N Overflow O Pause checks P Underlines U Warnings W __________________________________________________________________ Options Page 387 Once only options have a global effect - that is they are in effect or not for the who program. Changeable options are different because they can be turned on and off through your program, so some areas can have an option on, while others can have it turned off. Stand Alone .TTP Compiler In addition to the integrated, GEM-based version of the compiler we also supply PBASIC.TTP on disk 2. This is a stand-alone, TOS version of the compiler intended for users who have committed editor preferences, or who prefer a CLI-type of programming environment. To use from the Desktop simply double-click on it and enter a suitable command line, of the form: source_filename [options] The source_filename should be the name of the BASIC source file requiring compilation, and .BAS is assumed as an extension, but may be set explicitly to be something else. The options should be specified starting with '-' and are the same as those described previously. One important difference between this and the integrated compiler is that all options are default to off in the .TTP version. The file PBASIC.LIB should be on the same disk and in the same folder as the .TTP file. It is the same as the .LIB file on disk 1, it is included on disk 2 for convenience. For example, the command line DEMO -O, B+, FTEST will compile the file DEMO.BAS with overflow and break checks on and create the output file with the name TEST, the extension being decided by the compiler. Users of batch files may wish to use the Z option, which obviates the need to press a key after successful compilation and returns immediately (Z stands for zzzz!). __________________________________________________________________ Options Page 388 __________________________________________________________________ Options Page 389 __________________________________________________________________ Options Page 390 APPENDIX B ERROR MESSAGES __________________________________________________________________ GEMDOS Error Numbers This appendix details the GEMDOS error numbers and their meanings. The error numbers shown are those displayed from within the HiSoft BASIC Professional editor - when calling GEMDOS from your own programs these values are negative. 0 OK (no error) 32 Invalid function number 1 Fundamental error 33 File not found 2 Drive not ready 34 Path not found 3 Unknown command 35 Too many files open 4 CRC error 36 Access denied 5 Bad request 37 Invalid handle 6 Seek error 39 Insufficient memory 7 Unknown media 40 Invalid memory block address 8 Sector not found 46 Invalid drive 9 No paper 49 No more files 10 write fault 50 Disk full (not a GEMDOS error 11 Read fault - only produced by the editor) 12 General error 64 Range error 13 Write protect 65 Internal error 14 Media change 66 Invalid program load format 15 Unknown device 67 Setblock failure due to growth 16 Bad sectors on format restrictions 17 Insert other disk Run-time Errors These are errors produced by, or returned from, running compiled programs. They are listed in numeric order for easy reference when messages are not included in the compiled program and for the ERR function. On the next page they are listed in alphabetic order with explanations as to their meaning. 3 RETURN without GOSUB __________________________________________________________________ Errors Page 391 4 Out of data 5 Illegal function call 6 Overflow 7 Out of memory 9 Subscript out of range 10 Redimensioned array 11 Division by zero 13 Type mismatch 16 String formula too complex 20 RESUME without error 31 Wrong number of subscripts 50 FIELD overflow 51 Internal error 52 Bad file number 53 file not found 54 Bad file mode 57 Device I/O error 61 Disk full 62 Input past end 63 Bad record number 64 Bad file name 67 Too many files 68 Device function unavailable 70 Disk write protected 75 Path/file access error 76 Path not found 77 Break pressed 78 Fatal bus error 79 Fatal address error Run-time Errors Alphabetically Bad file mode You are trying to open a channel with an invalid mode string, or trying an input/output operation on a channel that cannot support it, e.g. PRINTing to a file opened for INPUT. Bad file name The file name is invalid, either because it is too long or because it contains invalid characters. __________________________________________________________________ Errors Page 392 Bad file number Valid channel numbers are from 1 to 255 inclusive. In addition windows use channel numbers 257 upwards. Bad record number A record number of 0 is not valid in a PUT or GET statement. Break pressed Ctrl-C was pressed during screen input or output. This error cannot be trapped by ON ERROR - if you wish Ctrl-C to be ignored then turn the break checks option off. Pressing Shift-Alt-Help when a program which was compiled to memory is running will also produce this error. Device function unavailable You are trying an operation on a device that cannot support it, such as drawing a circle on a disk file. Device I/O error A physical error has occurred during an input/output operation. Disk full Disk write protected Division by zero Fatal address error Address errors are processor exceptions caused by a memory access at an odd address, such as PEEKL(&H20011). This error is fatal and cannot be trapped. If a program is compiled to disk this error will produce 3 bombs. __________________________________________________________________ Errors Page 393 Fatal bus error Bus errors are processor exceptions caused by a memory access at an address in protected or non-existent memory. If you really want to access protected memory use the ST BASIC compatible PEEK or POKE functions. This error is fatal and cannot be trapped, and if it occurs in a program compiled to disk it will produce 2 bombs. FIELD overflow A FIELD statement has attempted to use more space than specified in the record size when OPENed, or PRINT# to a random file has filled the current record. File not found Illegal function call This error can be caused by a multitude of things and means a parameter was not in the range required by a function. The module name and line number can be used to track down the error. Input past end You have tried to read past the end of a file. Internal error This should never happen. Please report this to us together with a copy of your program. Out of data A READ has been attempted when no more DATA is available. __________________________________________________________________ Errors Page 394 Out of memory Normally this means the heap is full, which is the area of memory used for storing strings and arrays. If the error is in module MALLOC then the GEMDOS pool of memory is full. This can be increased by the use of the Keep and Leave options described in Appendix A. Overflow A result of numeric calculation is too large to fit into the required type. This can occur when you don't expect it, for example the line test!=32767+1 will produce it, as two integers are added together using integer arithmetic. The correct result can be obtained by forcing single- precision arithmetic: test!=32767!+1 Path not found An invalid path was specified in a DOS command. Path/file access error You are not permitted to do that operation with that file, such as trying to KILL a read-only file. Redimensioned array An existing array must be ERASEd before DIMmed for a second time. RESUME without error A RESUME command will only work from within an ON ERROR handler. __________________________________________________________________ Errors Page 395 RETURN without GOSUB A RETURN statement was executed but not from a section of the program which had been called with GOSUB. This error will only occur with the stack checks option turned on (see Appendix A). String formula too complex String operations use temporary descriptors for intermediate results, and it is remotely possible to run out and produce this error. Subscript out of range An array subscript used is larger than that specified in the dimensioned statement, negative, or 0 if OPTION BASE 1 is used. Too many files A maximum of 255 channels may be oppened at once from BASIC. In addition GEMDOS limits the number of simultaneous open disk files to approximately 70. Type mismatch A READ was attempted into a numeric variable but the data was found to be a string. Wrong number of subscripts An array has been referenced with a different number of dimensions to the number last DIMmed. Unlike other compilers this is a run- time error as HiSoft BASIC Professional arrays can be REDIMmed with different numbers of dimensions. Compilation Errors When the compiler detects an error or something that may be an error (a warning) it generates a message. __________________________________________________________________ Errors Page 396 The message is prefaced by the error number and followed by the line and file in which the error was detected. In the case of warnings the compiler will continue automatically. After an error it will ask you if you wish to continue. If you type n or N (for no) you will be returned to the editor. If you hit any other key compilation will continue. When you return to the editor you can use Alt-J to move to the next error with the error message displayed in the status line. If you have a large number of errors the editor may not be able to remember them all. Alt-J starts at the current position in the file; so to go the first error type Alt-T (to go to the top) and then Alt-J. If you insert or delete lines subsequently, Alt-J's will go to the wrong line. However if you have only inserted one or two lines it should be clear which is the offending line. Simply compile the program again if things get confusing. Normally the error message should be fairly obvious. the following list gives some extra hints for some of the error messages. Occasionally the compiler will spot errors somewhat later than you might expect. This is usually because the text up to the point it has read is allowed in certain contexts. If you have missed something out at the end of a line, then the error may be detected at the beginning of the next line. Note that, except in the case of missing sub-programs, line numbers or labels, the error in your program can not be after the point where the error was detected. On occasions the compiler will generate more than one error message as a result of a single error in your program; do not be put off by this. if you get confused, just re-compile. If you have a very badly formed source file, the compiler may slow down considerably. it is probably a good idea to type n to the continue prompt. Incedentally, if you start a compilation of a large program you can break out and return to the editor using the key combination Alt-Shift-Help when using the integrated compiler. It is possible that some error messages may have been added to the compiler; only if an error is generated without an error message is this possible bug in the compiler. If you do get an error number without a message, please tell us; see Appendix I __________________________________________________________________ Errors Page 397 Compiler Error Messages In the following list many of the messages give an identifier, reserved word or symbol, this is displayed instead of the % in the message. 2 ON... should be followed by GOTO/GOSUB May occur if the expression is misformed. 3 Undefined identifier % Occurs within sub-programs and functions if the V option is on. See Appendix A. 4 Unterminated string in data 5 Line number/label missing in GOTO/GOSUB % found instead This also occurs in ON GOTO/GOSUB/ERROR and RESUME statements if a line number or label is missing. 6 END DEF assumed 7 END SUB assumed Error messages 6 and 7 both occur if you attenpt to nest sub- programs or function definitions. 8 END DEF where END SUB expected 9 END SUB where END DEF expected Error messages 8 and 9 are both warnings. 10 Letter expected after DEevis e etc 11 Letter expected after - in DEeINT etc __________________________________________________________________ Errors Page 398 13 Too many ENDs/NEXTs or operand missing this error is generated in two different contexts, either when when you have too many ENDs or NEXTs or sometimes when omitting one of the operands to a dyadic operator (e.g. *) in an expression. 14 Numeric expression expected (not string) Many possible causes. 15 ) expected instead of % Many possible causes. 16 Unterminated string 17 Unexpected character in source This is a warning, the offending character will be ignored. 19 Bad line number (% is not positive) Or 0 not allowed in this context. 20 Bad line number (% is too large) 21 Bad line number (% has fraction/exponent) Or is far too large. 22 Line number % not found 23 Line number % not found __________________________________________________________________ Errors Page 399 24 Parameter (%) may not be used as FOR loop identifier Use a local variable instead. 25 Name (not %) expected in parameter list 26 Parameter % appears twice 28 ) expected at end of parameter list. % found instead Can also be caused by missing out the comma. 29 Name expected instead of % Many possible causes. 30 statement only allowed in sub-program or function These statements are LOCAL, SHARED, STATIC, EXIT DEe/SUB. 32 Label % defined twice 34 Line number/label expected instead of % Can occur if an expression is badly formed in an ON... GOTO/GOSUB. 36 Error during optimisation 39 Internal Error (bad source on pass 2) Can occasionally be generated by very badly formed source. __________________________________________________________________ Errors Page 400 40 Expression mismatch Normally caused by missing operands. 42 Expression too complex (too many operators) More than twenty operators pending. 43 Expression mismatch 44 Expression too complex More than twenty operands pending. 45 Expression syntax 46 Expression syntax Normally caused by missing out an entire expression. 49 SUB name % used in expression 50 expression mismatch: % is not a unary operator 51 Expression mismatch: No unary string minus 52 Expression mismatch 53 Illegal type combination Two strings used with arithmetic operators other than +. 54 Illegal type combination (not string) A string expression and a numberic expression have been used with an operator. __________________________________________________________________ Errors Page 401 56 Illegal type combination (not string) String could not be coerced to numeric type. 57 % is not a variable or the current function Using other function names is not allowed on the left hand side of assignments. 58 Variable is wrong type For example, if you pass a double array instead of an integer array to a sub-program. 59 Open bracket expected instead of % Many possible causes. 60 comma expected instead of % Many possible causes. Could be that an expression is mis- typed. 61 Semi-colon expected instead of % Many possible causes. 62 Extra characters at end of statement % is first Perhaps you didn't expect the statement to be over so soon. Check your expressions. 63 END DEe assumed at the end of program 64 END SUB assumed at the end of program 65 Code generation failed __________________________________________________________________ Errors Page 402 67 Bad option specified 68 ( expected in CALL statement instead of % When using the CALL statement for a sub-program with parameters, you must follow the sub-program name with an open parenthesis. 69 Subroutine % not found To CALL a variable use CALL LOC. 72 = expected instead of % Many possible causes. 76 LINE must be followed by INPUT not % To plot a line use the LINEF statement. 78 FOR variables must be simple variables (not % which is an array) 79 FOR variable % can't be a string 80 TO not % expected in FOR statement Is your initial assignment to the FOR variable correct. 83 BASE not % expected after OPTION 84 OPTION BASE must be followed by the number 0 or 1 not % 88 % cannot start a statement 89 Extra ELSE 90 ELSEIF must be followed by THEN not % __________________________________________________________________ Errors Page 403 91 % not allowed after END 92 Mismatched NEXT should be % 93 END IF expected before here 94 END REPEAT expected before here 95 NEXT expected before here 96 END SELECT expected before here 97 WEND expected before here 98 LOOP/WEND expected before here Errors 93 to 98 may occur if you have omitted the start of the structured statement in the error line. 99 Name required after SUB or DEe. % found instead Is it a reserved word? See Appendix D. 100 Identifier % redefined In sub-program or function definition. 102 Name expected after LET (not %) 103 GOTO, THEN or end of line expected after IF expression not % 105 Unexpected END SUB or END DEe Occurs when not in a function or sub-program definition. 106 CALL missing at start of statement This is a warning. For more information see Chapter 5. __________________________________________________________________ Errors Page 404 107 Unterminated control constructs Occurs at the end of sub-programs, user-defined function and sub-programs. 108 Function or sub-program redefined in library % 109 Unknown REPEAT loop in EXIT 110 Window statement misformed 111 Semi-colon or comma expected Many possible causes. 112 REDIM APPEND of arrays of more than one dimension not allowed Occurs in OPEN, NAME and FIELD statements. Perhaps an expression is wrong. 114 CONSTants must be integers not % 115 CONST % can not be assigned to 116 - expected instead of % in graphics GET 118 % is not a label Your source is probably severely malformed. 119 ( expected instead of % in graphics GET or PUT 120 Array expected but ordinary variable % found __________________________________________________________________ Errors Page 405 121 Argument to VARPTRS must be a subroutine name not % 123 INCLUDE file % not found 125 Value parameter must not be array 126 LOCATE, SOUND or WAVE statement has too many parameters LOCATE can have at most 3 parameters and SOUND and WAVE at most 5 parameters. 127 Library must be string literal not % Have you remembered the quotation marks? 128 Cannot open library 129 Library badly formed The PBASIC.LIB file is probably corrupt. 130 Too many parameters to COLOR statement (max is 5) 131 Sub-program % not found To CALL a variable use CALL LOC. 132 GOTO expected after ON ERROR not % 134 SELECT variable must only be a simple variable not % 135 LOOP/WEND expected before here 136 PALETTE USING must be followed by array at % __________________________________________________________________ Errors Page 406 137 ON/OFF expected after STRIG __________________________________________________________________ Errors Page 407 __________________________________________________________________ Errors Page 408 APPENDIX C CONVERTING PROGRAMS __________________________________________________________________ Introduction This Appendix is intended for use by programmers whishing to convert various forms of BASIC into HiSoft BASIC Professional. It starts with general notes about all conversions, then is sub- divided into sections for particular common BASIC implementations. General Conversions Most BASICs share a certain core of the language, no matter how different they seem to be. PRIis e always does the same thing, so does INPUT and so forth. BASICs can differ by being machine specific, ANSI standard, or conforming to a certain style (MicroSoft's QuickBASIC and Borland's Turbo Basic are notable examples). Whichever BASIC you are trying to convert a program from, you will need to get the source into ASCII. Some BASICs (e.g. ST BASIC) use ASCII for their programs anyway, but most interpreters use a tokenised form that will come out as gibberish if loaded into the editor. You should save your program from your BASIC interpreter using an ASCII option, if possible. Some things stand very little chance of being the same from one BASIC to another, in particular internal floating point representations and random-access file formats. One thing to be aware of particularly is that string length limitations found in other BASICs do not exist in HiSoft BASIC Professional. In particular the LEN function can return a long integer as a result, not just an integer as in other BASICs. __________________________________________________________________ Converting Page 409 Atari ST BASIC ST BASIC is supplied free with the machine and we have endeavoured to be as compatible as we can with it, even to the extent of emulating one of the bugs! One major difference is that double-precision numbers are fully supported in HiSoft BASIC Professional, unlike ST BASIC which pretends it has doubles but in fact only has singles internally. The limits of ST BASIC, such as strings up to 255 characters, arrays only taking a third of available memory and limited to 32k, and so, on are not relevant once the program has been compiled. The interpreter produces .BAS files in ASCII which are directly loadable by the HiSoft BASIC Professional editor. The bug we have deliberately emulated concerns the GOTOXY statement as so many existing programs rely on it. We have however not emulated the bugs in INT which, under ST BASIC, returns the same result as FIX and INKEY$ which always returns a null string. The FLOAT function in ST BASIC has absolutely no effect so we do not compile it. The CALL statement equivalent in HiSoft BASIC Professional is CALL LOC and the RESET command acts rather differently. In addition to the statements listed in the Command Reference section HiSoft BASIC Professional also supports the following functions and statements and produce the same results as ST BASIC: CONTRL, CLEARW, CLOSEW, FULLW, GB, GEMSYS, INTIN, INTOUT, OPENW, PTSIN, PTSOUT, and VDISYS. For documentation on these see your ST BASIC manual. we recommend strongly the use of the WINDOW statement and the VDI and AES libraries in preference to the ST BASIC statements. HiSoft BASIC Professional does not support the statements in the interpreter that have no meaning in a compiler environment: AUTO, BREAK, CONT, DELETE, DIR, EDIT, ERA, FLLOW, LIST, LLIST, LOAD, MERGE, NEW, OLD, QUIT, RENUM, REPLACE, SAVE, TRACE, UNBREAK, UNFOLLOW and UNTRACE. __________________________________________________________________ Converting Page 410 HiSoft BASIC Professional does not, at this time, support the following ST BASIC statements: COMMON, RESUME NEXT and WAIT. Old-Style Microsoft BASICs Micosoft BASIC is the closest thing to a world standard for the BASIC language and is the one we designed HiSoft BASIC Professional around. For this reason most versions of Microsoft BASIC should not present problems converting to HiSoft BASIC Professional. Programs written in the old-style BASICs, such as those found in Commodore 64s and under CP/M should require little or no work to convert, as long as machine-specific PEEKs and POKEs are avoided. You can also save typing by not entering the line numbers that aren't needed. Most BASIC interpreters from other vendors are at least in part based on the same principles as Microsoft so should also convert reasonably easily. New-Style Microsoft BASICs The new style of Microsoft BASIC is defined by QuickBASIC version 2 and 3 running on IBMs and compatibles. By new_style we mean support for structured programming such as sub-programs and parameter passing, CASE, REPEAT, DO etc. The main advantages of HiSoft BASIC Professional that you can exploit when converting programs from the IBM world, are the large memory and greater graphic support, in particular GEM. In addition, recursive programming techniques can be used. When converting QuickBASIC programs there are a few things which are not supported by HiSoft BASIC Professional by reason of operating system or hardware differences. Missing statements under this category are: COM, DRAW, ENVIRON$, ENVIRON, ERDEV, ERDEV$, IOCTL$, IOCTL, KEY, LINE, LOCK, ON various, PAINT, PEN, PLAY, PMAP, SHELL, UNLOCK, VARPTR$, VIEW, and WAIT __________________________________________________________________ Converting Page 411 Obviously PEEKs and POKEs are completely different, as are machine-code calling conventions. there are also slight differences in the following commands: CIRCLE, CLEAR, CLS, COLOR, FILES, LOCATE, OPEN, PCOPY, POINT, SCREEN, SOUND, STICK, and WINDOW. HiSoft BASIC Professional does not at this time support the following Microsoft BASIC statements: COMMON and RESUME NEXT In addition to this high degree of Microsoft compatibility, HiSoft BASIC Professional also compiles many of the additional features found in Borland's Turbo Basic compiler for the PC. Fast BASIC Fast BASIC has achieved a popular following on the ST, and deservedly so. It is easy to use, allows ood control over GEM and is fast (by interpreter standards anyway). Unfortunately it was not an attempt to follow the Microsoft path but instead BBC BASIC was chosen as a model. As a result there are a few non-trivial differences to the wary of when converting Fast BASIC programs to HiSoft BASIC Professional. Many AES and VDI calls have specific statements set up in Fast BASIC. These do not necessarily have the standard routine names or calling conventions (parameters passed etc.). Any program that makes use of Fast BASIC's GEM features must be changed to use the HiSoft BASIC Professional AES and VDI libraries. The same problem exists for GEMDOS, BIOS and XBIOS system. Usage of these must also be converting to use of the supplied operating system libraries and a good idea of which routine to use can be found in the Fast BASIC manual after each command description. Fast BASIC file handling is extremely ST specific. It uses the file handles returned by the operating system; these handle numbers can, for instance, be stored in variables. This form of file handling is not in the least compatible with the Microsoft style file handling system which uses channels. __________________________________________________________________ Converting Page 412 As far as general syntax is concerned, Fast BASIC doesn't deviate terribly much. The control structures are slightly different and variable type specifies use different characters. As Fast BASIC has so many reserved words it is case sensitive with respect to variable names, whereas HiSoft BASIC Professional is not, which may require KEYterations. The program FASTCONV is supplied in source form in the DEMOS folder; it is a Fast BASIC to HiSoft BASIC Professional converter. The list of words that are replaced appears early on in the program; various special cases (e.g. DEFs and various character substitutions) are dealt with later. There are few features of the converter which are important to know about: FASTCONV works only on ASCII files. Normal Fast BASIC sources are held in a tokenised format completely unintelligible to FASTCONV (or anything else apart from Fast BASIC itself). To produce an ASCII file you have to drag the icon of the source file on the Fast BASIC Desktop to the Clipboard. Then drag the Clipboard icon to the Disk Drive icon. A file selector will appear and you should enter the name of your file (the default extension for ASCII Fast BASIC files is .ASC). Be careful not to over-write your original source accedentally (i.e. the .BSC file). The .ASC file produced can be processed by FASTCONV. it is important to remember that FASTCONV cannot convert every Fast BASIC program completely. It is intended to relieve the programmer of the tedious replacement of keywords and variable type specifiers. The source of FASTCONV has been designed so that it is relatively easy to add features to the program; it also serves as an example of structured and modular BASIC programming. ST BASIC Version 2 ST BASIC 2 is approximately compatible with version 1, though the additional features of ST BASIC 2 are not directly supported by the compiler. __________________________________________________________________ Converting Page 413 The main difference as far as compiling ST BASIC 2 programs is that %s used after variable identifiers should be changed to &s as % in BASIC 2 means long-integer. There now follow notes for converting BASIC 2 specific features into HiSoft BASIC Professional. AREA The points should be put in an integer array then the VDI library routine v_fillarea used. ASK MOUSE x, y, b should be changed to x=MOUSE(0): y=MOUSE(1): b=MOUSE(2) ASK RGB reg, r, g, b should be changed to use the VDI library: vq_color reg, 0, rgb%(): r=rgb%(0): g=rgb%(1): b=rgb%(2) BIOS should be converted into BAR x1, y1, x2-x1, y2-y1 DRAW should be converted to use the VDI library routine v_pline DRAWMODE x should be converted to use the VDI library routine vswr_mode x ERR$ has no equivalent GEMDOS should be converted into a suitable GEMDOS library call. __________________________________________________________________ Converting Page 414 GSHAPE x, y, array() should be converted to PUT x, y, array LINEPAT x should be converted to use the VDI library routine vsl_type x LINEPAT 7, p should be converted to vsl_type 7: vsl_udsty p MAT AREA c, array%() should be changed to use the VDI routine v_fillarea c, array%() MAT DRAW c, array%() should be changed to use the VDI routine v_pline c, array%() MAT LINEF see MAT DRAW MAT SOUND array%() should be converted to use the XBIOS library routine junk&=FNdosound(VARPTR(array&(0)) Note that the array in BASIC 2 is denoted with % and must be converted to & in HiSoft BASIC Professional. PATTERN p, a%() should be converted to use the VDI library routine vsf_updat a%(), p RGB reg, r, g, b should be converted to use the VDI library routine vs_color reg, r, g, b __________________________________________________________________ Converting Page 415 SSHAPE x1, y1; x2, y2, array%() should be converted into GET (x1, y1) - (x2, y2), array%() though you should ensure the array you are using is of the correct size for HiSoft BASIC Professional. STATUS is normally equivalent to the return values of the function calls in HiSoft BASIC Professional library routines. XBIOS should be converted to a suitable XBIOS library routine. a=PEEK_B(x) If x is not protected memory then use a=PEEKB(x) else use DEF SEG 1: a=PEEK(x-1) a=PEEK_W(x) If x is not protected memory then use a=PEEKW(x) else use DEF SEG 0: a=PEEK(CLNG(x)) POKE_B, POKE_W, POKE_L Similar to PEEK above except use POKE equivalents. GEMSYS Replace with GEMSYS(x) where x is the number placed into GEM_CONTROL(0) in the BASIC 2 program. VDISYS Replace with VDISYS(0). __________________________________________________________________ Converting Page 416 CONTRL, PTSIN, PTSOUT, INTIN, INTOUT In BASIC 2 these are arrays and should be converted into PEEKW or POKEW statements. For example the BASIC 2 statements CONTRL(0)=11: CONTRL(1)=41: PTSIN(2)=3: x=PTSOUT(3) should be converted into POKEW CONTRL,11: POKEW CONTRL+2,42: POKEW PTSIN+4,3 x=PEEKW(PTSOUT+6) Note that the array index must be doubled before adding. GEM_ADDRIN, GEM_ADDROUT, GEM_CONTRL, GEM_GLOBAL, GEM_INTIN, GEM_INTOUT In BASIC 2 these are arrays and need to be converted into PEEKWs and POKEWs using additional long-integer variables set up like this: GEM_CONTRL&=PEEKL(GB) GEM_GLOBAL&=PEEKL(GB+4) GEM_INTIN&=PEEKL(GB+8) GEM_INTOUT&=PEEKL(GB+12) GEM_ADDRIN&=PEEKL(GB+16) GEM_ADDROUT&=PEEKL(GB+20) These can then be used in PEEKW & POKEW statements in a similar way to that described previously. __________________________________________________________________ Converting Page 417 __________________________________________________________________ Converting Page 418 APPENDIX D Reserved Words __________________________________________________________________ The following is a complete list of the reserved words in HiSoft BASIC Professional. These may not be used as sub-program or label names and not normally as variable names. See Chapter 5 for more details. ABS ACCESS AND APPEND AS ASC ATN AUTO BAR BASE BEEP BLOAD BREAK BSAVE CALL CALLS CASE CDBL CHAIN CHDIR CHR$ CINT CIRCLE CLEAR CLEARW CLNG CLOSE CLOSEW CLS COLOR COMMAND$ COMMON CONST CONTRL COS CSNG CSRLIN CVD CVI CVL CVS DATA DATE$ DECR DEF DEFDBL DEFINT DEFLNG DEFSNG DEFSTR DIM DO DRAW ELLIPSE ELSE ELSEIF END EOF EQV ERASE ERL ERR ERROR EXIT EXP FEXISTS FIELD FILES FILL FIX FOR FRE FULLW GB GEMSYS GET GOSUB GOTO GOTOXY HEX$ IF IMP INCR INKEY$ INP INPUT INPUT$ INSTR INT INTIN INTOUT KEY KILL LBOUND LCASE$ LEFT$ LEN LET LIBRARY LINE LINEF LOC LOCAL LOCATE LOF LOG LOG10 LOG2 LOOP LPOS LPRINT LSET MID$ MKD$ MKDIR MKI$ MKL$ MKS$ MOD MOUSE NAME NEXT NOT OCT$ OFF ON OPEN OPENW OPTION OR OUT OUTPUT PAINT PALLETTE PCIRCLE PCOPY PEEK PEEKB PEEKL PEEKW PELLIPSE PLAY POINT POKE POKEB POKEL POKEW POS PRESET PRINT PSET PTSIN PTSOUT PUT RANDOM RANDOMIZE READ REDIM REM REMAINDER REPEAT RESET RESTORE RESUME RETURN RIGHT$ RMDIR RND RSET RUN SADD SCREEN SCROLL SEG SELECT SGN SHARED SIN SOUND SPACE$ SPC SQR STATIC STEP STICK STOP STR$ STRIG STRING$ SUB SWAP SYSTAB SYSTEM TAB TAN TANH THEN TIME$ TIMER TO TROFF TRON UBOUND UCASE$ UNTIL USING VAL VARPTR VARPTRS VDISYS __________________________________________________________________ Reserved Words Page 419 WAIT WAVE WEND WHILE WIDTH WINDOW WRITE XOR __________________________________________________________________ Reserved Words Page 420 Notes __________________________________________________________________ Reserved Words Page 421 Notes __________________________________________________________________ Reserved Words Page 422 APPENDIX E Assembly Language Details __________________________________________________________________ This Appendix is intended for assembly-language programmers and details the memory maps and register usage of compiled programs; the creation of user libraries is also included here. If the previous sentence didn't make any sense then stop reading this Appendix now. Code Generation A BASIC source program is converted into true machine-code, there are no P-codes or interpretive run-times. The code produced distinguishes between program area and data area. Program area is what is written to the disk or to memory and is position dependent, relocated either by the GEMDOS loader in the case of disk files or the code generator itself with programs compiled directly to memory. All program code executes in user mode and is compatible with 68010, 68020 and 68030 processors. Figure E-1 on page E-3 shows the overall memory map of a compiled program. Note the gap between the program itself, held in the Text segment, and the data area, held in the BSS segment. When a program is run from disk these areas are continuous, but when run from memory using the editor or when in ROM they are not. Register Usage Several registers are committed to special purposes within a compiled program. These are: __________________________________________________________________ Assembly Language Page 423 A3 - Library Pointer In order to minimise the space and time taken for run-time lobrary calls, register A3 is dedicated to point to the run-time library, with a $8000 offset to allow a maximum of 64k for the whole library. Library calls from within the compiled code are of the form JSR -offset(A3) Library calls from within the library itself do not use A3, they use BSR statements and are resolved by the code generator during compilation. A4 - Local Variable Stack Frame At the very beginning of functions and sub programs a LINK instruction is done to allocate space on the stack for local variables (and function results) and to establish a register that can be used for accessing parameters. Only space for numeric variables are immediately allocated using LINK; arrays and string descriptors are allocated afterwards using a library call. For example a sub-program which has one local integer variable starts with the instruction LINK #-2,A4 Functions and sub programs finish with a corresponding UNLK A4 RTS A5 - Data Area Pointer the startup code of a compiled program sets up A5 to point to the data area of the program which of course is always RAM. At the start of the area are the run-time globals, followed by the descriptor table (descriptors are described later). Next is the global variable area, used for storing numeric variables. There is a 32k limit on the total size of these globals, but it would take a massive unstructured BASIC program to require such a number of globals. __________________________________________________________________ Assembly Language Page 424 A6 - Maths Stack This is a special stack used for storing intermediate results of numeric calculations. A7 - Machine Stack The regular machine stack used for return addresses and local variables (using A4). __________________________________________________________________ Assembly Language Page 425 Text Segment +-------------------------------+ ^ | | | | | | | Compiled Program | | No size limit | | | | | | A3-$8000---> +-------------------------------+ X | | | | Run-time Library | | 64k limit | | | +-------------------------------+ v BSS Segment A5---------> +-------------------------------+ ^ ^ | Run-time Globals | | S| +-------------------------------+ | i| | Descriptor Table | | z| +-------------------------------+ | 32k limit e| | | | |$ | Global Variables | | d|o | | | e|p +-------------------------------+ v t|t | Maths Stack | e|i +-------------------------------+ r|o | Machine Stack | m|n +-------------------------------+ i| | | n|K | | e| | | d| | The Heap | | | | b| | | y| | | | +-------------------------------+ X | System Memory | $option L size | +-------------------------------+ v Figure E-1 Compiled Program Memory Map __________________________________________________________________ Assembly Language Page 426 Startup Options There are three different versions of the startup code, determined by the use of the REM $option L, REM $option K and REM $option J metacommands as described in Appendix A. Note that both non-Desk Accessory versions of the GEM startup code check for the presence of GDOS and, if found, attempt to open a virtual workstation to the screen according to GDOS rules, allowing use of multiple fonts and devices if required. Low Level Debugging It is possible to debug compiled programs at the machine language level using a debugger such as MonST, supplied with DevpacST. If you do this it is strongly recommended that you use the Symbolic Debug option when compiling, so that run-time labels will be included in the binary file in the standard DR format. Finding Your Way It can be tricky finding your way around a compiled program and it is recommended that you also specify the Line Numbers option when compiling. This option adds instructions of the form MOVE.L #$AAAABBBB,(A5) to the program. The hex number AAAA is the physical line number i.e. the line number displayed by the editor, while the hex number BBBB is the last actual line number given in the source. These can be very useful for both finding particular lines and working out where you are in the program. If the BASIC program has the TRON statement anywhere in it then line numbers are coded using the sequence TRAP #4 DC.L $AAAABBBB __________________________________________________________________ Assembly Language Page 427 The first instruction in a compiled program is always a MOVE.L instruction setting up A3, followed by a jump around any DATA statements. Various registers are then set up before a library call to one of the startup routines. The startup routine itself should not be single-stepped, but skipped over. Most JSRs can be skipped over, but there is one notable exception to this: str_constant. Immediately following it is a string literal and you should not try skipping over the instruction (using Ctrl-T in MonST) but single-step the call, then skip over the calls it makes. Alternatively you can set a breakpoint later on in the code after the string in memory. Note that functions and procedure labels bear no similarity at all to the names used in your BASIC program. You should use the .SYM file produced by the compiler to get the 'magic' function and sub program numbers, and these will correspond to those labels starting SUB_ in the symbolic information within the file. If you have MonST version 2 or later you can use the MONBAS compilation option to specify longer run-time routine labels and the library calls will be shown symbolically once you have executed the first instruction that sets register A3. Note that you may see NOP instructions within the compiled code; don't be alarmed. These are produced by the code generator because on its first pass it leaves room for a JMP absolute instruction when program flow changes, but on pass 2 it notices that the destination is within range for a four byte BRA, so it has to add the NOP (it does not optimise to BRA.S as these take the same time to execute). As the NOPs never get executed there is no speed penalty, but there is a size increase. This is worthwhile; the rusult is that there are no size limits on compiled programs. __________________________________________________________________ Assembly Language Page 428 The Heap and Descriptors Crucial to the operation of HiSoft BASIC Professional compiled programs is the area of memory known as the heap. BASIC is one of two common languages (the other is LISP) that requires dynamic garbage collecion. Owing to the way strings in the language work it is necessary to allocate memory for them as required, then, when it runs out, to re-use all the memory no longer needed. This re-allocation is known as garbage collection. Many compilers and even some interpreters do not garbage collect and, as a result, certain operations can cause out-of-memory errors even though there is a lot of unused memory left. HiSoft BASIC Professional has a very advanced memory management system (which is hedden from the user normally) whereby any memory allocation request can cause a garbage collect to occur in order to satisfy the request. The heap itself is a large block of memory from which allocations for string variables and arrays take their memory. At the bottom of the heap (low memory) are all the string variables, while at the top are all the arrays. strings work their way upwards, while arrays grow downwards. Should they ever meet, a garbage collect occurs which deletes all unused strings and moves existing ones around as required. It is important to note that arrays never move in memory as a result of a garbage collect; an array can only move when you REDIM or ERASE any other array. As items on the heap are liable, without warning, to move about, ordinary pointers are useless. For this reason strings and arrays are accessed via descriptors, which exist normally in the global area and which themselves contain actual pointers to the data on the heap. As the memory manager knows where all the descriptors are it can update their pointers when a garbage collect occurs. Incidentally, the garbage collect itself is very fast; for example it can compact around 350k of fragmented heap in under 2 seconds, so there is never any noticeagle delay in the running of a program should it have to garbage collect. __________________________________________________________________ Assembly Language Page 429 Memory Formats Single-precision Floating Point These use the Motorola Fast Floating Point (FFP) format. The format is unusual by most standards, but was designed solely with the 68000 architecture in mind, and is as a result very fast. It is the same ormat as used by the ST BASIC, so random access files created with the interpreter should be directly usable within the compiler. 31 8 7 6 0 +-------------------------+-+-----------------+ | Mantissa |S| Exponent | +-------------------------+-+-----------------+ Figure E-2 Single Precision The sign bit is 0 for positive numbers and 1 for negative numbers. The mantissa has an implied binary point at bit 32 and thus ranges in value from 0.5 to <1.0. The exponent is held in excess - 64. The number zero is represented with 32 bits of zero. Double-precision Floating Point These use the IEEE format double-precision floats, each occupying 8 bytes, i.e. two longs. Doubles are actually stored in variables in reverse-long order due to the way the MOVEM instruction works. 63 62 52 51 0 +-+--------------+---------------------------------+ |S| Exponent | Mantissa | +-+--------------+---------------------------------+ Figure E-3 Double Precision Format The sign bit is 0 for positive numbers and 1 for negative numbers. The mantissa has an assumed bit of 1; if present it would be at bit 52. The exponent is held in excess-1023. The number zero is represented with 64 bits of zero. __________________________________________________________________ Assembly Language Page 430 Libraries Although this version of BASIC has many powerful features and extensions, occasionally there is a connamd or function that is not part of standard BASIC. Additionally, a specific task can be very time critical and need all the speed it can get. for these reasons, HiSoft BASIC Professional has the ability to incorporate assembly language subroutines in the form of libraries. A library is a collection of one or more assembler routines; the exact format of libraries is diskussed below. When a library is finished, it is added to PBASIC.LIB using the BUILDLIB program supplied. From there on, your assembly routine can be accessed directly from BASIC by name. How to write a Library A library source does not look much different from that of an ordinary assembly language program. There are several additions which are necessary so that the compiler knows what a routine is called, how many parameters of which type are required and if it is a function or subprogram. In the LIBS folder on disk 2 there is a file called LIBDEMO.S. This is an example of the format to use when writing a library. Study this example carefully before writing your own libraries. DevpacST, version 1.2 and higher, is required to write libraries. You must specify OPT L+, C+ to produce a linkable file with case sensitive labels, or re-install GenST to make this the default. A library's source code must conform to a defined format in order for BUILDLIB to be able to incorporate your library into PBASIC.LIB. Failure to conform will not normally be noticed by the assembler but will be reported, sometimes esoterically, by BUILDLIB. The beginning of every library source has to have the definitions of the routines it contains. The definition commands are defined as macros in the header file LIBRARY.H. This file should be INCLUDEd into the source. __________________________________________________________________ Assembley Language Page 431 INCLUDE LIBRARY.H This imports various constants and all the required maco definitions. After this you should define the name of your library; this is the name by which the library will be known to BASIC and need not be the same as its filename. The case of the name is irrelevant e.g. library STUFF Following this, the external references must be specified, e.g. XREF get_string XREF get_array XREF make_string XREF.L gl_scratch These external references are the routines in the BASIC runtime system that your library must call to access arrays and strings and to return strings; note that they are case-sensitive. Constants to be indexed off register A5 are imported using XREF.L. The names of the routines in your library must follow the external references as external definitions so that BUILDLIB and the compiler can reference them, e.g. XDEF setbit XDEF getbit XDEF straint XDEF baint XDEF nullterm When referring to these from BASIC, the case of the names is not important. It is however vitally important to remember the sequence in which you specified the names of your routines. The nex lines define the type of routine (subprogram or function), what types of parameters it takes and how many of them, and what type of value is returned (if any). subdef int, vlng setbit fn_int int, lng getbit subdef str, aint, lng straint subdef aint, aint, lng baint subdef vstr nullterm __________________________________________________________________ Assembly Language Page 432 The reason it is so vital that you remember the sequence of the XDEFs is because the routine definitions have to be in exactly the same order and there must be the same number. We have created a simple macro-language to cope with the many types of routines and parameters. Type Meaning subdef This specifies a subprogram, i.e. not a function. fn_int This specifies a function that returns a 16-bit signed integer. fn_lng This specifies a function that returns a 32-bit signed integer. fn_sng This specifies a function that returns a single- precision floating-point number in the Motorola FFP format. fn_dbl This specifies a function that returns a double- precision floating point number in the IEEE format. There are 15 different types of parameters that can be passed to an assembly language routine. They are: Type Meaning int a 16-bit signed integer value lng a 32-bit signed long integer value sng a 32-bit FFP single-precision value dbl a 64-bit IEEE double-precision value str a string value aint an array of ints alng an array of lngs asng an array of sngs adbl an array of dbls astr an array of strings __________________________________________________________________ Assembly Language Page 433 vint an int-variable vlng a lng-variable vsng a sng-variable vdbl a dbl-variable vstr a string-variable The first 5 types pass values directly while the last five pass pointers to variables like VAR parameters in Pascal. It is possible to pass a variable as a value parameter; it is not possible to pass a value parameter as a variable parameter. There is also a library command called option. This has the same effect as REM $OPTION in BASIC and takes the option letters as a parameter. option 'UV' lets labels containing underscores be valid and forces variable checks. option macro calls must occur after all sub and fns have been exported, and before libstart. When all of the routine definitions are finished, you must tell BUILDLIB that your code follows. You do this by specifying: libstart The Actual Code After libstart, your code follows. There are two restrictions on the code you write for libraries: o It must be completely position-independent. If you have GenST version 2, you can specify OPT P+ to force checks for position independent code. o Imported runtimes and globals cannot be referenced as part of expressions, so for example clr.b gl_scratch+10(a5) is not allowed. GenST prior to version 2 doesn't allow this anyway. A library routine must preserve registers A3-A6. Register A5 must be its normal value when any runtime routines are called. __________________________________________________________________ Assembly Language Page 434 Parameters are passed to the library routines via the stack in reverse order. Value parameters can be found directly on the stack, variable parameters are passed as pointers. Arrays and strings are passed to the library in the form of descriptors. For example, if vlng, aint, int are passed to a outine, they will appear in reverse order on the stack; it would look like this: Where Item (SP).L the return address 4(SP).W the INT value 6(SP).L the array descriptor 10(SP).L the pointer to the long integer variable The int's value can be used directly: MOVE.W 4(SP).D3 To get at the long variable is easy as well: MOVE.L 10(SP),A0 the pointer MOVE.L (A0),D0 the actual value and when you are ready to place the long back from D0 provided you have not altered A0, then MOVE.L D0,(A0) will do just that. Accessing arrays and strings is a bit more difficult. There are three subroutines in the BASIC runtimes provided just for this purpose: get_array, get_string, and make_string. The parameters they take and the values they return are as follows: get_array takes: A0 the array descriptor D0.W the number of dimensions the passed array should have returns: A2 the address of the first element in the array D4.L the total length in bytes taken up by the array elements __________________________________________________________________ Assembly Language Page 435 registers used: DO, D4, A1, A2 get_string takes: A0 the string descriptor returns: A1 the address of the string D4.L the length of the string registers used: A0, A1, D4 make_string takes: A0 the string descriptor of a string-variable; the descriptor of a string value will have no effect if passed to make_string A1 the address of your copy of the string D4.L the length of the string to be created registers used: D0-D4, A0-A2 gl_scratch This is the only area of the runtime globals that a library may use; it is 128 bytes long. gl_scratch is referenced off register A5, defined in LIBRARY.H by a register equate as global. If your routine needs more memory, you will have to use stack space, Under no circumstance should you use any part of the heap! Don't forget that strings in HiSoft BASIC Professional can be larger than 64k, thus length parameters are always long in size. To get the aint passed in the example, you must do the following: MOVE.L 6(SP),A0 MOVEQ.L #1,DO check if it's a single * dimensional array BSR get_array A2 now contains the address of the first element of the array, D4.L contains the total length of the array. If an array has more than one dimension, the dimensions are arranged in a linear fashion. For example, Array(0,0) is the first, then comes Array(0,1) until Array(0,end), then comes Array(1,0) etc. __________________________________________________________________ Assembly Language Page 436 String and Things The next example, nullterm, shows the use of get_string, make_string, and gl_scratch. Since libraries do not support a function that returns a string, a different way is used to return strings. The example below takes a string variable, copies it into gl_scratch, null-terminates it and returns the string to the variable. nullterm MOVE.L 4(SP),A0 get the descriptor BSR get_string CMP.L #128,D4 check for size BLT.S OKSiz MOVEQ #127,D4 reduce size to fit OKSiz LEA gl_scratch(global),A0 MOVEA.L A0,A2 save address of copy MOVE.L D4,D5 save string length SUBQ.W #1,D4 subtract 1 for DBF Loop MOVE.B (A1)+,(A0)+ copy string DBF D4,Loop MOVEA.L A2,A1 get the address back MOVE.L D5,D4 get the length back CLR.B 0(A1,D4.L) null terminate string ADDQ.W #1,D4 a byte was added MOVE.L 4(SP),A0 the target descriptor BRA make_string return the string and then back to BASIC Returning values from functions When a function returns a value to BASIC, it does so by putting the value in the register named tos (which is actually register D7). this applies to fn_ints, fn_lngs, and fn_sngs. This looks like: MOVE.W D0,tos returns a short integer MOVE.L D0,tos returns 32 bits When returning a 64-bit double, the register tos2 (actually D6) is used in addition to tos. The high 32-bits (exponent, sign and some of the mantissa) go into tos, while the low 32-bits of the mantissa go into tos2. __________________________________________________________________ Assembly Language Page 437 Library Format Summary To summarize, the basic format of library source code is: opt L+, C+ linkable, case dependent include LIBRARY.H library library_name defines name XREF runtime1,runtime2 runtimes needed XREF.L global1,global2 globals needed XDEF mysub1 XDEF mysub2 a list of exports XDEF myfn3 subdef mysub1 subdef mysub2 fn_int myfn3 matched list for BASIC option 'vun' (optional) libstart your code here Your source file should be assembled to a .BIN file, then linked into the BASIC library by running BUILDLIB. Using BUILDLIB BUILDLIB is used to add user libraries to PBASIC.LIB, the compiler's library. the user library file must have the .BIN extension, as it is in linkable format. BUILDLIB is a .TTP file, i.e. it takes a command line. On this command line should be listed the names of the files to be added to PBASIC.LIB, without their .BIN extentions specified. If no filenames are given, PBASIC.LOB will consists of only the standard runtimes. BUILDLIB expects to find the HBASLIB.BIN file in the current directory; this file contains the BASIC runtimes. It creates the file PBASIC.LIB in the current directory. __________________________________________________________________ Assembly Language Page 438 To aid to tracking down any errors during the operation of BUILDLIB, you can specify the -L option on the very beginning of the command line to show a running narrative on-screen of what is happening. When the error occurs, you will know in which library the error occurred. It can be easier to find symbol errors (e.g. undefined symbol) by using LinkST (supplied with DefpacST) to link PBASIC.BIN and your library. Any executable file produced by the linker should be deleted as it is not run-able. for example, double-clicking on BUILDLIB.TTP then entering -L DEMO TEST will cause the libraries contained in DEMO.BIN and TEST.BIN to be added to the runtimes from HBASLIB.BIN in PBASIC.LIB; the -L option dumps the narrative on the screen. Note that if you run BUILDLIB from within the HiSoft BASIC Professional editor using Run Other the new library created will not be used by programs you compile until you leave the editor and re-enter it. This is because the editor reads PBASIC.LIB into memory when it starts up and won't notice if it changes it in the meantime. __________________________________________________________________ Assembly Language Page 439 __________________________________________________________________ Assembly Language Page 440 APPENDIX F Hints and Tips __________________________________________________________________ This chapter shows how you can get the most out of programs written with the HiSoft BASIC Professional compiler. It is not necessarily intended only for the advanced programmer. Using HiSoft BASIC Professional Making a more efficient program requires knowledge of the features of HiSoft BASIC Professional. The following suggestions are intended to give you a firmer understanding of what can be done; we also hope that you will use this information as the basis for a more detailed exploration of HiSoft BASIC Professional. defing a-z It is a good idea to have this line in your program, it makes the default variable type a short integer. The main benefit from using ints is speed. The source becomes more understandable when &, !, and # are used explicitly. rem $option v+ This forces variable checks on. The primary benefit of this is that you can avoid unnecessary bugs caused by undefined variables in sub-programs and functions. STATIC variables in SUBs and FNs STATIC variables retain their values when a SUB or FN is exited and re-entered. There is a speed benefit in using STATICs as opposed to LOCALs: STATICs are only allocated once, whereas LOCALs must be allocated every time a SUB or FN is invoked. If your SUB or FN is recursive then LOCAL variables must be used. __________________________________________________________________ Hints & Tips Page 441 INCR and DECR These two statements respectively increment and decrement the value of a variable by one. When used on array elements they are considerably faster than e.g. Arr(1) = Arr(1)+1. == The double-equals comparison operator has different meanings depending on the type of value compared. When comparing strings, a case-independent comparison is made. It is considerably faster than using UCASE$ or LCASE$ and then comparing, or doing something line IF fred$="A" or fred$="a" THEN... When comparing numeric values, == is used as 'almost equals'; rounding errors can thus be avoided. There is a performance degradation when using == on numeric values. ! as opposed to # When using floating point maths, it is a good idea to know exactly how much accuracy is actually necessary. Single-precision is much faster than double-precision, due to the degree of accuracy required. If you want floating point, but do not need such a high degree of precision, single-precision is the variable type to use. VARPTR, SADD and PEEKtype When using VARPTR and SADD, you must be very careful. The reason for this is quite simple: due to the dynamic heap allocation and the blindingly-fast garbage collection of HiSoft BASIC Professional, strings are prone to move around without any prior notice. This is normally completely transparent to the user, but when using these functions it becomes a factor to be reckoned with. If you are going to use them, call the functions just before accessing the variable or array. In addition the address of any array will be invalid if a REDIM or ERASE statement has been executed since VARPTR was used to find the address. __________________________________________________________________ Hints & Tips Page 442 After using these functions, a PEEK or POKE is usually inflicted upon the data at the returned address, HiSoft BASIC Professional has faster varieties of PEEK and POKE and they are type-specific. They can be used to great effect e.g. when parsing a string. Let us suppose an entire file has been loaded into a single string using INPUT$; this is quite possible because strings in HiSoft BASIC Professional are only limited by available memory. SADD is called to determine where the string is. To go through the file at high speed, all you need is to remember your place in the string and PEEKB from the location that you need. Do not use PEEKW or PEEKL because strings can be on odd boundaries and an address exception will occur if you try to read a word or long from an odd address. Profiling, SUBs and FNs, and Libraries Profiling is a powerful feature whereby a programmer can find out where a program is spending its time. This is extremely useful when the program is finished and the programmer wants to upgrade the performance of the program as much as possible. For exact details about HiSoft BASIC Professional's profiling features, please see Appendix H. Using PROFILE.TTP you can find out which lines are executed most frequently. If you use sub-programs and functions, yuou can see which of these takes up the most time as well. Not only for this reason is it a good idea to use sub-programs, functions, SELECT CASE statements, DO...LOOPs and the many other structure elements of HiSoft BASIC Professional. The more you use these elements of the language, the more readable and modular your programs are. Sub-programs that you develop for one program can conceivably be used in another program by simply inserting the SUB. If you have found a routine that is extremely time-critical, but cannot be sped up within the context of BASIC, another alternative is to re-write the routine in assembly language. This is quite easy if you know 68000 assembler. For details on how to do this, please consult Appendix E. __________________________________________________________________ Hints & Tips Page 443 If you have decided that you wish to write a routine in assembly language, make sure that you have a working algorithm in BASIC. We have found that it helps immensely if the algorithm is worked out and debugged in BASIC, and then transcribed into assembler. Using this method, bugs can be avoided that would take longer to find in assembler than in BASIC. Programs that use graphics Since the ST has three available screen resolutions, the quality of life of a graphics programmer is both enhanced and complicated. On the positive side, the most suitable resolution can be chosen. On the negative side, programs really ought to be able to run in both monochrome and color; this makes more work for the programmer. A way of coping with the different resolutions is by calculating the points on screen in relations to the resolution. If you set up the default screen to be 640X400 (monochrome), you can defice the vertical values by 2 to cope with medium resolution (640X200), and additionally defide the horizontal values by 2 for low resolution (320X200). The other method is to use the GEM VDI and AES libraries so that your program 'knows' the size of the window. Making Your Programs "No-Limits" If you have been used to programming in more primitive versions of BASIC or in Pascal or C, avoiding arbitrary restrictions on the size and type of data that your program can manipulate can be hard work. For example, having a limit on the length of names that you can type into a business application can sometimes be very annoying. Similarly avoiding limits on the lengths of files and in line lengths can save you a lot of time, if say the file in question has odd end-of-line markers that mean that your program treats the whole file as one line. The following hints should help to avoid this sort of problem: __________________________________________________________________ Hints & Tips Page 444 When reading in or adding to arrays, have code to make the array larger if need be. In general adding a few elements at a time is not a good idea because the program may start spending all its time moving arrays. Normally it is a good idea to start off an array with the size as just larger than a typical requirement, but if an array is only used occasionally then the dimension can start off small. For example, if writing a cross-reference program for HiSoft BASIC Professional programs, it would probably be a good idea to start by assuming that the number of line numbers is small (say 10) and then if the program turns out to be a horrible old- fashioned program with a line number on every line then the arrays used for holding them can be grown using REDIM APPEND at, say, 100 elements at a time. When using byte or record numbers in files or strings use long integer variables (terminated with &). This should remove automatically many 32k or 64k limits on programs that are designed with 16-bit integers in mind. __________________________________________________________________ Hints & Tips Page 445 __________________________________________________________________ Hints & Tips Page 446 APPENDIX G Bibliography __________________________________________________________________ This bibliography contains our suggestions for further reading on the subject of the ST, BASIC, and GEM. The views expressed are our own and as with all reference books there is no substitute for looking at the books in a good bookshop before making a decision. ST The Abacus/Data Becker Books The series contains detailed descriptions of almost every aspect of the ST. Although they contain inaccuracies, they are the major source of information available to the general public. Atari ST Intgernals Published by Abacus/Data Becker This book is the best documentation available for the user who is not a registered ST developer. It is not suitable for the beginner, as it describes the hardware and operating system of the ST. The major fault with this book is that the BIOS listing is out of date and it contains some considerable inaccuracies. Concise Atari 68000 Programmer's Reference by Katherine Peel Published by (in the US) MichTron An alternative to Atari ST Internals. It contains information on the ST's hardware, the operating system and GEM. its coverage of the various levels of the machine is comprehensive, though a couple of sections are very inaccurate and some features are described that simply don't exist. It is rather difficult to find one's way around as the layout is based on large numbers of tables and it lacks an index. __________________________________________________________________ Bibliography Page 447 Hitchhiker's Guide to the BIOS Published by Atari Corp. This is the standard developer's document which is supplied with the official developer's package. It documents the BIOS and XBIOS, as well as correcting errors in the DR GEMDOS document. It is well written and updated when necessary. BASIC ST BASIC Sourcebook and Tutorial Published by Atari Corp. This handbook accompanies the ST BASIC that is shipped with every ST. It details the ST specific elements of the language. Microsoft QuickBASIC 3.0 Handbook Published by Microsoft Corporation The handbook that describes version 3.0 of the Microsoft QuickBASIC compiler for the IBM. It contains details of the structured elements in the language. Turbo Basic Owner's Handbook Published by Borland International Accompanies the IBM version of Borland's Turbo Basic compiler. It contains explanations of the more structured elements in the language. GEM GEM on the Atari ST Published by Abacus/Data Becker Describes programming under GEM. It is not as complete as the DR manual and contains similar errors. __________________________________________________________________ Bibliography Page 448 GEM Programmer's Guide Volumes 1 & 2 - VDI and AES Published by Digital Research This is the definitive document on GEM but contains many errors and is geared towards the 8086 version. Regrettably it is only available to registered developers. 68000 M68000 Programmer's Reference Manual Published by Prentice-Hall This is the definitive guide to the 68000 instruction set produced by Motorola themselves. ISBN 0-13-566795-X 68000 Tricks and Traps by Mike Morton BYTE September 1986 issue By far the best article on 68000 programming we have ever seen. We wish there was a book like this. __________________________________________________________________ Bibliography Page 449 __________________________________________________________________ Bibliography Page 450 APPENDIX H Program Profiling __________________________________________________________________ Introduction Profiling is a way to find out where your program is spending its time. This is particularly useful when a program is finished and you want to improve its performance. There are two distinct steps involved in obtaining a program profile: firstly the program itself must be modified to create a file containing the required information, and run: next the profiling analysis program is run. It presents the profiling information in an easy to understand form. Creating the Profile Profiling a program is quite easy. All you must do is insert the line rem $pron where you would like profiling to start. If you want to stop profiling, at any particular line you must state: rem $proff Turning the profile off is not a necessity; on the other hand, a profile is of more value when it measures the time critical areas of a program as accurately as possible. When your program is compiled a .SYM file is created; this file contains information used by the analysis program. When your program has finished, a file containing the profile information is created on the current drive in the current directory with the extension .PRF. The format of the .PRF file is straightforward: it is ASCII and has lines of the format line_number,times_sampled __________________________________________________________________ Program Profiling Page 451 The first number is the line number in the source, the second is the number of times this line was found to be executing. If you use the $include metacommand, line_number will be the line number processed by the compiler, not necessarily the line number within an include file. Note that a comma separates the two numbers so that INPUT# can be used to access the data. Analyzing the Profile Supplied with the compiler is a utility called PROFILE.TTP. This is the analysis program for profiling data. Run PROFILE.TTP by double-clicking on it from the desktop or by selecting PROFILE.TTP from Run Other on the Program menu in the editor. The parameter passed to the program is the name of the .PRF file (without extension) you wish to analyze. A .SYM file is automatically read. The profiler will then prompt you How many lines? Enter a number n; the analyzer will show the n most frequently executed lines together with the percentage of time spent and the number of times the line was sampled, depending on the number you enter; the default (just hit [Return]) is the top 12 lines. If you have used sub-programs and/or functions, PROFILE will prompt you again: How many SUBs and FNs? Again enter a number n; this will show the top n subprograms and functions; the default is 8. Finally you will be asked: Output to: The default is the screen. You can also have the analysis data put into a text file; all you have to do is specify the name and extension of the file the information is to be written to. If the output is going to the screen, you can use Ctrl-S and Ctrl- Q to pause and continue output. __________________________________________________________________ Program Profiling Page 452 Notes __________________________________________________________________ __________________________________________________________________ Program Profiling Page 453 Notes __________________________________________________________________ __________________________________________________________________ Program Profiling Page 454 APPENDIX I Technical Support __________________________________________________________________ So that we can maintain the quality of our technical support service we are detailing how to take best advantage of it. These guidelines will make it easier for us to help you, fix bugs as they get reported and save other users from having the same problem. Technical support is available in three ways: o The Best Way We are available in the MichTron RT on GEnie. Refer to the last page of this manual for more information. o Phone Please try to call between 3pm and 5 pm (Eastern Time), though calls will be accepted at other times. Please have your serial number handy. Telephone support is available only to registered users. o Mail Send a disk with your program on it. Please put your name, address, and serial number on it. Whichever method you use please always quote your serial number (from your master disk) and the version number of the program. We reserve the right to refuse technical support if you do not supply this information. For bug reports, please run the CHECKST.PRG program supplied and quote the information given by it, as well as details of any desk accessories and auto-folder programs in use. Inaddition always quote the version number of the program (the one displayed in the window title after loading the compiler) and the serial number found on your master disk. __________________________________________________________________ Technical Support Page 455 If you think you have found a bug, try and create a small program that reproduces the problem. It is always easier for us to answer your questions if you send us a letter and, if the problem is with a particular source file, enclose a copy on disk (which we will return). Upgrades As with all our products, HiSoft BASIC Professional is undergoing continual development and, periodically, new versions become available. There normally is a small charge for upgrades, though if extensive additional documentation is supplied the charge may be higher. All users who return their registration cards will be notified of major upgrades. Suggestions We welcome any comments or suggestions about our programs and, to ensure we remember them, they should be made in writing. __________________________________________________________________ Technical Support Page 456 Notes __________________________________________________________________ __________________________________________________________________ Technical Support Page 457 Notes __________________________________________________________________ __________________________________________________________________ Technical Support Page 458 APPENDIX J The ST ASCII Table __________________________________________________________________ Here is the 9-bit ASCII representation of the ST's character set: +-------------------------------------------------------------+ | | | | | Look in your AMIGA BASIC manual for the character set | | as I cannot duplicate it here. Sorry... | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +-------------------------------------------------------------+ __________________________________________________________________ ASCII Table Page 459 __________________________________________________________________ ASCII Table Page 460 APPENDIX K Desk Accessories __________________________________________________________________ HiSoft BASIC Professional can compile programs into s special form allowing the creating of desk accessories, usually reserved for languages such as C or Pascal. Normally the creation of a GEM program in HiSoft BASIC Professional requires no explicit AES or VDI calls - if required the program automatically initializes various arrays, opens a window and diverts all PRINT and INPUT via the window. Unfortunately desk accessories are not like this - they require similar calls to those used in C or Pascal, hence the following statement: +----------------------------------------------------------------+ | | |Warning: Writing desk accessories that use screen I/O requires | |a good knowledge of the AES and the VDI, particularly events. | |If you are not confident with, e.g., the AESDEMO program, do not| |attempt to write a desk accessory. This will save both you and | |us time. | | | +----------------------------------------------------------------+ Get Ready If you wish to write a desk accessory you will need to add the file GEMACC.BIN, and remove GEMAES.BIN from your PBASIC.LIB file, as described on page E-15, using BUILDLIB. Any program wishing to be compiled to desk accessory from should have the line REM $OPTION Jxx where xx is equivalent to the Keep size in Kilobytes, diskussed on page E-4. It is used to specify the whole workspace size of the desk accessory while it runs. This will change the extension of the compiled program to .ACC. The minimum value allowed is 15k, while 20k is recommended for smaller programs. Attempting to compile to memory will produce the message program buffer full. It is generally a good idea to use a separate disk or folder containing the compiler and library for writing desk accessories. __________________________________________________________________ Desk Accessories Page 461 The source to an accessory should also specify the line LIBRARY "gemacc" The GEMACC library is very similar to GEMAES, but with FNmenu& removed and three additional routines. These are: FNmenu_register%(id%,name$) This function should be called early in the initialization of the program and registers the accessory on the Desk menu. id% is the application id, which can be found using the expression PEEKW(PEEKL(GB+4)+4) and name$ is the name that appears in the Desk menu, normally starting with two spaces and no longer than 20 characters. The result of the function is the menu item identifier, from 0 to 5, or -1 if there is no room on the menu for the name. The startup code for the accessory is quite different to that of a normal compiled .PRG file in that little initialization is done, the only AES call made is appl_init. da_before This is a sub-program that should be called immediately before an OPEN#, FILE, BLOAD or BSAVE statement is executed. da_after This is a sub-program that should be called immediately after any of the above statements. Structure of a Desk Accessory An accessory should have the structure of any event-driven GEM program, based on a main loop of evnt_multi or evnt_mesage. When the accessory is chosen from the Desk menu a message of type AC_OPEN( 40, not 30 as often documented) will be received. The message AC_CLOSE (41, not 31) will be sent either when a GEM application terminates or the screen resolution is changed from the Desktop. __________________________________________________________________ Desk Accessories Page 462 A compiled desk accessory is rather different to an ordinary program. For example an accessory can never terminate - if it does the machine will crash. Should a program stop for any reason, such as with a run-time error, the message will be printed at the bottom of the screen and a keypress awaited in the normal way, then the accessory will become effectively dead until the machine is re-booted. Restrictions Many features perhaps taken for4 granted in HiSoft BASIC Professional are unavailable to accessories - the relevant library calls must be made instead. While often making programs look more complex they can improve code reliability as they often allow better error detection without the use of the dreaded ON ERROR GOTO construct. The compiler itself cannot check the incorrect use of certain statements - this is left to the programmer. The following commands should not be used within a desk accessory: BAR, CHAIN, CIRCLE, CLS, COLOR, COMMAND$, CSRLIN, FILL, GET (graphics), GOTOXY, INPUT, LINEF, LINE INPUT, LOCATE, LPRINT, MOUSE statement & function, PALETTE, PCIRCLE, PELLIPSE, POINT, POS, PRESET, PRINT, PSET, PUT(graphics), RUN, SCREEN, STICK, STRIG, TRON, TROFF, WINDOW statements, WRITE. These commands will either produce run-time errors or crash the machine. All graphics should be done via the VDI after having opened a virtual workstation. Windows should be controlled via the AES. The built-in file handling commands will work in an accessory but will cause it to stop if any error occurs, unless ON ERROR GOTO is mused. Most can be replaced with GEMDOS library calls which will allow error detection without the overhead of ON ERROR. Commands which fall into this category are: BLOAD, BSAVE, CHDIR, CLOSE, EOF, FEXISTS, FIELD, FILES, GET#, INPUT#, INPUT$, KILL, LINE INPUT#, LOC, LOF, MKDIR, NAME, PRINT#, PUT#, RMDIR and WRITE#. The SYSTAB table is much reduced compared to the normal. The only valid fields are the version and base page enties, though the long integer at offset 20 is used internally. __________________________________________________________________ Desk Accessories Page 463 Other statements not listed above can be assumed to be allowed in an accessory. Skeleton Desk Accessory The following program illustrates what is probably the smallest useful desk accessory which displays the system free memory when clicked on from the Desk menu. REM $OPTION J20 LIBRARY "gemacc" DEFINT a-z id=PEEKW(PEEKL(GB+4)+4) mpos=FNmenu_register(id," HiSoft BASIC Professional DA") DIM message(7) REPEAT main evnt_mesag VARPTR(message(0)) result=message(0) SELECT CASE result =40 ' AC_OPEN a$="[1]["+STR$(FRE(-1))+" bytes free][ OK ]" x=FNform_alert(1,a$) =REMAINDER REM check others here as required END SELECT END REPEAT main Debugging Accessories This is a difficult task and it is recommended that the program coded is tested and debugged as an ordinary stand-alone program if at all possible, using the GEMAES library instead of GEMACC. When compiling a desk accessory all code-generating options (i.e. array checks, stack checks, line numbers and overflow checks) should be off for the final release, though can be left on while testing. Note that if an application (i.e. the main program) erroneously generates certain exceptions (or bombs) these can be picked up by a compiled desk accessory normally resulting in a system crash. If you have an auto-booting hard disk it is strongly recommended you disable this feature while debugging - if an accessory crashes during its initialization an auto-boot hard-disk will infinitely try to re-boot, unsucessfully. __________________________________________________________________ Desk Accessories Page 464 General Notes We have never seen any official documentation about desk accessories, but have lernt a few things the hard way, mainly while writing our Saved! desk accessory. The following is a list of rules, or strong suggestions, that should save you from a certain amount of problems. Workstations Normally a compiled GEM program opens a workstation during its initialization but this is not done for accessories. If you need to do VDI calls you should open a virtual workstation at the same time you open a window, and close them at similar times. Problems can occur if you leave a workstation open when a main application terminates or the screen resolution changes. Windows Windows should be created using the AES window calls, but be careful. For example when setting the title or status line of a window the AES only remembers the address of the string parameter, not the string itself. As garbage collection occurs, the string can move, so you should copy the string into an immovable area of memory and pass the address. The recommended way is to use an integer array, declared before any others, as a buffer, then POKEB each character in, ending with a zero byte. When receiving an AC_CLOSE type message any windows you owned will have been deleted for you - do not try to wind_close or wind_delete them, merely update any relevant variables to indicate the window is no more. __________________________________________________________________ Desk Accessories Page 465 Timer Events If using evnt_multi and receiving timer events take great care what actions are performed when responding to them. In particular no GEMDOS calls can be made, either directly or indirectly via the file handling or date/time routines, unless your window is at the front. The reason for this is complex, but for the curious here it is: when an application makes a GEMDOS call via the TRAP #1 handler it is possible for the AES to be called, for example if the disk is write protected an alert box appears. Timer events will be sent at this time to an accessory and if it makes a GEMDOS call itself some system memory becomes fatally corrupted and the machine normally crashes when trying to return to the main application. Terminating An accessory should never terminate using any GEMDOS calls such as pterm0, ptermres or pterm as the machine will crash. In the event of a compiled accessory finishing, either accedentally (a run-time error) or deliberately (a STOP statement) the run-time system causes an infinite evnt_mesag loop to be entered. If an exception occurs due, for example, to an address or bus error, the normal bomb handler issues a terminate trap, and this will terminate the current application. If an accessory causes this to happen from within the Desktop the machine will deliberately reset itself. __________________________________________________________________ Desk Accessories Page 466 INDEX __________________________________________________________________ .PRG 87 blitter mode 317 .TOS 87 BLOAD statement 97 .TTP 87 Block ABS function 92 Copying 49 address Deleting 49 of subprogram 286 Marking 49 of variable 284 Printing 50 Advances Arrays 84 Saving 49 address Block Commands 48 screen 311 Break Checks (B) 382 Advanced GEM Techniques 364 Break pressed 393 Advanced Library Usage 361 BSAVE statement 98 AND 71 BUILDLIB 438 APPEND 207,235 CALL 62 appl_read 339 CALL LOC statement 101 appl_write 339 CALL statement 99 Arrays 70 CALLS statement 102 Advanced 84 CASE statement 250 and Sub-programs 82 cconout 300 Local 83 cconrs 301 Array Checks (A) 382 cconws 301 ASCII Table 459 CDBL function 103 ASC function 93 CHAIN statement 104 Assembly Language 423 Changable Options 387 Atari ST BASIC 410 CHANGE_HANDLE 320 ATN function 94 Character constants 66 Auto Indenting 52 Character Set 59 AUX 208 CHDIR statement 105 Backspace key 43 CHR$ function 106 backup 7 CINT function Backups 51 CIRCLE 213 Bad file mode 392 CIRCLE statement 108 Bad file name 392 clear Bad file number 393 screen 112 Bad record number 393 CLEAR statement 109 BAR statement 95 CLNG statement 109 BEEP statement 96 CLOSE 33 Bibliography 447 CLS statement 112 Binary Constants COLOR 211 BIOS COLOR statement 113 input 169 command line 115 output 210 Command Reference 91 BIOS Library 308 COMMAND$ function 115 bioskeys 315 __________________________________________________________________ Index Page 468 COMMON SHARED statement Delete key 43 116 Deleting a block 49 Compilation Errors 396 Deleting text 44 Compiler Options 382 descriptors 429 Compiling 52 Desk Accessories 56 CON 208 Desk Accessories 461 CONST statement 117 debugging 464 Converting Programs 409 example 464 Copying a block 49 Device function unavailable 393 COS function 118 Device I/O error 393 create DevpacST 431 directory 196 dfree 304 CSNG function 119 dgetpath 306 CSRLIN function 120 Dialog Boxes 40 cursor DIM SHARED 83 set position 188 DIM statement 133 Cursor keys 42 directory cursor position 221 changing current 105 CVD 121 create 196 CVI 34, 121 delete 244 CVL 34, 121 Dir2String Example Program 363 CVS 121 Disk full 393 da_after 462 Disk write protected 393 da_before 462 DiskCopy Example Program 362 DATA statement 123 Division by zero 393 Data Types 64 Double Clicking 56 DATA. 234 Double precision numbers 65 DATE$ 125 DO....LOOP statement 135 Debugging drawing mode 325 lowlevel 427 ELLIPSE 217 Debugging Accessories 464 ELLIPSE statement 137 Decimal numbers 65 ELSE statement 164 DECR 27 end of file DECR statement 126 go to 44 DEF FN statement 127 End of line DEF SEG 215,219 delete to 44 DEF SEG statement 130 END statement 138 DEFDBL, DEFING, 131 EOF function 140 Delete EQV 71 all the text 45 ERASE 85 directory 244 ERASE statement 141 file 176 ERL 142 to end of line 44 Error Message (E) 383 ERR 142 __________________________________________________________________ Index Page 469 Error FNcconin& 300 Jump to 55 FNcconis% 301 ERROR statement 143 FNcconos% 302 evnt_mesag 341 FNcnecin% 301 evnt_mouse 340 FNcprnos% 302 evnt_timer 341 FNcprnout% 301 EXIT statement 144 FNcrawcin% 301 EXP function 146 FNcrawio% 301 Fast BASIC 412 FNcursconf% 314 Fatal address error 393 FNdcreate% 304 Fatal bus error 394 FNddelete% 304 fdatime 308 FNdgetdrv% 302 FEXISTS function 147 FNdosound& 316 fforce 306 FNdrvmap% 310 FIELD 30 FNdsetdrv% 302 FIELD overflow 394 FNdsetpath% 304 FIELD statement 148 FNevnt_button 340 File not found 394 FNevnt_dclick 342 file FNevnt_keybd 340 delete 176 FNevnt_multi 341 rename 201 FNfattrib% 306 files FNfclose% 305 attribute bits 306 FNfcreate% 304 file handling 28 FNfdelete% 305 create 207 FNfdup% 306 length of file 189 FNfgetdta& 303 open 207 FNflopfmt% 313 File Selector 45 FNfloprd% 312 File Types 87 FNflopver% 314 FILES statement 150 FNflopwr% 312 FILL statement 151 FNfopen% 305 FIX function 152 FNform_alert 347 Floating point FNform_do 346 double-precision format 430 FNform_error 348 Single-precision format 430 FNfread& 305 FNappl_find name$ 339 FNfrename% 308 FNbconin& 309 FNfseek& 305 FNbconout% 309 FNfsfirst% 307 FNbconstat% 308 FNfsnext% 308 FNbcostat% 310 FNfwrite& 305 FNblitmode% 317 fnGDOS 320 FNcauxin% 300 FNgetbpb& 310 FNcauxis% 302 FNgetrez% 311 FNcauxos% 302 FNgettime& 315 FNcauxout% 300 FNgiaccess% 316 FNgraf_handle 349 FNgraf_slidebox 349 FNgraf_watchbox 349 __________________________________________________________________ Index Page 470 fnHANDLE 320 FNwind_create 351 FNiorec& 313 FNwind_delete 353 FNkbdvbase& 317 FNwind_find 355 FNkbrate% 317 FNwind_get 353 FNkbshift% 311 FNwind_open 352 FNkeytbl& 313 FNwind_set 354 FNlogbase& 311 FNwind_update 355 FNmalloc& 306 formatted output 226 FNmediach% 310 form_center 348 fnMENU& 342 form_dial 347 FNmenu_register%(id%,name$) FOR...NEXT statement 153 462 FRE function 155 FNmfree% 306 fsel_input 351 FNmshrink% 307 fsetdta 302 FNobjc_add 344 functions 74, 127 FNobjc_change 346 names. 69 FNobjc_delete 345 User-Defined 80 FNobjc_draw 345 garbage collection 429 FNobjc_edit 346 GEM 20 FNobjc_find 345 GEM Mode (G) 383 FNobjc_offset 345 GEMACC 364 FNobjc_order 345 GEMAES FNpexec% 307 Events 340 FNphysbase& 311 File Selector 351 FNrandom& 314 Forms 346 fnRESOLUTION 320 Graphics 348 FNrsrc_free 356 Menus 342 FNrsrc_gaddr 356 Message Passing 339 FNrsrc_load 356 Objects 344 FNrsrc_saddr 357 Resource Files 356 FNrwabs% 309 Scrap Directory 351 FNscrdmp% 314 Shell Routines 358 FNscrp_read 351 Utility routine. 339 FNscrp_write 351 Windows 351 FNsetcolor% 312 GEMAES.BH 38 FNsetexc& 309 GEMAES Library 337 FNsetprt% 316 GEMDOS Error Numbers 391 FNshel_find 358 GEMDOS Error Library 300 FNshel_read 358 gemvdi 24 FNsuper& 303 GEMVDI FNsversion% 304 Attributes 325 FNtgetdate% 303 Control 320 FNtgettime 303 Drawing Primitives 323 FNtickcal% 310 Enquires 334 FNvqt_name 336 Mouse & Keyboard State FNvst_load_fonts 322 Functions 333 FNwind_calc 356 Raster Functions 332 FNwind_close 352 __________________________________________________________________ Index Page 471 GEMVDI Library 318 Help Screen 50 GenSt 431 HEX$ function 163 get_array 435 hexadecimal 163 GET statement 33 Hexadecimal Constants 65 file i/o 156 Hints and Tips 441 graphics 157 If statement 164 get_string 436 ikbdws 315 getmpb 308 Illegal function call 394 gl_scratch 436 IMP 71 GOSUB 242 INCR 27 GOSUB statement 159 INCR statement 166 GOTO 69 indenting Goto Line 43 Auto 52 GOTO statement 161 initmous 311 GOTOXY statement 162 INKEY$ function 167 graf_dragbox 348 INP function 169 graf_growbox 349 INPUT statement 170 graf_mkstate 350 INPUT# 208 graf_mouse 350 INPUT# statement 171 graf_movebox 348 INPUT$ 208 graf_rubberbox 348 INPUT$ statement 172 graf_shrinkbox 349 Input past end 394 box 95 Inserting Text 47 circle 108 INSTR function 173 colors 113 INT function 175 ellipse 137 Integers 64 fill 151 Internal error 394 filled area 323 INTERSECTION 339 filled circle 213 jdisint 315 filled ellipse 217 jenabint 315 get area 157 joystick 262, 266, 267 lines 323 Jump to Error 55 line 183 justify line style 113 left 193 markers 323 right 246 pie slice 324 KBD 208 read pixel color 218 Keep (K) 387 rounded box 325 KILL statement 176 rounded filled box 325 labels 61 text 323 LBOUND 84 Hanoi LBOUND function 177 Towers of 14 LCASE$ function 178 HBASLIB.BIN 438 Leave (L) 386 heap 429 __________________________________________________________________ Index Page 472 LEFT$ function 179 menu_ienable 344 LEN function 180 menu_text 344 LET statement 181 menu_tnormal 344 LIBRARY statement 182 Meta-Commands 381 Libraries 299, 431 mfpint 313 format summary 438 Microsoft BASIC LIBRARY statement 299 New-style 411 Limitations 87 Old-style 411 LINE INPUT statement 184 MID 208 LINE INPUT# statement 185 MID$ function 194 Line numbers 61 midi 313 Line Numbers (N) 383 midiws 313 LINEF statement 183 MKD$ 121, 197 Loading Text 47 MKDIR statement 196 LOC function 186 MKI$ 32, 121, 197 Local Arrays 83 MKL$ 32, 121, 197 LOCAL statement 187 MKS$ 121, 197 Local variables 79 MOD 71 LOCATE statement 188 mode LOF 208 of screen 249 LOF function 189 MOUSE function 198 LOG 190 MOUSE statement 200 LOG10 190 NAME statement 201 Long Integers 64 NOT 71 LOOP statement 135 Numbers 64 lower case 178 Numeric Pad 51 LPOS function 191 OCT$ function 202 LPRINT, LPRINT USING 192 Octal 202 LSET 32, 197 Octal Constants 66 LSET statement 193 offgibit 316 LST 208 Once-only Options 387 machine code ON ERROR statement 203 calling 101 ON...GOSUB statement 205 libraries 182 ON...GOTO statement 206 make_string 436 ongibit 316 Marking a block 49 OPEN 31 match OPEN statement 207 string within string 173 Operators 71 memory Operating System Overview 362 free 155 OPTION BASE 85 Memory Map 426 OPTION BASE statement 209 menu_bar 343 Option Summary 387 menu_icheck 344 OR 71 __________________________________________________________________ Index Page 473 Out of data 394 file I/O statement 230 Out of memory 395 graphics statement 231 OUT statement 210 PUT statement 32 OUTPUT 207 Quick Tour 9 Output Filename (F) 383 Quitting HiSoft BASIC Overflow 395 Professional 44 Overflow Checks (O) 384 RANDOM 207 PALETTE statement 211 random numbers 245 Parameters RANDOMIZE 245 Value 76 RANDOMIZE statement 233 Variable 75 read Path not found 395 keyboard without echo 167 Path/file access error 395 READ statement 234 Pause Checks (P) 384 README File 7 PBASIC.LIB 438 Recursion 79 PCIRCLE statement 213 REDIM 85 PCOPY statement 214 REDIM APPEND. 85 PEEK function 215 REDIM statement 235 PEEKB, PEEKL, PEEKW 216 Redimensioned array 395 PELLIPSE statement 217 Registration Card 7 POINT function 218 REM statement 236 POKE statement 219 REM $INCLUDE filename 381 POKEB, POKEL, POKEW 220 REM $OPTION option_list 381 POS function 221 Rename file 201 Preferences 51 REPEAT...END REPEAT 237 PRESET statement 222 Replacing Text 48 PRINT 296 Reserved Words 68 PRINT statement 223 RESET statement 239 PRINT USING statement 226 resolution 272 PRINT# 208, 225 RESTORE statement 240 PRINT# USING 225 RESUME statement 241 Printing a block 50 RESUME without error 395 proff 451 return code 264 Profiling 451 RETURN statement 159, 242 pron 451 Return Stack Size (R) 384 protobt 314 RETURN without GOSUB 396 PRT 208 RIGHT$ function 243 prtblk 317 RMDIR statement 244 PSET statement 229 RND function 245 pterm 307 rsconf 313 pterm0 300 RSET 197, 246 ptermres 304 rsrc_obfix 357 puntaes 317 RUN statement 247 PUT __________________________________________________________________ Index Page 474 Running Programs 54 STRIG statement 267 Run-time Errors 391 string SADD 442 address of 248 SADD function 248 STRING$ function 268 Saved! 57 Strings 64 Saving a block 49 String formula too complex 396 Saving Preferences 52 Subscript out of range 396 Saving Text 46 Sub-program 17 SCREEN statement 249 Sub-programs 62 screen and Arrays 82 address 311 subprogram screendump 214 address of 286 screen mode 311 Subprograms 74 search calling 99 within string 173 SUB...END SUB 269 Searching 48 supexec 317 SELECT...END SELECT 250 SWAP statement 271 setpalette 312 SYSTAB function 272 setscreen 312 SYSTEM statement 274 settime 315 TAB function 275 SGN function 253 Tab key 43 SHARED statement 254 Tabs 51 SHARED variables 83 TAN function 276 SHARED variables 78 Technical Support 455 shel_envrn 358 Text Buffer Size 51 shift keys 198 The Editor 39 SIN function 255 THEN statement 164 Single precision numbers 65 TIME$ function 277 SOUND statement 256 TIME$ statement 278 SOUND. 287 TIMER function 279 SPACE$ function 258 Too many files 396 SPC function 259 Towers of Hanoi 14 SQR function 260 TRON, TROFF statements 280 square root 260 tsetdate 303 ssbrk 311 tsettime time% 303 Stack Checks (X) 385 Type mismatch 396 Startup Options 386 Tutorial 13 STATIC statement 261 UBOUND 84 STATIC variables 77 UBOUND function 281 STICK function 262 UCASE$ function 282 STOP statement 264 UnDelete Line 44 STR$ function 265 Underline (U) 385 STRIG 262 User Defined Functions 80 STRIG function 266 __________________________________________________________________ Index Page 475 v_arc 324 vr_recfl 23, 324 v_bar 324 vro_cpyfm 332 v_circle 324 vrt_cpyfm 333 v_cirwk 322 vs_clip 323 v_clsvwk 322 vs_color 326 v_clswk 321 vsc_form 334 v_contourfil 324 vsf_color 331 v_ellarc 324 vsf_interior 330 v_ellipse 325 vsf_perimeter 331 v_ellpie 325 vsf_style 331 v_fillarea 323 vsf_updat 331 v_get_pixel 333 vsl_color 327 v_gtext 323 vsl_ends 327 v_hide_c 333 vsl_type 326 v_justified 325 vsl_udsty 327 v_opnvwk 322 vsl_width 327 v_opnwk 321 vsm_color 328 v_pieslice 324 vsm_height 328 v_pline 323 vsm_type 328 v_pmarker 323 vst_alignment 330 v_rbox 325 vst_color 329 v_rfbox 23, 325 vst_effects 329 v_show_c flag 333 vst_font 329 v_updwk 322 vst_height 328 VAL function 283 vst_point 329 Value Parameters 76 vst_rotation 329 variable vst_unload_fonts 323 address of 284 vswr_mode 325 Variable Checks (V) 385 vsync 317 Variable Parameters 75 Warnings (W) 385 Variables 68 WAVE statement 287 LOCAL 79 WHILE...WEND 288 SHARED 78 WIDTH statement 290 STATIC 77 Window VARPTR function 284 Usage 55 VARPTR 442 WINDOW statements 291 vq_color 335 Window Defeat (Y) 386 vq_extnd flag 334 WRITE statement 296 vq_key_s 334 WRITE# 208 vq_mouse 334 WRITE# statement 297 vqf_attributes 335 Wrong number of subscripts 396 vql_attributes 335 XBIOS Library 311 vqm_attributes 335 xbtimer 316 vqt_attributes 336 XOR (exlusive or) 71 vqt_extent text$ 336 vqt_fontinfo 337 vqt_width 336 __________________________________________________________________ Index Page 476 __________________________________________________________________ Index Page 477 Come and join us at the Roundtable, Where the GEnie and the Griffin meet! Does this sound like a fantasy? Well, it may just be a dream come true! When General Electric's high-tech communications network meets MICHTRON's programmers and support crew, ST users around the contry will hear more, know more, and save more. We know that our low prices and superior quality wouldn't mean as much to you without proper support and service to back them up. So we are available on GEnie, the General Electric Network for Information Exchange.. Genie is a computer communications system which lets you use your personal computer, modem, and communication software to gain access to the latest news, product information, electron mail, games, and MICHTRON's own Roundtable (See the special MicroDeal Section for game information)!! The Roundtable Special Interest Groups (SIG) gives you a means of conveniently obtaining news about our current products, new releases, and future plans. Messages directly from the authors give you valuable technical support of our products, and the chance to ask questions (usually answered within a single business day). GEnie differs from other computer communication networks in its incredibuly low fees. With GEnie, you don't pay any hidden charges or minimum fees. You pay only for the time you're actually on-line with the MichTron product support Roundtable, and the low first-time registration fee. For more information on GEnie, follow this simple procedure for a free trial run. Then if you like, have ready your VISA, Mastercard or checking account number and you can set up your personal account immediately -- right on-line! 1. Set your modem for half duplex (local echo)--300 or 1200 baud. 2. Dial 1-800-638-8369. When connected, type HHH and press Return. 3. At the U#= prompt, type XJM11957,GENIE and press Return. And don't forget, MICHTRON's Bulletin Board System, The Griffen BBS, is still going strong (the griffen is the halp-lion/half- eagle creature on our logo). Our system is located at MICHTRON headquarters in Pontiac, Michigan. For a trial run, call (313) 332-5452. GEnie and Roundtable are Trademarks of General Electric Information Services. __________________________________________________________________ __________________________________________________________________ __________________________________________________________________ MICHTRON 576 S. Telegraph, Pontiac, MI 48053 Orders and Information (313) 334-5700 _________________________________________________________________ _________________________________________________________________