(C)Copyright 1987,1988 Matthew Dillon, All Rights Reserved
Modified by Peter King for the Scholar programme of Heriot-Watt
University
FEATURES:
COMMAND LINE:
dasm srcfile [options]
Example:
dasm master.asm -omaster.bin -lmaster.lst -v3
displayed information for symbols: ???? = unknown value str = symbol is a string eqm = symbol is an eqm macro (r) = symbol has been referenced (s) = symbol created with SET or EQM pseudo-op
The SEG pseudo-op creates/sets the current segment. Each segment has it's own origin and is optionally an `uninitialized' segment. Uninitialized segments produce no output and have no restrictions. This is useful for determining the size of a certain assembly sequence without generating code, and for assigning RAM to labels.
'Initialized' segments produce output. The following should be considered when generating code:
Most everything is recursive. You cannot have a macro DEFINITION within a macro definition, but can nest macro calls, repeat loops, and include files.
The other major feature in this assembler is the SUBROUTINE pseudo-op, which logically separates local labels (starting with a dot). This allows you to reuse label names (for example, .1 .fail) rather than think up crazy combinations of the current subroutine to keep it all unique. Almost nothing need be resolved in pass 1. The assembler will make multiple passes in an attempt to resolve the assembly (including just one pass if everything is resolved immediately).
The default size extension is a byte.
declare space (default filler is 0). Data is not generated if within an uninitialized segment. Note that the number of bytes generated is exp * entrysize (1,2, or 4)
The default size extension is a byte.
Note that the default filler is always 0 (has nothing to do with the ORG default filler).
This is equivalent to DC, but each exp in the list is passed through the symbolic expression specified by the EQM label. The expression is held in a special symbol dotdot '..' on each call to the EQM label.
See EQM below
Example: HEX 1A45 45 13254F 3E12
org 0,255 org 100,0 org 200 dc 23will result in 200 zero's and a 23. This allows you to specify some ORG, then change your mind and specify some other (lower address) ORG without causing an error (assuming nothing is generated in between).
Normally, DS and ALIGN are used to generate specific filler values.
The relocatable origin can skip around (no limitations). The relocatable origin is a function of the segment. That is, you can still SEG to another segment that does not have a relocatable origin activated, do other (independent) stuff there, and then switch back to the current segment and continue where you left off.
CHARLIE subroutine
ldx #10
.1 dex
bne .1
BEN subroutine
ldx #20
.qq dex
bne .qq
Automatic temporary label boundaries occur for each macro level.
Usually temporary labels are used in macros and within actual
subroutines (so you don't have to think up a thousand different
names)Arguments passed to macros are referenced with: {#}. The first argument passed to a macro would thus be {1}. You should always use LOCAL labels (.name) inside macros which you use more than once. {0} represents an EXACT substitution of the ENTIRE argument line.
Y SET 0 REPEAT 10 X SET 0 REPEAT 10 DC X,Y X SET X + 1 REPEND Y SET Y + 1 REPENDgenerates an output table: 0,0 1,0 2,0 ... 9,0 0,1 1,1 2,1 ... 9,1, etc...
Labels within a REPEAT/REPEND should be temporary labels with a SUBROUTINE pseudo-op to keep them unique.
The Label to the left of REPEND is assigned AFTER the loop FINISHES.
The label will be set to the current ORG/RORG either before or after a pseudo-op is executed. Most of the time, the label to the left of a pseudo-op is the current ORG/RORG. The following pseudo-ops labels are created AFTER execution of the pseudo-op:
SEG, ORG, RORG, REND, ALIGN
The assembler may have to make several passes through the source code to resolve all generation. The number of passes is not limited to two. Since this may result in an unexpected, verbose option 2, 3, and 4 have been provided to allow determination of the cause. The assembler will give up if it thinks it can't do the assembly in *any* number of passes.
Error reporting could be better....
[] may be used to group expressions. The precedence of operators is the same as for the C language in almost all respects. Use brackets [] when you are unsure. The reason () cannot be used to group expressions is due to a conflict with the 6502 and other assembly languages.
Some operators, such as ||, can return a resolved value even if one of the expressions is not resolved. Operators are as follows:
NOTE WELL! Some operations will result in non-byte values when a byte value was wanted. For example: ~1 is NOT $FF, but $FFFFFFFF. Preceding it with a < (take LSB of) will solve the problem. ALL ARITHMETIC IS CARRIED OUT IN 32 BITS. The final Result will be automatically truncated to the maximum that can be handled by the particular machine language (usually a word) when applied to standard mnemonics.
prec UNARY
20 ~exp one's complement.
20 -exp negation
20 !exp not expression (returns 0 if exp non-zero, 1 if exp zero)
20 <exp take LSB byte of a 16 bit expression
20 >exp take MSB byte of an expression
BINARY
19 * multiplication
19 / division
19 % mod
18 + addition
18 - subtraction
17 >>,<< shift right, shift left
16 >,>= greater, greater equal
16 <,<= smaller, smaller equal
15 == equal to. Try to use this instead of =
15 = exactly the same as == (exists compatibility)
15 != not equal to
14 & logical and
13 ^ logical xor
12 | logical or
11 && left expression is true AND right expression is true
10 || left expression is true OR right expression is true
9 ? if left expression is true, result is right expression,
else result is 0. [10 ? 20] returns 20
8 [] group expressions
7 , separate expressions in list (also used in
addressing mode resolution, BE CAREFUL!
Constants:
nnn decimal
0nnn octal
%nnn binary
$nnn hex
'c character
"cc.." string (NOT zero terminated if in DC/DS/DV)
[exp]d the constant expressions is evaluated and it's decimal
result turned into an ASCII string.
Symbols:
... -holds CHECKSUM so far (of actual-generated stuff)
.. -holds evaluated value in DV pseudo-op
.name -represents a temporary symbol name. Temporary symbols
may be reused inside MACROS and between SUBROUTINES, but
may not be referenced across macros or across SUBROUTINEs.
. -current program counter (as of the beginning of the
instruction).
name -beginning with an alpha character and containing letters,
numbers, or '_'. Represents some global symbol name.
Each bit in the WHY word (verbose option 1) is a reason (why the assembler needs to do another pass), as follows:
bit 0 expression in mnemonic not resolved 1 - 2 expression in a DC not resolved 3 expression in a DV not resolved (probably in DV's EQM symbol) 4 expression in a DV not resolved (could be in DV's EQM symbol) 5 expression in a DS not resolved 6 expression in an ALIGN not resolved 7 ALIGN: Relocatable origin not known (if in RORG at the time) 8 ALIGN: Normal origin not known (if in ORG at the time) 9 EQU: expression not resolved 10 EQU: value mismatch from previous pass (phase error) 11 IF: expression not resolved 12 REPEAT: expression not resolved 13 a program label has been defined after it has been referenced (forward reference) and thus we need another pass 14 a program label's value is different from that of the previous pass (phase error)
Certain errors will cause the assembly to abort immediately, others will wait until the current pass is over before terminating assembly. All remining types of error allow another pass to occur in the hopes the error will fix itself.