Applied patches from ggn for bugs #38, 40, & 41. Thanks!
authorShamus Hammons <jlhamm@acm.org>
Wed, 7 Oct 2015 02:09:15 +0000 (21:09 -0500)
committerShamus Hammons <jlhamm@acm.org>
Wed, 7 Oct 2015 02:09:15 +0000 (21:09 -0500)
madmac2.txt [new file with mode: 0644]
mark.c
object.c
rmac.c
token.c
version.h

diff --git a/madmac2.txt b/madmac2.txt
new file mode 100644 (file)
index 0000000..e9269d9
--- /dev/null
@@ -0,0 +1,2103 @@
+                                                                                ATARI
+MADMAC
+68000 Macro Assembler
+Reference Manual       
+                                                                                  version 1.00
+\f
+MADMAC Version 1.07 release notes, January, 1990.
+
+
+Using .cargs used to cause subsequent global symbols to disappear from 
+the symbol table. Now it doesn't.
+
+
+A movem instruction with no register list (i.e. "movem.l (sp)+,") 
+assembled without error; it now reports "missing regsiter list."
+
+
+
+
+
+
+
+
+
+
+
+
+MADMAC Version 1.05 release notes, August, 1988.
+
+
+This version of MadMac replaces version 1.00 and fixes some small bugs:
+
+
+      Symbols beginning with a capital L were not included in the 
+object file output. They should have been (and now are) excluded only 
+in AS68 compatibility mode, to avoid cluttering the output with 
+
+compiler-generated symbols.
+
+
+      Forward branches declared "short" (such as bras, dbra.s, bsr.$) 
+but whose targets were too far away did not cause an assembly-time 
+error; incorrect machine code was silently generated. They now cause 
+assembly-time errors.
+
+
+      Symbols appeared in the object file symbol table in the order •
+they were referenced in the source, not the order they were declared. 
+Now the order more nearly matches the order of declaration (but not 
+perfectly).
+
+
+      The disp(And(n.$) addressing mode produced correct machine code, 
+but incorrect output in the listing file. Now the output is correct.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+\f
+NOTE: Every effort has been made to ensure the accuracy and robustness of this 
+manual and the associated software. However, because Atari Corporation is con- 
+stantly improving and updating its computer software, it is unable to guarantee  
+the accuracy of printed or duplicated material after the date of publication and
+disclaims liability for changes, errors or omissions.
+
+
+
+
+
+
+
+
+
+
+
+
+ATARI, the Atari logo, MEGA, and ST are trademarks or registered trademarks of 
+Atari Corporation.
+Mark Williams is a trademark of Mark Williams Company.
+Motorola is a trademark of Motorola Inc.
+
+
+
+
+
+
+
+
+
+
+
+Copyright ® 1986, 1987, Atari Corporation 
+All rights reserved.
+
+Reproduction of this document or the associated software is not allowed without  
+the specific written consent of Atari Corporation.
+
+Printed in USA.
+
+Atari Document number C300341-001 Rev. A.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+\f
+                                           Contents
+
+
+
+
+
+
+
+
+Introduction .    .                                                   2
+    Getting Started .                                                 2
+The Command Line                                                      4
+Using MADMAC . .                                                      7
+    Example Command Lines                                             7
+    Interactive Mode .                                                7
+    Things You Should Be Aware Of .                                   8
+    Forward Branches    .                                             8
+    Notes for AS68 users  .   .                                       9
+    Notes for Mark Williams C Users .   .   .   .   .                 9
+    Using MADMAC as a Back-End to the Alcyon C Compiler           .  10
+    Text File Format .                                               10
+Source Format     .                                               .  11
+    Statements .                                                     11
+    Equates   .                                                   .  11
+    Symbols and Scope                                                11
+    Keywords .                                                    .  12
+    Constants                                                        13
+    Strings   .                                                   .  13
+    Register Lists                                                   13
+Expressions .     .                                               .  15
+    Order of Evaluation                                              15
+    Types .                                                       .  15
+    Unary Operators .                                                16
+    Binary Operators                                              .  16
+    Special Forms   .                                                16
+    Example Expressions                                           .  17
+Directives .    .                                                    18
+88000 Mnemonics                                                   .  22
+Macros .        .                                                    24
+    Macro Declaration .                                           .  24
+    Parameter Substitution                                           24
+    Macro Invocation  .                                           .  25
+    Example Macros .                                                 26
+    Repeat Blocks .                                               .  27
+6502 Support .      .   .                                            28
+    6502 Addressing Modes .                                       .  28
+    6502 Directives .   .                                            28
+    6502 Object Code Format                                       .  29
+Error Messages                                                       30
+
+
+
+
+
+
+                                              MADMAC Reference Manual 1
+\f
+              Introduction
+
+
+
+
+
+
+
+
+             Introduction
+             This document describes MADMAC, a fast macro assembler for the 68000. MAD- 
+             MAC currently runs on the Atari ST and under 4.2 BSD VAX UNIX. It was written 
+             at Atari Corporation by programmers who needed a high performance assembler 
+             for their work.
+                MADMAC is intended to be used by programmers who write mostly in as- 
+             sembly language. It was not originally a back-end to a C compiler, therefore it 
+             has creature comfort that are usually neglected in such back-end assemblers. It 
+             supports include files, macros, symbols with limited scope, some limited control 
+             structures, and other features. MADMAC is also blindingly fast, another feature 
+             often sadly and obviously missing in today's assemblers.1
+                MADMAC is not entirely compatible with the AS68 assembler provided with 
+             the original Atari ST Developer's Kit, but most changes are minor and a few minutes 
+             with an editor should allow you to assemble your current source files. If you are an 
+             AS68 user, before you leap into the unknown please read the section on Notes for 
+             AS68 Users.
+                This manual was typeset with TEX and the Computer Modern fonts, and it 
+             was printed on the Atari SLM-804 laser printer with a MEGA ST. Except for 200 
+             lines of assembly language, the assembler is written entirely in C.
+             Getting Started
+              =>Write protect your distribution disk and make a backup of it now. Put the
+                original disk in a safe place.
+              o The distribution disk contains a file called README that you should read.
+                This file contains important nays about the contents of the distribution disk 
+                and summarizes the most recent changes to the tools.
+              o Hard disk users can simply copy the executable files to their work or binary 
+                directories. People with floppy disks can copy the executables to ramdisks, 
+                install the assembler with the -q option, or even work right off of the floppies.
+              o You will need an editor that can produce "normal" format text files. Micro 
+                Emacs will work well, as will most other commercial program editors, but not 
+                most word processors (such as First Word or Microsoft Write).
+              o You will probably want to examine or get a listing of the file "ATARI.S". It 
+                contains lots of definitions for the Atari ST, including BIOS variables, most 
+                BIOS, XBIOS and GEMDOS traps, and line-A equates. We (or you) could 
+                split the file up into pieces (a file for line-A equates, a file for hardware and
+
+              1 It processes 30,000 lines a minute on a lightly loaded VAX 11/780; maybe 
+             40,000 on a 520-ST with an SH-204 hard disk. Yet it could be sped up even more 
+             with some effort and without resorting to assembly language; C doesn't have to be 
+             slow!
+
+             2 MADMAC Reference Manual
+\f
+                                                       Introduction
+
+                BIOS variables and so on), but MADMAC is so fast that it doesn't matter 
+                much.
+              o Read the rest of the manual, especially the first two chapters on The Com-
+                mand Line and Using MADMAC. The distribution disk contains example 
+                programs that you can look at, assemble and modify.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                                                                                  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                                         MADMAC Reference Manual 3 
+                                                                                 
+\f
+                     The Command Line
+
+
+
+
+
+
+
+
+
+                     The assembler is called "mac.prg". The command line takes the form:
+
+                                               mac [switches] [files ...]
+
+                     A command line consists of any number of switches followed by the names of files 
+                     to assemble. A switch is specified with a dash (-) followed immediately by a key 
+                     character. Key characters are not case-sensitive, so "-d" is the same as "-D". Some 
+                     switches accept (or require) arguments to immediately follow the key character, 
+                     with no spaces in between.
+                         Switch order is important. Command lines are processed from left to right in 
+                     one pass, and switches usually take effect when they are encountered. In general it 
+                     is best to specify all switches before the names of any input files.
+                         If the command line is entirely empty then MADMAC prints a copyright mes- 
+                     sage and enters an "interactive" mode, prompting for successive command lines 
+                     with a star (*). An empty command line will exit (See the examples in the chapter 
+                     on Using MADMAC). After each assembly in interactive mode, the assembler 
+                     will print a summary of the amount of memory used, the amount of memory left, 
+                     the number of lines processed, and the number of seconds the assembly took.
+
+                         Input files are assumed to have the extension ".s"; if a filename has no extension 
+                     (i.e. no dot) then ".s" will be appended to it. More than one source filename may be 
+                     specified: the files are assembled into one object file, as if they were concatenated. 
+                         MADMAC normally produces object code in "file.o" if "file.s" is the first 
+                     input filename. If the first input file is a special character device, the output name 
+                     is noname.o. The -o switch (see below) can be used change the output file name.
+
+
+                         Switch           Description
+                         -dname[=value] Define symbol, with optional value.
+                         -e[file[.err]] Direct error messages to the specified file.
+                         -fm              Produce Mark Williams format object file.
+                         -fmu             Like "-fm" , but move underscores to end of symbol names.
+                         -ipath           Set include-file directory search path.
+                         -l[file[prn]]  Construct and direct assembly listing to the specified file.
+                         -ofile[.o]     Direct object code output to the specified file.
+                         -p               Produce an executable (.prg) output file.
+                         -ps              Produce an executable (.prg) output file with symbols.
+                         -q               Make MADMAC resident in memory (Atari ST only).
+                         -s               Warn about unoptimized long branches.
+                         -u               Assume that all undefined symbols are external.
+                         -v               Verbose mode (print running dialogue).
+                         -yn              Set listing page size to n lines.
+                         -6               "Back end" mode for Alcyon C68.
+                         file[s]        Assemble the specified file.
+
+
+                    4 MADMAC Reference Manual
+\f
+                       The Command Line
+
+ The switches are described below. A summary of all the switches is given in 
+the table.
+-d
+ The -d switch permits symbols to be defined on the command line. The name 
+ of the symbol to be defined immediately follows the switch (no spaces). The 
+ symbol name may optionally be followed by an equals sign (=) and a decimal 
+ number. If no value is specified the symbol's value is zero. The symbol at- 
+ tributes are "defined, not referenced, and absolute". This switch is most useful 
+ for enabling conditionally-assembled debugging code on the command line; for 
+ example:
+      -dDEBUG -dLoopCount=999 -dDebugLevel=55
+-e
+ The -e switch causes MADMAC to send error messages to a file, instead of the 
+ console. If a filename immediately follows the switch character, error messages 
+ are written to the specified file. If no filename is specified, a file is created with 
+ the default extension ".err" and with the root name taken from the first input 
+ file name (e.g. error messages are written to "file.err" if "file" or "file.s" is 
+ the first input file name). If no errors are encountered, then no error listing 
+ file is created. Beware! If an assembly produces no errors, any error file from 
+ a previous assembly is not removed.
+-fm
+-fmu
+ The -fm and -fmu switches cause MADMAC to generate Mark Williams style 
+ object files instead of Alcyon object files. These files may be linked with the 
+ Mark Williams linker. The -fmu switch causes underscores on the first char- 
+ acter of a global symbol name to be moved to the end of the name, as per the 
+ Mark Williams C compiler naming convention. That is, "_main" will become 
+ "main_" and "__main" will become "_main_".
+
+ The -i switch allows automatic directory searching for include files. A list of 
+ semi-colon seperated directory search paths may be mentioned immediately 
+ following the switch (with no spaces anywhere). For example:
+         -im:;c:include;c:include\sys
+ will cause the assembler to search the current directory of device M, and the 
+ directories include and include\sys on drive C. If -1 is not specified, and the 
+ enviroment variable "MACPATH" exists, its value is used in the same manner. 
+ For example, users of the Mark Williams shell could put the following line in 
+ their profile script to achieve the same result as the -i example above:
+      setenv MACPATH="m:;c:include;c:include\sys"
+-l
+ The -l switch causes MADMAC to generate an assembly listing file. If a file- 
+ name immediately follows the switch character, the listing is written to the 
+ specified file. If no filename is specified, then a listing file is created with the 
+ default extension ".prn" and with the root name taken from the first input file 
+ name (e.g. the listing is written to "file.prn" if "file" or "file.s" is the first 
+ input file name).
+-o
+ The -o switch causes MADMAC to write object code on the specified file. No 
+ default extension is applied to the filename. For historical reasons the filename 
+ can also be seperated from the switch with a space (e.g. "-o file").
+
+                   MADMAC Reference Manual 5 
+
+\f
+           The Command Line
+
+
+
+           -p
+           -ps
+             The -p and -ps switches cause MADMAC to produce an Atari ST executable 
+             file with the default extension of ".prg". If there are any external references 
+             at the end of the assembly, an error message is emitted and no executable file 
+             is generated. The -p switch does not write symbols to the executable file. The 
+             -ps switch includes symbols (Alcyon format) in the executable file.
+
+
+           -q
+             The -q switch is aimed primarily at users of floppy-disk-only systems. It causes
+             MADMAC to install itself in memory, like a RAMdisk. Then the program 
+             m.prg (which is very short - less than a sector) can be used instead of 
+             mac.prg, which can take ten or twelve seconds to load.
+
+           -s
+             The -s switch causes MADMAC to generate a list of unoptimized forward 
+             branches as warning messages. This is used to point out branches that could 
+             have been short (e.g. "bra" could be "bra.s").
+
+           -u
+             The -u switch takes effect at the end of the assembly. It forces all referenced 
+             and undefined symbols to be global, exactly as if they had been made global 
+             with a .extern or .globl directive. This can be used if you have a lot of 
+             external symbols, and you don't feel like declaring them all external.
+
+           -v
+             The -v switch turns on a "verbose" mode in which MADMAC prints out (for 
+             example) the names of the files it is currently processing. Verbose mode is 
+             automatically entered when MADMAC prompts for input with a star.
+
+
+           -y
+             The -y switch, followed immediately by a decimal number (with no intervening 
+             space), sets the number of lines in a page. MADMAC will produce N lines 
+             before emitting a form-feed. If N is missing or less than 10 an error message is
+             generated.
+
+           -6
+             The -6 switch takes effect when it is mentioned. It allows MADMAC to be 
+             used as a back end to the Alcyon C compiler.1 Note: the assembler will 
+             produce code that is typically ten percent larger and ten percent slower than 
+             the output of the Alcyon assembler, therefore use of this switch for production 
+             code is discouraged.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+           1 The -6 switch is not a compatibility mode for AS68 - it has been carefully 
+           tailored to accept the output of the Alcyon C compiler.
+
+
+           6 MADMAC Reference Manual
+\f
+               Using MADMAC
+
+
+
+
+
+
+
+   Let's assemble and link some example programs. These programs are included 
+on the distribution disk in the "EXAMPLES" directory - you should copy them to 
+your work area before continuing. In the following examples we adopt the conven- 
+tions that the shell prompt is a percent sign (%) and that your input (the stuff you 
+type) is presented in bold face.
+   If you have been reading carefully, you know that MADMAC can generate 
+an executable file without linking. This is useful for making small, stand alone 
+programs that don't require externals or library routines. For example, the following 
+two commands:
+      % mac examples
+      % aln -s example.s
+could be replaced by the single command:
+      % mac -ps example.s
+since you don't need the linker for stand-alone object files.
+   Successive source files named in the command line are are concatenated, as in 
+this example, which assembles three files into a single executable, as if they were 
+one big file:
+      % mac -p bugs shift images
+Of course you can get the same effect by using the .include directive, but sometimes 
+it is convenient to do the concatenation from the command line.
+   Here we have an unbelievably complex command line:
+      % mac -lzorf -y95 -o tmp -ehack -Ddebug=123 -ps example
+This produces a listing on the file called "zorf.pni" with 95 lines per page, writes 
+the executable code (with symbols) to a file called "tmp.prg," writes an error list- 
+ing to the file "hack.err," specifies an include-file path that includes the current 
+directory on the drive "K:," defines the symbol "debug" to have the value 123, and 
+assembles the file "example.s". (Take a deep breath - you got all that?)
+   One last thing. If there are any assembly errors, MADMAC will terminate 
+with an exit code of 1. If the assembly succeeds (no errors, although there may be 
+warnings) the exit code will be 0. This is primarily for use with "make" utilities.
+
+Interactive Mode
+If you invoke MADMAC with an empty command line it will print a copyright 
+message and prompt you for more commands with a star (*). This is useful if you 
+are used to working directly from the desktop, or if you want to assemble several files 
+in succession without having to reload the assembler from disk for each assembly.
+   In interactive mode, the assembler is also in verbose mode (just as if you had 
+specified -v on each command line):
+
+                                                              MADMAC Reference Manual 7 
+
+\f
+             Using MADMAC
+
+                  %. mac
+
+                  MADMAC Atari Macro Assembler
+                  Copyright 1987 Atari Corporation 
+                  Beta version 0.12 Jun 1987 lmd
+
+                  * -ps example
+                  [Including: example.s] 
+                  [Including: atari.s] 
+                  [Leaving: atari.s] 
+                  [Leaving; example. a]
+                  [Writing executable tile: example.prg
+                  36K used, 3868K left, 850 lines, 2.0 seconds
+                  *
+
+             You can see that the assembler gave a "blow-by-blow" account of the files it pro- 
+             cessed, as well as a summary of the assembly's memory usage, the number of lines 
+             processed (including macro and repeat-block expansion), and how long the assembly 
+             took
+                The assembler prompts for another command with the star. At this point you 
+             can either type a new command line for the assembler to process, or you can exit 
+             by typing control-C or an empty line.
+
+             Things You Should Be Aware Of
+             MADMAC is a one pass assembler. This means that it gets all of its work done by 
+             reading each source file exactly once and then "back-patching" to fix up forward 
+             references. This one-pass nature is usually transparent to the programmer, with 
+             the following important exceptions:-
+              o in listings, the object code for forward references is not shown. Instead, lower- 
+                case "xx"s are displayed for each undefined byte, as in the following example:
+                  60xx   1: bra.s.2  ;forward branch
+                  xxxxxxxx  dc.l .2  ;forward reference
+                  60FE  .2: bra.s.2  ;backward reference
+
+              o Forward branches (including BSRs) are never optimized to their short forms. 
+                To get a short forward branch it is necessary to explicitly use the ".s" suffix in 
+                the source code.
+              o Error messages may appear at the end of the assembly, refering to earlier source 
+                lines that contained undefined symbols.
+              o All object code generated must fit in memory. Running out of memory is a 
+                fatal error that you must deal with by splitting up your source files, re-sizing 
+                or eliminating memory-using programs such as ramdisks and desk accessories, 
+                or buying more RAM.
+
+             Forward Branches
+             MADMAC does not optimize forward branches for you, but it will tell you about 
+             them if you use the -s (short branch) option:
+                  % mac -s example.s
+                  "example.s", line 20: warning: unoptimized short branch
+             With the -e option you can redirect the error output to a file, and determine by 
+             hand (or editor macros) which forward branches are safe to explicitly declare short.
+
+           8 MADMAC Reference Manual
+
+\f
+                                                                  Using MADMAC
+Notes for AS68 Users
+MADMAC is not entirely compatible with the Alcyon assembler, AS68. This section 
+outlines the major differences. In practice, we have found that very few changes are 
+necessary to make AS68 source code assemble.
+  o A semicolon (;) must be used to introduce a comment, except that a star (*) 
+    may be used in the first column. AS68 treated anything following the operand 
+    field, preceeded by whitespace, as a comment. (MADMAC treats a star that 
+    is not in column 1 as a multiplication operator).
+  o Labels require colons (even labels that begin in column 1).
+  o Conditional assembly directives are called if, else and endif. AS68 called these 
+    ifne, ifeq (etc.), and endc.
+  o The tilde (~) character is an operator, and back-quote (`) is an illegal character. 
+    AS68 permitted the tilde and back-quote characters in symbols.
+  o There are no equivalents to AS68's org or section directives. AS68's page 
+    directive has become eject. The AS68 .xdef and .xref directives are not imple- 
+    mented, but .globl makes these unnecessary anyway. The directives .comline, 
+    mask2, idnt and opt, which were unimplemented and ignored in AS68, are 
+    not legal in MADMAC.
+  o The location counter cannot be manipulated with a statement of the form: 
+                                  * = expression
+  o The ds directive is not permitted in the text or data segments (except in -6 
+    mode); an error message is issued. Use dcb instead to reserve large blocks of 
+    initialized storage.
+  o Back-slashes in strings are "electric" characters that are used to escape C-like 
+    character codes. Watch out for GEMDOS path names in ASCII constants -
+    you will have to convert them to double-backslashes.
+
+Notes for Mark Williams C Users
+MADMAC will generate object code that the Mark Williams C linker, ld, will 
+accept. This has been tested only with version 2.0 of the Mark Williams package. 
+Some notable differences between MADMAC and the Mark Williams assembler, as, 
+are:
+  o MWC permits 16-character symbol names in the object file, and MADMAC 
+    supports this;
+  o MWC object files can contain more code and data sections than the MADMAC 
+    (Alcyon) object code format. MADMAC maps its code sections as follows:
+                MWC Space                        MADMAC Space
+                shui (shared instruction)        text
+                prvi (private instruction)       unsupported 
+                bssi (uninitialized instruction) unsupported 
+                shrd (shared data)               data
+                prvd (private data)              unsupported 
+                bssd (uninitialized data)        bss
+                debug information                unsupported 
+                symbols                          symbols
+                absolute                         abs, equates, etc.
+
+                                                      MADMAC Reference Man real 9
+
+
+\f
+                 Using MADMAC
+
+                    It is not possible for MADMAC to generate code in the Mark Williams private 
+                    instruction, private data or uninitialized instruction spaces.
+                  o None of the Mark Williams assembler directives (e.g. ".long" and ". odd") are 
+                    supported. None of the MWC non-standard addressing modes are supported.
+                  o The Mark Williams debugger, db, does not support the Alcyon-format symbols 
+                    produced with the -ps switch; it complains about the format of the executable 
+                    file and aborts.
+                  o MADMAC does not support the method by which the Mark Williams shell 
+                    passes long command lines to programs. Command lines are truncated to 127 
+                    characters.
+
+                 Using MADMAC as a Back-End to the Alcyon C Compiler
+                 MADMAC can be used in place of the AS68 assembler as a back-end for the Alcyon 
+                 version 4.14 C compiler. The "-6" switch turns on a mode that warps and perverts 
+                 MADMAC's ordinary syntax into accepting what the Alcyon compiler dishes out. 
+                 This can be used in a batch file (for instance) with a line that looks like:
+                       mac -6 -o %1.o m:%1
+                 (Assuming that device "M:" is where the source was put by compiler phase c168). 
+                 You should be aware that AS68 generally produces better and faster code than 
+                 MADMAC, although it is slower to assemble.
+
+                 Text File Format
+                 For those using editors other than the "Emacs" style ones (Micro-Emacs, Mince, 
+                 etc.) this section documents the source file format that MADMAC expects.
+                  o Files must contain characters with ASCII values less than 128; it is not per- 
+                    missable to have characters with their high bits set unless those characters are 
+                    contained in strings (i.e. between single or double quotes) or in comments.
+                  o Lines of text are terminated with carriage-return/line-feed, linefeed alone, or 
+                    carriage-return alone.
+                  o The file is assumed to end with the last terminated line. If there is text beyond 
+                    the last line terminator (e.g. control-Z) it is ignored.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+             10 MADMAC Reference Manual
+
+\f
+                    Source Format
+
+
+
+
+
+
+
+Statements
+A statement may contain up to four fields which are identified by order of ap- 
+pearance and terminating characters. The general form of an assembler statement 
+is:
+      label: operator operand(s)  ; comment
+   The label and comment fields are optional. An operand field may not appear 
+without an operator field. Operands are seperated with commas. Blank lines are 
+legal. If the first character on a line is an asterisk (*) or semicolon (;) then the 
+entire line is a comment. A semicolon anywhere on the line (except in a string) 
+begins a comment field which extends to the end of the line.
+   The label, if it appears, must be terminated with a single or double colon. If 
+it is terminated with a double colon it is automatically declared global. It is illegal 
+to declare a confined symbol global (see: Symbols and Scope).
+Equates
+A statement may also take one of these special forms:
+      symbol equ expression 
+      symbol = expression 
+      symbol -- expression 
+      symbol set expression 
+      symbol reg register list
+   The first two forms are identical; they equate the symbol to the value of an 
+expression, which must be defined (no forward references). The third form, double- 
+equals (==), is just like an equate except that it also makes the symbol global. (As 
+with labels, it is illegal to make a confined equate global.) The fourth form allows 
+a symbol to be set to a value any number of times, like a variable. The last form 
+equates the symbol to a 16-bit register mask specified by a register list. It is possible 
+to equate confined symbols (see: Symbols and Scope). For example:
+      cr    equ    13          carriage-return
+      if    =      10          line-feed
+      DEBUG ==     1           global debug flag
+      count set    0           variable
+      count set    count + 1   increment variable
+      .rags reg    d3-d7/a3-a6 register list
+      .cr          13          confined equate
+Symbols and Scope
+Symbols may start with an uppercase or lowercase letter (A-Z a-z), an underscore 
+(_), a question mark (7) or a period ( ). Each remaining character may be an 
+upper or lowercase letter, a digit (0-9), an underscore, a dollar sign ($), or a ques- 
+tion mark. (Periods can only begin a symbol, they cannot appear as a symbol
+
+                                   MADMAC Reference Manual 11
+
+\f
+                 Source Format
+
+                 continuation character). Symbols are terminated with a character that is not a 
+                 symbol continuation character (e.g. a period or comma, whitespace, etc.). Case is 
+                 significant for user-defined symbols, but not for 68000 mnemonics, assembler direc- 
+                 tives and register names. Symbols are limited to 100 characters. When symbols 
+                 are written to the object file they are silently truncated to eight (or sixteen) char- 
+                 acters (depending on the object file format) with no check for (or warnings about) 
+                 collisions.
+                    For example, all of the following symbols are legal and unique: 
+                       reallyLougSymbolliame .reallyLongConfinadSymbollame 
+                       al0 ret move dc frog aae a9 ????
+                       .al .ret .move .dc .frog .a9 .9 ????
+                       .0  .00  .000 .1  .11. .111 . ._
+                       _frog ?zippo? sys$syetem atari Atari ATARI aTaRi
+                 while all of the following symbols are illegal:
+                       12days dc.10   dc.z   'quote  .right.here
+                       @work hi.there $money$ ~tilde
+                    Symbols beginning with a period (.) are confined; their scope is between two 
+                 normal (unconfined) labels. Confined symbols may be labels or equates. It is illegal 
+                 to make a confined symbol global (with the ".globl" directive, a double colon, or a 
+                 double equals). Only unconfined labels delimit a confined symbol's scope; equates 
+                 (of any kind) do not count. For example, all symbols are unique and have unique 
+                 values in the following:
+                       zero:: subq.w $1,d1
+                              bmi.s .ret
+                       .loop: clr.w (a0)+
+                              dbra  d0,.loop
+                       .ret:  rta
+                       FF::   subq.w #1,d1
+                              bmi.s .99
+                       .loop: move.w -1,(a0)+
+                              dbra  d0,.loop
+                       .99:   its
+                 Confined symbols are useful since the programmer has to be much less inventive 
+                 about finding small, unique names that also have meaning.
+                    It is legal to define symbols that have the same names as processor mnemonics 
+                 (such as "move" or "rts") or assembler directives (such as ".even"). Indeed, one 
+                 should be careful to avoid typographical errors, such as this classic (in 6502 mode):
+                              .6502 
+                       .org   =     $8000
+                 which equates a confined symbol to a hexadecimal value, rather than setting the 
+                 location counter, which the .org directive does (without the equals sign).
+                 Keywords
+                 The following names, in all combinations of uppercase and lowercase, are keywords 
+                 and may not be used as symbols (e.g. labels, equates, or the names of macros):
+                       equ set reg
+                       sr ccr pc sp ssp usp
+                       dO di d2 d3 d4 d5 d6 d7 
+                       a0 al a2 a3 a4 a5 a6 aT 
+                       r0 ri r2 r3 r4 r5 r6 r7
+                       r8 r9 r10 1'11 r12 rl3 ri4 ri5
+
+             12 MADMAC Reference Manual
+• 
+\f
+                                           Source Format
+
+Constants
+Numbers may be decimal, hexadecimal, octal, binary or concatenated ASCII. The 
+default radix is decimal, and it may not be changed. Decimal numbers are specified 
+with a string of digits (0-9). Hexadecimal numbers are specified with a leading 
+dollar sign ($) followed by a string of digits and uppercase or lowercase letters (A-F 
+a-f). Octal numbers are specified with a leading at-sign (@) followed by a string 
+of octal digits (0-7). Binary numbers are specified with a leading percent sign 
+(%) followed by a string of binary digits (0-1). Concatenated ASCII constants are 
+specified by enclosing from one to four characters in single or double quotes. For 
+example:
+
+      1234   decimal
+      $1234  hexadecimal
+      @777   octal
+      %10111 binary 
+      "z"    ASCII 
+      'frog' ASCII
+
+Negative numbers Are specified with a unary minus (-). For example:
+
+      -5678  -@334 -$4e71
+      -%11011 -'z' -"WIND"
+
+Strings
+Strings are contained between double (") or single ( ') quote marks. Strings may 
+contain non-printable characters by specifying "backslash" escapes, similar to the 
+ones used in the C programming language. MADMAC will generate a warning if a 
+backslash is followed by a character not appearing below:
+
+      \\    $5c    backslash
+      \n    $0a    line-feed (newline)
+      \b    $08    backspace
+      \t    $09    tab
+      \r    $0c1   carriage-return
+      \f    $0c    form-feed
+      \e    $1b    escape
+      \'    $27    single-quote
+      \"    $22    double-quote
+
+   It is possible for strings (but not symbols) to contain characters with their high 
+bits set (i.e. character codes 128...255).
+   You should be aware that backslash characters are popular in GEMDOS path 
+names, and that you may have to escape backslash characters in your existing source 
+code. For example, to get the file "c:\euto\andi.s" you would specify the string 
+"c:\\auto\\andi.s".
+
+Register Lists
+Register lists are special forms used with the movem mnemonic and the .reg 
+directive. They are 16-bit values, with bits 0 through 15 corresponding to registers 
+D0 through A7. A register list consists of a series of register names or register 
+ranges seperated by slashes. A register range consists of two register names, Rm
+and Rn,m<n, seperated by a dash. For example:
+
+                                  MADMAC Reference Manual 13
+
+
+\f
+                    Source Format
+
+                           register list           value
+                           -------------           -----
+                           40-d7/a0-a7             $FFFF
+                           d2-d7/a0/a3-a6          $39FC
+                           dO/d1/a0-a3/d7/a6-a7    $CF83
+                           d0                      $0001
+                           r0-r16                  $FFFF
+                        Register lists and register equates may be used in conjunction with the movem 
+                    mnemonic, as in this example:
+                           temps   reg     d0-d2/a0-a2     ; temp registers
+                           keeps   reg     d3-d7/d3-a6     ; registers to preserve
+                           allregs reg     d0-d7/a0-a7     ; all registers
+                                   movem.l #temps, -(sp)   ; these two lines ...
+                                   aovea.l dO -d2/a0 -a2, -(sp) ; are identical
+                                   movea.l #keeps, -(sp)   ; save "keep" registers
+                                   noven.1 (sp)+,#keeps    ; restore "keep" registers
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                14 MADMAC Reference Manual
+
+\f
+                        Expressions
+
+
+
+
+
+
+
+All values are computed with 32-bit 2's complement arithmetic. For boolean op- 
+erations (such as if or assert) zero is considered false, and non-zero is considered 
+true.
+     Expressions are evaluated strictly left-to-right, with no 
+     regard for operator precedence.
+Thus the expression "1+2*3" evaluates to 9, not 7. However, precedence may be 
+forced with parenthesis (()) or square-brackets ([]).
+
+Types
+Expressions belong to one of three classes: undefined, absolute or relocatable. An 
+expression is undefined if it involves an undefined symbol (e.g. an undeclared sym- 
+bol, or a forward reference). An expression is absolute if its value will not change 
+when the program is relocated (for instance, the number 0, all labels declared in 
+an abs section, and all Atari ST hardware register locations are absolute values). 
+An expression is relocatable if it involves exactly one symbol that is contained in a 
+text, data or BSS section.
+  Only absolute values may be used with operators other than addition (+) or 
+subtraction (-). It is illegal, for instance, to multiply or divide by a relocatable or 
+undefined value. Subtracting a relocatable value from another relocatable value in 
+the same section results in an absolute value (the distance between them, positive 
+or negative). Adding (or subtracting) an absolute value to or from a relocatable 
+value yeilds a relocatable value (an offset from the relocatable address).
+  It is important to realize that relocatable values belong to the sections they 
+are defined in (e.g. text, data or BSS), and it is not permissible to mix and match 
+sections. For example, in this code:
+     linel:  dc.l   line2, linel+8
+     line2:  dc.l   linel, line2-8
+     line3:  dc.l   line2-linel, 8
+     error:  dc.l   linel+line2, line2 >> 1, line3/4
+Line 1 deposits two longwords that point to line 2. Line 2 deposits two longwords 
+that point to line 1. Line 3 deposits two longwords that have the absolute value 
+eight. The fourth line will result in an assembly error, since the expressions (re- 
+spectively) attempt to add two relocatable values, shift a relocatable value right by 
+one, and divide a relocatable value by four.
+  The pseudo-symbol "*" (star) has the value that the current section's location 
+counter had at the beginning of the current source line. For example, these two 
+statements deposit three pointers to the label "bar":
+     too:    dc.l   *+4
+     bar:    dc.l   *, *
+
+  Similarly, the pseudo-symbol "$" has the value that the current section's loca- 
+tion counter has, and it is kept up to date as the assembler deposits information
+
+                               MADMAC Reference Manual 15 
+
+\f
+                           Expressions
+
+
+
+                           "across" a line of source code. For example, these two statements deposit four 
+                           pointers to the label "zip":
+
+
+                                     zip:      dc.l      $+8, $+4
+                                     zop:      dc.l      $, $-4
+
+
+                           Unary Operators
+
+                                       Operator                   Description
+                                       -                          Unary minus (2's complement).
+                                       !                          Logical (boolean) NOT.
+                                       ~                          Tilde: bitwise not (l's complement).
+                                       ^^defined symbol           True if symbol has a value.
+                                       ^^referenced symbol        True if symbol has been referenced.
+                                       ^^streq stringl,string2    True if the strings are equal.
+                                       ^^macdef macroName         True if the macro is defined.
+
+                              o The boolean operators generate the value 1 if the expression is true, and 0 if
+                                it is not.
+
+                              o A symbol is referenced if it is involved in an expression. A symbol may have 
+                                any combination of attributes: undefined and unreferenced, defined and unref- 
+                                erenced (i.e. declared but never used), undefined and referenced (in the case 
+                                of a forward or external reference), or defined and referenced.
+
+
+
+                           Binary Operators
+
+                                             Operator    Description
+                                             + -  * /     The usual arithmetic operators.
+                                             %            Modulo.
+                                             & | ^        Bit-wise AND, OR and Exclusive-OR.
+                                             << >>        Bit-wise shift left and shift right.
+                                             < <=  >=  >  Boolean magnitude comparisons.
+                                             =            Boolean equality.
+                                             <>  !=       Boolean inequality.
+
+                              o All binary operators have the same precedence: expressions are evaluated 
+                                strictly left to right.
+
+                              o Division or modulo by zero yields an assembly error
+
+                              o The "<>" and "!=" operators are synonyms.
+
+                              o Note that the modulo operator (%) is also used to introduce binary constants 
+                                (see: Constants). A percent sign should be followed by at least one space if 
+                                it is meant to be a modulo operator, and is followed by a '0' or '1'.
+
+                           Special Forms
+
+                                         Special Form    Description
+                                         ^^date          The current system date (Gemdos format). 
+                                         ^^time          The current system time (Gemdos format).
+
+                              o The "^^date" special form expands to the current system date, in Gemdos 
+                                format. The format is a 16-bit word with bits 0 ...4 indicating the day of the
+                                month (1...31), bits 5...8 indicating the month (1...12), and bits 9...15 
+                                indicating the year since 1980, in the range 0...119.
+
+                     16 MADMAC Reference Manual
+\f
+                                                       Expressions
+
+  o The "^^time" special form expands to the current system time, in Gemdos 
+    format. The format is a 16-bit word with bits 0...4 indicating the current 
+    second divided by 2, bits 5...10 indicating the current minute 0...59. and 
+    bits 11...15 indicating the current hour 0...23.
+
+Example Expressions
+
+        line address contents      source code
+        ---- ------- --------      -------------------------------
+           1 00000000 4480         lab1:  neg.l  d0
+           2 00000002 427900000000 lab2:  clr.w  lab1
+           3         =00000064     equ1   =      100
+           4         =00000096     equ2   =      equ1 + 50
+           5 00000008 00000064            dc.l   lab1 + equ1
+           6 0000000C 7FFFFFE6            dc.l   (equl + ~equ2) >> 1
+           7 00000010 0001                dc.w   ^^defined equl 
+           8 00000012 0000                dc.w   ^^referenced lab2
+           9 00000014 00000002            dc.l   lab2
+          10 00000018 0001                dc.w   ^^referenced lab2 
+          11 0000001A 0001                dc.w   lab1 = (lab2 - 6)
+Lines 1 through four here are used to set up the rest of the example. Line 5 deposits 
+a relocatable pointer to the location 100 bytes beyond the label "lab1." Line 6 is 
+a nonsensical expression that uses the and right-shift operators. Line 7 deposits 
+a word of 1 because the symbol "equ1" is defined (in line 3).
+    Line 8 deposits a word of 0 because the symbol "lab2," defined in line 2, has 
+not been referenced. But the expression in line 9 references the symbol "lab2," so 
+line 10 (which is a copy of line-8) deposits a word of 1. Finally, line 11 deposits a 
+word of 1 because the Boolean equality operator evaluates to true.
+    The operators "^^defined" and "^^referenced" are particularly useful in 
+conditional assembly. For instance, it is possible to automatically include debugging 
+code if the debugging code is referenced, as in:
+               lea    string,a0            ; AO -> message
+               jsr    debug                ; print a message 
+               its                         ; and return
+        string: dc.b  "Help me, Spock!",0  ; (the message)
+
+               .iif ^^defined debug, .include "debug.s"
+The jsr statement references the symbol debug. Near the end of the source file, the 
+".iif' statement includes the file "debug.s" if the symbol debug was referenced. 
+In production code, presumably all references to the debug symbol will be removed, 
+and the debug source file will not be included. (We could have as easily made the 
+symbol debug external, instead of including another source file).
+
+
+
+
+
+
+
+
+
+
+
+
+                                         MADMAC Reference Manual 17
+\f
+                    Directives
+
+
+
+
+
+
+
+
+
+
+                    Assembler directives may be any mix of upper- or lowercase. The leading periods 
+                    are optional, though they are shown here and their use is encouraged. Directives 
+                    may be preceeded by a label; the label is defined before the directive is executed. 
+                    Some directives accept size suffixes (.b, .s, .w or .1); the default is word (.w) if no 
+                    size is specified. The .s suffix is identical to .b. Directives relating to the 6502 are 
+                    described in the chapter on 6502 Support.
+
+
+
+
+                    .even
+                       If the location counter for the current section is odd, make it even by adding 
+                       one to it. In text and data sections a zero byte is deposited if necessary.
+                    .assert expression [,expression...]
+                       Assert that the conditions are true (non-zero). If any of the comma-seperated 
+                       expressions evaluates to zero an assembler warning is issued. For example:
+                               .assert *-start = $76 
+                               .assert stacksize >= $400
+                    .bss
+                    .data
+•                 .text
+                       Switch to the BSS, data or text segments. Instructions and data may not 
+                       be assembled into the BSS-segment, but symbols may be defined and storage 
+                       may be reserved with the As directive. Each assembly starts out in the text 
+                       segment.
+                    .abs [location]
+                       Start an absolute section, beginning with the specified location (or zero, if 
+                       no location is specified). An absolute section is much like BSS, except that 
+                       locations declared with .ds are based absolute. This directive is useful for 
+                       declaring structures or hardware locations.
+                       For example, the following equates:
+                               VPLANES = 0 
+                               VWRAP   = 2 
+                               CONTRL  = 4 
+                               INTIN   = 8 
+                               PTSIN   = 12
+                       could be as easily defined as:
+                                       .abs
+                               VPLAIES: ds.w    1
+                               VWRAP:  ds.w     1
+                               CONTRL: ds.l     1
+                               INTIE:  ds.l     1
+                               PTSIN:  ds.l     1
+
+•              18 MADMAC Reference Manual
+\f
+                         Directives
+
+.comm symbol, expression
+  Specifies a label and the size of a common region. The label is made global, 
+  thus confined symbols cannot be made common. The linker groups all com- 
+  mon regions of the same name; the largest size determines the real size of the 
+  common region when the file is linked.
+
+.dc[.size] expression [,expression...]
+  Deposit initialized storage in the current section. If the specified size is word 
+  or long, the assembler will execute a .even before depositing data. If the size 
+  is .b, then strings that are not part of arithmetic expressions are deposited 
+  byte-by-byte. If no size is specified, the default is .w. This directive cannot be 
+  used in the BSS section.
+
+.dcb[.size] expression 1, expression2
+  Generate an initialized block of expression) bytes, words or longwords of the 
+  value expression2. If the specified size is word or long, the assembler will 
+  execute .even before generating data. If no size is specified, the default is .w. 
+  This directive cannot be used in the BSS section.
+
+.ds[.size] expression
+  Reserve space in the current segment for the appropriate number of bytes, 
+  words or longwords. If no size is specified, the default size is .w. If the size 
+  is word or long, the assembler will execute .even before reserving space. This 
+  directive can only be used in the BSS or ABS sections (in text or data, use 
+  .dcb to reserve large chunks of initialized storage.)
+
+.init[.size] [#expression,]expression[.size] [,...]
+  Generalized initialization directive. The size specified on the directive becomes 
+  the default size for the rest of the line. (The "default" default size is .w.) A 
+  comma-seperated list of expressions follows the directive; an expression may be 
+  followed by a size to override the default size. An expression may be preceeded 
+  by a sharp sign, an expression and a comma, which specifies a repeat count to 
+  be applied to the next expression. For example:
+       .init.l -1, 0.w, #16,'z'.b, #3,0, 11.b
+
+  will deposit a longword of -1, a word of zero, sixteen bytes of lower-case 'z', 
+  three longwords of zero, and a byte of 11.
+  No auto-alignment is performed within the line, but a .even is done once 
+  (before the first value is deposited) if the default size is word or long.
+
+.cargs [#expression dsymboi[.size] [, symbol[.size].. .]
+  Compute stack offsets to C (and other language) arguments. Each symbol is 
+  assigned an absolute value (like equ) which starts at expression and increases 
+  by the size of each symbol, for each symbol. If the expression is not supplied, 
+  the default starting value is 4. For example:
+     .cargs #8, .fileliams.1, .openMode, .butPointer.l
+
+  could be used to declare offsets from A6 to a pointer to a filename, a word 
+  containing an open mode, and a pointer to a buffer. (Note that the symbols 
+  used here are confined). Another example, a C-style "string-length" function, 
+  could be written as.
+
+                  MADMAC Reference Manual 19 
+
+\f
+                Directives
+                         _strlen:: .cargs .string     ; declare arg
+                               move.l .string(sp),a0  ; a0 -> string 
+                               moveq  #-1,d0          ; initial size = -1
+                         .1:   addq.1 #1,d0           ; bump size
+                               tst.b  (a0)+           ; at end of string?
+                               bne   .1               ; (no -- try again)
+                               rts                    ; return string length
+                .end
+                   End the assembly. In an include file, end the include file and resume assembling 
+                   the superior file. This statement is not required, nor are warning messages 
+                   generated if it is missing at the end of a file. This directive may be used inside 
+                   conditional assembly, macros or .rept blocks.
+                .if expression
+                .else
+                .endif
+                   Start a block of conditional assembly. If the expression is true (non-zero) then 
+                   assemble the statements between the .if and the matching .endif or .else. 
+                   If the expression is false, ignore the statements unless a matching .else is 
+                   encountered. Conditional assembly may be nested to any depth.
+                   It is possible to exit a conditional assembly block early from within an include 
+                   file (with end) or a macro (with endni).
+                .iif expression, statement
+                   Immediate version of if. If the expression is true (non-zero) then the state- 
+                   ment, which may be an instruction, a directive or a macro, is executed. If 
+                   the expression is false, the statement is ignored. No .endif is required. For 
+                   example:
+                         .iif age < 21, canDrink = 0
+                         .iif weight > 500, dangerFlag = 1
+                         .iif !(^^defined DEBUG), .include dbsrc
+                .macro name [formal, formal,...]
+                .endim
+                .exitm
+                   Define a macro called name with the specified formal arguments. The macro 
+                   definition is terminated with a .endm statement. A macro may be exited early 
+                   with the .exitm directive. See the chapter on Macros for more information.
+                .undefmac macroName [, macroNarne. .]
+                   Remove the macro-definition for the specified macro names. If reference is 
+                   made to a macro that is not defined, no error message is printed and the name 
+                   is ignored.
+                .rept expression
+                .endr
+                   The statements between the .rept and .endr directives will be repeated ex- 
+                   pression times. If the expression is zero or negative, no statements will be 
+                   assembled. No label may appear on a line containing either of these directives.
+                .globl symbol [, symbol...]
+                .extern symbol [, symbol...]
+                   Each symbol is made global. None of the symbols may be confined symbols 
+                   (those starting with a period). If the symbol is defined in the assembly, the 
+                   symbol is exported in the object file. If the symbol is undefined at the end 
+                   of the assembly, and it was referenced (i.e. used in an expression), then the
+
+             20 MADMAC Reference Manual
+
+\f
+                                                                                                          Directives
+
+
+      symbol value is imported as an external reference that must be resolved by the 
+      linker. The .extern directive is merely a. synonym for
+
+.include "file"
+      Include a file. If the filename is not enclosed in quotes, then a default extension
+      of ".s" is applied to it. If the filename is quoted, then the name is not changed 
+      in any way.
+
+  Note: If the filename is not a valid symbol, then the assembler will generate an 
+             error message. You should enclose filenames such as "atari.s" in quotes, 
+             because such names are not symbols.
+
+      If the include file cannot be found in the current directory, then the direc- 
+      tory search path, as specified by -i on the commandline, or' by the NACPLTH 
+      enviroment string, is traversed
+
+.eject
+      Issue a page eject in the listing file.
+
+.title "string"
+.subttl [-] "string"
+      Set the title or subtitle on the listing page. The title should be specified on 
+      the the first line of the source program in order to take effect on the first page. 
+      The second and subsequent uses of .title will cause page ejects. The second 
+      and subsequent uses of .subttl will cause page ejects unless the subtitle string 
+      is preceeded by a dash (-).
+
+.list
+.nlist
+      Enable or disable source code listing. These directives increment and decrement 
+      an internal counter, so they may be appropriately nested. They have no effect 
+      if the -l switch is not specified on the commandline.
+
+.goto label
+      This directive provides unstructured flow of control within a macro definition. 
+      It will transfer control to the line of the macro containing the specified goto 
+      label. A goto label is a symbol preceeded by a colon that appears in the first 
+      column of a source line within a macro definition:
+
+                    :  label
+
+      where the label itself can be any valid symbol name, followed immediately by 
+      whitespace and a valid source line (or end of line). The colon must appear in 
+      the first column.
+             The goto-label is removed from the source line prior to macro expansion - 
+      to all intents and purposes the label is invisible except to the .goto directive 
+      Macro expansion does not take place within the label.
+             For example, here is a silly way to count from 1 to 10 without using .rept:
+
+                                  .macro Count
+                    count         set     1
+                    :loop         dc.w    count
+                    count         set     count + 1
+                                  iif count <= 10, goto loop 
+                                  .endm
+
+
+
+
+
+
+
+
+                                                                              MADMAC Reference Manual 21
+
+
+\f
+                           68000 Mnemonics
+
+
+
+
+
+
+
+
+
+
+                           Mnemonics
+                           All of the standard Motorola 68000 mnemonics and addressing modes are supported; 
+                           you should refer to The Motorola M68000 Programmer's Reference Manual 
+                           for a description of the instruction set and the allowable addressing modes for each 
+                           instruction. With one major exception (forward branches) the assembler performs 
+                           all the reasonable optimizations of instructions to their short or address register 
+                           forms.
+                                Register names may be in upper or lower case. The alternate forms R0 through 
+                           R15 may be used to specify D0 through A7. All register names are keywords, and 
+                           may not be used as labels or symbols. None of the 68010 or 68020 register names 
+                           are keywords (but they may become keywords in the future).
+
+                           Addressing Modes
+                                    Assembler Syntax         Description
+                                    Dn                       Data register direct
+                                    An                       Address register direct
+                                    (An)                     Address register indirect
+                                    (An)+                    Address register indirect postincrement
+                                    -(An)                    Address register indirect predecrement
+                                    disp(An)                 Address register indirect with displacement
+                                    bdisp(An, Xi[.size])     Address register indirect indexed 
+                                    abs.w                    Absolute short
+                                    abs                      Absolute (long or short)
+                                    abs.l                    Forced absolute long
+                                    disp(PC)                 Program counter with displacement
+                                    bdisp(PC, Xi)            Program counter indexed 
+                                    #imm                     Immediate
+
+
+                           Branches
+                           Since MADMAC is a one pass assembler, forward branches cannot be automatically 
+                           optimized to their short form. Instead, unsized forward branches are assumed to 
+                           be long. Backward branches are always optimized to the short form if possible.
+                                A table that lists "extra" branch mnemonics (common synonyms for the Mo- 
+                           torola defined mnemonics) appears below.
+
+                           Linker Constraints
+                           It is not possible to make an external reference that will fix up a byte. For example:
+
+                                                extern frog
+                                               move.l frog(pc,d0),d1
+
+                    22 MADMAC Reference Manual
+\f
+68000 Mnemonics
+Branch Synonyms
+Alternate name Becomes:
+bhs            bcc
+blo            bcs
+bse, bs        beq
+bns            bne
+dblo           dbcs  
+dbse           dbeq  
+dbra           dbf
+dbhs           dbhi  
+dbns           dbne
+is illegal (and generates an assembly error) when frog is external, because the  
+displacement occupies a byte field in the 68000 offset word, which the object file  
+cannot represent.
+Optimizations and Translations
+The assembler provides "creature comforts" when it processes 68000 mnemonics:
+
+o CLR.x An will really generate SUB.x An,An.
+o ADD, SUB and CMP with an address register will really generate ADDA,  
+SUBA and CMPA.
+o The ADD, AND, CMP, EOR, OR and SUB mnemonics with immediate  
+first operands will generate the "I" forms of their instructions (ADDI, etc.) if  
+the second operand is not register direct.
+o All shift instructions with no count value assume a count of one.
+o MOVE.L is optimized to MOVEQ if the immediate operand is defined and  
+in the range -128...127. However, ADD and SUB are never translated to  
+their quick forms; ADDQ and SUBQ must be explicit.
+MADMAC Reference Manual 23     
+
+\f
+                                            Macros
+
+
+
+
+
+
+
+                                          A macro definition is a series of statements of the form: 
+                                                                           .macro name [ formal-arg, ...]
+
+                                                                           statements making up the macro body
+
+                                                                           .endm
+
+                                          The name of the macro may be any valid symbol that is not also a 68000 instruction 
+                                          or an assembler directive. (The name may begin with a period - macros cannot 
+                                          be made confined the way labels or equated symbols can be). The formal argument 
+                                          list is optional; it is specified with a comma-seperated list of valid symbol names. 
+                                          Note that there is no comma between the name of the macro and the name of the 
+                                          first formal argument
+                                                  A macro body begins on the line after the .macro directive. All instructions 
+                                          and directives, except other macro definitions, are legal inside the body.
+                                                  The macro ends with the .endm statement. If a label appears on the line with 
+                                          this directive, the label is ignored and a warning is generated.
+
+                                          Parameter Substitution
+                                          Within the body, formal parameters may be expanded with the special forms:
+                                                          \name 
+                                                          \{name}
+
+                                          The second form (enclosed in braces) can be used in situations where the characters 
+                                          following the formal parameter name are valid symbol continuation characters. This 
+                                          is usually used to force concatentation, as in:
+                                                          \{frog}star 
+                                                          \(godzilla}vs\{reagan}
+
+                                                  The formal parameter name is terminated with a character that is not valid in 
+                                          a symbol (e.g. whitespace or puncuation); optionally, the name may be enclosed in 
+                                          curly-braces. The names must be symbols appearing on the formal argument list, 
+                                          or a single decimal digit (\1 corresponds to the first argument, \2 to the second, 
+                                          \9 to the ninth, and \0 to the tenth). It is possible for a macro to have more than 
+                                          ten formal arguments, but arguments 11 and on must be referenced by name, not 
+                                          by number.
+                                                  Other special forms are:
+
+                                 24 MADMAC Reference Manual
+
+\f
+                                                                                    Macros
+
+                             Special Form Description
+                             \\           a single "\",
+                             \~           a unique label of the form "Mn"
+                             \#           the number of arguments actually specified
+                             \!           the "dot-size" specified on the macro invocation 
+                             \?name       conditional expansion
+                             \?{name}     conditional expansion
+
+                     The last two forms are identical: if the argument is specified and is non-empty, the 
+                     form expands to a "1", otherwise (if the argument is missing or empty) the form 
+                     expands to a "0".
+                         The form "\!" expands to the "dot-size" that was specified when the macro 
+                     was invoked. This can be used to write macros that behave differently depending 
+                     on the size suffix they are given, as in this macro which provides a synonym for the 
+                     "dc" directive:
+                                    .macro deposit value 
+                                    dc\!   \value
+                                    .endm
+                                    deposit.b 1          ; byte of 1
+                                    deposit.w 2          ; word of 2
+                                    deposit.l 3          ; longvord of 3
+                                    deposit   4          ; word of 4 (no explicit size)
+
+                     Macro Invocation
+                     A previously-defined macro is called when its name appears in the operation field of 
+                     a statement. Arguments may be specified following the macro name; each argument 
+                     is seperated by a comma. Arguments may be empty. Arguments are stored for 
+                     substitution in the macro body in the following manner:
+                       o Numbers are converted to hexadecimal.
+                       o All spaces outside strings are removed.
+                       o Keywords (such as register names, dot sizes and "^^" operators) are converted 
+                         to lowercase.
+                       o Strings are enclosed in double-quote marks (").
+                     For example, a hypothetical call to the macro "mymacro", of the form:
+                            mymacro A0, , 'Zorch' / 32, "^^DEFINED foo, , , tick tock 
+                     will result in the translations:
+                         Argument  Expansion     Comment
+                         \1        a0            "A0" converted to lower-case
+                         \2                      empty
+                         \3        "Zorch"/$20   "Zorch" in double-quotes, 32 in hexadecimal
+                         \4        "^^defined foo" "^^DEFINED" converted to lower-case
+                         \5                      empty
+                         \6                      empty
+                         \7        ticktock      spaces removed (note concatenation)
+
+                         The .exitm directive will cause an immediate exit from a macro body. Thus 
+                     the macro definition:
+
+                                                                 MADMAC Reference Manual 25
+\f
+    Macros
+              .macro foo source
+                  .iif !\?source, .exitm ; exit if source is empty 
+                  move \source,d0      ; otherwise, deposit source 
+              .endm
+
+    will not generate the move instruction if the argument "source" is missing from 
+    the macro invocation.
+        The .end, .endif and .exitm directives all pop-out of their include levels 
+    appropriately. That is, if a macro performs a include to include a source file, an 
+    executed .exitm directive within the include-file will pop out of both the include-file 
+    and the macro.
+        Macros may be recursive or mutually recursive to any level, subject only to 
+    the availability of memory. When writing recursive macros, take care in the coding 
+    of the termination condition(s). A macro that repeatedly calls itself will cause the 
+    assembler to exhaust its memory and abort the assembly.
+
+
+    Example Macros
+
+    The Gemdos macro is used to make file system calls. It has two parameters, a 
+    function number and the number of bytes to clean off the stack after the call. The 
+    macro pushes the function number onto the stack and does the trap to the file 
+    system. After the trap returns, conditional assembly is used to choose an addq or 
+    an add.w to remove the arguments that were pushed.
+           .macro Gemdos trpno, clean
+              move.w  #\trpno,-(sp)  ; push trap number
+              trap    #1             ; do GEMDOS trap
+              .if \clean <= 8        ;
+              addq    Aclean,sp      ; clean-up up to 8 bytes
+              .else                  ;
+              add.w   $\clean,sp     ; clean-up more than 8 bytes
+              .endif
+           .endm
+
+        The Fopen macro is supplied two arguments; the address of a filename, and 
+    the open mode. Note that plain move instructions are used, and that the caller of 
+    the macro must supply an appropriate addressing mode (e.g. immediate) for each 
+    argument.
+           .macro Fopen file, mode
+              movs.w   \mode,-(sp)  ;push open mode
+              move.1   \file,-(sp)  ;push address of tile name
+              Gemdos   $3d,8        ;do the GEMDOS call
+           .endm
+
+        The String macro is used to allocate storage for a string, and to place the 
+    string's address somewhere. The first argument should be a string or other expres- 
+    sion acceptable in a dc.b directive. The second argument is optional; it specifies 
+    where the address of the string should be placed. If the second argument is omitted, 
+    the string's address is pushed onto the stack. The string data itself is kept in the 
+    data segment.
+
+26 MADMAC Reference Manual
+
+\f
+                                                                                                                                                          Macros
+
+                   .macro String str,loc
+                       .if \?loc                                        ; if lac is defined
+                         move.l #.\~,\loc                               ; put the string's address there 
+                       .else                                            ; otherwise
+                         pea .\~                                        ; push the string's address
+                       .endif                                           ;
+                       .data                                            ; put the string data
+                   .\~: dc.b \str,0                                     ;  in the data segment
+                             .text                                      ; and switch back to the text segment
+                   .endm
+
+         The construction ".\~" will expand to a label of the form ".Mn" (where n is 
+a unique number for every macro invocation), which is used to tag the location of 
+the string. The label should be confined because the macro may be used along with 
+other confined symbols.
+         Unique symbol generation plays an important part in the art of writing fine 
+macros. For instance, if we needed three unique symbols, we might write ".a\~", 
+".b\~" and ".c\~".
+
+Repeat Blocks
+Repeat-blocks provide a simple iteration capability. A repeat block allows a range 
+of statements to be repeated a specified number of times. For instance, to generate 
+a table consisting of the numbers 255 through 0 (counting backwards) you could 
+write:
+
+                   .count  set     255             ; initialize counter 
+                           .rept 256               ; repeat 256 times:
+                           dc.b    .count          ;  deposit counter
+                   .count  set     .count - 1      ;  and decrement it 
+                           .endr                   ; (end of repeat block)
+
+Repeat blocks can also be used to duplicate identical pieces of code (which are 
+common in bitmap-graphics routines). For example:
+
+                   .rept 16                        ; clear 16 words
+                   clr.w (a0)+                     ;   starting at AO 
+                   .endr                           ;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                                                                                                            MADMAC Reference Manual 27
+
+                                                                                                                                                                                                                    •
+\f
+               6502 Support
+
+
+
+
+
+
+
+
+               MADMAC will generate code for the Motorola 6502 microprocessor. This chapter 
+               describes extra addressing modes and directives used to support the 6502.
+                  As the 6502 object code is not linkable (currently there is no linker) external 
+               references may not be made. (Nevertheless, MADMAC may reasonably be used for 
+               large assemblies because of its blinding speed.)
+                  All standard 6502 addressing modes are supported, with the exception of the 
+               accumulator addressing form, which must be omitted (e.g. "ror a" becomes "ror"). 
+               Five extra modes, synonyms for existing ones, are included for compatibility with 
+               the Atari Coinop assembler.
+                      empty     implied or accumulator (e.g. tsx or ror)
+                      expr      absolute or zeropage
+                      *expr     immediate
+                      (expr,x)  indirect X 
+                      (expr),y  indirect Y
+                      (expr)    indirect
+                      @expr,x   indexed X
+                      @expr,y   indexed Y
+                      @expr(x)  indirect X 
+                      x,expr(y) indirect Y
+                      y,expr    indirect
+ •                  x,expr    indexed X
+                      y,expr    indexed Y
+                  While MADMAC lacks "high" and "low" operators, high bytes of words may 
+               be extracted with the shift (>>) or divide (/) operators, and low bytes may be 
+               extracted with the bitwise AND (&) operator.
+               .6502
+                  This directive enters the 6502 section. The location counter is undefined, and 
+                  must be set with ".org" before any code can be generated.
+                     The "dc.w" directive will produce 6502-format words (low byte first). The 
+                  68000's reserved keywords (d0-d7/a0-a7/ssp/usp and so on) remain reserved 
+                  (and thus unusable) while in the 6502 section. The directives globl, dc.l, 
+                  dcb.l, text, data, bas, abs, even and comm are illegal in the 6502 section. 
+                  It is permitted, though probably not useful, to generate both 6502 and 68000 
+                  code in the same object file.
+               .68000
+                  This directive leaves the 6502 segment and returns to the 68000's text segment. 
+                  68000 instructions may be assembled as normal.
+               .org location
+                  This directive is only legal in the 6502 section. It sets the value of the location 
+                  counter (or pc) to location, an expression that must be defined, absolute, and 
+                  less than $10000.
+
+            28 MADMAC Reference Manual
+
+\f
+                                     6502 Support
+
+  WARNING
+  It is possible to assemble "beyond" the microprocessor's 64K address space, but 
+  attempting to do so will probably screw up the assembler. DO NOT attempt 
+  to generate code like this:
+      .org $fffe
+      nop 
+      nop 
+      nop
+  the third NOP in this example, at location $10000, may cause the assembler 
+  to crash or exhibit spectacular schizophrenia. In any case, MADMAC will give 
+  no warning before flaking out.
+
+Object Code Format
+This is a little bit of a kludge. An object file consists of a page map, followed by 
+one or more page images, followed by a normal Alcyon 68000 object file. If the page 
+map is all zero, it is not written.
+  The page map contains a byte for each of the 256 256-byte pages in the 6502's 
+64K address space. The byte is zero ($00) if the page contained only zero bytes, or 
+one ($01) if the page contained any non-zero bytes. If a page is flagged with a one, 
+then it is written (in order) following the page map.
+  The following code:
+      .6502
+      .org  $8000
+      .dc.b 1
+      .org  $8100
+      .dc.b 1
+      .org  $8300
+      .dc.b 1
+      .end
+will generate a page map that looks (to a programmer) something like:
+      <80 bytes of zero>
+      01 01 00 01
+      <$7c more bytes of zero, for $100 total>
+      <image of page $80> 
+      <image of page $81> 
+      <image of page $83>
+  Following the last page image is an Alcyon-format object file, starting with 
+the magic number $601a. It may contain 68000 code (although that is probably 
+useless), but the symbol table is valid and available for debugging purposes. 6502 
+symbols will be absolute (not in text, data or bss).
+
+
+
+
+
+
+
+
+
+
+
+
+                             MADMAC Reference Manual 29 
+
+\f
+  Error Messages
+
+
+
+
+
+
+
+
+  When Things Go Wrong
+  Most of MADMAC's error messages are self-explanatory. They fall into four classes: 
+  warnings about situations that you (or the assembler) may not be happy about, 
+  errors that cause the assembler to not generate object files, fatal errors that cause 
+  the assembler to abort immediately, and internal errors that should never happen.1
+    You can write editor macros (or sed or awk scripts) to parse the error messages 
+  MADMAC generates. When a message is printed, it is of the form:
+           "filename" , line line-number: message
+  The first element, a filename enclosed in double quotes, indicates the file that gen- 
+  erated the error. The filename is followed by a comma, the word "line", and a line 
+  number, and finally a colon and the text of the message. The filename "(*top*)" 
+  indicates that the assembler could not determine which file had the problem.
+    The following sections list warnings, errors and fatal errors in alphabetical 
+  order, along with a short description of what may have caused the problem.
+
+  Warnings
+  bad backslash code in string
+    You tried to follow a backslash in a string with a character that the assembler 
+    didn't recognize. Remember that MADMAC uses a C-style escape system in 
+    strings.
+  label ignored
+    You specified a label before a macro, rept or endm directive. The assembler 
+    is warning you that the label will not be defined in the assembly.
+  unoptimized short branch
+    This warning is only generated if the -s switch is specified on the command 
+    line. The message refers to a forward, unsized long branch that you could have 
+    made short (.s).
+
+  Fatal Errors
+  cannot continue
+    As a result of previous errors, the assembler cannot continue processing. The 
+    assembly is aborted.
+  line too long as a result of macro expansion
+    When a source line within a macro was expanded, the resultant line was too 
+    long for MADMAC (longer than 200 characters or so).
+
+
+   1 If you come across an internal error, we would appreciate it if you would contact  
+  Atari Technical Support and let us know about the problem.
+
+30 MADMAC Reference Manual
+\f
+                                                       Error Messages
+
+
+memory exhausted
+    The assembler ran out of memory. You should (1) split up your source files 
+    and assemble them seperately, or (2) if you have any ramdisks or RAM-resident 
+    programs (like desk accessories) decrease their size so that the assembler has 
+    more RAM to work with. As a rule of thumb, pure 68000 code will use up to 
+    twice the number of bytes contained in the source files, whereas 6502 code will 
+    use 64K of ram right away, plus the size of the source files. The assembler itself 
+    uses about 80K bytes. Get out your calculator...
+
+too many ENDMs
+
+    The assembler ran across an endm directive when it wasn't expecting to see 
+    one. The assembly is aborted. Check the nesting of your macro definitions -
+    you probably have an extra endm.
+
+
+Errors
+
+
+.cargs syntax
+    Syntax error in .cargs directive.
+
+.comm symbol already defined
+    You tried to .comm a symbol that was already defined.
+
+.ds permitted only in BSS
+    You tried to use .ds in the text or data section.
+
+.init not permitted in BSS or ABS
+
+    You tried to use .init in the BSS or ABS section.
+
+.org permitted only in .6502 section
+    You tried to use .org in a 68000 section.
+
+Cannot create: filename
+    The assembler could not create the indicated filename.
+
+External quick reference
+    You tried to make the immediate operand of a moveq, subq or addq instruc- 
+    tion external.
+
+
+PC-relative expr across sections
+    You tried to make a PC-relative reference to a location contained in another
+    section.
+
+[bwsl] must follow '.' in symbol
+
+    You tried to follow a dot in a symbol name with something other than one of 
+    the four characters 'B', 'W', 'S' or 'L'.
+
+addressing mode syntax
+
+    You made a syntax error in an addressing mode.
+
+assert failure
+    One of your .assert directives failed!
+
+bad (section) expression
+    You tried to mix and match sections in an expression
+
+bad 6502 addressing mode
+    The 6502 mnemonic will not work with the addressing mode you specified. 
+
+bad expression
+    There's a syntax error in the expression you typed.
+
+
+
+
+                                            MADMAC Reference Manual 31
+\f
+          Error Messages
+
+          bad size specified
+            You tried to use an inappropriate size suffix for the instruction. Check your 
+            68000 manual for allowable sizes.
+          bad size suffix
+            You can't use .b (byte) mode with the movem instruction.
+          cannot .globl local symbol
+            You tried to make a confined symbol global or common.
+          cannot initialize non-storage (BSS) section
+            You tried to generate instructions (or data, with dc) in the BSS or ABS section.
+          cannot use '.b' with an address register
+            You tried to use a byte-size suffix with an address register. The 68000 does not 
+            perform byte-sized address register operations.
+          directive illegal in .6502 section
+            You tried to use a 68000-oriented directive in the 6502 section.
+          divide by zero
+            The expression you typed involves a division by zero.
+          expression out of range
+            The expression you typed is out of range for its application.
+          external byte reference
+            You tried to make a byte-sized reference to an external symbol, which the 
+            object file format will not allow
+          external short branch
+            You tried to make a short branch to an external symbol, which the linker cannot 
+            handle.
+          extra (unexpected) text found after addressing mode
+            MADMAC thought it was done processing a line, but it ran up against "extra" 
+            stuff. Be sure that any comment on the line begins with a semicolon, and check 
+            for dangling commas, etc.
+          forward or undefined .assert
+            The expression you typed after a .assert directive had an undefined value. 
+            Remember that MADMAC is one-pass.
+          hit EOF without finding matching .endif
+            The assembler fell off the end of last input file without finding a . endif to 
+            match an . it. You probably forgot a . endif somewhere.
+          illegal 6502 addressing mode
+            The 6502 instruction you typed doesn't work with the addressing mode you 
+            specified.
+          illegal absolute expression
+            You can't use an absolute-valued expression here.
+          illegal bra.s with zero offset
+            You can't do a short branch to the very next instruction (read your 68000 
+            manual).
+          illegal byte-sized relative reference
+            The object file format does not permit bytes contain relocatable values; you 
+            tried to use a byte-sized relocatable expression in an immediate addressing 
+            mode.
+
+        32 MADMAC Reference Manual
+
+\f
+                     Error Messages
+
+illegal character
+ Your source file contains a character that MADMAC doesn't allow. (most 
+ control characters fall into this category).
+illegal initialization of section
+ You tried to use .dc or .dcb in the BSS or ABS sections.
+illegal relative address
+ The relative address you specified is illegal because it belongs to a different 
+ section.
+illegal word relocatable (in .PRG mode)
+ You can't have anything other than long relocatable values when you're gener- 
+ ating a .PRG file.
+inappropriate addressing mode
+ The mnemonic you typed doesn't work with the addressing modes you specified. 
+ Check your 68000 manual for allowable combinations.
+invalid addressing mode
+ The combination of addressing modes you picked for the movem instruction 
+ are not implemehydd by the 68000. Check your 68000 reference manual for 
+ details.
+invalid symbol following ^^
+ What followed the ^^ wasn't a valid symbol at all.
+mis-nested .endr
+ The assembler found a .endr directive when it wasn't prepared to find one. 
+ Check your repeat-block nesting.
+mismatched .else
+ The assembler found a .else directive when it wasn't prepared to find one. 
+ Check your conditional assembly nesting.
+mismatched .endif
+ The assembler found a .endif directive when it wasn't prepared to find one. 
+ Check your conditional assembly nesting.
+missing '='
+missing '}'
+missing argument name 
+missing close parenthesis ')'
+missing close parenthesis ']' 
+missing comma
+missing filename
+missing string
+missing symbol
+missing symbol or string
+ The assembler expected to see a symbol/filename/string (etc...), but found 
+ something else instead. In most cases the problem should be obvious.
+misuse of '.', not allowed in symbols
+ You tried to use a dot (.) in the middle of a symbol name.
+mod (%) by zero
+ The expression you typed involves a modulo by zero.
+
+
+
+
+                 MADMAC Reference Man ual 33
+
+\f
+  Error Messages
+
+  multiple formal argument definition
+    The list of formal parameter names you supplied for a macro definition includes 
+    two identical names.
+  multiple macro definition
+    You tried to define a macro which already had a definition.
+  non-absolute byte reference
+    You tried to make a byte reference to a relocatable value, which the object file  
+    format does not allow.
+  non-absolute byte value
+    You tried to dc.b or dcb.b a relocatable value. Byte relocatable values are 
+    not permitted by the object file format.
+  register list order
+    You tried to specify a register list like D7-D0, which is illegal. Remember 
+    that the first register number must be less than or equal to the second register  
+    number.
+  register list syntax
+    You made an error in specifying a register list for a .reg directive or a .movem  
+    instruction.
+  symbol list syntax
+    You probably forgot a comma between the names of two symbols in a symbol 
+    list, or you left a comma dangling on the end of the line.
+  syntax error
+    This is a "catch-all" error.
+  undefined expression
+    The expression has an undefined value because of a forward reference, or an 
+    undefined or external symbol.
+  unimplemented addressing mode
+    You tried to use 68020 "square-bracket" notation for a 68020 addressing mode. 
+    MADMAC does not support 68020 addressing modes.
+  unimplemented directive
+    You have found a directive that didn't appear in the documentation. It doesn't 
+    work.
+  unimplemented mnemonic
+    You've found an assembler for documentation) bug.
+  unknown symbol following ^^
+    You followed a ^^ with something other than one of the names defined, ref- 
+    erenced or streq.
+  unsupported 68020 addressing mode
+    The assembler saw a 68020-type addressing mode. MADMAC does not assem- 
+    ble code for the 68020 or 68010.
+  unterminated string
+    You specified a string starting with a single or double quote, but forgot to type 
+    the closing quote.
+  write error
+    The assembler had a problem writing an object file. This is usually caused by 
+    a full disk, or a bad sector on the media.
+
+34 MADMAC Reference Manual
+
+\f
+
+\f
diff --git a/mark.c b/mark.c
index ed76b4effc9116a5762d65bcbd4f9c73aab9d3bd..d593b21d6997adda8fbf45015fb0672bd48e586d 100644 (file)
--- a/mark.c
+++ b/mark.c
@@ -19,6 +19,10 @@ LONG mcalloc;                        // #bytes alloc'd to current mark chunk
 LONG mcused;                   // #bytes used in current mark chunk
 uint16_t curfrom;              // Current "from" section
 
+//
+//  Imports
+//
+extern int prg_flag;   // 1, write ".PRG" relocatable executable
 
 //#define DEBUG_IMAGE_MARKING
 
@@ -69,6 +73,21 @@ if (symbol)
        if (symbol != NULL)
                flags |= MSYMBOL;
 
+       //
+       //  Complain about some things are not allowed in `-p' mode:
+       //    o marks that aren't to LONGs;
+       //    o external references.
+       //
+       if (prg_flag)
+       {
+               if ((flags & MLONG) == 0)
+                       error("illegal word relocatable (in .PRG mode)");
+
+               if (symbol != NULL)
+                       errors("illegal external reference (in .PRG mode) to '%s'",
+                                  symbol->sname);
+       }
+
        mcused += sizeof(WORD) + sizeof(LONG);
        *markptr.wp++ = flags;
        *markptr.lp++ = loc;
@@ -126,6 +145,201 @@ int amark(void)
 }
 
 
+/*
+ *  Table to convert from TDB to fixup triad
+ *
+ */
+static char mark_tr[] = {
+       0,                              /* (n/a) */
+       2,                              /* TEXT relocatable */
+       1, 0,                           /* DATA relocatable */
+       3                               /* BSS relocatable */
+};
+
+
+/*
+ *  Make mark image for Alcyon .o file
+ *  okflag     --  1, ok to deposit reloc information
+ */
+LONG markimg(register char * mp, LONG siz, LONG tsize, int okflag)
+{
+       MCHUNK * mch;           /* -> mark chunk */
+       register PTR p;         /* source point from within mark chunk */
+       WORD from;                      /* section fixups are currently FROM */
+       register WORD w;        /* a word (temp) */
+       LONG loc;                       /* location (temp) */
+       LONG lastloc;           /* last location fixed up (RELMOD) */
+       SYM * symbol;           /* -> symbols (temp) */
+       char * wp;                      /* pointer into raw relocation information */
+       register char * dp;     /* deposit point for RELMOD information */
+       int firstp;                     /* 1, first relocation (RELMOD) */
+       LONG diff;                      /* difference to relocate (RELMOD) */
+
+       if (okflag)
+               //clear(mp, siz);               /* zero relocation buffer */
+               memset(mp, 0, siz);             /* zero relocation buffer */
+
+       from = 0;
+
+       for(mch=firstmch; mch!=NULL; mch=mch->mcnext)
+       {
+               for(p=mch->mcptr;;)
+               {
+                       w = *p.wp++;            /* w = next mark entry */
+
+                       if (w & MCHEND)         /* (end of mark chunk) */
+                               break;
+
+                       /*
+                        *  Get mark record
+                        */
+                       symbol = NULL;
+                       loc = *p.lp++;          /* mark location */
+
+                       if (w & MCHFROM)        /* maybe change "from" section */
+                               from = *p.wp++;
+
+                       if (w & MSYMBOL)        /* maybe includes a symbol */
+                               symbol = *p.sy++;
+
+                       /*
+                        *  Compute mark position in relocation information;
+                        *  in RELMOD mode, get address of data to fix up.
+                        */
+                       if (from == DATA)
+                               loc += tsize;
+
+                       wp = (char *)(mp + loc);
+
+                       if (okflag && (w & MLONG)) /* indicate first word of long */
+                       {
+                               wp[1] = 5;
+                               wp += 2;
+                       }
+
+                       if (symbol)
+                       {
+                               /*
+                                *  Deposit external reference
+                                */
+                               if (okflag)
+                               {
+                                       if (w & MPCREL)
+                                               w = 6;          /* pc-relative fixup */
+                                       else
+                                               w = 4;          /* absolute fixup */
+
+                                       w |= symbol->senv << 3;
+                                       *wp++ = w >> 8;
+                                       *wp = w;
+                               }
+                       }
+                       else
+                       {
+                               /*
+                                *  Deposit section-relative mark;
+                                *  in RELMOD mode, fix it up in the chunk,
+                                *  kind of like a sleazoid linker.
+                                *
+                                *  In RELMOD mode, marks to words (MWORDs) "cannot happen,"
+                                *  checks are made when mark() is called, so we don't have
+                                *  to check again here.
+                                */
+                               w &= TDB;
+
+                               if (okflag)
+                                       wp[1] = mark_tr[w];
+                               else if (prg_flag && (w & (DATA | BSS)))
+                               {
+                                       dp = wp;
+                                       diff = ((LONG)(*dp++ & 0xff)) << 24;
+                                       diff |= ((LONG)(*dp++ & 0xff)) << 16;
+                                       diff |= ((LONG)(*dp++ & 0xff)) << 8;
+                                       diff |= (LONG)(*dp & 0xff);
+
+#ifdef DO_DEBUG
+                                       DEBUG printf("diff=%lx ==> ", diff);
+#endif
+                                       diff += sect[TEXT].sloc;
+
+                                       if (w == BSS)
+                                               diff += sect[DATA].sloc;
+
+                                       dp = wp;
+                                       *dp++ = (char)(diff >> 24);
+                                       *dp++ = (char)(diff >> 16);
+                                       *dp++ = (char)(diff >> 8);
+                                       *dp = (char)diff;
+#ifdef DO_DEBUG
+                                       DEBUG printf("%lx\n", diff);
+#endif
+                               }
+                       }
+               }
+       }
+
+       /*
+        *  Generate ".PRG" relocation information in place in
+        *  the relocation words (the ``RELMOD'' operation).
+        */
+       if (okflag && prg_flag)
+       {
+               firstp = 1;
+               wp = mp;
+               dp = mp;
+
+               for(loc=0; loc<siz;)
+               {
+                       if ((wp[1] & 7) == 5)
+                       {
+                               if (firstp)
+                               {
+                                       *dp++ = (char)(loc >> 24);
+                                       *dp++ = (char)(loc >> 16);
+                                       *dp++ = (char)(loc >> 8);
+                                       *dp++ = (char)loc;
+                                       firstp = 0;
+                               }
+                               else
+                               {
+                                       for(diff=loc-lastloc; diff>254; diff-= 254)
+                                               *dp++ = 1;
+
+                                       *dp++ = (char)diff;
+                               }
+
+                               wp += 4;
+                               lastloc = loc;
+                               loc += 4;
+                       }
+                       else 
+                       {
+                               loc += 2;
+                               wp += 2;
+                       }
+               }
+
+               /*
+                *  Terminate relocation list with 0L (if there was no
+                *  relocation) or 0.B (if relocation information was
+                *  written).
+                */
+               if (!firstp)
+                       *dp++ = 0;
+               else for (firstp = 0; firstp < 4; ++firstp)
+                       *dp++ = 0;
+
+               /*
+                *  Return size of relocation information
+                */
+               loc = dp - mp;
+               return loc;
+       }
+
+       return siz;
+}
+
+
 //
 // Make mark image for BSD .o file
 //
@@ -336,3 +550,4 @@ printf("  rsize = $%X\n", rsize);
 
        return siz;
 }
+
index d8b4b577017d2729031544cf7639325960a65bdb..2702c54ad4dd4cdf586f63351d5fc6bb7d60474b 100644 (file)
--- a/object.c
+++ b/object.c
 #include "error.h"
 #include "riscasm.h"
 
+/*
+ *  Imports
+ */
+extern int obj_format;         // object file format to write
+extern int prg_flag;           // generate Atari ST direct executable
+
 LONG symsize = 0;                      // Size of BSD symbol table
 LONG strindx = 0x00000004;     // BSD string table index
 char * strtable;                       // Pointer to the symbol string table
@@ -71,6 +77,110 @@ char * constr_bsdsymtab(char * buf, SYM * sym, int globflag)
 }
 
 
+/*
+ *  Alcyon symbol flags
+ */
+#define        AL_DEFINED      0x8000
+#define        AL_EQUATED      0x4000
+#define        AL_GLOBAL       0x2000
+#define        AL_EQUREG       0x1000
+#define        AL_EXTERN       0x0800
+#define        AL_DATA         0x0400
+#define        AL_TEXT         0x0200
+#define        AL_BSS          0x0100
+#define        AL_FILE         0x0080
+
+
+static WORD tdb_tab[] = {
+       0,                              /* absolute */
+       AL_TEXT,                /* TEXT segment based */
+       AL_DATA, 0,             /* DATA segment based */
+       AL_BSS                  /* BSS segment based */
+};
+
+
+#define HDRSIZE 0x1C           /* size of Alcyon header */
+
+
+/*
+ *  Add entry to symbol table;
+ *  if `globflag' is 1, make the symbol global;
+ *  if in .PRG mode, adjust symbol values for fake link.
+ *
+ */
+char * constr_symtab(register char * buf, SYM * sym, int globflag)
+{
+       register int i;
+       register char * s;
+       register WORD w;
+       register LONG z;
+       register WORD w1;
+
+       /*
+        *  Copy symbol name
+        */
+       s = sym->sname;
+
+       for(i=0; i<8 && *s; i++)
+               *buf++ = *s++;
+
+       while (i++ < 8)
+               *buf++ = '\0';
+
+       /*
+        *  Construct and deposit flag word
+        *
+        *      o  all symbols are AL_DEFINED
+        *      o  install T/D/B/A base
+        *    o  install 'equated'
+        *    o  commons (COMMON) are AL_EXTERN, but not BSS
+        *      o  exports (DEFINED) are AL_GLOBAL
+        *      o  imports (~DEFINED) are AL_EXTERN
+        *
+        */
+       w1 = sym->sattr;
+       w = AL_DEFINED | tdb_tab[w1 & TDB];
+
+       if (w1 & EQUATED)               /* equated */
+               w |= AL_EQUATED;
+
+       if (w1 & COMMON)
+       {
+               w |= AL_EXTERN | AL_GLOBAL;     /* common symbol */
+               w &= ~AL_BSS;           /* they're not BSS in Alcyon object files */
+       }
+       else if (w1 & DEFINED)
+       {
+               if (globflag)           /* export the symbol */
+                       w |= AL_GLOBAL;
+       }
+       else w |= AL_EXTERN;            /* imported symbol */
+
+       *buf++ = w >> 8;
+       *buf++ = w;
+
+       z = sym->svalue;
+
+       if (prg_flag)                   /* relocate value in .PRG segment */
+       {
+               w1 &= DATA | BSS;
+
+               if (w1)
+                       z += sect[TEXT].sloc;
+
+               if (w1 & BSS)
+                       z += sect[DATA].sloc;
+       }
+
+       *buf++ = z >> 24;               /* deposit symbol value */
+       *buf++ = z >> 16;
+       *buf++ = z >> 8;
+       *buf++ = z;
+
+       return buf;
+}
+
+
 //
 // Write an object file to the passed in file descriptor
 // N.B.: Return value is ignored...
@@ -169,6 +279,82 @@ int WriteObject(int fd)
                        free(buf);                                      // Free allocated memory
 
                break;
+
+       case ALCYON:
+               /*
+                *  Compute size of symbol table;
+                *   assign numbers to the symbols...
+                */
+               ssize = 0;
+
+               if (prg_flag != 1)
+                       ssize = ((LONG)sy_assign(NULL, NULL)) * 14;
+
+               /*
+                *  Alloc memory for header+text+data, symbol and
+                *   relocation information construction.
+                */
+               t = tds = sect[TEXT].sloc + sect[DATA].sloc;
+
+               if (t < ssize)
+                       t = ssize;
+
+               buf = malloc((t + HDRSIZE) + HDRSIZE);
+
+               /*
+                *  Build object file header
+                *   just before the text+data image
+                */
+               chptr = buf - HDRSIZE;  /* -> base of header */
+               D_word(0x601a);                 /* magic number */
+               t = sect[TEXT].sloc;    /* TEXT size */
+               D_long(t);
+               t = sect[DATA].sloc;    /* DATA size */
+               D_long(t);
+               t = sect[BSS].sloc;             /* BSS size */
+               D_long(t);
+               D_long(ssize);                  /* symbol table size */
+               D_long(0);                              /* stack size (unused) */
+               D_long(0);                              /* entry point (unused) */
+               D_word(0);                              /* relocation information exists */
+
+               /*
+                *  Construct text and data segments;
+                *  fixup relocatable longs in .PRG mode;
+                *  finally write the header+text+data
+                */
+               p = buf;
+
+               for(i=TEXT; i<=DATA; i++)
+               {
+                       for (cp=sect[i].sfcode; cp!=NULL; cp=cp->chnext)
+                       {
+                               memcpy(p, cp->chptr, cp->ch_size);
+                               p += cp->ch_size;
+                       }
+               }
+
+               if (prg_flag)
+                       markimg(buf, tds, sect[TEXT].sloc, 0);
+
+               write(fd, buf - HDRSIZE, tds + HDRSIZE);
+
+               /*
+                *  Construct and write symbol table
+                */
+               if (prg_flag != 1)
+               {
+                       sy_assign(buf, constr_symtab);
+                       write(fd, buf, ssize);
+               }
+
+               /*
+                *  Construct and write relocation information;
+                *   the size of it changes if we're writing a RELMODed executable.
+                */
+               tds = markimg(buf, tds, sect[TEXT].sloc, 1);
+               write(fd, buf, tds);
+               break;
        }
 
        return 0;
diff --git a/rmac.c b/rmac.c
index ae44c750ded296248692f0a833cc478d45e4bf70..a7d1770b1a2348fc81ac1ccbedca0495c1f806df 100644 (file)
--- a/rmac.c
+++ b/rmac.c
@@ -29,6 +29,7 @@ int as68_flag;                                        // as68 kludge mode
 int glob_flag;                                 // Assume undefined symbols are global
 int lsym_flag;                                 // Include local symbols in object file
 int sbra_flag;                                 // Warn about possible short branches
+int prg_flag;                                  // !=0, produce .PRG executable (2=symbols)
 int legacy_flag;                               // Do stuff like insert code in RISC assembler
 int obj_format;                                        // Object format flag
 int debug;                                             // [1..9] Enable debugging levels
@@ -125,6 +126,7 @@ void DisplayHelp(void)
                "  -dsymbol[=value]  Define symbol\n"
                "  -e[errorfile]     Send error messages to file, not stdout\n"
                "  -f[format]        Output object file format\n"
+               "                    a: ALCYON (use this for ST)\n"
                "                    b: BSD (use this for Jaguar)\n"
                "  -i[path]          Directory to search for include files\n"
                "  -l[filename]      Create an output listing file\n"
@@ -246,6 +248,10 @@ int Process(int argc, char ** argv)
                                switch (argv[argno][2])
                                {
                                case EOS:
+                               case 'a':                       // -fa = Alcyon [the default]
+                               case 'A':
+                                       obj_format = ALCYON;
+                                       break;
                                case 'b':                       // -fb = BSD (Jaguar Recommended)
                                case 'B':
                                        obj_format = BSD;
@@ -283,9 +289,33 @@ int Process(int argc, char ** argv)
                                                errcnt++;
                                                return errcnt;
                                        }
+
                                        objfname = argv[argno];
                                }
 
+                               break;
+                       case 'p':               /* -p: generate ".PRG" executable output */
+                       case 'P':
+                               /*
+                                * -p           .PRG generation w/o symbols
+                                * -ps  .PRG generation with symbols
+                                */
+                               switch (argv[argno][2])
+                               {
+                                       case EOS:
+                                               prg_flag = 1;
+                                               break;
+
+                                       case 's':
+                                       case 'S':
+                                               prg_flag = 2;
+                                               break;
+
+                                       default:
+                                               printf("-p: syntax error\n");
+                                               ++errcnt;
+                                               return errcnt;
+                               }
                                break;
                        case 'r':                               // Pad seg to requested boundary size
                        case 'R':
@@ -412,7 +442,7 @@ int Process(int argc, char ** argv)
                        firstfname = defname;
 
                strcpy(fnbuf, firstfname);
-               //fext(fnbuf, prg_flag ? ".prg" : ".o", 1);
+               fext(fnbuf, (prg_flag ? ".prg" : ".o"), 1);
                fext(fnbuf, ".o", 1);
                objfname = fnbuf;
        }
@@ -433,7 +463,7 @@ int Process(int argc, char ** argv)
 
                if (verb_flag)
                {
-                       s = "object";
+                       s = (prg_flag ? "executable" : "object");
                        printf("[Writing %s file: %s]\n", s, objfname);
                }
 
diff --git a/token.c b/token.c
index 5f076a231cff1793394adaa0bba7a1a9b6fbed2d..ca38406e5707dd07c44abed620dad9b5f5bcdeb9 100644 (file)
--- a/token.c
+++ b/token.c
@@ -1204,26 +1204,61 @@ if (verb_flag) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n");
                                {
                                        v = 0;
 
+                                       // Parse the hex value
                                        while ((int)hextab[*ln] >= 0)
                                                v = (v << 4) + (int)hextab[*ln++];
 
+                                       // ggn: Okay, some comments here are in order I think....
+                                       // The original madmac sources didn't parse the size at
+                                       // this point (i.e. .b/.w/.l). It was probably done at
+                                       // another point, although it's unclear to me exactly
+                                       // where. So why change this? My understanding (at least
+                                       // from what SCPCD said on IRC) is that .w addressing
+                                       // formats produce wrong code on jaguar (or doesn't execute
+                                       // properly? something like that). So the code was changed
+                                       // to mask off the upper bits depending on length (note: I
+                                       // don't think .b is valid at all! I only know of .w/.l, so
+                                       // this should probably be wiped). Then the code that
+                                       // parses the constant and checks to see if it's between
+                                       // $ffff0000 and $8000 never got triggered, so yay job
+                                       // done! ...now say we want to assemble a st .prg. One of
+                                       // the most widely spread optimisations is move.X expr.w,Y
+                                       // (or vice versa, or both, anyway...) to access hardware
+                                       // registers (which are mapped to $fxxxxx). This botchy
+                                       // thing would create "hilarious" code while trying to
+                                       // access hardware registers. So I made a condition to see
+                                       // if st mode or jaguar is active and apply the both or
+                                       // not. One last note: this is hardcoded to get optimised
+                                       // for now on ST mode, i.e. it can't generate code like
+                                       // move.w $00001234,d0 - it'll always get optimised to
+                                       // move.w $1234.w,d0. It's probably ok, but maybe a warning
+                                       // should be emitted? Or maybe finding a way to make it not
+                                       // auto-optimise? I think it's ok for now...
                                        if (*ln == '.')
                                        {
-                                               if ((*(ln + 1) == 'b') || (*(ln + 1) == 'B'))
+                                               if (obj_format == ALCYON)
                                                {
-                                                       v &= 0x000000FF;
-                                                       ln += 2;
-                                               }
-
-                                               if ((*(ln + 1) == 'w') || (*(ln + 1) == 'W'))
-                                               {
-                                                       v &= 0x0000FFFF;
-                                                       ln += 2;
+                                                       if ((*(ln + 1) == 'b') || (*(ln + 1) == 'B') || (*(ln + 1) == 'w') || (*(ln + 1) == 'W') || (*(ln + 1) == 'l') || (*(ln + 1) == 'L'))
+                                                       {
+                                                               ln += 2;
+                                                       }
                                                }
-
-                                               if ((*(ln + 1) == 'l') || (*(ln + 1) == 'L'))
+                                               else
                                                {
-                                                       ln += 2;
+                                                       if ((*(ln + 1) & 0xDF) == 'B')
+                                                       {
+                                                               v &= 0x000000FF;
+                                                               ln += 2;
+                                                       }
+                                                       else if ((*(ln + 1) & 0xDF) == 'W')
+                                                       {
+                                                               v &= 0x0000FFFF;
+                                                               ln += 2;
+                                                       }
+                                                       else if ((*(ln + 1) & 0xDF) == 'L')
+                                                       {
+                                                               ln += 2;
+                                                       }
                                                }
                                        }
 
index f59c0dd0c935e0137626e650a278b4f12a81dfdc..31ce8213baab7eb71e7e5aeb5ce34719c6b95a46 100644 (file)
--- a/version.h
+++ b/version.h
@@ -13,6 +13,6 @@
 
 #define MAJOR   1              // Major version number
 #define MINOR   3              // Minor version number
-#define PATCH   6              // Patch release number
+#define PATCH   7              // Patch release number
 
 #endif // __VERSION_H__