-
Notifications
You must be signed in to change notification settings - Fork 1
/
macxx.doc
2285 lines (1814 loc) · 88.3 KB
/
macxx.doc
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
MACxx Macro Assembler
Version 7.7
Created Nov 1976
Revisions through Nov 1989
MACxx is a one pass assembler written in C that has been ported to
various operating systems. It consists of a core group of pseudo-ops
common among all versions of the assembler (MAC65, MAC68, MACAS, MACPP,
MAC68K, etc) and a common statement syntax. The output of these assemblers
(except MACPP) is expected to be further processed by LLF, a linkage
editor, into a load image.
Copyright Atari Games, Corp. 1977 through 1989. Unauthorized
reproduction, adaptation, distribution, performance or display
of this document, the associated computer program or the
audiovisual work is strictly prohibited.
Chapter 1 - Statement syntax
1.0 Statement syntax
A source program is composed of a sequence of source lines; each
source line contains a single assembly language statement followed by a
terminator (line feed or form feed). Input lines are limited to 255
characters.
A statement can contain up to four fields which are identified by order
of appearance and by specified terminating characters. The general
format of a MACxx assembly statement is:
label: opcode operand(s) ;comments
The label and comment fields are optional and delimited by one or two
colon characters (:) and the semicolon (;) respectively. White space
may be required to delimit the opcode from the operand and multiple
operands may need either a comma (,) or white space to delimit them from
one another but otherwise, white space is optional.
1.1) Label field
A label is a user defined symbol that is unique to the first n characters
(the default is 6, but can be changed to any number up to 32) and is
assigned to the value of the current location counter and entered into
the user symbol table (as opposed to the 'permanent' symbol table). The
value may be either absolute (fixed at a specific location in memory at
assembly time) or relocatable (fixed at a specific location at link or
load time). This depends on whether the current section is absolute or
relocatable. A label is a symbolic method of referring to a specific place
in memory. If present, a label must be first in the statement and
terminated with a colon. For example:
FRED: LDA FOOBAR
defines FRED to point to the location in memory of the LDA instruction.
More than one label can appear on a single statement, however, each
will be given the same value. For example:
ONE: TWO: THREE: LDA FOOBAR
defines ONE, TWO and THREE to point to the location in memory of the LDA
instruction. A symbol used as a label may not be redefined and any
attempt to do so will result in an error message. If two colon
characters are used to delimit the label, then the label is defined
as a global. Global labels are inserted into the object file so that
LLF and, subsequently, other modules will be able to reference them
by name.
For example:
FRED:: LDA FOOBAR ;fred is defined and also made global
Internal symbols may belong to the current program section or to other
program sections. Expressions containing symbols belonging to different
program sections may not be completely resolved by the assembler.
Depending on the type of operation that is required in the expression,
it may not be possible for the assembler to resolve an expression
regardless of which section a symbol belongs. In these cases, the
expression will be passed to LLF to be resolved after all the sections
have been relocated and labels defined to their ultimate values.
1.2) Opcode field
The opcode field contains an opcode, macro name or assembler directive
(pseudo-op). Is is legally terminated by white space or any
non-alphanumeric character. For example:
LDA #FRED ;the white space delimits the opcode
LDA#FRED ;the # delimits the opcode
1.3) Operand field
The operand field contains zero, one or more items that may be separated
by commas or white space depending on the requirements of the opcode,
macro or pseudo-op. The operand field is terminated by the semicolon of
an optional comment or an end-of-line. For example:
CLC ;no operands are required
LDA FRED ;FRED is the operand
LDA FRED,X ;FRED and X are operands to the LDA opcode
1.4) Comment field
The comment field is optional and may contain any printing ASCII
character as well as tab and space. All other non-printing ASCII
characters except new-line will be converted to white space. The
comment begins with a semicolon (;) which may appear anywhere on the
line and continues to end-of-line. The contents of comments are
ignored by the assembler.
1.5) Formatting
Spaces, tabs and form feeds may be used at will to control the text
formatting in the source file. A form feed character is interpreted as
a new line. Except in certain contexts (such as ASCII constants and
parameter delimiting) white space is ignored by the assembler.
1.6.0) Symbols
Assembler symbols, labels and macro names can be comprised of any of the
letters A through Z (upper and/or lower case), digits 0 through 9,
period (.), dollar sign ($) and underscore (_). The first character of a
symbol or label must not be a digit. The case of the letters in a symbol
is not significant unless the .ENABL LOWER option has been selected. For
example:
Valid symbols Invalid symbols
------------- ---------------
ABC 0123
abc 2abc
$._AB_C.$$ 9$AB_.
The symbol length is, by default, significant to the first 6 characters
only. The length can, however, be changed via a command line option or
an assembler directive. In either case the significant length cannot be
reduced to less than 6 nor made greater then 32. Symbols output in the
object file will be uppercased (unless the .ENABL LOWER option has been
selected) and truncated to the significant length. Symbols are delimited
by any character that is not included in the list of valid symbol
characters. Be advised that not all load file formats accept symbol names
as long as 32 characters. Extended TEKhex, for example, will only pass
the first 16 characters of a symbol name. This will only be a
significant factor if one intends on passing global symbols with long
names to a symbolic debugger via a restricting load file format.
1.6.0.1) Permanent symbols
Permanent symbols are those pre-defined in the assembler and consist
entirely of opcodes and pseudo-ops. The assembler allocates memory from
the operating system and "seeds" this area with the permanent symbols
stored internal to the assembler. Macro names that are defined by the
user are placed into the permanent symbol table perhaps replacing an
existing entry.
1.6.0.2) User defined symbols
User symbols both ordinary and local are stored in a user symbol table.
This symbol table is the only one searched during expression evaluation.
The permanent symbol table is the only one searched for opcodes.
Consequently, macro and opcode names may be the same as symbol and label
names and each represents different values.
User defined symbols are either internal or external (global). All user
defined symbols are internal unless explicitly declared otherwise.
MAC68K and MACAS have predefined user symbols representing the standard
register names found in those processors. See the appendix for specifics.
1.6.0.3) Local symbols
There's a special type of symbol known as a local symbol. This symbol
is a string of decimal digits terminated with a dollar sign. Its
presence is known only within what is known as a local symbol block.
The local symbol block is delimited, unless otherwise indicated, with
changes in program sections or by the definition of a new label.
Local symbols can be used anywhere ordinary symbols can be used and are
defined the same as ordinary symbols. They cannot, however, be declared
global. Local symbols must consist only of the digits 0-9 and a
trailing dollar sign, but otherwise they are treated as ordinary strings
and are limited in length to the maximum input size of 255 characters.
Some examples:
lsb_1: ;Any label starts a new local symbol block
10$: ;defines local symbol 10$
20$ = fred ;direct assignments work too,...
LABEL = fred ; ...however, they do NOT open a new lsb
30$: ;another label
lsb_2: ;Opens a new local symbol block
10$: ;these local symbols are not the same as
20$: ; the other ones because they are in a
30$: ; different local symbol block.
.PSECT ;this opens a new local symbol block too
There may be instances where one needs to reference local symbols
across ordinary labels or through program section changes. This can be
accomplished with a pseudo-op:
.ENABL LSB ;opens a local symbol block and turns OFF
; the normal lsb delimiter sensing.
10$: ;defines a local symbol
LABEL: ;in this case, does NOT open a new lsb
.WORD 10$ ;refers to the 10$ above LABEL
.DSABL LSB ;closes the local block and turns back ON
; then normal lsb delimiter sensing.
1.6.0.4) Location counter symbol
There's another special pre-defined symbol, period (.), that refers to
the current location counter. The value of this symbol is always defined
and may be relocatable or absolute depending on the attribute of the
current section. The period may not be used as a label. It may only be
used in expressions and as the target of a direct assignment statement.
For example:
saved_place = . ;saves current location
. = some_new_place ;set the current location to new place
offset = <.+3>/4 ;compute displacement
Care must be used when making direct assignments to the location counter
or there will certainly be unexpected results. For example, there are
times when one wants to position the location counter to a fixed
location from the beginning of a RELOCATABLE program section. This
CANNOT be done by simply assigning the location counter to the offset.
Suppose one wants to set the location counter to an offset of 1000 from
the start of section DATA. First a symbol would have to be defined at
the beginning of the DATA section:
.PSECT DATA ;declare section DATA
START_OF_DATA: ;define first location of section DATA
Then the location counter can be set:
. = START_OF_DATA+1000 ;move PC to DATA+1000.
The more direct approach of .=1000 is only allowed when the current
location is an absolute (non-relocatable) section. Direct assignments
that would result in having the current section change are not allowed
and will result in an error message. For example:
.PSECT TEXT
FRED:
.PSECT DATA
. = FRED ;will result in an error since FRED
; is not in the DATA psect
1.6.0.5) Symbol blocks
Another form of local symbol block exists which allows for all forms of
symbols to appear "local to the block". That is, symbols and labels
defined within a symbol block can only be referenced by code and data
appearing within that block or a fully enclosed block. These blocks can
be nested to a depth of 7. Nested levels beyond 7 are folded into
level 7 and a warning message stating that the scoping is too deep is
displayed. Inner blocks may reference symbols and labels defined in an
outer block, but outer blocks may not reference symbols and labels
defined in inner blocks. The outer most level is 0 and is the level
used by normal symbols and labels. There are a maximum of 8192 blocks
available in a single assembly module.
WHEN USING SYMBOL BLOCKS, FORWARD REFERENCES TO SYMBOLS OR LABELS ARE
NOT ALLOWED. All symbols and labels referenced in the current block must
be predefined or predeclared. There is a .LOCAL directive to declare a
symbol and/or label in a block if it is referenced before it is defined.
1.6.1.0) Radix
The programmer can specify the radix with which a number is to be
interpreted on each number appearing in the source or globally for all
numbers appearing in the source. The radix values can be one of 2,8,10
or 16. Using the .RADIX pseudo-op specifies which radix to use for all
numbers appearing between that directive and the next .RADIX or end of
file. The unary operators ^B, ^O, ^D (or trailing period), ^X or ^H
can be used on individual numbers to indicate the radices 2, 8, 10, 16
or 16 respectively. In addition, hexadecimal numbers may be expressed by
prefixing a "0x" or "0X" to them.
1.6.1.1) Numbers
Number constants are strings consisting of the digits 0-9 and the
letters A-F. The first character of the number must be a digit 0-9
regardless of the current radix. Any character not of that character set
delimits the number. If the number contains digits that are greater than
the current radix allows, the assembler will attempt to evaluate the
number at the appropriate higher radix and displays an error message. A
temporary decimal radix can be set by appending a period to the number
or any other temporary radix can be set via a one of the unary operators
(^B, ^D, ^O, ^X or ^H for binary, decimal, octal, hex or hex respectively).
For example:
0110 ;valid binary, octal, decimal or hex number
1234 ;valid octal, decimal or hexadecimal number
7890 ;valid decimal or hexadecimal number
0FFF ;valid hex number
A000 ;not a valid number (valid symbol, though)
1000. ;decimal 1000
0x1234 ;hexadecimal number
1.7) Expressions
An expression is a collection of one or more terms separated by
arithmetic operators. There are both unary operators (apply only to a
single term) and binary operators (apply to two terms). Unlike most
other languages, all operators have equal precedence and are evaluated
from left to right. The order of evaluation can be changed by the use of
the parenthesis. (In MAC65, the parenthesis must be substituted with the
expression brackets "<" and ">"). All terms in an expression and the
result of the expression itself are 32 bits (signed). The relational
operators (not available in MAC65) return either a 0 for false or 1 for
true.
Binary operators: Examples
---------------- ---------
+ add A+B (can also be +A which means 0+A)
- subtract A-B (can also be -A which means 0-A)
* multiply A*B (returns a 32 bit product)
/ divide A/B (returns a 32 bit quotient)
& logical and A&B
| logical or A|B
The following are available ONLY in MAC65, MAC68 and MAC69:
! logical or A!B (same as |)
? exclusive or A?B
{ shift left A{B A is shifted B bits left
} shift right A}B A is shifted B bits right
The following are NOT available in MAC65, MAC68 and MAC69:
^ exclusive or A^B
<< shift left A<<B
>> shift right A>>B
== equality A==B returns 1 if A equals B
!= not equal A!=B returns 1 if A not equal B
> greater than A>B returns 1 if A greater than B
< less than A<B returns 1 if A less than B
>= greater, equal A<=B 1 if A greater than or equal to B
<= less, equal A>=B 1 if A less than or equal to B
Unary operators are escaped with a circumflex (^) which means the character
following the circumflex is the operator.
Unary operators Examples
--------------- --------
^B change radix to 2 ^B 111000
^C 1's compliment ^C A ;takes 1's compliment of A
^D change radix to 10 ^D 100 ;constant 100 decimal
^H change radix to 16 ^H 100 ;constant 100 hexadecimal
^X change radix to 16 ^X 1FF ;constant 1FF hexadecimal
^O change radix to 8 ^O 100 ;constant 100 octal
^V take low byte ^V A ;bits 0-7 of A
^^ take high byte ^^ A ;bits 8-15 of A
^~ swap bytes ^~ A ;swap bits 0-7 with bits 8-15
;and bits 16-23 with bits 24-31
Any term of an expression may be enclosed in a pair of expression
brackets ('<' and '>' in MAC65, MAC68 and MAC69 or '(' and ')'
in all other assemblers) and itself be a collection of one or
more terms. For example:
A+<<B*C/D+6>*100>/4?^V<FRED*10>+^H<0FFF+ABC+1234> ;MAC65, MAC68 or MAC69
A+((B*C/D+6)*100)/4^^V(FRED*10)+^H(0FFF+ABC+1234) ;others
would evaluate in the following order (left to right, all operators having
equal precedence):
B*C/D+6*100+A/4 exclusive OR'd with the low byte of FRED*10
and the whole result added to ABC+(hex)2233
1.8) Direct assignment
A direct assignment statement associates a symbol with a value (or an
expression). When a direct assignment statement is used for the first
time that symbol is entered into the user defined symbol table and the
specified value is attached to it. If the expression does not resolve
to an absolute value, then the expression is attached to the symbol. A
symbol may be re-defined by assigning a new value to it. The latest
assigned value replaces any previous value assigned to the symbol.
The general format is:
symbol = expression ;comments
Symbols take on the relocatable or absolute attributes of their defining
expression. If the expression does not resolve to a single term then the
resultant expression is attached to the symbol and the value of the
symbol becomes a multiple term expression which will be substituted in
whatever other expressions the symbol is used and, in fact, may be
passed on to LLF if it cannot be resolved during object file creation. A
double equal sign will declare the symbol global as well as defining it,
however, for purposes of linking, only the last assignment made to a
symbol is passed to LLF (i.e. the value at the end of pass one of the
assembler is what gets passed to LLF). One may prefix a colon to the
equals or double equals to indicate that the symbol is to be defined
only once (i.e. generate an error if the symbol is redefined elsewhere).
For example:
A = 1 ;A has absolute value of 1
B: ;defines B as a relocatable
C = B ;C is equivalent to B
D = E+F+G ;If E, F or G is undefined or relocatable then
; D becomes defined as E+F+G (expression)
H == 12 ;H is global 12
. = .+100 ;move the location counter up 100 bytes
J := 10 ;make J an absolute 10 and not eligible for
; redefinition
DO NOT MAKE CIRCULAR ASSIGNMENTS SUCH AS
A = B
B = C
C = A
1.9) Register symbols and expressions
Some assemblers (such as MACAS and MAC68K) may have opcodes that allow
or require registers as operands. They may, in fact, sense the type of
operand and output object data differently based on whether there is a
register referenced in the operand. Any valid expression term with a
leading percent sign (%) declares that term as a register (for example
%5 means register 5). Symbols can be defined as being register
designators by assigning them to an expression with one or more of the
terms being a register term. The symbol will inherit the register
attribute from the expression. For example:
R0 = %0 ;general register 0
R10 = %10. ;general register 10
TEMP = R0 ;symbol TEMP becomes equivalent to R0
GR11 == %11. ;global general register 11
Register symbols can be global and can even be defined in other modules.
Global register symbols used but not defined in a given module must be
declared with the .GLOBR pseudo-op. The register attribute of a symbol
is only significant during the operand processing of an opcode. The
register attribute of a symbol is not significant in any other assembler
expression. The register attribute is ignored in MAC65. Undefined registers
are not allowed in MAC68K. See the appendix for a list of pre-defined
register symbols for the assembler you are using.
Chapter 2 - Assembler Directives
2.0) Assembler Directives, aka pseudo-ops, are statements that the
assembler intreprets as commands to itself. Directives control various
aspects of the assembler behavior and output.
2.1) .ALIGN Alignment directive
.ALIGN expression
where expression must resolve to an absolute between the values 0 and 31
inclusive. The value of expression becomes an exponent of 2 and the location
counter is adjusted to the next multiple of the result. The alignment
attributes of the current program section must enforce an alignment at least
as great as the one requested or a warning message will be displayed.
If the alignment attributes of the current section do not enforce an
alignment as great as the one requested, then do not expect the resultant
location after linking (LLF) to be correct. Some examples:
.ALIGN 3 ;aligns to next multiple of 8 bytes
.ALIGN 0 ;aligns to next byte (a nop effectively)
.ALIGN 1 ;aligns to 2 byte boundary
.ALIGN fred ;aligns to whatever FRED resolves to
2.2) .ASCII Ascii string directives
.ASCIN
.ASCIZ
Deposits a string of ASCII characters beginning at the current location.
The parameter string consists of a string of ASCII characters delimited
by a pair of ASCII characters. The first character in the string is assumed
the delimiter for the string. The delimiters are not considered part of the
string so are not inserted into the output file. Any printing character can
be a delimiter. Expressions can be inserted in the middle of the string by
delimiting the string and enclosing the expression in matching expression
brackets (<>'s in MAC65, ()'s in the other assemblers). Ths general
format is:
.ASCII string ;Straight ASCII string
.ASCIN string ;The last byte of the string has bit 7 set
.ASCIZ string ;An extra byte of 0 is inserted at the end
; of the string
Some examples:
.ASCII /123/ ;puts (hex) 31 32 33 beginning at the current location
.ASCIN /123/ ;puts (hex) 31 32 B3
.ASCIZ /123/ ;puts (hex) 31 32 33 00
.ASCII \123\<some_expression>/456/ ;puts 31 32 33 xx 34 35 36
;second set of delimiters doesn't have to match the
; first set of delimiters.
2.3) .ASECT Absolute program section directive
.ASECT
This directive sets the current program section to the default absolute
section and sets the location counter to the value that was last used in
that section. It is equivalent to:
.PSECT .ABS.
See the .PSECT directive for more details.
2.4) .BLKx Space allocation directives
.BLKB expression ;allocates bytes (expression*1)
.BLKW expression ;allocates words (expression*2)
.BLKL expression ;allocates longs (expression*4)
.BLKQ expression ;allocates quads (expression*8)
DS.B expression ;(identical to .BLKB)
DS.W expression ;(identical to .BLKW)
DS.L expression ;(identical to .BLKL)
Effectively allocates space in the current program section. It moves the
location counter by the specified number of elements. The expression
must be absolute but does not have to be positive (a negative value will
move the location counter backwards). The .BLKW, .BLKL and .BLKQ
directives will also verify that the current location is aligned
correctly as indicated by the current section alignment attributes.
Examples:
.BLKB 100 ;reserve 100 bytes
.BLKL 200 ;reserve 200 longwords (800 bytes)
2.5) .BSECT Base section directive
An obsolete directive. See .PSECT for details.
2.6) .BYTE Constant storage directives
.WORD
.LONG
DC.B (same as .BYTE)
DC.W (same as .WORD)
DC.L (same as .LONG)
Syntax:
directive expression [[,]...]
All of the above directives have the same syntax. There can be 0 or more
expressions separated by any construct that is not a valid expression
term such as a comma or two terms not joined with an expression
operator. Each expression is inserted in the object code at the next
higher location. The location counter is verified to have the correct
alignment according to those specified in the current program section.
The .BYTE directive places 1 or more bytes in the object file. The .WORD
directive places one or more 16 bit words in the object file. The .LONG
directive places one or more 32 bit longwords in the object file.
Some examples:
.BYTE ;no expression means insert a 0
.BYTE 1,2,3 ;puts a (hex) 01 02 03 in the output file
.WORD one two three ;puts 3 words (6 bytes) in the object file
.LONG fred + sam foobar ;This puts 2 longs into the output file
;because fred + sam is a legal expression
;with or without the whitespace. As a result
;the first longword output would be the
;expression fred+sam and the second longword
;would be the expression foobar.
.BYTE fred '+ sam foobar ;puts 4 expressions into the output file.
;the '+ is not a valid operator to join two
;terms, so it is assumed to be a term of its
;own. As a result, four expressions are output:
;fred, '+ (hex 2B), sam and foobar.
2.10) .CSECT
An obsolete directive. See .PSECT for details.
2.11) .DEFINE
The .DEFINE directive allows for the assignment of an arbirtary string
to a single assembler symbol. Everywhere in the source between the
.DEFINE and an .UNDEFINE where the symbol appears, the string will be
substituted. It works similar to a #define in the C language. The
general form is:
.DEFINE symbol an_arbitrary_string [;comments]
where symbol is the name of the symbol which is to be substituted and
"an_arbitrary_string" is any string of printable characters up to but
not including the semicolon delimiting any comments. White space
between the symbol name and the string as well as white space between
the last character of the string and the comment is not included in the
string. Only one level of substitution is performed, that is to say no
tokens on a .DEFINE or .UNDEFINE directive will be substituted with
previously .DEFINE'd symbols. Once a symbol is substituted, the text
that has been substituted is not checked for further substitutions.
Token substitution can take place embedded in strings if the token in
question is surrounded with apostrophes (the same rules as an argument
in a macro). Inside macro calls .DEFINEd tokens are replaced after all
macro arguments are inserted.
Having one or more .DEFINE'd symbols will have an adverse effect on the
assembler's performance. It is better used in small sections of source
code (such as during macro definitions), since a symbol can be
.UNDEFINE'd which will restore the assembler's performance. Examples:
.define fred any string of chars up to a semicolon
.define foo a+b ;defines foo
will force all subsequent occurrences of "fred" in the source file to be
replaced with the text "any string of chars up to a semicolon" and foo
to be replaced with the string "a+b".
Note that the text appearing in the list file will be that with all
tokens substituted. If the resulting assembly of the line produces
errors, then the original source line will be output to stderr
(SYS$ERROR) along with the error message but without the line with the
circumflex (^).
NOTE: As of version 11.06, using a .DEFINE in an -assem command line
option doesn't work. Avoid using it until it can be fixed.
2.12) .DEFSTACK
Defines an array that may be used at assembly time as a stack or as
temporary storage. This is most useful in complex macros that need to
be able to save and have access to large amounts of data. The syntax is:
.DEFSTACK stack_name [,size [,type]]
where
stack_name is an arbitrary name of the stack which does not have
to be unique from a symbol, macro or opcode name. The
stack_name is used as an argument to subsequent .PUSH,
.POP, .SETPOINTER and/or .GETPOINTER directives.
size is an expression that resolves to the desired size of the
array in elements. If this argument is left blank or
resolves to 0, the stack is purged and the memory
returned to the system.
type is a keyword of BYTE, WORD, LONG or RELATIVE which
represents 1, 2, 4 and ~32 byte element sizes
respectively. The default is RELATIVE.
Note that the amount of memory used is the product of the stack size and
the element type size. Care should be taken as not to create an array so
large that there is no memory left for the assembler proper. On MS-DOS
systems, no single array can be larger than 65,536 bytes (32,768 words;
16,384 longs; ~2000 relative values).
There is a stack pointer associated with each array. The pointer will be
pre-decremented when an item is .PUSH'ed and post-incremented when an item
is .POP'ped. The pointer always moves by one regardless of the size of
the element.
The .GETPOINTER and .PUTPOINTER directives will respectively get or set
the stack pointer on a named stack.
Examples:
FRED = 100
.DEFSTACK temp,FRED+2 ;make a temp array of longs
.DEFSTACK words,16,WORD ;array of words
.DEFSTACK temp ;purge temp array
NOTE: These stack options are not available in recent macxx versions.
2.15) .DSABL and .ENABL directives
Many of the states and operational characteristics that MACxx provides can be
enabled or disabled by way of one of these directives. The syntax is
directive arg1[,...,argn]
where directive is one of .ENABL (to enable the function) or .DSABL to
disable the function and arg1 through argn represents one of the following
keywords:
ABS - Has no effect. Exists simply for compatibility with older
versions of the assembler.
LC - Has no effect. Exists simply for compatibility with older
versions of the assembler.
LSB - Enables or disables a Local Symbol Block. Normally a local
symbol block starts/ends with the presence of a label or
encountering a .PSECT directive. A local symbol block
opened with a .ENABL LSB, remains in effect until a
.DSABL LSB directive is encountered regardless of how
many labels and .PSECT directives lie in between.
USD - Causes all divisions in both local and global expressions
to be computed using unsigned arithmetic (UnSigned Divide).
The default is .DSABL USD (use signed divides).
GBL - Causes all undefined symbols to automatically be declared
global. Use with care. The default is .DSABL GBL.
WORD or .WORD - enables or disables the feature where undefined
opcodes are assumed to be arguments to a .WORD directive.
The default is .DSABL WORD (undefined opcodes/directives
are reported as an error).
BYTE or .BYTE - enables or disables the feature where undefined
opcodes are assumed to be arguments to a .BYTE directive.
The default is .DSABL BYTE (undefined opcodes/directives
are reported as an error).
M68 - If enabled, causes words and longs to be output big endian
style (as the Motorola processors require) and if disabled
causes words and longs to be output in little endian style
(such as the 6502 and 80x86 require). The default is
processor specific. MAC65 and MACAS default to .DSABL M68.
MAC68K defaults to .ENABL M68.
LOWER_CASE - If enabled, makes all symbols and labels case
sensitive. Global symbols and labels are passed to LLF
without having their case changed. Additionally, no
changes are made to PSECT names.
DOLLAR_HEX - If enabled, allows hexidecimal constants to be
expressed Motorola style, that is with a leading dollar
sign. I.e. 0x1234 <==> $1234.
CR - If enabled, allows carriage return characters in the input
stream. Otherwise, the carriage return, '\r' character
terminates the line. Disbabled by default. WARNING: Enable
of this function will likely break the .IF BLANK and .IF
IDENTICAL (and equivalent) conditionals.
The following keywords are specific to MAC65 and the 6502 processor.
MOS - If enabled, turns on the MOS TECHNOLOGY 6502 opcode and
address mode syntax. If disabled, turns on the old Atari
opcode and address mode syntax. See appendix A for details
of both. The default is .DSABL MOS.
AMA - If enabled, instructs MAC65 to attempt to determine from the
value of an operand whether the address mode should be
zero page or absolute mode. If disabled, the shortest
(fewest number of bytes) form of the instruction will be
selected. See appendix A for more details. The default
is .DSABL AMA.
Some examples:
.ENABL MOS,AMA,USD
.DSABL WORD,GBL
.ENABL LSB
2.16) .END
Declares the logical end of assembly and an optional transfer address.
.END [transfer_address]
The transfer address, if present, must be an expression that resolves to
a single term that must be defined. If no transfer address is defined,
no transfer address will be delivered to LLF. Except for the
transfer address argument, the directive is ignored by MACxx and
assembly continues until end of file. The directive is not required.
2.17) .ENDC
Declares the end of a conditional block. There must be exactly one
matching .IF directive preceding this directive. An error will be
displayed if a .ENDC directive is encountered outside a conditional
block or if a conditional block is opened and not closed with a .ENDC
before an end of file is detected. No arguments are required or allowed
on this directive.
2.18) .ENDM and .ENDR
Declare the end of a macro block. The two directives are identical but
the .ENDM is typically used to close a .MACRO block and the .ENDR is
used to close a repeat block (one of .REPT, .IRP or .IRPC). Either
directive accepts a single argument which, if present, is compared
against the name of the macro for which it belongs. If the names don't
match, an error message will be displayed. Repeat blocks are not named
so no argument should be used on a .ENDx that closes a repeat block.
2.19) .ENDP
Declares the end of a procedure block as declared with a .PROC
directive. The symbol block level is decremented. An error will be
displayed if this directive is used in symbol block level 0 (the top
level). It neither requires nor accepts any arguments. An example:
FUNC_1: .PROC
bla_bla
.ENDP
2.20) .ERROR
.ERROR [[expression] [;comments]]
This directive generates an error and computes and displays the value
of the optional expression. It is useful if included in macros or
conditionals to force an error if desired conditions are not met.
Being that it generates an error, the whole statement will be displayed
in the list file and on standard error, so the comments can best be
used to describe the reason for the error.
2.200) .ESCAPE
This directive allows the changing of various escape characters.
Currently the only characters that can be changed are the macro escape
characters. The form is:
.ESCAPE arg=expression[,...]
where arg is one of the strings itemized below and expression is an
absolute expression that resolves to a printing but non-alphanumeric
character.
Arg Default Function
-------- ------- ---------
MACRO_OPEN '< start of macro argument
MACRO_CLOSE '> end of macro argument
MACRO_ESCAPE '^ alternate macro argument delimiter
MACRO_GENSYM '? indicates argument is autogenerated
MACRO_GENVAL '\ convert macro argument to ASCII
2.21) .EVEN
This directive forces the current location counter to the next higher
even value. Note that the PSECT attributes of the current program
section must enforce a section alignment of at least 1 (word alignment)
in order for this directive to really do what is desired. If the psect
attributes do not enforce at least a word alignment, then the section
may not be located on an even address by LLF (which will make the
effect of the .EVEN to become a .ODD). A warning will be displayed by
the assembler if this condition is present. This directive neither
requires nor accepts any arguments. See .ODD and .ALIGN for additional
alignment options.
2.22) .GETPOINTER
This directive assigns to a symbol the current value of the stack
pointer of the named stack. The symbol must be eligible for
redefinition. The syntax is:
.GETPOINTER stack_name,symbol
where stack_name is the name of the stack as specified in a .DEFSTACK
directive and symbol is the name of a symbol whose value will become
the current value of the stack pointer. An example:
.DEFSTACK FRED,10 ;make a stack
.PUSH FRED,TEMP ;save value of temp
.GETPOINTER FRED,T ;T gets value of stack pointer
NOTE: These stack options are not available in recent macxx versions.
2.23) .GLOBB
.GLOBL
.GLOBR
.GLOBS
.GLOBx symbol_1[,symbol_2,...]
These directives declare one or more symbols or labels as being global
in scope. That is the listed symbols or labels are made known to the
LLF. The symbols or labels may or may not be defined. If they are not
defined anywhere in the source code, then they will be assumed to be
defined in another module or explicitly by LLF. The .GLOBL directive is
the general case for declaring ordinary symbols or labels as global in
scope. The .GLOBR directive declares the symbols as being both global in
scope and of type register (same as .GLOBL in MAC65). The .GLOBB
directive declares the symbols or labels as being resident in base page
(zero page), and at present is only significant to MAC65. The .GLOBS
directive identifies labels and symbols as accessible via "short" (i.e.
16 bit offset) address modes in MAC68K (the directive is identical to a
.GLOBB). Any number of symbols may be listed separated with white space
or commas.
2.25) .IF Conditional directives
.IFF
.IFT
.IFTF
This is the general case conditional directive. It opens a conditional
block which encompasses all the source code between the .IF and a
matching .ENDC directive. The sense of the conditional can be changed
with the .IFF (If False), .IFT (If True) and .IFTF (If True or False).
While the condition is true, the source code is assembled. While the
condition is false, the source code is examined only for conditional
directives and otherwise is ignored. The condition is closed when the
matching .ENDC is encountered. Conditional blocks can be nested to 32
levels within a single macro level. That is, each level of macro call
(including the 0th level) has 32 levels of conditional nesting.
The syntax is:
.IF condition,expression [;comments]
where expression must resolve to an absolute value and condition must
be one of the following strings:
Condition Conditional considered true if
String expression resolves to:
---------- ------------------------------
EQ zero
NE not zero
G greater than zero
GT greater than zero
GE greater than or equal to zero
L less than zero
LT less than zero
LE less than or equal to zero
NZ not zero
Z zero
T true (expression resolves to non-zero)
F false (expression resolves to zero)
EQUAL zero
NOT_EQUAL not zero
GREATER_THAN greater than zero
GREATER_OR_EQUAL greater than or equal to zero
LESS_THAN less than zero
LESS_OR_EQUAL less than or equal to zero
NOT_ZERO not zero
ZERO zero
TRUE true (expression resolves to non-zero)
FALSE false (expression resolves to zero)
There are some special case .IF's that use something other than an
expression to determine the test. These cases are:
.IF condition,symbol
Condition Conditional considered true if
String symbol is:
---------- ------------------------------
DF defined
NDF not defined
DEFINED defined
NOT_DEFINED not defined
In the DF and NDF cases, the symbol may be more than one separated with
either a ampersand (&) for AND or a vertical bar (|) for OR (an
exclamation point (!) in MAC65). For example: .IF DF, LABEL1 & LABEL2
indicates the condition is true only if both label1 and label2 are
defined.
.IF condition,string
Condition Conditional considered true if
String string is:
---------- ------------------------------
B blank
NB not blank
BLANK blank
NOT_BLANK not blank
Note that if the string is enclosed in macro argument delimiters
(normally <>'s) then only the contents between the delimiters is
tested for blank or not blank. Otherwise, if ANY text appears on
the line after the comma separating the condition, the "string"
is considered not blank. This directive only is allowed (or
useful) inside a macro.
.IF condition,string1,string2
Condition
String Conditional considered true if:
---------- ------------------------------
DIF string1 is different than string2
IDN string1 is identical to string2
DIFFERENT strings are different
IDENTICAL strings are identical
SAME strings are identical
Note that string1 and string2 are compared with a simple string
compare. They must match exactly to be considered identical. If
either or both of the strings are enclosed in macro argument
delimiters (normally <>'s), then only the contents between the
delimters is compared.
Some examples:
.IF eq,FRED ;true if FRED is 0
.IF GT,LAB1-LAB2*100 ;true if result is greater than 0
.if ne,LABL-9 ;true if LABL is not 9
.if NE,FLAGS&100 ;true if bit 8 set in FLAGS
.if idn,<arg1>,<arg2> ;true if macro arg1 is same as arg2
.if ndf,label ;true if LABEL is not defined
.if defined, label1 & label2 ;true if both labels are defined
.if b,<param3> ;true if macro param 3 blank
.IF EQ,FLAG ;open a conditional
...some source ;stuff to do if flag is 0
.IFF ;kinda like an ELSE
...some source ;stuff to do if flag is not 0
.IFTF
...more source ;stuff to do regardless of flag value
.IFT
...still more ;stuff to do if flag is 0
.ENDC ;done with conditional
2.26) .IIF
This is a special one line conditional (Immediate IF). It has the same
syntax and rules as the .IF directive except the single statement to be
executed follows the conditional argument(s) separated with a comma.
See .IF for details about the conditionals.
Example:
.IIF NDF,LABEL,LABEL = 100 ;define if not already defined
.IIF EQ,LAB1-10,.error LAB1 ;LAB1 is too big
.IIF b,<arg5>,.error ;No ARG5 argument supplied
2.27) .INCLUDE
This directive allows for additional source files to be included for
assembly. The syntax is:
.INCLUDE filename [;comments]
Note that the semicolon delimits comments so, on VMS systems anyway,
you cannot specify version numbers on filenames. The filename string