AmigaDOS Replacement Project V1.1 (REL2) AmigaDOS Replacement Project V1.1 (REL2) ABSTRACT An overview of the new functions and support materials available to programmers using ARP, including a discussion of calling arp.library from the C language. NOTE - THIS V1.1 MANUAL HAS BEEN INCLUDED WITH THE V1.3 ARP PROGRAMMERS SUPPORT RELEASE UNMODIFIED. PLEASE SEE THE FILES IN THE SUBDIRECTORY "NEW_MANUAL" FOR ALL FUNCTIONAL CHANGES FROM THE V1.1 RELEASE! CONTENTS Current Status of ARP................................ 1 1. Changes to old functions............................. 1 1.1 GADS().......................................... 1 1.2 FileRequest()................................... 1 2. New Functions........................................ 2 2.1 Process Control and Resident.................... 2 2.2 Date functions.................................. 3 2.3 Misc functions.................................. 3 3. Language Support..................................... 3 3.1 C Language Support.............................. 4 3.2 Modula II support............................... 7 - i - ARP Prog Manual V1.1 Software (REL2) February 27, 1988 Current Status of ARP This release meets our first goal in producing ARP. It is now possible for users of the Amiga to work in a practically BCPL free environment, allowing programmers to write software free of BCPL headaches. This release of the library (arp.library) introduces what we feel are important advances and standards for the Amiga, including new process control functions and a resident program standard. Old functions have been enhanced, the GADS() argument parser now supports a new template type which allows the user to enter any number of arguments, and the FileRequest() has been very greatly enhanced, it now sports a parent gadget, and provides much more programmer control than previously. It is beautiful. 1. Changes to old functions Only GADS() and FileRequest() received significant enhancements. Both of these are completely compatible with older code. 1.1 GADS() The only change to GADS() is the introduction of a new template type which allows any number of arguments to be placed on the command line. It consists of the usual slash followed by three periods (/...). On return from GADS(), the array element which corresponds to the multiarged type will be a pointer to another array of character pointers ( *(**char)) which contain the actual arguments entered by the user. This array is guranteed to be null terminated. See the GADS manual page for more information. Note that the ugly and limited ",,,," construct is still supported if you are into commas. 1.2 FileRequest() FileRequest has been greatly enhanced and extended in this release. You can now alter FileRequest's window, add or subtract your own gadgets, handle gadget events relating to your own gadgets, and so on. The FileRequester structure has been changed, however old code using the old FileRequester structure will still work as long as you set the old fr_Flags variable to zero as warned. See the FileRequest() manual page and arpbase.[ih] for more information. Page 1 ARP Prog Manual V1.1 Software (REL2) February 27, 1988 2. New Functions Many new functions have been added in this release. Perhaps the most important are the process control functions and the date functions. The date functions support international date formats for both input and output, and were provided by Ken Salmon. 2.1 Process Control and Resident arp.library now has a background process spawner which should eliminate any future need for programs to call Execute(). You can set many options with this function including stdio handles, or you can specify a flag which will create a new interactive environment for the process. Note that this function creates new CLI style processes as its default action, and it may be called from Workbench programs. It also searches the Resident list first, and so may be used to run multiple copies of the same code, and it automatically takes advantage of stack settings using the new ResidentProgramTag. The spawner will not execute BCPL programs. This would have been done if it were reasonably possible to do so, but it was not. However, now that most of the ARP command replacements are done this should not be an issue, since any disk which has arp.library will also have the command replacements. The spawner will return an error code to you, at which point you can inform the user, or attempt to execute the BCPL program using Execute(), and all its attendent problems. The spawner causes processes to automatically clean up after themselves, this includes closing all stdio handles and freeing stack and possibly also data memory, if that was allocated by the startup code, so there is no reason for your program to hang around waiting for child exits, although you can if you wish to. For more information, see the ASyncRun() manual page. 2.1.1 Resident programs This release introduces a method for creating shared text processes on the Amiga. The code for these processes in the past has had to be reentrant, and that is still the simplest case. ARP provides a method for specifying that a separate data segment should be allocated if your program is resident, and you can then copy the data to the new data segment, and use that, thus preserving a clean slate for the next execution. The compiler startup code is responsible for initializing the data segment. This was done to keep the support routines as general as possible, the actual data copying is extremely short, as a Page 2 ARP Prog Manual V1.1 Software (REL2) February 27, 1988 look at the arprescrt0.s source will demonstrate. Users now have a program to install processes as Resident as well as a program to execute these processes. Hopefully more people will take advantage of the new resident standard and write more of this low overhead software. For more informtion, see the manual page for Resident in the users manual, and the AddResidentPrg() and LoadPrg() etc., functions in the programmers manual. 2.2 Date functions These date functions provide a method for converting between AmigaDOS datestamps and strings and vice-versa. These functions provide a wide variety of international date format input and output conversions. You must specify the conversion you want. The ARP standard has been to accept the value of the dateformat environment variable as set by users. If this is undefined, default to the current AmigaDOS convention. You must check this variable yourself, the StrtoStamp() and StamptoStr() functions will not do this for you. For more information see the manual pages for these two functions, as well as the DateTime struct in arpbase.[ih]. 2.3 Misc functions The following utility functions have been added in V34: - PreParse() - prepare a string for PatternMatch() - LMult(), LDiv(), LMod() - LONG multiply divide and modulus routines. - TackON() - add a filename to a pathname. - BaseName() - return a pointer to the BaseName of a PathName. 3. Language Support Support is provided in the form of header files and linkable libraries or pragma files for Aztec C, Lattice C TDI Modula II, and of course assembler. Page 3 ARP Prog Manual V1.1 Software (REL2) February 27, 1988 3.1 C Language Support Startup code which automatically opens arp.library and initializes IntuitionBase and GfxBase as well as ArpBase is provided for both Lattice and Manx. We have attempted to keep filename conventions and header file proliferations to a minimum, and have succeeded pretty well so far, so the discussion which follows applies pretty well to both compilers. Differences are noted where they are significant. The general goals have been to minimize the overall impact on the compiler user, and to make the code we supply assemble/compile with the usual tools provided by each manufacturer. So, for example, the Manx code still uses the two functions cli_parse() and wb_parse() to do pretty much the same things as they did before, while Lattice code remains in _main(). Each compilers workbench interface is unchanged, and the normal default CLI command line processing should appear the same or very similar. The differences are mostly in the use of GADS() to do CLI parsing, and in the use of the ARP tracking functions to allocate memory, although we also provide some resident support code that provides very extended capabilities. 3.1.1 How to linkup with ARP The easiest way to link up with arp is to use the arp 'wrapper' which we supply for both Lattice and Manx compilers. This code opens arp.library, and initializes GfxBase and IntuitionBase as valid pointers from the values in ArpBase. To use this ARP wrapper, simply link with arp.lib (Lattice users should also use the arpc.o instead of the usual c.o as the first module in their blink command lines), and then with your compiler libraries. Here are sample link lines for Manx and Lattice: ln program.o -larp -lc blink arpc.o prog.o to prog lib arp.lib lc.lib amiga.lib If you prefer to use the OpenLibrary() call, then instead of the above command lines, simply include the library file a.lib in your usual link command line. 3.1.2 GADS The use of GADS() to handle the program arguments from the CLI command line introduces some differences. argc will be the number of arguments actually entered, and argv[0] will be the program name, as usual, but the actual arguments may or may not be in successive array positions in argv, and the actual element in the argv array may be a boolean value (if a /S was used), a pointer to character (as usual) or itself the base of another argv style array (if the new /... template type is used). (The Page 4 ARP Prog Manual V1.1 Software (REL2) February 27, 1988 default template, which consists simply of a series of commas, does provide for standard C processing of command line arguments.) To supply your own template, set the global variable CLI_Template to point to the string containing your template. You can provide an extended help message by setting the global variable CLI_Help to what you wish to display if the user asks for more help: char *CLI_Template = "FROM/A,TO,OPT/K"; char *CLI_Help = "This is an extra help string"; See the GADS manual page and some of the short example programs in the demos directory. Note that you will not get error returns from GADS() using the default startup code, the startup code handles those on its own, displaying the GADS() error message and aborting the program. 3.1.3 Exiting under ARP It is *not* recommended that you call the ArpExit() function from C, this could possibly bypass allocations that your compiler library has made on your behalf, and cause problems with open files or unreleased memory. The recommended way to exit from a program using ARP, whether or not you are using the supplied startup code, is to use exit() or to simply fall off the end of the world. If you are not using the arp startup code you should first CloseLibrary(ArpBase), if you are using the arp startup code you should not CloseLibrary(ArpBase). 3.1.4 Availabilty of source All the source code to the startup code is provided, so you can see exactly what it does and modify it should you need to. In each case it was assembled using the native tools supplied by the manufacturer. 3.1.5 Creating shared text (resident) programs in C At the time this is written we still have not been able to succesfully assemble resident startup code for Lattice. This appears to be a limitation of the lattice supplied asm. The lattice compiler is very capable of taking advantage of this, and lattice has been very helpful, but we still do not have the support for resident code and Lattice. Manx users can take advantage of the shared code and stack setting capabilities of the resident code standard as follows. - 1) Use the +b option to the C compiler for all the modules in the program. Page 5 ARP Prog Manual V1.1 Software (REL2) February 27, 1988 - 2) You must use the rstart.o or rstart32.o as the first module in your linker command line, and you should also link with res.lib or res32.lib. The default stack has been set to 10240 for the rstart modules. If this is too high or too low, you can change the arprescrt0.s file and reassemble. Manx has promised support for the ARP resident standard with their 4.0 release, but currently the only way to set the stack is to reassemble. 3.1.5.1 Programming using Resident You do not have to write re-entrant code using the ARP resident standard. arp.library and the startup code cooperate to make copies of your data and bss segments, so you may feel free to alter static global data without being concerned about not being able to be resident. The only problems that you are likely to have involve pre-compiled references from data to data, and only if these are not read-only. As an example, consider the following: BYTE buffer1[100]; BYTE buffer2[100]; struct b { BYTE *b1, *b2; }; struct b example = { &buffer[0], &buffer[1] }; In the above example, the references to buffer[0] and buffer[1] in struct b are a reference from data (the struct b data) back to other data (the buffer data). When these data references are cloned by the resident startup code, they will still refer to the same memory location, they are not relocated. That means that any writes to buffer[0] or buffer[1] using the addresses stored in the structure will change the original copy of the data, and therefore result in a checksum error being reported the next time the resident program is run. The solution to this is to perform run-time initialization of data such as this. Note that this applies only to data that is going to be written. Data which is not altered is data you don't have to worry about at all. The most likely candidates for run-time initialization in Amiga programs are MenuItem structures and Menu structures. I have my own version of the MicroEmacs that has been floating Page 6 ARP Prog Manual V1.1 Software (REL2) February 27, 1988 around which uses Amiga windows and menus, and is not at all careful about altering static data. I converted this to run resident using only four loops (one for each menu) in about a half an hour. Now each invocation of the Editor uses only 4000 bytes of stack (instead of the 20000 I use at the CLI), and it uses no more memory for its code, either in a ramdisk or in memory. Since the actual program is 35,644 bytes, I save about 50,000 bytes each time the program is invoked. Not bad for a half an hours work. You can tell if you are running as a resident launched program if you examine the global long __fromdisk__. This variable will be non-zero (-1) when you are not resident. 3.2 Modula II support We have not yet received a Modula II support package from anyone. No one directly involved with ARP speaks Modula II, so we are dependent on contributors for support for this language. The MII support materials we do provide are from the first release, and cover only the first release functions. These were contributed by Martin Taillefer. Page 7