forked from PDP-10/its
-
Notifications
You must be signed in to change notification settings - Fork 0
/
midas.26
executable file
·4485 lines (3763 loc) · 176 KB
/
midas.26
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
-*-Text-*-
MIDAS Node: Top, Up: (DIR), Next: Invoke
Overview of MIDAS
MIDAS is a PDP-10 assembler. It takes as its input an ASCII file,
and produces a binary file in any of several formats (*Note Out: Output.)
NOTE: Numbers used in this document are assumed to be octal, unless
followed by a "." in which case they are decimal. E.G. 12 = 10. = ten.
* Menu:
* Invoke:: How to invoke MIDAS. Commands strings.
* Switches:: MIDAS command string switches.
* INTerrupts:: Terminal Interrupt Characters.
* Basic:: Introduction to MIDAS input syntax.
* Example:: Simple example of MIDAS code.
* Frame:: The beginning and end of a MIDAS program.
* Words:: Syntax of the "Word" -- the fundamental MIDAS construct.
* FIelds:: Words are made up of fields, which are made of syllables.
* SYllables:: A syllable is a number, symbol, etc.
* LocnCtr:: The "location counter" is used to assign storage locations
to the words which MIDAS assembled.
* Output:: Output formats.
* Relocation:: Relocatable assemblies.
* SYMbols:: Defining symbols.
* DDT:: Communicating to DDT.
* Numbers:: Hairy ways of writing numbers.
* LIterals:: Generating constants in memory where you want to use them.
* BYtes:: Pseudos for working with bytes and byte pointers.
* FILeinfo:: How filenames can be accessed at assembly time.
* Terminal:: Typing on the terminal. Reading from the terminal.
* Macros:: MIDAS macros: definition and use.
* LOOps:: Assembly-time iterations for use with macros.
* Cond:: Assembly conditionals.
* Arithmetic:: .I and .F: the "arithmetic assignment" statements.
* FASL:: Assembling code to be loaded by MacLisp.
* BLocks:: Symbol table block structure.
* CONStructs:: Alphabetical index of constructs (special characters).
* Pseudos:: Alphabetical index of pseudo-ops.
* LIB: (LIB) The subroutine libraries for MIDAS programs.
* OUTFormats:: More obscure details about output formats (RIM, etc)
* Changes: (MIDAS ARCHIV)* MIDAS changes in chronological order.
MIDAS Node: Invoke, Up: Top, Previous: Top, Next: Switches
MIDAS Command Strings
Once you have run the program MIDAS, it will ask for a command line
on which you must specify the names of the input and output files. In
addition to the filenames, the command line usually contains switches.
*Note Switches: Switches.
MIDAS can write four output files for each assembly: a binary
output file, an error file containing whatever would normally appear on the
terminal, a listing file, and a cross-reference table file. The
cross-reference table file (a compact binary file, not a DEC cref listing)
is not really useful now that the @ program exists (*Note @: (@)Top.).
The listing output file is also inferior to an @ listing, but it is
sometimes useful for debugging hairy macros. To facilitate this use, it is
possible to ask for a listing of both passes (some macros cause fatal
errors on the first pass). The binary output file is essential; an error
output file is also very useful as a permanent record of the assembly
errors.
Normally, one specifies either just the input file or the input
file and the binary output file. The error output file name is allowed to
default from them. MIDAS tries hard to default all filename components so
as to minimize your type-in. Not specifying the binary file name is
equivalent to letting each component of the name default based on the input
file name.
Defaulting in MIDAS works bidirectionally; the input file name can
default from the binary file name, and the binary file name can default
from the input file name. This is actually useful. Note how the Twenex
GTJFN-from-the-terminal scheme of things cannot provide this!
The binary file's device defaults to DSK. The directory defaults
to your working directory. The second filename defaults based on the type
of output format used: BIN for SBLK files, FASL for FASL output files, or
REL for relocatable output files. The first filename defaults to the input
files's first filename. One exception: if TTY: is specified as the input
file, and the binary file name is not specified, no binary file is made.
The input file's device and directory default to those of the
binary file. The second filename defaults to ">" for ITS and "MID" on DEC
systems. The first filename defaults to that of the binary file. If
no first filename is specified for either file, the default is "PROG".
This becomes relevant sometimes when TTY: is specified as the input device.
Exception: if the binary file was on device PTP or NUL, the default is DSK.
These defaulting rules make common things very convenient.
To assemble a file FOO;BAR > onto the same directory, you can use
FOO;BAR_
letting the input file names default. To assemble it onto your directory,
just say
FOO;BAR
letting the binary file names default.
* Menu:
* Switches:: Command line switches.
* Interrupts:: Terminal interrupt characters.
MIDAS Node: Switches, Previous: Invoke, Up: Top, Next: Interrupts
Switches:
Switches should be enclosed in parentheses or preceded by slashes,
and may go anywhere in the command string. The effects of a switch in no
way depend on where it appears, although it should not appear in the middle
of a file name as that may confuse the filename parser. Any number of
switches may be enclosed by one pair of parentheses, as in (ET) which is
equivalent to (E)(T) or /E/T. Each slash is good for just one switch.
It is sometimes significant whether a switch occurs once or twice: (TT) is
not the same as (T).
/C Produce a CREF file.
/E Produce an error output file.
/L Produce a listing.
(LL) List on 1st pass as well as 2nd.
/T Read assembly input from the terminal after the TITLE
statement, on pass 1. You can type in parameter assignments
to control conditional assembly.
(TT) Read from the terminal on both passes.
/W Do not print on the terminal.
This implies the (E) switch, so your errors are not lost.
/W works by setting the .TTYFLG variable initially to 1.
MIDAS Node: Interrupts, Previous: Switches, Up: Top, Next: Basic
Terminal Interrupt Characters.
In the ITS and Twenex (I believe) versions, the characters ^H, ^V and ^W
have an instantaneous effect if typed on the terminal while MIDAS is
running.
^H Causes an error message "^H-BREAK"
(which says where the assembly has reached)
followed by the .INSRTion of TTY:.
Thus, this is a sort of "break-loop" you can use
to debug runaway macros. To exit, cause an end-of-file
on the terminal input.
^V Decrements .TTYFLG.
Since type-out on the terminal happens only when .TTYFLG is
negative or zero, this undoes the effect of one ^W.
(some very bad errors that .INSRT TTY:
also zero .TTYFLG before typing an error message.)
^W Increments .TTYFLG, suppressing terminal type-out.
It is not wise to do this if you don't have an error
output file (since after the assembly has been started
it is too late to start writing one).
In the Bottoms-10 version, you can get a ^H-break by typing
^C and then Reenter.
MIDAS Node: Basic, Previous: Interrupts, Up: Top, Next: Example
Machine Instructions in MIDAS
The main body of a MIDAS program is composed primarily of machine
instructions -- just as you would expect.
The PDP-10 machine language instruction breaks down into five
fields of bits: a nine bit opcode field, a four bit accumulator (AC) field,
a one bit indirect field, a four bit index register field, and an 18 bit
memory address field. The instruction set is documented very clearly in
the "DecSystem-10 System Reference Manual" (DEC-10-HGAC-D, and the later
versions), which is published by the manufacturer, Digital Equiptment Corp.
("DecSystem-10" is a pretentious salesman's name for the PDP-10).
In MIDAS, the fundamental syntactic construct is the word. Its
components parallel the fields of a machine instruction, but it is flexible
enough to be used for all other purposes as well. This is because the
subunits or "fields" which compose a word are simply added together, into
parts of the 36-bit word determined by the pattern of spaces and commas
that separate them. Every word of data assembled into the binary program
is written in MIDAS as a syntactical word of some sort or other, with the
sole exception of multi-word text strings. *Note Words: Words, for full
details.
Words are terminated and separated by the "line terminators", which
are Return, Linefeed, and "?". Return and Linefeed should always be used
together, to prevent confusion when editing the program. Strictly
speaking, Return Linefeed contains a blank line, but blank lines are
ignored anyway.
The value of the words that appear in a MIDAS program become the
words of the binary program output. Each word is assembled at the
address specified by the MIDAS "location counter", which increments by one
after each word to put consecutive words in consecutive locations. This is
called "assembling a storage word". The ultimate goal of assembling a
program is to assemble storage words, but word quantities can appear in
other contexts such as to be passed as arguments to functions. Before
each word in the MIDAS input, at the beginning of the line, there may be
one or more "labels", which are symbols which are defined to equal the
current value of the location counter. Thus, a label preceding a word is
defined to be the address of that word. *Note LocnCtr: LocnCtr.
The other most important constituent of a MIDAS program is the
comment. A comment starts with a semicolon ";" and ends with the following
Return. The whole thing is equivalent to a single Return. Another way to
think of it is that you can put a comment at the end of any line in the
file; but "lines" terminated by the "?" character do not count.
A few other MIDAS constructs may appear in place of a word. One is
the parameter assignment, which defines a symbol with an explicitly
specified value at assembly time. *Note Assign: Symbols. Another is the
"Statement". Everything that must be specified in a MIDAS program aside
from the contents of words to be loaded and the values of symbols is
specified by means of statements. A statement begins with a symbol which
is the name of a "pseudo-op"; it is a sort of escape which directs MIDAS
to perform some special function. Some pseudo-ops read arguments. The
syntax of the arguments depends on which pseudo-op it is. An example of a
statement is the END statement, which must appear at the end of every
program. It starts with the symbol END. After that comes the program's
starting address, which is syntactically a word (and thus, terminated by a
"?" or Return or Linefeed). If a Return immediately follows the symbol
END, then there is no argument (and no starting address).
The separation into lines should not be thought of as a
hard-and-fast rule. The "line-separating" characters USUALLY have that
effect, but in some contexts (such as text-string constants) they may have
NO special effect. <cr> and "?" are both "line-separators", but in a
semicolon-comment they do not act the same: a <cr> ends the comment, but a
"?" is ignored as "part" of the comment. Semicolon usually starts a
comment, but not inside a text string. Thus,
MOVE A,B ;COMMENT ? MOVE C,D
assembles only a single instruction. The moral is that the meaning of a
character depends on its context, which depends on the characters IN FRONT
of it. MIDAS does not work by BNF-like grammatical rules ("a MUMBLE can be
either a FOO or three BARs in a row") although a few constructs can be
approximated by them. It works like a finite-state machine: "In the normal
input-reading state, if a <cr> is read, terminate the line and process it;
if a question-mark is read, terminate the line and process it; if a
semicolon is read, enter the comment-reading state. In the comment-reading
state, if anything but a <cr> is read, ignore it; if a <cr> is read, return
to the normal input-reading state and terminate the line and process it."
MIDAS Node: Example, Previous: Basic, Up: Top, Next: Frame
Simple examples of MIDAS code
MOVE C,COUNTA
TLNE B,100
SETZ C,
JUMPGE A,@DISTAB(B)
JRST LABEL1
Each of these lines will generate one storage word in the output.
The first line will generate a MOVE instruction that will load the
contents of memory location COUNTA into accumulator C. This is accomplished
by putting the value of the symbol C in the instruction's AC field,
and the value of the symbol COUNTA in the address field, and then adding
the value of the symbol MOVE (which supplies the appropriate value in the
op-code field). The second line is similar, except that the address field
is specified by the octal number 100 instead of a symbol. That is a
common thing to do with instructions like TLNE which use the address
as a bit-mask. The third line is a SETZ instruction. The address field
has been omitted, because the SETZ instruction ignores its address.
In fact, the address field will be assembled as zero. The SETZ has been
indented one space as a note to humans that the preceding TLNE instruction
can skip over it. The fourth line
is a JUMPGE instruction which demonstrates indexing and indirect addressing.
The "@" turns on the instruction's indirect-bit, selecting indirect
addressing. The "(B)" puts B's value in the index field. Presumably,
B is the number of an accumulator which is to be used as an index register.
The fifth line shows a JRST instruction, for which it is not necessary
to specify an accumulator. In fact, the accumulator field of the instruction
will be assembled as zero; but instructions that actually use accumulator
zero should say so explicitly.
So in the simple cases, MIDAS agrees with the format used in the
"DecSystem-10 System Reference Manual."
MIDAS Node: Frame, Previous: Example, Up: Top, Next: Words
The Framework of Every MIDAS Program
A MIDAS program consists primarily of PDP-10 instructions and
data, together with labels and comments. But other things are usually
or always needed at the beginning and end of the program.
The first thing in every MIDAS program (or every subfile of
one, for that matter) is a line containing ";-*-MIDAS-*-" to tell
EMACS how the file is to be edited.
The second thing in a MIDAS program, which is not actually
needed for small programs, is a .SYMTAB statement which says how large
a symbol table is required. The argument to .SYMTAB is the desired
number of entries in the symbol table. This must include the
predefined symbols, the user-defined symbols, and some extra to make
hashing efficient. It should also be prime. To help you set up your
.SYMTAB, MIDAS prints the symbol table size and the number of entries
used at the end of the assembly.
Next, in every MIDAS program, should come the TITLE statement,
which consists of TITLE followed by a line of text, and performs these
functions:
1) for relocatable assemblies, the first symbol following TITLE
becomes the name of the relocatable program being assembled;
2) the text following TITLE is printed on the terminal on each pass.
3) when the /T switch is used to request input from the terminal,
this input is read when the TITLE statement is reached.
Because of 3), it is sometimes useful to define a few symbols before
the TITLE statement so that they can be used when giving input on the
terminal. If there is no TITLE statement, /T won't do anything!
After the TITLE statement, you should define names for the
accumulators. Single letters starting with A=1 are best. Accumulator
0 should also have a name, but not in sequence with 1, since 0 can
only be used for special purposes. But don't ever write an
instruction which actually USES accumulator 0 without putting in the
name of that accumulator. The stack pointer should be in accumulator
17, which should be named P. Putting the accumulator definitions on
page 1 will produce the best results in @ listings.
After this point, you are on your own. But at the end of the
program, you need an END statement. The END statement consists of END
followed by the starting address of the program (this is an old assembler
tradition). You can omit the starting address if you don't want your
program to have one (in a relocatable program, this is often the case). If
you don't have an END statement, you get an error. This catches many
errors in assembly conditionals and macro definitions which cause the
END statement not to be recognized as such. Any text which follows the END
statement will be ignored completely by MIDAS.
MIDAS Node: Words, Previous: Frame, Up: Top, Next: Fields
Words, and Their Syntax
The "word" is the most commonly used MIDAS construct, as a storage
word to be assembled must be, syntactically, a word, and an ordinary PDP-10
instruction is an example of a word. However, the word construct includes
other things than instructions, and is used in other contexts besides that
of storage words. This section of the manual describes how to put a WORD
together. The concept of a WORD is tied closely to those of SYLLABLES and
FIELDS, out of which WORDS are made. Loosely, a syllable is a number or
symbol, and a field is an arithmetic expression. Words are made up of
fields, and fields are made up of syllables. Do not confuse a MIDAS field
with a "field" of bits in a PDP-10 machine language word.
A word is one or more fields connected by field separators, with
optionally an indirect bit or index field anywhere among them. There
are two field separators, space (or horizontal tab) and comma. (Space and
horizontal tab are identical and will both be referred to as space.) To
improve readability, spaces before and after a word and spaces adjacent to
a comma are ignored, and more than one space in a row are treated as one.
The values of the fields are combined to form the values of the
word according to the number of fields and the pattern of separators. These
formats are described in the following table, in which A, B, and C are
fields. "TR(x)" is used to represent the result of truncating x to 18. bits.
pattern format # value
in octal
====== ======= =====
,,C 13 TR(C)
,B 14 TR(B)
,B C 15 unassigned
,B, 16 unassigned
,B,C 17 unassigned
A 20 A
21,22,23 not possible
A B 24 A++TR(B)
A B C 25 A++TR(B)++TR(C)
A B, 26 A+<<B&17>_23.>
A B,C 27 A+<<B&17>_23.>++TR(C)
A, 30 A
31 not possible
A,, 32 <TR(A)>_18.
A,,C 33 <TR(A)>_18.+TR(C)
A,B 34 A++TR(B)
A,B C 35 unassigned
A,B, 36 unassigned
A,B,C 37 unassigned
Here are some examples of what these formats are most useful for:
A B,C This is the normal instruction format, e.g., CAMN A,FOO
A B This is good for instructions with no accumulator field,
e.g., JRST BAR
A B, and this is for instructions with no address field, e.g.,
SETZ D,
A,,C This is the standard way to specify the contents of a
storage word by half-words, e.g.,
BLETCH: -PDL,,PDB
NOTES:
1) "+" means normal 36-bit addition, but "++" addition is special in
that carry from bit 18 to bit 17 is suppressed. In other words, when the
user specifies a field which is supposed to be a right half-word field, he
can normally rest assured that his quantity didn't carry over into the left
half.
2) A word may have more than three fields. In that case, the
fourth and following fields are added in with the third field. Thus,
if the third field is truncated to 18. bits and added in, so are the
following fields. Only spaces may be used for separating fields after
the third field; a comma after the third field is an error, but will
be treated as a space. Commas are flagged so as to catch places where
the accidental omission of a <cr> has run two lines together.
4) The user can redefine these formats by using the .FORMAT pseudo-op.
That is what the "Format number" of a format is used for, and the pseudo
is documented here:
.FORMA fno,fval
Inserts an entry in the format table (ie replaces old entry) for
format number "fno". The numeric value of field fval is taken as three
12-bit bytes referring to the (up to) three distinctly handled fields in a
word: the left 12 bits refer to the rightmost field, the middle 12 bits to
the field next to the rightmost (if any) and the right 12 bits to the field
2 from the right and any additional fields. (If there is only one field in
a given format it is the rightmost regardless of punctuation which may be
required after it.)
A 12-bit byte describing a particular field is in turn treated as
two 6-bit bytes. The right 6-bit byte specifies a mask and the left 6-bit
byte specifies a shift. The mask number (say M) directs that only the
right M bits of the field value be taken. The shift number (say S) directs
that the bits remaining after masking be shifted left S bits. The fields,
after this masking and shifting are added to give the value of the word.
(Example: the 12-bit specification 2704 describes an accumulator field:
<f&17>_23.)
There are three exceptions to the above procedure. (1) If a field
is specified as 0022 (right half, not shifted) the carry out of bit 18 is
suppressed as the field is added into the word. (2) A virtual quantity may
only occur in a field specified 0044, 0022, 2222, 0504, or 2704. (3) If as
a syllable in the leftmost field of a word appears any of the eight I/O
instructions (DATAO, DATAI, CONO, CONI, BLKO, BLKI, CONSZ, CONSO) then any
field in that word specified 2704 is instead taken as if specified 3211
(I/O device field)
In addition to the fields and separators that make up a word, there
can be an indirect bit and an index field. These subconstructs resemble
the fields of the word in that their values are merged into the value of
the word. They differ from the fields in that they are marked out by their
own special syntax, and are interpreted in the same way no matter where in
the word they appear (unlike fields, which are all the same and are
interpreted according to their position in sequence).
a. The Indirect bit
The character @ (atsign) is a special character. It may occur
anywhere inside a word. Whenever MIDAS encounters an @ inside a word, a 1
is ORed into bit 22. of the word, i.e., the indirect bit. The @ does not
terminate syllables or fields, nor is it taken as part of a syllable or
field.
Its position in the word is totally irrelevant. However, the
normal convention is to put it in front of the field specifying the right
half of the word (the address) if there is one; if not, put the @ where the
address would go.
b. The Index field
To get a certain quantity into the index field, the easy, convntional
way is to use a bracketed word of the parentheses type. For example,
MOVE A,FOO(D)
will put the value of D into the storage word's index field. As explained
in section C.2.d, the parenthesis bracketed word works in its strange way
because the index field of the machine word is the lowest four bits in the
left halfword.
The index field, used this way, may appear anywhere in the word
except in the middle of a syllable or following an arithmetic operator, but
the normal convention is to put it at the end of the field specifying the
right half of the word (the address) if there is one. When "(" appears
following an arithmetic operator, it signifies a type of bracketed word,
rather than an index field.
MIDAS Node: Fields, Previous: Words, Up: Top, Next: Syllables
Fields
A "field" in MIDAS is essentially an arithmetic expression. A
field may be either a single syllable, or two or more syllables combined
arithmetic operators. Many MIDAS pseudo-ops take arguments that are
syntactically fields. These are the arithmetic operators, in their order
by priority:
char. operator
===== ========
highest _ left shift 1st operand by # of bits specified by 2nd
operand. (Negative 2nd operand shifts right)
& bitwise AND
# bitwise XOR
\ bitwise OR
* and / 36. bit integer multiplication and division
lowest + and - 36. bit integer addition and subtraction
Thus all _'s are done first, then &'s, then #'s, then \'s, then *'s
and /'s, and finally +'s and -'s. Operators of the same priority will be
performed in left-to-right order. Examples: (assuming that A, B and FOO
are numerically defined symbols with the values 1, 2, and 53 respectively.)
Field Value
===== =====
3+4 7
1+4&FOO+1 2
1+4&<FOO+1> 5
The first example is rather trivial. The second and third
demonstrate the use of angle brackets as algebraic parentheses (actually,
part of the syntax of syllables). In the second, 4 is anded with FOO,
giving zero, then 1+0+1 equals 2. In the third example, first FOO is added
to 1, giving 54. Then 54&4 gives 4, and then the 4 is added to the 1,
giving 5.
Note that there may NOT be spaces within a field; so "4 * 5" is
not the same as "4*5".
MIDAS Node: Syllables, Previous: Fields, Up: Top, Next: LocnCtr
Syllables
There are several types of MIDAS syllables. A symbol may be a
NUMBER, a NUMERICALLY DEFINED SYMBOL, a QUOTED CHARACTER, a BRACKETED WORD,
or a call to a PSEUDO-OP (but see *Note MACROS:macros.).
(Note: only "value-returning" pseudo-ops can be used to make syllables.
Other pseudo-ops will either be ignored by the process of building words
and fields out of syllables (except for their side effects), or illegal to
be used except alone on a line).
Each syllable has a value, which is a 36.-bit quantity.
a. NUMBERS
The simplest form of number is an octal integer, which is just a
string of digits. Following them with a "." makes it a decimal integer
instead.
*Note Numbers: Numbers, for other sorts of numbers, which you won't
need very often.
b. SYMBOLS
A symbol is a string of SQUOZE characters which is not a
number. More precisely, it is a string of characters from the
SQUOZE character set of length 1 or greater which contains at
least one letter, or at least one % (percent) or $ (dollarsign),
or at least two .'s (periods). The SQUOZE set includes all 26.
letters, all 10. digits, and the characters $ (dollar sign), %
(percent sign), and "." (period). (Note that the symbol "." (a
single period) is special; *Note LocnCtr: LocnCtr.).
Here are some examples of symbols:
LOC3
GOHERE
$END
A%LOCATION
35X
1.2.3
.$Z%.G
(The last example is NOT considered an example of good programming style.)
A symbol has no length restriction, but MIDAS only looks at the first six
characters, so the symbols THISLOCN and THISLO, for example, are
effectively identical.
MIDAS symbols can have several sorts of definitions. The symbols
that can appear as syllables are those with numeric definitions (other
sorts of symbols might appear at the same places, but they would be
interpreted differently and would constitute different constructs). MIDAS
provides many predefined numeric symbols (including all the PDP-10
instructions, and others specific to the operating system), and programmer
can define others (*Note Define: Symbols.).
An example of numerically defined symbols:
In the word MOVE B,FOO , there are three symbols: MOVE, B, and FOO.
The symbol MOVE is predefined; the other two must be defined by the
programmer.
c. Quoted Characters:
A quoted character starts with any one of the characters ' (single
quote), " (double quote), or ^ (uparrow) followed by a character. The
quote or uparrow and the character following are taken as a syllable. A '
followed by a character has the value of the SIXBIT representation of the
character. A " followed by a character has as its value the ASCII
representation of the character. ^ works the same way as " except that the
ASCII value is ANDed with 77 octal; that is, only the low six bits are
kept. ^ is used for generating the ASCII code for "control" characters.
Examples of quoted characters:
Syllable Value
======== =====
'A 41 octal
"+ 53 octal
^C 3 octal
d. Bracketed words:
A word surrounded by ( ) (parentheses), < > (angle brackets), or [
] (square brackets) is a syllable called a BRACKETED WORD. Each works in
its own way:
<word> is simply a syllable whose value is that of the word between the
brackets. Angle brackets act much like algebra's parentheses,
and are usually used that way.
(word) works two different ways. If the preceeding character is an
arithmetic operator, the value of the word has its halves swapped,
and this becomes the value of the syllable, on which the arithmetic
operator acts. If the preceeding character is not an arithmetic
operation, the value of the word is swapped and saved, and at the
end of the outer word, it is added into the word being formed.
This quirk is so that (5) stuck at most places in a word will put 5
in the index field.
[word] is a LITERAL, or CONSTANT. *Note Literals: Literals. The value of
the syllable is the location where MIDAS put the literal.
It is hard to give examples of ( ) and < > until some further
concepts have been introduced, so these have been delayed.
e. Pseudo-ops which return a value:
Pseudo-ops are instruction given by the programmer to MIDAS in the
input ASCII file about how to assemble various things. They are described
in section E, "Pseudo-ops that every programmer needs," and in the section
on pseudo-ops.
They are the "built-in functions" of the MIDAS assembly-time
programming language. Some pseudo-ops are used for their side-effects;
some, to compute values. Calls to value-returning pseudo-ops constitute
syllables, whose value, of course, is the value returned by the pseudo-op.
MIDAS Node: LocnCtr, Previous: Syllables, Up: Top, Next: Output
The Location Counter
Normally, when MIDAS finishes reading a Word at top level in the
input file, the value of that word is assembled into the binary program
output. The place where it will be loaded is specified by the location
counter, which is normally an 18.-bit number. After assembling each such
word, MIDAS increments the location counter.
The value of location counter is explicitly available as the value
of the symbol ".". It refers to the address of the current word, not the
following one. A label defines a symbol to equal the current value of ".".
The location counter can be set with a LOC statement, or by
assigning a value to the symbol "." (*Note .=: Symbols, for how to do
that). These have slightly different effects when an offset is in effect.
In a relocatable program, the location counter can be set to a relocatable
value or to an absolute value.
The usual way to leave space for non-constant data in a program is
the BLOCK statement.
BLOCK 200
leaves 200 words of space, by incrementing the location counter by 200 .
It is an error to ask for a block of negative length.
In relocatable assemblies, the location counter starts out at
relocatable zero. In absolute assemblies, it starts out at absolute 100
octal.
Sometimes it is necessary to assemble code at one location and copy
it to another before using it. When that is done, all references to labels
in the code (whether from within it or outside it) should be arranged so as
to be correct when the code has been moved to its ultimate position. This
can be done by defining an offset. The statement
OFFSET 200
causes all references to the location counter -- the symbol ".", labels,
etc. -- to add 200 to the real value of the location counter. If the code
being assembled is moved 200 words upward, it will be at the addresses at
which the program will refer to it.
Offsets do not affect the actual location counter, which is the
place at which code will actually be loaded. They affect the value of the
location counter as seen by references to it from within the program.
The difference between LOC and assigning a value to "." is that LOC sets
the real location counter, whereas assigning "." sets the value of ".":
that is, it subtracts the offset and then sets the real location counter,
so that when the offset is added in again to get the value of "." it will
equal the value assigned.
An offset can be cancelled by setting the offset to zero.
A frequent use of the offset is for error checking. If there are a
series of symbols FOO, BAR, QUUX ... with values 0, 1, 2 ... intended to be
the values of a particular table index, with MAX being 1 larger than the
largest legal index, the table can be defined with
TABLE: OFFSET -.
FOO:: <table entry for FOO>
BAR:: <table entry for BAR>
QUUX:: <table entry for QUUX
...
MAX:: OFFSET 0
Then, if any entries are missing from the table or in the wrong order, one
of the labels will report a multiply-defined symbol error. The double
colons are for half-killing; *Note Labels: Symbols.
MIDAS Node: Output, Up: Top, Previous: LocnCtr, Next: Relocation
Output formats
MIDAS can produce its binary output in any of several different
formats. The format used is specified by the user with pseudo-ops
(see *Note Pseudo-ops:Pseudos.). The currently available formats are:
SBLK the usual format in ITS.
FASL used for programs which are meant to be loaded by LISP.
.DECREL compatible with the D.E.C. operating system.
.DECSAV SAV files produced directly, without taking time to link.
RELOCATABLE relocatable binary to be loaded by STINK.
Any MIDAS output format consists primarily of 36-bit storage words,
which are intended for loading into memory locations of a job. The output
also includes a symbol table (a list of the names and values of all the
symbols defined by the programmer), and some information on how to load the
file into core memory.
SBLK format is documented in *Note BINFMT:(ITSDOC;BINFMT)*,
and the format of the SBLK file symbol table in *Note DDTORD:(.INFO.;DDTORD)*.
If you visit these non-infoized files as footnotes, do "L" to get back here.
For RIM, SBLK, DECSAV, DECREL, STINK see *Note OUTFORMATS:outformats.
MIDAS Node: Relocation, Previous: Output, Up: Top, Next: Symbols
Relocatable Assemblies. Specifying the Type of Output.
Like MACRO-10, MIDAS is capable of making both relocatable and
absolute assemblies. The type of assembly is controlled by pseudos
appearing in the program, with a default which varies with the operating
system. In an absolute assembly, all location counter values (and all
expression values, in fact) are completely known at assembly time, or else
are undefined. In a relocatable assembly, while some location counter
values and expression values may be known at assembly time, most depend on
an unknown relocation which will be determined only by the linking loader.
The location counter value is likely to be a known quantity plus the
unknown relocation. Symbol values can also have that form (and will, when
the symbol is defined as a label when the location counter has that form).
Expression values can take the form of a known quantity plus any number
times the relocation that number being the "relocation factor". Values
completely known at assembly time are called "absolute", and have a
relocation factor of 0. Simply relocatable quantities, such as typical
location counter values, have relocation factors of 1. MIDAS can handle
higher or negative relocation factors internally but cannot write them into
the output file except in STINK format output.
Whether an assembly is absolute or relocatable is tied closely to
what output format is used. The formats that exist are
SBLK Standard ITS absolute format.
This is the default on ITS.
RELOCATABLE STINK format (relocatable).
Used only on ITS, and not much.
.DECREL Standard DEC relocatable, for LINK10.
This is the default on non-ITS systems.
.DECTWO <n> Standard DEC two-segment relocatable.
<n> is the segment boundary, usually 400000 .
.DECSAV Standard DEC SAV file format. Absolute.
.FASL MACLISP FASL file format. Relocatable.
RIM Read-In Mode format for PDP-6. Absolute.
RIM10 Read-In Mode format for PDP-10. Absolute.
The names of the formats are all pseudo-ops which you can put in
the program to specify those formats. If the format you want is the
default for your particular system, you don't need to specify it, but if
you can anticipate that your program will be assembled on other systems it
might be wise to do so anyway.
A few functions are available for manipulation of relocatable
quantities. These include .ABSP, .RELP, and .RL1. .ABSP and .RELP return
the absolute and relocatable parts of a quantity (the relocatable part is
the relocation factor. .RL1 is a symbol whose value is a pure
relocatability of 1; that is, a relocatable zero. You can think of these
as analogous to the the complex number functions Re, Im and the constant i.
.RELP .RL1 is nonzero if the asembly is relocatable.
MIDAS Node: Symbols, Previous: Relocation, Up: Top, Next: DDT
Defining Symbols
You have already been told how to use symbols and what names they
are allowed to have. Here is how to define them.
A symbol can have these types of definition (or none at all):
numerically defined symbols, pseudo-op names *Note PSEUDOS:pseudos.), and
macroinstruction names (*Note MACROS:macros.). Here we are concerned only
with numerically defined symbols. New pseudo-ops cannot be defined by the
user, so the initial supply is all you get, but pseudo-op definitions can
be copied from one symbol to another using EQUALS.
There are basically two ways to define a symbol numerically: as a
LABEL, and as a PARAMETER.
1. Labels.
The primary use of symbols is to hold the address of an instruction
or variable in the program. MIDAS has a special construct, the LABEL, for
defining such symbols. A label is simply a symbol followed by a colon, and it
can appear at the beginning of any line. Its effect is to give the
symbol a value equal to the address where the next storage word will go.
A line can have several labels in it, but a label may not appear after
any other construct has begun. A label may be followed by anything at all,
or it may be the only thing on its line. An example is:
FOO: MOVE A,TABLE(C)
which assembles a storage word containing a MOVE instruction, and
also defines FOO as the address of that instruction.
If a symbol is defined as a label, it can have only one value.
If anything in the program tries to define the symbol with a different
value, either before or after the symbol's appearance as a label, an
error message will be typed. It is legal to define the symbol again
with the SAME value. In fact, that happens to every label, since it
is seen on both passes of the assembly.
The parameter assignment "<symbol>=:." has the exact same
effect as the label "<symbol>:", which is allowed for convenience's sake.
2. Parameters.
There are other uses of numerically defined symbols besides
their use as labels. MIDAS also allows definition of symbols by
PARAMETER ASSIGNMENT. A parameter assignment is a line of the form
<symbol>=<word> or <symbol>==<word>
which tells MIDAS to compute the value of <word> and make that the value
of <symbol>. This is similar to the "assignment" statement of most
mathematical languages, such as FORTRAN. Using the == construction
makes the symbol half-killed in DDT (this is explained in the section
on OUTPUT; for now, suffice to say that the == form is the one you
probably want to use.) Here is one of the ways to use this feature:
Say a programmer is writing a program which knows how to handle
four FOOBAR's. If in the future he should want to modify the program
to handle five or six FOOBAR's, there might be many places where the
program would have to be changed. Now if he had made the number of
FOOBAR's an assembly parameter, by defining a symbol as in:
NFOOBR==4
and writing all of the program to work for NFOOBR FOOBAR's
Whenever there is a table or block of data whose length must
be referred to by the program, that length should be expressed
by a numeric symbol.
Symbol definitions actually have a static scoping or block
structure as in Algol or PL/I. *Note Blocks: Blocks.
MIDAS Node: DDT, Previous: Symbols, Up: Top, Next: Numbers
Communicating Information about Symbols to DDT
One of the most important things about symbols in assembler
programs is that they are passed to DDT. MIDAS has several features
designed specifically for communicating with DDT.
If DDT, needing to print the value 205, chose at random a symbol
whose value was close to 205, it would be likely to find several names for
bits in various registers. It is essential to have a way to tell DDT which
symbols ought to be used for such type-out. This is done by "half-killing"
the symbols which ought not to be used.
The most common way to half-kill a symbol is to duplicate the colon
or equal sign used to define it. Thus, FOO==200 says that FOO is to be
half-killed and should never be printed out, while FOO=200 allows FOO to be
printed out. FOO:: defines FOO as a half-killed label.
If those methods of half-killing are not convenient, the .HKILL
statement is available. .HKILL followed by a list of symbols half-kills
those symbols. If the symbol .HKALL is nonzero, then all labels defined
are half-killed.
.KILL can be used to avoid sending a symbol to DDT at all. It is
followed by a list of symbols to kill. MIDAS does not forget the value of
a symbol when you .KILL it, so .KILL is not the same as EXPUNGE. .KILL
causes the symbol to be forgotten only when the symbol table is written
into the output file.
The NOSYMS statement can be used to avoid outputting any symbol
table at all.
MIDAS Node: Numbers, Previous: DDT, Up: Top, Next: Literals
Details of the Syntax of Numbers
A string of digits in which no digit is preceeded by a period
forms an INTEGER, a type of syllable whose value is the value of the
number interpreted in the CURRENT RADIX (octal by default, but see
*Note PSEUDO-OPS:pseudos.).
However, an integer followed by ' (single quote) is interpreted as octal,
and one followed by . (period) is interpreted as decimal, regardless of
the current radix. A string of digits with a . (period) to the left of
some digit forms a FLOATING-POINT NUMBER, interpreted in decimal.
Either of these may be followed by a ^ (uparrow) which works
something like scientific notation. An integer may be followed by an
integer as
A^B
which would have the value of
B
A*R
where R is the radix in which A is expressed. The result is fixed-point.
A floating point number may also be followed by a ^ and an integer, as in
X.Y^A
which is interpreted as
A
X.Y*10.
that is, as scientific notation. The result is still floating-point.
Also, any of the preceeding numeric formats may be followed by a _
(backarrow, or underscore) and an integer, which multiplies the value by
integer
2
The integer is interpreted in the current radix, but may
be forced to decimal or octal by terminating it with . or ' as explained
above. The result is always a fixed-point number, even if the first number
was floating-point!
Examples of NUMBERS:
(the current radix is taken to be octal)
Syllable Value
======== =====
23 23 octal
23. 27 octal
3^3 3000 octal
3.^3 5760 octal (3000. decimal)
1_3 10 octal
23_10. 46000 octal
3.5 3.5 floating-point
3.5^4 35000.0 floating-point
3^3_4 60000 octal
1.5_3 14 octal (Note: NOT floating point!)
MIDAS Node: Literals, Previous: Numbers, Up: Top, Next: Bytes
Literals
Normally, when you write a machine instruction in an assembler, you
specify the memory operand by its address. Sometimes, it is desirable to
refer to "a word containing X" without worrying about where that word is
going to be stored. The LITERAL is a construct that permits just this.
A literal consists of any number of lines enclosed in square
brackets ("[" and "]"). MIDAS assembles the lines enclosed into locations
of its own choosing. The value of the literal, where it appears, is the
address of the location chosen by MIDAS to hold the first word of the
literal. For example,
MOVEI A,[1 ? 2 ? 3]
would load accumulator A with the address of a three-word table whose
contents are 1, 2 and 3 in successive words. It is equivalent to
MOVEI A,FOO1
....
FOO1: 1 ? 2 ? 3
where FOO1 is a non-existent label by which you can imagine that MIDAS
connects the usage of the literal with the location of its contents.
Unless you request otherwise, all literals will actually appear at
the end of your program (that is, at wherever the location counter was set
when the END statement was encountered). However, you can alter this with
the pseudo-op CONSTANTS. Whenever CONSTANTS appears, all saved-up literals
will be "dumped out" or assigned locations starting at the current location
counter. CONSTANTS may appear any number of times (up to 75 or so), but
must appear the same number of times and at the same locations on both
passes.
On pass 1, MIDAS doesn't know where a literal is going to be
located until the CONSTANTS statement is seen. On pass 2, the location of
the CONSTANTS statement is known in advance (remember, it must be the same
as on pass 1), but the location of the literal is still not known until the
end of the literal (so that recursive literals can work). For these