@database snma.hyper
@node Main "Samu Nuojua's Macro Assembler, SNMA v1.90"
******************************************************
* *
* S N M A V1.90 *
* ~~~~~~~~~~~~~~~~~~~~~~ *
******************************************************
SNMA is 680x0 conditional macro assembler.
1. @{" Introduction " link intro} Blablaablaa....
2. @{" Usage " link HowTo} How to use (start).
3. @{" Features " link feature} Expressions, directives...
4. @{" ARexx " link arexx} ARexx interface
5. @{" Author " link Author} Me.
@endnode
@node intro "1. Introduction"
Introduction to Samu Nuojua's Macro Assembler, SNMA
SNMA is 680x0/6888x macro assembler. SNMA requires OS 2.0+.
If you have used some other assembler, snma should not throw big
suprises to your face (I hope). (Look at @{" things to note " link note})
1.1 @{" Copyright and other boring stuff " link legal}
1.2 @{" What you need " link need}
1.3 @{" How to Install " link install}
1.4 @{" Good & Bad things " link GoodBad}
1.5 @{" History " link History}
1.6 @{" Bug reports " link bug_report}
1.7 @{" Misc. " link nonsense}
@endnode
@node legal "1.1 Copyright ©"
SNMA stands for Samu Nuojua's Macro Assembler.
SNMA is © copyright 1993-1994 by Samu Nuojua.
All SNMA documents are © copyright 1993-1994 by Samu Nuojua.
SNMA is FREEWARE. I reserve all rights to SNMA. You can copy it as
long you don't ask payment (small fee is allowed to cover the expenses
of the possible disk/postage fee). Permission is granted to upload
SNMA to the bulletin boards and FTP sites. Also, you must provide all
the files supplied when you are copying SNMA to somewhere/somebody
(including all the documents).
DISCLAIMER:
~~~~~~~~~~
SNMA software and documents are provided 'as is'. No guarantee of
any kind is given what SNMA does or that information in files is
correct in any way. You are using this software at your own risk.
Author of SNMA is in NO WAY responsible for any losses or damage
caused by SNMA.
@endnode
@node need "1.2 What you need"
What you need to use SNMA to produce stand alone programs.
- AmigaOS 2.04 or higher (V37)
- Linker (to produce executables)
- Text editor (to write/edit programs)
- The following libaries:
V. Where note
~~ ~~~~~ ~~~~
- dos.library 37 in rom
- intuition.library 36 in rom
- utility.library 36 in rom
- icon.library any * in rom WB support
- mathieeedoubbas.library any * libs: fp support
- mathieeedoubtrans.library any * libs: fp support
- rexxsyslib.library 36 * libs: Arexx support
Libraries marked with * are not neccessarily required. Math
libraries are needed for the single and double floating point
conversions. 6888x or 680x0 with FPU is needed for the extended
floating point conversions. Rexxsyslib is needed for the Arexx
support and icon.library for the WB support (if snma is started
from the icon).
You need linker to produce executables. There are several choices,
snma should work with the ones which can deal with standard hunks.
I have used DLink (from the freely distributable DICE, not the
registered or commercial one, I don't know do they differ any way)
and that works just fine and is free.
Recommended:
- Hard Disk
- Manuals, manuals...
- Debugger
- Time (8')
- Development tools (Includes and so on)
*********************************************************************
* Remember, this isn't pascal, this is REAL programming. *
* - 68000 Assembly language, techniques for building programs *
*********************************************************************
(Good book (a bit old, however) by D.Krantz and J.Stanley).
@endnode
@node install "1.3 Installing SNMA "
There are couple of files to be copied. Installer ? Well, as soon as
I have some time to spare.
SNMA main file, copy somewhere under the search path if
using snma in shell mode. In arexx mode snma needs to
be started only once so its not so neccasary to be
under the search path. SNMA has now icon so it can be
started directly from the WB.
SNMA.guide Documents in AmigaGuide format. Copy anywhere you like.
examples/ Very simple example files.
arexx/ Arexx macros. Copy to the rexx: directory the ones
you are going to use.
See also examples/alias.txt file.
(User friendlies at the best 8'| )
@endnode
@node GoodBad "1.4 Good & Bad"
My personal view from this assembler.
Things are not in any particular order.
Good:
- It's free.
- Most common @{" directives " link Direc} are supported.
- Macros are supported.
- All 680x0, 6888x, 68851 and 68030 PMMU instructions are supported
- Does normal optimizations, including forward branches.
- It's not terribly slow.
- It's coded with assembler. (See below, Bad things).
- Enforcer was in duty all the time I coded, checked, debugged...
- Supports all data types of 680x0 6888x family (I think).
(FFP conversions not supported).
- @{" ARexx " link arexx} interface.
- Global symbol table
Bad:
- 68040/68060 instructions (those couple of) are not yet supported.
- All source files must fit to memory at the same time.
- Is coded with assembler. Messy code sometimes, my fault, my
problem. (Moral: Assembly is two edged sword).
- Doesn't support any small data model.
- Some kind of beginners help would be good (sources...).
- Only outputted format is Amiga object code.
- No LINE DEBUG HUNK (or whatever it is) nor any new hunks.
- This document is a translators nightmare!!!!
From the one (TK) who tried to fix english...
(Authors note: Oh, life is so hard. 8^)
- No GUI, but I'm not sure would it even be useful.
@endnode
@node History "1.5 History of SNMA"
Changes, fixes and additions I have made to SNMA
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
V1.90
o moveq didn't allow xref'd data.
o mc68xxx directives
o Command line additions ([-option])
o Object code naming now also checks ".s" and ".a" suffix.
o OBJ filename in template was ignored (oh my).
o tst with pc-relative was allowed on 68000 mode.
o ext_ref symbols with same name were written many times, causing
larger object file size (not actual code size).
o xdef symbols were written to the all sections.
o divu.l wasn't allowed.
o Equates with relative components are handled better now.
o Minimal WorkBench support
o \*VALOF() + other macro 'insert functions'.
o abslong to pc-relative optimizing.
o DC generated too much data if the 2nd operand of the
previous instruction was one which took some space.
o REPT/ENDR directives
o Global symbol table.
o In cases where reloc was needed didn't create it, when
symbol referred to equate which type was relative.
o Equates with relative components are no longer written to
the symbol list.
o CHDIR (AREXX) command called FreeVec with wrong argument,
causing memory loss (no crash, at least in my system).
V1.70
o BTST/BCHG/BSET/BCLR Dn,<ea> set always <ea> as d0. (uups)
o MOVEP didn't allow zero displacement.
o ENDC switched assembly on sometimes when it shouldn't.
V1.68
o Some minor bug fixes and changes (okay, I forgot them).
V1.65
o Address components which started with 'Z' or 'z' were
parsed to the totally wrong thing. (Bad one).
o IFGT did unsigned test, instead of signed.
o Didn't notice all cases when macro was already defined.
o Include <devicename:filepath> didn't work.
o Expression handler didn't catch all undefined symbols.
o AREXX, SET command.
o 'TST An' in 020+ mode wasn't allowed.
o Destination address mode optimizing in move instruction
generated spurious opcodes in some cases.
o Movem->move optimizing.
V1.60
o AREXX PORT finally added
o Several bugs fixed
o LONGBRA flag to the template
o ZAn no longer required if An omitted in addressing mode.
Probaply I don't remember all the changes and fixed bugs, but I
hope all the major ones are here.
First released version of SNMA is 1.39.
@endnode
@node bug_report "1.6 Bug reports"
Bug reports are WELCOME.
Please, state following facts:
1) Your system configuration (Model, CPU, MEM, OS, ...) and the
version of SNMA.
2) What you did. Source code which caused bug. If I can't make the
bug appear, it is awful task to find out what went wrong. If
possible try to isolate the bug, only tiny piece of code is
usually required to show it. Or if the bug is not directly
related to the source code, describe it well enough (in any
case).
If you find out something is implemented badly, something would
need a little polishing or something is missing, and things like that,
suggestions are welcome.
I'm also intrested does snma work in all (OS2.04+) Amiga models
with enough memory.
Where to report, see @{" author " link Author}.
----------------------------
--* fixed bug better bug *--
----------------------------
@endnode
@node nonsense "1.7 Misc., general things"
Some words from the inner working of SNMA
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SNMA is not traditional two pass assembler altough its operations
can be divided down to two stages. Source files are read and
parsed only once. SNMA creates its own internal structures in this
first pass. In the second pass, snma solves all undefined symbols,
optimizes code, recalculates the changed values (like pc-relative
stuff) and writes object code (and other requested files).
Listing file creation is sloooow. (I suspect the buffered IO, but
can't make sure because I don't have 3.1 where SetVBuf() actually does
something).
Memory usage of snma isn't the most economical, since all source
files must fit in the memory and the way I implemented all the
other stuff. Strip comments from the include files you use, because
that reduces memory usage.
As a memory usage example:
One source code module: size 25625 bytes, 1061 lines
with includes 7423 lines
SNMA uses 99403 bytes to store source files, 225356 bytes to the
all other stuff, total 324759 bytes.
The way I have implemented macros costs memory because snma needs
the produced macro lines to be in the memory in second pass where
expressions with relative and undefined symbols are re-calculated
and possible errors told. (SNMA won't read the source twice).
I know, the actual snma file is quite large also. Well, can't help
a lot anymore, without complete re-desing and re-write which is not
in my top ten list of how to spend the next years of my life.
(Actually I have managed to drop the size little).
The development of SNMA
~~~~~~~~~~~~~~~~~~~~~~~
I started the development of snma somewhere on the first half of
year 1993. I have coded SNMA entirely with the assembler, most of it
with a68k and minor parts with snma itself. It works pretty stable
in my system (A2000, GVP A3001 28Mhz 68030/882, 4M fast 1Mchip,
OS2.04). I'm developing it in my free time and have spend long
nights staring at my old 1081 and wondering what the **** is wrong
with everything.
Thanks
~~~~~~
I really must thank all you who have made so much wonderful
'Freely Distributable' software to Amiga.
Special thanks to the following people for the software I mainly
use while developing SNMA.
- Charlie Gibbs, A68k
- Matt Dillon, DME and DLink
- Aaron Digulla, XDME
- Steffan Becker, ToolManager
- Jorrit Tyberghein, PowerVisor.
@endnode
@node HowTo "2. How to use "
SNMA can be started from the Shell or from the WorkBench.
2.1 @{" Shell startup " link shell_startup}
2.2 @{" Workbench startup " link wbargs}
2.3 @{" Starting arexx host " link rexx_start}
@endnode
@node Shell_startup "2.1 Startup from shell"
SNMA can be started from the shell like 'traditional' assembler.
It parses it arguments using AmigaDOS 2.0 templates. Some of the options
can be specified also in the @{" 'old way' " link oldtemp}, i.e. with '-'.
These 'old way' arguments override the template arguments.
Command Line template:
SNMA
SOURCEFILE/A O=OBJ/K O=OBJ/K I=INCLUDE/K H=HEADER/K E=EQUATE/K
L=LISTING/K Q=QUICKOPT P=PCOPT A=ADDRESSOPT B=BASEFORCE S=SYMBOL
L=LONGBRA AREXX/S PORTNAME/K QUIET/S PAGELEN/K/N
Where:
SOURCEFILE is the name of the source file. It is a first
argument and must be there always.
OBJ defines the name of the object file.
alias: -o<name>
INCLUDE defines list of directories where @{" INCLUDE " link dir_include } directive
searches include files
alias: -i<namelist>
HEADER defines file to be included before any lines from
source file are assembled. Only one is allowed.
alias: -h[<name>]
EQUATE defines equate file name to be created. Empty
string is allowed, SNMA produces name from the
source file name. Currently equate file is
generated at the end of assembly. Symbols are taken
from the hash table, so they are in mixed order.
You can use AmigaDOS SORT command if you like some
sort of order.
alias: -e[<name>]
LISTING Listing file to be created. Minimal formatting can be
done by using PAGELEN option.
alias: -l[<name>]
QUICKOPT Quick optimizing flag, default: on
PCOPT pc-relative optimizing, default: off
ADDRESSOPT effective address optimizing default: on
BASEFORCE Auto-force (Bd,An)->(disp16,An) default: on
SYMBOL Write symbol data hunk default: off
LONGBRA Long branches (wo/size field) default: off
AREXX flag to start @{" AREXX " link arexx} command host SNMA.
Overrides others.
QUIET Disables output
PAGELEN Defines pagelen used in listing file. If null, snma
does not create pages (useful if you want to do
your own formatting).
Default: NULL.
See @{" Options " link dir_opt}.
SNMA does not check the stack anyway. I haven't had any problems with
stack size of 4000 bytes. You can overflow stack with very deep
expressions or very nested includes. One level on both cases takes
about 100 bytes, so very means here something like 40 levels. Actually
little less. If you worry about that, use bigger stack.
@{" Examples " link cliexample}
@endnode
@node oldtemp "2.1.1 template: old flags"
Many applications use the '-' as a option start character.
(like: a68k file.asm -l -iinclude:).
If you want just to flag that you want some file to be generated and
want snma to create the file name from the source name, you had to pass
empty string (like LISTING ""). I have to admit that this isn't very
elegant method and when trying to pass commands to arexx macros I had
several problems with the quotes. So, to allow easier use, couple of
'-' flags are also allowed in commandline. In template they show
as OLDFLAGS/M template. In the template explanation they are referred
as 'alias:'.
@endnode
@node cliexample "2.1.2 Command Line Examples"
prompt> SNMA mycode.asm obj mycode.o include myinc:
Mycode.asm is a source file, mycode.o is a object file and include
files are searched from the current directory and then from myinc:
directory.
prompt> SNMA mycode.asm Q on A off B off S on I work:,work2:inc
mycode.asm is a source file. Flags are set on and off. Include files
are searched from the current directory, work: and work2:inc.
prompt> SNMA mycode.asm EQUATE myequ
produces myequ.equ named equate file and mycode.o object code.
prompt> SNMA mycode.asm E ""
produces mycode.equ named equate file and mycode.o object code.
prompt> SNMA arexx
Starts SNMA @{" Arexx " link arexx} command host.
prompt> SNMA mycode.s -e -l -iinclude:
mycode.s is source code, -e and -l flags snma to produce equate and
listing file, and -iinclude: tells snma to search include files from
the include: directory.
@endnode
@node wbargs "2.2 Workbench support"
SNMA can be started from the Workbench, too. Its behaviour is
controlled with ToolTypes. SNMA can assemble file(s) or start Arexx
SNMA. You can disable ToolType removing it or setting it to parenthesis
"()".
Tooltypes:
~~~~~~~~~
AREXX flag to start snma in arexx mode.
PORTNAME=<name> AREXX port name. If omitted, uses default
(SNMA) name.
WINDOW=<file> Specify output file. If omitted, snma
will use its default output (CON:...). If
AREXX flag is set too, no default output is
created, if omitted.
See @{" Arexx/SET "link rx_set}.
The default tooltypes are so that AREXX snma will be started.
You can have many SNMAs running at the same time (altough it is not
very useful). If you click several times snma icon several SNMAs are
started, each with dirreferent portname. See @{" Arexx "link arexx}.
To stop SNMA you have to send QUIT command to it. Here's how you do it
from the shell:
->rx "address SNMA QUIT"
where "SNMA" is the name of the arexx port.
How to stop from the WB ? For example, use tool like ToolManager, and
create the "SNMA OFF" command which is just like the above shell
command.
If you want to assemble files playing with icons, I suggest you to use
for example ToolManager which makes your life a lot easier.
I added the WB support mainly because it may be helpful to start SNMA
in arexx mode from the icon.
If you start SNMA from the WB and pass it arguments (you have selected
other icons as well), SNMA will try to open WINDOW=<file>, if omitted
it will open its default output window. Then the passed file(s) is(are)
assembled just like in shell mode. SNMA won't check any of the
tooltypes of arguments and it does not check if there is already snma
arexx host where the assembly could be directed. (I strongly doubt
anyone will even use this method, but it was rather easy to implent so
there it is).
@endnode
@node rexx_start "2.3 Starting the arexx SNMA host"
SNMA can be started as arexx host and I suggest to use snma that
way.
Startup from:
- Shell use AREXX template
- WB use AREXX tooltype
See @{" Arexx " link arexx} section (4.).
@endnode
@node feature "3. Features of SNMA"
This section covers all the features of SNMA, relating to the actual
assembly process.
3.1 @{" Source code format " link source}
3.2 @{" Symbols " link symbol}
3.3 @{" Expressions " link express}
3.4 @{" Addressing modes " link eas}
3.5 @{" Directives " link Direc}
3.6 @{" Data types " link dtypes}
3.7 @{" Things to note " link note}
3.8 @{" Errors " link error}
@endnode
@node source "3.1 Source code format"
The format of the source code is 'standard'.
One line can be 256 bytes long (after macro expansion, too).
One source code line may have following components:
<Label> <opcode> <operands> <comment>
<Label> Label must start from the first column.
It may end to the colon (':').
Legal label chars are 'A-Z', 'a-z', '0-9', '_', '.'
or codes 127-255 (chars like äöåÞÐ).
First char must be: 'A-Z', 'a-z', codes 127-255, '_','.'
After that digits (0-9) are legal, too.
Local labels are supported. You have three alternatives
to define local label:
1) add '.' in front of it. For example: .local
2) add '\' in front of it. For example: \local
3) add '$' to the end of it. For example: local$
Local label can start also with a digit (actual label part).
(1$, .1,...)
<opcode> Opcode field is separated from the label field at least one
space. Opcode can be:
1) MC680x0 operation code (instruction).
2) Assembler @{" directive " link Direc}
3) Macro invocation
<operands> Operand field is separated from the opcode field at least
one space. Operand field may contain 0 to 9 operands,
depending from what is in the opcode field. Operands are
separated with comma (,).
<comment> Anything after the operand field is ignored and treated as
comment. Those MC680x0 instructions which don't have
operands ignore anything after the opcode field. Anything
after the ";" character is treated as comment. If the
character in the first column is "*" entire line is
comment or if the opcode is * it is ignored.
@endnode
@node symbol "3.2 Symbols in SNMA"
Symbols in SNMA have different meaning, depending on where they are
used.
Absolute symbols
~~~~~~~~~~~~~~~~
Absolute symbols are defined with the @{" EQU " link dir_equ} or @{" SET " link dir_set} directive. Symbols
may be local symbols same way as labels. See @{" label " link source} definition.
Absolute symbols refer to the numerical values.
@{" Example" link locsymb_example }
SNMA @{" pre-defines " link predefs} some symbols with SET directive.
Relative Symbols
~~~~~~~~~~~~~~~~
Relative symbols are labels, or equates which have relative symbols
in the expression which defines it. Only exception to this is expression
Relative-Relative which results absolute type. See @{" expressions " link express}
for the restrictions with the relative symbols.
"*" is special symbol and has the value of the program counter (PC).
For example:
data ds.b 100 ; define space 100 bytes
size equ *-data ; size gets value of 100 (abs type)
Register Equates
~~~~~~~~~~~~~~~~
Register equates are defined with @{" equr " link dir_equr} directive.
Register symbol refers to the register (Dn or An).
Register lists
~~~~~~~~~~~~~~
Register lists are only allowed in movem and fmovem instructions.
They are defined with @{" reg " link dir_reg} directive.
Register list refers to the list of registers.
Macro symbols
~~~~~~~~~~~~~
Macros are defined with @{" macro " link dir_macro} and @{" endm " link dir_endm} directives.
macro symbol refers to the defined macro.
@endnode
@node predefs "Pre-defined symbols"
SNMA pre-defines the following symbols with SET.
symbol name value
~~~~~~~~~~~ ~~~~~
SNMA 0
snma 0
NARG 0 (actually number of args in macro call)
M68000 1
M68010 2
M68020 4
M68030 8
M68040 16
M68881 512
M68882 512
M68851 2048
F040 1024
These symbols are case-sensitive. 'SnMa' is not same as 'SNMA'.
M68xxx symbols are meant to be used with @{" cpu " link dir_cpu} directive.
See also @{" register names " link regnames}.
@endnode
@node regnames "Register names"
SNMA uses the following register names:
D0-D7 A0-A7 SP CCR SR SFC DFC CACR USP VBR CAAR MSP ISP FP0-FP7 FPCR
FPSR FPIAR TT0 TT1 TC DRP SRP CRP CAL VAL SCC AC MMUSR PSR PCSR
BAD0-BAD7 BAC0-BAC7
Registers from the CCR in above list are special registers. If
the name of special register is only component of address mode (like
'lea CAL,a0') snma thinks it to be special register. If the name
of special register is one of the components of address mode (like 'lea
(CAL,pc),a0') it is treated as a normal symbol. However, to avoid any
confusion, I strongly suggest you to use these names only when refering
to the special registers.
@endnode
@node express "3.3 Expressions in SNMA"
Expressions can be used almost anywhere where numerical
component(s) is(are) needed. Only exception is floating
point numbers which don't allow expressions. Expressions use
32 bit integer math.
Expressions may have: 1) symbols, 2) constants, 3) operators,
4) parenthesis.
1) @{" Symbols " link symbol} must be absolute or relative ones.
2) Constants are numbers. They can be decimal, hexadecimal ($), or
in binary (%) form. Sorry, I'm too lazy to do octal conversion, but if
somebody really needs it, I may add it (never,ever used
it by myself).
3) operators
- Unary minus
~ bitwise NOT (one's complement)
<< or < left shift
>> or > right shift
& bitwise AND
! or | bitwise OR
* multiply
/ divide
+ add
- subtract
4) Parenthesis are (). They can be nested.
For example: 3*((12-6)/(2+2))
Expressions are either absolute or relative, depending from the
types of the symbols and operators. Relative symbols are allowed
only to add and sub operands. When expression is evaluated, it is
divided to the sub-expressions down to stage <number operand number>,
where number can be symbol. This sub-expression gets its own sub-type.
Confusing ? See below.
For example: (Rel2-Rel1)/4 is legal expression, because
the type of Rel2-Rel1 is absolute although they both
are relative symbols. See the table below.
Following table tells types of expressions.
A = Absolute , R = Relative, - = not allowed
Operator operands
~~~~~~~ ~~~~~~~~
A op A A op R R op A R op R
+ A R R -
- A - R A
*, /, &, !, <<, >> A - - -
@endnode
@node locsymb_example "Local symbol example"
Following example demonstrates local and global symbols.
; start-----------------------------------------
num equ 123 ; define global symbol
start:
.num equ 10 ; define local symbol
move.l #.num,d0 ; move 10 to d0
move.l #num,d1 ; move 123 to d1
new:
.num equ 23 ; define local symbol
move.l #.num,d0 ; move 23 to d0
move.l #num,d1 ; move 123 to d1
rts
end
; end-----------------------------------------
@endnode
@node eas "3.4 Address modes"
SNMA supports all the addressing modes of the 680x0.
SNMA supports Motorola's new addressing mode format as well as
the old one. I don't have any of the Motorala's manuals, but I have
seen enough 'new format' sources. The actual change is more cosmetic, I
think. ( Aku(a0) is in new format (Aku,a0)).
Forcing the size
~~~~~~~~~~~~~~~~
In some places, you can force value to be either word or long word.
This is generally used to force something to the word size, but it
can be used to force something to the long size, too. Forcing is
implemented adding .w (for word) or .l (for long word) suffix to
the symbol. For example, 'move.l (4.w),a0'.
Note1: Above addressing mode is optimized when using simple 'move.l
(4),a0'. 'move.l (4.l),a0' would not allow optimizing because
of the force suffix.
Note2: SNMA won't complain mode (4).w, but it ignores the forcing
suffix. Above mode is discouraged anyway if you take a look to
the new addressing mode syntax of Motorola. At least in SNMA.
Base displacement modes (including Memory Indirect)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can force Base Displacement and Outer Displacement to be a long
word or word with .l (long) or .w (word) suffix.
For example: ([BD.w,A0,d1.w],OD.l) where BD and OD are
symbols.
SNMA will optimize addressing modes to the best possible. If certain
components are omitted change to the quicker mode can be made. When you
force some value with .l or .w, value must be within range and even if
actual value would be optimized it is not, because it is forced.
Example:
jsr (BD.w,a6)
BD equ 0
; Although BD is null, generated addressing mode will be disp16(An)
; because we forced BD to be word.
tst.l (BD,a0)
BD equ 0
; This will generate addressing mode (An)
; end of example
Same thing applies to the Outer Displacement, except that addressing
mode is always Memory Indirect if there is OD.
Don't care, if above is confusing. You don't have to force usually
anything, SNMA optimizes best mode for you. If you want some value
to be exactly specified size (when importing value, for example)
forcing is handy feature.
No Address Register in addressing mode
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When address register is not part of address generation you have two
ways to exclude it. First, just don't set it (like (d2.l) ). Then you
can always use Zero Suppressed address register using name ZAn (n does
not matter) instead of An. For example,
(10,d3.l) = (10,za0,d3.l)
(d1.l) = (za0,d1.l)
(10,a2.w) = (10,za0,a2.w) index register is An
You may wonder what the <---> is this Zero suppress stuff. The book
I used as a reference manual mentioned it and I fool didn't realized it
until now (long time passed) that index register has suffix stuff which
says : HEY ! I'm the index register. Oh well...
Immediate values
~~~~~~~~~~~~~~~~
SNMA checks immediate values so that they are in range, depending from
the size of the instruction. Immediate values can also be longer than
32 bits if instruction is some fpu/mmu instruction. FPU instructions
allow real mode definition of the number like -11.13232e-2.
FP values are not checked.
Optimizing Address modes
~~~~~~~~~~~~~~~~~~~~~~~~
Address modes are optimized very well in SNMA. Forward optimizing is
also included. See @{" OPT " link dir_opt} directive. See above for
more information. I suggest that you keep addressing mode optimizing on,
ecspecially when the 68020+ mode is on, because the way SNMA works.
(You will get definetely the worst addressing mode if the symbols
are not defined when the line is assembled first time).
@endnode
@node Direc "3.5 Directives"
The following directives are supported:
@{" CNOP " link dir_cnop } Conditional NOP
@{" CNUL " link dir_cnul } Conditional NULL
@{" CPU " link dir_cpu } Define CPU ID type
@{" DC " link dir_dc } Define Constant
@{" DCB " link dir_dcb } Define Constant Block
@{" DS " link dir_ds } Define Space
@{" ELSEIF " link dir_elseif } Conditional assembly toggle
@{" END " link dir_end } End of source file
@{" ENDC " link dir_endc } End conditional assembly
@{" ENDIF " link dir_endc } Alias for endc
@{" EDNM " link dir_endm } End macro definition
@{" ENDR " link dir_endr } End repeat block
@{" EQU " link dir_equ } Define symbol value
@{" EQUR " link dir_equr } Define register equate
@{" EVEN " link dir_even } Ensure PC is even
@{" FAIL " link dir_fail } User error
@{" IDNT " link dir_idnt } Set program unit name
@{" IFC " link dir_ifc } Assemble if strings equal
@{" IFcc " link dir_ifcc } Assemble if condition true
@{" IFD " link dir_ifd } Assemble if symbol defined
@{" IFNC " link dir_ifnc } Assemble if strings not equal
@{" IFND " link dir_ifnd } Assemble if symbol undefined
@{" INCBIN " link dir_incbin } Include Binary
@{" INCDIR " link dir_incdir } Include directory list
@{" INCLUDE " link dir_include} Include source file
@{" LIST " link dir_list } Turn on listing file generation
@{" MACRO " link dir_macro } Start macro definition
@{" MC680x0 " link dir_mc68000} CPU mode
@{" MEXIT " link dir_mexit } Exit from macro
@{" NOLIST " link dir_nolist } Turn off listing file generation
@{" OPT " link dir_opt } Define options
@{" REG " link dir_reg } Define register list
@{" REPT " link dir_rept } Start repeat block
@{" SECTION " link dir_section} Start new section
@{" SET " link dir_set } Define SET value
@{" XDEF " link dir_xdef } Export symbol
@{" XREF " link dir_xref } Import symbol
@endnode
@node dir_cnop "CNOP directive "
Conditional NOP. This directive is used to align data arbitrarily.
CNOP offset,alignment
Offset is value which is added to the alignment.
Alignment is alignment boundary value.
cnop 0,4 aligns pc to the long word boundary.
cnop 2,8 align pc to the 8 byte boundary plus two bytes.
@endnode
@node dir_cnul "CNUL directive "
CNUL offset,alignment
Conditional NULL. Same as @{" CNOP " link dir_cnop}, but instead of NOP directive, pads with
null word.
@endnode
@node dir_cpu "CPU directive "
CPU <expression>
Defines what kind of instructions are legal. This is also used to FPU
and MMU instructions.
Expression is simple numerical value which is set to the internal SNMA
variable (CPU command is only way to set it, it is not a symbol).
See @{" Pre-defined symbols " link predefs}.
M68000
M68010
M68020
M68040
M68851 MMU
M68881 FPU
M68882 FPU same as M68881
F040 MC68040 floating point only
M030 68030 MMU
Examples:
CPU M68000 enables 68000 instructions
CPU M68000!M68010!M68020 enables instructions of those cpu's.
CPU M68020!M68030!M68881 enables FPU instruction also.
This directive can be used so that if code is wanted to be run in
M68000 machines you can check that there are no other instructions
than those which MC68000 recognizes. All combinations are possible.
CPU -1 enables all instructions to be assembled. SNMA performs "CPU -1"
in the beginning of the assembly.
See also @{" MC680x0 " link dir_mc68000} directives.
@endnode
@node dir_dc "DC directive "
Define Constant
DC.n <expression> or <single value>
n is size of data.
See @{" Data types " link dtypes}.
dc.b 2+1 reserves one byte and sets 3 to its value.
dc.l 12 reserves long word and sets 12 to its value
dc.s $FEEBD00D reserves long word and sets it to $FEEBD00D
dc.d +12.9292e-2 reserves two long words and sets its value what
that number is in double format (binary).
Expressions are only valid to the integers. Expressions with the
floating point numbers are not allowed.
If n is not defined, default is word.
@endnode
@node dir_dcb "DCB directive"
Define Constant Block
dcb.n <abs expression>,<value>
Reserves space for given data type (n). All entries are set to single
value which is given as second argument. See @{" Data types " link dtypes}.
@endnode
@node dir_ds "DS directive"
Define Space
DS.n <abs expression>
Defines storage for given data type (n).
ds.b 12 reserves space for 12 bytes
ds.l 3 reserves space for 3 longs (12 bytes)
ds.x 4*4 reserves space for 16 extended type fp number.
(192 bytes)
<abs expression> must be evaluated and it cannot contain relative
symbols (or undefined by far).
All reserved space is set to null.
See @{" Data types " link dtypes}.
@endnode
@node dir_elseif "ELSEIF directive "
ELSEIF toggles conditional assembly. If assembly was off, it
toggles it on and vice versa.
Warning! This one does NOT WORK as it should, when conditional assembly
nests. (I should fix that...).
@endnode
@node dir_end " End Directive"
End directive ends assembly. It is not required to be in the end of
source file. When source file ends it also ends assembly.
Anything after END directive is not assembled.
@endnode
@node dir_endc " ENDC directive"
ENDC (alias ENDIF)
Toggles off conditional assembly if nest count match.
@endnode
@node dir_endm "ENDM directive "
ENDM
Ends current macro definition.
@endnode
@node dir_endr "ENDR directive "
ENDR
Ends current repeat block.
See @{" REPT " link dir_rept}.
@endnode
@node dir_equ "EQU directive"
EQUate.
symbol EQU <expression>
Sets the value of the symbol to <expression>. Symbol and
<expression> are both required. = is equivalent to equ.
See @{" Expressions " link express}.
Floating point numbers are supported by specifying size field to
the EQU.
See @{" Data types " link dtypes}.
Only floating point data types are supported in equ if n suffix is
there. (You can't 'equ.b 5').
When symbol is used as part of fpu instruction simple type checking
is done, but only between floating point types.
The following code would cause ERROR:
NUM equ.d +11.234343
fmove.s #NUM,fp0
To fix this, change NUM to single or fmove to double.
NUM equ.d +11.234343
fmove.d #NUM,fp0 declared type same as used type !
The following code would not cause error, because fmove uses long type
which is not floating point type (okay, it would be good to check
anyway).
NUM equ.d 12.23232
fmove.l #NUM,fp0
@endnode
@node dir_equr "EQUR directive "
EQUR means register equate.
It allows register to be addressed as symbols.
Register equates must de defined before used.
Example:
count equr d0
move.l #0,count ; means move.l #0,d0
@endnode
@node dir_even " EVEN directive"
EVEN aligns PC to be divisible by two if it is not already. It does
same thing as cnop 0,2 See @{" CNOP." link dir_cnop}.
@endnode
@node dir_fail "FAIL directive"
FAIL flags assembler to stop assembling. It is used to flag user
errors. It may be used if macro call won't get enough parameters,
for example.
@endnode
@node dir_idnt "IDNT directive "
IDNT <name>
Sets name of program unit to <name>.
@endnode
@node dir_ifc " IFC directive"
IFC 'string1','string2'
If string1 = string2 DO assemble.
See also @{" IFNC " link dir_ifnc}.
@endnode
@node dir_ifcc " IFcc directives"
IFcc <expression>
IFcc is conditional assembly control directive.
cc is condition. Expression is tested against the value of zero.
directive means
~~~~~
IFEQ <expression> EQual
IFNE <expression> NEqual
IFGT <expression> Greater Than
IFGE <expression> Greater or Equal
IFLT <expression> Lower Than
IFLE <expression> Lower or Equal
If condition is true, assembling is continued. If condition is false
assembling is turned off. @{" ENDC " link dir_endc} directive ends
conditional assembling.
@endnode
@node dir_ifd " IFD directive"
IFD <symbol>
Conditional assembly trigger.
IF symbol is defined, do assemble, else don't.
See also @{" IFND " link dir_ifnd}.
@endnode
@node dir_ifnc " IFNC directive"
IFNC 'string1','string2'
If string1 <> string2 DO assemble.
See also @{" IFC " link dir_ifc}.
@endnode
@node dir_ifnd " IFND directive "
IFND <symbol>
Conditional assembly trigger.
IF symbol is not defined, do assemble, else don't.
See also @{" IFD " link dir_ifd}.
@endnode
@node dir_incbin " INCBIN directive"
INCBIN <file>
Incbin directive includes file to the code in its binary form. No
assembling is done to the file. If you have file named bin and it
contains following data in hex form (4 bytes long file):
0BAD BEEF
Now..
IncBin bin
would do same as
dc.l $0BADBEEF.
If the length of the file is not even, extra null byte is added to
the end of the data when it is set to the produced code. This makes
sure that the program counter stays aligned. This is just the same as
the Incbin without this feature (in SNMA this feature is always on):
incbin <file>
even
Thus, above 'even' is done automatically (always) by 'incbin' and is
unnecessary in SNMA.
@endnode
@node dir_incdir "INCDIR directive "
INCDIR <mydir1>[,mydir2,mydir3...]
INCDIR directive adds directories to the directory list where
INCLUDE files are searched from.
INCBIN uses this list, too.
@endnode
@node dir_include " INCLUDE directive "
INCLUDE <file>
Starts to assemble <file>. After it has been assembled, continues
assembling after INCLUDE directive.
Include files are searched first from the current directory, then
from directory list which can be defined in @{" command line " link HowTo 9}
or with @{" INCDIR " link dir_incdir} directive. If include file is
not found assembly is stopped right there (fatal error).
When snma is in arexx mode it can have global include tables. If <file> is
already in global table, it is skipped (not even loaded to the memory).
See @{" ADDGB " link rx_addgb}.
@endnode
@node dir_list "LIST directive"
LIST turns on listing file generation. You can disable portions
(like includes) of listing file to be generated with LIST and
@{" NOLIST " link dir_nolist} directives. These don't nest.
@endnode
@node dir_macro "MACRO directive "
<Symbol> MACRO
Starts macro definition. Code inside macro definition is not assembled
yet. It is assembled when macro is called. NARG symbol is set to
number of arguments passed to macro, when macro is called.
Backslash ("\") has special meaning in macro definition. If character
after it is:
1) 1-9 insert argument number <number>
2) 0 insert size field of macro call
3) @<label> produces unique label (like local labels).
4) *<function()> executes special function
;------------------------------------------------------
simple example:
Do macro
move.\0 \1,\2
endm
Do.b d0,d1 ; produces move.b d0,d1
;------------------------------------------------------
Special functions (4) insert result string to the macro. If there is
error actual function call is inserted. These 'functions' do not nest,
BUT you can define macro arguments in the argument of function (like
\*valof(\1)).
The parenthesis are required always because there must be some
way to tell when 'function' ends.
\*VALOF(expression) inserts the numerical value of expression.
This expression is only solved during
pass1. If expression has relative
components, optimizing may change it but
the change is NOT reflected here. Also,
expression must be already defined.
\*DATE(format) inserts the current date string of the system.
Format char format type
~~~~~~~~~~~ ~~~~~~~~~~~
d DOS (dd-mmm-yy)
i INT (yy-mmm-dd)
u USA (mm-dd-yy)
c CND (dd-mm-yy)
DATE() uses dos/datestamp.
\*TIME() inserts current system time
TIME() uses dos/datestamp.
\*VAR(name) inserts local or global (ENV:) dos variable
using dos/GetVar().
\*STRLEN(string) insert lenght of string
\*UPPER(string) converts string to uppercase
\*LOWER(string) converts string to lowercase
DATE macro
dc.b 'Assembling Date: \*DATE(d)',0
endm
@endnode
@node dir_mc68000 "mc680x0 directives"
The following directives are shortcut to the cpu directive.
mc68000
mc68010
mc68020
mc68030
mc68040
mc68881
mc68882
They do same as @{" CPU " link dir_cpu} with single argument, which is one of the types
of cpu. MC68881 (mc68882) enables also 68020 (68030). Using CPU
directive, you can control arbitrarily the value of CPUID.
mc68040 is bit useless now because I still don't know the 68040
specific instructions (expect floating point).
@endnode
@node dir_mexit "MEXIT directive "
MEXIT
Exit from macro definition.
When macro is called it may be useful to exit from macro expansion
before actual macro ends.
Used usually in conditional macros.
@endnode
@node dir_nolist "NOLIST directive"
NOLIST directive turns off listing file generation.
See also @{" LIST " link dir_list} directive.
@endnode
@node dir_opt " OPT directive"
OPT flag[,flag,flag...]
where flags are:
Q Quick optimizing. Move->moveq, add->addq,sub->subq
whenever possible. Also movem -> move if only one reg.
Default: on
P Absolute long addressing -> program counter relative
whenever possible.
Default: off
A Effective address optimizing. 0(An)->(An), BD and OD
optimizing if 0 or word. (BD,An)->dip16(An) if possible.
Optimizes address modes as quick as they can be.
Default: on
B Auto-force (BD,An) -> disp16(An). This can be overridden
disabling this flag or using .l suffix in the symbol.
(BD.l,An) makes addressing mode always long, no matter of
the B flag. This feature is there because routines of the
run-time libraries can all be called by (disp16,An) mode.
Often displacement is xref'd symbol which is solved during
linking time. Because symbol is xref'd it must be treated
like being 32 bit because in theory it can be so. All
library calls however can use (disp16,An) mode. This method
is provided so that you don't have to add .w extension to
all calls. Default: on
S If flag is on, symbol hunks are written to the object file.
This is handy when used with symbolic debuggers.
Default: Off
L Long braches. If on Bcc instructions without size specifier
are first treated long branches. If this flag is off they
are converted to word braches (but they may change to the
byte if possible).
Default: Off
Example:
OPT S,P+,B-
Write symbol hunks, Optimize Absolute long -> pc-relative, Disable
Auto-forcing of (BD,An).
@endnode
@node dir_reg "REG directive "
Symbol REG <reg-list>
REG directive specifies register list used by movem instruction.
List may contain symbolic register name defined by equr.
Symbolic register lists must be defined before used.
Symbols defined by REG can be used only with movem instruction.
<reg-list> may be omitted. If <reg-list> is empty, movem
instruction, which uses empty list, is not generated.
example:
list reg d0-d3/a0-a2/a5
movem.l list,-(sp) push registers to stack
nop
movem.l (sp)+,list pop registers from stack
@endnode
@node dir_rept "REPT directive "
REPT <num>
Starts repeat block. <num> specifies how many times repeat block is
repeated.
Example
rept 100 ; clear 400 bytes
clr.l (a0)+
endr
See @{" ENDR " link dir_endr}.
Don't define things inside repeat block or use include or anything
like that.
@endnode
@node dir_section " SECTION directive"
SECTION <name>[,<type>[,<mem type>]]
Start new section. Name of the section is set to <name>.
Type of the section is one of these:
CODE CODE_C CODE_F
DATA DATA_C DATA_F
BSS BSS_C BSS_F
_C extension specifies mem type (C=CHIP, F=FAST).
<mem type> specifies the type of the memory where hunk should be
loaded. It can be specified with <type> field by extension or with
separate third argument which is CHIP or FAST.
@endnode
@node dir_set " SET directive"
<Symbol> SET <number>
With SET you can define symbol whose value can be changed
arbitrarily later on. You can 'equ' set symbol but then it becomes
absolute symbol which cannot be changed anymore.
@endnode
@node dir_xdef "XDEF directive "
XDEF <symbol>[,<symbol>[,<symbol>...]]
Define external symbol. Defines symbol value to be visible to other
modules. (Export).
@endnode
@node dir_xref "XREF directive "
XREF <symbol>[,<symbol>[,<symbol>...]]
External reference to symbol. Defines label to be imported from
other modules.
@endnode
@node dtypes "3.6 Data types"
Supported data types.
All data types are NOT supported by ALL instructions.
Directives which support:
DC.n
DCB.n
DS.n
EQU.n (all integers are 32 bit values and they are defined without
suffix).
n is one of these. size
~~~~~~~~~~~~~~~~~ ~~~~
b = byte ( 1 byte )
w = word ( 2 bytes)
l = long word ( 4 bytes)
s = single precision floating point number ( 4 bytes)
d = double precision floating point number ( 8 bytes)
x = extended precision floating point number (12 bytes)
p = packed floating point number (12 bytes)
Used K-factor is 17 with packed type.
@endnode
@node note "3.7 Things to Note"
Things to note when using SNMA.
@{" 3.7.1 Instructions " link note_inst }
@{" 3.7.2 Expressions " link note_exp}
@{" 3.7.3 Include files " link note_include}
@{" 3.7.4 Directives " link note_dir}
@{" 3.7.5 Misc. " link note_misc}
@endnode
@node note_inst "3.7.1 Notes about instructions"
@{" Bcc " link ins_bcc} (bsr, bra, beq,...) instructions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- If there is no size field (like bra or bsr ) SNMA tries to optimize
branch to the shortest one. If the size field is given (like bsr.w)
SNMA belives that it is just what is wanted, and doesn't try to
optimize instruction.
If the size field is omitted:
- LONGRA flag tells to SNMA whether to use long or word size.
LONGBRA=on enables long braches in these cases and
LONGBRA=off disables longs, forcing SNMA to use word size branches.
- If the value is external reference, SNMA won't optimize it. Instead,
depending on LONGBRA flag (and CPU mode) it may be set to long
or word.
- Currently, if you Bcc to other module and SNMA ends up to long branch,
things go wrong. I have to dig out what's in in those new hunks my old
bantam book knows nothing at all. Until then, be warned...
(Change to jsr could be made but I'm searching more elegant method).
SNMA should really warn if this happens.
@endnode
@node ins_bcc " Bcc instruction "
Bcc instruction. (Also bsr).
Sizes: .s .b (byte)
.w (word)
.l (long)
@endnode
@node note_exp "3.7.2 Notes about the expressions"
The Check of the data sizes
~~~~~~~~~~~~~~~~~~~~~~~~~~~
SNMA checks that specified data fits where it is set. For example if
you have instruction move.w #100000,d0 SNMA tells you that value won't
fit to word. Positive number range is unsigned and negative signed.
Remember that when using NOT (~) operation all 32 bits are affected,
not only parts of it.
Range check can be annoying if you are using NOTs with bit masks and
other sizes than long word. (Hint: you can mask values with AND). The
check of the ranges of SNMA is revealed some bugs (value too big to
fit in byte) which were not noticed when using a68k, so I think it is
useful feature.
@endnode
@node note_include "3.7.3 Notes about the include files"
SNMA assembles V37 includes just fine.
The V40 includes which I get from the NativeDeveloperKit3.1 have
very little problems with SNMA.
devices/conunit.i has some weird parenthesis '<' and '>' or at least
I think they are parenthesis. I don't know which assembler uses these
but I don't like them to be parenthesis. So fix them if you like to use
conunit.i with SNMA.
NOTE: I haven't tried all possible macros, so I don't claim all
macros will work as intended. If you have problems @{" report " link bug_report} is
welcome.
StripC tool which is in the NDK3.1 won't handle exec/macros.i, BTW.
@endnode
@node note_dir "3.7.4 Notes about the directives"
The OPT directive format is not neccesarily same in other assemblers.
CPU directive works little bit differently than the MACHINE directive
found in some assemblers. So, to avoid any confusion I implemented CPU
directive instead.
@endnode
@node note_misc "3.7.5 Misc. notes "
Alignement problems
~~~~~~~~~~~~~~~~~~~
SNMA does not produce mis-aligned code. One thing to mention:
;-----------
s dc.b 'arg' line 1
sl = *-s line 2
dc.w 0 line 3
;-----------
Value of 'sl' will be 4 instead of intended 3. SNMA 'adjusts' dc.b in this
case with one null byte. To prevent this (so that 'sl' will get the
right value) , add EVEN or CNOP between line2 and line3. (It is good
practice to have EVEN or CNOP 0,4 after 'DC.B's anyway).
@endnode
@node error "3.8 Error messages of SNMA"
The error messages of SNMA are quite self-explaining. Error may be
"DEAD END" error which means that assembling cannot be continued.
Object file is NOT produced if there is even one error. If there
is old object file it is deleted so you don't link it by accident.
There are couple of warnings,too. Grammar of the error messages is
quite awful, by the way, but I hope you get an idea what caused error
(I hope you understand this guide, too).
First char of the possible cause of the error is underscored.
This might be sometimes in wrong spot, so don't wonder if you think
the error is somewhere else (it sure can be). I added this feature later
on and there are quite a lot of places I should adjust so that error column
would be in right spot always. When I found it is in wrong place I
usually (or sometimes) try to fix the problem, which is not quite big
one, however.
When error is in the macro you get two messages in SHELL interface.
First one tells where the error is in macro and 2nd one where the macro
call is which caused error. Error count is added by one, however,
because there is only one error, expect in @{" AREXX " link arexx} mode
where both are counted.
When the error is found in pass 2 (solving undefined symbols...) you
get only one error message when error is in macro, however. This thing
needs some work to do but you can see where the error is quite easily
even now (well, not always...8-( )
If you get an error which says its internal bug or something similar,
@{" bug report " link bug_report} is welcome.
You can control error message mechanism with @{" AREXX/SET " link rx_set} command.
@endnode
@node arexx "4. SNMA, ARexx "
ARexx interface is implemted as a command host.
PORTNAME keyword in template can be used to change the basename
of the Arexx port. Default basename is SNMA.
RexxMaster must be running when using snma in arexx mode.
SNMA itself cannot execute any Arexx macros, it is simple command host.
4.1 @{" General " link rx_general}
4.2 @{" Commands " link rx_cmd}
4.3 @{" Examples " link rx_example}
SNMA's ARexx port is the first one I wrote so it may need little
more polishing, but it works the way I want. Totally different
question is, is that way the right one...8^)
@endnode
@node rx_general "4.1 general arexx stuff"
GENERAL AREXX THINGS
~~~~~~~~~~~~~~~~~~~~
I recommend to use snma as arexx host. Calling snma directly from the
text editor and using global symbol table make the development much
quicker. If you have problems in writing interface macros to the text
editor you use, you can always use the ShellAsm.rexx macro. The
interface is basicly same as in snma's shell mode. That way you can
still use global tables. Also, snma is in the memory all the time, no
load time here neither.
Its possible to display error messages as in shell mode when snma is in
arexx mode. SNMA writes the messages to the default output if you want
(you can always redirect the default output wherever you want, for
example to the con:). See @{" AREXX/SET " link rx_set} command.
There are lots of possibilities how to use snma, be creative !
(As usual).
@endnode
@node rx_cmd "4.2 ARexx commands of SNMA"
Many commands use RexxVariableInterface to pass information back.
4.2.1 @{" ASM " link rx_asm} Assemble file
4.2.2 @{" CHDIR " link rx_chdir} Change working directory
4.2.3 @{" FREE " link rx_free} Free resources of last assembly
4.2.4 @{" GETERR " link rx_geterr} Get the errors
4.2.5 @{" INFO " link rx_info} Get info about the last assembly
4.2.6 @{" QUIT " link rx_quit} Quit SNMA (ARexx)
4.2.7 @{" SET " link rx_set} SET attributes
4.2.8 @{" ADDGB " link rx_addgb} Add global include
4.2.9 @{" REMGB " link rx_remgb} Remove global include
If you are planning to call directly SNMA arexx port from another
progman (ie. not from Arexx macro) don't do it now. SNMA uses RVI
to pass information back, you won't get, it goes to the Arexx. I'm
planning to add code which detects this and passes information some
other way.
@endnode
@node rx_asm "4.2.1 SNMA,Arexx: ASM command"
Command:
~~~~~~~ ASM SOURCEFILE/A,OBJ=O/K,INCLUDE=I/K,HEADER=H/K,LISTING=L/K,
EQUATE=E/K
Template:
~~~~~~~
All keywords are the same as in SNMA commandline. SNMA
Arexx commandline does not have PORTNAME, AREXX or @{" OPT " link dir_opt}
flags. You can set OPT flags with @{" SET " link rx_set} command.
Results:
~~~~~~~
ASM command triggers SNMA to assemble SOURCEFILE.
To find out how assembly went, see/use @{" INFO " link rx_info} command.
@endnode
@node rx_chdir "4.2.2 SNMA, ARexx: CHDIR command"
Command: CHDIR DIRNAME/A
~~~~~~~
Template: DIRNAME is the name of the directory
~~~~~~~~
Function:
~~~~~~~~
Changes the working directory of SNMA. You can set the
working directory to the same directory where your source
file is with this command. If you have include files in the
same directory with the program source this is quite
helpful command. If DIRNAME does not exists or it is file,
SNMA prompts Requester to tell it.
Why this is CHDIR instead of CD ? To avoid any confusion
between this one and AmigaDOS CD.
@endnode
@node rx_free "4.2.3 SNMA, ARexx: FREE command"
Command: FREE
~~~~~~~
Template: none
~~~~~~~~
Function:
~~~~~~~~
Frees all resources opened by ASM command. After you
execute this command you lose all the information about the
last assembly, including errors.
Resources here means memory. All file opening/closing is
internal in ASM command.
@endnode
@node rx_geterr "4.2.4 SNMA, ARexx: GETERR command"
Command: GETERR NUMBER/N REMOVE/S WARN/S STEM/K
~~~~~~~
Template:
~~~~~~~~
NUMBER error/warning number. SNMA keeps track which error was
requested last. If the number is omitted next error is
returned. If GETERR tries to fetch error which does not
exists it returns special values, see below.
REMOVE Toggle removes error from the list. Errors are numbered so
that the first one is always number one and if you remove
number one, the second one becomes number one and so on.
WARN Toggle causes GETERR to return WARNINGS instead
of the ERRORS.
STEM variable specifies variable base name.
Results:
~~~~~~~
<STEM>.LINENUM
<STEM>.LINETXT
<STEM>.FILENAME
<STEM>.ERRTXT
<STEM>.COLUMN
<STEM>.LINENUM
The line number of the error. If this is NULL there is no
error you requested.
<STEM>.LINETXT
String which holds the source code line where error
is.
<STEM>.FILENAME
Name of the source code file.
<STEM>.ERRTXT
Error description text.
<STEM>.COLUMN
Column number where SNMA thinks the error is.
If your source code has TABS in it you may need to change
TAB value with @{" SET " link rx_set} command to get right
column. Default TAB is 8 (AmigaDOS uses).
<STEM>.ERRNUM
Which error this was. Handy if you want to know when using
GETERR to fetch next error. Number 1 is first.
Function:
~~~~~~~~ GetErr is used to fetch errors SNMA found from source code.
Warning are fetched with GetErr, too.
Errors are stored in list. First error is first in the list,
2nd is 2nd and so on. Warnings are in the separate list.
Exactly how many errors is in the list can be found with
the @{" INFO "link rx_info} command from the <STEM>.ERRORS field. Warnings are
in <STEM>.WARNINGS field.
GETERR REMOVE changes these values if you call INFO after
GETER REMOVE, but it does not change them when you call
GETERR.
If you call GETERR with illegal error number (error which
does not exists) you get the following results:
LINENUM=0
LINETEXT=' '
FILENAME=' '
ERRTXT='No more errors'
ERRIND=0
LINENUM=0 is not generated anywhere else because line
numbers star at one(1), so its safe to check in arexx macro
from this field if the error fetching succeed.
If you call GETERR to get next error and there is no next
error (all errors are handled) the situation is same as
above.
@endnode
@node rx_info "4.2.5 SNMA, ARexx: INFO command"
Command: INFO <STEM>
~~~~~~~
Template:
~~~~~~~~
<STEM> is the stem variable where values are put.
Results:
~~~~~~~
<STEM>.STATUS ok, warn, error, fail
<STEM>.LINES How many lines we assembled
<STEM>.ERRORS number of errors
<STEM>.WARNINGS number of warnings
<STEM>.CODE number of code sections
<STEM>.DATA data
<STEM>.BSS bss
<STEM>.CODESIZE number of bytes in code sections
<STEM>.DATASIZE data
<STEM>.BSSSIZE bss
<STEM>.FAILSTR possible failure string (if STATUS="FAIL")
.STATUS is one of the following strings:
OK = assembly went just fine / nothing assembled yet
WARN = last assembly resulted warn
ERROR = last assembly resulted error
FAIL = last assembly resulted failure
if .STATUS is "FAIL" .FAILSTR has the failure
description.
.LINES tells how many lines SNMA assembled. (Include files
are also counted for this).
.ERRORS How many errors if any. Failures don't count here.
.WARNINGS How many warnings if any.
.CODE Number of the CODE sections.
.DATA and .BSS are equivalent with .CODE
.CODESIZE
Number of the bytes section(s) take. This is the sum of
all CODE sections.
.DATASIZE and .BSSSIZE are equivalent with .CODESIZE.
.FAILSTR Possible failure description. See .STATUS.
@endnode
@node rx_quit "4.2.6 SNMA, Arexx: QUIT command"
Command: QUIT
~~~~~~~
Template: none
~~~~~~~~
Function: Quits SNMA
~~~~~~~~
@endnode
@node rx_set "4.2.7 SNMA, Arexx: SET command"
Command: SET Q=QUICKOPT/T P=PCOPT/T A=ADDRESSOPT/T
~~~~~~~ B=BASEFORCE/T S=SYMBOL/T L=LONGBRA/T
TABS/K/N KS=KEEPSOURCE/T OF=OUTFILE/T RE=RXERR/T
Template:
~~~~~~~~ QUICKOPT Q flag move-moveq and so on
PCOPT P flag absolute long ->pc-relative
ADDRESS A flag address mode optimizing
BASEFORCE B flag ensure disp16(an) mode
SYMBOL S flag write symbol hunk
LONGBRA L flag enable long branches (wo/ .l suffix)
TABS
Number which specifies you current TAB setting.
SNMA needs this for the GETERR.COLUMN field. If
the value is NULL or negative SNMA simply
ignores it.
Default is 8.
KEEPSOURCE
If off snma frees all source codes it allocated
in last assembly and you cannot print the line
where error is, but when working from the text
editor that is not neccessary. When this flag
is on snma frees the source code when next
assembly is started (or with FREE command),
keeping the source in memory between last
assembly and next one.
Default = ON.
OUTFILE
Toggle to enable/disable normal snma output. If
this is OFF snma won't write assembly messages
to the default output. When ON snma writes to
the default output. Default = OFF.
RXERR
Enable/disable rexx errors. Normally, in rexx
mode this flag is kept on. If it is off snma
will NOT create rexx error structures. INFO and
GETERR commands think that there were no errors
if this flag in off, even if there are errors.
Default = ON.
Function:
~~~~~~~~~
To change default settings of SNMA. @{" OPT " link dir_opt} directive
overrides those flags which can be set with OPT.
SET arexx command has nothing to do with SET directive.
@endnode
@node rx_addgb "4.2.8 SNMA, Arexx: ADDGB command"
Command: ADDGB
~~~~~~~ SOURCEFILE/A,OBJ=O/K,INCLUDE=I/K,HEADER=H/K,LISTING=L/K,
EQUATE=E/K
Template:
~~~~~~~~ Template is same as in @{" ASM " link rx_asm} command.
Function:
~~~~~~~~ To add symbols and macros to the global table. Single
ADDGB can add any number of include files to the global
table.
ADDGB works like @{" ASM " link rx_asm} with the following expections:
1) No code is generated
2) Second pass is not executed
3) Absolute symbols and macros are transfered to the global
table at the end of assembly.
4) Include files are added to the internal include file list
to prevent them to be included anymore.
Equates, sets, floating point equates and macros are transfered
to the global table.
Idea of global table is to lower include file loading and
processing time. You have to do this process only once,
after that SNMA will find the symbol (or macro) from the
global symbol table if it is there. If you try to
@{" INCLUDE " link dir_include} file which is ADDGB'd, the
include file is skipped. If you have includes in your
source, include files which are ADDGB'd are not processed.
SNMA locks the files you add to the global table. This
prevents you to modify (you can read it) these files, as the
change doesn't mirror to the global table anyway.
{" REMGB "link rx_remgb} command can be used to remove file from the global
table.
Important! The main sourcefile symbols and macros are NOT
transfered to the global table. File you handle with this
command usually contains INCLUDE directives which SNMA
process. This enables you to process your current
sourcefiles with ADDGB.
Errors are reported just like in ASM command.
If you have includes which produce code and you want that
code to be included DO NOT use ADDGB command to include
that file.
Global table can be used only in arexx mode.
So, what does all that mean in practice ?
There is little example in snma/examples. See it.
@endnode
@node rx_remgb "4.2.9 SNMA, Arexx: REMGB command"
Command: REMGB FILENAME
~~~~~~~
Template:
~~~~~~~~ FILENAME Name of include file you want to remove.
This removes only symbols added in main
include file. If this include has included
other include files they will not be
removed.
If the FILENAME is omitted, global
table is cleared and symbols freed.
Function:
~~~~~~~~ To remove symbols and macros one file (or all) has included
to the global tables. You can see what files are in global
tables with @{" SEEGB " link rx_seegb} command.
I have the following alias defined in shell-startup:
alias remgb "rx 'address SNMA remgb "[]"'
Then, just typing remgb <name> will remove the file from
the global table if present there.
Symbols which have been declared by using SET directive
belongs to the first file which defines them. When you
remove that file, the symbol is removed from the global
table, even if some other include file has changed (i.e.
declared by using SET) it.
@endnode
@node rx_seegb "4.2.10 SNMA, Arexx: SEEGB command"
Command: SEEGB STEM
Template:
~~~~~~~~ STEM stem variable name.
STEM.COUNT will hold the number of filenames
STEM.0 filename 0
STEM.1 filename 1
STEM.n filename n
Function:
~~~~~~~~ To get information what files are in the global symbol table.
If you don't specify STEM variable, this command is no-op.
@endnode
@node rx_example "4.3 ARexx examples"
The arexx directory of the snma package has several arexx macros
(programs). You can use them as they are and/or modify them anyway
you like.
ShellAsm.rexx is simple macro to call from the shell and it does
basically the same as SNMA in shell mode. Looks little
better than the one in V1.70 release.
addgb.rexx adds symbols to the global table. Basicly same as
ShellAsm.rexx.
seegb.rexx displays what include files are in snma's global
symbol table.
Other macros are for the XDME text editor. Those who have some other
text editor (which supports ARexx) may found them helpful to write
their own interface macros.
asm.xdme assembles file
GetErr.xdme fetches error information
snmainfo.xdme displays information about last assembly
These macros will need little more work but they work now. GetErr
macro needs some work with 'user macro' errors, at least.
Feel free to modify these macros anyway you like or write
completely new ones. My taste is not neccessarily yours.
If you modify these files and distribute them, please change the
names, at least, and state what they are supposed to do clearly
enough.
@endnode
@node Author "5. Author "
Author lives in Helsinki, Finland.
He is currently intrested in do the people actually use snma at
all, i.e. is he developing mainly to himself or to the larger
audience. So, if you are using snma, by sending a mail or a
postcard you will motivate him to work even harder with snma. By
stating which Amiga model you use, the author knows that snma has
no problems (has it ? It shouldn't) with different Amiga models. By
stating where you get the snma package, you will give intresting
information, too. (Paranoid ? Who ? Me ? Why ? 8')
Send your comments, flames or whatever to
E-mail: snuojua@cc.helsinki.fi
or
smail: Samu Nuojua
Harustie 8 B 15
00980 Helsinki
FINLAND
Well, although snma is freeware, donations are always welcome.
(Really ? 8')
Finally, thanks to Satu for the patience.
@endnode