CHAPTER 5 - LINKER
Jump to navigation
Jump to search
Well, this file concludes the majority of the tutorial on Devpac version 2. for more information, see the accompanying quick reference files also on this Sewer Doc Disk Number 8, the Devpac Disk. As usual, this file was typed by the Animal House and edited by Sewer Rat CHAPTER 5 LINKER Introduction A linker's job is to accept one or more input files generated with GenST or a high-level language compiler and create a single executable file from it. One of the most powerful features is library searching, which means that the linker will only use the parts of a library of modules that are required by other sections of the program, resulting in much smaller output files. There are unfortunately tow different linker file formats on the Atari ST, known as DRI- and GST-formats. While GenST can generate both formats, only the GST-format is supported in the LinkST linker. To link DRI code you need either the Atari ALN program or the Digital Research LINK68 and RELMOD programs. Note: LinkST will only link GST format files. Invoking the Linker The simplest way to run the linker from the Desktop is to double-click on the LINKST.TTP icon, and enter a suitable command line. There is another way to invoke the linker, using a control file which contains the required options. The command line contains the necessary information for the linker to read all the relevant files, and generate an output file. Command Line The command line should be of the form: <filename> <-options> [filename] [options] Options are denoted by a - sign then an alphabetic character, allowed options being: B generate a true BSS section for any such named sections D debug - include all symbols in the binary file using DR standard 8 character format (for MonST or other debuggers) F force pass 2 of the linker, useful if you want to see all errors (as any pass 1 errors will by default stop the link before the second pass) L specify that all following filenames are library filenames M dump a map file showing the order of the sections and labels, will be the main filename with an extension of .MAP O specify object code filename, may be followed by white space before filename Q 'quiet' mode, which disables the pause after the link S dump a symbol table listing, will be the main filename with an extension of .SYM X extended debug, using the HiSoft Extended Debug format W specify control file filename, defaults to .LINK extension Normally any filenames given are taken to be input files, defaulting to the extension of .BIN, though if a .LNK extension is specified it will be taken to be a control file, or after a -L option filenames are all assumed to be libraries. The output filename can be specified with the -o option on the command line, or using the OUTPUT directive in the control file. If there is more than one of these, the last one is used. If there is none, then the first input filename specified in the command line or control file is used with an extension of .PRG. Example Command Lines PART1 PART2 -d Reads PART1.BIN and PART2.BIN as input files, and generates PART1.PRG as an output file complete with debugging information. PART1 PART2 -o TEST.PRG Reads PART1.BIN and PART2.BIN as input files, and generates TEST.PRG as an output file. -o TEST.TOS START -1 MYLIB -s Reads START.BIN as an input file, selectively reads MYLIB.BIN as a library, and generates the output file TEST.TOS and the symbol listing file TEST.SYM. LiokST Running LinkST has tow passes - during pass 1 it builds up a symbol table of all sections and modules, and during pass 2 it actually creates the output file. When it starts a logon message, then reports on which files it is reading or scanning during both passes. This gives you some idea of what takes time to do, as well as exactly where errors have occurred. If there is enough free memory at the end of pass 1 LinkST will use a cache to store the output file, which greatly speeds up the process. If it uses the cache it will write to the disk at the end of pass 2, and report the number of errors. When the link finishes you will be prompted to press a key before quitting. This is to give you an opportunity to read any warning or error messages before returning to the Desktop. You can disable this pause by using the -q option, useful if you are using a CLI or batch file program. LinkST was especially optimised for speed, though the speed of the ST floppies is still a restricting factor. If you can't afford a hard disk we recommend the use of a RAM disk which can make great improvements, but leave enough memory free for the linker to cache your output file. If you are limited in what you can fit on your RAM disk we recommend you put many small library or input files on there. Error and warning messages are directed to the screen - if you want to pause output you can press Ctrl-S, and Ctrl-Q will resume it. Pressing Ctrl-C will abort the linker immediately. You can re-direct screen output to a disk file by starting the command line with >FILENMAE.TXT or you can re-direct it to a printer by starting the command line with >PRN: (parallel port) or >AUX: (serial port) Control Files The alternate way to run the linker is to have a control file for the programs which you are linking together. If you require a lot of options which won't fit on the command line or you get bored of typing them you can use a control file, which is a text file containing commands and filenames for the linker. The default extension is .LNK, and the text file can be generated with GenST (though don't try and assemble it!). The control filename is specified on the command line with the -w (for With) option, and each line can be one of the following: INPUT <filename> This specifies a filename to be read as an input file. The default extension is .BIN if none is given. OUTPUT <filename> This specifies the filename to be used for the output file. There is no default extension - you should specify it explicitly. LIBRARY <filename> This specifies a filename to be scanned as a library. The default extension is .BIN if none is given. SECTION <sectionname> This allows specific section ordering to be forced. DEBUG All symbol names included in the link are put in the output file so that debugging programs such as MonST can use them when the program is running. XDEBUG Similar to debug option us uses HiSoft Extended Debug format for up to 22 character significance. DATA size(K) The BSS segment size is set accordingly. The size can be given either as a number of bytes of as a number of K-bytes (units of 1024). This option is particularly useful for compilers like Prospero Pascal which store their variables in the BSS segment. Blank lines in the control file are ignored, and comments can be included by making the first character in the line a (small zero in superscript), a semicolon or an exclamation mark. BSS <sectionname> Specifies that the named sections should lie in the GEMDOS BSS section area. This can save valuable disk space, but will generate errors if the section contains any non-zero data. This should not be used at the same time as the DATA statement. With the INPUT or OUTPUT directive if the filename is specified as (small zero in superscript) it is substituted for the first filename on the command line. This can be useful for having a generic control file for linking C programs, for example. An example control file is: (small zer in superscript) control file for linking C program INPUT STARTUP INPUT (small zero in superscript) XDEBUG LIBRARY BLIB Assuming this control file is called CPROG.LNK, the LinkST command line TEST -w CPROG will read as input files STARTUP.BIN and TEST.BIN, and scan the library CLIB.BIN. The object code, including extended debug information, will be written to TEST.PRG, as none was explicitly specified. If you do not specify a drive name in the control file or on the command line, the default drive will be assumed. If you run LinkST from the Desktop, the default drive will always be the same as the file on which you double-clicked; though if you run it from a CLI or from the GenST editor this will not necessarily be so. Automatic Double-Clicking It is possible to install LinkST so that you can double-click on a .LNK file from the Desktop to invoke the linker, by using the Install Application option from the Desktop. This is a similar process to that described for GenST, except the type should be left as TOS Take Parameters and the extension should be .LNK. LinkST Warnings Warnings are messages indicating that something might be wrong, but it's nothing too serious. duplicate definition of value for symbol "x" The symbol was defined twice. This can happen if you replace a subroutine in a module with one of your own, for example. The linker will use the first definition it comes across, and give this warning on the second. module name is too long Module names can only be 80 characters long. comment is too long Comment directives are only allowed to 80 characters long (don't ask us why, we don't know!) absolute sections overlap Two absolute sections clash with each other. SECTION "x" is neither COMMON nor SECTION A section name was specified without defining its type. LinkST Errors LinkST errors divide into four areas; general errors, I/O errors, binary file errors, and linker bugs. In some error messages a string is included, denoted by "x" below. In others a number may be output, denoted by 99 below. General Errors unresolved symbol "x" in file "x" The symbol was referred to but not defined in the file. There may also be other files which refer to the symbol, but this gives you a start in your search! XREF value truncated A value was too large to fit into the space allocated for it, for example a BSR to an external may be out of range. bad control line "x" An illegal line was found in a control file. non-zero data in BSS section A section wanted as a true BSS section contained non-zero data. file "x" not found Can't open output file "x" Can't open map file "x" Can't open symbol file "x" Can't open input file "x" i/o error on input file disk write failed filename "x" was too long Binary File Errors These are errors in the internal syntax of the input file, and should not occur. If they do it probably means the compiler or assembler produced incorrect code. missing SOURCE directive Can occur if a file is not in GST format, for example a DRI file. runtime relocation is only available for LONGs attempt to redefine id of symbol "x" attempt to DEFINE "x" with <id> of zero bad operator code 0x99 in XREF directive bad truncation rule in XREF wrongly placed SOURCE directive bad directive 99 <id> 99 not DEFINEd as a SECTION but used as one attempted re-use of <id> 99 as SECTION id attempted re-use of "x" as SECTION name Section is COMMON but being used as though it's not SECTION is being misused as COMMON unexpected end of input file 'Linker Bug' Messages These can be produced as a result of internal checks by the linker. If you get one please send us copies of the files you are trying to link! APPENDIX A GEMDOS error codes This appendix details the numeric GEMDOS errors and their meanings. The error numbers shown are those displayed by MonST and GenST; when calling GEMDOS from your own programs these values will be 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 medium 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 produced by GenST) 12 General error 64 Range error 13 Write protect 65 Internal error 14 Medium 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 APPENDIX B GenST error messages GenST can produce a large number of error messages, most of which are pretty self explanatory. This appendix lists them all in alphabetic order, with clarifications for those which require them. Please note that GenST is continually being improved and list may not agree exactly with the version you have, there may be additional messages not documented here. Errors If you get a message beginning with INTERNAL please tell us - you should never see these. .W or .L expected as index size absolute expression MUST evaluate absolute not allowed additional symbol on pass 2 somehow a symbol has appeared during pass 2 that did not appear during pass 1 address register expected addressing mode not allowed addressing mode not recognised BSS or OFFSET cannot contain data OFFSET sections and non-GST BSS sections can only contain DS directives cannot create a binary file could be a bad filename, or a write-protected disk, etc. cannot export symbol cannot import symbol cannot reset MACRO definitions or define in REPTs macro definitions may not be nested or defined within repeat loops cannot nest repeat loops comma expected data register expected data too large division by zero duplicate MODULE name module names must be unique error during listing output listing will be stopped at this point error during writing binary file normally disk full executable code only only executable code may be assembled to memory expression mismatch normally a syntax error within an expression fatally bad conditional there were more ENDCs in a macro than IFs file not found forward reference garbage following instruction illegal BSR.S a BSR.S to the following instruction is not allowed - change it to BSR illegal type combination immediate data expected imported label not allowed include file read error instruction not recognised invalid FORMAT parameter invalid IF expression, ignored invalid MOVEF addressing mode invalid number invalid numeric expression the symbol is not defined or relative or a syntax error invalid option invalid printer parameter invalid register list invalid section name, TEXT assumed invalid size line malformed linked format restriction the DRI format is destructive about where it allows imports local not allowed missing close bracket missing ENDC there were more IFs than ENDCs missing quote misuse of label not yet implemented number too large odd address option must be at start ORG not allowed out of memory phasing error should never happen, look investigate immediately before first such error program buffer full change the program buffer size when assembling to memory register expected relative not allowed relocation not allowed repeated include file each include file may only be included once on each pass source expired prematurely with an IF, MACRO or REPT and the source ran out spurious ENDC spurious ENDM or MEXIT spurious ENDR symbol defined twice symbol expected undefined symbol user error caused by FAIL directive wrong processor XREFs not allowed within brackets Warnings 68010 instruction, converted to MOVE SR MOVE CCR, is not a 68000 instruction branch made short by optimising directive ignored invalid LINK displacement if negative or odd offset removed xx(An) form reduce to (An) by optimising relative cannot be relocated short branch converted to NOP sign extended operand data in MOVEQ needed sign extension to fit size should be .W APPENDIX C ST Memory Map This Appendix details certain information about the ST memory map: 1. Processor Dump area 2. Base Page layout 3. Hardware memory map Processor Dump Area When the ST crashes with an exception (i.e. mushrooms or bombs) it stores a copy of the processor's state in an area of memory which is not destroyed by a RESET. Thus after such a crash you can load MonST and investigate the relevant area of memory to try to ascertain what exactly went wrong. If this happens a lot you should use the auto-resident version of MonST so you will have a much better idea of the cause of the problem. $380 long contains $12345678 if valid $384 8 longs saved values of D0-D7 $3A4 8 longs saved values of A0-A7 $3C4 byte exception number $3C8 long saved USP $3CC 16 words copied from the SSP Base Page Layout Every program that runs under GEMDOS has a base page area which contains certain information. It is $100 bytes long. Offset Name Contents $00 p_lowtpa base address of the TPA (i.e. here) $04 p_hitpa pointer to end of TPA+1 $08 p_tbase pointer to start of TEXT area $0C p_tien length of TEXT area $10 p_dbase pointer to start of DATA area $14 p_dlen length of DATA area $18 p_bbase pointer to start of BSS area $1C p_blen length of BSS area $20 p_data pointer to DTA address $24 p_parent pointer to parents's base page (0 if desk acc.) $28 (reserved) $2C p_env pointer to environment string $80 p_cmdlin command line: length byte then string, which is not guaranteed to be null- terminated $100 your program starts here Hardware Memory Map Address Usage MonST Access Read Write FFFFFF ÿ ÿ Hardware Registers FF8000 FFEFFF ÿ System ROM | FC0000 | Expansion ROM | FA0000 - 1040ST 100000 _ _ 520ST 080000 | | RAM | | 020000 | | Protected RAM | | 000000 | ÿ ÿ ÿ Not to scale APPENDIX D Calling the Operating System The operating system of the ST is large and complex and consists of various levels. To help in your own program development, this appendix describes the calling mechanisms and routines available, but it is not intended to be definitive. It also details the various example programs and include files supplied with DevpacST. The various levels of the operating system are: GEM AES window and event manager GEM VDI device-independent graphics routine GEMDOS disk and screen I/O, similar to MS-DOS BIOS low level I/O XBIOS extended low level I/O Each of these will now be described in varying degrees of detail. GEMDOS - Disk and Screen I/O GEMDOS was converted from CP/M 68k and is similar in many ways to generic CP/M but with extra facilities (e.g. sub-directories) taken from MS-DOS. It is responsible for disk I/O and character I/O via the screen, keyboard, serial and parallel ports. It is also responsible for memory management. GEMDOS was designed to be called directly from C, so all parameters are put onto the stack and have to be removed afterwards. The calling sequence from assembler is of this general form: move ??,-(a7) put parameters on stack move.w #??,-(a7) the function number trap #1 call GEMDOS\ add.l #??,a7 restore the stack After the call the stack has to be corrected; while an ADD.L can be used as above, it is slow and takes six bytes. If the stack needs correction by 8 bytes or less, the best way is to use add.l #??,a7 which takes two bytes. If it has to be corrected by more than 8 bytes, the best way is lea ??(a7),a7 which takes four bytes. Both methods are smaller and faster than the first method. Incidentally, a major source of bugs when starting programming with GEMDOS is forgetting to correct the stack, or correcting it by the wrong value. Program Startup and Termination When a GEMDOS program starts up it owns all free memory - that is the memory from the end of the program through to the end of usable RAM (normally just before the screen) is owned by the program, which is just as well as the stack is at the very end of the area. If any memory management calls (such as m_alloc) are required, you wish to execute other programs within yours, or if you are writing a GEM program, it is important to give back some of this memory. If you don't there will be no free memory for these uses. this is normally done during at the beginning of programs using the m_shrink call, utilising the fact that a pointer to the programs basepage is 4 bytes down on the stack, like this: move.l 4(a7),a3 basepage move.l $C(a3),d0 text length add.l $14(a3),d0 data length add.l $1C(a3),d0 BSS length add.l #extra,d0 any additional memory add.l #$100,d0 basepage length move.l #mystack,a7 before shrinking move.l d0,-(a7) move.l a3,-(a7) clr.w -(a7) move.w _(a7) trap #1 do the shrink lea 12(sp),sp The extra bytes may be required for your programs storage. Note that you should move the stack to a safe before the shrink, otherwise the stack will be in memory that is not owned by your program and liable to corruption. A GEMDOS program can terminate in one of three ways: p_term0, which is not recommended, p_term, the normal way to finish a program, and p_termres, for system patches and the like. For normal termination use this code: clr.w -(a7) no return code move.w #S4c,-(a7) p_term trap #1 When a program terminates all memory it owns is freed and any open files are closed. GEMDOS Summary The calls will now be described in numeric order by giving the size of the parameters, in the order they should be placed on the stack, and the stack correction number. For example, using function call 2, c_conout, to print the character x, the code would be move.w #'X',-(a7) the character move.w #2,-(a7) the function number trap #1 call it addq.l #4,sp then correct At present GEMDOS calls corrupt registers d0 and a0 only, but this is not documented. We therefore recommended programmers to assume that registers d0-d2/a0-a2 are corrupted, in a similar way to the other operating system calls. 0 - Terminate Process (old form), p_term0 Parameters: None Result: None Stack: 2 This terminates the current program, with a return code of 0. It is recommended that p_term (function $4c) should be used in preference to this call. As control never returns after the call, no stack correction is actually required. 1 - Read character from keyboard, c_conin Parameters: None Result: D0.L=key code Stack: 2 This waits for a key to be struck, echoes it to the screen, and returns its value. The long result has the ASCII value in the lowest 8 bits, and a physical key number is returned in bits 16- 23. All other bits are set to 0. 2 - Write character to screen, c_conout Parameters: word: character Result: None Stack: 4 This writes the given character to the screen. A 16-bit parameter is supported for future expansion, so bytes should always be ANDed with $FF before the call, though currently the upper 8 bits are ignored. 3 - Read Character from serial port, c_auxin Parameters: None Result: D0.B=character read Stack: 2 This waits for a byte to be received from the auxiliary device, which is the serial port. 4 - Write characters to serial port, c_auxout Parameters: word: character Result: None Stack: 4 This sends the character out via the serial port. As with function 2, the upper 8 bits of the word should be 0 for upward compatibility. 5 - Write character to printer, c_prnout Parameters: word: character Result: D0.W=0 if failed, -1 if OK Stack: 4 This sends the character out via the parallel printer port. As with functions 2 and 4 above, bits 8-15 of the word should be 0. 6 - Raw I/O to standard I/O, c_rawio Parameters: word: character for output, or $00FF to read Result: D0.W if $00FF passed Stack: 4 If the character is passed as $00FF then the keyboard is scanned and a result returned in D0.W (or 0 if no key available). If the character is not $00FF, then it is printed on the screen. 7 - Raw input from keyboard, c_rawcin Parameters: None Result: D0.L=character read Stack: 2 This waits for a key to be pressed and returns its value. It does not echo it to the screen. 8 - Read character from keyboard, no echo, c_necin Parameters: None Result: D0.L=character read Stack: 2 This waits for a key to be pressed and returns its value. It does not echo, but the control keys Ctrl-C, Ctrl-S and Ctrl-Q are interpreted in their usual way - Ctrl-C will abort the program. Ctrl-S will pause output and Ctrl-Q will resume it. 9 - Write string to screen, c_conws Parameters: long: address of string Result: Non Stack: 6 This writes the given null-terminated string to the screen. $A - Read edited string from keyboard, c_conrs Parameters: long: address of input buffer Result: None Stack: 6 Before calling this, the first byte of the buffer should be set to the size of the data portion of the buffer. On return, the second byte in the buffer will be set to the length of the string, and the string itself starts at the third byte. No CR or null is stored in the returned string and pressing Ctrl-C will terminate the entire program. $B - Check status of keyboard, c_conis Parameters: None Result: D0.L=-1 if character available, 0 if none Stack: 2 This returns the status of the keyboard. The key itself should be read with another call. $E - Set default drive, d_setdrv Parameters: word: drive number Result: D0.L=bit map of drives in the system Stack: 4 This sets the default drive; a word of 0 denotes A:, 1 denotes B;, etc. The returned value has a bit set for each installed drive, bit 0=A:, bit 1=B:, etc. $10 _ Check status of standard output, c_conos Parameters: None Result: D0.L=-1 if ready, 0 if not Stack: 2 This tests to see if the console device is ready for output. $11 - Check status of printer, c_prnos Parameters: None Result: D0.L=-1 if ready, 0 if not Stack: 2 This tests the status of the printer port. If the printer is ready to receive a character it returns -1, else it returns 0. $12 - Check status of serial port input, c_auxis Parameters: None Result: D0.L=-1 if character waiting. 0 if not Stack: 2 This tests the serial port and returns -1 if there is a character waiting to be read. $13 - Check status of serial port output, c_auxos Parameters: None Result: D0.L=-1 if ready, 0 if not Stack: 2 This tests the serial port and returns -1 if it is ready to receive a character. $19 - Get default drive, d_getdrv Parameters: None Result: D0.W=drive number Stack: 2 This returns the number of the current drive, with A:=0, B:=1, etc. $1A - Set disk transfer address, f_setdta Parameters: long: pointer to disk transfer address Result: None Stack: 6 This sets the address of a 44-byte buffer used for searching for filenames. It must be word-aligned. $20 - Get into Supervisor/User Mode, s_super Parameters: long: value for stack, or 0 or 1 Result: D0.L=(depends on parameter) Stack: 6 This has two functions - it can tell you if the program is in User or Supervisor mode and it can switch from one mode to another. To find which mode the processor is in, call this routine with a parameter of 1. The return value will be 0 for user mode, and -1 for supervisor. To switch modes you have to supply a new stack pointer, or pass 0 if you want the stack to remain unchanged. For example, if you are in user mode and want to switch to supervisor mode using a SPP at address myssp, the code would be: move.l #myssp,-(a7) move.w #$20,-(a7) trap #1 addq.l #6,a7 When switching to supervisor mode the old value of the SSP is returned in d0.l. If you only want to go temporarily into Supervisor mode to hack protected memory, for example, XBIOS call supexec is a lot easier. $2A - Get date, t_getdate Parameters: None Result: D0.W Stack: 2 This reads the date, with the result in this format: Day: bits 0-4 Month: bits 5-8 Year: bits 9-15 (since 1980). $2B - Set date, t_setdate Parameters: word: date Result: None Stack: 4 This sets the date, using the same word format as the previous function. $2C - Get time, t_gettime Parameters: None Result: D0.W Stack: 2 This returns the time of day, with the result in this format: Seconds/2: bits 0-4 Minutes: bits 5-10 Hours: bits 11-15 $2D - Set time, t_settime Parameters: word: time Result: None Stack: 4 This sets the current time of day, in the same word format as the previous function. $2F - Get disk transfer address, f_getdta Parameters: None Result: D0.L=pointer to disk transfer address Stack: 2 This returns the current disk transfer address, and should always be even. $30 - Get version number, s_version Parameters: None Result: D0.W=version number Stack: 2 This returns the GEMDOS version number, with the major number in the low byte, and the minor number in the high byte. Known releases at this time are: $0D00 version 0.13 (obsolete disk-based) $1300 version 0.19 (ROM-based) $31 - Terminate and stay resident, p_termres Parameters: word: exit code, long: bytes to keep Result: None Stack: 8 This allows a program to terminate while keeping part or all of it in memory. It is useful for programs which extend the system, such as RAM disk drivers; if they terminated normally the memory the lie in would get destroyed when the next program loaded. The memory that can be retained is that starting at the base page, and the length parameter should include the $100 of the base page, the required program length, data and stack space if relevant. $36 - Get drive free space, d_free Parameters: word: drive code, long: pointer to buffer Result: None Stack: 8 This returns various bits of information about a particular disk drive. The drive code should be 0 for the default drive, 1 for A:, 2 for B:, etc. The buffer should be 16 bytes long, and word aligned. On return, it will contain 4 longs of information; free space, number of available clusters, sector size (in bytes), and cluster size (in sectors). $39 - Create a sub-directory, d_create Parameters: long: address of pathname Result: D0.W=0 if OK, else error code Stack: 6 This creates a new directory, according to the null-terminated string. $3A - Delete a sub-directory, d_delete Parameters: long: address of pathname Result: D0.W=0 if OK, else error code Stack: 6 This deletes a directory, so long as it has no files or other directories in it. $3B - Set current directory, d_setpath Parameters: long: address of pathname Result: D0.W=0 if OK, else error code Stack: 6 This sets the current directory, according to the null-terminated string. Note that drive specifiers are not allowed - you should set the current drive then its directory. $3C - Create a file, f_create Parameters: word: attributes, long: pointer to string Result: D0.W=file handle if successful, else error (and longword negative) Stack: 8 This will attempt to create the given file and if successful will return a file handle that can be used in other file GEMDOS calls. The attribute word can be these values: 01 read only 02 hidden file 04 hidden system file 08 filename contains volume name in first 11 bytes File handle numbers returned by this call and the following one start are words normally starting at 6 and go upwards. Handles 0 to 5 are standard handles which are already open when a program starts. They correspond to the following devices: 0 - console input 1 - console output 2 - serial port 3 - parallel port There are three system device names, called CON:, AUX: and PRN: which can be used with this and the following call. They return negative works, so to distinguish these from error returns always TST.L/BMI for the error case. $3D - Open a file, f_open Parameters: word: mode, long: pointer to filename Result: D0,W=file handle if successful, else error (and longword negative) Stack: 8 This will open an existing file for reading, writing, or both. The mode word must be one of the following: 0 open to read 1 open to write 2 open for both reading and writing If successful this will return a handle which can be used subsequently, else an error number. $3E - Close file, f_close Parameters: word: handle Result: D0.W=0 if OK, else an error number Stack: 4 Given a file handle this will close the file. Do not close a standard handle. Note: This call, along with all the others that require handles, do not do very extensive checks on the validity of the handle. If you pass an invalid one you may get an error return, or the machine may crash! $3F - Read file, f_read Parameters: long: load address, long: number of bytes to read, word: handle Result: D0.L=number of bytes read, or an error code Stack: 12 This will attempt to read bytes from the given file. If an error occurs D0.L will be negative. If the end of file is reached during the read operation an error code is not returned - if you wish to check for this you have to compare the number of bytes you asked for with the result - if they are different then you tried to read past the end of file. $40 - Write file, f_write Parameters: long: start address, long: number of bytes to write, word: handle Result: D0.L=number of bytes written, or an error code Stack: 12 This will attempt to write bytes to the given file. If an error occurs D0.L will be negative. If the disk becomes full an error code will not be issued, but the value returned will not be the same as the value passed to it as the number of bytes to write. Note: If you pass a negative length parameter GEMDOS will crash very badly. $41 - Delete File, f_delete Parameters: long: pointer to filename Result: D0.W=0 if successful, else error code Stack: 6 This will attempt to delete the given file. $42 - Seek file pointer, f_seek Parameters: word: mode, word: file handling, long position Result: D0.L=absolute position in file after seek Stack: 10 This will move the file pointer to a given position in the file. The mode word should be one of the following. 0 move to N bytes from the start of the file 1 move to N bytes from the current location 2 move to N bytes from the end of the file If you try and move past either end of the file you will get a result of 0 (for the start) or the actual length of the file. $43 - Get/Set file attributes, f_attrib Parameters: word: attributes, word: get/set, long: pointer to filename Result: D0.W=new attributes, or an error code Stack: 10 This can be used to get or set the attributes for a given file. The attribute's word can be: 01 read only 02 hidden file 04 hidden system file 08 filename is actually the volume label in first 11 bytes $10 sub-directory $20 file is written and closed The other word should be 0 to Get the attribute, or 1 to Set it. $45 - Duplicate File Handle, f_dup Parameters: word: standard handle Result: D0.W=new handle, or error code Stack: 4 Given a handle to a standard device (0-5), this function returns another handle that can be used to address the same device. It can also be closed without affecting the standard device handle. $46 - Force file handle, f_force Parameters: word: non-standard handle, word: standard handle Result: D0.W=0 if OK, else error code Stack: 6 This forces the standard handle to point to the same device or file as the non-standard one, and can be used, for example, to re-direct screen output to a disk file. $47 - Get Current Directory, d_getpath Parameters: word: drive number, long: pointer to buffer Result: D0.W=0 if OK, else error code Stack: 8 Given a drive number (default drive=0, A:=1, B:=2 etc.) this will return the current directory in the given buffer, in null- terminated form. The buffer should be 64 bytes long. $48 - Allocate Memory, m_alloc Parameters: long: number of bytes required Result: D0.L=address of memory allocated, or 0 if failed Stack: 6 This allocates the given amount of memory from the system pool, if available. When a program terminates all its memory allocations are cleaned up. This call can also be used to find the amount of free memory, if -1 is passed. Note: When GEMDOS itself uses this call it always ensures the number of bytes required is even, so we recommend this out of paranoia. This call can occasionally return an odd value for the start of the allocated memory under TOS 13. $49 - Free Allocated Memory, m_free Parameters: long: address of area to free Result: D0.W=0 if OK, else an error code Stack: 6 This frees a block of memory allocated with m_alloc above. $4A - Shrink Allocated Memory, m_shrink Parameters: long: length to keep, long: start address to keep, word: 0 Result: D0.W=0 if OK, else an error code Stack: 12 This is normally used when a program starts up and releases part of the allocated memory back to GEMDOS. $4B - Load or Execute a Program, p_exec Parameters: long: pointer to environment string, long: pointer to command line, long: pointer to filename, word: mode Result: D0.L=(depends on mode) Stack: 16 This call can be used for loading and chaining programs. The mode word can be one of: 0 load and execute 3 load but do not execute 4 execute base page 5 create base page For load and execute, the return value is either an error code, or the value returned when the child program exited. For load but don't execute the return value is either an error code, or a pointer to the base page of the loaded program. A discussion of using modes 4 and 5 is beyond the scope of this document. The command line should be of the form of a length byte followed by the line itself. The environment string may be passed as 0 to inherit the programs parents basepage, or as a pointer to a list of null-terminated environment strings, ending in a double-null. The normal environment looks like this: dc.b 'PATH=',0,'A:\',0,0 $4C - Terminate Program, p_term Parameters: word: return value Result: N/A as doesn't return Stack: N/A $4E - Search for First, f_sfirst Parameters: word: attributes, long: pointer to filespec Result: D0.W=0 if found, else -33 not found Stack: 8 This trap can be used to scan a directory using wild-cards to find all the files. This should be called to find the first one, then f_snext should be called for the rest. When a file is found the parameters of the file are returned in the DTA buffer area. The attribute word determines which file types are to be included in the search, and may be one of: 00 normal files 01 read only files 02 hidden files 04 system files 08 return volume name only $10 sub-directories $20 files that have been written to and closed The returned values in the DTA buffer are: 0-20 reserved for internal use 21 file attributes 22-23 file time stamp 24-25 file date stamp 26-29 file size (long) 30-43 name and extension of file, null terminated The address of the DTA buffer can be set with function $1A, and read with function $2F. $4F - Search for Next Occurrence, f_snext Parameters: None Result: D0.W=0 if found, else -33 not found Stack: 2 After calling f_first to find the first occurrence of a filespec, this call is used to find subsequent files. When a file is found the DTA buffer is filled as described previously. For it to work the first 20 bytes of the DTA must remain untouched between calls. $57 - Rename a file, f_rename Parameters: long: pointer to new name, long: pointer to old name, word: 0 Result: D0.W=0 if OK, else error code Stack: 12 This will attempt to rename the file to the new name. A file with the new name must not already exist. $57 - Get/Set File Date & Time Stamp Parameters: word: 0 for Get/1 for Set, word: file handle, long: pointer to buffer Result: None Stack: 10 This can be used to get or set the time and date stamp on an open file. The buffer should contain two words, the first being the time, and the second the date, in the format already described. BIOS - Basic I/O System The ST BIOS is intended for low-level access to the screen, keyboard and disk drives. It is accessed using the stack for parameters as described previously, but using TRAP #13 to invoke it. Programmers who require access to the BIOS are likely to need much more details then we could provide, so only one BIOS call is described here. For greater BIOS detail see the books in the bibliography. The BIOS handler preserves registers D3-D7/A3-A7 - all others may be corrupted by a call. BIOS 5 - Set Exception Vector, setexc This is a very useful trap and sets certain system vectors to point to your own routines. It can set both exception vectors and system vectors. The calling sequence is: move.l #myroutine,-(a7) address of new handler move.w #vectornum,-(a7) vector number move.w #5,-(a7) BIOS function number trap #8,a7 restore stack move.l d0,oldroutine store old one The vector number should be the exception number (2 for bus error, 3 for address error etc.) or one of the following system vectors: $45 200Hz list $100 system timer interrupt $101 critical error handler $102 process terminate hook On return from the trap D0.L contains the previous value. If a program modifies any vectors it should always restore them to their original values before terminating. If you pass an address of -1 it will not be changed, but the current value will be returned in D0.L. XBIOS - Extended BIOS The XBIOS consists of 40 functions for a wide variety of functions including hardware access, screen control, and keyboard mapping. Again we leave most of the description to the books in the bibliography, with the exception of five XBIOS calls. The XBIOS handler preserves registers D3-D7/A3-A7 - all others can be corrupted by a call. The calling sequence is the usual one: put parameters on the stack, put a function word on the stack, do a TRAP #14, then restore the stack. The XBIOS functions are: XBIOS 2 - Get Physical Screen Address, _physbase Parameters: None Result: D0.L=start of screen Stack: 2 This will return the physical address of the screen, which always occupies 32000 bytes and is aligned on a 256-byte boundary. XBIOS 3 - Get Logical Screen Address, _logbase Parameters: None Result: D0.L=start of screen Stack: 2 This will return the logical address of the screen. XBIOS 4 - Get Screen Resolution, _getRez Parameters: None Result: D0.W=0 low, 1 medium, 2 high Stack: 2 This will return the current screen resolution. XBIOS 5 - Set Screen Address & Mode, _setScreen Parameters: word: mode, long: physical address, long: logical address Result: None Stack: 12 This lets you change the screen resolution and addresses. If any parameter is specified as -1 then it is left alone. Changing the screen mode will clear the screen. XBIOS $26 - Call Supervisor Routine, supexec Parameters: long: address of routine Result: None Stack: 6 This will call the given routine in supervisor mode. The routine should not make any BIOS, XBIOS or GEMDOS calls. GEM Libraries GEM itself consists of two components; the VDI and the AES. The GEM VDI (for virtual Device Interface) is the main part of the operating system that draws graphics and text on the screen. The GEM AES (for Application Environment Services) is the part of the operating system that provides the user-interface facilities of GEM such as windows, menus and dialogue boxes. This section is intended to give details of the supplied library files and calling conventions used. It does not attempt to describe either the VDI or the AES in great detail - the books in the Bibliography should be referred to for this. However, details are given of information that we feel is badly documented or not documented at all. GEM AES Library The calling sequence to the AES is based on various arrays of words and longwords. These arrays are defined using DS directives and are: control words int_in words addr_in longwords int_out words addr_out words aes_params longwords global words For example the C program segement val=int_out (2)+int_out (3) could be converted into this assembly language: move.w int_out+4,d0 add.w int_out+6,d0 Note the way that the array index is doubled before adding to the start of the array, as it is an array of words. For an array of longs the index should be quadrupled. A macro file, called GEMMACRO.S should be used which defines various macros and, if generating executable code, the file AESLIB.S should be included at the end of assembly. The macros take a varying number of parameters and place them in the required places in the AES arrays, before making a call to the general AES routine. If passing a constant to a macro be sure to precede it with a # sign, for example passing the parameters 3,myptr to a macro could generate the code move.w 3,int_in move.1 myptr,addr_in The first line will cause a run-time error, the parameter should have been #3. There are a few AES macros which do not take all the required parameters - additional information may have to be placed in other arrays. On return from and AES macro D0.W (and the flags) reflect the contents of the array int_out(0), normally useful. Various return values can often be found in the int_out array. The following descriptions assume all parameters to be word sized, unless shown with a .L suffix, denoting a longword parameter. Application Library appl_init Should be called at the start of any AES program. appl_read id,length,buffer.L apppl_write id,length,buffer.L appl_find name.L Find a named program, normally a desk accessory appl_tplay memory.L,number scale appl_trecord memory.L,count appl_exit Should be just before an AES program terminates. It sends AC_CLOSE type messages to all desk accessories. Event Library evnt_keybd evnt_button clicks,mask,state The return value is the number of times the button entered the desired state. Array elements 1-4 of int_out contain the X co- ordinate, the Y co-ordinate, the button state and the keyboard state at the time of the event in that order. evnt_mouse flags,x,y,w,h The return values are as described for the previous call. evnt_mesag buffer.L evnt_timer count.L evnt_multi flags,clicks,mask,m1flags,m1x,m1y,m1w,m1h, & m2flags,m2x,m2y,m2w,m2h,count.L All parameters except the first are optional, specifying a null parameter means nothing is placed in the relevant element of int_in. It shown above with the syntax of a multi-line macro call but this is not obligatory. The int_out array contains which event, mouse X, mouse Y, button, keyboard state, keyboard code and button value, respectively. evnt_dclick new,getset Menu Library menu_bar free.L,show menu_icheck tree.L,item,check menu_ienable tree.L,item,enable menu_tnormal tree.L,title,normal menu_text tree.L,item,text.L menu_register id,string Note: Normally a menu tree is generated by a resource editor though they can be constructed, with a great deal of care, by hand. Another alternative is to use the MENU2ASM compiler,detailed later in this section. Object Library Object trees are normally constructed with a resouce editor, though they can be constructed by hand if required. Dialog boxes are the easiest type of object tree to construct by hand and menus the most difficult. objc_add tree.L,parent,child objc_delete tree.L,object objc_draw tree.L,startob,depth,x,y,w,h objc_find tree.L,startob,depth,x,y objc_offset tree.L,object Elements 1 and 2 of int_out contain the returned X and Y co- ordinates. objc_order tree.L,object,newpos objc_edit tree.L, object,char,idx,kind int_out(1) contains the new idx objc_change tree.L,object,x,y,w,h,new,redraw Form Library form_do tree.L,startob Never pass startob as -1 as often documented, use 0 instead form_dial flag,x1,y1,w1,h1,x2,y2,w2,h2 form_alert button,string.L form_error errnum Error numbers should be positive and less than 64 form_center tree.L Graphics Library graf_rubberbox x,y,w,h int_out(1) contains the finish width, int_out(2) the height graf_dragbox w,h,x,y,bx,by,bw,bh int_out(1) contains the finish X co-ordinate, int_out(2) the Y graf_movebox w,h,x,y,dx,dy graf_growbox w,y,w,h,fx,fy,fw,fh graf_shrinkbox x,y,w,h,sx,sy,sw,sh graf_watchbox tree.L,object,instate,outstate graf_slidebox tree.L,parent,obj,vh graf_handle The int_out array will contain the VDI handle, character cell width, then height, system font width, then height graf_mouse number,address.L The address parameter is optional, only required if defining your own shape graf_mkstate The int_out array will contain a reserved value, mouse X and Y position, mouse button state and keyboard state. Scrap Library scrp_read buffer.L scrp_write buffer.L File Selector Library fsel_input path.L,filename.L The path parameter should point to a buffer containing the null-terminated path, such as A:\ø.S, and the new path will be returned in it, so be sure it is large enough. The filename buffer should be 13 bytes, with a maximum of 12 used for filename, for example TEST.S. If D0.W is non-zero on return then it means there was not enough free memory to invoke the selector, else int_out(1) will contain 0 if Cancelled. Window Library wind_create kind,x,y,w,h wind_open handle,x,y,w,h wind_close handle wind_delete handle wind_get handle,field wind_set handle,field wind_find x,y wind_update begend wind_calc type,kind,inx,iny,inw,inh Resource Library rsrc_load filename.L rsrc_free rsrc_gaddr type,index The result address may be found in addr_out rsrc_saddr type,index,saddr.L rsrc_obfex tree.L,object Shell Library shel_read command.L,shell.L shel_write doex,sgr,scr,cmd.L,shell.L We have never managed to get this call to work reliably shel_find buffer.L The buffer should be a minimum of 80 bytes shel_envrn value.L,string.L Debugging AES Calls Unlike the calls to the VDI, calls to the AES are not immediately obvious when viewed from MonSt as they are of the form: moveq #??,d0 AES function number bsr CALL_AES As an aid to decoding these, here is a table listing all the AES calls and their hex function numbers: A appl_init B appl_read C appl_write D appl_find E appl_tplay F appl_trecord 13 appl_exit 14 evnt_keybd 15 evnt_button 16 evnt_mouse 17 evnt_mesag 18 evnt_timer 19 evnt_multi 1A evnt_dclick 1E menu_bar 1F menu_icheck 20 menu_ienable 21 menu_tnormal 22 menu_text 23 menu_register 28 objc_add 29 objc_delete 2A objc_draw 2B objc_find 2C objc_offset 2D objc_order 2E objc_edit 2F objc_change 32 form_do 33 form_dial 34 form_alert 35 form_error 36 form_center 46 graf_rubberbox 47 graf_dragbox 48 graf_movebox 49 graf_growbox 4A graf_shrinkbox 4B graf_watchbox 4C graf_slidebox 4D graf_handle 4E graf_mouse 4F graf_mkstate 50 scrp_read 51 scrp_write 5A fsel_input 64 wind_create 65 wind_open 66 wind_close 67 wind_delete 68 wind_get 69 wind_set 6A wind_find 6B wind_update 6C wind_calc 6E rsrc_load 6F rsrc_free 70 rsrc_gaddr 71 rsrc_saddr 72 rsrc_obfix 78 shel_read 79 shel_write 7A shel_find 7B shel_envrn GEM VDI Library The calling sequence itself to the VDI is, like the AES, based on various arrays of words and longwords. These arrays are defined using DS directives and are: contrl words intin words ptsin words intout words ptsout words vdi_params longwords All (but one) VDI calls require a VDI handle, which by tradition is a parameter to every call. However, the majority of programs only use one handle, to a virtual workstation (the screen), so the supplied VDI libraries use a word called current_handle as the handle to pass on to the VDI itself. This saves an appreciable amount of code and is the same way the HiSoft BASIC libraries work. As the source to the library is supplied you could change this, if required. The macro file GEMMACRO.S should be used which defines various macros and, if generating executable code, the file VDILIB.S should be included at the end of assembly. The macros take a varying number of parameters and place them in the required places in the VDI arrays, before making a call to a VDI library routine. The warning about # signs in parameters described previously applies to the VDI too. There are a number of VDI macros which do not take all the required parameters - additional information may have to be placed in other macros. On return, various return values can often be found in the intout ptsout arrays. The following descriptions assume all parameters to be word sized, unless shown with a .L suffix, denoting a longword parameter. Control Functions v_opnwk Open Workstation This should not be used unless GDOS is installed. The intin array should be suitably initialised, current_handle will be set to the result of this call. v_clswk Close Workstation v_opnvwk Open Virtual workstation This uses current_handle to open another workstation and sets current_handle to the result. intin is normally filled with 10 words of 1 and one word of 2 (denoting RC co-ordinates). v_clsvwk Close Virtual Workstation V_clrwrk Clear Workstation v_updwk Update Workstation vst_load_fonts Load Fonts Do not attempt this unless GDOS is loaded. vst_unload_fonts Unload Fonts Fonts must be unloaded before a workstation is closed. vs_clip flag,x1,y1,x2,y2 Set Clipping Rectangle Output Functions v_pline count Polyline The input co-ordinates should be copied to intin before the call. v_pmarket count Polymarker The input co-ordinates should be copied to intin before the call. v_gtext x,y,string.L Text The string should be in the form of null-terminated bytes. v_fillarea Filled Area The input co-ordinates should be copies to itin before the call. v_contourfill x,y,index Contour Fill vr_recfl x1,y1,x2,y2 Bar v_arc x,y,radius,start,end Arc v_pieslice x,y,radius,start,end Pie v_circle x,y,radius Circle v_ellarc x,y,xradius,yradius,start,end Elliptical Arc v_ellpie x,y,xradius,yradius,start,end Elliptical Pie v_ellipse x,y,xradius,yradius Ellipse v_rbox x1,y1,x2,y2 Rounded Rectangle v_rfbox x1,y1,x2,y2 Filled Rounded Rectangle v_justified x,y,string.L,length,ws,cs Justified Graphics Text The string should be null-terminated Attribute Functions vswr_mode mode Set Writing Mode vs_colour index,red,green,blue Set Colour Representation vsl_type style Set Polyline Line Type vsl_udsty pattern Set User Defined Line Style Pattern vsl_width width Set Polyline Line Width vsl_color index Set Polyline Colour Index vsl_ends begin,end Set Polyline End Styles vsm_type symbol Set Polymarker Type vsm_height height Set Polymarker Height vsm_color index Set Polymarker Colour Index vst_height height Set Character Height, Absolute Mode The ptsout array will contain the selected size vst_point point Set Character Height, Points Mode The ptsout array will contain the selected size. vst_rotation angle Set Character Baseline Vector vst_font font Set Text Face vst_colour index Set Graphic Text Colour Index vst_effects effect Set Graphic Text Special Effects vst_alignment horizontal,vertical Set Graphic Text Alignment vst_interior style Set Fill Interior Style vst_style index Set Fill Style Index vsf_color index Set Fill Colour Index vsf_perimeter vis Set Fill Perimeter Visibility vsf_updat Set User Defined Fill Pattern The intin array should be filled with the pattern and contrl(3) set suitably. Raster Operations vro_cpyfm mode,source.L,dest.L Copy Raster, Opaque This is the general blit call, most often used for scrolling the screen. The source and destination parameters should point to a memory form definition block (MFDB) which describes the format of the memory to blit. An MFDB consists of ten words: 0 high word of address 2 low word of address 4 width in pixels 6 height in pixels 8 width in words 10 form flag, normally 1 12 number of planes 14-18 reserved, set to 0 The address in the first two words is normally either the screen address of the address of a buffer being used for the blit. The width and height fields should be those suitable for the screen size and the number of planes can be found from a vq_extend 1 call in intout(4). When scrolling the screen the source and destination parameters may point to the same MFDB. The source and destination rectangles should be placed in the ptsin array, each in the form x1,y1,x2,y2. A mode of 3 means replace. vrt_cpyfm mode,source.L,dest.L,i1,i2 Copy Raster, Transparent vr_trnfm source.L,destination.L Transform Form vr_get_pixel x,y Get Pixel Input Functions vex_timv newtimer Exchange Timer Interrupt Vector v_show_c reset Show Cursor v_hide_c Hide Cursor vq_mouse Sample Mouse Button State vex_butv newxbut Exchange Button Change Vector vex_motv newmotv Exchange Mouse Movement Vector vex_curv newcursor Exchange Cursor Change Vector vq_key_s Sample Keyboard State Information Inquire Functions vq_extnd flag Extended Inquire vq_color index,flag Inquire Colour Representation vql_attributes Inquire Polyline Attributes vqm_attributes Inquire Polymarker Attributes vqf_attributes Inquire Fill Area Attributes vqf_attributes Inquire Graphic Text Attributes vqt_extent string.L Inquire Text Extent The string should be null-terminated, the results will be found in ptsout. vqt_width char Inquire Character Cell Width vqt_name number Inquire Face Name & Index vqt_fontinfo Inquire Current Face Information AES & VDI Program Skeleton The general structure of a GEM-type program is as follows: shrink memory call call appl_init set current_handle to the result from graf_handle open a virtual workstation using this handle open a window, perhaps main wait for events & act on them as required quit close any window call appl_exit finally p_term Desk Accessories A desk accessory is an executable file with the extension .ACC loaded during AES initialisation. We have never seen any official documentation on desk accessories, and the following information has been learnt the hard way, mainly when writing our Saved! program. The first thing to be wary of is that it is not a normal GEMDOS program. When it starts up all registers including A7 are 0, with the exception of A0 which points to the basepage. An accessory must include all the memory it requires within itself, the BSS segment being a good place. An accessory must not do a GEMDOS shrink call or attempt to terminate. The main loop of an accessory is like any other AES program, consisting of an event loop, but note that most documentation details incorrect message numbers - AC_OPEN is really 40 and AC_CLOSE is 41. Other programmers have reported problems using the VDI from within an accessory. The recommended method is to open a virtual workstation only when you have to (i.e. before creating a window) and always close it (when you close your window or, failing that, when receiving an AC_CLOSE message. The example accessory supplied, like our Saved! program, does not use the VDI at all - paranoia rules! If your accessory responds to timer events ensure that no GEMDOS calls (Trap #1s) are made unless your window is the front one, otherwise time bombs will be set and a crash is highly likely. The file DESKACC.S contains the source to an example accessory, which simply displays the system free memory in an alert box. It has a label called RUNNER which can be set to 1 to produce a stand-alone application instead of an accessory. This can be invaluable during program development as you can symbolically debug a stand-alone program, while an accessory has to be debugged using AMONST without the benefit of symbols. Linking with AES & VDI Libraries The supplied macro file GEMMACRO.S is designed to be used in executable or linkable programs. The files AESLIB.S and VDILIB.S contain the actual code and should be included at the end of programs when generating executable code, but if generating linkable code they should not. If you look at GEMTEST.S you can see how a conditional is used to make this automatic. When developing a program using these libraries we recommend executable code as it greatly reduces development time. However the file size can be reduced by using the selective library feature of the linker and using the GEMLIB.BIN file. For example, if GEMTEST is linked to GST-linkable code, producing GEMTEST.BIN, it can be linked with this library by passing LinkST the command line gemtest -wgemlib The GEMLIB.LNK control file will do the rest. If you want to reduce your program to the absolute minimum then you can change the libraries as you require, which is why we supply the source code. Menu Compiler For those who wish to use menus without using a resource editor we supply the program MENU2ASM.TTP which converts a menu definition file into assembly language source statement for inclusion in your program. We use this method ourselves in the GenST editor. The menu specification should be created in a text file with the extension .MDF and an example follows: [ Desk | About Program ] [ File | New \ Load \ (-------\ Quit ] [ Search | Find ] and so on. Line breaks are ignored. Each menu title and its items are enclosed in square brackets [ and ]. There is a vertical bar (|) after each title and the individual items separated by back- slashes (\). For grey items precede the text with an open parentheses (. The first menu is always the desk title (normally Desk); the currently loaded desk accessories will be added by the AES. (It is no coincidence that this is the same syntax as that accepted by our BASIC compilers). We recommend that you precede each menu item with two spaces and have at least one space after the item. Menu titles should have one space before and after them. To compile a file double-click on MENU2ASM.TTP and enter the filename, without an extension. It will produce a file with an extension of .MNU which may be included in your program. The file MENUTEST.MDF contains an example definition of a menu and MENUTEST.S the source code to a program illustrating its use, as well as showing other AES features. Old GenST AES & VDI Libraries The folder OLDGEM contains updated versions of the source files supplied with version 1 of DevpacST. These use different calling conventions and are supplied for users who have upgraded. VT52 Screen Codes When writing to the screen via the BDOS or BIOS calls, the screen driver emulates VT52 protocols. The control codes are sent via escape sequences, which means an escape character is sent (27 decimal, or $1B) followed by one or more other characters. ESC A cursor up; no effect if at the top line ESC B cursor down; no effect if at the bottom line ESC C cursor right; no effect if on the right hand side ESC D cursor left; no effect if on left hand side ESC E clear screen and home cursor ESC H home cursor ESC I move cursor up one line; if at top scrolls the screen down a line ESC J erase to end of screen, from the cursor position onwards ESC K clear to end of line ESC L insert a line by moving all following lines down. Cursor is positioned at start of the new line ESC M delete a line by moving all following lines up ESC Y position cursor; should be followed by two characters the first being the Y position, the second the X. Row and column numbering starts at (32,32) which is the top left ESC b foreground colour; should be followed by a character to determine the colour, of which the four lowest bits are used ESC c background colour; similar to above ESC d erase from beginning of display to the current position ESC e enable cursor ESC f disable cursor ESC j save the current cursor position ESC k restore a current position saved using ESC j ESC l erase a line and put cursor at start of line ESC o erase from start of line to cursor position ESC p inverse video on ESC q inverse video off ESC v wrap around at end of line on ESC w wrap around at end of line off APPENDIX E Converting from other Assemblers Most 68000 assemblers for the ST follow, to one degree or another the Motorola standard. While the instructions themselves are thankfully standard, the syntax rules for labels, comments and directives can, and do, vary. This Appendix covers the changes most likely to be made when converting programs from another assembler, whether they are your old source files or a program listed in a magazine. It does not attempt to detail the differences in user interfaces or options between the different assemblers. Atari MADMAC GenST does not require colons after labels or comments to be delimited with semi-colons, but it does not allow instructions or directives to start in the label field. The syntax and rules for local labels are the same, though $ and ? are not valid in GenST symbols. The use of \ in quoted strings may have to be changed, and some arithmetic operators and priorities are different. MADMAC allows directives to start with dot, if these are removed most directives are the same as GenST. Those that differ, and their GenST equivalents are: BSS=SECTION BSS, DATA=SECTION DATA, TEXT=SECTION TEXT, ABS=OFFSET, ELSE=ELSEIF, ENDIF=ENDC, EXITM=MEXIT, GLOBL and EXTERN=XREF or XDEF, EJECT=PAGE, TITLE=TTL, NLIST=NOLIST. INIT can be converted to DC or DCB statements and CARGS can be replaced with suitable RS directives. MADMACs macro syntax is unique and its named parameters will need conversion, equivalents for its parameters are \~=\@ and \#=NARG.\? can be emulated using IFC or IFNC. The 6502 options of MADMAC are not supported. GST-ASM GST labels are significant only to the first 8 characters and are case insensitive so OPT C8- may be required. Its rules for expression evaluation are very similar though $ is not allowed within a GenST symbol. Most directives are the same, those requiring name changes are PAGEWID=LEN and PAGELEN=PLEN. Macro definitions will require conversion as will GSTs unique form of local symbols. Built-in functions and structure statements are not supported. MCC Assembler Very few changes are required, only the syntax for local labels and add.L to XREF directives of absolutes. K-SEKA Colons are not required after labels in GenST though instructions or directives that start in the label field will need a tab added before them. Several Seka directives default to Byte instead of Word sizes for some reason. Equivalent directives names are: D=DC, BLK=DS, CODE=SECTION CODE, DATA=SECTION DATA, IF=IFNE, ELSE=ELSEIF, ENDIF=ENDC. Macro syntax requires ?s to be changed to \s, except ?0 which should be replaced with \@. Fast ASM The syntax of Fast ASM was designed around GenST 1.2 so few changes are required. Tokenised source files will need conversion to ASCII (using the Clipboard) before attempting to load them into the GenST editor. The main change involves comment delimiters - Fast ASM lines starting with \ should be changed to start with ø or ;-\s used after instructions will not require any changes. The floating point facilities in Fast ASM, left over from its BASIC interpreter origins, are not supported in GenST. APPENDIX F BIBLIOGRAPHY This bibliography contains our suggestions for further reading on the subject of the 68000, the ST, 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. 68000 Programming M68000 Programmer's Reference Manual Published by Prentice-Hall The definitive guide to the instruction set produced by Motorola. the supplied Pocket Guide is a subset of this book. Be sure to get the latest version - at the time of writing the Fifth Edition is the latest. 68000 Assembly Language Programming by Kane, Hawkins & Leventhal Published by Osborne/McGraw-Hill This is large (and expensive) but good, containing lots of examples. Be sure to get the second edition. Not for complete beginners to microprocessors. 68000 Tricks and Traps by Mike Morton BYTE magazine, September 1986 issue By far the best article on 68000 programming we have ever seen. We wish there was a book like this. ST Technical Manuals GEM Programmer's Guide Volumes 1 & 2 - VDI and AES By Digital Research The definitive guide to the VDI and the AES, but marred by mistakes and lack of 68000 details. Only available to registered developers. GEMDOS Specification by Digital Research The definition of the GEMDOS calls. Only available to registered developers. A Hitchhikers Guide to the BIOS by Atari Corp The definition of the BIOS and XBIOS calls, and corrections to the GEMDOS manual. This is accurate, a good read and updated regularly. Normally only available to developers. The Anatomy of the Atari ST by Data Becker/Abacus This book is the best documentation available for the user who is not a registered developer. It describes the hardware and non-GEM aspects of the operating system, including an (out-of-date) BIOS listing. Thoroughly recommended, despite its inaccuracies. GEM on the Atari ST by Data Becker/Abacus This describes programming under GEM, though is not as complete as the DR manual, but has similar errors. It describes calls mainly from C, although there is more reference to the 68000 than in the DR manual. Better than no book at all on GEM. Concise Atari 68000 Programmer's Reference by Katherine Peel Published by Glentop 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. Tricks and Tips on the Atari St by Data Becker/Abacus This contains a wide variety of material, including an accurate description of the more esoteric ST BASIC commands, and good sample listings including a RAM-disk driver and desk accessory. M68000 Cross Macro Assembler Reference Manual Published by Motorola (M68KXASM) The official definition of 68000 assembly-language syntax on which GenST is based. M68000 Resident Structured Assembler Reference Manual Published by Motorola (M68KMASM) This details the more advanced aspects of the Motorola standard including extended macros and 68010/20/881 processors. APPENDIX G TECHNICAL SUPPORT & UPGRADES 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. Phone our technical support hour is normally between 3 p.m. and 4 p.m. though non-European customers' calls will be accepted at other times. Post if sending a disk, please put your name & address on it. BIXTM our username is (not surprisingly) hisoft. Would UK customers please use more old fashioned methods; it's cheaper for everyone. 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. 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, DevpacST is undergoing continual development and, periodically, new versions become available. We make 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 out programs and, to ensure we remember them, they should be made in writing. DevpacST Developer Version For those that require maximum power from their 68000 assembler we have available the Developer version of Devpac ST. Features over and above this version include: GDOS is supplied together with documentation, sample program and calling sequences; Motorola S record hex output and multiple-ORG statements for users cross-developing; Amiga executable & linkable file formats; 68010/20/30/881/882 instructions; Dual machine debugging; Detailed notes on GST & DRI file formats including special dump programs for both formats, source (in HiSoft BASIC) included; Free upgrades for a year, despatched automatically). DevpacST Developer is available as an upgrade. APPENDIX H REVISION HISTORY Product History DevpacST 0.50 was first released in late 1985, but with various restrictions to do with the editor and lack of linkable code. The next major version was 0.91 which was much improved in many respects, followed by 0.99f, the last version which didn't produce linkable code. Version 1.0 was released in April 1986, and underwent a few minor changes before the release of version 1.22 in June 1986, the first version supplied in a ring-bound manual. After various small revisions the greatly improved version 2.0 was released in April 1988. Development Technique DevpacST was originally based on DevpacQL, our Assembler Development suite for the Sinclair QL. Both GenST and MonST were written in assembler on the QL then uploaded via the serial port into the ST, and LinkST was written using Lattice C on the ST. Development moved across to the ST around version 1.24 which had minor changes made, reaching version 1.26. Special internal versions were written to experiment with things like linkable code and extended debug and reached version 1.57 before both GenST and MonST were completely re-written for version 2. The editor was extensively altered, originally for HiSoft BASIC, then Power BASIC, then GenST. The editor is written entirely in assembly language. Summary of Version 2 Improvements This section is intended as a quick guide to the main additional features for users who have upgraded from version 1.2 or DevpacST. It gives an overview of the new features, for further details you should consult the relevant sections of the new manual. The Editor This has been greatly enhanced, with an overall improvement in display speed being the most obvious. The editor supports lines up to 240 characters in length, sideways scrolling as required. It also works in low-resolution. There is now a horizontal scroll bar and the workings of the vertical scroll bar is now more "standard". By default the numeric pad is configured as an IBM- style cursor cluster and the text editor. This, combined with the saving of preferences, means the installation program in version 1 is redundant. Other programs can be run from within the editor using the Run Other facility. Block Deleter has changed to Shift-F5 from Shift-F3 (as fast left-handed typists can generate the Shift-F3 scan-code in ordinary typing) and now remembers the block, if possible, allowing it to be pasted. A deleted line may be recalled as many times as required. A block may be copied to the block buffer, and marked blocks are now shown on screen. Our Saved! desk accessory may be invoked at the press of a key, there is a keyboard shortcut for Save, and the editor will now run in low-resolution. The Assembler Symbols are now significant to the first 127 characters and local labels are supported. The INCBIN directive takes a straight binary file and copies it into the output file, particularly useful for screen data. Speed - include files are read only once, memory permitting, and the binary file is buffered for as long as possible. The absolute maximum speed has over doubled to 75,000 lines per minute though for real programs 35,000 lines is the norm. The output file is also extensively buffered if possible producing spectacular improvements during floppy-to-floppy assemblies in particular. General improvements in symbol table searching and hashing have also increased overall speed. Extended Debug - a HiSoft extended version of the DR symbol table, allowing debugging with up to 22 character significance. Macro calls and Includes may be nested as deeply as memory allows. IFs can be 64K levels deep. TEXT, DATA & BSS segments are properly supported when generating executable code. There is much greater control over output filenames. Multiple Modules & Sections - the GST linker format is more fully supported allowing multiple modules and multiple sections. Externals may be used in expressions, with each other if required. DRI linkable code can now be generated. Optimising can now be performed by the assembler on things such as short branches. Macros now support up to 36 parameters multi- line calls and numeric substitution. The macro buffer is now dynamic, the free space in the editor workspace is no longer used for this. REPEAT loops are now allowed and the exprerssion evaluator now includes comparisons. The REG directive allows symbolic register lists. There are a considerable number of extensions to the OPT directive. Octal numbers are supported. Registers may also be called R0 through R15. A stand-alone assembler is supplied for those who use alternate editors, CLIs or batch files. Compatibility Issues Most source files should assemble with little or no changes. The differences to be careful of are: BSS sections - neither RSBSS or DSBSS are supported, the code should be converted to switch to SECTION BSS then use DS statements. Symbols now default to case- dependent and are significant to the first 127 characters. OPT N for narrow listings has been superseded with the FORMAT directive allowing much greater flexibility and general listing control has been improved. The ORG statement has changed which will effect any programs that use it. HiSoft BASIC users - if creating libraries please note that GenST 2 output is not accepted by BUILDLIBs prior to version 1.4. BRA.W wasn't accepted by version 1, forcing the use of BRA.L - this is, strictly speaking, a 68020 instruction so now generates a warning, BRA.W (and BRA.B) are now accepted. Various minor changes have been made to the parsing of instructions allowing a greater degree of flexibility. If you used (expressions)\W (denoting short-word addressing) within a macro this will be ignored as \W and \L refer to macro parameters and will probably be replaced with nulls. Use instead (expression).W. which is the Motorola standard. The use of \W or \L after register equates used as index registers is no longer required, for example if buf is a register equate then move,b d0,0(a6,buf.l) is now allowed. Register equates are now allowed in MOVEMs. The priority of the equality operator (=) has been changed. The GEM example program has been changed to use a true BSS section and to fix a bug preventing correct operation under GDOS - this and its include file can be found in the OLDGEM folder. Many new example files are supplied including a desk accessory and completely new AES and VDI libraries. The assembler now reports syntactic errors on pass 1 and will not start pass 2 if errors have been found. It now uses GEMDOS character output routines so can be paused with Ctrl-S, resumed with Ctrl-Q and aborted with Ctrl-C. There are several new directives which could potentially clash with macro names in GenST 1 source files. These are: COMMENT, DCB, ELSEIF, ENDR, FORMAT, IIF, INCBIN, OFFSET, OUTPUT, REG, REPT, RSSET, SUBTTL. There are three reserved symbols which could theoretically clash with your own, all starting with two underlines: __LK, __RS and __G2. Debugger MonST supports a great number of new features including multiple windows and, as a result, has a changed user interface. It is strongly recommended that you read the Reference section of the Chapter 4 before trying any serious work with the new version. The main new features are: Multi-window display; Timed screen switching removing flicker; Full expression evaluator including indirection; Supports up to 22 significant characters in symbols; Multi-resolution allows you to debug a low-res program in medium res (or vice versa); Allows the viewing of source files within the debugger; Disassemble to printer with automatic label generation or to a disk file in GenST format; Conditional breakpoints; History Buffer; Interrupt running programs. Both GEM and TOS versions of the debugger are now the same except for the file extension and one one auto-resident version needs to be supplied. Integration Probably the greatest improvement to the package as a whole is the integration between its various parts. The assembler is available at the press of a key from the editor, as it was, but so is the debugger. The assembler can assemble directly into memory, then the code can be run from the editor without any disk accesses. If required debugging information can also be included in assembled-to-memory programs so they can be debugged at the press of a key, directly from the editor. A program assembled to memory is a true GEMDOS task so no code changes are required. Assembly warnings and errors are remembered by the editor and can be stepped through by pressing Alt-J. Errors are no longer lost when the number of lines is changed, though they are not re- calculated. After an assembly which had an error the editor will automatically place the cursor on the line of the first error. Linker This now supports the HiSoft Extended Debug format and is faster than its predecessors. It also allows explicit section ordering and true BSS sections. Note that LinkST only supports the GST format - if you wish to link DRI format code you need to use the Atari ALN or the Digital Research LINK68 linkers.