-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathasmx-doc.html
1271 lines (1117 loc) · 57.7 KB
/
asmx-doc.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> -->
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=us-ascii">
<TITLE>asmx multi-CPU assembler documentation</TITLE>
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#FFFFFF">
<H1>asmx semi-generic assembler</H1>
<H2>FOREWORD</H2>
Okay, so it's not really generic, just semi generic. This started
from an 8080 assembler I wrote in Turbo Pascal back in my college days
when I had a class where I had to write an 8080 emulator. The assembler
wasn't part of the class, but no way was I going to hand assemble code
again like I did back in my early TRS-80 days. Then when I started
dabbling with ColecoVision and Atari 2600 code, I made a Z-80 and a 6502
assembler from it.
<P>
But Turbo Pascal and MS-DOS are way out of style now, so I ported the
code to plain standard C. It should run on any Unix-like operating
system. It should also run on any operating system that provides
Unix-style file and command-line handling. In particular, it runs fine
under Mac OS X, which is what I use on my laptop.
<P>
Porting it to C wasn't enough, though. I had added some nice features
like macros to the 6502 assembler and I wanted them in the Z-80
assembler too. But I didn't want to have to copy and paste code every
time I added a new feature. So I turned the code inside out, and made
the common code into a gigantic <tt>.h</tt> file. This made writing an
assembler for a new CPU easy enough that I was able to write a 6809
assembler in one day, plus another day for debugging.
<P>
Unlike most "generic" assemblers, I make an effort to conform to the
standard mnemonics and syntax for a CPU, as you'd find them in the chip
manufacturer's documentation. I'm a bit looser on the pseudo-ops,
trying to be inclusive whenever possible so that existing code has a
better chance of working with fewer changes, especially code written
back in the '80s.
<P>
This is a two-pass assembler. That means that on the first pass it
figures out where all the labels go, then on the second pass it
generates code. I know there are popular multi-pass assemblers out
there (like DASM for 6502), and they have their own design philosophy.
I'm sticking with the philosopy that was used by the old EDTASM
assemblers for the TRS-80. There are a few EDTASM-isms that you might
notice, if you know what to look for.
<P>
But being a two-pass assembler, there are some things you can't do.
You can't <tt>ORG</tt> to a label that hasn't been defined yet, because on
the second pass it'll have a value, and your code will go into a
different location, and all your labels will be at the wrong
address. This is called a "phase error". You also can't use a
label that hasn't been defined yet with <tt>DS</tt> or <tt>ALIGN</tt> because they
affect the current location.
<P>
Some CPUs like the 6502 and 6809 have different instructions which
can provide smaller faster code based on the size of an operand.
To make this work, the assembler keeps an extra flag in the symbol
table during the second pass, which tells if the symbol was known
yet at this point in the first pass. Then the assembler can know
to use the longer form to avoid a phase error. The 6809 assembler
syntax uses "<tt><</tt>" (force 8-bits) and "<tt>></tt>" (force 16-bits) to override
this decision. The 6502 assembler can also override this with a
"<tt>></tt>" before an absolute or absolute-indexed address operand. (Note
that this usage is different from "<tt><</tt>" and "<tt>></tt>" as a high/low byte
of a word value.)
<P>
Some assemblers can only output code in binary. This might be nice
if you're making a video game cartridge ROM, but it's really not
very flexible. Intel and Motorola both came up with very nice text
file formats which don't require any kind of padding when you do an
<tt>ORG</tt> instruction, and don't require silly "segment" definitions
just to keep <tt>DS</tt> instructions from generating object code. Then,
following the Unix philosophy of making tools that can connect to
other tools, you can pipe the object code to another utility which
makes the ROM image.
<P>
Anyhow, it works pretty well for what I want it to do.
<P>
- Bruce -
<HR>
<H2>HOW TO BUILD asmx</H2>
The standard way to build asmx is using the makefile:
<p>
<pre> make</pre>
<p>
This will create the asmx binary in the src sub-directory.
That's it. Now you will might want to copy it to your
<tt>/usr/local/bin</tt> or <tt>~/bin</tt> directory, but that's your choice.
<p>
If you are using a unix-like OS such as Linux, OS X, or BSD, you
can also use:
<p>
<pre> make install</pre>
<p>
This will install the binaries to <tt>~/bin</tt>, unless you change the
makefile to install it somewhere else. Symbolic links are generated
so that each CPU assembler can be used with a separate command.
<p>
If you can't use the makefile, the simplest way is this:
<p>
<pre> gcc *.c -o asmx</pre>
<p>
Windows users should install Cygwin as the easiest way to get GCC.
<HR>
<H2>RUNNING IT</H2>
Just give it the name of your assembler source file, and
whatever options you want.
<P>
<tt>asmx [options] srcfile</tt>
<P>
Here are the command line options:
<P>
<pre>
-- end of options
-e show errors to screen
-w show warnings to screen
-l [filename] make a listing file, default is srcfile.lst
-o [filename] make an object file, default is srcfile.hex or srcfile.s9
-d label[[:]=value] define a label, and assign an optional value
-s9 output object file in Motorola S9 format (16-bit address)
-s19 output object file in Motorola S9 format (16-bit address)
-s28 output object file in Motorola S9 format (24-bit address)
-s37 output object file in Motorola S9 format (32-bit address)
-b [base[-end]] output object file as binary with optional base/end addresses
-c send object code to stdout
-C cputype specify default CPU type (currently 6502)
</pre><P>
Example:
<P>
<tt>asmx -l -o -w -e program.asm</tt>
<P>
This assembles the source file "<tt>program.asm</tt>", shows warnings and
errors to the screen, creates a listing file "<tt>program.asm.lst</tt>", and
puts the object code in an Intel hex format file named "<tt>program.asm.hex</tt>".
(Binary files get named "<tt>program.asm.bin</tt>", and Motorola S9 files get an
extension of <tt>.s9</tt>, <tt>.s19</tt>, <tt>.s28</tt>, or <tt>.s37</tt>.)
<P>
Notes:
<P>
The '<tt>--</tt>' option is needed when you use <tt>-l</tt>, <tt>-o</tt>, or <tt>-b</tt> as the last option
on the command line with no parameters, so that they don't try to eat up your source file
name. It's really better to just put <tt>-l</tt> and <tt>-o</tt> first in the options.
<P>
The value in <tt>-d</tt> must be a number. No expressions are allowed. The
valid forms are:
<P>
<table style='margin-left:20pt'>
<tr><td><tt>-d label</tt> <td> defines the label as <tt>EQU 0</tt>
<tr><td><tt>-d label=value</tt> <td> defines the label as <tt>EQU value</tt>
<tr><td><tt>-d label:=value</tt> <td> defines the label as <tt>SET value</tt>
</table>
<P>
By default, object code is written as an Intel hex file unless the <tt>-s</tt> or
<tt>-b</tt> option is specified.
<P>
The value in <tt>-b</tt> specifies the start address for your binary file. If you
are making code for a ROM at address range 0xC000-0xFFFF, use "<tt>-b 0xC000-0xFFFF</tt>"
and the first byte of the object file will be whatever belongs at 0xC000. Anything
at a lower address is not written to the file, any gaps are filled
with 0xFF, and no bytes past 0xFFFF are written to the file. The object file is <i>not</i>
padded to the full address range. Be careful about using large <tt>ORG</tt> values without
an end address, or the resulting binary file could become VERY large.
<P>
The <tt>-c</tt> and <tt>-o</tt> options are incompatible. Attempting to use both will
result in an error. Normal screen output (pass number, total errors,
error messages, etc.) always goes to stderr.
<HR>
<H2>EXPRESSIONS</H2>
Whenever a value is needed, it goes through the expression evaluator.
The expression evaluator will attempt to do the arithmetic needed to
get a result.
<P>
Unary operations take a single value and do something with it. The
supported unary operations are:
<P>
<table border=1>
<tr><td>+ val <td>positive of val
<tr><td>- val <td>negative of val
<tr><td>~ val <td>bitwise NOT of val
<tr><td>! val <td>logical NOT of val (returns 1 if val is zero, else 0)
<tr><td>< val <td>low 8 bits of val
<tr><td>> val <td>high 8 bits of val
<tr><td>..DEF sym <td>returns 1 if symbol 'sym' has already been defined
<tr><td>..UNDEF sym <td>returns 1 if symbol 'sym' has not been defined yet
<tr><td>( expr ) <td>parentheses for grouping sub-expressions
<tr><td>[ expr ] <td>square brackets can be used as parentheses when necessary
<tr><td>'c' <td>One or two character constants, equal to the ASCII value
<tr><td>'cc' <td>of c or cc. In the two-byte case, the first character
is the high byte.
<tr><td>H(val) <td>high 8 bits of val; whitespace not allowed before '('
<tr><td>L(val) <td>low 8 bits of val; whitespace not allowed before '('
</table>
<P>
NOTE: with the Z-80, <tt>(expr)</tt>, <tt>H(val)</tt>, and <tt>L(val)</tt> will likely not work at
the start of an expression because of Z-80 operand syntax. Likewise
with the 6809, <tt><val</tt> and <tt>>val</tt> may have special meaning at the start of
an operand.
<P>
Binary operations take two values and do something with them. The
supported binary operations are:
<P>
<table border=1>
<tr><td>x * y <td>x multipled by y
<tr><td>x / y <td>x divided by y
<tr><td>x % y <td>x modulo y
<tr><td>x + y <td>x plus y
<tr><td>x - y <td>x minus y
<tr><td>x << y <td>x shifted left by y bits
<tr><td>x >> y <td>x shifted right by y bits
<tr><td>x & y <td>bitwise x AND y
<tr><td>x | y <td>bitwise x OR y
<tr><td>x ^ y <td>bitwise x XOR y
<tr><td>x = y <td rowspan=6>comparison operators, return 1 if condition is true<br>(note that = and == are the same)
<tr><td>x == y
<tr><td>x < y
<tr><td>x <= y
<tr><td>x > y
<tr><td>x >= y
<tr><td>x && y <td>logical AND of x and y (returns 1 if x !=0 and y != 0)
<tr><td>x || y <td>logical OR of x and y (returns 1 if x != 0 or y != 0)
</table>
<P>
Numbers:
<P>
<table border=1>
<tr><td>. <td rowspan=3>current program counter
<tr><td>*
<tr><td>$
<tr><td>$nnnn <td rowspan=3>hexadecimal constant
<tr><td>nnnnH
<tr><td>0xnnnn
<tr><td>nnnn <td rowspan=2>decimal constant
<tr><td>nnnnD
<tr><td>nnnnO <td>octal constant
<tr><td>%nnnn <td rowspan=2>binary constant
<tr><td>nnnnB
</table>
<P>
Hexadecimal constants of the form "<tt>nnnnH</tt>" don't need a leading zero if
there is no label defined with that name.
<P>
Operator precedence:
<P>
<tt>( ) [ ]</tt><br>
unary operators: <tt>+ - ~ ! < > ..DEF ..UNDEF</tt><br>
<tt>* / %</tt><br>
<tt>+ -</tt><br>
<tt>< <= > >= = == !=</tt><br>
<tt>& && | || ^ << >></tt>
<P>
WARNING:<br>
Shifts and AND, OR, and XOR have a lower precedence than the comparison
operators! You must use parentheses when combining them with comparison operators!
<P>
Example:<br>
Use "<tt>(OPTIONS & 3) = 2</tt>", not "<tt>OPTIONS & 3 = 2</tt>". The former checks the
lowest two bits of the label <tt>OPTIONS</tt>, the latter compares "<tt>3 = 2</tt>"
first, which always results in zero.
<P>
Also, unary operators have higher precedence, so if X = 255, "<tt><X + 1</tt>" is
256, but "<tt><(X + 1)</tt>" is 0.
<P>
With the 6809 assembler, a leading "<tt><</tt>" or "<tt>></tt>" often refers to an addressing
mode. If you really want to use the low-byte or high-byte operator, surround
the whole thing with parentheses, like "<tt>(<LABEL)</tt>". This does not apply to
immediate mode, so "<tt>LDA #<LABEL</tt>" will use the low byte of <tt>LABEL</tt>.
<P>
NOTE:
<tt>..def</tt> and <tt>..undef</tt> do not work with local labels. (the ones that start with
'<tt>@</tt>' or '<tt>.</tt>')
<HR>
<H2>LABELS AND COMMENTS</H2>
Labels must consist of alphanumeric characters or underscores, and must
not begin with a digit. Examples are "<tt>FOO</tt>", "<tt>_BAR</tt>", and "<tt>BAZ_99</tt>". Labels
are limited to 255 characters. Labels may also contain '<tt>$</tt>' characters, but
must not start with one.
<P>
Labels must begin in the first column of the source file when they are
declared, and may optionally have a "<tt>:</tt>" following them. Opcodes with no
label must have at least one blank character before them.
<P>
Local labels are defined starting with "<tt>@</tt>" or "<tt>.</tt>". This glues whatever
is after the "<tt>@</tt>" or "<tt>.</tt>" to the last non-temporary code label defined so far,
making a unique label. Example: "<tt>@1</tt>", "<tt>@99</tt>", "<tt>.TEMP</tt>", and "<tt>@LOOP</tt>". These
can be used until the next non-local label, by using this short form. They
appear in the symbol table with a long form of "<tt>LABEL@1</tt>" or "<tt>LABEL.1</tt>", but
can not be referenced by this full name. Local labels starting with a "<tt>.</tt>"
can also be defined as subroutine local, by using the <tt>SUBROUTINE</tt> pseudo-op.
<P>
Comments may either be started with a "<tt>*</tt>" as the first non-blank character
of a line, or with a "<tt>;</tt>" in the middle of the line.
<P>
Lines after the <tt>END</tt> pseudo-op are ignored as though they were comments,
except for <tt>LIST</tt> and <tt>OPT</tt> lines.
<HR>
<H2>PSEUDO-OPS</H2>
These are all the opcodes that have nothing to do with the instruction
set of the CPU. All pseudo-ops can be preceeded with a "<tt>.</tt>" (example:
"<tt>.BYTE</tt>" works the same as "<tt>BYTE</tt>")
<P>
NOTE:
All of the data pseudo-ops like <tt>DB</tt>, <tt>DW</tt>, and <tt>DS</tt> have a limit of 1023
bytes of initialized data. (This can be changed in <tt>asmx.h</tt> if
you really need it bigger.)
<H3>.6502 / .68HC11 / etc.</H3>
The CPU type can be specified this way in addition to the <tt>CPU</tt> and
<tt>PROCESSOR</tt> pseudo-ops.
<H3>ASCIC</H3>
Creates a text string preceeded by a single byte indicating the length
of the string. This is equivalent to a Pascal-style string.
<H3>ASSERT expr</H3>
Generates an error if expr is false (equals zero).
<H3>ALIGN</H3>
This ensures that the next instruction or data will be located on a
power-of-two boundary. The parameter must be a power of two (2, 4,
8, 16, etc.)
<H3>CPU</H3>
This is an alias for <tt>PROCESSOR</tt>.
<H3>DB / BYTE / DC.B / FCB</H3>
Defines one or more constant bytes in the code. You can use as many
comma-separated values as you like. Strings use either single or
double quotes. Doubled quotes inside a string assemble to a quote
character. The backslash ("<tt>\</tt>") can escape a quote, or it can
represent a tab ("<tt>\t</tt>"), linefeed ("<tt>\n</tt>"), or carriage return ("<tt>\r</tt>")
character. Hex escapes ("<tt>\xFF</tt>") are also supported.
<H3>DW / WORD / DC.W / FDB</H3>
Defines one or more constant 16-bit words in the code, using the
native endian-ness of the CPU. With the 6502, Z-80, and 8080, the
low word comes first; with the 6809, the high word comes first.
Quoted text strings are padded to a multiple of two bytes. The
data is not aligned to a 2-byte address.
<H3>DL / LONG / DC.L</H3>
Defines one or more constant 32-bit words in the code, using the
native endian-ness of the CPU. With the 6502, Z-80, and 8080, the
low word comes first; with the 6809, the high word comes first.
Quoted text strings are padded to a multiple of four bytes. The
data is not aligned to a 4-byte address.
<H3>DRW</H3>
Define Reverse Word - just like <tt>DW</tt>, except the bytes are reversed
from the current endian setting.
<H3>DS / RMB / BLKB</H3>
Skips a number of bytes, optionally initialized.
<P>
Examples:
<pre>
DS 5 ; skip 5 bytes (generates no object code)
DS 6,"*" ; assemble 6 asterisks</pre>
<P>
Note that no forward-reference values are allowed for the length
because this would cause phase errors.
<H3>ERROR message</H3>
This prints a custom error message.
<H3>EVEN</H3>
This is an alias for <tt>ALIGN 2</tt>.
<H3>FCC</H3>
Motorola's equivalent to <tt>DB</tt> with a string. Each string starts and
ends with the same character. The start/end character must not be
alphanumeric or an underscore.
<P>
Examples:
<pre>
FCC /TEXT/ ; 4 bytes "TEXT"
FCC \TEXT\ ; 4 bytes "TEXT"</pre>
<P>
In this assembler, <tt>FCC</tt> is extended by allowing it to work like <tt>DB</tt>
afterward, only with a different quote character. Also, the
string delimiter can be repeated twice inside the string to
include the delimiter in the string.
<P>
Examples:
<pre>
FCC /TEXT//TEXT/ ; 9 bytes "TEXT/TEXT"
FCC /TEXT/,0 ; 5 bytes "TEXT" followed by a null
FCC /TEXT/,0,/TEXT/ ; 9 bytes "TEXT", null, "TEXT"</pre>
<P>
There is also a second mode where the length is specified, the text has
no quotes, and the text is padded to the specified length with blanks.
Be aware that if the text is too short, it will copy more data from your
source line, even if you have a comment in the line! However, it will
stop copying when it encounters a tab character.
<P>
Example:
<pre>
FCC 9,TEXT <- this is 9 bytes "TEXT "
FCC 9,TEXT;comm <- this is 9 bytes "TEXT;comm"
FCC 9,TEXT;comment <- this is 9 bytes "TEXT;comm", then an error from "ent"</pre>
<H3>END</H3>
This marks the end of code. After the <tt>END</tt> statement, all input is
ignored except for <tt>LIST</tt> and <tt>OPT</tt> lines.
<H3>EQU / = / SET / :=</H3>
Sets a label to a value. The difference between <tt>EQU</tt> and <tt>SET</tt> is that
a <tt>SET</tt> label is allowed to be redefined later in the source code.
<tt>EQU</tt> and '<tt>=</tt>' are equivalent, and <tt>SET</tt> and '<tt>:=</tt>' are equivalent.
<H3>HEX</H3>
Defines raw hexadecimal data. Individual hex bytes may be separated by
spaces.
<P>
Examples:
<pre>
HEX 123456 ; assembles to hex bytes 12, 34, and 56
HEX 78 9ABC DE ; assembles to hex bytes 78, 9A, BC and DE
HEX 1 2 3 4 ; Error: hexadecimal digits must be in pairs</pre>
<H3>IF expr / ELSE / ELSIF expr / ENDIF</H3>
Conditional assembly. Depending on the value in the <tt>IF</tt> statement,
code between it and the next <tt>ELSE</tt> / <tt>ELSIF</tt> / <tt>ENDIF</tt>, and code between
an <tt>ELSE</tt> and an <tt>ENDIF</tt>, may or may not be assembled.
<P>
<tt>ELSIF</tt> is the same as "<tt>ELSE</tt>" followed by "<tt>IF</tt>", only without the need
for an extra <tt>ENDIF</tt>.
<P>
Example:
<pre>
IF .undef mode
ERROR mode not defined!
ELSIF mode = 1
JSR mode1
ELSIF mode = 2
JSR mode2
ELSE
ERROR Invalid value of mode!
ENDIF</pre>
<P>
IF statements inside a macro only work inside that macro. When
a macro is defined, <tt>IF</tt> statements are checked for matching <tt>ENDIF</tt>
statements.
<H3>INCBIN filename</H3>
This inserts the contents of the named binary file into the object
code output. The size of the binary file is shown in the listing.
<H3>INCLUDE filename</H3>
This starts reading source code from the named file. The file is
read once in each pass. <tt>INCLUDE</tt> files can be nested to a maximum
of 10 levels. (This can be changed in <tt>asmx.c</tt> if you really need
it bigger.)
<H3>LIST / OPT</H3>
These set assembler options. Currently, the options are:
<P>
<table border=1>
<tr><td><tt>LIST ON</tt> / <tt>OPT LIST</tt> <td>Turn on listing
<tr><td><tt>LIST OFF</tt> / <tt>OPT NOLIST</tt> <td>Turn off listing
<tr><td><tt>LIST MACRO</tt> / <tt>OPT MACRO</tt> <td>Turn on macro expansion in listing
<tr><td><tt>LIST NOMACRO</tt> / <tt>OPT NOMACRO</tt> <td>Turn off macro expansion in listing
<tr><td><tt>LIST EXPAND</tt> / <tt>OPT EXPAND</tt> <td>Turn on data expansion in listing
<tr><td><tt>LIST NOEXPAND</tt> / <tt>OPT NOEXPAND</tt> <td>Turn off data expansion in listing
<tr><td><tt>LIST SYM</tt> / <tt>OPT SYM</tt> <td>Turn on symbol table in listing
<tr><td><tt>LIST NOSYM</tt> / <tt>OPT NOSYM</tt> <td>Turn off symbol table in listing
<tr><td><tt>LIST TEMP</tt> / <tt>OPT TEMP</tt> <td>Turn on temp symbols in symbol table listing
<tr><td><tt>LIST NOTEMP</tt> / <tt>OPT NOTEMP</tt> <td>Turn off temp symbols in symbol table listing
</table>
<P>
The default is listing on, macro expansion off, data expansion on,
symbol table on.
<H3>MACRO / ENDM</H3>
Defines a macro. This macro is used whenver the macro name is
used as an opcode. Parameters are defined on the <tt>MACRO</tt> line,
and replace values used inside the macro.
<P>
Macro calls can be nested to a maximum of 10 levels. (This can
be changed in <tt>asmx.c</tt> if you really need it bigger.)
<P>
Example:
<pre>
TWOBYTES MACRO parm1, parm2 ; start recording the macro
DB parm1, parm2
ENDM ; stop recording the macro
TWOBYTES 1, 2 ; use the macro - expands to "DB 1, 2"</pre>
<P>
An alternate form with the macro name after <tt>MACRO</tt>, instead of as
a label, is also accepted. A comma after the macro name is
optional.
<pre>
MACRO plusfive parm
DB (parm)+5
ENDM</pre>
<P>
When a macro is invoked with insufficient parameters, the remaining
parameters are replaced with a null string. It is an error to invoke
a macro with too many parameters.
<P>
Macro parameters can be inserted without surrounding whitespace
by using the '<tt>##</tt>' concatenation operator.
<pre>
TEST MACRO labl
labl ## 1 DB 1
labl ## 2 DB 2
ENDM
TEST HERE ; labl ## 1 gets replaced with "HERE1"
; labl ## 2 gets replaced with "HERE2"</pre>
<P>
Macro parameters can also be inserted by using the backslash ("<tt>\</tt>")
character. This method also includes a way to access the actual
number of macro parameters supplied, and a unique identifier for
creating temporary labels.
<P>
<tt>\0</tt> = number of macro parameters<br>
<tt>\1</tt>..<tt>\9</tt> = nth macro parameter<br>
<tt>\?</tt> = unique ID per macro invocation (padded with leading zeros to five digits)
<P>
NOTE: The line with the <tt>ENDM</tt> may have a label, and that will be included in the
macro definition. However if you include a backslash escape before the <tt>ENDM</tt>, the
<tt>ENDM</tt> will not be recognized, and the macro definition will not end. Be careful!
<H3>ORG</H3>
Sets the origin address of the following code. This defaults to
zero at the start of each assembler pass.
<H3>PROCESSOR</H3>
This selects a specific CPU type to assemble code for. Some assemblers
support multiple CPU sub-types. Currently supported CPU types are:
<P>
<table border=1>
<tr><td>NONE <td>No CPU type selected
<tr><td>1802 <td>RCA 1802
<tr><td>6502 <td>MOS Technology 6502
<tr><td>6502U <td>MOS Technology 6502 with undocumented instructions
<tr><td>65C02 <td>Rockwell 65C02
<tr><td>6809 <td>Motorola 6809
<tr><td>6800 6802 <td>Motorola 6800
<tr><td>6801 6803 <td>Motorola 6801
<tr><td>6805 <td>Motorola 6805
<tr><td>6303 <td>Hitachi 6303 (6800 variant)
<tr><td>6811 68HC11
<br>68HC711 68HC811
<br>68HC99 <td>Motorola 68HC11 variants
<tr><td>68HC16 <td>Motorola 68HC16
<tr><td>68HSC08 <td>Motorola 68HSC08 (6805 variant)
<tr><td>68K 68000 <td>Motorola 68000
<tr><td>68010 <td>Motorola 68010
<tr><td>8051 <td>Intel 8051 variants
<tr><td>8080 <td>Intel 8080
<tr><td>8085 <td>Intel 8085
<tr><td>8085U <td>Intel 8085 with undocumented instructions
<tr><td>ARM <td>ARM (32-bit little-endian)
<tr><td>ARM_BE <td>ARM big-endian
<tr><td>ARM_LE <td>ARM little-endian
<tr><td>THUMB <td>ARM Thumb (16-bit little-endian)
<tr><td>THUMB_BE <td>ARM Thumb big-endian
<tr><td>THUMB_LE <td>ARM Thumb little-endian
<tr><td>F8 <td>Fairchild F8
<tr><td>TOM <td>Atari Jaguar GPU
<tr><td>JERRY <td>Atari Jaguar DSP
<tr><td>Z80 <td>Zilog Z-80
<tr><td>GBZ80 <td>Gameboy Z-80 variant
</table>
<P>
At the start of each pass, this defaults to the assembler specified
in the "<tt>-C</tt>" command line option, if any, or the assembler type determined
from the name of the executable used on the command line. The latter is
useful with soft-links when using Unix-type systems. In that case, the
default assembler name can be determined by looking at the end of the
executable name used to invoke asmx, then selecting that CPU type.
<P>
If no default assembler is specified, the <tt>DW</tt>/<tt>WORD</tt> and <tt>DL</tt>/<tt>LONG</tt> pseudo-ops
will generate errors because they do not know which endian order to use.
<P>
Opcodes for the selected processor will have priority over generic
pseudo-ops. However, assemblers for CPUs which have a "<tt>SET</tt>" opcode have
been specifically designed to pass control to the generic "<tt>SET</tt>" pseudo-op.
<H3>REND</H3>
Ends an <tt>RORG</tt> block. A label in front of <tt>REND</tt> receives the relocated
address + 1 of the last relocated byte in the <tt>RORG</tt> / <tt>REND</tt> block.
<H3>RORG</H3>
Sets the relocated origin address of the following code. Code
in the object file still goes to the same addresses that follow
the previous <tt>ORG</tt>, but labels and branches are handled as though
the code were being assembled starting at the <tt>RORG</tt> address.
<H3>SEG / RSEG / SEG.U segment</H3>
Switches to a new code segment. Code segments are simply different
sections of code which get assembled to different addresses. They
remember their last location when you switch back to them. If no
segment name is specified, the null segment is used.
<P>
At the start of each assembler pass, all segment pointers are reset
to zero, and the null segment becomes the current segment.
<P>
<tt>SEG.U</tt> is for DASM compatibility. DASM uses <tt>SEG.U</tt> to indicate an
"unitialized" segment. This is necessary because its <tt>DS</tt> pseudo-op
always generates data even when none is specified. Since the <tt>DS</tt>
pseudo-op in this assembler normally doesn't generate any data,
unitialized segments aren't supported as such.
<P>
<tt>RSEG</tt> is for compatibility with vintage Atari 7800 source code.
<H3>SUBROUTINE / SUBR name</H3>
This sets the scope for temporary labels beginning with a dot.
At the start of each pass, and when this pseudo-op is used with
no name specified, temporary labels beginning with a dot use the
previous non-temporary label, just as the temporary labels
beginning with an '<tt>@</tt>'.
<P>
Example:
<pre>
START
.LABEL NOP ; this becomes "START.LABEL"
SUBROUTINE foo
.LABEL NOP ; this becomes "FOO.LABEL"
SUBROUTINE bar
.LABEL NOP ; this becomes "BAR.LABEL"
SUBROUTINE
LABEL
.LABEL NOP ; this becomes "LABEL.LABEL"</pre>
<H3>WORDSIZE n</H3>
Specifies the CPU's word size in bits. This is for CPUs which do not
support byte addressing. If the word size is zero, the native CPU
word size is used. Currently only the Jaguar DSP/GSP uses a word
size that is not equal to 8.
<P>
This is primarily intended for using <tt>DS</tt> pseudo-ops to create data
structure offsets, using <tt>WORDSIZE 8</tt>.
<H3>ZSCII</H3>
Creates a compressed text string in the version 1 Infocom format.
Otherwise, this works exactly like the <tt>DB</tt> pseudo-op. Note that this
will always generate a multiple of two bytes of data.
<P>
WARNING: using a forward-referenced value could cause phase errors!
<P>
See <A HREF="http://www.wolldingwacht.de/if/z-spec.html">
http://www.wolldingwacht.de/if/z-spec.html</A> for more information
on the compressed text format.
<P>
There is also one CPU-specific pseudo-op:
<H3>SETDP value</H3>
With the 6809 assembler, this sets the current value of the
direct page register, for determining whether to use direct or
extended mode. It defaults to zero at the start of each
assembler pass.
<HR>
<H2>SYMBOL TABLE DUMP</H2>
The symbol table is dumped at the end of the listing file. Each
symbol shows its name, value, and flags. The flags are:
<P>
<table border=1>
<tr><td>U<td>Undefined<td>this symbol was referenced but never defined
<tr><td>M<td>Multiply defined<td>this symbol was defined more than once with
different values (only the first is kept)
<tr><td>S<td>SET<td>this symbol was defined with the <tt>SET</tt> pseudo-op, or from
the <tt>-dLABEL:=VALUE</tt> command line option
<tr><td>E<td>EQU<td>this symbol was defined with the <tt>EQU</tt> pseudo-op, or from
the <tt>-dLABEL=VALUE</tt> command line option
</table>
<HR>
<H2>CHANGE HISTORY</H2>
<H3>Version 1.1 changes (April 1995)</H3>
(this version was on the original Starpath "Stella Gets a New Brain" CD)
<UL>
<LI>Fixed a bug that would prevent using any label beginning with the letter
'A' as the first parameter of an opcode.
<LI>Prevented output of unnecessary origin commands to <tt>.DAT</tt> file to avoid
complaints from <tt>MAKEROM</tt>.
<LI>Fixed the "data overwritten" error in <tt>MAKEROM</tt>, which was only displaying
the low byte of the offending address.
<LI>Improved <tt>MAKEROM</tt>'s handling of out-of-range memory addresses.
<LI>Added a basic macro feature, controlled by the following pseudo-ops:
<pre>
<label> MACRO start recording the macro with the name <label>
ENDM end the macro
LIST MACRO enable macro expansion in listings
LIST NOMACRO disable macro expansion in listings (default)
<label> use the macro
</pre>
Note that macros can not currently call other macros.
</UL>
<HR>
<H3>Version 1.2 changes (September 1996)</H3>
<UL>
<LI>Added macro parameters
<LI>Added <tt>FCB</tt>, <tt>FDB</tt>, <tt>RMB</tt>, <tt>BYTE</tt>, <tt>WORD</tt>, and <tt>BLKB</tt> pseudo-ops
<LI>Added binary constants (<tt>xxxxxxxxB</tt> and <tt>%xxxxxxxx</tt>)
<LI>Added <tt>ASLA</tt>, <tt>ROLA</tt>, <tt>LSRA</tt>, and <tt>RORA</tt> opcodes
<LI>Added '<tt>$</tt>' by itself as the current location, in addition to '<tt>.</tt>' and '<tt>*</tt>'
<LI><tt>DB</tt> and <tt>DW</tt> opcodes now work properly with multiple operands
<LI>Added <tt>&</tt>, <tt>|</tt>, <tt><<</tt>, and <tt>>></tt> to expression evaluator. Each of these operators
has the same precedence, below <tt>+</tt> and <tt>-</tt>.
<LI>Default file extension was changed from <tt>.A65</tt> to <tt>.ASM</tt>
<LI>Allowed command line options to be specified in lowercase
<LI>Added a new <tt>RORG</tt> "relative <tt>ORG</tt>" pseudo-op to allow assembling code that
will later be moved to a different address
</UL>
<HR>
<H3>Version 1.3 changes (December 1996)</H3>
<UL>
<LI>No more than one macro could be defined, because the macro list wasn't
being linked properly.
<LI>Errorlevel 1 is now returned if any errors occurred during assembly.
</UL>
<HR>
<H3>Version 1.4 changes (February 2002)</H3>
<UL>
<LI>Added <tt>FCC</tt> pseudo-op
<LI>Lines beginning with "<tt>*</tt>" are now comments
<LI>Jump indirect wouldn't work correctly if the line had a comment
<LI>No error was generated if too many macro parameters were used
<LI>Maximum macro parameters increased from 5 to 10
<LI>Lines from macro expansions with errors are now displayed
<LI>Symbol table is now displayed with more than one column
<LI>Lines that generate more than 3 bytes are flagged with a "+"
</UL>
<HR>
<H3>Version 1.5 changes (2004-02-24)</H3>
<UL>
<LI>Converted from Pascal to C.
<LI>Added 65C02 opcodes. They can be disabled at compile time with a <tt>#define</tt>.
<LI>Improved output with more than 3 bytes of object code from a line.
<LI>Now outputs code in Intel Hex format. Old object format still available
by changing a <tt>#define</tt>.
</UL>
<HR>
<H3>Version 1.6 changes (2004-04-30)</H3>
<UL>
<LI>Separated common code so that my Z-80 assembler could use the new features
like macros and <tt>INCLUDE</tt>.
<LI>Fixed a bug that would cause phase errors with one-character label names.
<LI>Fixed a bug that would prevent control pseudo-ops from working after <tt>END</tt>
pseudo-op.
<LI>Added <tt>DC.B</tt>, <tt>DC.W</tt>, <tt>.BYTE</tt>, and <tt>.WORD</tt> pseudo-ops for compatibility with source
code written for various other assemblers.
<LI><tt>DB</tt> now handles double quotes, <tt>\r</tt> <tt>\n</tt> <tt>\t</tt> <tt>\'</tt> and <tt>\"</tt>. A bug in the handlng of
paired quotes (<tt>"foo""bar"</tt>) was fixed.
<LI>new <tt>DRW</tt> pseudo-op to do a <tt>DW</tt> in reverse order (such as for Atari 7800 Maria
chip display lists)
<LI>added <tt>INCLUDE</tt> pseudo-op. Maximum nesting level is set to 10 by a <tt>#define</tt>.
<LI>added <tt>PROCESSOR 6502</tt>/<tt>PROCESSOR 65C02</tt> pseudo-op to select 65C02 instructions,
and for improved DASM compatiblity. The default is 6502 instructions only.
<LI>increased the size of <tt>bytStr[]</tt> from 256 to 1024 bytes. This will allow more
data for long-data pseudo-ops like <tt>DB</tt>, etc.
<LI>added support for <tt>DS</tt> pseudo-op with an initializer. This is currently
limited to a max of 1024 bytes. (<tt>DB</tt>, <tt>DW</tt>, and <tt>FCC</tt> also have this limit, but
do not yet have a bounds check for it.)
<LI>added <tt>HEX</tt> pseudo-op. This also currently limited to a max of 1024 bytes.
<LI>[ and ] can now be used as parentheses in expressions, for better DASM source
compatibility.
<LI><tt>REND</tt> pseudo-op added for better DASM source compatibility. Note that a label
on the <tt>REND</tt> line will receive the relocated value of the last relocated code
byte + 1.
</UL>
<HR>
<H3>Version 1.7 changes (2004-08-25)</H3>
<UL>
<LI>Added a 6809 assembler back-end.
<LI>Added an 8085 assembler back-end. Couldn't just add 8080/8085 style opcodes
to the Z-80 assembler because the <tt>JP</tt> opcode with no condition in the Z-80
style mnemonics conflicts with <tt>JP</tt> in the 8080/8085 style mnemonics.
Irony: this assembler originally started out a long time ago as an 8080
assembler, and now it is again! I did this new 8080 code from scratch,
rather than porting the old Turbo Pascal code to C.
<LI>Added a 68HC11 assembler back-end, with support for 6800, 6801, and 6303
instruction set variations.
<LI>Added support for undocumented 6502 instructions, enabled with "<tt>PROCESSOR
6502U</tt>". Only the most reliable and useful instructions are implemented:
3-cycle <tt>NOP</tt> (mnemonic <tt>NOP3</tt>), <tt>LAX</tt>, <tt>DCP</tt>, <tt>ISB</tt>, <tt>RLA</tt>, <tt>RRA</tt>, <tt>SAX</tt>, <tt>SLO</tt>, <tt>SRE</tt>, <tt>ANC</tt>,
<tt>ARR</tt>, <tt>ASR</tt>, and <tt>SBX</tt>.
<LI>Added pseudo-ops to 6502 assembler to select CPU type without <tt>PROCESSOR</tt>
pseudo-op: <tt>.6502</tt>, <tt>.6502U</tt>, <tt>.65C02</tt>
<LI>Added conditional assembly using <tt>IF <expr></tt> / <tt>ELSE</tt> / <tt>ELSIF <expr></tt> / <tt>ENDIF</tt>.
Maximum official nesting level is 255, but beyond that it will still work if
you don't try wierd stuff like multiple <tt>ELSE</tt> statements in a row. <tt><expr></tt> is
an expression that is false if it is equal to 0 and true if it is not equal
to 0.
<LI>Added new operators to the expression evaluator, because IF needed them:<br>
<tt>..def</tt> symbol (returns 1 if symbol is defined)<br>
<tt>..undef</tt> symbol (returns 1 if symbol is not defined)<br>
<tt>&&</tt>, <tt>||</tt> (boolean and/or, returns either 1 or 0)<br>
<tt><</tt> <tt><=</tt> <tt>></tt> <tt>>=</tt> <tt>=</tt> <tt>==</tt> <tt>!=</tt> (returns either 1 or 0; <tt>=</tt> and <tt>==</tt> are the same)<br>
Beware the operator precedence when using these!
<LI>Added new <tt>H()</tt> and <tt>L()</tt> operators for compatiblity with vintage Atari 7800
source code, equivalent to <tt>>()</tt> and <tt><()</tt>. Note that no whitespace is allowed
before the left paren.
<LI>Symbols may now contain the '$' character, but they must not start with it.
This, combined with <tt>H()</tt> and <tt>L()</tt>, will allow the original Atari 7800 ROM
source code to compile as-is.
<LI>Single quote operator can now handle 2-byte constants. The first character
becomes the high byte of the constant.
<LI>Added <tt>0xnnnn</tt> hexadecimal constants (but not <tt>0nnn</tt> octal constants).
<LI>Fixed problems with <tt>DB</tt>, <tt>DW</tt>, <tt>DS</tt>, and <tt>FCC</tt> pseudo-ops.
<LI>Added bounds checking to <tt>DB</tt>, <tt>DW</tt>, and <tt>FCC</tt> pseudo-ops. They are now limited to
<tt>MAX_BYTSTR - 1</tt> bytes (1023).
<LI>Added <tt>ERROR</tt> pseudo-op.
<LI>Added <tt>ALIGN</tt> pseudo-op.
<LI>Added <tt>SEG</tt>/<tt>RSEG</tt>/<tt>SEG.U</tt> pseudo-op.
<LI><tt>INCLUDE</tt> pseudo-op can now accept file names surrounded by single or double
quotes.
<LI>Handled division by zero.
<LI>Improved handling of form feed characters in source files.
<LI>Fixed some bugs in macro handling, and expanded maximum macro parameters from
10 to 30.
<LI>Temporary labels can now start with '<tt>.</tt>' in addition to '<tt>@</tt>'.
<LI>Labels can be defined from the command line with "<tt>-d label=value</tt>". If value
is not specified, the label is set to zero.
<LI>Added <tt>-9</tt> command line option to generate Motorola S9-record code output.
<LI>Added <tt>-c</tt> command line option to send object code to stdout, to allow piping
to makerom.
<LI>Console output now goes to stderr.
<LI>Error messages now include file name and line number.
<LI>Bytes out of -127..256 range now generate a warning instead of an error.
<LI>Rewrote the documentation.
</UL>
<HR>
<H3>Version 1.7.1 changes (2004-10-20)</H3>
<UL>
<LI>Added exclusive-or ("<tt>^</tt>") to the expression evaluator. This has the same
precedence as the existing <tt>AND</tt> and <tt>OR</tt> operators.
<LI><tt>DB</tt> has been modified to handle the case of arithmetic parameters which
start with a single-quoted character, such as "<tt>DB 'X'+$80</tt>".
<LI>6809 conditional long branches were off by one.
<LI>Changed 68HC11 assembler file name to all lowercase.
<LI>Found out that <tt>asm68hc11.c</tt> wasn't being included in the zip archive anyhow.
<LI>Added an F8 assembler back-end. Since I have no real code to test this on,
it should be considered experimental.
</UL>
<HR>
<H3>Version 1.7.2 changes (2005-08-21)</H3>
<UL>
<LI>Added the <tt>SUBROUTINE</tt> pseudo-op.
<LI>Added <tt>BLKB</tt> pseudo-op as an alias to <tt>DS</tt>.
<LI>Fixed a bug that would cause errors if the line after an <tt>ENDM</tt>
was not a blank line.
<LI>F8 assembler relative branches were off by one.
<LI>Other minor changes to F8 assembler, including allowing expressions for
register numbers in more places, and 'A' and 'B' as hex register numbers
when not inappropriate.
<LI>Tweaked symbol table output to show up to 19 characters of symbol names,
and to fit in 80 columns.
<LI><tt>ENDIF</tt> lines and the guts of <tt>MACRO</tt> declarations did not respect the
<tt>LIST OFF</tt> setting.
<LI>Macro parameters can now be inserted without surrounding whitespace using
the '<tt>##</tt>' concatenation operator, similar to how it works in C macros.
<LI>6502 assembler can now force absolute or absolute-indexed addressing mode
(instead of zero-page and zero-page-indexed) by using '<tt>></tt>' in front of the
address, similar to how the 6809 does it.
<LI>When not using the <tt>-w</tt> option, warning lines would still print to the
console.
<LI>Z-80 assembler can now take parameters after a <tt>RST</tt> instruction, which are
interpreted as <tt>DB</tt> bytes. Example: <tt>RST 08H,'('</tt>
<LI>Fixed a bug that could cause phase errors if a forward-referenced label was
used with <tt>DW</tt>.
<LI>started work on <tt>REP</tt> pseudo-op (code still under construction)
<LI>Added an 1802 assembler back-end.
<LI>Added opcode table of common pseudo-ops to <tt>asmguts.h</tt>, and removed "<tt>DoStdOpcode</tt>"
pass-thru in order to keep more generic stuff out of the CPU-specific .c files.
<LI><tt>CPU_BIG_ENDIAN</tt>/<tt>CPU_LITTLE_ENDIAN</tt> <tt>#define</tt> now automatically controls
<tt>DW</tt>/<tt>DRW</tt> opcodes and <tt>Instr3W</tt>/<tt>Instr4W</tt>/<tt>Instr5W</tt> calls.
<LI>Cleanups for GCC 4 stricter type checking: string signedness with <tt>Str255</tt> type
and forward declaration of <tt>OpcdTab</tt>.
<LI>Short branch range check was allowing branches too far forward.
<LI>Z-80 assembler couldn't do "<tt>CP (a+b)/256</tt>" (or <tt>SUB</tt>, </tt>AND</tt>, <tt>OR</tt>, <tt>XOR</tt>) because it was
expecting "<tt>CP (HL)</tt>" etc. Now it falls back and tries to evaluate the parens as
an immediate operand.
<LI>Added <tt>OPT NOEXPAND</tt> to disable expanding hex output for more than one listing line.
<LI>All standard pseudo-ops can now optionally start with a period, such as <tt>.DB</tt>, <tt>.DW</tt>,
<tt>.EQU</tt>, etc.
<LI>Standard pseudo-ops can now start with a period in column 1.
<LI>Symbol table output handles long symbols better by stretching really long symbol
names into multiple columns.
</UL>
<HR>
<H3>Version 1.7.3 changes (2006-01-23)</H3>
<UL>
<LI>Added "<tt>\0</tt>".."<tt>\9</tt>" macro parameter substitution as per the ASnn series of
assemblers at <A HREF="http://www.kingswood-consulting.co.uk/assemblers/">
http://www.kingswood-consulting.co.uk/assemblers/</A>. Even though
it seems a bit silly to have more than one way to access macro parameters,
this does provide a way to get the number of macro parameters, and to generate
unique labels inside a macro.
<P>
<tt>\0</tt> = number of macro parameters<BR>
<tt>\1</tt>..<tt>\9</tt> = nth macro parameter<BR>
<tt>\?</tt> = unique ID per macro invocation (padded with leading zeros to five digits)
<LI>6809 <tt>SETDP</tt> pseudo-op was broken by the opcode table rearrangement in 1.7.2.
It has been fixed.
<LI>Added the "<tt>:=</tt>" pseudo-op as an alias for the "<tt>SET</tt>" pseudo-op.
<LI>Multi-level nested macros have been implemented.
<LI>The "<tt>SET</tt>" pseudo-op now works properly for Z-80. The <tt>SET</tt> opcode was hiding
access to the pseudo-op, though other variations ("<tt>.SET</tt>" and "<tt>:=</tt>") would still
work. This fix is tricky enough that there may be some wierd side-effects in
error situations. Some bugs with Z-80 <tt>SET</tt> opcode error handling were fixed as
well.
<LI>Added backslash hex escapes ("<tt>\xFF</tt>") for strings in <tt>DB</tt> pseudo-op.
<LI>"Short branch out of range" was changed from a warning to an error.
<LI>Added an 8051 assembler back-end.
</UL>
<HR>
<H3>Version 1.7.4 changes (2006-11-09)</H3>
<UL>
<LI>Updated Z-80 assembler with improved parsing techniques from the 8051
assembler.
<LI>In Z-80 assembler, "<tt>LD BC,(foo - 1) * 256</tt>" wouldn't assemble properly.