last change: 27-Sep-92 ******************************** * * * P h x A s s V 2.xx * * * * MC68000 Macro Assembler * * * * Written by Frank Wille * * * ******************************** Preface ======= PhxAss is FREEWARE and © copyright 1992 by Frank Wille. Commercial usage of this program, without a written permission of the author, is strictly forbidden ! Most assemblers which support Sections, XDefs, XRefs, etc. can't be used for assembling programs to absolute addresses or are missing an Incbin directive. Other assemblers (like SEKA) don't support the Amiga-DOS object file format or are missing an Include directive. It was my aim to write an assembler which supports all the important directives like SECTION, XREF, XDEF, INCLUDE, ORG, INCBIN, etc. and which can assemble absolute and relocatable code in the same way. Apart from that the assembler should be able to generate code using the small-code and/or small-data model. PhxAss understands nearly all of the standard assembler directives, making it easy to convert source code from other assemblers. In addition, all directives directives generated by the Aztec-C compiler are processed correctly. This makes it possible to assemble Aztec-C source code with (the faster) PhxAss instead of Manx-AS. Starting PhxAss =============== Start the assembler by entering the command line: PhxAss [<-options>] [<-options>] where [<-options>] specify optional parameters and is the name of the file to be assembled. If no extension in is given, the assembler assumes ".asm" for being the extension. Some options cannot be specified before the file name (see Assembler Options). must be the name of an assembler source code file. The source code must be an ASCII text file where any line ends with a linefeed ($0a) character (the format, which all Amiga editors generate). TAB-codes ($09) are allowed. When the assenbler is running, it can be stopped at any time with CTRL-C. Assembler Options ================= The following assembler options are supported by PhxAss V2.xx : -o Defines the name of the output file. If not specified, PhxAss takes the source code's filename and replaces its extension with ".o" . -d The names of all global labels of each section are written to symbol data blocks. A debugger can use these names instead of addresses. -a Enable auto-align for DC.x directives. All DC.W, DC.L, etc. directives in the code will be automatically aligned to word-boundaries. -s[=value] Predefines a symbol by SET directive. If the value is missing, the symbol will be set to 1. -e[] Generates an equates file. If is missing, the name of the source code with extension ".equ" will be used. Cannot be specified before the name of the source code. -l[] Generates a listing file. If is missing, the name of the source code with extension ".lst" will be used. Cannot be specified before the name of the source code. -x Includes a reference list of all global symbols in the listing file. If no listing file was opened, this option will cause an error. -p[] Sets the page length for equates and listing files. If isn't specified or set to zero, no form. feed ($0c) characters will be generated. The default value is 60 lines. -i[,..] Defines one or more include-paths which will be used by the INCLUDE and INCBIN directives. -h[,..] Defines one or more INCLUDE directives at the top of the source code. -mf Forces the whole code to use the large code and large data model. NEAR directives within the source code will be ignored. -mn[][,] Forces the whole code to use the small data model. or [,S...] (default: 4) specifies the number of the address register which will be used as pointer to the small data section. Only the registers A2-A6 can be used. is the number of the section which will be the small data section (defaults to 0). If a string, starting with a 'S' (f.ex. "SmallData"), is specified instead of the section number, all Data and Bss sections will be treated as a whole small data section. They are coalesced by calling the linker with the small data option. -mc Forces the whole code to use the small code model. All JSR and JMP instructions which are referencing external symbols are converted to BSR and BRA instructions. -n[] Sets the optimize flags. The following characters must appear directly behind the '-n' : n (normal) These are the standard optimizations: clr.l Dn -> moveq #0,Dn movem (one reg.) -> move add/sub #(1-8) -> addq/subq mulu/muls #0,Dn -> moveq #0,Dn move.l #(-128..127) -> moveq Absolute Long -> PC Displace (when possible) z (zero displace) 0(An) -> (An) b (branches) Bcc.L -> Bcc.S s (left shifts) lsl/asl #1/2,Dn -> add Dn,Dn [add Dn,Dn] j (jumps) jmp/jsr -> bra/bsr p (force pea lea) move.l #x,An -> lea x,An move.l #x,-(SP) -> pea x m (mulu/muls/divu) mulu/muls #1,Dn -> swap clr swap / ext.l mulu/muls #2..256,Dn -> .. lsl/asl .. divu #2..256,Dn -> ror swap rol swap x (bset/bclr/bchg) bset #x,Dn -> ori.w #(2^x),Dn (for x = 0..15) bclr #x,Dn -> andi.w #~(2^x),Dn bchg #x,Dn -> eori.w #(2^x),Dn The last two optimize flags (m and x) are 'wild' optimizations. They generate the correct result, but the status flags are 'wrong'. To select all non-wild optimizations, write: -nnzbsjp There are two short cuts: * Selects all non-wild optimizations (-nnzbsjp). ! Allows all optimizations possible (-nnzbsjpmx). -n without parameters will forbid any optimizing. If -n is not specified the assembler uses n,z,b and p. -q Quiet mode. The assembler makes no outputs until an error occurs. Programmer Information ====================== 1. Comments Comments start with a ';' or with a '*'. The text which follows after the operand field is also a comment and doesn't need ';' or '*'. Example: ; Comment text moveq #0,d0 ** This is a comment too ** nop ; comment add.l d0,d0 comment after operand field If no operand field is given, e.g. after the NOP instruction, the comment must be preceded by a ';' or '*'. The example above without a semicolon after the NOP would make the assembler to treat 'comment' as its operand. 2. Labels Labels must start in the first column of a line. The colon at the label's end is optional. Example: Label: moveq #0,d0 Local labels have a '$' suffixed and are only valid between two global labels. Example: Global1: add.w d0,d1 bne.s local$ rts local$: moveq #-1,d0 rts Global2: The length for global and local labels is unlimited. Valid characters for the labels are: 'a'-'z', 'A'-'Z', '0'-'9' and '_' . The first character can be a '.', but global labels cannot start with a digit. 3. Executable M68000 instructions They have the general format: label operation operand PhxAss recognizes all operations found in Motorola's 8-/16-/32-bit Micro- processor User's Manual and all of the common additions and short forms like BHS instead of BCC, BLO instead of BCS, MOVE instead of MOVEA, ADD instead of ADDI, etc. . In the current version only MC68000 instructions are supported. The operand field consists of one or two expressions seperated by a comma with no imbedded spaces. 4. Expressions Expressions consist of symbols and constants. Symbols can be absolute, relocatable or external. The arithmetic operations supported by PhxAss are (from highest to lowest precedence) : ~ not (unary) - negation (unary) << shift left >> shift right * multiplication / division // modulo & and | or ('!' also allowed) ^ exclusive or - subtraction + addition [ ] brackets An important difference to other assemblers is, that no parentheses ( '(',')' ) are allowed in PhxAss expressions. Use brackets ( '[',']' ) instead. For absolute symbols and constants (which are absolute too), all arithmetic operations are allowed. If relocatables or externals occur in the expression, only subtraction and addition is possible with some restrictions: reloc - abs extern - abs reloc - reloc reloc + abs extern + abs abs + reloc abs + extern are defined, the others are illegal. There are five types of constants: Hexadecimal, preceded by a '$', consists of '0'-'9' and 'A'-'F' (or 'a'-'f') Decimal, consists of '0'-'9' Octal, preceded by a '@', consists of '0'-'7' Binary, preceded by a '%', consists of '0' and '1' String, embedded by ' or ", consists of one to four characters. The character '\' is an escape-symbol, which can generate the following codes: \\ the '\'-character itself \' character #39 (single quote) \" character #34 (quote) \0 character #0 (string terminator) \n character #10 (line feed) \f character #12 (formular feed) \b character #8 (backspace) \t character #9 (tabulator) \r character #13 (carriage return) 5. Directives The following paragraphs describe all directives that are supported by the assembler. EQU symbol equ symbol = The expression will be assigned to the symbol. EQU.x symbol equ.x symbol =.x An equate with the extension .d,.f,.p,.s or .x will assign the value of a floating-point expression to the symbol. No arithmetic operations are allowed with floating-point. The expression must be a constant or another floating-point symbol. EQUR symbol equr This directive assigns a register (D0-D7,A0-A7 or SP) to the symbol. REG symbol reg This directive assigns the value of the register list to the symbol. Valid register lists contain several register names (see EQUR) separated by the '/' character. The '-' character defines a range of registers. The following are valid register lists: a1/a3-a5/d0/d2/d4 a2-a6/d0-d7 SET symbol set This directive assigns the value of the expression to the symbol. No relocatables or externals are allowed within the expression. A symbol defined by a SET directive may change its value by another SET. There are some set-symbols which are defined by PhxAss: _PHXASS_ set 1 _VERSION_ set version<<16+revision According to the connected processor and co-processor PhxAss will set _MC68000_, _MC68010_, _MC68020_ and _MC68881_. NARG is zero outside a macro. Within a macro NARG is set to the number of specified arguments. TTL ttl This directive sets the name of the object file unit which the assembler will generate. By default, no name will be set (length 0). LIST The following source code will be written to the listing file. NOLIST The following source code will not be written to the listing file. OPT opt Changes optimization. For a listing of all optimize flags, see Assembler Options. MACRO, ENDM symbol macro ...text... endm macro symbol ...text... endm This directive assigns a macro to the symbol. The symbol may appear on the left or the right side of the directive. The text between the MACRO and ENDM directives will be inserted into the source code when the assembler discovers the symbol. When calling the macro, up to nine arguments, separated by a comma, can be specified in the operand field. They are referenced in the macro text as '\1' through '\9'. '\0' is reserved for the extension of the macro symbol. Example: bhs macro bcc.\0 \1 endm This macro can be called by: bhs.s label ".s" will be assigned to \0 and "label" will be assigned to \1. A "\@" within the macro is replaced by text of the form "nnn", where nnn is a unique three-digit number for each macro call. Labels within a macro should consist of "\@", because defining labels twice is illegal. MEXIT Upon encountering this directive within a macro, the assembler scans for the ENDM directive and leaves the macro. END In pass one the assembler ignores the rest of the source code and starts pass two. In pass two the assembler closes all files and terminates. By default the assembler terminates at end of file. FAIL The assembler displays the error "69 Assembly aborted !" and terminates. ECHO echo The assembler echoes the string. If isn't specified, only a newline is echoed. SECTION section [,[,]] The following code will be placed in the section named . There are three section types: CODE, DATA and BSS. CODE contains the executable M68000 instructions, DATA contains initialized data and BSS contains un- initialized data (set to zero before the program is started). By default is set to CODE. The section will be loaded to the memory indicated by the argument. This can be FAST or CHIP. By default the section will be loaded to the memory with the highest priority. Creating a section lets the assembler change into relocatable mode. In this mode the following directives are illegal: org, load, file, trackdisk CODE, CSEG These directives correspond to: section "CODE",code DATA, DSEG These directives correspond to: section "DATA",data BSS (1) This directive corresponds to: section "BSS",bss BSS (2) bss symbol, BSS with arguments does not start a section. It defines a symbol to be in the BSS-section, reserves bytes in this section and assigns the address of the first byte to the symbol. GLOBAL global symbol, This directive does the same as BSS symbol,. In addition GLOBAL will declare the symbol as XDEF (ext_def). INCLUDE include This directive causes the assembler to suspend the assembly of the current file and to assemble the file named . When done, the assembler continues assembling the original file. If PhxAss can't find the include file, it first searches within the include directory defined by the environment variable PHXASSINC. Then it searches within the include directories defined by the -i assembler option. INCBIN incbin This directive causes the assembler to include a binary file into the current section (f.ex. graphics, samples or trigonometrical tables). The assembler searches in the same include directories like INCLUDE. XREF xref symbol1[,symbol2,...] This directive tells the assembler that the specified symbols are externally defined and will be inserted by the linker. NREF nref symbol1[,symbol2,...] This directive does the same like XREF, but the assembler is forced to use these symbols as small-data relocatables. XDEF xdef symbol1[,symbol2,...] This directive causes the assembler to add the names and values of the specified symbols to the external-block of the object file. The linker can read the values of these symbols and insert them into other object files. PUBLIC public symbol1[,symbol2,...] When the specified symbols are defined in the current code, PUBLIC will do the same like XDEF. When the symbols are unknown, PUBLIC will do the same like XREF. ORG org address Defines the origin of the following code and lets the assembler change into absolute mode. Since V1.8 several ORG directives are allowed and each one can be seen as a new section. The following directives are illegal in absolute mode: ttl, code, cseg, data, dseg, bss, section, xref, nref, xdef, public. LOAD load address After assembly is done, the executable code will be loaded to this address. By default the code will be loaded to the address which was specified as origin. FILE file After assembly is done, the executable code will be written to the file named . TRACKDISK trackdisk ,[,] After assembly is done, the executable code will be written directly to floppy disk using the 'trackdisk.device'. is valid from 0 to 3. is valid from 0 to 1759. , which is zero by default, specifies the byte-offset within a block and is valid from 0 to 511. NEAR near [An[, | SmallData]] This directive initializes the parameters used by the small-data model. NEAR with arguments may appear only once in the whole source code. After initializing the small-data model, it can be switched on and off by NEAR and FAR without arguments. The first argument, the address-register, is valid from A2 to A6 and will be A4 by default. , which defaults to zero, specifies the number of the section which will be accessed by address register indirect with displacement. If is a string starting with 'S' or 's', all Data and Bss sections will be accessed in small-data mode. near code If the argument equals to the string "CODE" the assembler activates the small-code model. FAR This directive turns off the small-data model when active. INITNEAR This directive inserts two M68000 instructions into the code which will initialize the small-data model depending on the parameters set by the NEAR directive. The assembler will generate this code (10 bytes): lea SmallDataBase,An lea 32766(An),An DC label dc.x [,,...] label dc.b "string"[,...] The DC (Define Constant) directive causes one or more fields of memory to be allocated and initialized. Each field has the same size, specified by the extension of the directive. Each byte, word or longword can be an expression and may contain forward references. For floating- point values, only constants are allowed. The following extensions are valid: .B (1 byte) Byte .W (2 bytes) Word .L (4 bytes) Longword .F (4 bytes) Fast Floating Point .S (4 bytes) Single Precision .D (8 bytes) Double Precision .X (12 bytes) Ext. Precision .P (12 bytes) Packed BCD If the extension is .B, .W or .L several values can be expressed by a string, but when using word- or longword-size the string must be aligned. DCB, BLK label dcb.x [,] label blk.x [,] These directives allocate a block of memory having entries. The available entry-sizes are the same like above. The block will be initialized with which is assumed to be zero when missing. DS label ds.x This directive allocates a block of memory having entries and initializes each field with zero. See DCB, BLK. CNOP cnop , This directive aligns the address of the following code to . Then the is added. Example: cnop 2,4 . This example would align the next address two bytes after the next longword boundary. If is greater than two, the optimization for the whole section will be disabled, but since CNOP will be used mainly in data sections it should be no problem, because data cannot be optimized. EVEN This directive equals to cnop 0,2 which will make the address word- aligned. IFcond, ELSE, ENDIF, ENDC These directives support conditional assembly. The general form of the IF directive is: ifcond or symbol ... [else ...] endc (or endif) PhxAss supports the following conditions: IFC "string1","string2" compares two strings. This is useful within macros, when the strings contain macro- arguments '\x' . IFD/IFND symbol Tests if the symbol is defined (undefined). IFEQ/IFNE Tests if is zero (not zero). IFGT/IFLT Tests if is greater (less) than zero. IFGE/IFLE Tests if is greater (less) than or equal to zero. Assembler Errors ================ In the current version of PhxAss the following errors can be generated: 01 Out of memory 02 Only ONE source file can be assembled Example: phxass file1 file2 -> Error 02 03 Listing file option was declared twice 04 Need source file for this option Example: phxass -e srcfile or phxass -l srcfile -> Error 04 phxass srcfile -e -> ok 05 Equates file option was declared twice 06 Need filename after -o option 07 Need filename after -h option 08 Need directory name after -i option 09 Illegal model. Use F for far or N[2-6][,SecNum] for near 10 The near data model accepts only a2-a6 for base register 11 Missing source filename 12 File doesn't exist 13 Missing include filename 14 Read error 15 String buffer overflow Source code lines are limited to 79 characters. 16 Too many sections Maximum is 255 sections. 17 Symbol can't be declared as external XDEF can only be used with absolute or relocatable symbols. 18 Symbol was declared twice 19 Unable to declare XREF-symbol A symbol, which is defined in the current source code, can't be an external. 20 Illegal opcode extension Legal: .b .w .l .s .f .d .x .p 21 Illegal macro parameter Possible parameters are: \0 (opcode extension), \1 - \9 and \@ 22 Illegal characters in label See Labels chapter in Programmer Information. 23 Unknown directive The opcode is whether a 68000-mnemonic nor an assembler directive or macro. 24 Too many parameters for a macro Nine parameters ( \1 to \9 ) are possible. 25 Can't open trackdisk.device 26 Argument buffer overflow Arguments are limited to 79 chracters. 27 Bad register list Valid register lists: d0-d3 d3-d4/a2 d2/d3/a4-a6 a2/a3/a4 d7 a0/d2 28 Missing label This directive requires a label. 29 Illegal seperator for a register list Valid seperators are '-' and '/'. 30 SET, MACRO, XDEF, XREF and PUBLIC are illegal for a local symbol 31 Not a register (try d0-d7 or a0-a7 or sp) 32 More ')'-brackets than '(' 33 Unknown addressing mode for this operation See Motorola' 8-/16-/32-bit Microprocessor User's Manual for a description of all addressing modes. 34 Illegal addressing mode Example: move.b d0,a1 / move usp,d2 / clr.w (d3)+ -> Error 34 35 Can't use macro in operand Macros must be used as opcodes. 36 Undefined symbol 37 Missing register Example: move.w d0, -> Error 37 38 Need data-register 39 Need address-register 40 Word at odd address Example: dc.b "Hallo" dc.w 0 -> Error 40 Insert CNOP 0,2 or EVEN after string-constants. 41 Syntax error in operand 42 Relocatability error Example: move.l label(pc),d0 , where label is not a reloc. and/or label is not defined in the current section -> Error 42 43 Too large distance Example: move.w 50000(a0),d0 -> Error 43 Too large distance for a displacement by indirect addressing or branches. Short branches have a range of +126/-128 bytes. Long branches have a range of +32766/-32768 bytes. 44 Displacement expected Example: label: move.l label(a2),d1 -> Error 44 45 Valid address expected A program-address was expected. 46 Missing argument 47 Need numeric symbol 48 Symbols must be declared in the same section Example: bra label , where label is not defined in the current section -> Error 48 49 Only one distance allowed Expression can't contain several distances. Example: move.l #[label1-label2]+[label3-label4],d0 -> Error 49 50 Missing ']'-bracket 51 Expression stack overflow A maximum of 128 arguments are allowed in one expression. 52 Unable to negate an address 53 Can't use distance and reloc in the same expression 54 Can't shift an address 55 Can't multiply an address 56 Overflow during multiplication 57 Can't divide an address 58 Division by zero 59 No logical operation allowed on addresses 60 Need two addresses to make a distance 61 Unable to sum to addresses 62 Write error 63 Alignment error Example: dc.l "XYZ" -> Error 63 64 Can't subtract a XREF Valid operations with externals: ext + abs , abs + ext and ext - abs 65 Impossible in absolute mode These directive can't be used in absolute mode: ttl, code, cseg, data, dseg, bss, section, xref, nref, xdef, public 66 Unknown error (fatal program failure) The assembler or its memory was corrupted by a faulty program running at the same time. 67 No externals in absolute mode See 65. 68 Out of range Example: addq.l #9,d1 -> Error 68 69 Assembly aborted Generated by the FAIL directive. 70 Missing ENDC/ENDIF 71 Missing macro name 72 Missing ENDM 73 Can't define macro within a macro 74 Unexpected ENDM 75 Unexpected ENDC/ENDIF 76 Impossible in relative mode These directive can't be used in relative mode: org, file, load, trackdisk. 77 Parameter buffer overflow Parameters are limited to 79 characters. 78 Can't open timer.device 79 Unable to create file Maybe the destination disk is write-protected. 80 Need listing file to add references -x option was specified without the -l option. 81 No address allowed here Example: ds.l label -> Error 81 82 Illegal characters in symbol See error 22. 83 Source-code too large (max. 65535 lines) 84 No floating point without mathieeedoubbas.library To use floating point symbols, you must have the mathieeedoubbas.library in your LIBS: directory. 85 IEEE Double Precision Overflow/Underflow 86 IEEE Single Precision Overflow/Underflow 87 Motorola FFP Overflow/Underflow 88 Incompatible float types 89 Packed BCD Overflow/Underflow 90 Can't mix LOAD, FILE and TRACKDISK Example: load $70000 file "mycode" -> Error 90 91 Near mode not activated The near mode must be initialized first, before using the INITNEAR directive. Bugs ==== Known bugs in version V2.04 : Floating-point symbols defined by the EQU directive does not appear in the equates file (but who needs it ?). I cannot guarentee that PhxAss is working with OS 2.0, because I did not have the opportunity to test it with that system. If any errors or questions occur, please write to : Frank Wille Auf dem Dreische 45 D-W-4900 Herford GERMANY