This document explains how to write functions and subroutines in assembly language. It was copied from the version 1.0 User's Guide. We regret that we did not have the resources to write as detailed an article as we did in the case of C subroutines. However, since assembly language programmers are usually highly trained individuals, we are hoping the explanation presented here will be adaquate. We assume you already know how to program in assembly language on the Amiga. If not, here are some suggested references: Motorola M68000 16/32-Bit Microprocessor Programmer's Reference Manual, Prentice-Hall, Englewood Cliffs, NJ 07632 G Kane, 68000 Microprocessor Handbook, Osbornd/McGraw-Hill, 630 Bancroft Way, Berkely, CA 94710 We also assume that you know how to use the Amiga's CLI or SHELL, command line interface. If not, refer to your AmigaDOS documentation. OVERVIEW There are six steps in creating and using a subroutine in assembly. 1 - Write the routine in assembly 2 - Assemble and save it. 3 - Link it. 4 - Run FinalTouch on it. 5 - Add a LIBRARY statement to the True BASIC program that you want to use it. 6 - Call it. ASSEMBLY LANGUAGE DIRECTORY Your True BASIC disk contains a directory named Assembly. It holds a number of sample programs written in assembly language and C. These sample programs are the sources for the AmigaLIB* LIBRARY. The Assembly directory also contains the include file TB.i for use with assembly language routines. It defines the format of arguments passed from True BASIC and the location of an assortment of global data that may be handy to you. Read this include file to see what it contains. EDITING A ROUTINE You can use any editor to create your assembly language routine. Just be sure that it creates plain text. True BASIC itself is a fine editor. ASSEMBLING A ROUTINE Once you have created an assembly routine you must assemble it. This will produce a file that can then be linked. The following file is saved in your Assembly directory as "MyOrd.asm". ; ; ; Sample Assembly Language Routine -- MyOrd ; ; Equivalent to: def MyOrd(s$) = Ord(s$[1:1]) ; move.l (a6),a1 ;pick up ptr to string arg move.l -(a6),a2 ;and ptr to output arg move.l (a1),a1 ;point to string block with a1 moveq #-1,d0 ;integer -1 value (with exp = -1) tst.l (a1)+ ;check string length beq.s 1$ ;if null string, return -1 clr.w d0 ;clear integer part move.b (a1),d0 ;get first byte as an integer 1$ move.l d0,(a2) ;save in output variable rts ;and done The above routine returns the numeric value of the first byte in a string, or a -1 for a null string. To assemble this program , give the following CLI command: assem MyOrd.asm -o MyOrd.o This tells the assembler to take MyOrd.asm as input, and put the resulting object file in a new file "MyOrd.o". Assembler commands can be much more complicated than this. See your AmigaDOS Developer's Manual for more details. LINKING After assembling, you must link your routine. Since MyOrd has no external references, we do not need to give the Linker any libraries to search. Thus: BLink MyOrd.o to MyOrd* Programs with external references will need to be linked with one or more libraries. For instance, the sample assembly language subroutine Cycle would be linked by: BLink Cycle.o LIB :LIB/Amiga.lib to Cycle* USING FINALTOUCH The file "MyOrd*" is almost ready to be used, but it's missing one thing: the compiled file header which tells True BASIC the routine's name, what kind of routine it is, and what kind of arguments it takes. The True BASIC program "FinalTouch" adds this header. When you run FinalTouch, it will ask for the SUB or DEF statement that defines your routine. Just imagine the SUB or DEF line that your program would have if it was written in True BASIC. For MyOrd this would be: DEF MyOrd(s$) You can give the routine name and parameter names in any mixture of upper and lower case. It doesn't matter what names you give for the parameters, but you must correctly indicate their types. * Be sure to get the types right, or True BASIC will abort when you call this routine. FinalTouch then asks for the name of the file containing your linked assembly-language routine. Here you would supply "MyOrd*". It will add the necessary information to this file. CALLING A ROUTINE When FinalTouch is done, you can use the file "MyOrd*" as a LIBRARY of compiled routines. The True BASIC program below uses MyOrd to find the ordinal value of the first byte in a line of input, and prints it on the screen: ! Use the assembly language version of MyOrd. ! LIBRARY "MyOrd*" DECLARE FUNCTION MyOrd DO LINE INPUT S$ LET X = MyOrd(S$) PRINT X LOOP END THE CALLING INTERFACE Your assembly language routine is called via a JSR instruction to the first byte. The registers at call are initialized as follows: A7 is the stack pointer. True BASIC uses only a small, fixed size amount of the task stack. The rest is for you. By default, the task stack is about 4K bytes. You can change this size by clicking on True BASIC and then choosing Info from the Workbench menu. When it presents information about True BASIC, adjust the stack size. From the CLI, use the STACK command. A6 points to pointers to the arguments. Each argument pointer is 32 bits long. The pointer to the first argument lies at 0(A6), the pointer to the second argument lies at -4(A6), the third at -8(A6), and so on. For FUNCTIONS, the returned value is treated as a final parameter. A5 points to a vector of useful global data. This includes such things as Amiga resident library pointers, and a pointer to your program's output window. Definitions for this structure are found in the TB.i file, in the Assembly directory. Your routine receives the pointers A5 and A6. It must then trace down the A6 argument pointer to find its actual True BASIC arguments. When your routine returns to its caller, only A7 need be the same as it was upon entry. You need not restore the values of any other registers. For more information on how the arguments are handed over to your routine from True BASIC, refer to the article describing the design of C subroutines, or contact True BASIC product support.