Commit | Line | Data |
---|---|---|
038c5eb8 PH |
1 | |
2 | ||
3 | ||
4 | ||
5 | ||
6 | ||
7 | ||
8 | ||
9 | ||
10 | ||
11 | ||
12 | ||
13 | ||
14 | ||
15 | ||
16 | OS/8 FORTRAN IV | |
17 | ||
18 | SOFTWARE SUPPORT MANUAL | |
19 | ||
20 | ||
21 | ||
22 | ||
23 | ||
24 | ||
25 | ||
26 | ||
27 | ||
28 | ||
29 | ||
30 | ||
31 | ||
32 | ||
33 | ||
34 | ||
35 | ||
36 | ||
37 | ||
38 | DISCLAIMER | |
39 | ||
40 | This document file was created by scanning the | |
41 | original document and then editing the scanned | |
42 | text. As much as possible, the original text | |
43 | format was restored. Some format changes were | |
44 | made to insure this document would print on | |
45 | current laser printers using 60 lines per page, | |
46 | which changed the page numbering. The original | |
47 | spelling and grammar have been preserved. | |
48 | ||
49 | ||
50 | 1-NOV-1997 | |
51 | \f | |
52 | ||
53 | DEC-S8-LFSSA-A-D | |
54 | ||
55 | AA-4532A-TA 056573 | |
56 | ||
57 | ||
58 | ||
59 | ||
60 | ||
61 | ||
62 | ||
63 | ||
64 | ||
65 | ||
66 | ||
67 | ||
68 | ||
69 | ||
70 | ||
71 | ||
72 | ||
73 | OS/8 FORTRAN IV | |
74 | ||
75 | SOFTWARE SUPPORT MANUAL | |
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 | | For additional copies, order No. DEC-S8-LFSSA-A-D | | |
104 | | from Software Distribution Center, Digital Equipment | | |
105 | | Corporation, Maynard, Mass. | | |
106 | ---------------------------------------------------------- | |
107 | ||
108 | ||
109 | digital equipment corporation - maynard, massachusetts | |
110 | \f | |
111 | ||
112 | ||
113 | First Printing | |
114 | June, 1973 | |
115 | ||
116 | ||
117 | ||
118 | ||
119 | ||
120 | ||
121 | ||
122 | ||
123 | ||
124 | ||
125 | ||
126 | ||
127 | ||
128 | ||
129 | ||
130 | Copyright (c) 1973 by Digital Equipment Corporation | |
131 | ||
132 | ||
133 | ||
134 | ||
135 | ||
136 | ||
137 | ||
138 | ||
139 | ||
140 | ||
141 | ||
142 | ||
143 | ||
144 | ||
145 | ||
146 | The following are trademarks of Digital Equipment Corporation, | |
147 | Maynard, Massachusetts: | |
148 | ||
149 | CDP DIGITAL KA10 PS/8 | |
150 | COMPUTER LAB DNC LAB-8 QUICKPOINT | |
151 | COMTEX EDGRIN LAB-8/e RAD-8 | |
152 | COMSYST EDUSYSTEM LAB-K RSTS | |
153 | DDT FLIP CHIP OMNIBUS RSX | |
154 | DEC FOCAL OS/8 RTM | |
155 | DECCOMM GLC-8 PDP SABR | |
156 | DECTAPE IDAC PHA TYPESET 8 | |
157 | DIBOL IDACS UNIBUS | |
158 | INDAC | |
159 | ||
160 | ||
161 | ||
162 | ||
163 | ||
164 | ||
165 | ||
166 | ||
167 | ||
168 | ii | |
169 | \f | |
170 | ||
171 | ||
172 | CONTENTS | |
173 | ||
174 | ||
175 | ||
176 | ||
177 | CHAPTER 1 THE F4 COMPILER 1-1 | |
178 | ||
179 | CHAPTER 2 THE RALF ASSEMBLER 2-1 | |
180 | ||
181 | CHAPTER 3 THE FORTRAN IV LOADER 3-1 | |
182 | ||
183 | CHAPTER 4 THE FORTRAN IV RUN-TIME SYSTEM 4-1 | |
184 | ||
185 | CHAPTER 5 LIBRA AND FORLIB 5-1 | |
186 | ||
187 | APPENDIX A RALF Assembler Permanent Symbol Table A-1 | |
188 | ||
189 | APPENDIX B Assembly Instructions B-1 | |
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 | iii | |
228 | \f | |
229 | ||
230 | ||
231 | CHAPTER 1 | |
232 | ||
233 | THE F4 COMPILER | |
234 | ||
235 | ||
236 | The OS/8 F4 compiler runs in 8K on either a PDP-8 or a PDP-12. It | |
237 | operates in three passes to transform FORTRAN IV source programs into | |
238 | RALF assembly language. The function of each of the three passes is: | |
239 | ||
240 | 1. Analyze statements, check syntax and convert to a polish | |
241 | notation. | |
242 | ||
243 | 2. Convert output of PASS1 to RALF assembly language making | |
244 | extensive use of code skeleton tables. | |
245 | ||
246 | 3. Produce a listing of the FORTRAN source program and/or chain | |
247 | to the assembler. | |
248 | ||
249 | The following is a more complete description of each of the three | |
250 | passes. | |
251 | ||
252 | ||
253 | ||
254 | PASS1 OPERATION | |
255 | ||
256 | After opening the source language input file(s) and an intermediate | |
257 | output file, PASS1 processes statements in the following fashion: | |
258 | ||
259 | 1. Assemble a statement into the statement buffer by reading | |
260 | characters from the OS/8 input file. This section eliminates | |
261 | comments and handles continuations so that the statement | |
262 | buffer contains the entire statement as if it had been | |
263 | written on one long line. | |
264 | ||
265 | 2. The statement is first assumed to be an arithmetic assignment | |
266 | and an attempt is made to compile it as such. This is done | |
267 | with a special switch (NOCODE) set so that in the event the | |
268 | statement is not arithmetic, no erroneous output is produced. | |
269 | Thus, with this switch set, the expression analyzer | |
270 | subroutine is used merely as a syntax checker. | |
271 | ||
272 | 3. If the statement is indeed an arithmetic assignment statement | |
273 | (or arithmetic statement function) the switch is set off and | |
274 | the statement is then recompiled, this time producing output. | |
275 | ||
276 | 4. If not an arithmetic assignment, the statement might be one | |
277 | of the keyword defined statements. The compiler now checks | |
278 | the first symbol on the line to see of it is a legal keyword | |
279 | (REAL, GOTO, etc.) and jumps to the appropriate subroutine if | |
280 | so. Any statement that is not now classified is considered | |
281 | to be in error. | |
282 | ||
283 | 5. The compilation of each statement takes place. Some state- | |
284 | ments produce only symbol table entries (e.g., DIMENSION) | |
285 | ||
286 | 1-1 | |
287 | \f | |
288 | ||
289 | ||
290 | which will be processed by PASS2. Others use the arithmetic | |
291 | expression analyzer (EXPR) and also output special purpose | |
292 | operators which will tell PASS2 what to do with the value | |
293 | represented by the arithmetic expression (e.g., IF, DO). | |
294 | ||
295 | 6. After the statement has been processed, control passes to the | |
296 | end-of-statement routine which handles DO-loop terminations | |
297 | and then outputs the end-of-statement code. | |
298 | ||
299 | 7. Statements containing some kind of error cause a special | |
300 | error code to be output. | |
301 | ||
302 | 8. The entire process is now repeated for the next statement. | |
303 | ||
304 | 9. When the END statement is encountered, PASS1 chains to PASS2. | |
305 | ||
306 | ||
307 | ||
308 | PASS1 SYMBOL TABLE | |
309 | ||
310 | A significant portion of the PASS1 processing involves the production | |
311 | of symbol table entries. These entries contain all storage related | |
312 | information, i.e., variable name, type, dimensions, etc. | |
313 | ||
314 | The symbol table is organized as a set of linked lists. The first 26 | |
315 | such lists are for variables, with the first letter of the variable | |
316 | name corresponding to the ordinal number of the list. There are also | |
317 | separate lists for statement numbers and literals (integer, real, | |
318 | complex, double, and Hollerith). In addition to list elements, there | |
319 | are special entries for holding DIMENSION and EQUIVALENCE information. | |
320 | ||
321 | A detailed description of each type of entry follows. (NOTE: All | |
322 | symbol table entries are in Field 1.) | |
323 | ||
324 | 1. VARIABLE - The first word of each entry is a pointer to the | |
325 | next entry, with a zero pointer signaling end of list. The | |
326 | second word contains type information. The third word points | |
327 | to the dimension and/or equivalence information blocks. The | |
328 | next one to three words contain the remainder of the name | |
329 | (the first character is implied by which list the entry is | |
330 | in) in stripped six-bit ASCII terminated by a zero character. | |
331 | Thus, shorter variables take less symbol table space. The | |
332 | entries are (as for all lists in the symbol table) arranged | |
333 | in order of increasing magnitude, or alphabetically. | |
334 | ||
335 | ||
336 | ||
337 | ||
338 | ||
339 | ||
340 | ||
341 | ||
342 | ||
343 | ||
344 | ||
345 | 1-2 | |
346 | \f | |
347 | ||
348 | ||
349 | --------------- | |
350 | POINTER | ------> | | |
351 | |-------------| | |
352 | TYPE | | | | | | | | | |
353 | |-------------| | |
354 | DIMENSION/EQUIVALENCE | ------> | | |
355 | |-------------| | |
356 | NAME 2-3 | N | A | | |
357 | |-------------| | |
358 | NAME 4-5 | M | E | | |
359 | |-------------| | |
360 | NAME 6 | X | 0 | | |
361 | --------------- | |
362 | ||
363 | ||
364 | TYPE WORD FORMAT | |
365 | ||
366 | 0 1 2 3 4 5 6 7 8 9 10 11 | |
367 | ---------------------------------------------------------------------- | |
368 | | C | D | E | A | E | E || L | A | T || Y | P | E | | |
369 | | O | I | X | S | Q | X || I | R | || | | | | |
370 | | M | M | T | F | U | P || T | G | || | | | | |
371 | | | | | | I | L || | | || | | | | |
372 | | | | | | V | I || | | || | | | | |
373 | | | | | | | C || | | || | | | | |
374 | ---------------------------------------------------------------------- | |
375 | ||
376 | BIT | |
377 | ||
378 | 0 - Variable is in common. | |
379 | 1 - Variable is dimensioned. | |
380 | 2 - External symbol or subroutine/function name. | |
381 | 3 - Symbol is the name of an arithmetic statement function. | |
382 | 4 - Variable is an equivalence slave. | |
383 | 5 - Variable is explicitly typed. | |
384 | 6 - Entry is a literal. | |
385 | 7 - Variable is a formal parameter. | |
386 | ||
387 | - 1 integer | |
388 | | 2 real | |
389 | | 3 complex | |
390 | 8-11 < 4 double | |
391 | Type | 5 logical | |
392 | | 8 statement number | |
393 | - 9 common section name | |
394 | ||
395 | 2. STATEMENT NUMBER - The first two words are the standard | |
396 | pointer/type. The next three words are the statement number, | |
397 | with leading zeros deleted, in stripped six-bit ASCII, filled | |
398 | to the right with blanks. | |
399 | ||
400 | ||
401 | ||
402 | ||
403 | ||
404 | 1-3 | |
405 | \f | |
406 | ||
407 | --------------- | |
408 | POINTER | ------> | | |
409 | |-------------| | |
410 | TYPE | | | | | | | | | |
411 | |-------------| | |
412 | NUMBER 1-2 | N | U | | |
413 | |-------------| | |
414 | NUMBER 3-4 | M | B | | |
415 | |-------------| | |
416 | NUMBER 5 | R | | | |
417 | --------------- | |
418 | ||
419 | 3. INTEGER OR REAL LITERALS - The first two words are the | |
420 | pointer and type. The next three words are the value in | |
421 | standard floating-point format (12-bit exponent, 24-bit | |
422 | signed 2's complement mantissa). Since the type of the | |
423 | literal must be preserved, there are two lists; hence use of | |
424 | 1 and 1.0 in the same program will cause one entry in each of | |
425 | the integer and real literal lists. | |
426 | ||
427 | --------------- | |
428 | POINTER | ------> | | |
429 | |-------------| | |
430 | TYPE | | | | | | | | | |
431 | |-------------| | |
432 | EXPONENT | V | | |
433 | |----A--------| | |
434 | MANTISSA 0-11 | L | | |
435 | |--------U----| | |
436 | MANTISSA 12-23 | E | | |
437 | --------------- | |
438 | ||
439 | 4. COMPLEX LITERALS - The first two words are standard. The | |
440 | next three are the real part in standard floating-point | |
441 | format. The next three are the imaginary part. | |
442 | ||
443 | --------------- | |
444 | POINTER | ------> | | |
445 | |-------------| | |
446 | TYPE | | | | | | | | | |
447 | |-------------| | |
448 | REAL EXPONENT | R | | |
449 | |----E--------| | |
450 | REAL MANTISSA 0-11 | A | | |
451 | |------L------| | |
452 | REAL MANTISSA 12-23 | | | |
453 | |-------------| | |
454 | IMAGINARY EXPONENT | IM | | |
455 | |----A--------| | |
456 | IMAGINARY MANTISSA 0-11 | GIN | | |
457 | |--------A----| | |
458 | IMAGINARY MANTISSA 12-23 | RY | | |
459 | --------------- | |
460 | ||
461 | ||
462 | ||
463 | 1-4 | |
464 | \f | |
465 | ||
466 | ||
467 | 5. DOUBLE PRECISION LITERALS - The first two words are standard. | |
468 | The next six are the literal in FPP extended format (12-bit | |
469 | exponent, 60-bit mantissa). | |
470 | ||
471 | --------------- | |
472 | POINTER | ------> | | |
473 | |-------------| | |
474 | TYPE | | | | | | | | | |
475 | |-------------| | |
476 | EXPONENT | | | |
477 | |-------------| | |
478 | MANTISSA 0-11 | | | |
479 | |-------------| | |
480 | MANTISSA 12-23 | | | |
481 | |-------------| | |
482 | MANTISSA 24-35 | | | |
483 | |-------------| | |
484 | MANTISSA 36-47 | | | |
485 | |-------------| | |
486 | MANTISSA 48-59 | | | |
487 | --------------- | |
488 | ||
489 | 6. HOLLERITH (quoted) LITERALS - The first two words are stan- | |
490 | dard. The next N words are the characters of the literal in | |
491 | stripped six-bit ASCII, ending in a zero character. | |
492 | ||
493 | --------------- | |
494 | POINTER | ------> | | |
495 | |-------------| | |
496 | TYPE | | | | | | | | | |
497 | |-------------| | |
498 | CHARACTERS 1-2 | | | |
499 | --------------- | |
500 | etc. ............. | |
501 | ||
502 | ||
503 | 7. DIMENSION INFORMATION BLOCK - If a variable is DIMENSIONed, | |
504 | the third word of its symbol table entry will point to its | |
505 | dimension information block (may be indirectly, see section | |
506 | 8 below). The first word of this block is the number of | |
507 | dimensions. The second word is the total size of the array | |
508 | in elements; thus the size in PDP-8 words may be 3 or 6 times | |
509 | this number. The third word contains the "magic number" | |
510 | which is computed as follows: | |
511 | ||
512 | n-1 i | |
513 | MN= - 1+ SUM of d(j) | |
514 | i=1 j=1 | |
515 | ||
516 | where d(j) is the jth dimension and n is the number of | |
517 | dimensions. | |
518 | ||
519 | ||
520 | ||
521 | ||
522 | 1-5 | |
523 | \f | |
524 | ||
525 | ||
526 | For a 3-dimensional variable this number becomes: | |
527 | ||
528 | MN+ 1+d(1)+d(1)d(2) | |
529 | ||
530 | The magic number must be subtracted from any computed index, | |
531 | since indexing starts at one and not zero. The fourth word | |
532 | will (in PASS2) contain the displacement from #LIT of a | |
533 | literal which will contain either the magic number in | |
534 | un-normalized form (for dimensioned variables which are | |
535 | subroutine arguments) or the address of the variable minus | |
536 | the magic number (for local or COMMON dimensioned variables). | |
537 | This literal is necessary for calling subroutines where a | |
538 | subscripted variable is an argument. The next N words are | |
539 | the dimensions of the variable. If the variable is a formal | |
540 | parameter of the subroutine, it may have one or more dimen- | |
541 | sions which are also formal parameters. In this case, the | |
542 | magic number is zero, and the dimension(s) is a pointer to | |
543 | the symbol table entry for the variable(s) used as a dimen- | |
544 | sion. | |
545 | ||
546 | ---------- | |
547 | NUMBER OF DIMENSIONS | # | | |
548 | |--------| | |
549 | TOTAL NUMBER OF ELEMENTS | SIZE | | |
550 | |--------| | |
551 | MAGIC NUMBER | MN | | |
552 | |--------| | |
553 | RESERVED | | | |
554 | |--------| | |
555 | DIMENSION 1 | D1 | | |
556 | |--------| | |
557 | DIMENSION 2 | D2 | | |
558 | ---------- | |
559 | ........ | |
560 | ---------- | |
561 | DIMENSION n | Dn | | |
562 | ---------- | |
563 | ||
564 | 8. EQUIVALENCE INFORMATION BLOCK - If a variable is an | |
565 | EQUIVALENCE slave variable, the third word of its symbol | |
566 | table entry points to the equivalence information block. | |
567 | The first word of this block points to the dimension infor- | |
568 | mation (if any) of the variable. The second word points to | |
569 | the symbol table entry of the EQUIVALENCE master variable. | |
570 | The third word is the linearized subscript of the master | |
571 | variable from the EQUIVALENCE statement. The fourth word is | |
572 | the linearized subscript of the slave variable. | |
573 | ||
574 | ||
575 | ||
576 | ||
577 | ||
578 | ||
579 | ||
580 | ||
581 | 1-6 | |
582 | \f | |
583 | ||
584 | ||
585 | --------------- | |
586 | POINTER TO DIMENSIONS | ------> | | |
587 | |-------------| | |
588 | POINTER TO MASTER | ------> | | |
589 | |-------------| | |
590 | MASTER SUBSCRIPT | SSM | | |
591 | |-------------| | |
592 | SLAVE SUBSCRIPT | SSM | | |
593 | --------------- | |
594 | ||
595 | 9. COMMON INFORMATION BLOCK - If a symbol is defined as the name | |
596 | of a COMMON section, the third word of its symbol table entry | |
597 | points to a list of common information blocks. The first | |
598 | word of each such block points to the next block. The second | |
599 | word is the number of entries in the list that follows. The | |
600 | rest of the block is a set of pointers to the symbol table | |
601 | entries of the variables in the COMMON section. | |
602 | ||
603 | --------------- | |
604 | POINTER TO NEXT CIB | ------> | | |
605 | |-------------| | |
606 | NUMBER OF ENTRIES | # | | |
607 | |-------------| | |
608 | - | ------> | | |
609 | | |-------------| | |
610 | POINTER TO VARIABLES < | ------> | | |
611 | IN THIS COMMON | |-------------| | |
612 | - | ------> | | |
613 | --------------- | |
614 | ||
615 | ||
616 | ||
617 | PASS1 OUTPUT | |
618 | ||
619 | The output of PASS1 is a stream of polish with many special operators. | |
620 | Whenever an operand is to be output, the address of its symbol table | |
621 | entry is used. The following is a list of the output codes (in their | |
622 | mnemonic form, obtain numeric values from listing of PASS1) and the | |
623 | operation they are conveying to PASS2: | |
624 | ||
625 | PUSH The next word in the output file is an operand | |
626 | (symbol table pointer) to be put onto the stack. | |
627 | ||
628 | ADD Add the operands represented by the top two stack | |
629 | entries (actually this causes PASS2 to generate | |
630 | the RALF coding which will do the desired add). | |
631 | ||
632 | SUB Subtract top from next-to-top. | |
633 | ||
634 | MUL Multiply top two. | |
635 | ||
636 | DIV Divide top into next-to-top. | |
637 | ||
638 | EXP Raise next-to-top to power of top. | |
639 | ||
640 | 1-7 | |
641 | \f | |
642 | ||
643 | ||
644 | NOT Logical .NOT. of top of stack. | |
645 | ||
646 | NEG Negate top of stack. | |
647 | ||
648 | GE Compare top two for greater than or equal to, this | |
649 | has TRUE value if the next-to-top is .GE. the top. | |
650 | ||
651 | GT Compare for greater than. | |
652 | ||
653 | LE Compare for less than or equal. | |
654 | ||
655 | LT Compare for less than. | |
656 | ||
657 | AND Logical AND of top two entries. | |
658 | ||
659 | OR Logical inclusive OR of top two. | |
660 | ||
661 | EQ Compare top two for equality. | |
662 | ||
663 | NE Compare top two for inequality. | |
664 | ||
665 | XOR Exclusive OR of top two. | |
666 | ||
667 | EQV EQUIVALENCE of top two. | |
668 | ||
669 | PAUSOP Use top of stack as PAUSE number. | |
670 | ||
671 | DPUSH The next two words are a symbol table pointer and | |
672 | a displacement; put them onto the stack (used for | |
673 | DATA statements). | |
674 | ||
675 | BINRD1 Take the top of stack as the unit number and com- | |
676 | pile an unformatted READ-open. | |
677 | ||
678 | FMTRD1 The top two stack elements are the unit and | |
679 | format, take them and compile a formatted READ- | |
680 | open. | |
681 | ||
682 | RCLOSE Compile a READ-close. | |
683 | ||
684 | DARD1 Take the top two stack elements as a unit number | |
685 | and a block number and compile a direct access | |
686 | unformatted READ-open. | |
687 | BINWR1 - | |
688 | FMTWRI |> Same as for the corresponding READ case, except | |
689 | WCLOSE | substitute the word "WRITE". | |
690 | DAWR1 - | |
691 | ||
692 | DEFFIL Take the top four stack entries as the unit, | |
693 | number of records, record size, and index | |
694 | variable and compile a DEFINE FILE call. | |
695 | ||
696 | ASFDEF Set the PASS2 switch which says that the following | |
697 | statement is an arithmetic statement function. | |
698 | ||
699 | 1-8 | |
700 | \f | |
701 | ||
702 | ||
703 | ARGSOP The next word is a count, call it n; take the | |
704 | previous n stack entries as subscripts (or | |
705 | arguments) and the N+1st entry from the top as | |
706 | the array (or function) name; now compile this | |
707 | as an array reference (or function/subroutine | |
708 | call). | |
709 | ||
710 | EOLCOD The current statement is completed, reset stacks | |
711 | and do other housekeeping. | |
712 | ||
713 | ERRCOD The following word contains an error code, write | |
714 | it on the TTY together with the current line | |
715 | number, and put the error code and line number | |
716 | into the error list for possible PASS3. | |
717 | ||
718 | RETOPR Compile a subroutine RETURN. | |
719 | ||
720 | REWOPR Take the top of stack as a unit and compile a | |
721 | rewind. | |
722 | ||
723 | STOROP Compile a store of the top of stack into the | |
724 | next-to-top. | |
725 | ||
726 | ENDOPR Compile a RETURN if a function or subroutine or | |
727 | a CALL EXIT if a main program. | |
728 | ||
729 | DEFLBL The following word is a symbol table pointer to | |
730 | a statement number, compile this as the tag for | |
731 | the current RALF line. | |
732 | ||
733 | DOFINI The following word is a symbol table pointer for | |
734 | the DO-loop index, compile the corresponding | |
735 | DO-ending code. | |
736 | ||
737 | ARTHIF The following one, two, or three words are symbol | |
738 | table pointers to statement numbers for the less | |
739 | than zero, zero, and greater than zero conditions | |
740 | with the comparison to be made on the top of | |
741 | stack. | |
742 | ||
743 | LIFBGN The top of stack is taken as a logical expression | |
744 | PASS 2 should compile a jump-around-on-false; this | |
745 | implies that some statement is to follow. | |
746 | ||
747 | DOBEGN The top two stack entries represent the final | |
748 | value and increment of the DO-loop, process them | |
749 | in hopes of finding a matching DOFINI. | |
750 | ||
751 | ENDFOP The top of stack is a unit, compile an END FILE. | |
752 | ||
753 | STOPOP Compile a CALL EXIT. | |
754 | ||
755 | ||
756 | ||
757 | ||
758 | 1-9 | |
759 | \f | |
760 | ||
761 | ||
762 | ASNOPR The next word is the address of the symbol table | |
763 | entry for a statement number; compile an ASSIGN | |
764 | of this statement number to the variable | |
765 | represented by the top of stack. | |
766 | ||
767 | BAKOPR Take the top of stack as the unit and compile | |
768 | a BACKSPACE. | |
769 | ||
770 | FMTOPR The following word is a count N; the next N words | |
771 | after that are the image of the FORMAT statement. | |
772 | ||
773 | GO2OPR The following word is the symbol table entry for | |
774 | the statement number which is to be executed next. | |
775 | ||
776 | CGO2OP The following word is a count N; the next N words | |
777 | are symbol table pointers for the statement | |
778 | numbers of a computed GO TO list; use the value | |
779 | represented by the top of stack to compile a | |
780 | computed GO TO into this list. | |
781 | ||
782 | AGO2OP Compile an assigned GO TO with the top of stack. | |
783 | ||
784 | IOLMNT Take the top of stack as a list element for an | |
785 | I/O statement and compile read or write; PASS2 | |
786 | knows if it is a READ or WRITE by remembering | |
787 | previous FMTRD1, FMTWR1, etc. | |
788 | ||
789 | DATELM The next word is a count N; the next N words are | |
790 | a data element. | |
791 | ||
792 | DREPTC The next word is a repetition count for the set | |
793 | of DATELMs up until the next ENDELM. | |
794 | ||
795 | ENDELM Signals the end of a data element group. | |
796 | ||
797 | PRGSTK Tells PASS2 to purge the top stack entry. | |
798 | ||
799 | DOSTOR Performs the same function as STOROP after | |
800 | checking the top two stack elements for legal | |
801 | DO-parameter type (integer or real). | |
802 | ||
803 | ||
804 | ||
805 | PASS 1 SUBROUTINES | |
806 | ||
807 | The following is a brief description of the function of each of the | |
808 | major PASS1 subroutines: | |
809 | ||
810 | RDWR Compiles everything in a READ or WRITE statement | |
811 | starting at the first left parenthesis. | |
812 | ||
813 | RESTCP Restore character pointer and count for the | |
814 | statement buffer from the stack. | |
815 | ||
816 | ||
817 | 1-10 | |
818 | \f | |
819 | ||
820 | ||
821 | OUTWRD Output a word (the AC on entering) to the PASS1 | |
822 | output file. | |
823 | ||
824 | COMARP Test for comma or right parenthesis, skip one | |
825 | instruction if a comma, two if a right | |
826 | parenthesis, and none if neither. | |
827 | ||
828 | BACK1 Backup the statement buffer character pointer. | |
829 | ||
830 | GETSS Scans a variable reference, or subscripted | |
831 | variable reference with numeric subscripts and | |
832 | returns the linearized subscript. | |
833 | ||
834 | MUL12 Perform a 12-bit unsigned integer multiply. | |
835 | ||
836 | DOSTUF Handles compilation of DO-loop setup. | |
837 | ||
838 | TYPLST Process a type declaration, DIMENSION, or | |
839 | COMMON statement; sets up type bits and/or | |
840 | dimension information. | |
841 | ||
842 | LOOKUP Perform a symbol table search for variables and | |
843 | Hollerith literals. | |
844 | ||
845 | LUKUP2 Perform a symbol table search for integer, real, | |
846 | complex, and double precision literals or | |
847 | statement numbers. | |
848 | ||
849 | EXPR Analyze and process an arithmetic expression. | |
850 | ||
851 | LETTER Get next character from the statement buffer and | |
852 | skip if it is a letter, otherwise put the | |
853 | character back and don't skip. | |
854 | ||
855 | CHECKC The first word after the JMS is the negative of | |
856 | the ASCII character to test for; if this is the | |
857 | next character, skip. | |
858 | ||
859 | GETCWB Get the next character from the statement buffer | |
860 | preserving blanks. | |
861 | ||
862 | SAVECP Save the character pointer and count on the stack. | |
863 | ||
864 | GETC Get the next character ignoring blanks. | |
865 | ||
866 | ERMSG Output an error code to PASS1 output file. | |
867 | ||
868 | POP Pop the stack into the AC. | |
869 | ||
870 | PUSH Push the AC onto the stack. | |
871 | ||
872 | LEXPR Analyze and process an arithmetic expression, | |
873 | legal to the left of the equal sign in an | |
874 | assignment statement. | |
875 | ||
876 | 1-11 | |
877 | \f | |
878 | ||
879 | GET2C Get the next two character into one word. | |
880 | ||
881 | STMNUM Scan off a statement number and do the symbol | |
882 | table search. | |
883 | ||
884 | DIGIT Same as letter, except checks for a digit. | |
885 | ||
886 | NUMBER Scans off an integer, real, or double precision | |
887 | literal. | |
888 | ||
889 | GETNAM Scan off a variable name. | |
890 | ||
891 | ICHAR Get the next character from the input file. | |
892 | ||
893 | ||
894 | ||
895 | PASS2 OPERATION | |
896 | ||
897 | The first part of PASS2 generates the storage for variables, | |
898 | arguments, arrays, literals and temporaries by processing the symbol | |
899 | table built by PASS1, which is kept in core. The next step is to | |
900 | generate the code for subroutine entry and exit including argument | |
901 | pickup and restore. After all such prolog code is generated, PASS2O | |
902 | is loaded into core, overlaying most of the prolog-generating | |
903 | functions. The main loop of the compiler is now entered. This | |
904 | consists simply of reading a PASS1 output code from the intermediate | |
905 | file and using this number as an index into a jump table. The | |
906 | sections of code entered in this way then perform the correct | |
907 | generation of RALF code. | |
908 | ||
909 | Example: | |
910 | ||
911 | The statement: A=B+C*D | |
912 | would produce the following PASS1 output: | |
913 | (assuming A,B,C,D are REAL) | |
914 | ||
915 | 1) PUSH | |
916 | ->A (symbol table address of A) | |
917 | ||
918 | 2) PUSH | |
919 | ->B | |
920 | ||
921 | 3) PUSH | |
922 | ->C | |
923 | ||
924 | 4) PUSH | |
925 | ->D | |
926 | ||
927 | 5) MUL | |
928 | ||
929 | 6) ADD | |
930 | ||
931 | 7) STOROP | |
932 | ||
933 | 8) EOLCOD | |
934 | ||
935 | 1-12 | |
936 | \f | |
937 | ||
938 | ||
939 | The corresponding operations performed by PASS2 are: | |
940 | ||
941 | 1) Make a 3-word entry on the stack corresponding to the | |
942 | variable A consisting of a pointer to the symbol table | |
943 | entry, a word containing the type, and one reserved word. | |
944 | ||
945 | 2) Repeat above for B. | |
946 | ||
947 | 3) Repeat above for C. | |
948 | ||
949 | 4) Repeat above for D. | |
950 | ||
951 | 5) The multiply operator is handled like any of the binary | |
952 | operators by the subroutine CODE. This routine is called | |
953 | with the address of the multiply skeleton table. The | |
954 | top two stack entries are taken as the operands, with | |
955 | their types used to index into the skeleton tables. | |
956 | (See description of binary operator skeleton tables below.) | |
957 | The correct skeleton for this combination is chosen based on | |
958 | the where-abouts of each of the operands (AC or memory) | |
959 | at the corresponding point in the code which is being | |
960 | compiled. There are three possible cases: Memory,AC; | |
961 | Memory,Memory; AC,Memory. In this example, both operands | |
962 | are in memory so the code generated would be: | |
963 | ||
964 | FLDA C | |
965 | ||
966 | FMUL D | |
967 | ||
968 | The CODE subroutine then makes a new stack entry to replace | |
969 | the entries for C and D. This entry has a 0 in place of | |
970 | the symbol table pointer, signifying that the operand is in | |
971 | the AC. Other special case operand codes are: | |
972 | ||
973 | 0 - AC ( Already mentioned) | |
974 | ||
975 | 1 - 51 Temporaries | |
976 | ||
977 | 52 - 60 Array reference, the subscript of which is in | |
978 | an index register (1-7). | |
979 | ||
980 | 61 - A variable, the address of which is in base | |
981 | location 0. | |
982 | ||
983 | 62 - A variable, the address of which is in base | |
984 | location 3. | |
985 | ||
986 | 63-6777 - Symbol table entry (can be variable or | |
987 | literal). | |
988 | ||
989 | 7000 - Special temporary | |
990 | ||
991 | ||
992 | ||
993 | ||
994 | 1-13 | |
995 | \f | |
996 | ||
997 | ||
998 | 6) The add operator is handled in the same way as for multiply, | |
999 | except that in this case the add skeleton table is used. | |
1000 | When the correct row is found, the memory,AC case is chosen | |
1001 | since the result of C*D is now in the AC. This skeleton | |
1002 | simply generates: | |
1003 | ||
1004 | FADD B | |
1005 | ||
1006 | The new top of stack entry is a 0, since the result is in | |
1007 | the AC. | |
1008 | ||
1009 | 7) The store operation works in a similar manner using a special | |
1010 | skeleton table to determine whether the value to be stored is | |
1011 | already in the AC and whether it must be converted from one | |
1012 | type to another. In this case, no conversion need be | |
1013 | performed and the code generated is: | |
1014 | ||
1015 | FSTA A | |
1016 | ||
1017 | 8) The end of statement has been reached and any necessary | |
1018 | bookkeeping is performed. | |
1019 | ||
1020 | ||
1021 | ||
1022 | PASS2 SYMBOL TABLE | |
1023 | ||
1024 | PASS2 modifies the symbol table entries corresponding to variables | |
1025 | by replacing the first word of the entry with the first character of | |
1026 | the name, this character being derived from the list in which the name | |
1027 | is located. | |
1028 | ||
1029 | ||
1030 | ||
1031 | PASS2 ERROR LIST | |
1032 | ||
1033 | PASS2 creates a list (in field 1) of error codes and line numbers | |
1034 | corresponding to the errors printed on the Teletype during PASS2. | |
1035 | This list works downward starting just below the skeleton table area, | |
1036 | working towards the symbol table area. PASS3 uses this list to | |
1037 | write out extended error messages on the listing. | |
1038 | ||
1039 | ||
1040 | ||
1041 | PASS2 SKELETON TABLES | |
1042 | ||
1043 | All binary operators have associated with them a skeleton table | |
1044 | having 24 entries arranged in 8 rows and 3 columns. The rows | |
1045 | correspond to the following eight possibilities: | |
1046 | ||
1047 | 1) Both operands integer or real. | |
1048 | 2) Both operands complex. | |
1049 | 3) Both operands double precision. | |
1050 | 4) First operand integer or real, second complex. | |
1051 | 5) First operand integer or real, second double precision. | |
1052 | ||
1053 | 1-14 | |
1054 | \f | |
1055 | ||
1056 | ||
1057 | 6) First operand complex, second integer or real. | |
1058 | 7) First operand double precision, second integer or real. | |
1059 | 8) Both operands logical. | |
1060 | ||
1061 | The columns correspond to the following three possibilities: | |
1062 | ||
1063 | 1) First operand in memory, second in AC. | |
1064 | 2) Both operands in memory. | |
1065 | 3) First operand in the AC, second in memory. | |
1066 | ||
1067 | Each entry of the skeleton tables is either zero (illegal operator- | |
1068 | type combination) or points to a code skeleton (minus one). Code | |
1069 | skeletons are composed of combinations of the following types of | |
1070 | elements: | |
1071 | ||
1072 | 1) OPCODES - If an element has a non-negative value, it is taken | |
1073 | as the address of a text string for the desired opcode. This | |
1074 | works since all such text strings are stored below location | |
1075 | 4000 (in field 0). In this case, the next word of the | |
1076 | skeleton is taken as a designator for the address field, the | |
1077 | possibilities are: | |
1078 | ||
1079 | a. A non-negative values means the address field is a | |
1080 | literal text string, with the value being the address of | |
1081 | the string. (Same restriction as for opcode text | |
1082 | strings.) | |
1083 | ||
1084 | b. A zero indicates that this instruction should have no | |
1085 | address field. | |
1086 | ||
1087 | c. A minus one indicates that the address field is the | |
1088 | operand defined by the three variables ARG1, TYPE1, and | |
1089 | BASE1. | |
1090 | ||
1091 | d. A minus two indicates that the address field is the | |
1092 | operand defined by the three variables ARG2, TYPE2, and | |
1093 | BASE2. | |
1094 | ||
1095 | 2) MODE CHANGE - An element value of minus one means generate a | |
1096 | STARTF if currently in extended mode. A value of minus two | |
1097 | means generate a STARTE if currently in single mode. | |
1098 | ||
1099 | 3) MACRO - Any other negative value is taken as the address | |
1100 | (minus 3) of a sub-skeleton. This sub-skeleton may contain | |
1101 | anything except another sub-skeleton reference. When the | |
1102 | end of the sub-skeleton is encountered, the main skeleton is | |
1103 | re-entered. | |
1104 | ||
1105 | 4) END-OF-SKELETON - A zero indicates the end of the skeleton. | |
1106 | ||
1107 | ||
1108 | ||
1109 | ||
1110 | ||
1111 | ||
1112 | 1-15 | |
1113 | \f | |
1114 | ||
1115 | ||
1116 | PASS2 SUBROUTINES | |
1117 | ||
1118 | The following is a list of the major PASS 2 subroutines together with | |
1119 | a brief functional description. | |
1120 | ||
1121 | ERMSG Output a 2-character error code together with the | |
1122 | line number on the Teletypes; also put the code and | |
1123 | line number into the error list for PASS3. | |
1124 | ||
1125 | UCODE Generate the code for unary operators, given the | |
1126 | skeleton table address. | |
1127 | ||
1128 | CODE Generate code for binary operators, given the | |
1129 | skeleton table address. | |
1130 | ||
1131 | INWORD Read a word from the PASS1 output file. | |
1132 | ||
1133 | FATAL Output a fatal error message and exit to OS/8. | |
1134 | ||
1135 | ONUMBER Output the AC as a 4-digit octal number. | |
1136 | ||
1137 | SAVEAC Generate an FSTA #TMP+XXXX if necessary. | |
1138 | ||
1139 | GENCOD Generate the code specified by the given code | |
1140 | skeleton. | |
1141 | ||
1142 | OPCOD Output a TAB followed by the specified opcode | |
1143 | field. | |
1144 | ||
1145 | OPCODE Same as OPCOD, except output a second TAB after | |
1146 | the opcode field. | |
1147 | ||
1148 | OADDR Generate the address field specified by the | |
1149 | argument. | |
1150 | ||
1151 | GENSTF Generate STARTF if in E mode. | |
1152 | ||
1153 | GENSTE Generate STARTE if in F mode. | |
1154 | ||
1155 | OSNUM Output a statement number preceded by a "#". | |
1156 | ||
1157 | CRLF Output a carriage return/line feed. | |
1158 | ||
1159 | OTAB Output a TAB. | |
1160 | ||
1161 | OUTSYM Output a text string. | |
1162 | ||
1163 | GARG Pop the top entry of the stack into ARG1, TYPE1, | |
1164 | and BASE1. | |
1165 | ||
1166 | GARGS Pop the top two stack entries into ARG1, TYPE1, | |
1167 | BASE1 and ARG2, TYPE2, BASE2. | |
1168 | ||
1169 | OUTNAM Output a variable name. | |
1170 | ||
1171 | 1-16 | |
1172 | \f | |
1173 | ||
1174 | ||
1175 | OLABEL Output a generated label. | |
1176 | ||
1177 | GETSS Find the address of the dimension information | |
1178 | block given the symbol table address. | |
1179 | ||
1180 | SKPIRL Skip if integer, real, or logical. | |
1181 | ||
1182 | GENCAL Generate the code for a subroutine call from | |
1183 | the information contained on the stack. | |
1184 | ||
1185 | MUL12 Do a 12-bit unsigned multiply. | |
1186 | ||
1187 | OINS Output a literal opcode and address field. | |
1188 | ||
1189 | OCHAR Output a character | |
1190 | ||
1191 | NUMBRO Output a 5-digit octal number. | |
1192 | ||
1193 | ||
1194 | ||
1195 | PASS3 OPERATION | |
1196 | ||
1197 | PASS3 first initializes the listing header line with the version | |
1198 | number, date, and page number. It then processes lines, much like | |
1199 | PASS1, handling continuations and comments and outputs their image | |
1200 | to the listing file together with the line number. A constant check | |
1201 | is made on the error message list for line numbers that correspond | |
1202 | to the current line number, When such a correspondence occurs, the | |
1203 | error code is used to find the associated detailed error message, | |
1204 | which is then printed out. | |
1205 | ||
1206 | ||
1207 | ||
1208 | ||
1209 | ||
1210 | ||
1211 | ||
1212 | ||
1213 | ||
1214 | ||
1215 | ||
1216 | ||
1217 | ||
1218 | ||
1219 | ||
1220 | ||
1221 | ||
1222 | ||
1223 | ||
1224 | ||
1225 | ||
1226 | ||
1227 | ||
1228 | ||
1229 | ||
1230 | 1-17 | |
1231 | \f | |
1232 | ||
1233 | ||
1234 | CHAPTER 2 | |
1235 | ||
1236 | THE RALF ASSEMBLER | |
1237 | ||
1238 | ||
1239 | RALF and FLAP are essentially the same program, with differences con- | |
1240 | trolled by the conditional assembly parameter RALF, which must be | |
1241 | nonzero to assemble RALF, or zero to assemble FLAP. The source may be | |
1242 | assembled by either PAL8 or FLAP; although FLAP flags one error (a US | |
1243 | on a FIELD statement), this may safely be ignored. The remainder of | |
1244 | this chapter applies to RALF only. The following definitions are pre- | |
1245 | requisite to discussion of the operation of this assembler. | |
1246 | ||
1247 | MODULE The relocatable binary output of an assembly. A module | |
1248 | is physically an OS/8 file or sub-file in a library, | |
1249 | and is made up of an external symbol dictionary and | |
1250 | related text. Logically, it consists of one or more | |
1251 | program sections and COMMON sections. | |
1252 | ||
1253 | LIBRARY An OS/8 file on a directory device containing a catalog | |
1254 | and one or more modules as sub-files. Used solely by | |
1255 | the loader, as a source of modules with which to | |
1256 | satisfy unresolved symbols in a program being loaded. | |
1257 | ||
1258 | CATALOG A list of entry points defined in modules contained in | |
1259 | a library, with an indication of the locations of the | |
1260 | modules which define them. | |
1261 | ||
1262 | EXTERNAL A list of the global symbols defined in and/or used by | |
1263 | SYMBOL a module. Usually called ESD table. | |
1264 | DICTIONARY | |
1265 | ||
1266 | TEXT That part of the assembler's binary output which | |
1267 | contains the binary data to be loaded into memory, | |
1268 | along with sufficient information for the loader to | |
1269 | associate the output with specific memory locations | |
1270 | through references to the ESD table. | |
1271 | ||
1272 | SECTION A unit of binary data output by the assembler as part | |
1273 | of a module to be loaded into a contiguous area of | |
1274 | memory. COMMON sections are a special case in that | |
1275 | they may be defined with the same name in each of many | |
1276 | modules. In this case, all the definitions are combined | |
1277 | to create a single section in memory whose size is that | |
1278 | of the largest COMMON section with the given name. | |
1279 | Program sections, the only other type of section, must | |
1280 | have unique names. Sections are listed in the ESD | |
1281 | table by name, type and size. | |
1282 | ||
1283 | ENTRY POINT An address within a section which is named and defined | |
1284 | to be global, so that it may be used for the resolution | |
1285 | of external references in other sections. Entry points | |
1286 | are listed in the ESD table by name, type and address | |
1287 | within the section in which they occur. | |
1288 | ||
1289 | 2-1 | |
1290 | \f | |
1291 | ||
1292 | ||
1293 | EXTERNAL A symbol which is specified at assembly time to be | |
1294 | SYMBOL defined in another module as an entry point. External | |
1295 | symbols are listed in the ESD table by name and type. | |
1296 | A complete program must include entry point names | |
1297 | equivalent to every external symbol defined in every | |
1298 | module in the program. There need not, however, be an | |
1299 | external symbol for every entry point, nor is there any | |
1300 | limit on the number of modules which may contain | |
1301 | external symbols referencing one entry point. From a | |
1302 | functional viewpoint, entry points correspond to tags | |
1303 | within a program and external symbols correspond to | |
1304 | references to those tags. Every section is considered | |
1305 | to have an entry point at location zero of the section. | |
1306 | The name of this entry point is the section name. | |
1307 | ||
1308 | When RALF is called from the monitor, execution begins at the tag | |
1309 | BEGIN. Unless entry is via CHAIN, the OS/8 command decoder is called | |
1310 | to obtain input and output file designations. If entry is by way of | |
1311 | CHAIN, it is assumed that the command decoder area has already been | |
1312 | set up by the caller. In either case, it is always assumed that the | |
1313 | USR is already in core. A check is made to determine that the first | |
1314 | output file is a directory device file and, if no first output file | |
1315 | was specified, the default file SYS:FORTRN.RL is set up. | |
1316 | ||
1317 | Default output file extensions are defined if none were specified to | |
1318 | the command decoder, using .RL for the first output file and .LS for | |
1319 | the second output file. The first output file is then opened, and the | |
1320 | handler for the first input file is FETCHed. If /L or /G was | |
1321 | specified, the loader is looked up on SYS so that chaining will be | |
1322 | possible. The symbol table, which is loaded above 12000 in order to | |
1323 | preserve the USR, is now moved down to 10000. Finally, the system | |
1324 | date word is converted to character form and stored in the title | |
1325 | buffer. This completes the initialization procedure, and control is | |
1326 | passed to NEWLIN to collect the first line in the buffer. | |
1327 | ||
1328 | At NEXTST, teats are made to determine whether the line just assembled | |
1329 | needs to be listed, and whether there are any remaining significant | |
1330 | characters in the line which have not been assembled. If a semicolon | |
1331 | terminated the statement, the character pointers are bumped to skip | |
1332 | over it, and control passes to ASMBL to process the next statement on | |
1333 | the line. If the assembler is currently in a REPEAT line and the | |
1334 | count is not exhausted, the current line is re-assembled. Otherwise, | |
1335 | a new line is obtained in the line buffer by collecting input | |
1336 | characters until a carriage return is found. If the line is longer | |
1337 | than 128 characters, all characters after the 128th are ignored and | |
1338 | the LT message is printed. The line length is calculated and saved. | |
1339 | ||
1340 | At ASMBL, ASMOF is tested to determine whether the assembly is | |
1341 | currently inside a conditional. If so, the line is scanned for angle | |
1342 | brackets but not assembled. If not, and the first character is not a | |
1343 | slash, leading blanks are thrown away and control passes to LUNAME. | |
1344 | If there is a name, it is collected. If it is followed by a comma, | |
1345 | the symbol is looked up in the user symbol table. If the symbol is | |
1346 | undefined, it is defined as a label. If it was already defined, the | |
1347 | ||
1348 | 2-2 | |
1349 | \f | |
1350 | ||
1351 | ||
1352 | current location counter is compared with it to check for a possible | |
1353 | MD error. Control then returns to ASMBL. | |
1354 | ||
1355 | If the symbol found by LUNAME was followed by an equal sign, it is | |
1356 | looked up and defined according to the expression to the right of the | |
1357 | equal sign. If it was followed by a space, either of the characters | |
1358 | ' or #, or the character % and then a space, it is looked up in the | |
1359 | op-code table. If it is found, control passes to the appropriate | |
1360 | op-code handler. Otherwise, control is dispatched to GETEXP which | |
1361 | restores the character pointers saved by LUNAME, processes the rest of | |
1362 | the line as a single-word expression, and returns to NEXTST for the | |
1363 | next statement. | |
1364 | ||
1365 | Expressions are processed on a strict left-to-right basis by the | |
1366 | routine EXPR. A symbol is looked up, and its value is stored in WORD1 | |
1367 | and WORD2. It is then combined with the accumulated expressions in | |
1368 | EXPVAL according to the operator in LASTOP. A new operator (if any) | |
1369 | is then located, and the loop begins again. When no operator is found | |
1370 | after some symbol, the expression is considered complete and control | |
1371 | returns to the calling routine. Undefined symbols appearing in an | |
1372 | expression cause output of a US message, and the value zero is used | |
1373 | in their place. COMMON and section names in the symbol table have | |
1374 | special values (namely their lengths), but they always refer to the | |
1375 | starting location of the sections they define, and their values are | |
1376 | taken to be zero of the section so named. If GETNAM is not able to | |
1377 | find a symbol in the expression, three possibilities are checked | |
1378 | before flagging the expression as invalid: | |
1379 | ||
1380 | 1. It may be a number, rather than a symbol. | |
1381 | ||
1382 | 2. It may be one of the characters period (representing the | |
1383 | current value of the location counter) or double quote | |
1384 | (representing the binary value of the next ASCII character). | |
1385 | ||
1386 | 3. The last operator may have been a plus sign in an indexed FPP | |
1387 | instruction. | |
1388 | ||
1389 | At the end of expression evaluation, the console keyboard flag is | |
1390 | checked to ensure that the user has not typed CTRL/C to stop the | |
1391 | assembly. | |
1392 | ||
1393 | There are six expression operator routines, one each for the | |
1394 | operations add, subtract, AND, OR, multiply and divide. Except for | |
1395 | add and subtract, these routines must operate on absolute addresses | |
1396 | because the loader does not have facilities for non-additive | |
1397 | resolution of address constants. | |
1398 | ||
1399 | The symbol table is the sole occupant of field 1, except for the OS/8 | |
1400 | field 1 resident. The symbol table is loaded at location 12000 to | |
1401 | prevent an unnecessary swap of the USR, but moved down, to start at | |
1402 | location 10000, during initialization. Subsequent calls to the USR do | |
1403 | require a swap. The symbol table is a set of linked lists, or, more | |
1404 | properly, two sets; one for user-defined symbols and one for op-codes | |
1405 | and pseudo-ops. Each set contains a list corresponding to every | |
1406 | ||
1407 | 2-3 | |
1408 | \f | |
1409 | ||
1410 | ||
1411 | letter of the alphabet, and each list consists of the symbols which | |
1412 | start with that same letter. Every time a symbol is encountered in | |
1413 | the source, the list corresponding to its first letter is searched | |
1414 | until a match is found, or until the end of the list or a symbol of | |
1415 | higher alphabetical order is found. In the latter cases, the new | |
1416 | symbol is inserted into the user symbol table by changing the list | |
1417 | pointers so that the new symbol appears in the list in correct | |
1418 | alphabetical order. The pre-defined symbol table is never changed, | |
1419 | because the user is not permitted to define op-codes or pseudo-ops. | |
1420 | ||
1421 | A RALF output file of relocatable binary data consists of two parts; | |
1422 | the ESD table and the text. The ESD table contains all information | |
1423 | required by LIBRA or the loader, and is generated between the first | |
1424 | and second passes of assembly. It serves as a partial symbol table | |
1425 | for the loader (the full symbol table is built up from the ESD tables | |
1426 | of all the modules in a program) and provides the name, attributes, | |
1427 | and value of every global symbol used by any module, as well as an ESD | |
1428 | code by which the symbol may be referred to within the text. Every | |
1429 | entry in the ESD table is six words long. The first three words are | |
1430 | the symbol itself, packed in stripped ASCII, with two characters per | |
1431 | word. The next word contains type information in the following | |
1432 | format: | |
1433 | ||
1434 | A VALUE OF INDICATES | |
1435 | ||
1436 | 0 Last entry in the ESD table. | |
1437 | ||
1438 | 1 The symbol is defined as external to this module. The | |
1439 | value of the symbol must be resolved by a symbol of the | |
1440 | same name appearing in the ESD table of another module. | |
1441 | The ESD code which follows the type code is the code by | |
1442 | which references to this symbol will be identified in the | |
1443 | text. | |
1444 | ||
1445 | 2 The symbol is defined as an entry point in this module. | |
1446 | It is therefore suitable for the resolution of external | |
1447 | references in other modules. The ESD code which follows | |
1448 | the type word identifies the program section in which | |
1449 | this entry point appears, and the value of the symbol is | |
1450 | relative to that section. | |
1451 | ||
1452 | 3 The symbol is defined as a COMMON section whose size is | |
1453 | at least as large as specified by the value of the | |
1454 | symbol. If several modules contain ESD entries referring | |
1455 | to COMMON sections with the same name, a single COMMON | |
1456 | block having the size of the largest symbol is allocated | |
1457 | for all of them. A name consisting of blanks is treated | |
1458 | in the same manner as any other name. | |
1459 | ||
1460 | 4 The symbol is defined as a section of location | |
1461 | independent (that is, fully word-relocatable) code of a | |
1462 | size equal to the value of the symbol. The ESD code for | |
1463 | this section allows text from the module to be included | |
1464 | in this section, and relocated with respect to it. | |
1465 | ||
1466 | 2-4 | |
1467 | \f | |
1468 | ||
1469 | ||
1470 | 5-17 Undefined | |
1471 | ||
1472 | The text portion of a relocatable binary file consists of the binary | |
1473 | data to be loaded into memory, along with information directing the | |
1474 | loader on how to modify that data to correct the addresses for program | |
1475 | relocation. The first word of text is a control word, which is made | |
1476 | up of a 4-bit type code and an 8-bit indicator. Following the control | |
1477 | word, and depending on the type code, are a number of data words to be | |
1478 | loaded as directed by the type code and the indicator. The control | |
1479 | word type codes are: | |
1480 | ||
1481 | CODE FUNCTION | |
1482 | ||
1483 | 0 End of text, if the indicator is zero, or no operation | |
1484 | otherwise. | |
1485 | ||
1486 | 1 Copy the number of words given by the indicator from text | |
1487 | directly into memory without modification. | |
1488 | ||
1489 | 2 Re-origin to the section identified by the indicator, | |
1490 | with a relative location defined by bits 9-23 of the | |
1491 | following doubleword. Thus, the next two words define a | |
1492 | new origin for the following text, in the program section | |
1493 | identified by the indicator. | |
1494 | ||
1495 | 3 Relocate the following doubleword bits 9-23 by the value | |
1496 | of the symbol whose ESD code is identified by the | |
1497 | indicator. The following doubleword is usually a two- | |
1498 | word FPP instruction, the low-order 15 bits of which are | |
1499 | to be relocated by the value of the symbol identified by | |
1500 | the indicator. | |
1501 | ||
1502 | ||
1503 | ||
1504 | WRITING PDP-8 CODE UNDER OS/8 FORTRAN IV | |
1505 | ||
1506 | ||
1507 | RALF contains the normal set of PDP-8 instructions (TAD, DCA, CDF, | |
1508 | KSF, etc.), however RALF does not allow literals, the PAGE pseudo-op, | |
1509 | or the use of I to specify indirect addressing. PDP-8 code generated | |
1510 | by RALF is not relocatable; therefore, operations such as the | |
1511 | following are illegal: | |
1512 | ||
1513 | EXTERN SWAP /Illegal | |
1514 | TAD (SWAP /Under | |
1515 | CDF SWAP /RALF | |
1516 | ||
1517 | The character % appended to the end of a memory reference instruction | |
1518 | indicates indirect addressing, and the character Z indicates a page 0 | |
1519 | reference: | |
1520 | ||
1521 | ||
1522 | ||
1523 | ||
1524 | ||
1525 | 2-5 | |
1526 | \f | |
1527 | ||
1528 | ||
1529 | CURRENT PAGE PAGE ZERO | |
1530 | DIRECT INDIRECT DIRECT INDIRECT | |
1531 | ||
1532 | TAD A TAD% A TADZ A TADZ% A | |
1533 | DCA B DCA% B DCAZ B DCAZ% B | |
1534 | ||
1535 | Spaces are not allowed between memory reference instructions and | |
1536 | either the Z or the % characters. The Z must precede the % when both | |
1537 | are used. I.e., do not write "DCA%Z". | |
1538 | ||
1539 | Three pseudo-ops have been added to RALF: SECT8, COMMZ, and FIELD1. | |
1540 | All three define sections of code and are handled in the same manner | |
1541 | as SECT; however, these new sections have special meaning for the | |
1542 | loader. The address pseudo-op (ADDR) which generates a two word re- | |
1543 | locatable 15 bit address (i.e., JA TAG without use of JA) might prove | |
1544 | useful in 8-mode routines. The following example demonstrates a way | |
1545 | in which an 8-mode routine in one RALF module calls an 8-mode routine | |
1546 | in another module: | |
1547 | ||
1548 | EXTERN SUB | |
1549 | . | |
1550 | . | |
1551 | RIF /Set DF to current | |
1552 | TAD ACDF /IF for return | |
1553 | DCA .+1 | |
1554 | 0 /CDF X | |
1555 | TAD KSUB /Make a CIF from | |
1556 | RTL CLL /Field bits | |
1557 | RAL | |
1558 | TAD ACIF | |
1559 | DCA .+1 | |
1560 | 0 /CIF to field | |
1561 | /Containing SUB | |
1562 | JMS% KSUB+1 | |
1563 | ||
1564 | KSUB, ADDR SUB /Psuedo-op to | |
1565 | /Generate 15 bit | |
1566 | /ADDR of subroutine | |
1567 | /SUB | |
1568 | ACDF, CDF | |
1569 | ACIF, CIF | |
1570 | ||
1571 | In general the address pseudo-op can be used to supply an 8-mode | |
1572 | section with an argument or pointer external to the section. | |
1573 | ||
1574 | FPP and 8-mode code may be intermixed in any RALF section. PDP-8 mode | |
1575 | routines must be called in FPP mode by either: | |
1576 | ||
1577 | TRAP3 SUB | |
1578 | ||
1579 | or TRAP4 SUB | |
1580 | ||
1581 | A TRAP3 SUB causes FRTS to generate a JMP SUB with interrupts on and | |
1582 | the FPP hardware (if any) halted. TRAP4 generates a JMS SUB under the | |
1583 | ||
1584 | 2-6 | |
1585 | \f | |
1586 | ||
1587 | ||
1588 | same conditions. The return from TRAP4 is: | |
1589 | ||
1590 | CDF CIF 0 | |
1591 | JMP% SUB | |
1592 | ||
1593 | The return from TRAP3 is: | |
1594 | ||
1595 | CDF CIF 0 | |
1596 | JMP% RETURN+1 | |
1597 | EXTERN #RETRN | |
1598 | RETURN, ADDR #RETRN | |
1599 | ||
1600 | ||
1601 | Communication between FPP and 8-mode routines is best done at the FPP | |
1602 | level because of greater flexibility in both addressing and relocation | |
1603 | in FPP mode. The following routine demonstrates how to pass an argu- | |
1604 | ment to, and retrieve an argument from, an 8-mode routine: | |
1605 | ||
1606 | EXTERN SUB | |
1607 | EXTERN SUBIN | |
1608 | EXTERN SUBOUT | |
1609 | . | |
1610 | . | |
1611 | . | |
1612 | FLDA X /Arg for SUB | |
1613 | FSTA SUBIN | |
1614 | TRAP4 SUB /Call SUB | |
1615 | FLDA SUBOUT /Get result | |
1616 | FSTA Y | |
1617 | ||
1618 | If the 8-mode routine SUB were in the same module as the FPP routine, | |
1619 | the externs would not be necessary. In practice it is common for FPP | |
1620 | and 8-mode routines that communicate with one another to be in the | |
1621 | same section. A number of techniques can be used to pass arguments. | |
1622 | For example, an FPP routine could move the index registers to an | |
1623 | 8-mode section and pass single precision arguments via ATX. | |
1624 | ||
1625 | Because 8-mode routines are commonly used in conjunction with FPP code | |
1626 | (generated by the compiler), the 8-mode programmer should be familiar | |
1627 | with OS/8 FORTRAN IV subroutine calling conventions. The general code | |
1628 | for a subroutine call is a JSR, followed by a JA around a list of | |
1629 | arguments, followed by a list of pointers to the arguments. The FPP | |
1630 | code for the statement: | |
1631 | ||
1632 | CALL SUB (X,Y,Z) | |
1633 | ||
1634 | would be | |
1635 | ||
1636 | EXTERN SUB | |
1637 | JSR SUB | |
1638 | JA BYARG | |
1639 | JA X | |
1640 | JA Y | |
1641 | JA Z | |
1642 | ||
1643 | 2-7 | |
1644 | \f | |
1645 | ||
1646 | ||
1647 | BYARG, . | |
1648 | . | |
1649 | . | |
1650 | . | |
1651 | ||
1652 | The general format of every subroutine obeys the following scheme: | |
1653 | ||
1654 | SECT SUB | |
1655 | JA #ST /Jump to start of | |
1656 | /Routine | |
1657 | TEXT +SUB+ /Needed for | |
1658 | /Trace back | |
1659 | RTN, SETX XSUB /Reset SUB's index | |
1660 | SETB BSUB /And base page | |
1661 | BSUB, FNOP /Start of base page | |
1662 | JA . | |
1663 | . | |
1664 | . | |
1665 | ORG BSUB+30 /Restart for SUB | |
1666 | FNOP:JA RTN | |
1667 | GOBAK, FNOP:JA . /Return to | |
1668 | /Calling program | |
1669 | ||
1670 | Location 00000 of the calling routine's base page points to the list | |
1671 | of arguments, if any, and may be used by the called subroutine | |
1672 | provided that it is not modified. Location 0003 of the calling | |
1673 | routine's base page is free for use by the called subroutine. | |
1674 | ||
1675 | Location 0030 of the calling routine's base page contains the address | |
1676 | where execution is to continue upon exit from the subroutine, so that | |
1677 | a subroutine should not return from a JSR call via location 0 of the | |
1678 | calling routine: | |
1679 | ||
1680 | CORRECT INCORRECT | |
1681 | ||
1682 | FLDA 30 FLDA 0 | |
1683 | JAC JAC | |
1684 | ||
1685 | The "non-standard" return allows the calling routine to reset its own | |
1686 | index registers and base page before continuing in-line execution. | |
1687 | General initialization code for a subroutine would be: | |
1688 | ||
1689 | SECT SUB | |
1690 | JA #ST | |
1691 | . | |
1692 | . | |
1693 | . | |
1694 | BASE 0 | |
1695 | ||
1696 | #ST, STARTD /So only 2 words | |
1697 | /Will be picked up | |
1698 | FLDA 30 /Get return JA | |
1699 | FSTA GOBAK /Save it | |
1700 | FLDA 0 /Get pointer to list | |
1701 | ||
1702 | 2-8 | |
1703 | \f | |
1704 | ||
1705 | ||
1706 | SETX XSUB /Set SUB's XR | |
1707 | SETB BSUB /Set SUB's Base | |
1708 | BASE BSUB | |
1709 | INDEX XSUB | |
1710 | FSTA BSUBX /Store pointer | |
1711 | /Somewhere on Base | |
1712 | . | |
1713 | . | |
1714 | . | |
1715 | STARTF /Set F mode before | |
1716 | JA GOBAK /Return | |
1717 | ||
1718 | The above code can be optimized for routines that do not require full | |
1719 | generality. The JA #ST around the base page code is a convenience | |
1720 | which may be omitted. The three words of text are necessary only for | |
1721 | error traceback and may also be omitted. If the subroutine is not | |
1722 | going to call any general subroutines, the SETX and SETB instructions | |
1723 | at location RTN and the JA RTN at location 0030 are not necessary. If | |
1724 | the subroutine does not require a base page, the SETB instruction is | |
1725 | not necessary in subroutine initialization; similar remarks apply to | |
1726 | index registers. If neither base page nor index registers are | |
1727 | modified by the subroutine, the return sequence: | |
1728 | ||
1729 | FLDA 0 | |
1730 | JAC | |
1731 | ||
1732 | is also legal. In a subroutine call, the JA around the list of argu- | |
1733 | ments is unnecessary when there are no arguments. A RALF listing of | |
1734 | a FORTRAN source will provide a good reference of general FPP coding | |
1735 | conventions. | |
1736 | ||
1737 | In order to generate good 8-mode code, one must be aware of the manner | |
1738 | in which the loader links and relocates RALF code. The loader handles | |
1739 | three 8-mode section types: COMMZ, FIELD1, and SECT8. All three | |
1740 | types of section are forced to begin and end on page boundaries and to | |
1741 | be a part of level MAIN; 8-mode sections never reside in overlays. | |
1742 | COMMZ and FIELD1 sections are forced to reside in field 1; SECT | |
1743 | sections may be in any field. The first COMMZ section encountered is | |
1744 | forced to begin at location 10000, thus enabling a page 0 in field 1. | |
1745 | COMMZ sections of the same name are handled like COMMON sections of | |
1746 | the same name (i.e., they are combined into one common section). This | |
1747 | feature allows 8-mode code in different modules to share page 0, pro- | |
1748 | vided that the modules do not destroy each other's page 0 allocations. | |
1749 | Suppose two modules were to share page 0, with the first using | |
1750 | location 0-17 and the second using locations 20-37: | |
1751 | ||
1752 | /Module A | |
1753 | COMMZ SHARE | |
1754 | P1, 1 | |
1755 | P2, 2 | |
1756 | KSUBA1, SUBA1 | |
1757 | KSUBA2, SUBA2 | |
1758 | . | |
1759 | . | |
1760 | ||
1761 | 2-9 | |
1762 | \f | |
1763 | ||
1764 | ||
1765 | . /Should not go over | |
1766 | LASTA, -1 /20 locations | |
1767 | ||
1768 | FIELD1 A | |
1769 | ||
1770 | TADZ P1 | |
1771 | JMSZ% KSUBA1 | |
1772 | . | |
1773 | . | |
1774 | . /Module B | |
1775 | COMMZ SHARE | |
1776 | ORG .+20 /ORG past module A's | |
1777 | /Page 0 | |
1778 | P3, 3 | |
1779 | P4, 4 | |
1780 | KSUBB, SUBB | |
1781 | . | |
1782 | . | |
1783 | . | |
1784 | LASTB -2 | |
1785 | FIELD1 B | |
1786 | TADZ P3 | |
1787 | . | |
1788 | . | |
1789 | . | |
1790 | ||
1791 | The two COMMZ sections will be put on top of one another, however, | |
1792 | because of the ORG .+20 in module B, they will effectively reside back | |
1793 | to back. When the image is loaded, the COMMZ sections will look as | |
1794 | follows: | |
1795 | ||
1796 | LOC CONTENTS | |
1797 | ||
1798 | 1 0000 1 | |
1799 | 0001 2 | |
1800 | 2 SUBA1 | |
1801 | 3 SUBA2 | |
1802 | . | |
1803 | . | |
1804 | . | |
1805 | 1 0017 -1 /LASTA | |
1806 | 1 0020 3 | |
1807 | 21 4 | |
1808 | 22 SUBB | |
1809 | . | |
1810 | . | |
1811 | . | |
1812 | 37 -2 /LASTB | |
1813 | ||
1814 | If module A is to reference module B's page 0, the procedure is: | |
1815 | ||
1816 | P3=20 | |
1817 | TADZ P3 | |
1818 | ||
1819 | ||
1820 | 2-10 | |
1821 | \f | |
1822 | ||
1823 | ||
1824 | Alternately, a duplicate of the source code for COMMZ SHARE may be | |
1825 | included in module B. Modules that are using the same COMMZ section | |
1826 | must be aware of how it is divided up. Although COMMZ SHARE takes only | |
1827 | 40 locations, the loader allocates a full 200 locations to it. All | |
1828 | 8-mode section core allocations are always rounded up so that they | |
1829 | terminate on a page boundary. If COMMZ sections of different names | |
1830 | exist, they are accepted by the loader and inserted into field 1, but | |
1831 | only one COMMZ is the real page 0. In general, it is unwise to have | |
1832 | more than 1 COMMZ section name. | |
1833 | ||
1834 | FIELD1 sections are identical to COMMZ sections in most respects. | |
1835 | Memory allocation for FIELD1 sections is assigned after COMMZ sections, | |
1836 | however, and FIELD1 sections are combined with FORTRAN COMMON sections | |
1837 | of the same name as well as other FIELD1 sections of the same name. | |
1838 | The first difference ensures that COMMZ will be allocated page 0 | |
1839 | storage even in the presence of FIELD1 sections. The second allows | |
1840 | PDP-8 code to be loaded into COMMON, making it possible to load | |
1841 | initialization code into data buffers. Two FIELD1 sections with the | |
1842 | same name may be combined in the same manner as two COMMZ, sections. | |
1843 | ||
1844 | The primary purpose of COMMZ is to provide a PDP-8 page 0; the primary | |
1845 | purpose of FIELD1 is to ensure that 8-mode code will be loaded into | |
1846 | field 1 and that generating CIF CDF instructions in-line is not neces- | |
1847 | sary. SECT8 sections may not be combined in the manner of a COMMON | |
1848 | and are not ensured of being placed into field 1. | |
1849 | ||
1850 | An 8-mode section does not have to be less than a page in length; | |
1851 | however, the programmer should be aware that a SECT8 section which | |
1852 | exceeds one page may be loaded across a field boundary and could | |
1853 | thereby produce disastrous results at execution time. For this | |
1854 | reason, it is generally unwise to cross pages in SECT8 code. This | |
1855 | situation will never occur on an 8K configuration. If the total | |
1856 | amount of COMMZ and FIELD1 code exceeds 4K, the loader generates an | |
1857 | OVER CORE message. The loader generates an MS error for any of the | |
1858 | following: | |
1859 | ||
1860 | 1. A COMMZ section name is identical to some entry point or some | |
1861 | non-COMMZ section name. | |
1862 | ||
1863 | 2. A FIELD1 section name is identical to some entry point or a | |
1864 | SECT, SECT8 or COMMZ section name. | |
1865 | ||
1866 | 3. A SECT8 section name is identical to an entry point or some | |
1867 | other section name. | |
1868 | ||
1869 | COMMZ sections, like FORTRAN COMMONS, are never entered in the library | |
1870 | catalog. | |
1871 | ||
1872 | For users who intend to write 8-mode code that will execute in | |
1873 | conjunction with certain 8-mode library routines, the layout of PDP-8 | |
1874 | FIELD1 #PAGE 0 is: | |
1875 | ||
1876 | ||
1877 | ||
1878 | ||
1879 | 2-11 | |
1880 | \f | |
1881 | ||
1882 | ||
1883 | LOCATION USE | |
1884 | ||
1885 | 0-1 Temps for any non-interrupt time routine. | |
1886 | 2-13 User locations. | |
1887 | 14-157 System locations. | |
1888 | 160-177 User locations. | |
1889 | ||
1890 | 1. Do not define any COMMZ sections other than the system COMMZ | |
1891 | which is #PAGE0. | |
1892 | ||
1893 | 2. If the system page 0 is desired, it will be pulled in from | |
1894 | the library if EXTERN #DISP appears in the code. | |
1895 | ||
1896 | 3. Do not use any part of page 0 reserved for the system. | |
1897 | ||
1898 | Special purpose PDP-8 mode subroutines may be written to perform idle | |
1899 | jobs (refreshing a scope, checking sense lines) or to handle specific | |
1900 | interrupts not serviced by FRTS. | |
1901 | ||
1902 | The run-time system enters idle loops while waiting for the FPP to | |
1903 | complete a task or for an I/O job to complete. It is possible to | |
1904 | effect a JMS to a user routine during the idle loop. | |
1905 | ||
1906 | RTS contains a set of instructions such as: | |
1907 | ||
1908 | #IDLE, JMP .+4 | |
1909 | 0 | |
1910 | CDF CIF | |
1911 | JMS I .-2 | |
1912 | ||
1913 | This sequence of instructions must be revised if an IDLE routine is to | |
1914 | be called. | |
1915 | ||
1916 | The location #IDLE must be changed to a SKP (7410). #IDLE+1 must be | |
1917 | set to the address of the routine to be called. #IDLE+2 must be set | |
1918 | to a CDF CIF to the field of the routine. This setup can be done in a | |
1919 | routine that is called at the beginning of MAIN. For example: | |
1920 | ||
1921 | CALL SETIDL | |
1922 | ||
1923 | where SETIDL is a routine such as: | |
1924 | ||
1925 | SECT8 SETIDL /Must be an 8-mode section | |
1926 | JA #RET | |
1927 | TEXT +SETIDL+ /Traceback information | |
1928 | SXR, SETX XR | |
1929 | SETB BP | |
1930 | BP, 0.0 | |
1931 | XR, 0.0 | |
1932 | . | |
1933 | . | |
1934 | . | |
1935 | ||
1936 | ||
1937 | ||
1938 | 2-12 | |
1939 | \f | |
1940 | ||
1941 | ||
1942 | ORG 10*3+BP | |
1943 | FNOP /For trace back | |
1944 | JA SXR | |
1945 | . | |
1946 | 0 | |
1947 | RET, JA . /Return address | |
1948 | . | |
1949 | . | |
1950 | . | |
1951 | #RET, STARTD /Set up | |
1952 | FLDA 10*3 /Return address | |
1953 | FSTA RET | |
1954 | SETB BP /Just for traceback | |
1955 | TRAP4 SET8 /Go to the 8 mode | |
1956 | /Routine set 8 | |
1957 | STARTF | |
1958 | JA RET /Return to main | |
1959 | SET8, 0 | |
1960 | TAD IDLAD /Field of idle | |
1961 | CLL RTL | |
1962 | RAL /Move to | |
1963 | /Bits 6-8 | |
1964 | TAD SCDF /CDF to #IDLE | |
1965 | DCA .+3 | |
1966 | TAD IDLAD+1 /Address of #IDLE | |
1967 | DCA IDPTR | |
1968 | 0 /CDF goes here | |
1969 | TAD S7410 /SKP | |
1970 | DCA% IDPTR /Store at #IDLE | |
1971 | TAD JOB+1 /Address of IDLE top routine | |
1972 | ISZ IDPTR | |
1973 | DCA IDPTR /Store a #IDLE+1 | |
1974 | TAD JOB /Field of routine | |
1975 | CLL RTL | |
1976 | RAL /Position | |
1977 | TAD SFIELD | |
1978 | ISZ IDPTR | |
1979 | DCA% IDPTR /Store at #IDLE+2 | |
1980 | CDF CIF /Set to field 0 | |
1981 | JMP% SET8 /Return to instruction | |
1982 | /Following "TRAP4 SET8" | |
1983 | EXTERN #IDLE | |
1984 | IDLAD, ADDR #IDLE /15 bit address of IDLE | |
1985 | JOB, ADDR DOIT /15 bit address of IDLE | |
1986 | /Routine "DOIT" | |
1987 | SCDF, 6201 /CDF | |
1988 | SFIEL, 6203 /CDF CIF | |
1989 | IDPTR, 0 | |
1990 | S7410, 7410 /Skip | |
1991 | ||
1992 | /The following routine performs the | |
1993 | /IDLE task | |
1994 | /Executed during IDLE loops | |
1995 | ||
1996 | ||
1997 | 2-13 | |
1998 | \f | |
1999 | ||
2000 | ||
2001 | DOIT, 0 | |
2002 | . | |
2003 | . | |
2004 | . /Perform task | |
2005 | . | |
2006 | CDF CIF 0 /Back to field 0 | |
2007 | JMP% DOIT /And back | |
2008 | ||
2009 | If the subroutine is checking for an illegal argument, an argument | |
2010 | error message with traceback can be included in the subroutine by | |
2011 | adding two lines somewhere on the base pages | |
2012 | ||
2013 | EXTERN #ARGER | |
2014 | EXAMER, TRAP4 #ARGER | |
2015 | ||
2016 | When the error is detected in the program, effect a jump to the TRAP4 | |
2017 | instruction. For example, | |
2018 | ||
2019 | FLDA% EXTMP1 | |
2020 | JEQ EXAMER /A value of 0 is illegal | |
2021 | or | |
2022 | ||
2023 | FLDA EXTMP1 | |
2024 | FNEG | |
2025 | FADD EXTMP2 | |
2026 | JLT EXAMER /The value in EXTMP1 must be | |
2027 | /greater than that in EXTMP2 | |
2028 | ||
2029 | Some points to note in the above example | |
2030 | ||
2031 | 1. Using a # as the first character in the name of the start of the | |
2032 | program assumes that the name is not called from the FORTRAN level. | |
2033 | This is because # is an illegal FORTRAN keyboard character. | |
2034 | ||
2035 | 2. If index registers 3-5 are not used by the subroutine, the space | |
2036 | from XR3 to the ORG statement can be used for temporary storage, | |
2037 | if needed. | |
2038 | ||
2039 | 3. The arguments passed from the FORTRAN level do not have to be | |
2040 | picked up all at once at the start of the calculation (3-word) | |
2041 | portion of the program. They can be picked up as required during | |
2042 | the program, can be saved in temporary space, or accessed | |
2043 | indirectly each time required, as best suits the subroutine. | |
2044 | ||
2045 | If a call to this routine such as Z=EXAMPL(A,B,C,D) were encountered | |
2046 | by the compiler, it would generate the following call to the routine: | |
2047 | ||
2048 | JSR EXAMPL /go to the routine | |
2049 | JA .+10 /jump around arguments | |
2050 | JA A /pointer to lst argument | |
2051 | JA B /pointer to 2nd argument | |
2052 | JA C /pointer to 3rd argument | |
2053 | JA D /pointer to 4th argument | |
2054 | ||
2055 | ||
2056 | 2-14 | |
2057 | \f | |
2058 | ||
2059 | ||
2060 | The AMOD routine is listed below to illustrate an application of the | |
2061 | formal calling sequence. It also includes an error condition check | |
2062 | and picks up two arguments. When called from FORTRAN, the code is | |
2063 | AMOD(X,Y). | |
2064 | ||
2065 | / | |
2066 | / | |
2067 | / | |
2068 | / A M O D | |
2069 | / - - - - | |
2070 | / | |
2071 | /SUBROUTINE AMOD(X,Y) | |
2072 | SECT AMOD /SECTION NAME(REAL NUMBERS) | |
2073 | ENTRY MOD /ENTRY POINT NAME(INTEGERS) | |
2074 | JA #AMOD /JUMP TO START OF ROUTINE | |
2075 | TEXT +AMOD + /FOR ERROR TRACE BACK | |
2076 | AMODXR, SETX XRAMOD /SET INDEX REGISTERS | |
2077 | SETB BPAMOD /ASSIGN BASE PAGE | |
2078 | BPAMOD, F 0.0 /BASE PAGE | |
2079 | XRAMOD, F 0.0 /INDEX REGS. | |
2080 | AMODX, F 0.0 /TEMP STORAGE | |
2081 | ORG 10*3+BPAMOD /RETURN SEQUENCE | |
2082 | FNOP | |
2083 | JA AMODXR | |
2084 | 0 | |
2085 | AMDRTN, JA . /EXIT | |
2086 | EXTERN #ARGER | |
2087 | AMODER, TRAP4 #ARGER /PRINT AN ERROR MESSAGE | |
2088 | FCLA /EXIT WITH FAC=0 | |
2089 | JA AMDRTN | |
2090 | BASE 0 /STAY ON CALLER'S BASE PG | |
2091 | /LONG ENOUGH TO GET RETURN ADDRESS | |
2092 | MOD, /START OF INTEGER ROUTINE SAME AS | |
2093 | #AMOD, STARTD /START OF REAL NUM. ROUTINE | |
2094 | FLDA 10*3 /GET RETURN JUMP | |
2095 | FSTA AMDRTN /SAVE IN THIS PROGRAM | |
2096 | FLDA 0 /GET POINTER TO PASSED ARG | |
2097 | SETX XRAMOD /ASSIGN MOD'S INDEX REGS | |
2098 | SETB BPAMOD /AND ITS BASE PAGE | |
2099 | BASE BPAMOD | |
2100 | LDX 1,1 | |
2101 | FSTA BPAMOD | |
2102 | FLDA% BPAMOD,1 /ADDR OF X | |
2103 | FSTA AMODX | |
2104 | FLDA% BPAMOD,1+ /ADDR OF Y | |
2105 | FSTA BPAMOD | |
2106 | STARTF | |
2107 | FLDA% BPAMOD /GET Y | |
2108 | JEQ AMODER /Y=0 IS ERROR | |
2109 | JGT .+3 | |
2110 | FNEG /ABS VALUE | |
2111 | FSTA BPAMOD | |
2112 | FLDA% AMODX /GET X | |
2113 | JGT .+5 | |
2114 | ||
2115 | 2-15 | |
2116 | \f | |
2117 | ||
2118 | ||
2119 | FNEG /ABS VALUE | |
2120 | LDX 0,1 /NOTE SIGN | |
2121 | FSTA AMODX /SAVE IN A TEMPORARY | |
2122 | FDIV BPAMOD /DIVIDE BY Y | |
2123 | JAL AMODER /TOO BIG. | |
2124 | ALN 0 /FIX IT UP NOW. | |
2125 | FNORM | |
2126 | FMUL BPAMOD /MULTIPLY IT. | |
2127 | FNEG /NEGATE IT. | |
2128 | FADD AMODX /AND ADD IN X. | |
2129 | JXN AM,1 /CHECK SIGN | |
2130 | FNEG | |
2131 | AM, JA AMDRTN /DONE | |
2132 | ||
2133 | RTS has its own interrupt skip chain in which all on-line device flags | |
2134 | are checked and serviced. This chain may be extended to handle | |
2135 | special interrupts. The external tag #INT marks the first of three | |
2136 | locations on RTS which have to be modified to effect a JMS to the | |
2137 | user's special interrupt handler. The three locations must be set up | |
2138 | in exactly the same manner as that used to set up #IDLE, #IDLE1, | |
2139 | #IDLE2 as described above. All the same conventions hold. Refer also | |
2140 | to the library subroutines ONQI and ONQB. | |
2141 | ||
2142 | Three pseudo-ops have been added to RALF to help the loader determine | |
2143 | core allocation. Each is a more definitive case of the SECT pseudo-op | |
2144 | and defines a chunk of code, thereby providing more control for the | |
2145 | user. They are: | |
2146 | ||
2147 | SECT8 - section starts at a page boundary | |
2148 | FIELD1 - section starts at a page boundary and is in field 1 | |
2149 | COMMZ - section starts at page 0 of field 1 | |
2150 | ||
2151 | If there is more than one SECT8 section in a module, those sections | |
2152 | are not necessarily loaded in contiguous core. The loader considers | |
2153 | core to be in two chunks - one block in field 0, and all of field 1 | |
2154 | and above. | |
2155 | ||
2156 | If there is more than one COMMZ pseudo-op in a module, they are | |
2157 | stacked one behind the other, but there is no way of specifying which | |
2158 | one starts at absolute location 0 of field 1. COMMZ sections are | |
2159 | allocated by the loader before FIELD1 sections. | |
2160 | ||
2161 | Modules can share a COMMZ section in the same way that FORTRAN COMMON | |
2162 | sections can be shared. FIELD1 sections can also be shared by using | |
2163 | the same FIELD1 section name in each module. | |
2164 | ||
2165 | The first occurrence of a section name defines that section. For | |
2166 | example, | |
2167 | ||
2168 | SECT8 PARTA | |
2169 | . | |
2170 | . | |
2171 | . | |
2172 | SECT8 PARTB | |
2173 | ||
2174 | 2-16 | |
2175 | \f | |
2176 | ||
2177 | ||
2178 | . | |
2179 | . | |
2180 | . | |
2181 | SECT8 PARTA | |
2182 | ||
2183 | The second mention of PARTA in the same module continues the source | |
2184 | where the first mention of PARTA ended at execution time. (There is | |
2185 | a location counter for each section.) | |
2186 | ||
2187 | To save core, a RALF FIELD1 section and FORTRAN COMMON section of the | |
2188 | same name are mapped on top of each other, being allocated the length | |
2189 | of the longer and the same absolute address by the loader. This | |
2190 | feature is useful for initialization (once-only) code, which can | |
2191 | later be overlayed by a data area. Thus, the occurrence of FIELD1 | |
2192 | AREA1 in the RALF module and COMMON AREA1 in the FORTRAN program | |
2193 | causes AREA1 to start the same location (in field 1) and have a length | |
2194 | of at least 200 locations (depending on the length of the RALF FIELD1 | |
2195 | section or of the COMMON section in the FORTRAN). | |
2196 | ||
2197 | If the subroutine is longer than one page and values are to be passed | |
2198 | across page boundaries, the address pseudo-op, ADDR, is required. | |
2199 | The format is: | |
2200 | ||
2201 | AVAR1, ADDR VAR1 | |
2202 | ||
2203 | This generates a two-word reference to the proper location on another | |
2204 | page, here VAR1. For example, to pass a value to VAR1, possible code | |
2205 | is: | |
2206 | ||
2207 | 00124 1244 TAD VAR2 /Value on this page | |
2208 | 00125 3757 DCA% AVAR1+1 /Pass through 12-bit | |
2209 | . /location | |
2210 | 00156 0000 AVAR1,ADDR VAR1 /Field and | |
2211 | 00157 0322 /location of VAR1 | |
2212 | ||
2213 | Any reference to an absolute address can be effected by the ADDR | |
2214 | pseudo-op. | |
2215 | ||
2216 | If it is doubtful that the effective address is in the current data | |
2217 | field, it is necessary to create a CDF instruction to the proper field. | |
2218 | In the above example, suitable code to add to specify the data field | |
2219 | is: | |
2220 | ||
2221 | TAD AVAR1 /Get field bits | |
2222 | RTL /Rotate to bits 6-8 | |
2223 | RAL | |
2224 | TAD (6201 /Add a CDF | |
2225 | DCA .+1 /Deposit in line | |
2226 | 0 /Execute CDFn | |
2227 | ||
2228 | If the subroutine includes an off-page reference to another RALF | |
2229 | module (e.g., in FORLIB), it can be addressed by using an EXTERN | |
2230 | with an ADDR pseudo-op. For example, in the display program, a ref- | |
2231 | erence to the non-interrupt task subroutine ONQB is coded as | |
2232 | ||
2233 | 2-17 | |
2234 | \f | |
2235 | ||
2236 | ||
2237 | EXTERN ONQB | |
2238 | ONQBX, ADDR ONQB | |
2239 | ||
2240 | and is called by | |
2241 | ||
2242 | JMS% ONQBX+1 | |
2243 | ||
2244 | The next instruction in the program is ADDR DISPLY so that DISPLY will | |
2245 | be added to the background list. Execution from ONQB returns after | |
2246 | the ADDR pseudo-op. | |
2247 | ||
2248 | It may be desirable to salvage the first (field) word allocated by | |
2249 | ADDR pseudo-ops. If the address requires only twelve bite for proper | |
2250 | execution, code such as | |
2251 | ||
2252 | TMP, TMP,ADDR X | |
2253 | ARG,ADDR X or ARG= .-1 | |
2254 | ||
2255 | permits TMP to be used for temporary storage because ARG+1 in the left | |
2256 | hand example or just ARG in the right hand example defines the 12-bit | |
2257 | address. | |
2258 | ||
2259 | RALF does not recognize LINC instruction or PDP-8 laboratory device | |
2260 | instructions. Such instructions can be included in the subroutine by | |
2261 | defining them by equate statements in the program. | |
2262 | ||
2263 | For example, adding the statements: | |
2264 | ||
2265 | PDP = 2 | |
2266 | LINC = 6141 | |
2267 | DIS = 140 | |
2268 | ||
2269 | takes care of all instructions for coding the PDP-12 display | |
2270 | subroutine. | |
2271 | ||
2272 | When writing a routine that is going to be longer than a page, it can | |
2273 | be useful to have a non-fixed origin in order not to waste core and to | |
2274 | facilitate modification of the code. A statement such as | |
2275 | ||
2276 | IFPOS .-SECNAM&177-K<ORG .-SECNAM&7600+200+SECNAM> | |
2277 | ||
2278 | will start a new page only if the value [current location less section | |
2279 | name] is greater than some K (start of section has a relative value of | |
2280 | 0) where K<=177 and is the relative location on the current page | |
2281 | before which a new page should be started. The ORG statement includes | |
2282 | an AND mask of 7600 to preserve the current page. When added to 200 | |
2283 | for the next page and the section name, the new origin is set. | |
2284 | ||
2285 | When calculating directly in a module, the following rules apply to | |
2286 | relative and absolute values. | |
2287 | ||
2288 | ||
2289 | ||
2290 | ||
2291 | ||
2292 | 2-18 | |
2293 | \f | |
2294 | ||
2295 | ||
2296 | relative - relative = absolute | |
2297 | absolute + relative = relative | |
2298 | OR (!), AND (&) and ADD (+) of relative symbols | |
2299 | generate the RALF error message RE. | |
2300 | ||
2301 | When passing arguments (single precision) from FPP code to PDP code, | |
2302 | using the index registers is very efficient. For example, | |
2303 | ||
2304 | . | |
2305 | . | |
2306 | . | |
2307 | FLDA% ARG1 /Get argument in FPP mode | |
2308 | SETX MODE8 /Change index registers so XR0 is | |
2309 | /At MODE8 | |
2310 | ATX MODE8 /Save argument | |
2311 | . | |
2312 | . | |
2313 | . | |
2314 | TRAP4 SUB8 /Go to PDP-8 routine | |
2315 | . | |
2316 | . | |
2317 | . | |
2318 | SUB8, 0 /PDP-8 routine | |
2319 | . | |
2320 | . | |
2321 | . | |
2322 | TAD MODE8 /Get argument | |
2323 | . | |
2324 | . | |
2325 | . | |
2326 | MODE8, 0 /Index registers set here | |
2327 | . | |
2328 | . | |
2329 | . | |
2330 | ||
2331 | ||
2332 | ||
2333 | ||
2334 | ||
2335 | ||
2336 | ||
2337 | ||
2338 | ||
2339 | ||
2340 | ||
2341 | ||
2342 | ||
2343 | ||
2344 | ||
2345 | ||
2346 | ||
2347 | ||
2348 | ||
2349 | ||
2350 | ||
2351 | 2-19 | |
2352 | \f | |
2353 | ||
2354 | ||
2355 | CHAPTER 3 | |
2356 | ||
2357 | THE FORTRAN IV LOADER | |
2358 | ||
2359 | ||
2360 | The FORTRAN IV loader accepts a set of (up to 128) RALF modules as | |
2361 | input, and links the modules, along with any necessary library | |
2362 | components, to form a loader image file that may be read into memory | |
2363 | and executed by the run-time system. The main task accomplished by the | |
2364 | loader is program relocation, achieved by replacing the relative | |
2365 | starting address of every section with an absolute core address. | |
2366 | Absolute addresses are also assigned to all entry points, all | |
2367 | relocatable binary text, and the externs. | |
2368 | ||
2369 | The loader executes in three passes. Pass 0 begins by determining how | |
2370 | much memory is available on the running hardware configuration, and | |
2371 | then constructs tables from the OS/8 command decoder input for use by | |
2372 | pass 1 and pass 2. | |
2373 | ||
2374 | Pass 1 reads the relocatable binary input and creates the loader | |
2375 | symbol table. The length of each input module is computed and stored, | |
2376 | along with the relative values of entry points defined within the | |
2377 | input modules. When an undefined symbol is encountered, pass 1 | |
2378 | searches the catalog of the FORTRAN IV library specified to pass 0, | |
2379 | or FORLIB.RL if no other library was explicitly specified, and loads | |
2380 | the library routine corresponding to the undefined symbol. | |
2381 | ||
2382 | Pass 1 also allocates absolute core addresses to all modules and, | |
2383 | through them, to all symbols. Pass 1 execution concludes by computing | |
2384 | the lengths of all overlay levels defined for the current FORTRAN IV | |
2385 | job. Trap vectors are also set up at this time, and the tables | |
2386 | required for pass 2 loading are initialized. | |
2387 | ||
2388 | Pass 2 concludes loader execution by creating a loader image file from | |
2389 | the relocated binary input and symbol values processed by pass 1. | |
2390 | Pass 2 also produces the loader symbol map, if requested, and chains | |
2391 | to the run-time system if /G was specified. | |
2392 | ||
2393 | Pass 0 contains very few subroutines. The routine CORDSW checks for | |
2394 | the presence of /U, /C or /O option specifications, as supplied to the | |
2395 | command decoder, and processes these options if necessary. A routine | |
2396 | called UPDMOD is called when input to each overlay has been concluded, | |
2397 | to update the module counts in the module count table. | |
2398 | ||
2399 | CORMOV is a general core-moving subroutine, called by the instruction | |
2400 | sequence: | |
2401 | ||
2402 | JMS CORMOV | |
2403 | CDF FROMFIELD | |
2404 | FROMADDR - 1 | |
2405 | CDF TOFIELD | |
2406 | TOADDR - 1 | |
2407 | - COUNT | |
2408 | ||
2409 | ||
2410 | 3-1 | |
2411 | \f | |
2412 | ||
2413 | ||
2414 | LOADER PASS 0 (FILE COLLECTION) | |
2415 | ------------------------------ | |
2416 | 00000 | OS/8 Command Decoder | FIELD 0 | |
2417 | | | | |
2418 | | | | |
2419 | |----------------------------| | |
2420 | 02000 | Loader Pass 1 and | | |
2421 | | Pass 2 | | |
2422 | | | | |
2423 | |----------------------------| | |
2424 | 04600 | Core measuring routine | | |
2425 | | and scratch area to | | |
2426 | | save 00000-02000 | | |
2427 | | during CD calls | | |
2428 | |----------------------------| | |
2429 | 06600 | | | |
2430 | | Unused | | |
2431 | | | | |
2432 | |----------------------------| | |
2433 | 07600 | OS/8 Field 0 resident | | |
2434 | |----------------------------| | |
2435 | 10000 | OS/8 User Service Routine | FIELD 1 | |
2436 | | | | |
2437 | | | | |
2438 | |----------------------------| | |
2439 | 12000 | Symbol table, loader map | | |
2440 | | titles | | |
2441 | 12400 | | | |
2442 | |----------------------------| | |
2443 | 13200 | Pass 0 code | | |
2444 | |----------------------------| | |
2445 | 14000 | Pass 1 initialization | | |
2446 | | | | |
2447 | | | | |
2448 | |----------------------------| | |
2449 | 16000 | Module count and | | |
2450 | | module tables | | |
2451 | |----------------------------| | |
2452 | 17000 | Library catalog header | | |
2453 | | read into this block | | |
2454 | |----------------------------| | |
2455 | 17600 | OS/8 Field 1 resident | | |
2456 | ------------------------------ | |
2457 | ||
2458 | while ERROR is the local error processing routine, called with a | |
2459 | pointer to the appropriate error message in the accumulator. | |
2460 | ||
2461 | The major pass 1 and pass 2 subroutines, described below, operate on | |
2462 | the loader internal tables, whose format is presented later in this | |
2463 | chapter. The subroutines are presented in approximately the order | |
2464 | that they occur in the source listing. | |
2465 | ||
2466 | ||
2467 | ||
2468 | ||
2469 | 3-2 | |
2470 | \f | |
2471 | ||
2472 | ||
2473 | LOADER PASS 1 (SYMBOL RESOLUTION) | |
2474 | ------------------------------ | |
2475 | 00000 | Pass 1 and Pass 2 | FIELD 0 | |
2476 | | utility routines | | |
2477 | |----------------------------| | |
2478 | 01400 | Symbol map printer | | |
2479 | |----------------------------| | |
2480 | 02000 | Pass 2 | | |
2481 | |----------------------------| | |
2482 | 03200 | Pass 1 symbol collection | | |
2483 | |----------------------------| | |
2484 | 04000 | Inter-pass code allocates | | |
2485 | | storage, builds and writes | | |
2486 | | Loader Image Header Block. | | |
2487 | |----------------------------| | |
2488 | 04600 | Library catalog loads | | |
2489 | | here in 8K. Unused in | | |
2490 | | 12K or more. | | |
2491 | |----------------------------| | |
2492 | 07200 | Input device handlers | | |
2493 | |----------------------------| | |
2494 | 07600 | OS/8 Field 0 resident | | |
2495 | |----------------------------| | |
2496 | 10000 | ESD table | FIELD 1 | |
2497 | | | | |
2498 | 11400 | | | |
2499 | |----------------------------| | |
2500 | 12000 | Symbol table | | |
2501 | |----------------------------| | |
2502 | 15400 | Overlay length table | | |
2503 | |----------------------------| | |
2504 | 16000 | Module count and module | | |
2505 | | tables (MCTTBL, MODTBL) | | |
2506 | |----------------------------| | |
2507 | 17200 | Loader header | | |
2508 | |----------------------------| | |
2509 | 17400 | ESD reference page | | |
2510 | |----------------------------| | |
2511 | 17600 | OS/8 Field 1 resident | | |
2512 | |----------------------------| | |
2513 | 20000 | Library catalog loads here | FIELD 2 | |
2514 | | in 12K or more. | | |
2515 | |----------------------------| | |
2516 | 25000 | OS/8 BATCH processor if | | |
2517 | | 12K or more and BATCH | | |
2518 | | is running | | |
2519 | ------------------------------ | |
2520 | ||
2521 | ||
2522 | ||
2523 | ||
2524 | ||
2525 | ||
2526 | ||
2527 | ||
2528 | 3-3 | |
2529 | \f | |
2530 | ||
2531 | ||
2532 | LOADER PASS 2 (LOADER IMAGE BUILDER) | |
2533 | ----------------------------------- | |
2534 | 00000 | Utility routines: Symbol table | FIELD 0 | |
2535 | | look-up, TTY message handler, | | |
2536 | | OS/8 block I/O, MCTTBL | | |
2537 | | processor. | | |
2538 | |---------------------------------| | |
2539 | 01400 | Routine to print symbol map. | | |
2540 | |---------------------------------| | |
2541 | 02000 | Pass 2 | | |
2542 | |---------------------------------| | |
2543 | 03200 | Binary buffer #1 | | |
2544 | | | | |
2545 | |---------------------------------| | |
2546 | 05200 | Binary buffer #2 | | |
2547 | | | | |
2548 | |---------------------------------| | |
2549 | 07200 | I/O device handlers | | |
2550 | |---------------------------------| | |
2551 | 07600 | OS/8 Field 0 resident | | |
2552 | |---------------------------------| | |
2553 | 10000 | RALF module text loads | FIELD 1 | |
2554 | | here if 8K. | | |
2555 | |---------------------------------| | |
2556 | 12000 | Symbol table | | |
2557 | | | | |
2558 | |---------------------------------| | |
2559 | 15400 | Overlay length table | | |
2560 | |---------------------------------| | |
2561 | 16000 | MCTTBL and MODTBL | - | |
2562 | |---------------------------------| | | |
2563 | 17200 | Binary section table and | > symbol map | |
2564 | | binary buffer (LDBUFS) table | | output buffer | |
2565 | |---------------------------------| | | |
2566 | 17400 | ESD reference page | - | |
2567 | |---------------------------------| | |
2568 | 17600 | OS/8 Field 1 resident | | |
2569 | |---------------------------------| | |
2570 | 20000 | Binary buffer #3, if >8K | FIELD 2 | |
2571 | |---------------------------------| | |
2572 | 22000 | Binary buffer #4, if >8K | | |
2573 | |---------------------------------| | |
2574 | 24000 | Binary buffer #5, if >12K | | |
2575 | |---------------------------------| | |
2576 | 26000 | Unused | | |
2577 | |---------------------------------| | |
2578 | 30000 | RALF module text loads | FIELD 3 | |
2579 | | here if >12K | | |
2580 | ----------------------------------- | |
2581 | ||
2582 | ||
2583 | ||
2584 | ||
2585 | ||
2586 | ||
2587 | 3-4 | |
2588 | \f | |
2589 | ||
2590 | ||
2591 | SETBPT Sets words BPTR and BPT2 to contain AC and AC+1, | |
2592 | respectively. | |
2593 | ||
2594 | TTYHAN Subroutine to unpack and print a TEXT message on the | |
2595 | console terminal. TTYHAN is called by: | |
2596 | ||
2597 | CDF CURRENT | |
2598 | CIF 0 | |
2599 | JMS TTYHAN | |
2600 | CDF MSGFIELD | |
2601 | MSG | |
2602 | ||
2603 | RTNOS8 Prints a fatal error message and then returns to the | |
2604 | OS/8 monitor. A pointer to the message must follow | |
2605 | the JMS RTNOS8. | |
2606 | ||
2607 | IOHAN Used to execute all I/O under OS/8. The calling | |
2608 | sequence is: | |
2609 | ||
2610 | TAD (ACARG /Optional | |
2611 | CDF CURRENT | |
2612 | CIF 0 | |
2613 | JMS IOHAN | |
2614 | ADDR | |
2615 | ARG1 | |
2616 | ARG2 | |
2617 | ARG3 | |
2618 | ||
2619 | where ARG1, ARG2 and ARG3 are standard OS/8 device | |
2620 | handler arguments and ADDR points to a three-word block | |
2621 | in field 1 which contains the OS/8 unit number in word | |
2622 | 1, the file length in word 2, and the starting block | |
2623 | number in word 3. | |
2624 | ||
2625 | If ACARG is zero, the indicated I/O operation is | |
2626 | executed after the handler has been FETCHed, if | |
2627 | necessary. If ACARG=n (greater than zero), the handler | |
2628 | for OS/8 unit n is FETCHed, no I/O is done, and the | |
2629 | four arguments that conclude the calling sequence are | |
2630 | not needed. | |
2631 | ||
2632 | ADVOVR Called to initialize the loader to accept a new input | |
2633 | module. ADVOVR determines whether a new overlay or | |
2634 | level is being started by accessing the module count | |
2635 | table. If so, it sets various pointers and internal | |
2636 | counters accordingly, rounds the previous overlay to | |
2637 | terminate on a 200 word boundary, and updates the | |
2638 | length of the previous level, if necessary, as the | |
2639 | maximum of its constituent overlay lengths. | |
2640 | ||
2641 | NXTOVR Called by ADVOVR when the next input module will be the | |
2642 | first module in a new overlay. | |
2643 | ||
2644 | ||
2645 | ||
2646 | 3-5 | |
2647 | \f | |
2648 | ||
2649 | ||
2650 | SETCNT Initializes the pointers and counters used by ADVOVR. | |
2651 | SETCNT is called once at the beginning of each pass. | |
2652 | ||
2653 | LOOK Executes a symbol look-up in the loader symbol table. | |
2654 | LOOK is called by: | |
2655 | ||
2656 | TAD (Pointer to symbol name in | |
2657 | RALF ESD format | |
2658 | JMS LOOK | |
2659 | RETURN here if not found | |
2660 | RETURN here if found | |
2661 | GPTR points to word following entry name | |
2662 | ||
2663 | If the symbol is not found, it is inserted into the | |
2664 | loader symbol table and GPTR is set to point to the | |
2665 | word following the symbol name. | |
2666 | ||
2667 | SYMMAP Produces the symbol map. | |
2668 | ||
2669 | PUTSYM Enters an ESD symbol in the loader symbol table. PUTSYM | |
2670 | calls LOOK to determine whether the symbol is already | |
2671 | present in the symbol table and, if so, verifies that | |
2672 | the symbol is not multiply defined. Otherwise, it | |
2673 | copies the ESD data words into the symbol table entry, | |
2674 | updates the length of the current overlay by the length | |
2675 | associated with the symbol, and links the symbol to its | |
2676 | parent symbol, if any. | |
2677 | ||
2678 | FIT Fits a section into core by subtracting its length from | |
2679 | the amount of core still available and substituting its | |
2680 | load address for its length in the symbol table. | |
2681 | ||
2682 | DO8S, FIT8S Fits an 8-mode section into core by calling FIT and | |
2683 | then checking for field 1 overflow. | |
2684 | ||
2685 | SETREF Extracts data from the ESD table of the current module | |
2686 | and initializes the ESD reference page at 17400. | |
2687 | ||
2688 | BLDTV Builds the transfer vector. A transfer vector entry | |
2689 | is created for each subroutine in an overlay. This | |
2690 | entry provides the information that the run-time system | |
2691 | will require in order to load the overlay containing | |
2692 | the referenced subroutine. | |
2693 | ||
2694 | NEWORG Called whenever an origin is found in an input module, | |
2695 | to map the location referenced by the origin into a | |
2696 | block of the loader image file and an address within | |
2697 | that block. | |
2698 | ||
2699 | NEWBB Called whenever a new binary buffer is needed during | |
2700 | loader image file construction. NEWBB scans a list of | |
2701 | available buffers and dumps the content of the least | |
2702 | recently accessed buffer to free up space for new data. | |
2703 | ||
2704 | ||
2705 | 3-6 | |
2706 | \f | |
2707 | ||
2708 | ||
2709 | MERGE Relocates an input word pair and outputs it to the | |
2710 | loader image file. | |
2711 | ||
2712 | GETCTL Gets a control byte from the input module and incre- | |
2713 | ments its return address by the content of the control | |
2714 | byte. | |
2715 | ||
2716 | PUTBIN Inserts words, sequentially, into the current binary | |
2717 | buffer. When the buffer is full, PUTBIN calls NEWBB to | |
2718 | execute output to the loader image file and supply a | |
2719 | new buffer. | |
2720 | ||
2721 | TXTSCN Called once for each input module. TXTSCN reads and | |
2722 | relocates an entire input module, executing calls to | |
2723 | MERGE, PUTBIN and NEWORG as needed. | |
2724 | ||
2725 | ||
2726 | ||
2727 | SYMBOL TABLE | |
2728 | ||
2729 | ||
2730 | ||
2731 | The loader symbol table begins at location 12000 and contains room for | |
2732 | 26 (decimal) permanent system symbol entries and 218 (decimal) user | |
2733 | entries. Each entry is 7 words long, and provides the name and | |
2734 | definition of a symbol. The table is organized in buckets according | |
2735 | to the first character of the symbol, which must be A to Z, #, or | |
2736 | blank (for blank COMMON). The table of bucket pointers begins at | |
2737 | location 12000 with the pointer to bucket A, and consists of one word | |
2738 | per bucket. This word contains a value of zero, if there are no | |
2739 | symbols in the corresponding bucket, or else the address of the first | |
2740 | symbol in the bucket. | |
2741 | ||
2742 | Symbols within a bucket are arranged in alphabetical order, with each | |
2743 | symbol entry pointing to the following entry, and the last entry | |
2744 | pointing to zero. Thus, the symbol table appears as a set of threaded | |
2745 | lists in core. The format of a symbol table entry is: | |
2746 | ||
2747 | ||
2748 | ||
2749 | ||
2750 | ||
2751 | ||
2752 | ||
2753 | ||
2754 | ||
2755 | ||
2756 | ||
2757 | ||
2758 | ||
2759 | ||
2760 | ||
2761 | ||
2762 | ||
2763 | ||
2764 | 3-7 | |
2765 | \f | |
2766 | ||
2767 | ------------------------------ | |
2768 | | Pointer to next symbol in | | |
2769 | | bucket (zero if none). | WORD 1 | |
2770 | |----------------------------| | |
2771 | | S | Y | WORD 2 | |
2772 | |----------------------------| | |
2773 | | M | B | WORD 3 | |
2774 | |----------------------------| | |
2775 | | O | L | | |
2776 | |----------------------------| | |
2777 | | | 3-bit | 4-bit | | | |
2778 | | * | level | overlay | ** | | |
2779 | | | # | # | | | |
2780 | |----------------------------| | |
2781 | | 9-bit pointer to | | | |
2782 | | parent symbol | | | |
2783 | | during pass 1 | | | |
2784 | | (zero if none). | Field | | |
2785 | | Trap vector | bits | | |
2786 | | displacement | | | |
2787 | | during pass 2. | | | |
2788 | |----------------------------| | |
2789 | | ADDRESS | | |
2790 | | (Length during pass 1) | | |
2791 | ------------------------------ | |
2792 | ||
2793 | ||
2794 | * 1-bit trap vector flag during pass 1. Error flag during pass 2. | |
2795 | ||
2796 | ** 4-bit type code | |
2797 | 0- undefined | |
2798 | 1- entry point | |
2799 | 2- extern | |
2800 | 3- common sect | |
2801 | 4- program sect | |
2802 | 5- multiple entry point | |
2803 | 6- multiple sect | |
2804 | 7- SECT8 sect | |
2805 | 10- COMMZ | |
2806 | 11- FIELD1 | |
2807 | 12 to 17- undefined | |
2808 | ||
2809 | Several special symbols are created by the loader. The symbol #YLVLn, | |
2810 | where n is an octal digit, describes overlay level n. This symbol | |
2811 | table entry contains the length of level n during pass 1 and the | |
2812 | starting address of level n during pass 2. | |
2813 | ||
2814 | The symbol #YTRAP describes the trap vector, a method by which the | |
2815 | run-time system controls automatic overlaying of user subroutines. | |
2816 | Four words are allocated in the trap vector for each entry point in | |
2817 | every overlay except overlay #MAIN. The symbol table entry for #YTRAP | |
2818 | contains the accumulated length of the trap vector during pass 1 and | |
2819 | the trap vector starting address during pass 2. | |
2820 | ||
2821 | ||
2822 | ||
2823 | 3-8 | |
2824 | \f | |
2825 | ||
2826 | ||
2827 | ESD CORRESPONDENCE TABLE (ESDPG) | |
2828 | ||
2829 | ||
2830 | ||
2831 | The ESD correspondence table begins at location 17400 and contains 128 | |
2832 | (decimal) 1-word entries. This table establishes the correspondence | |
2833 | between the local ESD reference numbers used to reference a symbol | |
2834 | inside a RALF module, and the address of that symbol in the loader | |
2835 | symbol table. The nth entry in the ESD correspondence table points to | |
2836 | the address of ESD symbol n. | |
2837 | ||
2838 | ||
2839 | ||
2840 | BINARY BUFFER TABLE (LDBUFS) | |
2841 | ||
2842 | ||
2843 | ||
2844 | The binary buffer table begins at location 17247 and contains from two | |
2845 | to ten entries, depending upon the amount of memory available. Each | |
2846 | entry is 4 words in length. The binary buffers function as windows | |
2847 | into the loader image file, through which the loaded program is | |
2848 | written onto mass storage. Each binary buffer is 8 pages (4 OS/8 | |
2849 | blocks) in length. The loader tries to minimize the amount of "window | |
2850 | turning" necessary to buffer the binary data by keeping a record of | |
2851 | the last time each buffer was referenced. In this way, when the | |
2852 | content of a binary buffer must be dumped to make room for new data, | |
2853 | the loader empties that buffer which was least recently used. | |
2854 | ||
2855 | In addition, program loading is overlay oriented such that only one | |
2856 | overlay is loaded at a time and while any specific overlay is being | |
2857 | loaded, only origins inside that overlay are legal. | |
2858 | ||
2859 | The format of a binary buffer table entry is: | |
2860 | ||
2861 | ------------------------------------ | |
2862 | | Pointer to the binary buffer of | | |
2863 | | "next earliest reference", i.e., | | |
2864 | | the youngest buffer older than | WORD 1 | |
2865 | | this buffer. Contains zero if | | |
2866 | | this buffer is oldest. | | |
2867 | |----------------------------------| | |
2868 | | Loader image block #. Contains | | |
2869 | | zero if buffer has not been used.| WORD 2 | |
2870 | |----------------------------------| | |
2871 | | Blocks left in current overlay | | |
2872 | | If <4, only part of buffer will | WORD 3 | |
2873 | | be dumped. | | |
2874 | |----------------------------------| | |
2875 | | Page address | Buffer | | | |
2876 | | of buffer. | field | Unused | WORD 4 | |
2877 | | | bits | | | |
2878 | ------------------------------------ | |
2879 | ||
2880 | ||
2881 | ||
2882 | 3-9 | |
2883 | \f | |
2884 | ||
2885 | ||
2886 | The number of binary buffers used varies with the amount of memory | |
2887 | available as follows: | |
2888 | ||
2889 | ------------------------------------------- | |
2890 | MEMORY | NO. OF | |
2891 | AVAIL | BUFFERS | |
2892 | -------------------|----------------------- | |
2893 | 8K | 2 | |
2894 | 12K | 4 | |
2895 | 16K | 5 | |
2896 | 20K | 7 | |
2897 | 24K | 10 (decimal) | |
2898 | 28K | 10 (decimal) | |
2899 | 32K | 10 (decimal) | |
2900 | ------------------------------------------- | |
2901 | ||
2902 | ||
2903 | ||
2904 | BINARY SECTION TABLE | |
2905 | ||
2906 | ||
2907 | ||
2908 | The binary section table overlays the loader image header block | |
2909 | (described under FRTS) after the latter has been written into the | |
2910 | loader image file at the beginning of pass 2. Thus, the binary | |
2911 | section table begins at location 17200 and contains eight 4-word | |
2912 | entries. Each entry relates the core origin of one of the eight | |
2913 | overlay levels to that level's position in the loader image file. | |
2914 | The format of a binary section table entry is: | |
2915 | ||
2916 | ----------------------------------- | |
2917 | | | Field | | |
2918 | | Unused | of | WORD 1 | |
2919 | | | level | | |
2920 | |---------------------------------| | |
2921 | | Address of level | WORD 2 | |
2922 | |---------------------------------| | |
2923 | | Relative block # | WORD 3 | |
2924 | |---------------------------------| | |
2925 | | Length (in blocks) | WORD 4 | |
2926 | ----------------------------------- | |
2927 | ||
2928 | ||
2929 | OVERLAY TABLE (OVLTBL) | |
2930 | ||
2931 | ||
2932 | The overlay table begins at location 15435 and contains room for 113 | |
2933 | (decimal) 2-word entries. There is one entry for each overlay | |
2934 | defined, including overlay MAIN, with each entry designating the | |
2935 | length in words, of the corresponding overlay. The format of an | |
2936 | overlay table entry is: | |
2937 | ||
2938 | ||
2939 | ||
2940 | ||
2941 | 3-10 | |
2942 | \f | |
2943 | ||
2944 | ||
2945 | OVLTBL | |
2946 | ----------------------- | |
2947 | | LEVEL MAIN | | |
2948 | |---------------------| Negated to indicate | |
2949 | | LEVEL 1 OVERLAY 1 | last table entry | |
2950 | |--------/\/----------| / | |
2951 | . - / | |
2952 | . | ------------------- / | |
2953 | . | | HIGH-order bits |/ | |
2954 | |--------/\/----------| | | of length | WORD 1 | |
2955 | | LEVEL m OVERLAY n-1 |>----< |-----------------| | |
2956 | |---------------------| | | LOW-order bits | | |
2957 | | LEVEL m OVERLAY n | | | of length | WORD 2 | |
2958 | |---------------------| | ------------------- | |
2959 | | OVLTBL format | - individual entry (2 words) | |
2960 | ----------------------- | |
2961 | ||
2962 | ||
2963 | ||
2964 | MODULE DESCRIPTOR TABLE (MODTBL) | |
2965 | ||
2966 | ||
2967 | ||
2968 | The module descriptor table begins at location 16172 and contains | |
2969 | room for 172 (decimal) 3-word entries. Each entry provides the | |
2970 | information needed to locate an input module. The first MODTBL entry | |
2971 | corresponds to the library file to be used in building the current | |
2972 | loader image. Successive entries correspond to input modules and | |
2973 | appear in the order that the modules were specified by the user, | |
2974 | (i.e., in ascending order by level, and ascending by overlay within | |
2975 | any given level.) At the end of pass 1, entries corresponding to | |
2976 | individual library modules are appended to the end of the table, even | |
2977 | though the library modules load into level MAIN. The table format is: | |
2978 | ||
2979 | ||
2980 | MODTBL | |
2981 | -------------------------------- | |
2982 | | FORLIB.RL or user- | | |
2983 | | specified library | - | |
2984 | |------------------------------| | -------------------------- | |
2985 | | Level MAIN module #1 | | | OS/8 I/O unit # | | |
2986 | |------------------------------| | |------------------------| | |
2987 | | Level MAIN module #2 | < | File length (positive) | | |
2988 | |------------------------------| | |------------------------| | |
2989 | | Level MAIN module #3 | | | Starting block # | | |
2990 | |----/\/----------------\/\----| | -------------------------- | |
2991 | - | |
2992 | |----/\/----------------\/\----| | |
2993 | | Level MAIN module n | MODTBL format of | |
2994 | |------------------------------| individual entry (3 words) | |
2995 | | Level 1 Overlay 1 module #1 | | |
2996 | |------------------------------| | |
2997 | | Level 1 Overlay 1 module #2 | | |
2998 | |----/\/----------------\/\----| | |
2999 | ||
3000 | 3-11 | |
3001 | \f | |
3002 | ||
3003 | ||
3004 | |----/\/----------------\/\----| | |
3005 | | Level 1 Overlay 1 module #n | | |
3006 | |------------------------------| | |
3007 | | Level 1 Overlay 2 module #1 | | |
3008 | |----/\/----------------\/\----| | |
3009 | . | |
3010 | . | |
3011 | . | |
3012 | |----/\/----------------\/\----| | |
3013 | | Level m Overlay n module #p | | |
3014 | |------------------------------| | |
3015 | | Library module #1 | | |
3016 | |------------------------------| | |
3017 | | Library module #2 | | |
3018 | |----/\/----------------\/\----| | |
3019 | ||
3020 | MODTBL format | |
3021 | ||
3022 | ||
3023 | ||
3024 | MODULE COUNT TABLE (MCTTBL) | |
3025 | ||
3026 | ||
3027 | ||
3028 | The module count table begins at location 16000 and contains room for | |
3029 | 122 (decimal) 1-word entries that give the (two's complement) module | |
3030 | count for each overlay level. The table format is: | |
3031 | ||
3032 | ||
3033 | MCTTBL | |
3034 | ------------------------- | |
3035 | | LEVEL MAIN | 1-word ENTRIES | |
3036 | |-----------------------| | |
3037 | | 0 | | |
3038 | |-----------------------| | |
3039 | | LEVEL 1 OVERLAY 1 | | |
3040 | |-----------------------| | |
3041 | | LEVEL 1 OVERLAY 2 | | |
3042 | |-----------------------| | |
3043 | | LEVEL 1 OVERLAY 3 | | |
3044 | |----/\/---------\/\----| | |
3045 | ||
3046 | |----/\/---------\/\----| | |
3047 | | LEVEL 1 OVERLAY n | | |
3048 | |-----------------------| | |
3049 | | 0 | | |
3050 | |-----------------------| | |
3051 | | LEVEL 2 OVERLAY 1 | | |
3052 | |-----------------------| | |
3053 | | LEVEL 2 OVERLAY 2 | | |
3054 | |----/\/---------\/\----| | |
3055 | ||
3056 | ||
3057 | ||
3058 | ||
3059 | 3-12 | |
3060 | \f | |
3061 | ||
3062 | ||
3063 | ||
3064 | |----/\/---------\/\----| | |
3065 | | LEVEL 2 OVERLAY n | | |
3066 | |-----------------------| | |
3067 | | 0 | | |
3068 | |-----------------------| | |
3069 | | LEVEL 3 OVERLAY 1 | | |
3070 | |----/\/---------\/\----| | |
3071 | . | |
3072 | . | |
3073 | . | |
3074 | |----/\/---------\/\----| | |
3075 | | LEVEL m OVERLAY n | | |
3076 | |-----------------------| | |
3077 | | 0 | | |
3078 | |-----------------------| | |
3079 | | 0 | | |
3080 | ------------------------- | |
3081 | ||
3082 | If an overlay or level is not defined for a specific program, there is | |
3083 | no module count table entry corresponding to that overlay or level. | |
3084 | ||
3085 | The loader image file, produced by the loader and read as input by the | |
3086 | run-time system, consists of a header block followed by a binary image | |
3087 | of each level defined in the FORTRAN IV job. | |
3088 | ||
3089 | ----------------------------------- ----------- | |
3090 | | HEADER | LEVEL | LEVEL / / LEVEL | | |
3091 | | BLOCK | MAIN | 1 \ \ n | | |
3092 | | | | / / | | |
3093 | ---------------------------------- ------------ | |
3094 | ||
3095 | ||
3096 | The loader image file header block contains information in the | |
3097 | following format: | |
3098 | ||
3099 | LOCATION CONTENTS | |
3100 | 0 2 -- Identifies the file as a loader image file. | |
3101 | 1-2 Initial SWAP arguments to load level MAIN. | |
3102 | 3-4 Highest address used by core load, including overlays | |
3103 | but not including OS/8 device handlers. | |
3104 | 5 Loader version number. | |
3105 | 6 Double-precision flag. | |
3106 | 7-46 User overlay information table containing one 4-word | |
3107 | entry per overlay level (the level MAIN entry is | |
3108 | ignored) in the following format: | |
3109 | ||
3110 | ||
3111 | ||
3112 | ||
3113 | ||
3114 | ||
3115 | ||
3116 | ||
3117 | ||
3118 | 3-13 | |
3119 | \f | |
3120 | ||
3121 | ||
3122 | --------------------------------------- | |
3123 | | Unused until SWAP time. Must | WORD 1 | |
3124 | | be positive or zero. | | |
3125 | |-------------------------------------| | |
3126 | Load | Page | Bits 4-5 | Field | Bits 9-11 | WORD 2 | |
3127 | address ---> | bits | unused | bits | unused | | |
3128 | |-------------------------------------| | |
3129 | | Block number of this level, | WORD 3 | |
3130 | | relative to header block. | | |
3131 | |-------------------------------------| | |
3132 | | Length of overlays in this level, | WORD 4 | |
3133 | | in blocks. | | |
3134 | --------------------------------------- | |
3135 | ||
3136 | ||
3137 | ||
3138 | ||
3139 | ||
3140 | ||
3141 | ||
3142 | ||
3143 | ||
3144 | ||
3145 | ||
3146 | ||
3147 | ||
3148 | ||
3149 | ||
3150 | ||
3151 | ||
3152 | ||
3153 | ||
3154 | ||
3155 | ||
3156 | ||
3157 | ||
3158 | ||
3159 | ||
3160 | ||
3161 | ||
3162 | ||
3163 | ||
3164 | ||
3165 | ||
3166 | ||
3167 | ||
3168 | ||
3169 | ||
3170 | ||
3171 | ||
3172 | ||
3173 | ||
3174 | ||
3175 | ||
3176 | ||
3177 | 3-14 | |
3178 | \f | |
3179 | ||
3180 | ||
3181 | CHAPTER 4 | |
3182 | ||
3183 | THE FORTRAN IV RUN-TIME SYSTEM | |
3184 | ||
3185 | ||
3186 | The FORTRAN IV run-time system supervises execution of a FORTRAN job | |
3187 | and provides an I/O interface between the running program and the OS/8 | |
3188 | operating system. FRTS includes its own loader, which should not be | |
3189 | confused with LOAD, the system loader. It executes with only one | |
3190 | overlay, used to restore the resident monitor and effect program | |
3191 | termination. The run-time system was designed to permit convenient | |
3192 | modification or enhancement, and it is well documented in the assembly | |
3193 | language source, available from the Software Distribution Center, | |
3194 | which includes extensive comments. | |
3195 | ||
3196 | One of the most valuable modifications to FRTS provides for the | |
3197 | inclusion of background (or idle) jobs. When FORTRAN is waiting for | |
3198 | I/O operations or the FPP to complete execution, the PDP-8 or PDP-12 | |
3199 | processor is sitting in an idle loop. An idle job may be executed by | |
3200 | the PDP-8 or PDP-12 CPU during this time, perhaps for the purpose of | |
3201 | refreshing a CRT display, for example, or monitoring a controlled | |
3202 | process. To indicate such a job, the idle wait loop must be modified | |
3203 | to include a reference to the user's PDP-8 routine. The routine #IDLE | |
3204 | in FRTS must be changed as part of the user's subroutine from | |
3205 | ||
3206 | #IDLE, JMP .+4 to #IDLE, SKP | |
3207 | 0 ADDUSR | |
3208 | CDF CIF FLDUSR | |
3209 | JMS I .-2 JMS I .-2 | |
3210 | ||
3211 | Devices issuing interrupts may be added to the interrupt skip chain so | |
3212 | that FORTRAN checks the user's device as well as system devices. The | |
3213 | original code is: | |
3214 | ||
3215 | #INT, JMP .+4 | |
3216 | 0 | |
3217 | CDF CIF | |
3218 | JMS I .-2 | |
3219 | ||
3220 | ||
3221 | and must be changed, as above, to: | |
3222 | ||
3223 | #INT, SKP | |
3224 | ADDUSR | |
3225 | FLDUSR | |
3226 | JMS I .-2 | |
3227 | ||
3228 | In both cases, ADDUSR should be the address of the user's routine, and | |
3229 | FLDUSR should be the memory field of the user's routine. | |
3230 | ||
3231 | The idle job is initiated by the subroutine HANG in the run-time | |
3232 | system. Hang should only be called when the FORTRAN program must wait | |
3233 | for an I/O device flag. The calling sequence is: | |
3234 | ||
3235 | ||
3236 | 4-1 | |
3237 | \f | |
3238 | ||
3239 | ||
3240 | EXTERN #HANG | |
3241 | IOF /Important. | |
3242 | CDF n /Where n is current field. | |
3243 | CIF 0 | |
3244 | JMS% HANG+1 | |
3245 | ADDRSS | |
3246 | /Return here with interrupts OFF | |
3247 | /When device flag is raised. | |
3248 | ||
3249 | HANG, ADDR #HANG | |
3250 | ||
3251 | The word ADDRSS must point to a location in page 400 of the run-time | |
3252 | system which must normally contain a JMP DISMIS. Three such locations | |
3253 | have been provided for the user at #DISMS, #DISMS+1, and #DISMS+2. The | |
3254 | selected location must be the location via which the interrupt caused | |
3255 | by the desired flag is dismissed. No two flag routines should use the | |
3256 | same dismiss location. The following program example illustrates | |
3257 | these calling conventions. This routine may be used to drive a | |
3258 | Teletype terminal via the PT08 option. | |
3259 | ||
3260 | EXTERN #ONQI | |
3261 | EXTERN #DISMS | |
3262 | FIELD1 GETCH /JMS GETCH GETS A CHAR | |
3263 | 0 /GETCH RUNS IN FIELD I ONLY | |
3264 | ISZ FIRST | |
3265 | JMP NOTFST | |
3266 | JMS% ONQI+1 | |
3267 | KSF1 | |
3268 | ADDR KSFSUB | |
3269 | TAD DISMIS+1 /SET UP TO CALL HANG | |
3270 | DCA HNGLOC | |
3271 | NOTFST, IOF | |
3272 | TAD INCHR | |
3273 | SZA CLA | |
3274 | JMP GOT1 | |
3275 | CIF 0 | |
3276 | JMS% HANG+1 /NO CHAR READY: HANG | |
3277 | HNGLOC, 0 | |
3278 | /HANG RETURNS W/ IOF | |
3279 | GOT1, TAD INCHR | |
3280 | DCA FIRST | |
3281 | DCA INCHR | |
3282 | TAD FIRST | |
3283 | ION | |
3284 | JMP% GETCH | |
3285 | /INTERRUPT ROUTINE - | |
3286 | KSFSUB, 0 /CALLED AS SUBROUTINE | |
3287 | KRB1 | |
3288 | DCA INCHR | |
3289 | CDF CIF 0 | |
3290 | JMP% DISMIS+1 /RETURN TO SYSTEM LOCATION | |
3291 | /CONTAINING "JMP DISMIS" | |
3292 | INCHR, 0 | |
3293 | ONQI, ADDR #ONQI | |
3294 | ||
3295 | 4-2 | |
3296 | \f | |
3297 | ||
3298 | ||
3299 | HANG, ADDR #HANG | |
3300 | DISMIS, ADDR #DISMS | |
3301 | FIRST, -1 | |
3302 | ||
3303 | In most cases, it is easier to include references to the FORLIB module | |
3304 | ONQI for adding a handler to the interrupt skip chain and ONQB for | |
3305 | adding a job to the idle chain, instead of trying to modify #IDLE and | |
3306 | #INT. ONQB provides slots for up to 9 idle jobs to be executed | |
3307 | round-robin, and ONQI provides for up to 9 user flags to be tested on | |
3308 | program interrupts. | |
3309 | ||
3310 | FRTS entry points are listed, along with the core map, on the | |
3311 | following pages. The FRTS calling sequence must be observed in any | |
3312 | user subroutine. The formal calling sequence is illustrated below. In | |
3313 | general, it can be used exactly as illustrated, changing only the | |
3314 | section, entry, base page, index register and return location names. | |
3315 | ||
3316 | ||
3317 | ||
3318 | FRTS CALLING SEQUENCE | |
3319 | ||
3320 | ||
3321 | ||
3322 | SECT EXAMPL /Section name. Your module may | |
3323 | /require another section pseudo-op | |
3324 | /such as FIELD1 or SECT8. | |
3325 | JA #EXSRT /Jump to start of subroutine | |
3326 | /Use # for first character | |
3327 | TEXT +EXAMPL+ /6 character section name for | |
3328 | /error traceback (optional) | |
3329 | EXAMXR, SETX XREXAM /Set up index registers | |
3330 | /for this subroutine | |
3331 | SETB BPEXAM /and its base page. | |
3332 | BPEXAM, F 0.0 /Base page | |
3333 | XREXAM, F 0.0 /Index registers 0-2 | |
3334 | F 0.0 /Index registers 3-5 (optional) | |
3335 | EXTMP1, F 0.0 /Space between index registers | |
3336 | EXTMP2, F 0.0 /and the ORG for temporary | |
3337 | EXTMP3, F 0.0 /storage (optional) | |
3338 | ORG 10*3+BPEXAM /Location 30 of base page | |
3339 | FNOP /Force a two-word instruction | |
3340 | JA EXAMXR /Jump to base page for | |
3341 | /return to calling program | |
3342 | 0 /Force a two-word instruction | |
3343 | EXMRTN, JA . /Will be replaced by return jump | |
3344 | BASE 0 /Caller's base page | |
3345 | #EXSRT, STARTD /Start of subroutine | |
3346 | FLDA 10*3 /Get return jump from caller's | |
3347 | /base page | |
3348 | FSTA EXMRTN /Save in return location for | |
3349 | /this routine | |
3350 | FLDA 0 /Location 0 of caller's routine | |
3351 | /is a pointer to the argument list | |
3352 | SETX XREXAM /Change to EXAMPL's index registers | |
3353 | ||
3354 | 4-3 | |
3355 | \f | |
3356 | ||
3357 | ||
3358 | SETB BPEXAM /Change to EXAMPL's base page | |
3359 | BASE BPEXAM | |
3360 | FSTA BPEXAM /Save the pointer | |
3361 | LDX 1,1 /Set up index register 1 | |
3362 | FLDA% BPEXAM, 1 /Get address of argument list | |
3363 | FSTA EXTMP1 /Save the addresses | |
3364 | FLDA% BPEXAM, 1+ /of all passed arguments | |
3365 | FSTA EXTMP2 | |
3366 | FLDA% BPEXAM, 1+ | |
3367 | FSTA EXTMP3 /Continue for all arguments | |
3368 | . /to be picked up | |
3369 | . | |
3370 | . | |
3371 | STARTF /Start three-word instructions | |
3372 | FLDA% EXTMP1 | |
3373 | . | |
3374 | . | |
3375 | . | |
3376 | FLDA% EXTMP2 | |
3377 | . | |
3378 | . | |
3379 | . /Continue to get arguments | |
3380 | . /as required in routine | |
3381 | JA EXMRTN /Exit when done | |
3382 | ||
3383 | ||
3384 | ||
3385 | RTS ENTRY POINT USEAGE AND COMMENTS | |
3386 | ||
3387 | #UE TRAP3 #UE /Produces USER ERROR error message. | |
3388 | ||
3389 | #ARGER or TRAP4 #ARGER /Produces BAD ARG error message. | |
3390 | #ARGERR | |
3391 | ||
3392 | #READO TRAP3 #READO /Initializes | |
3393 | JA UNITNO /formatted | |
3394 | JA FORMAT /read operation. | |
3395 | ||
3396 | #WRITO TRAP3 #WRITO /Initializes | |
3397 | JA UNITNO /formatted | |
3398 | JA FORMAT /write operation. | |
3399 | ||
3400 | #RUO TRAP3 #RUO /Initializes unformatted | |
3401 | JA UNITNO /read operation. | |
3402 | ||
3403 | #WUO TRAP3 #WUO /Initializes unformatted | |
3404 | JA UNITNO /write operation. | |
3405 | ||
3406 | #RDAO TRAP3 #RDAO /Initializes | |
3407 | JA UNITNO /direct access | |
3408 | JA RECNO /read operation. | |
3409 | ||
3410 | ||
3411 | ||
3412 | ||
3413 | 4-4 | |
3414 | \f | |
3415 | ||
3416 | ||
3417 | #WDAO TRAP3 #WDAO /Initializes | |
3418 | JA UNITNO /direct access | |
3419 | JA RECNO /write operation. | |
3420 | ||
3421 | #RFSV TRAP3 #RFSV /Passes a variable to or from the read/ | |
3422 | /write processors via the floating AC. | |
3423 | ||
3424 | #RENDO TRAP3 #RENDO /Terminates a read/write operation. | |
3425 | ||
3426 | #ENDF FLDA UNITNO /Executes an | |
3427 | TRAP3 #ENDF /end file, | |
3428 | #REW or TRAP3 #REW /rewind, | |
3429 | #BAK or TRAP3 #BAK /backspace (depending upon the entry used) | |
3430 | /on the referenced I/O unit. | |
3431 | ||
3432 | #DEF TRAP3 #DEF /Opens a file | |
3433 | JA UNITNO /for direct access I/O. | |
3434 | JA RECORDS | |
3435 | JA FPNPR /(FPP numbers per record) | |
3436 | JA VARIABLE /Refer to DEFINE FILE statement | |
3437 | ||
3438 | #EXIT JSR #EXIT /Terminates current FORTRAN IV job. | |
3439 | ||
3440 | #SWAP TRAP3 #SWAP /Reads overlay OVLY into level LVL and | |
3441 | ADDR /jumps to ADR. ADDR is given by: | |
3442 | /ADDR=4000000*OVLY+100000*LVL+ADR | |
3443 | ||
3444 | #8OR12 /=00000001 if the CPU is a PDP-12. | |
3445 | ||
3446 | #IDLE Address of background job, used by ONQB. Contains: | |
3447 | ||
3448 | JMP I (NULJOB /Replace by SKP | |
3449 | 0 /Replace by addr of background job | |
3450 | CDF CIF 0 /Replace by field of background job | |
3451 | JMS I .-2 | |
3452 | JMP .-4 | |
3453 | ||
3454 | ||
3455 | ||
3456 | CORE LAYOUT OF FRTS | |
3457 | ||
3458 | NON-FPP FPP (Same as non-FPP | |
3459 | unless indicated) | |
3460 | ----------------------------------- | |
3461 | 0000 | Page zero (0120-0134 free) | | |
3462 | |---------------------------------| | |
3463 | 0200 | Most entry points, character | | |
3464 | | I/O handlers, interrupt | | |
3465 | | service, and HANG routine | | |
3466 | |---------------------------------| | |
3467 | 0600 | Format decoder; A, H, and ' | | |
3468 | | format processors, and EXIT | | |
3469 | |------\/\---------------/\/------| | |
3470 | ||
3471 | ||
3472 | 4-5 | |
3473 | \f | |
3474 | ||
3475 | ||
3476 | |------\/\---------------/\/------| | |
3477 | 1400 | REWIND, ENDFILE, BACKSPACE and | | |
3478 | | general unit initialization | | |
3479 | | DATABL table (3wds/unit) | | |
3480 | |---------------------------------| | |
3481 | 2000 | I, E, F and G output | | |
3482 | |---------------------------------| | |
3483 | 2400 | I, E, F and G input | | |
3484 | |---------------------------------| | |
3485 | 2600 | X, L and T formats and | | |
3486 | | GETHND routine | | |
3487 | |---------------------------------| | |
3488 | 3000 | Char in and char out routines | | |
3489 | | including OS/8 packing, editing | | |
3490 | | and forms control | | |
3491 | |---------------------------------| | |
3492 | 3400 | Binary and D. A. I/O, and | | |
3493 | | DEFINE FILE processor | | |
3494 | |---------------------------------| | |
3495 | 3600 | Overlay loader | | |
3496 | |---------------------------------| | |
3497 | 4000 | Input line buffer, overlay | | |
3498 | | and DSRN tables, FORMAT | | |
3499 | | parenth pushdown list, /P | | |
3500 | | processor and init flag clear | | |
3501 | |---------------------------------| | |
3502 | 4400 | Floating-point utilities (shift,| | |
3503 | | add, etc.) used even w/FPP | | |
3504 | |---------------------------------| | |
3505 | 4600 | Error routine and messages | | |
3506 | |---------------------------------| | |
3507 | 5200 | OS/8 handler area and part of | | |
3508 | | FRTS loader initialization | | |
3509 | |---------------------------------|----------------------------- | |
3510 | 5600 | FPP simulator | FPP start-up and trap | | |
3511 | | | routines | | |
3512 | | |----------------------------| | |
3513 | 6000 | | B and D format I/O | | |
3514 | |---------------------------------|----------------------------| | |
3515 | 6600 | Floating-point package and | Floating-point package | | |
3516 | | part of LPT ring buffer | (never used) and part of | | |
3517 | | | LPT ring buffer | | |
3518 | |---------------------------------|----------------------------- | |
3519 | 7400 | Most of LPT ring buffer | | |
3520 | |---------------------------------| | |
3521 | 7600 | OS/8 handler and field | | |
3522 | | 0 resident | | |
3523 | |---------------------------------| | |
3524 | 10000 | OS/8 User Service Routine | | |
3525 | |---------------------------------| | |
3526 | 12000 | FRTS loader tables, IONTBL | Locations 12000 to 17400 are | |
3527 | | | overlayed at execution time | |
3528 | |------\/\---------------/\/------| | |
3529 | ||
3530 | ||
3531 | 4-6 | |
3532 | \f | |
3533 | ||
3534 | ||
3535 | |------\/\---------------/\/------| | |
3536 | 12200 | FRTS loader: main flow | | |
3537 | |---------------------------------| | |
3538 | 12400 | program start-up (1) | | |
3539 | |---------------------------------| | |
3540 | 12600 | initialize and | | |
3541 | | configure system | | |
3542 | |---------------------------------| | |
3543 | 13000 | Load OS/8 handlers and assign | | |
3544 | | unit numbers to OS/8 files | | |
3545 | |---------------------------------| | |
3546 | 13400 | Utility and error routines, | | |
3547 | | error messages | | |
3548 | 14000 | | | |
3549 | |---------------------------------| | |
3550 | 15600 | FPP start-up and trap routines | Locations 14000 to 16777 are | |
3551 | |---------------------------------| used to save lower field 0 | |
3552 | 16000 | B and D format I/O | during loading of device | |
3553 | |---------------------------------| handlers and file | |
3554 | 16600 | EAE Floating-point package | specifications | |
3555 | |---------------------------------| | |
3556 | 17400 | Termination routine | Locations 17400 to 17777 are | |
3557 | |---------------------------------| written on SYS block 37 | |
3558 | 17600 | OS/8 field 1 resident | before program load and | |
3559 | |---------------------------------| restored on termination | |
3560 | ||
3561 | ||
3562 | ||
3563 | ||
3564 | ||
3565 | #INT /Address of user interrupt location, used by ONQI: | |
3566 | ||
3567 | JMP .+4 /Replace with SKP | |
3568 | 0 /Replace with address of interrupt | |
3569 | processor | |
3570 | CDF CIF 0 /Replace with field of interrupt | |
3571 | processor | |
3572 | JMS I .-2 | |
3573 | ||
3574 | #DISMS /Addresses first of three JMP DISMIS instructions | |
3575 | for use by specialized I/O routines. | |
3576 | ||
3577 | #HANG /Addresses I/O dismiss routine. | |
3578 | ||
3579 | #RETRN /Provides return from TRAP3. | |
3580 | ||
3581 | ||
3582 | ||
3583 | ||
3584 | ------------------------ | |
3585 | (1) Program start-up moves OS/8 handler to top of core, writes field | |
3586 | 1 resident onto SYS, and termination routine goes to FRTS to load | |
3587 | program. | |
3588 | ||
3589 | ||
3590 | 4-7 | |
3591 | \f | |
3592 | ||
3593 | ||
3594 | DSRN TABLE | |
3595 | ||
3596 | ||
3597 | ||
3598 | The DSRN table controls files and I/O devices used under OS/8 FORTRAN | |
3599 | IV ASCII, binary and direct access I/O operations, including | |
3600 | BACKSPACE, REWIND, and END FILE operations. The exact meaning of the | |
3601 | initials DSRN is one of the great, unanswered questions of FORTRAN IV | |
3602 | development and, as such, has considerable historical interest. The | |
3603 | DSRN table provides room for 9 entries; each entry is 9 words in | |
3604 | length, and contains the following data: | |
3605 | ||
3606 | WORD 1: (HAND) Handler entry point. If this value is positive, the | |
3607 | I/O device handler is a FORTRAN internal (character-oriented) | |
3608 | handler, and the remainder of the DSRN table entry is | |
3609 | ignored. If the value is negative, the handler is an OS/8 | |
3610 | device handler whose entry point is the two's complement of | |
3611 | the value. Entry points always fall in the range [7607, | |
3612 | 7777] for resident handlers or [5200, 5377] for non-resident | |
3613 | handlers. Space for non-resident handlers is allocated | |
3614 | downward from the top of memory, and the handlers are moved | |
3615 | into locations 5200 to 5577 before being called. | |
3616 | ||
3617 | WORD 2: (HCODEW) Handler code word. Bits 0-4 of this word specify | |
3618 | the page into which the device handler was loaded, while bits | |
3619 | 6-8 specify the memory field. If all of bits 0-8 are zero, | |
3620 | the handler is permanently resident. When any of these bits | |
3621 | are non-zero, the data is used to determine which handler, if | |
3622 | any, currently occupies locations 5200-5577. This eliminates | |
3623 | unnecessarily moving the content of memory. Bit 10 is set if | |
3624 | forms control has been inhibited on the I/O unit. Bit 11 is | |
3625 | set if the device handler can execute with the interrupt | |
3626 | system enabled. The data in bits 10 and 11 is obtained from | |
3627 | the IOWTBL table in the FRTS loader. | |
3628 | ||
3629 | WORD 3: (BADFLD) Buffer address and field. Bits 0-4 address the | |
3630 | memory page at which the I/O buffer for this unit begins, | |
3631 | while bits 6-8 specify the memory field. Unlike the FORTRAN | |
3632 | internal I/O unit buffers, OS/8 device handler buffers always | |
3633 | occupy two full pages of memory. Buffer space is allocated | |
3634 | upward from the top of the FORTRAN program. | |
3635 | ||
3636 | WORD 4: (CHRPTR) Character pointer. | |
3637 | ||
3638 | WORD 5: (CHRCTR) Character counter. Words 4 and 5 of each DSRN table | |
3639 | entry define the current character/position in the I/O buffer | |
3640 | as follows: | |
3641 | ||
3642 | ||
3643 | ||
3644 | ||
3645 | ||
3646 | ||
3647 | ||
3648 | ||
3649 | 4-8 | |
3650 | \f | |
3651 | ||
3652 | ||
3653 | Value of Character Next value Next value Special | |
3654 | CHRCTR position of CHRCTR of CHRPTR Conditions | |
3655 | ---------------------------------------------------------------------- | |
3656 | | Bits 4-11 of word | | | Refresh buffer if | |
3657 | -3 | addressed by | -2 | CHRPTR + 1 | input operation and | |
3658 | | CHRPTR | | | CHRPTR mod 256=0 | |
3659 | | | | | | |
3660 | -2 | " | -1 | " | none | |
3661 | | | | | | |
3662 | -1 | Bits 0-3 of words | | | | |
3663 | | addressed by | | | Dump buffer if | |
3664 | | CHRPTR-2 and | -3 | CHRPTR | output operation | |
3665 | | CHRPTR-1 | | | and CHRPTR mod | |
3666 | | | | | 256=0 | |
3667 | | | | | | |
3668 | ---------------------------------------------------------------------- | |
3669 | ||
3670 | ||
3671 | WORD 6: (STBLK) Starting block of file. | |
3672 | ||
3673 | WORD 7: (RELBLIC) Current relative block of file. That is, block to | |
3674 | be accessed next. | |
3675 | ||
3676 | WORD 8: (TOTBLK) Length of file in blocks. | |
3677 | ||
3678 | WORD 9: (FFLAGS) Status flags: | |
3679 | ||
3680 | Bit 0 - Has been written flag. Set to 1 if unit has | |
3681 | received output since last REWIND. | |
3682 | ||
3683 | Bit 1 - Formatted I/O flag. Set to 1 if an ASCII I/O | |
3684 | operation has occurred since last REWIND. | |
3685 | ||
3686 | Bit 2 - Unformatted I/O flag. Set to 1 if a binary or | |
3687 | direct access I/O operation has occurred since last | |
3688 | REWIND. Bits 1 and 2 are never set simultaneously. | |
3689 | ||
3690 | Bit 11- END FILEd flag. Set to 1 if unit has been END | |
3691 | FILEd. Bit 11 is not cleared by a REWIND. | |
3692 | ||
3693 | When any active unit is selected for an I/O operation, the DSRN table | |
3694 | entry for that unit is moved into 9 words on page 0. These 9 words | |
3695 | are tagged with the labels cited above. Upon completion of the I/O | |
3696 | operation, the 9 words are moved from page 0 back into the DSRN table. | |
3697 | ||
3698 | ||
3699 | ||
3700 | ||
3701 | ||
3702 | ||
3703 | ||
3704 | ||
3705 | ||
3706 | ||
3707 | ||
3708 | 4-9 | |
3709 | \f | |
3710 | ||
3711 | ||
3712 | /FORTRAN 4 RUNTIME SYSTEM - R.L PAL8-V8 PAGE 3 | |
3713 | ||
3714 | /PAGE ZERO FOR FORTRAN IV RTS | |
3715 | ||
3716 | 0000 *0 /INTERRUPT STUFF | |
3717 | 00000 0000 0 | |
3718 | 00001 5402 JMP I .+1 | |
3719 | 00002 0400 INTRPT | |
3720 | 00003 5165 LPGET, LPBUFR /LINE PRINTER RING BUFFER FETCH | |
3721 | 00004 0000 TOCHR, 0 /TELETYPE STATUS WORD | |
3722 | 00005 0000 KBDCHR, 0 /KEYBOARD INPUT CHARACTER | |
3723 | 00006 0000 POCHR, 0 /P.T. PUNCH COMPLETION FLAG | |
3724 | 00007 0000 RDRCHR, 0 /P.T. READER STATUS | |
3725 | 00010 0000 FMTPXR, 0 /XR USED TO INDEX FORMAT PARENTH | |
3726 | 00011 3777 INXR, INBUFR-1 /XR USED TO GET CHARS FROM INPUT | |
3727 | 00012 0000 XR, 0 | |
3728 | 00013 0000 XR1, 0 | |
3729 | ||
3730 | 0016 *16 | |
3731 | 00016 0000 VEOFSW, 0 /USED BY "EOFCHK" TO STORE VARIABLE ADDRESS | |
3732 | 00017 0000 0 /*K* MUST BE IN AUTO - XR | |
3733 | 00020 0000 T, 0 /TEMPORARY | |
3734 | 00021 0000 DFLG, 0 /0 = F.P., 1 = D.P. | |
3735 | 00022 0000 INST, 0 /CURRENT INSTRUCTION WORD | |
3736 | ||
3737 | /IOH PAGE ZERO LOCATIONS | |
3738 | ||
3739 | 00023 0000 RWFLAG, 0 /READ/WRITE FLAG | |
3740 | 00024 0000 FMTTYP, 0 /TYPE OF CONVERSION BEING DONE | |
3741 | 00025 0000 EOLSW, 0 /EOL SW ON INPUT - CHAR POS ON OUT | |
3742 | 00026 0000 N, 0 /REPEAT FACTOR | |
3743 | 00027 0000 W, 0 /FIELD WIDTH | |
3744 | 00030 0000 D, 0 /NUMBER OF PLACES AFTER DECIMAL | |
3745 | 00031 0300 DATCDF, 0 /SUBROUTINE TO CHANGE DATA FIELD | |
3746 | 00032 0000 DATAF, 0 /CONTAINS VARIOUS CDF'S | |
3747 | 00033 5431 JMP I DATCDF /RETURN | |
3748 | 00034 5013 ERR, ERROR /POINTER TO ERROR ROUTINE | |
3749 | 00035 0000 FATAL, 0 /FATAL ERROR FLAG - 0=FATAL | |
3750 | 00036 5000 MCDF, MAKCDF | |
3751 | ||
3752 | /FPP PARAMETER TABLE LOCATIONS: | |
3753 | ||
3754 | 00037 0000 APT, 0 /VARIOUS FIELD BITS FOR FPP | |
3755 | 00040 5313 PC, DPTEST /FPP PROGRAM COUNTER | |
3756 | 00041 0000 XRBASE, 0 /FPP INDEX REGISTER ARRAY ADDRESS | |
3757 | 00042 0000 BASADR, 0 /FPP BASE PAGE ADDRESS | |
3758 | 00043 0000 ADR, 0 /ADDRESS TEMPORARY | |
3759 | 00044 0000 ACX, 0 | |
3760 | 00045 0000 ACH, 0 /*** FLOATING ACCUMULATOR *** | |
3761 | 00046 0000 ACL, 0 | |
3762 | 00047 0000 EAC1, 0 | |
3763 | 00050 0000 EAC2, 0 /** FOR EXTENDED PRECISION OPTION ** | |
3764 | 00051 0003 EAC3, 0 | |
3765 | ||
3766 | ||
3767 | 4-10 | |
3768 | \f | |
3769 | ||
3770 | ||
3771 | /FORTRAN 4 RUNTIME SYSTEM - R.L PAL8-V8 PAGE 4 | |
3772 | ||
3773 | /FLOATING POINT PACKAGE LOCATIONS | |
3774 | ||
3775 | 00052 0000 AC0, 0 | |
3776 | 00053 0000 AC1, 0 /FLOATING AC OVERFLOW WORD | |
3777 | 00054 0000 AC2, 0 /OPERAND OVFLOW WORD | |
3778 | 00055 0000 OPX, 0 | |
3779 | 00056 0000 OPH, 0 /*** FLOATING OPERAND REGISTER *** | |
3780 | 00057 0000 OPL, 0 | |
3781 | ||
3782 | /RTS I/O SYSTEM LOCATIONS | |
3783 | ||
3784 | 00060 0000 FMTBYT, 0 /FORMAT BYTE POINTER | |
3785 | 00061 0000 IFLG, 0 /I FORMAT FLAG | |
3786 | 00062 0000 GFLG, 0 /G FORMAT FLAG | |
3787 | 00063 0000 EFLG, 0 /E FORMAT FLAG - SOMETIMES ON FOR | |
3788 | 00064 0000 OD, 0 | |
3789 | 00065 0000 SCALE, 0 | |
3790 | 00066 0000 PFACT, 0 /P-SCALE FACTOR | |
3791 | 00067 0000 PFACTX, 0 /TEMP FOR PFACT | |
3792 | 00070 0000 INESW, 0 /EXPONENT SWITCH | |
3793 | 00071 0000 CHCH, 0 | |
3794 | 00072 0000 FMTNUM, 0 /CONTAINS ACCUMULATED NUMERIC VALUE | |
3795 | 00073 0000 CTCINH, 0 /^C INHIBIT FLAG | |
3796 | 00074 0320 PTTY, TTY /POINTER TO TTY HANDLER - USED BY | |
3797 | 00075 0000 0 / SO FORMS CONTROL WILL WORK ON | |
3798 | 00076 6001 FPNXT, ICYCLE /USED AS INTERPRETER ADDRESS IF | |
3799 | ||
3800 | /DSRN IMAGE | |
3801 | ||
3802 | 00077 0000 HAND, 0 /HANDLER ENTRY POINT | |
3803 | 00100 0000 HCODEW, 0 /HANDLER LOAD ADDR & FIELD + IOFFL | |
3804 | 00101 0000 BADFLD, 0 /BUFFER ADDRESS AND FIELD | |
3805 | 00102 0000 CHRPTR, 0 /ACTUALLY A WORD POINTER | |
3806 | 00103 0000 CHRCTR, 0 /COUNTER - RANGES FROM -3 TO -1 | |
3807 | 00104 0000 STBLK, 0 /STARTING BLOCK OF FILE | |
3808 | 00105 0000 RELBLK, 0 /CURRENT RELATIVE BLOCK NUMBER | |
3809 | 00106 0000 TOTBLK, 0 /LENGTH OF FILE | |
3810 | 00107 0000 FFLAGS, 0 /FILE FLAGS: | |
3811 | /BIT 0 - "HAS BEEN WRITTEN" FLAG | |
3812 | /BITS 1-2 - FORMATTED/UNFORMATTED | |
3813 | /BIT 11 - "END-FILED" FLAG | |
3814 | 00110 0000 BUFFLD, 0 /ROUTINE TO SET DF TO BUFFER FIELD | |
3815 | 00111 7402 BUFCDF, HLT | |
3816 | 00112 5510 JMP I BUFFLD | |
3817 | 00113 0000 FGPBF, 0 /THESE THREE WORDS ARE USED | |
3818 | 00114 0000 BIOPTR, 0 /TO FETCH AND STORE FLOATING POINT | |
3819 | 00115 0000 FEXIT /FROM RANDOM MEMORY | |
3820 | 0200 PAGE | |
3821 | ||
3822 | ||
3823 | ||
3824 | ||
3825 | ||
3826 | 4-11 | |
3827 | \f | |
3828 | ||
3829 | ||
3830 | /FORTRAN 4 RUNTIME SYSTEM - R.L PAL8-V8 PAGE 5 | |
3831 | ||
3832 | /STARTUP CODE | |
3833 | ||
3834 | 00200 2203 FTEMP2, ISZ .+3 /ALSO USED AS I/O F.P. TEMPORARY | |
3835 | 00201 6213 CDF CIF 10 | |
3836 | 00202 5603 JMP I .+1 | |
3837 | 00203 2200 VDATE, RTSLDR /USED TO STORE OS/8 DATE | |
3838 | ||
3839 | /RTS ENTRY POINTS - "VERSION INDEPENDENT" | |
3840 | ||
3841 | 00204 5777 VUERR, JMP I (USRERR /USER ERROR | |
3842 | /** LOADER MUST DEFINE #ARGER AS | |
3843 | 00205 4434 VARGER, JMS I ERR /LIBRARY ARGUMENT ERROR | |
3844 | 00206 2023 VRENDO, ISZ RWFLAG /END OF I/O LIST | |
3845 | 00207 5634 VRFSV, JMP I GETLMN /I/O LIST ARG ENTRY - COROUTINE | |
3846 | 00210 5776 VBAK, JMP I (BKSPC /"BACKSPACE" ROUTINE | |
3847 | 00211 5775 VENDF, JMP I (ENDFL /"END FILE" ROUTINE | |
3848 | 00212 5774 VREW, JMP I (RWIND /"REWIND" ROUTINE | |
3849 | 00213 5773 VDEF, JMP I (DFINE /"DEFINE FILE" ROUTINE | |
3850 | 00214 7330 VWUO, AC4000 /UNFORMATTED WRITE | |
3851 | 00215 5772 VRUO, JMP I (RWUNF /UNFORMATTED READ | |
3852 | 00216 7330 VWDAO, AC4000 /DIRECT ACCESS WRITE | |
3853 | 00217 5771 VRDAO, JMP I (RWDACC /DIRECT ACCESS READ | |
3854 | 00220 7330 VWRITO, AC4000 /FORMATTED (ASCII) WRITE | |
3855 | 00221 5770 VREADO, JMP I (RWASCI /FORMATTED (ASCII) READ | |
3856 | 00222 5767 VSWAP, JMP I (SWAP /OVERLAY PROCESSOR | |
3857 | 00223 3000 VEXIT, TRAP3; CALXIT /"STOP" ROUTINE - ENTERED IN FPP | |
3858 | 00224 1317 | |
3859 | 00225 0000 V8OR12, 0;0 /0;1 IF CPU IS A PDP-12 | |
3860 | 00226 0000 | |
3861 | 00227 5766 VBACKG, JMP I (NULLJB /BACKGROUND JOB DISPATCHER | |
3862 | 00230 0000 0 | |
3863 | 00231 6203 CDF CIF 0 /USED BY ROUTINE "ONQB" IN LIBRARY | |
3864 | 00232 4630 JMS I .-2 | |
3865 | 00233 5227 JMP VBACKG | |
3866 | ||
3867 | /IOH GET VARIABLE ROUTINE. | |
3868 | /THIS ROUTINE MAKES THE FORMATTED I/O PROCESSOR AND THE | |
3869 | /PROGRAM CO-ROUTINES (DEF(COROUTINE): 2 ROUTINES EACH | |
3870 | / IS A SUBROUTINE). ON ENTRY FAC=INPUT NUMBER | |
3871 | /IF I/O IS A READ, ON RETURN FAC=OUTPUT NUMBER IF I/O | |
3872 | ||
3873 | 00234 0000 GETLMN, 0 | |
3874 | 00235 5577 VRETRN, JMP I [RETURN | |
3875 | ||
3876 | ||
3877 | ||
3878 | ||
3879 | ||
3880 | ||
3881 | ||
3882 | ||
3883 | ||
3884 | ||
3885 | 4-12 | |
3886 | \f | |
3887 | ||
3888 | ||
3889 | All FORTRAN IV mass storage I/O is performed in terms of OS/8 blocks, | |
3890 | including direct access I/O. Hence, all FORTRAN IV files conform to | |
3891 | OS/8 standard ASCII file format. When a formatted READ or WRITE is | |
3892 | requested, the data is converted to or from 8-bit binary representa- | |
3893 | tion according to the FORMAT statement associated with the READ or | |
3894 | WRITE. Standard OS/8 file format packs three 8-bit characters into | |
3895 | two 12-bit words as follows: | |
3896 | ||
3897 | MASS STORAGE CORE | |
3898 | ----------------------------- ------------------ | |
3899 | | WORD 3 | | | WORD 1 | | |
3900 | | bits 0-3 | WORD 1 | |----------------| | |
3901 | |---------------------------- | WORD 2 | | |
3902 | | WORD 3 | | |----------------| | |
3903 | | bits 4-7 | WORD 2 | | WORD 3 | | |
3904 | ----------------------------- ------------------ | |
3905 | ||
3906 | Unformatted (i.e. direct access) READ and WRITE operations also | |
3907 | operate on standard OS/8 format files, with each statement causing one | |
3908 | FORTRAN IV record to be read or written. A FORTRAN IV record must | |
3909 | contain at least one OS/8 block, and always contains an integral | |
3910 | number of blocks. The number of variables contained in a 1-block | |
3911 | record depends upon the content and format of the I/O list, as | |
3912 | follows: | |
3913 | ||
3914 | Number of 12-bit Number of | |
3915 | Format type Words/Variable Variables/Block | |
3916 | ___________ ________________ _______________ | |
3917 | ||
3918 | Integer 3 85 | |
3919 | Real 3 85 | |
3920 | Double precision 6 42 1/2 | |
3921 | Complex 6 42 1/2 | |
3922 | ||
3923 | It is possible to mix any types of data in an I/O list; however, no | |
3924 | more than 85 variables may be stored in one OS/8 block. The number of | |
3925 | blocks required for a FORTRAN IV record depends, therefore, upon the | |
3926 | number of variables in the I/O list, and may be minimized by supplying | |
3927 | every direct access WRITE with sufficient data to nearly fill an | |
3928 | integral number of blocks without overflowing the last block. | |
3929 | ||
3930 | The last word in every file block contains a block count sequence | |
3931 | number and is not available for data storage. FRTS assigns block | |
3932 | count numbers sequentially, beginning with 1, whenever a file is | |
3933 | written. Block count numbers must be maintained by the user when | |
3934 | FORTRAN IV files are created outside of an OS/8 FORTRAN IV | |
3935 | environment. While reading a binary file, FRTS checks the block count | |
3936 | sequence numbers on input blocks and ignores any block whose sequence | |
3937 | number is larger than expected. Sequence number checking is disabled | |
3938 | during direct access READ operations. | |
3939 | ||
3940 | When FRTS is loaded and started, the initialization routines deter- | |
3941 | mine what optional hardware, such as FPP-12 Floating Point Processor | |
3942 | or KE8E Extended Arithmetic Element, is present in the running | |
3943 | hardware configuration. The initialization routines then modify FRTS | |
3944 | ||
3945 | 4-13 | |
3946 | \f | |
3947 | ||
3948 | ||
3949 | to use the optional hardware, if available. When an FPP is present in | |
3950 | the system and it becomes desirable to disable the FPP under FRTS, | |
3951 | this may be accomplished by changing the content of location 12621 | |
3952 | from 6555 to 7200. The extended arithmetic element may be disabled in | |
3953 | the same manner by changing the content of FRTS location 12623 from | |
3954 | 7413 to 7200. These changes must be made before FRTS is started. The | |
3955 | OS/8 monitor GET and ODT commands provide an excellent mechanism for | |
3956 | changes of this type. | |
3957 | ||
3958 | The FRTS internal line printer handler uses a linked ring buffer for | |
3959 | maximum I/O buffering efficiency. The buffer consists of several | |
3960 | contiguous sections of memory, linked together by pointers. All of | |
3961 | these buffer segments are located above 04000, so that the pointers | |
3962 | are readily distinguishable from buffered characters. The entire | |
3963 | 07400 page is included in the line printer ring buffer. If it becomes | |
3964 | desirable to modify FRTS by patching or reassembly, most of the 07400 | |
3965 | page may be reclaimed from the buffer by changing the content of | |
3966 | location 07402 from 7577 to 5164. This frees up locations 07403 to | |
3967 | 07577 for new code and still leaves about eighty character positions | |
3968 | in the LPT ring buffer. | |
3969 | ||
3970 | Because FRTS executes with the processor interrupt system enabled, it | |
3971 | may hang up on hardware configurations that include equipment capable | |
3972 | of generating spurious program interrupts. In addition, any OS/8 I/O | |
3973 | device handler that exits without clearing all device flags may cause | |
3974 | troublesome interrupts when it is assigned as a FORTRAN I/O unit under | |
3975 | FRTS. To counteract these potential problems, FRTS provides certain | |
3976 | areas that are reserved for inclusion of user-generated code designed | |
3977 | to clear device flags and/or inhibit spurious interrupts. | |
3978 | ||
3979 | A string of NOP instructions beginning at location 04020 is executed | |
3980 | during FRTS initialization, just before the interrupt system is | |
3981 | enabled. When the /H option is specified to FRTS, the system halts | |
3982 | after these NOPs have been executed and the interrupt system has been | |
3983 | enabled. Another string of NOPs occupying the eight locations from | |
3984 | 03746 to 03755 is executed after every call to an OS/8 device handler. | |
3985 | Any of these NOP instructions may be replaced by flag-handling or | |
3986 | interrupt-servicing code. If additional memory locations are | |
3987 | required, they may be obtained by replacing some of the code from | |
3988 | locations 04007 to 04017 with flag-handling code. Locations 04007-17 | |
3989 | are used to clear flags associated with LAB-8/E peripheral devices. | |
3990 | ||
3991 | Due to memory limitations, it is not possible to add internal I/O | |
3992 | device handlers to the four internal handlers supplied with the | |
3993 | system. However, FORTRAN I/O unit 0, which is not defined by the ANSI | |
3994 | standard, may be specified for terminal I/O via the internal console | |
3995 | terminal handler. I/O unit 0 is not re-assignable. | |
3996 | ||
3997 | The FRTS /P option provides a mechanism whereby the core image gener- | |
3998 | ated from a FORTRAN program may be punched onto paper tape in binary | |
3999 | loader format. This permits the loader image to be executed on a | |
4000 | hardware configuration that does not include mass-storage devices. To | |
4001 | use the /P option, specify /P to FRTS and assign a device or file as | |
4002 | FORTRAN I/O unit 9. Assigning the paper tape punch as unit 9 causes | |
4003 | ||
4004 | 4-14 | |
4005 | \f | |
4006 | ||
4007 | ||
4008 | /FORTRAN 4 RUNTIME SYSTEM - R.L PAL8-V8 PAGE 6 | |
4009 | ||
4010 | /INTERRUPT DRIVEN I/O HANDLERS | |
4011 | ||
4012 | 00236 0000 LPT, 0 /RING-BUFFERED - LP08 OR LS8E | |
4013 | 00237 0176 AND [377 /JUST IN CASE | |
4014 | 00240 7450 LPTSNA, SNA | |
4015 | 00241 5765 JMP I (IOERR /CANNOT BE USED FOR INPUT | |
4016 | 00242 6002 IOF | |
4017 | 00243 3667 DCA I LPPUT | |
4018 | 00244 1003 TAD LPGET | |
4019 | 00245 7041 CIA | |
4020 | 00246 1267 TAD LPPUT | |
4021 | 00247 7640 SZA CLA /IS LPT QUIET? | |
4022 | 00250 5253 JMP .+3 /NO | |
4023 | 00251 1667 TAD I LPPUT | |
4024 | 00252 6666 LLS /YES - START 'ER UP | |
4025 | 00253 7201 CLA IAC | |
4026 | 00254 6665 LIE /ENABLE LPT INTERRUPTS | |
4027 | 00255 1267 TAD LPPUT /1 IN AC, REMEMBER? | |
4028 | 00256 3267 DCA LPPUT | |
4029 | 00257 1667 TAD I LPPUT | |
4030 | 00260 7510 SPA | |
4031 | 00261 5256 JMP .-3 /NEGATIVE NUMBERS ARE BUFFER LINKS | |
4032 | 00262 7640 SZA CLA /ANY ROOM LEFT IN BUFFER? | |
4033 | 00263 4764 JMS I (HANG | |
4034 | 00264 0436 LPUHNG /WAIT FOR LINE PRINTER | |
4035 | 00265 6001 ION /TURN INTERRUPTS BACK ON | |
4036 | 00266 5636 JMP I LPT /RETURN | |
4037 | ||
4038 | 00267 5165 LPPUT, LPBUFR | |
4039 | ||
4040 | 00270 0000 PTP, 0 /PAPER TAPE PUNCH HANDLER | |
4041 | 00271 7450 SNA | |
4042 | 00272 5765 JMP I (IOERR /INPUT IS ERROR | |
4043 | 00273 3236 DCA LPT /SAVE CHAR | |
4044 | 00274 6002 IOF | |
4045 | 00275 1006 TAD POCHR /IF PUNCH IS NOT IDLE, | |
4046 | 00276 7640 SZA CLA /WE DISMISS JOB | |
4047 | 00277 4764 JMS I (HANG | |
4048 | 00300 0502 PPUHNG /WAIT FOR PUNCH INTERRUPT | |
4049 | 00301 1236 TAD LPT | |
4050 | 00302 6026 PLS /OUTPUT CHAR | |
4051 | 00303 3006 DCA POCHR /SET FLAG NON-ZERO | |
4052 | 00304 6001 ION | |
4053 | 00305 5670 JMP I PTP | |
4054 | ||
4055 | /*K* THE FOLLOWING ADDRESSES GET FALLEN INTO & MUST BE SMALL | |
4056 | ||
4057 | IFNZRO PPUHNG&7000 <--ERROR--> | |
4058 | IFNZRO TTUHNG&7000 <--ERROR--> | |
4059 | IFNZRO KBUHNG&7000 <--ERROR--> | |
4060 | IFNZRO RDUHNG&7000 <--ERROR--> | |
4061 | IFNZRO LPUHNG&7000 <--ERROR--> | |
4062 | ||
4063 | 4-15 | |
4064 | \f | |
4065 | ||
4066 | ||
4067 | /FORTRAN 4 RUNTIME SYSTEM - R.L PAL8-V8 PAGE 7 | |
4068 | ||
4069 | /INTERRUPT-DRIVEN PTR AND TELETYPE HANDLER | |
4070 | ||
4071 | 00306 0000 PTR, 0 /CRUDE READER HANDLER | |
4072 | 00307 7640 SZA CLA | |
4073 | 00310 5765 JMP I (IOERR /OUTPUT ILLEGAL TO PTR | |
4074 | 00311 6002 IOF | |
4075 | 00312 6014 RFC /START READER | |
4076 | 00313 4764 JMS I (HANG | |
4077 | 00314 0510 RDUHNG /HANG UNTIL COMPLETE | |
4078 | 00315 1007 TAD RDRCHR /GET CHARACTER | |
4079 | 00316 6001 ION | |
4080 | 00317 5706 JMP I PTR /RETURN | |
4081 | 00320 0000 TTY, 0 /BUFFERS 2 CHARS ON OUTPUT, 1 ON | |
4082 | 00321 6002 IOF /DELICATE CODE AHEAD | |
4083 | 00322 7450 SNA /INPUT OR OUTPUT? | |
4084 | 00323 5342 JMP KBD /INPUT | |
4085 | 00324 3236 DCA LPT /OUTPUT - SAVE CHAR | |
4086 | 00325 1004 TAD TOCHR /GET TTY STATUS | |
4087 | 00326 7740 SMA SZA CLA /G.T. 0 MEANS A CHAR IS BACKED UP | |
4088 | 00327 4764 JMS I (HANG | |
4089 | 00330 0451 TTUHNG /WAIT FOR LOG JAM TO CLEAR | |
4090 | 00331 1004 TAD TOCHR /NO CHAR BACKED UP - SEE IF TTY | |
4091 | 00332 7104 CLL RAL /"BUSY" FLAG IN LINK - INTERRUPTS | |
4092 | 00333 7230 CLA CML RAR /COMPLEMENT OF BUSY IN SIGN | |
4093 | 00334 1236 TAD LPT /GET CHAR | |
4094 | 00335 7510 SPA /IF TTY NOT BUSY, | |
4095 | 00336 6046 TLS /OUTPUT CHAR | |
4096 | 00337 3004 DCA TOCHR /STORE POS OR NEG, BACKED UP | |
4097 | 00340 6001 TTYRET, ION /TURN INTERRUPTS BACK ON | |
4098 | 00341 5720 JMP I TTY /AND LEAVE | |
4099 | ||
4100 | ||
4101 | /FORTRAN 4 RUNTIME SYSTEM - R.L PAL8-V8 PAGE 8 | |
4102 | ||
4103 | 00342 1005 KBD, TAD KBDCHR /HAS A CHARACTER BEEN INPUT? | |
4104 | 00343 7650 SNA CLA | |
4105 | 00344 4764 JMS I (HANG | |
4106 | 00345 0465 KBUHNG /NO - RUN BACKGROUND UNTIL ONE IS | |
4107 | 00346 1005 TAD KBDCHR /GET CHARACTER | |
4108 | 00347 3236 DCA LPT | |
4109 | 00350 3005 DCA KBDCHR /CHEAR CHARACTER BUFFER | |
4110 | 00351 1236 TAD LPT | |
4111 | 00352 5340 JMP TTYRET /RETURN WITH INTERRUPTS ON | |
4112 | ||
4113 | 00353 6554 KILFPP, FPHLT /BRING FPP TO A SCREECHING HALT | |
4114 | 00354 2353 ISZ .-1 | |
4115 | 00355 5354 JMP .-1 /WAIT FOR IT TO STOP | |
4116 | 00356 6552 FPICL /CLEAN UP MESS HALT HAS MADE IN FPP | |
4117 | 00357 7430 SZL /^C OR ^B? | |
4118 | 00360 5763 JMP I (7600 /^C - HIYO SILVER, AWAY! | |
4119 | 00361 6032 KCC /CLEAR KBD FLAG ON ^B | |
4120 | 00362 4434 CTLBER, JMS I ERR /*** THIS MAY BE DANGEROUS! ** | |
4121 | ||
4122 | 4-16 | |
4123 | \f | |
4124 | ||
4125 | ||
4126 | /FORTRAN 4 RUNTIME SYSTEM - R.L PAL8-V8 PAGE 9 | |
4127 | ||
4128 | /INTERRUPT SERVICE ROUTINES | |
4129 | ||
4130 | 00400 3322 INTRPT, DCA INTAC | |
4131 | 00401 7010 RAR | |
4132 | 00402 3323 DCA INTLNK | |
4133 | 00403 5207 VINT, JMP .+4 /** MUST BE AT 403 ** | |
4134 | IFNZRO VINT-403 <--- CHANGE LOADER!!!> | |
4135 | 00404 0000 0 | |
4136 | 00405 6203 CDF CIF 0 /USER INTERRUPT ROUTINE GOES HERE | |
4137 | 00406 4604 JMS I .-2 | |
4138 | ||
4139 | 00407 6551 FPINT /CHECK FOR FPP DONE | |
4140 | 00410 5215 JMP LPTEST | |
4141 | 00411 5314 FPUHNG, JMP DISMIS /ALWAYS GOES TO RESTRT | |
4142 | ||
4143 | 00412 5314 VDISMS, JMP DISMIS /FOR USE BY USERS | |
4144 | 00413 5314 JMP DISMIS | |
4145 | 00414 5314 JMP DISMIS | |
4146 | 00415 6661 LPTEST, LSF | |
4147 | 00416 5240 JMP NOTLPT | |
4148 | 00417 6662 LPTLCF, LCF /CLEAR FLAG | |
4149 | 00420 1403 TAD I LPGET | |
4150 | 00421 7650 SNA CLA /CHECK FOR SPURIOUS INTERRUPT | |
4151 | 00422 5314 JMPDIS, JMP DISMIS /GO AWAY IF SO | |
4152 | 00423 3403 DCA I LPGET /ZERO CHAR JUST OUTPUT | |
4153 | 00424 2003 ISZ LPGET | |
4154 | 00425 1403 TAD I LPGET | |
4155 | 00426 7510 SPA | |
4156 | 00427 3003 DCA LPGET /TAKE CARE OF BUFFER LINKS | |
4157 | 00430 7450 SNA | |
4158 | 00431 1403 TAD I LPGET /HAKE SURE CHAR IS IN AC | |
4159 | 00432 7440 SZA /IS THERE A CHARACTER? | |
4160 | 00433 6666 LLS /YES - PRINT IT | |
4161 | 00434 7200 CLA | |
4162 | 00435 6661 LSF /CHECK FOR IMMEDIATE FLAG | |
4163 | 00436 5314 LPUHNG, JMP DISMIS /NO - MAYBE RESTART PROGRAM | |
4164 | 00437 5217 JMP LPTLCF /YES - LOOP | |
4165 | ||
4166 | 00440 6041 NOTLPT, TSF /CHECK TTY | |
4167 | 00441 5252 JMP NOTTTY | |
4168 | 00442 6042 TCF /CLEAR FLAG | |
4169 | 00443 1004 TAD TOCHR /GET TTY STATUS | |
4170 | 00444 7540 SMA SZA /IF THERE IS A CHARACTER WAITING, | |
4171 | 00445 6046 TLS /OUTPUT IT. | |
4172 | 00446 7740 SMA SZA CLA /CHANGE "WAITING" TO "BUSY", | |
4173 | 00447 7130 STL RAR /"BUSY" TO "IDLE". | |
4174 | 00450 3004 DCA TOCHR | |
4175 | 00451 5314 TTUHNG, JMP DISMIS | |
4176 | ||
4177 | ||
4178 | ||
4179 | ||
4180 | ||
4181 | 4-17 | |
4182 | \f | |
4183 | ||
4184 | ||
4185 | /FORTRAN 4 RUNTIME SYSTEM - R.L PAL8-V8 PAGE 10 | |
4186 | ||
4187 | /KBD AND PTP INTERRUPTS | |
4188 | ||
4189 | 00452 6031 NOTTTY, KSF | |
4190 | 00453 5276 JMP NOTKBD | |
4191 | 00454 1175 TAD [200 | |
4192 | 00455 6034 KRS /USE KRS TO FORCE PARITY BIT | |
4193 | 00456 3005 DCA KBDCHR /AND ALSO SO THAT ^C WILL STILL | |
4194 | 00457 1005 TAD KBDCHR | |
4195 | 03460 1377 TAD (-202 /CHECK FOR ^C OR ^B | |
4196 | 00461 7110 CLL RAR | |
4197 | 00462 7650 SNA CLA | |
4198 | 00463 5266 JMP CTCCTB /YUP - TAKE SOME DRASTIC ACTION | |
4199 | 00464 6032 KCC /DATA CHARACTER - CLEAR FLAG | |
4200 | 00465 5314 KBUHNG, JMP DISMIS | |
4201 | ||
4202 | 00466 1073 CTCCTB, TAD CTCINH | |
4203 | 00467 7650 SNA CLA /ARE WE IN A HANDLER? | |
4204 | 00470 5366 JMP NOTINH /NO | |
4205 | 00471 1323 TAD INTLNK | |
4206 | 00472 7104 CLL RAL /YES - RETURN WITH INTERRUPTS OFF | |
4207 | 00473 1322 TAD INTAC /TRUST IN GOD AND RTS | |
4208 | 00474 6244 RMF | |
4209 | 00475 5400 JMP I 0 | |
4210 | ||
4211 | 00476 6021 NOTKBD, PSF | |
4212 | 00477 5303 JMP NOTPTP | |
4213 | 00500 6022 PCF /P.T. PUNCH INTERRUPT - CLEAR FLAG | |
4214 | 00501 3006 DCA POCHR /CLEAR SOFTWARE FLAG | |
4215 | 00502 5314 PPUHNG, JMP DISMIS | |
4216 | ||
4217 | 00503 6011 NOTPTP, RSF | |
4218 | 00504 5311 JMP LPTERR | |
4219 | 00505 1175 TAD [200 | |
4220 | 00506 6012 RRB /GET RDR CHAR | |
4221 | 00507 3007 DCA RDRCHR | |
4222 | 00510 5314 RDUHNG, JMP DISMIS | |
4223 | ||
4224 | 00511 6663 LPTERR, LSE /TEST FOR LP08 ERROR FLAG | |
4225 | 00512 7410 SKP | |
4226 | 00513 6667 LIF /DISABLE LP08 INTERRUPTS IF ERROR | |
4227 | 00514 1323 DISMIS, TAD INTLNK | |
4228 | 00515 7104 CLL RAL | |
4229 | 00516 1322 TAD INTAC /RESTORE AC AND LINK | |
4230 | 00517 6244 RMF | |
4231 | 00520 6001 ION | |
4232 | 00521 5400 JMP I 0 /RETURN FROM THE INTERRUPT | |
4233 | ||
4234 | 00522 0000 INTAC, 0 | |
4235 | 00523 0000 INTLNK, 0 | |
4236 | ||
4237 | ||
4238 | ||
4239 | ||
4240 | 4-18 | |
4241 | \f | |
4242 | ||
4243 | ||
4244 | /FORTRAN 4 RUNTIME SYSTEM - R.L PAL8-V8 PAGE 11 | |
4245 | ||
4246 | /BACKGROUND INITIATE/TERMINATE ROUTINE | |
4247 | ||
4248 | 00524 0000 HANG, 0 /ALWAYS CALLED WITH INTERRUPTS OFF! | |
4249 | 00525 1724 TAD I HANG /GET POINTER TO UNHANGING LOCATION | |
4250 | 00526 3371 DCA UNHANG | |
4251 | 00527 6214 RDF /GET FIELD CALLED FROM | |
4252 | 00530 1332 TAD HCIDF0 | |
4253 | 00531 3364 DCA HNGCDF /SAVE FOR RETURN | |
4254 | 00532 6203 HCIDF0, CDF CIF 0 | |
4255 | 00533 1376 TAD (JMP RESTRT /CHANGE THE "JMP DISMIS" | |
4256 | 00534 3771 DCA I UNHANG /TO A "JMP RESTRT" | |
4257 | 00535 1373 TAD BACKLK | |
4258 | 00536 7104 CLL RAL | |
4259 | 00537 1372 TAD BACKAC /SET UP BACKGROUND AC AND LINK | |
4260 | 00540 6202 BAKCIF, CIF 0 | |
4261 | 00541 6201 BAKCDF, CDF 0 | |
4262 | 00542 6001 ION | |
4263 | 00543 5774 JMP I BACKPC /INITIATE BACKGROUND | |
4264 | ||
4265 | / COME HERE WHEN THE HANG CONDITION HAS GONE AWAY | |
4266 | ||
4267 | 00544 1222 RESTRT, TAD JMPDIS /RESTORE THE UNHANG LOCATION | |
4268 | 00545 3771 DCA I UNHANG | |
4269 | 00546 1322 TAD INTAC /SUSPEND THE BACKGROUND | |
4270 | 00547 3372 DCA BACKAC | |
4271 | 00550 1323 TAD INTLNK | |
4272 | 00551 3373 DCA BACKLK | |
4273 | 00552 1000 TAD 0 | |
4274 | 00553 3374 DCA BACKPC | |
4275 | 00554 6234 RIB | |
4276 | 00555 0174 AND [70 | |
4277 | 00556 1332 TAD HCIDF0 | |
4278 | 00557 3340 DCA BAKCIF | |
4279 | 00560 6234 RIB | |
4280 | 00561 4436 JMS I MCDF /*K* OK SINCE BACKGROUND DOESN'T | |
4281 | 00562 3341 DCA BAKCDF | |
4282 | 00563 2324 ISZ HANG | |
4283 | 00564 7402 HNGCDF, HLT | |
4284 | 00565 5724 JMP I HANG /INTERRUPTS ARE OFF - RETURN | |
4285 | 00566 1222 NOTINH, TAD JMPDIS /IN CASE WE WERE HUNG, WE DON'T | |
4286 | 00567 3771 DCA I UNHANG /TO GET "UNHUNG" OUT OF THE ERROR | |
4287 | 00570 5775 JMP I (KILFPP /KILL FPP AND GO TO EXIT OR ERROR | |
4288 | ||
4289 | 00571 0000 UNHANG, 0 | |
4290 | 00572 0000 BACKAC, 0 | |
4291 | 00573 0000 BACKLK, 0 | |
4292 | 00574 0227 BACKPC, VBACKG | |
4293 | 0524 VHANG= HANG | |
4294 | IFNZRO VHANG-0524 <--CHANGE LOADER!> | |
4295 | 00575 0353 | |
4296 | 00576 5344 | |
4297 | 00577 7576 | |
4298 | 0600 PAGE | |
4299 | 4-19 | |
4300 | \f | |
4301 | ||
4302 | ||
4303 | the image to be punched out directly; however, it may be desirable to | |
4304 | direct the binary output to an intermediate file for later transfer to | |
4305 | paper tape via OS/8 PIP. In any event, FRTS returns to the monitor | |
4306 | once the core image has been transferred. | |
4307 | ||
4308 | The output file is a binary image of memory locations 00000 to 07577 | |
4309 | and 10000 up to the highest location used by the FORTRAN load. The | |
4310 | content of each field is punched separately with its own checksum and | |
4311 | leader/trailer. | |
4312 | ||
4313 | With the BIN loader resident in field 0, load the binary tape produced | |
4314 | under the /P option by reading each segment separately and verifying | |
4315 | the checksum as each memory field is loaded. When all segments have | |
4316 | been read into memory, start execution at location 00200. The | |
4317 | following restrictions apply: | |
4318 | ||
4319 | 1. OS/8 device handlers which have been assigned FORTRAN I/O | |
4320 | unit numbers are not necessarily punched out. For this | |
4321 | reason, I/O unit assignments other than in the form /n=m | |
4322 | should be avoided. | |
4323 | ||
4324 | 2. With respect to the presence of an FPP and/or EAE, the con- | |
4325 | figuration on which the image is punched must be identical to | |
4326 | the configuration on which it is to be run. If the punching | |
4327 | configuration contains hardware that is absent from the | |
4328 | target configuration, this hardware must be disabled under | |
4329 | FRTS. If the target configuration contains hardware that is | |
4330 | absent from the punching configuration, the extraneous | |
4331 | hardware will not be used. | |
4332 | ||
4333 | 3. The statements STOP and CALL EXIT cause a core load produced | |
4334 | under the /P option to halt. Any fatal error flagged during | |
4335 | punching or execution causes error traceback followed by a | |
4336 | halt. Do not press CONTinue in response to either of these | |
4337 | machine halts. | |
4338 | ||
4339 | A FORTRAN IV program is terminated in one of three ways: | |
4340 | ||
4341 | 1. A fatal error condition is flagged (CTRL/B) is processed as a | |
4342 | fatal error. | |
4343 | ||
4344 | 2. CTRL/C is recognized, or the CPU is halted and re-started in | |
4345 | 07600. | |
4346 | ||
4347 | 3. A STOP, CALL EXIT, or (under RALF) JSR #EXIT statement is | |
4348 | executed. | |
4349 | ||
4350 | The sequence of events that results in program termination proceeds as | |
4351 | follows: | |
4352 | ||
4353 | ||
4354 | ||
4355 | ||
4356 | ||
4357 | ||
4358 | 4-20 | |
4359 | \f | |
4360 | ||
4361 | ||
4362 | Fatal Error STOP | |
4363 | (1) (CTRL/B) (2) CTRL/C CALL EXIT (3) | |
4364 | | | JSR #EXIT | | |
4365 | ------------- --------------- --------------- | |
4366 | | BRANCH TO | | | | SIMULATE | | |
4367 | | ERROR | | EXECUTE IOF | | END FILE ON | | |
4368 | | ROUTINE | | | | ANY OPEN | | |
4369 | ------------- --------------- | FILES | | |
4370 | | | --------------- | |
4371 | | | |<------- | |
4372 | ------------- --------------- / \ | | |
4373 | | | | LET I/O DE- | / TTY, \ | | |
4374 | | PRINT | | VICE HANDLER| /LPT BUFFERS\_| | |
4375 | | TRACEBACK | | PROCESS ^C | \ CLEAR / NO | |
4376 | ------------- --------------- \ ? / | |
4377 | | | \ / | |
4378 | | | | YES | |
4379 | | | | | |
4380 | | ------------- | --------------- | |
4381 | | | | | | SET NORMAL | | |
4382 | ----->| JMP 07605 |<------ | TERMINATION | | |
4383 | | | | FLAG | | |
4384 | ------------- --------------- | |
4385 | | | | |
4386 | | Location 07605 traps back to FRTS | | |
4387 | -------------------------------------| | |
4388 | (A) | |
4389 | ||
4390 | ||
4391 | ||
4392 | At point A, FRTS executes the following operations. | |
4393 | ||
4394 | 1. Read termination routine into memory. | |
4395 | ||
4396 | 2. Read OS/8 field 0 resident from block 37 of SYS. | |
4397 | ||
4398 | 3. Jump into termination routine at location 17400. | |
4399 | ||
4400 | 4. restore normal content of locations 07600 and 07605 (in OS/8 | |
4401 | resident). | |
4402 | ||
4403 | 5. If configuration is an in-core TD8E DECtape system, restore | |
4404 | second part of TD8E handler from n7600 to 27600. | |
4405 | ||
4406 | 6. Wait for TTY to finish all pending I/O. If BATCH is running, | |
4407 | print LF on TTY and LPT. | |
4408 | ||
4409 | 7. If normal termination flag is set, close any output files | |
4410 | that were opened by the FRTS loader. | |
4411 | ||
4412 | 8. Return to OS/8 monitor via location 07605. | |
4413 | ||
4414 | ||
4415 | ||
4416 | ||
4417 | 4-21 | |
4418 | \f | |
4419 | ||
4420 | ||
4421 | /FORTRAN 4 RUNTIME SYSTEM - R.L PAL8-V8 PAGE 78 | |
4422 | ||
4423 | 6600 FPPKG= . /FOR EAE OVERLAY | |
4424 | ||
4425 | /23-BIT FLOATING PT INTERPRETER | |
4426 | /W.J. CLOGHER, MODIFIED BY R.LARY FOR FORTRAN | |
4427 | ||
4428 | 06600 0000 LPBUF2, ZBLOCK 16 | |
4429 | 06616 7160 LPBUF3 | |
4430 | ||
4431 | 06617 0000 AL1BMP, 0 /*K* UTILITY SUBROUTINE | |
4432 | 06620 7240 STA | |
4433 | 06621 1044 TAD ACX | |
4434 | 06622 3044 DCA ACX | |
4435 | 06623 4542 JMS I [AL1 | |
4436 | 06624 5617 JMP I AL1BMP | |
4437 | ||
4438 | /FLOATING MULTIPLY-DOES 2 24X12 BIT MULTIPLIES | |
4439 | 06625 4777 DDMPY, JMS I (DARGET | |
4440 | 06626 7410 SKP | |
4441 | 06627 4776 FFMPY, JMS I (ARGET /GET OPERAND | |
4442 | 06630 4304 JMS MDSET /SET UP FOR MPY-OPX IN AC ON RETN. | |
4443 | 06631 1044 TAD ACX /DO EXPONENT ADDITION | |
4444 | 06632 3044 DCA ACX /STORE FINAL EXPONENT | |
4445 | 06633 3304 DCA MDSET /ZERO TEM STORAGE FOR MPY ROUTINE | |
4446 | 06634 3054 DCA AC2 | |
4447 | 06635 1045 TAD ACH /IS FAC=0? | |
4448 | 06636 7650 SNA CLA | |
4449 | 06637 3044 DCA ACX /YES-ZERO EXPONENT | |
4450 | 06640 4334 JMS MP24 /NO-MULTIPLY FAC BY LOW ORDER OPR. | |
4451 | 06641 1056 TAD OPH /NOW MULTIPLY FAC BY HI ORDER MULT | |
4452 | 06642 3057 DCA OPL | |
4453 | 06643 4334 JMS MP24 | |
4454 | 06644 1054 TAD AC2 /STORE RESULT BACK IN FAC | |
4455 | 06645 3046 DCA ACL /LOW ORDER | |
4456 | 06646 1304 TAD MDSET /HIGH ORDER | |
4457 | 06647 3045 DCA ACH | |
4458 | 06650 1045 TAD ACH /DO WE NEED TO NORMALIZE? | |
4459 | 06651 7004 RAL | |
4460 | 06652 7710 SPA CLA | |
4461 | 06653 4217 JMS AL1BMP /YES-DO IT FAST | |
4462 | 06654 1053 TAD AC1 | |
4463 | 06655 7710 SPA CLA /CHECK OVERFLOW WORD | |
4464 | 06656 2046 ISZ ACL /HIGH BIT ON - ROUND RESULT | |
4465 | 06657 5265 JMP MDONE | |
4466 | 06660 2045 ISZ ACH /LOW ORDER OVERFLOWED - INCREMENT | |
4467 | 06661 1045 TAD ACH | |
4468 | 06662 7510 SPA /CHECK FOR OVERFLOW TO 4000 0000 | |
4469 | 06663 5775 JMP I (SHR1 /WE HANDLE A SIMILIAR CASE IN | |
4470 | 06664 7200 CLA | |
4471 | ||
4472 | ||
4473 | ||
4474 | ||
4475 | ||
4476 | 4-22 | |
4477 | \f | |
4478 | ||
4479 | ||
4480 | /FORTRAN 4 RUNTIME SYSTEM - R.L PAL8-V8 PAGE 79 | |
4481 | ||
4482 | 06665 3053 MDONE, DCA AC1 /ZERO OVERFLOW WD(DO I NEED THIS??? | |
4483 | 06666 2333 ISZ MSIGN /SHOULD RESULT BE NEGATIVE? | |
4484 | 06667 7410 SKP /NO | |
4485 | 06670 4543 JMS I [FFNEG /YES-NEGATE IT | |
4486 | 06671 1045 TAD ACH | |
4487 | 06672 7650 SNA CLA /A ZERO AC MEANS A ZERO EXPONENT | |
4488 | 06673 3044 DCA ACX | |
4489 | 06674 1021 TAD DFLG | |
4490 | 06675 7740 SMA SZA CLA /D.P. INTEGER MODE? | |
4491 | 06676 1044 TAD ACX /WITH ACX LESS THAN 0? | |
4492 | 06677 7450 SNA | |
4493 | 06700 5476 JMP I FPNXT /NO - RETURN | |
4494 | 06701 7040 CMA | |
4495 | 06702 4541 JMS I [ACSR /UN-NORMALIZE RESULT | |
4496 | 06703 5476 JMP I FPNXT /RETURN | |
4497 | ||
4498 | ||
4499 | ||
4500 | ||
4501 | /FORTRAN 4 RUNTIME SYSTEM - R.L PAL8-V8 PAGE 80 | |
4502 | ||
4503 | /MDSET-SETS UP SIGNS FOR MULTIPLY AND DIVIDE | |
4504 | /ALSO SHIFTS OPERAND ONE BIT TO THE LEFT. | |
4505 | /EXIT WITH EXPONENT OF OPERAND IN AC FOR EXPONENT | |
4506 | /CALCULATION-CALLED WITH ADDRESS OF OPERAND IN AC AND | |
4507 | /DATA FIELD SET PROPERLY FOR OPERAND. | |
4508 | ||
4509 | 06704 0000 MDSET, 0 | |
4510 | 06705 7344 CLA CLL CMA RAL /SET SIGN CHECK TO -2 | |
4511 | 06706 3333 DCA MSIGN | |
4512 | 06707 1056 TAD OPH /IS OPERAND NEGATIVE? | |
4513 | 06710 7700 SMA CLA | |
4514 | 06711 5314 JMP .+3 /NO | |
4515 | 06712 4774 JMS I (OPNEG /YES-NEGATE IT | |
4516 | 06713 2333 ISZ MSIGN /BUMP SIGN CHECK | |
4517 | 06714 1057 TAD OPL /AND SHIFT OPERAND LEFT ONE BIT | |
4518 | 06715 7104 CLL RAL | |
4519 | 06716 3057 DCA OPL | |
4520 | 06717 1056 TAD OPH | |
4521 | 06720 7004 RAL | |
4522 | 06721 3056 DCA OPH | |
4523 | 06722 3053 DCA AC1 /CLR. OVERFLOW WORD OF FAC | |
4524 | 06723 1045 TAD ACH /IS FAC NEGATIVE | |
4525 | 06724 7700 SMA CLA | |
4526 | 06725 5331 JMP LEV /NO-GO ON | |
4527 | 06726 4543 JMS I [FFNEG /YES-NEGATE IT | |
4528 | 06727 2333 ISZ MSIGN /BUMP SIGN CHECK | |
4529 | 06730 7000 NOP /MAY SKIP | |
4530 | 06731 1055 LEV, TAD OPX /EXIT WITH OPERAND EXPONENT IN AC | |
4531 | 06732 5704 JMP I MDSET | |
4532 | 06733 0000 MSIGN, 0 | |
4533 | ||
4534 | ||
4535 | 4-23 | |
4536 | \f | |
4537 | ||
4538 | ||
4539 | /FORTRAN 4 RUNTIME SYSTEM - R.L PAL8-V8 PAGE 81 | |
4540 | ||
4541 | /24 BIT BY 12 BIT MULTIPLY. MULTIPLIER IS IN OPL | |
4542 | /MULTIPLICAND IS IN ACH AND ACL | |
4543 | /RESULT LEFT IN MDSET,AC2, AND AC1 | |
4544 | ||
4545 | 06734 0000 MP24, 0 | |
4546 | 06735 1373 TAD (-14 /SET UP 12 BIT COUNTER | |
4547 | 06736 3055 DCA OPX | |
4548 | 06737 1057 TAD OPL /IS MULTIPLIER=0? | |
4549 | 06740 7440 SZA | |
4550 | 06741 5345 JMP MPLP1 /NO-GO ON | |
4551 | 06742 3053 DCA AC1 /YES-INSURE RESULT=0 | |
4552 | 06743 5734 JMP I MP24 /RETURN | |
4553 | 06744 1057 MPLP, TAD OPL /SHIFT A BIT OUT OF LOW ORDER | |
4554 | 06745 7010 MPLP1, RAR /OF MULTIPLIER AND INTO LINK | |
4555 | 06746 3057 DCA OPL | |
4556 | 06747 7420 SNL /WAS IT A 1? | |
4557 | 06750 5356 JMP MPLP2 /NO - 0 - JUST SHIFT PARTIAL PROD | |
4558 | 06751 1054 TAD AC2 /YES-ADD MULTIPLICAND TO PARTIAL | |
4559 | 06752 1046 TAD ACL /LOW ORDER | |
4560 | 06753 3054 DCA AC2 | |
4561 | 06754 7024 CML RAL /*K* NOTE THE "SNL" 5 WORDS BACK! | |
4562 | 06755 1045 TAD ACH /HI ORDER | |
4563 | 06756 1304 MPLP2, TAD MDSET | |
4564 | 06757 7010 RAR /NOW SHIFT PARTIAL PROD. RIGHT 1 | |
4565 | 06760 3304 DCA MDSET | |
4566 | 06761 1054 TAD AC2 | |
4567 | 06762 7010 RAR | |
4568 | 06763 3054 DCA AC2 | |
4569 | 06764 1053 TAD AC1 | |
4570 | 06765 7010 RAR /OVERFLOW TO AC1 | |
4571 | 06766 3053 DCA AC1 | |
4572 | 06767 2055 ISZ OPX /DONE ALL 12 MULTIPLIER BITS? | |
4573 | 06770 5344 JMP MPLP /NO-GO ON | |
4574 | 06771 5734 JMP I MP24 /YES-RETURN | |
4575 | 06773 7764 | |
4576 | 06774 7203 | |
4577 | 06775 7110 | |
4578 | 06776 6514 | |
4579 | 06777 6460 | |
4580 | 7000 PAGE | |
4581 | ||
4582 | ||
4583 | /FORTRAN 4 RUNTIME SYSTEM - R.L PAL8-V8 PAGE 82 | |
4584 | ||
4585 | /DIVIDE-BY-ZERO ROUTINE - MUST BE AT BEGINNING Of PAGE | |
4586 | ||
4587 | 07000 2035 DBAD, ISZ FATAL /DIVIDE BY 0 NON-FATAL | |
4588 | 07001 4434 JMS I ERR /GIVE ERROR MSG | |
4589 | 07002 1200 TAD DBAD | |
4590 | 07003 3044 DCA ACX /RETURN A VERY LARGE POSITIVE NUM | |
4591 | 07004 7332 AC2000 | |
4592 | 07005 5325 JMP FD | |
4593 | ||
4594 | 4-24 | |
4595 | \f | |
4596 | ||
4597 | ||
4598 | /FLOATING DIVIDE - USES DIVIDE-AND-CORRECT METHOD | |
4599 | ||
4600 | 07006 4777 DDDIV, JMS I (DARGET | |
4601 | 07007 7410 SKP | |
4602 | 07010 4776 FFDIV, JMS I (ARGET /GET OPERAND | |
4603 | 07011 4775 JMS I (MDSET /GO SET UP FOR DIVIDE-OPX IN AC | |
4604 | 07012 7041 CMA IAC /NEGATE EXP. OF OPERAND | |
4605 | 07013 1044 TAD ACX /ADD EXP OF FAC | |
4606 | 07014 3044 DCA ACX /STORE AS FINAL EXPONENT | |
4607 | 07015 1056 TAD OPH /NEGATE HI ORDER OP. FOR USE | |
4608 | 07016 7141 CLL CMA IAC /AS DIVISOR | |
4609 | 07017 3056 DCA OPH | |
4610 | 07020 4231 JMS DV24 /CALL DIV.--(ACH+ACL)/OPH | |
4611 | 07021 1046 TAD ACL /SAVE QUOT. FOR LATER | |
4612 | 07022 3053 DCA AC1 | |
4613 | 07023 1057 TAD OPL | |
4614 | 07024 7650 SNA CLA | |
4615 | 07025 5327 JMP DVL2 /AVOID MULTIPLYING BY 0 | |
4616 | 07026 1374 TAD (-15 /SET COUNTER FOR 12 BIT MULTIPLY | |
4617 | 07027 3231 DCA DV24 /TO MULTIPLY QUOT. OF DIV. BY | |
4618 | 07030 5267 JMP DVLP1 /LOW ORDER OF OPERAND (OPL) | |
4619 | ||
4620 | /DIVIDE ROUTINE - (ACH,ACL)/OPH = ACL REMAINDER REM | |
4621 | ||
4622 | 07031 0000 DV24, 0 | |
4623 | 07032 1045 TAD ACH /CHECK THAI DIVISOR IS .GT. | |
4624 | 07033 1056 TAD OPH /DIVISOR IN OPH (NEGATIVE) | |
4625 | 07034 7630 SZL CLA /IS IT? | |
4626 | 07035 5200 JMP DBAD /NO-DIVIDE OVERFLOW | |
4627 | 07036 1374 TAD (-15 /YES-SET UP 12 BIT LOOP | |
4628 | 07037 3054 DCA AC2 | |
4629 | 07040 5251 JMP DV1 /GO BEGIN DIVIDE | |
4630 | 07041 1045 DV2, TAD ACH /CONTINUE SHIFT OF FAC LEFT | |
4631 | 07042 7004 RAL | |
4632 | 07043 3045 DCA ACH /RESTORE HI ORDER | |
4633 | 07044 1045 TAD ACH /NOW SUBTRACT DIVISOR FROM HI ORDER | |
4634 | 07045 1056 TAD OPH /DIVIDEND | |
4635 | 07046 7430 SZL /GOOD SUBTRACT? | |
4636 | 07047 3045 DCA ACH /YES-RESTORE HI DIVIDEND | |
4637 | 07050 7200 CLA /NO-DON'T RESTORE--OPH.GT.ACH | |
4638 | 07051 1046 DV1, TAD ACL /SHIFT FAC LEFT 1 BIT-ALSO SHIFT | |
4639 | 07052 7004 RAL /1 BIT OF QUOT. INTO LOW ORD OF ACL | |
4640 | 07053 3046 DCA ACL | |
4641 | 07054 2054 ISZ AC2 /DONE 12 BITS OF QUOT? | |
4642 | 07055 5241 JMP DV2 /NO-GO ON | |
4643 | 07056 5631 JMP I DV24 /YES-RETN W/AC2=0 | |
4644 | ||
4645 | ||
4646 | ||
4647 | ||
4648 | ||
4649 | ||
4650 | ||
4651 | ||
4652 | ||
4653 | 4-25 | |
4654 | \f | |
4655 | ||
4656 | ||
4657 | /FORTRAN 4 RUNTIME SYSTEM - R.L PAL8-V8 PAGE 83 | |
4658 | ||
4659 | /DIVIDE ROUTINE CONTINUED | |
4660 | ||
4661 | 07057 3057 MP12L, DCA OPL /STORE BACK MULTIPLIET | |
4662 | 07060 1054 TAD AC2 /GET PRODUCT SO FAR | |
4663 | 07061 7420 SNL /WAS MULTIPLIER BIT A 1? | |
4664 | 07062 5265 JMP .+3 /NO-JUST SHIFT THE PARTIAL PRODUCT | |
4665 | 07063 7100 CLL /YES-CLEAR LINK AND ADD MULTIPLICAND | |
4666 | 07064 1046 TAD ACL /TO PARTIAL PRODUCT | |
4667 | 07065 7010 RAR /SHIFT PARTIAL PRODUCT-THIS IS HI | |
4668 | 07066 3054 DCA AC2 /RESULT-STORE BACK | |
4669 | 07067 1057 DVLP1, TAD OPL /SHIFT A BIT OUT OF MULTIPLIER | |
4670 | 07070 7010 RAR /AND A BIT OR RESLT. INTO IT (LO | |
4671 | 07071 2231 ISZ DV24 /DONE ALL BITS? | |
4672 | 07072 5257 JMP MP12L /NO-LOOP BACK | |
4673 | 07073 7141 CLL CIA /YES-LOW ORDER PROD. OF QUOT. X | |
4674 | 07074 3046 DCA ACL /NEGATE AND STORE | |
4675 | 07075 7024 CML RAL /PROPAGATE CARRY | |
4676 | 07076 1054 TAD AC2 /NEGATE HI ORDER PRODUCT | |
4677 | 07077 7161 STL CIA | |
4678 | 07100 1045 TAD ACH /COMPARE WITH REMAINDER OF FIRST | |
4679 | 07101 7430 SZL /WELL? | |
4680 | 07102 5331 JMP DVOPS /GREATER THAN REM. - ADJUST QUOT OF | |
4681 | 07103 3045 DCA ACH /OK - DO (REM - (Q*OPL)) / OPH | |
4682 | 07104 4231 DVL3, JMS DV24 /DIVIDE BY OPH (HI ORDER OPERAND) | |
4683 | 07105 1053 DVL1, TAD AC1 /GET QUOT. OF FIRST DIV. | |
4684 | 07106 7500 SMA /IF HI ORDER BIT SET-MUST SHIFT 1 | |
4685 | 07107 5325 JMP FD /NO-ITS NORMALIZED-DONE | |
4686 | 07110 7100 SHR1, CLL | |
4687 | 07111 2046 ISZ ACL /ROUND AND SHIFT RIGHT ONE | |
4688 | 07112 7410 SKP | |
4689 | 07113 7001 IAC /DOUBLE PRECISION INCREMENT | |
4690 | 07114 7010 RAR | |
4691 | 07115 3045 DCA ACH /STORE IN FAC | |
4692 | 07116 1046 TAD ACL /SHIFT LOW ORDER RIGHT | |
4693 | 07117 7010 RAR | |
4694 | 07120 3046 DCA ACL /STORE BACK | |
4695 | 07121 2044 ISZ ACX /BUMP EXPONENT | |
4696 | 07122 7000 NOP | |
4697 | 07123 1045 TAD ACH | |
4698 | 07124 5306 JMP DVL1+1 /IF FRACT WAS 77777777 WE MUST | |
4699 | 07125 3045 FD, DCA ACH /STORE HIGH ORDER RESULT | |
4700 | 07126 5773 JMP I (MDONE /GO LEAVE DIVIDE | |
4701 | ||
4702 | 07127 3046 DVL2, DCA ACL /COME HERE IF LOW-ORDER QUO=0 | |
4703 | 07130 5304 JMP DVL3 /SAVE SOME TIME | |
4704 | ||
4705 | ||
4706 | ||
4707 | ||
4708 | ||
4709 | ||
4710 | ||
4711 | ||
4712 | 4-26 | |
4713 | \f | |
4714 | ||
4715 | ||
4716 | /FORTRAN 4 RUNTIME SYSTEM - R.L PAL8-V8 PAGE 84 | |
4717 | ||
4718 | /ROUTINE TO ADJUST QUOTIENT OF FIRST DIVIDE (MAYBE) WHEN | |
4719 | /REMAINDER OF THE FIRST DIVIDE IS LESS THAN QUOT*OPL | |
4720 | ||
4721 | 07131 7041 DVOPS, CMA IAC /NEGATE AND STORE REVISED REMAINDER | |
4722 | 07132 3045 DCA ACH | |
4723 | 07133 7100 CLL | |
4724 | 07134 1056 TAD OPH | |
4725 | 07135 1045 TAD ACH /WATCH FOR OVERFLOW | |
4726 | 07136 7420 SNL | |
4727 | 07137 5344 JMP DVOP1 /OVERFLOW-DON'T ADJUST QUOT. OF 1 | |
4728 | 07140 3045 DCA ACH /NO OVERFLOW-STORE NEW REM. | |
4729 | 07141 7040 CMA /SUBTRACT 1 FROM QUOT OF | |
4730 | 07142 1053 TAD AC1 /FIRST DIVIDE | |
4731 | 07143 3053 DCA AC1 | |
4732 | 07144 7300 DVOP1, CLA CLL | |
4733 | 07145 1045 TAD ACH /GET HI ORD OF REMAINDER | |
4734 | 07146 7450 SNA /IS IT ZERO? | |
4735 | 07147 3046 DVOP2, DCA ACL /YES-MAKE WHOLE THING ZERO | |
4736 | 07150 3045 DCA ACH | |
4737 | 07151 4231 JMS DV24 /DIVIDE EXTENDED REM. BY HI DIVISOR | |
4738 | 07152 1046 TAD ACL /NEGATE THE RESULT | |
4739 | 07153 7141 CLL CMA IAC | |
4740 | 07154 3046 DCA ACL | |
4741 | 07155 7420 SNL /IF QUOT. IS NON-ZERO, SUBTRACT | |
4742 | 07156 7040 CMA /ONE FROM HIGH ORDER QUOT. | |
4743 | 07157 5305 JMP DVL1 /GO TO IT | |
4744 | ||
4745 | 07160 0000 LPBUF3, ZBLOCK 12 | |
4746 | 07172 7316 LPBUF4 | |
4747 | 07173 6665 | |
4748 | 07174 7763 | |
4749 | 07175 6704 | |
4750 | 07176 6514 | |
4751 | 07177 6460 | |
4752 | 7200 PAGE | |
4753 | ||
4754 | ||
4755 | ||
4756 | ||
4757 | ||
4758 | ||
4759 | ||
4760 | ||
4761 | ||
4762 | ||
4763 | ||
4764 | ||
4765 | ||
4766 | ||
4767 | ||
4768 | ||
4769 | ||
4770 | ||
4771 | 4-27 | |
4772 | \f | |
4773 | ||
4774 | ||
4775 | /FORTRAN 4 RUNTIME SYSTEM - R.L PAL8-V8 PAGE 85 | |
4776 | ||
4777 | /"NRMFAC" AND "OPNEG" MUST BE AT 0 AND 3 ON PAGE | |
4778 | ||
4779 | 07200 3053 NRMFAC, DCA AC1 /KILL OVERFLOW BIT | |
4780 | 07201 4271 JMS FFNOR | |
4781 | 07202 5476 JMP I FPNXT | |
4782 | ||
4783 | 07203 0000 OPNEG, 0 /ROUTINE TO NEGATE OPERAND | |
4784 | 07204 1057 TAD OPL /GET LOW ORDER | |
4785 | 07205 7141 CLL CMA IAC /NEGATE AND STORE BACK | |
4786 | 07206 3057 DCA OPL | |
4787 | 07207 7024 CML RAL /PROPAGATE CARRY | |
4788 | 07210 1056 TAD OPH /GET HI ORDER | |
4789 | 07211 7141 CLL CMA IAC /NEGATE AND STORE BACK | |
4790 | 07212 3056 DCA OPH | |
4791 | 07213 5603 JMP I OPNEG | |
4792 | / | |
4793 | /FLOATING SUBTRACT AND ADD | |
4794 | / | |
4795 | 07214 4777 FFSUB, JMS I (ARGET /PICK UP THE OP. | |
4796 | 07215 4203 JMS OPNEG /NEGATE OPERAND | |
4797 | 07216 7410 SKP | |
4798 | 07217 4777 FFADD, JMS I (ARGET /PICK UP OPERAND | |
4799 | 07220 1056 TAD OPH /IS OPERAND = 0 | |
4800 | 07221 7650 SNA CLA | |
4801 | 07222 5476 JMP I FPNXT /YES-DONE | |
4802 | 07223 1045 TAD ACH /NO-IS FAC=0? | |
4803 | 07224 7650 SNA CLA | |
4804 | 07225 5236 JMP DOADD /YES-DO ADD | |
4805 | 07226 1044 TAD ACX /NO-DO EXPONENT CALCULATION | |
4806 | 07227 7141 CLL CMA IAC | |
4807 | 07230 1055 TAD OPX | |
4808 | 07231 7540 SMA SZA /WHICH EXP. GREATER? | |
4809 | 07232 5243 JMP FACR /OPERANDS-SHIFT FAC | |
4810 | 07233 7041 CMA IAC /FAC'S-SHIFT OPERAND=DIFFRNCE+1 | |
4811 | 07234 4246 JMS OPSR | |
4812 | 07235 4541 JMS I [ACSR /SHIFT FAC ONE PLACE RIGHT | |
4813 | 07236 1055 DOADD, TAD OPX /SET EXPONENT OF RESULT | |
4814 | 07237 3044 DCA ACX | |
4815 | 07240 4537 JMS I [OADD /DO THE ADDITION | |
4816 | 07241 4271 JMS FFNOR /NORMALIZE RESULT | |
4817 | 07242 5476 JMP I FPNXT /RETURN | |
4818 | 07243 4541 FACR, JMS I [ACSR /SHIFT FAC = DIFF.+1 | |
4819 | 07244 4246 JMS OPSR /SHIFT OPR. 1 PLACE | |
4820 | 07245 5236 JMP DOADD /DO ADDITION | |
4821 | ||
4822 | ||
4823 | ||
4824 | ||
4825 | ||
4826 | ||
4827 | ||
4828 | ||
4829 | ||
4830 | 4-28 | |
4831 | \f | |
4832 | ||
4833 | ||
4834 | /FORTRAN 4 RUNTIME SYSTEM - R.L PAL8-V8 PAGE 86 | |
4835 | ||
4836 | /OPERAND SHIFT RIGHT-ENTER WITH POSITIVE COUNT-1 IN AC | |
4837 | ||
4838 | 07246 0000 OPSR, 0 | |
4839 | 07247 7040 CMA /- (COUNT+1) TO SHIFT COUNTER | |
4840 | 07250 3052 DCA AC0 | |
4841 | 07251 1056 LOP2, TAD OPH /GET SIGN BIT | |
4842 | 07252 7100 CLL /TO LINK | |
4843 | 07253 7510 SPA | |
4844 | 07254 7020 CML /WITH HI MANTISSA IN AC | |
4845 | 07255 7010 RAR /SHIFT IT RIGHT, PROPAGATING SIGN | |
4846 | 07256 3056 DCA OPH /STORE BACK | |
4847 | 07257 1057 TAD OPL | |
4848 | 07260 7010 RAR | |
4849 | 07261 3057 DCA OPL /STORE LO ORDER BACK | |
4850 | 07262 2055 ISZ OPX /INCREMENT EXPONENT | |
4851 | 07263 7000 NOP | |
4852 | 07264 2052 ISZ AC0 /DONE ALL SHIFTS? | |
4853 | 07265 5251 JMP LOP2 /NO-LOOP | |
4854 | 07266 7010 RAR /SAVE 1 BIT OF OVERFLOW | |
4855 | 07267 3054 DCA AC2 /IN AC2 | |
4856 | 07270 5646 JMP I OPSR /YES-RETN. | |
4857 | ||
4858 | 07271 0000 FFNOR, 0 /ROUTINE TO NORMALIZE THE FAC | |
4859 | 07272 1045 TAD ACH /GET THE HI ORDER MANTISSA | |
4860 | 07273 7450 SNA /ZERO? | |
4861 | 07274 1046 TAD ACL /YES-HOW ABOUT LOW? | |
4862 | 07275 7450 SNA | |
4863 | 07276 1053 TAD AC1 /LOW=0, IS OVRFLO BIT ON? | |
4864 | 07277 7650 SNA CLA | |
4865 | 07300 5313 JMP ZEXP /#=0-ZERO EXPONENT | |
4866 | 07301 7332 NORMLP, CLA CLL CML RTR /NOT 0-MAKE A 2000 IN AC | |
4867 | 07302 1045 TAD ACH /ADD HI ORDER MANTISSA | |
4868 | 07303 7440 SZA /HI ORDER = 6000 | |
4869 | 07304 5307 JMP .+3 /NO-CHECK LEFT MOST DIGIT | |
4870 | 07305 1046 TAD ACL /YES-6000 OK IF LOW=O | |
4871 | 07306 7640 SZA CLA | |
4872 | 07307 7710 SPA CLA /2,3,4,5,ARE LEGAL LEFT MOST DIGS. | |
4873 | 07310 5314 JMP FFNORR /FOR NORMALIZED #-(+2000=4,5,6,7) | |
4874 | 07311 4534 JMS I (AL1BMP /SHIFT AC LEFT AND BUMP ACX DOWN | |
4875 | 07312 5301 JMP NORMLP /GO BACK AND SEE IF NORMALIZED | |
4876 | 07313 3044 ZEXP, DCA ACX | |
4877 | 07314 3053 FFNORR, DCA AC1 /DONE W/NORMALIZE - CLEAR AC1 | |
4878 | 07315 5671 JMP I FFNOR /RETURN | |
4879 | ||
4880 | 07316 0000 LPBUF4, ZBLOCK 60 | |
4881 | 07376 7400 LPBUFE | |
4882 | 07377 6514 | |
4883 | 7400 PAGE | |
4884 | ||
4885 | ||
4886 | ||
4887 | ||
4888 | ||
4889 | 4-29 | |
4890 | \f | |
4891 | ||
4892 | ||
4893 | CHAPTER 5 | |
4894 | ||
4895 | LIBRA AND FORLIB | |
4896 | ||
4897 | ||
4898 | The binary output of an assembly under RALF is called a RALF module. | |
4899 | Every RALF module consists of an External Symbol Dictionary (or ESD) | |
4900 | and associated text. The ESD lists all global symbols defined in the | |
4901 | assembly, while the text contains the actual binary output along with | |
4902 | relocation data. | |
4903 | ||
4904 | There are three major classes of global symbols. Entry points are | |
4905 | global symbols defined in a module and referenced by code in other | |
4906 | modules. Thus, entry points include the names of all modules and the | |
4907 | names of all globally callable subroutines within modules. Externs are | |
4908 | global symbols that are referenced in a module but not defined in that | |
4909 | module. For example, the entry point of module A would appear as an | |
4910 | extern if referenced in module B. The COMMON area comprises a third | |
4911 | class of global symbols including all global symbols which define | |
4912 | COMMON. | |
4913 | ||
4914 | A FORTRAN IV library is a specially formatted file, created with | |
4915 | LIBRA, consisting of a library catalog (which lists section names and | |
4916 | entry points of library modules) and a set of RALF modules, perhaps | |
4917 | interspersed with empty subfiles. The loader uses one such library, | |
4918 | specified by the user, to resolve externs while building a loader | |
4919 | image file. The general structure of a FORTRAN IV library is: | |
4920 | ||
4921 | ---------------------------------------------------------------- | |
4922 | | CATALOG | MODULE | FREE | MODULE | MODULE | \ | |
4923 | | | | AREA | | | etc. / | |
4924 | | | | | | | \ | |
4925 | ----------------------------------------------------------------- | |
4926 | ||
4927 | LIBRA is a very simple program, basically a file-to-file copy inside | |
4928 | several nested loops. The outer loop begins at START, and calls the | |
4929 | command decoder for specification of the library and input files. If | |
4930 | no library is specified, the previous library name is used (initially | |
4931 | this is SYS:FORLIB.RL). If a new name is given, but no extension is | |
4932 | specified, .RL is forced. A check is made to verify that the | |
4933 | specified library is on a file-structured device, and the handler is | |
4934 | FETCHed. | |
4935 | ||
4936 | At ZTEST, the /Z switch is tested. If it was set, control passes to | |
4937 | NEWLIB to create a new library. Otherwise, an attempt is made to find | |
4938 | an old library of the specified name on the device. If it fails, | |
4939 | control passes to NEWLIB. Otherwise, the catalog of the old library | |
4940 | is read and scanned to determine the starting block of available | |
4941 | space. This is stored at LAVAIL. Control then passes to GETINF to | |
4942 | begin reading input files. | |
4943 | ||
4944 | If /Z was set, or the specified library isn't found, a new library is | |
4945 | entered at NEWLIB, and an empty catalog is written. Control passes to | |
4946 | GETINF. There, a check is made to determine whether input is | |
4947 | ||
4948 | 5-1 | |
4949 | \f | |
4950 | ||
4951 | ||
4952 | presently coming from another library. If it is, control passes to | |
4953 | INLIB to obtain the next module from the library. Otherwise, the next | |
4954 | input file is obtained from the command decoder area in field 1, and | |
4955 | if one exists, control passes to FTCHIN to load the handler. If there | |
4956 | is none, the /C switch is tested. If it is not set, control is passed | |
4957 | to LCLOSE to close the library. If it is set, however, the command | |
4958 | decoder is recalled to obtain a continuation of the preceding input | |
4959 | line, and control returns to NXTINF to look in the command decoder | |
4960 | area. | |
4961 | ||
4962 | At FTCHIN, the unit, starting block, and length of the next input file | |
4963 | are obtained from the command decoder area, the appropriate device | |
4964 | handler is fetched, and at LUKMOD, the input file is read to ensure | |
4965 | that it is either a module or a library. If a library, control passes | |
4966 | to GOTLIB, which sets INLSW and goes to INLIB to obtain the first | |
4967 | module from the library. Otherwise, the length is checked against the | |
4968 | available length in the library, to ensure that this module can be fit | |
4969 | in, and control goes to NXTEBK to read the ESD. | |
4970 | ||
4971 | At INLIB, the catalog of the library being input is read, and scanned | |
4972 | until a module is found with a starting block greater than the | |
4973 | starting block of the last input module (in the case of the first | |
4974 | module in a library, MODBLK, which normally contains the starting | |
4975 | block of a module, contains the starting block of the library, so this | |
4976 | scan yields the starting block of the first module in the library). | |
4977 | When the next module has been found, control returns to LUKMOD to | |
4978 | check the length of the module against the available length in the | |
4979 | library. | |
4980 | ||
4981 | At NXTEBK, the end of the input module is scanned for entry point and | |
4982 | section names. Whenever one is found, the catalog of the output | |
4983 | library is scanned for a matching name. If a match is found, control | |
4984 | passes to GOTMAT, which prints the duplicated name, and if the /I | |
4985 | switch is set, asks the operator which name to keep. If he types N, | |
4986 | for new, control passes to DLETO to delete the old name. Otherwise, | |
4987 | control is passed to ESDLND to find the next entry point or section | |
4988 | name in the input. If /I is not set, /R is tested. If it is not set, | |
4989 | control is passed to ESDLND. If it is, control flows into DELTO, | |
4990 | where the old name is cleared, and the rest of the catalog is scanned | |
4991 | to find the first available name slot. Control then passes to INSERT. | |
4992 | ||
4993 | If no match was found, the /I switch is tested. If it was set, the | |
4994 | operator is asked whether to include the name. If he types, N, for | |
4995 | no, control is passed to ESDLND. Otherwise, or if /I was not set, a | |
4996 | pointer is set up for the new name, and control passes to INSERT, | |
4997 | where the new name is added to the catalog. | |
4998 | ||
4999 | When the entire ESD has been scanned, INCLUD is tested to determine | |
5000 | whether any name has been included in the catalog, and assuming at | |
5001 | least one has, the module is copied into the library, and LAVAIL is | |
5002 | updated to indicate the next available block in the library. Control | |
5003 | returns to GETINF for another module. | |
5004 | ||
5005 | ||
5006 | ||
5007 | 5-2 | |
5008 | \f | |
5009 | ||
5010 | ||
5011 | LCLOSE receives control whenever the end of the input file string is | |
5012 | reached and /C is not set. Here, any remaining changes in the library | |
5013 | catalog are written, and if a new library was entered, it is closed. | |
5014 | Control passes to CATLST, to create a catalog listing. The second | |
5015 | output file, if any was specified, is opened, a title is output to it, | |
5016 | and at PRCAT, the entire contents of the catalog are listed. When | |
5017 | this process is complete, the output file is closed, and control | |
5018 | returns to start for more command decoder input. | |
5019 | ||
5020 | User-coded modules may be added to the system library or incorporated | |
5021 | in a new library provided that entry points, variable storage | |
5022 | allocations, calling sequences, error conditions and the like are | |
5023 | handled with care. | |
5024 | ||
5025 | Every library module must have a unique section (and entry) name(s). | |
5026 | The library supplied by DEC uses the character # before names where | |
5027 | duplication in the FORTRAN program may be possible. Note that this | |
5028 | character is acceptable to RALF, but is illegal in a FORTRAN source. | |
5029 | If more than one entry is required to the routine, they should be | |
5030 | listed as such using the pseudo-op ENTRY before they are encountered | |
5031 | as tags in the code. Thus, if a double precision tangent routine is | |
5032 | being written, it may be helpful to have an entry for a double | |
5033 | precision co-tangent calculation also. Appropriate code would be: | |
5034 | ||
5035 | SECT DTAN | |
5036 | JA #DTAN | |
5037 | ENTRY DCOT | |
5038 | JA #DCOT | |
5039 | . | |
5040 | . | |
5041 | . | |
5042 | #DCOT, | |
5043 | . | |
5044 | . | |
5045 | . | |
5046 | #DTAN, | |
5047 | ||
5048 | When routines will handle double precision or complex values, allocate | |
5049 | six words for their storage. Such routines can switch between the | |
5050 | STARTF (3 word format) and STARTE (6 word format) pseudo-ops as | |
5051 | required, being careful to define variables of the proper length to | |
5052 | keep track of temporary locations. | |
5053 | ||
5054 | All user-written library routines are called by a JSR in STARTF mode. | |
5055 | Depending on the type of function, the routine must be coded to exit | |
5056 | as follows in order to return the result to the program: | |
5057 | ||
5058 | Single precision Answer in AC in STARTF mode | |
5059 | (integer, real and logical) | |
5060 | ||
5061 | FLDA ANSWER /In STARTF mode | |
5062 | JA RETURN /3 word result | |
5063 | ||
5064 | ||
5065 | ||
5066 | 5-3 | |
5067 | \f | |
5068 | ||
5069 | ||
5070 | Double precision: Answer in AC in STARTE mode | |
5071 | ||
5072 | FLDA ANSWER /In STARTE mode | |
5073 | JA RETURN /6 word result | |
5074 | ||
5075 | Complex: Answer in location #CAC in | |
5076 | STARTE mode | |
5077 | ||
5078 | EXTERN #CAC /Real part in first 3 words | |
5079 | STARTE /Imaginary in last 3 words | |
5080 | FLDA ANSWER /Exit in STARTE mode | |
5081 | FSTA #CAC /6 word result | |
5082 | JA RETURN | |
5083 | ||
5084 | Routines should conform to the FPP FORTRAN calling sequence. An | |
5085 | example of that sequence follows: | |
5086 | ||
5087 | SECT DTAN /Sector name | |
5088 | JA #DTAN /Jump to Start of Function | |
5089 | TEXT +DTAN + /6 characters for trace | |
5090 | /back feature must be | |
5091 | /immediately before index | |
5092 | /register assignment. | |
5093 | DTANXR, SETX XRDTAN /This tag referenced when | |
5094 | /returning to reset base | |
5095 | /page and index registers | |
5096 | SETB BPDTAN /if this routine called. | |
5097 | ||
5098 | BPDTAN, F 0.0 /3 words each | |
5099 | XRDTAN, F 0.0 /These locations may be | |
5100 | /used for temporary storage or | |
5101 | ORG 10*3+BPDTAN /If this routine is called, | |
5102 | /will set up return to it. | |
5103 | FNOP | |
5104 | JA DTANXR | |
5105 | 0 | |
5106 | DTNRTN, JA . /Return to calling program | |
5107 | BASE 0 /Still on caller's base page | |
5108 | #DTAN, STARTD /Start of subroutine | |
5109 | FLDA 10*3 /Get jump to caller's return jump | |
5110 | FSTA DTNRTN /Save for return from this routine | |
5111 | FLDA 0 /Get next location in caller's | |
5112 | /routine (pointer to argument list) | |
5113 | SETX XRDTAN /Change index registers to this | |
5114 | /routine's | |
5115 | SETB BPDTAN /Change base page to this routine's | |
5116 | BASE BPDTAN /Change base page to this routine's | |
5117 | FSTA TEMP /Save pointer | |
5118 | LDX 1,1 /Set up XRL | |
5119 | FLDA% TEMP,1 /Get address of argument list | |
5120 | FSTA TEMP /Save it | |
5121 | STARTE /A double precision routine | |
5122 | FLDA% TEMP /Get variable | |
5123 | FSTA TEMP /Save variable | |
5124 | ||
5125 | 5-4 | |
5126 | \f | |
5127 | ||
5128 | ||
5129 | . | |
5130 | . | |
5131 | . /Calculate result | |
5132 | . | |
5133 | . | |
5134 | . | |
5135 | FLDA ANSWER /Load answer | |
5136 | JA DTNRTN /Exit | |
5137 | ||
5138 | The following conventions must be observed to return to the calling | |
5139 | program at the correct location, to permit the error trace back | |
5140 | feature to function properly, and to preserve index registers and base | |
5141 | page integrity. | |
5142 | ||
5143 | Locations 0 and 30 of the called (user-coded) program are determined | |
5144 | by a statement in the form ORG 10*3+BPAGE which must be followed by a | |
5145 | two-word jump to the index register and base page assignment | |
5146 | instructions JA BPXR. In the above example, the code is: | |
5147 | ||
5148 | ORG 10*3+BPDATN | |
5149 | FNOP | |
5150 | JA DTANXR | |
5151 | ||
5152 | By saving the contents of location 30 of the calling program (FLDA | |
5153 | 10*3,FSTA RETURN) for the return exit, the called program executes | |
5154 | (when control is returned to it) a JA BPXR to its base page and index | |
5155 | register assignment statement. In the calling program this resets the | |
5156 | index registers and base page and then returns to execute the | |
5157 | instruction in the calling program. In the tangent example above, the | |
5158 | code is: | |
5159 | ||
5160 | FLDA 10*3 | |
5161 | FSTA DTNRTN | |
5162 | ||
5163 | which creates the instruction | |
5164 | ||
5165 | JA xxx | |
5166 | ||
5167 | at the tag DTNRTN, where xxx is the location in the calling routine | |
5168 | whose function corresponds to DTANXR in DTAN. | |
5169 | ||
5170 | When called, the routine must assign its own base page and index | |
5171 | registers (SETX XROWN, SETB BPOWN). If arguments are to be passed to | |
5172 | the called routine, a scheme such as illustrated above permits any | |
5173 | number of arguments to be passed from the calling program and saved on | |
5174 | the base page of the called program, in this case just two arguments. | |
5175 | ||
5176 | The corresponding code for the calling program (as created by the | |
5177 | compiler) is: | |
5178 | ||
5179 | ||
5180 | ||
5181 | ||
5182 | ||
5183 | ||
5184 | 5-5 | |
5185 | \f | |
5186 | ||
5187 | ||
5188 | EXTERN DTAN | |
5189 | JSR DTAN | |
5190 | JA .+4 /Jump past all arguments | |
5191 | JA A /Argument | |
5192 | . | |
5193 | . | |
5194 | . | |
5195 | FSTA Q /Save result in some variable | |
5196 | ||
5197 | The FORTRAN for such code is: | |
5198 | ||
5199 | Q = DTAN (A) | |
5200 | ||
5201 | The calling sequence is also discussed in Chapter 2. | |
5202 | ||
5203 | To permit the error trace back feature to function properly, a TEXT | |
5204 | statement followed by a six alphanumeric character name is required | |
5205 | immediately before the index register and base page assignment | |
5206 | statements. Thus, if the cotangent routine includes a JSR TAN and an | |
5207 | unacceptable argument is passed to the tangent function, the trace | |
5208 | back indicates the location of the problem by a sequence such as: | |
5209 | ||
5210 | DIV0 MAIN | |
5211 | ARGUMENT | |
5212 | 7777 SIN | |
5213 | 0000 TAN | |
5214 | 0000 COT | |
5215 | 0007 MAIN | |
5216 | ||
5217 | (Line numbers are not relevant in RALF modules such as TAN and SIN: | |
5218 | they are meaningful only in FORTRAN source programs.) | |
5219 | ||
5220 | A new library routine may call other new or existing library routines | |
5221 | as part of its function, as well as the error handling function of the | |
5222 | run-time system. To invoke the error message program, code such as | |
5223 | the following is required: | |
5224 | ||
5225 | EXTERN #ARGER | |
5226 | MERROR, TRAP4 #ARGER | |
5227 | ||
5228 | Then any condition encountered in the program that is an error should | |
5229 | jump to MERROR. For example, if an argument of <=0 is illegal, it | |
5230 | could be examined and handled as follows: | |
5231 | ||
5232 | FLDA% ARG2 | |
5233 | JLE MERROR /<0 error | |
5234 | FSTA NEXT / Save non-zero value | |
5235 | ||
5236 | In this case, the TRAP4 #ARGER at MERROR will produce the message BAD | |
5237 | ARG DTAN nnnn followed by traceback and program termination. If a new | |
5238 | library routine would like to use an existing library routine, a JSR | |
5239 | to that routine is required. The sequence for passing arguments is: | |
5240 | ||
5241 | ||
5242 | ||
5243 | 5-6 | |
5244 | \f | |
5245 | ||
5246 | ||
5247 | EXTERN ATAN2 | |
5248 | JSR ATAN2 | |
5249 | JA .+6 /Execute upon exit from | |
5250 | JA A /1st arg | |
5251 | JA B /2nd arg | |
5252 | FSTA ANSWER /Save answer | |
5253 | ||
5254 | The arguments must be referenced in the order expected by the called | |
5255 | routine and must agree in number and type. The following routines can | |
5256 | can be used in this manner: | |
5257 | ||
5258 | ROUTINE ARGUMENTS PASSED\r _______ ________________ | |
5259 | ||
5260 | AMOD Address of X then Y | |
5261 | SQRT Address of X | |
5262 | ALOG10 Address of X | |
5263 | EXP Address of X | |
5264 | SIN Address of X | |
5265 | COS Address of X | |
5266 | TAN Address of X | |
5267 | SIND Address of X | |
5268 | COSD Address of X | |
5269 | TAND Address of X | |
5270 | ASIN Address of X | |
5271 | ACOS Address of X | |
5272 | ATAN Address of X | |
5273 | ATAN2 Address of X then Y | |
5274 | SINH Address of X | |
5275 | COSH Address of X | |
5276 | TANH Address of X | |
5277 | DMOD Address of X then Y | |
5278 | DSIGN Address of X then Y | |
5279 | DSIN Address of X | |
5280 | DLOG Address of X | |
5281 | DSQRT Address of X | |
5282 | DCOS Address of X | |
5283 | DLOG10 Address of X | |
5284 | DATAN2 Address of X then Y | |
5285 | DATAN Address of X | |
5286 | DEXP Address of X | |
5287 | CMPLX Address of X | |
5288 | CSIN Address of X | |
5289 | CCOS Address of X | |
5290 | REAL Address of X | |
5291 | AIMAG Address of X | |
5292 | CONJG Address of X | |
5293 | CEXP Address of X | |
5294 | CLOG Address of X | |
5295 | CABS Address of X | |
5296 | CSQRT Address of X | |
5297 | ||
5298 | For real and double precision routines, the result is returned via the | |
5299 | FAC (3 or 6 words, respectively). For complex routines, the result is | |
5300 | returned in #CAC (6 words). | |
5301 | ||
5302 | 5-7 | |
5303 | \f | |
5304 | ||
5305 | ||
5306 | The TAN function from FORLIB is included here as an example of the | |
5307 | requirements just discussed. The TAN function calls two external | |
5308 | functions, has the standard calling sequence, and contains an error | |
5309 | condition exit. | |
5310 | ||
5311 | / T A N | |
5312 | / - - - | |
5313 | / | |
5314 | /SUBROUTINE TAN(X) | |
5315 | SECT TAN /SECTION NAME | |
5316 | JA #TAN /JUMP AROUND BASE PAGE | |
5317 | ||
5318 | EXTERN #ARGER | |
5319 | TANER, TRAP4 #ARGER /EXIT TO ERROR MESSAGE HANDLER | |
5320 | TEXT +TAN + /FOR ERROR TRACE BACK | |
5321 | TANXR, SETX XRTAN /START OF FORMAL CALLING SEQUENCE | |
5322 | SETB BPTAN | |
5323 | BTAN, FNOP /START OF BASE PAGE | |
5324 | 0 | |
5325 | 0 | |
5326 | XRTAN, F 0.0 /INDEX REGISTERS | |
5327 | TAN1, F 0.0 /LOCATIONS 21-42 OCTAL AVAILABLE | |
5328 | /FOR USER STORAGE | |
5329 | TAN2, F 0.0 | |
5330 | ORG 10*3+BPTAN /SET UP FOR A RETURN | |
5331 | /TO THIS ROUTINE | |
5332 | FNOP | |
5333 | JA TANXR /JUMP TO XR + RP ASSIGNMENT | |
5334 | 0 | |
5335 | TANRTN, JA . | |
5336 | BASE 0 | |
5337 | #TAN, STARTD | |
5338 | FLDA 10*3 /SAVE RETURN JUMP | |
5339 | FSTA TANRTN | |
5340 | FLDA 0 /GET NEXT LOCATION | |
5341 | /IN CALLING PROGRAM | |
5342 | SETX XRTAN /SET UP FOR TAN'S INDEX REGS | |
5343 | SETB BPTAN /SET UP FOR TAN'S BP | |
5344 | BASE BPTAN | |
5345 | LDX 1,1 | |
5346 | FSTA BPTAN | |
5347 | FLDA% BPTAN,1 /GET ADDRESS OF X | |
5348 | FSTA BPTAN | |
5349 | STARTF | |
5350 | FLDA% BPTAN /GET X | |
5351 | JEQ TANRTN /IF 0 RETURN NOW | |
5352 | FSTA TAN1 /SAVE FOR A SECOND | |
5353 | EXTERN COS | |
5354 | JSR COS /TAKE COS(X) | |
5355 | JA .+4 /JUMP AROUND ARGUMENT LIST | |
5356 | JA TAN1 /REFERENCE TO PASSED ARGUMENT | |
5357 | JEQ TANER /COS=0. A NO-NO | |
5358 | FSTA TAN2 /SAVE IT | |
5359 | EXTERN SIN | |
5360 | ||
5361 | 5-8 | |
5362 | \f | |
5363 | ||
5364 | ||
5365 | JSR SIN /NOW TAKE SIN(X) | |
5366 | JA .+4 /JUMP AROUND ARGUMENT LIST | |
5367 | JA TAN1 /REFERENCE TO ARGUMENT | |
5368 | FDIV TAN2 /DIV BY COS(X) | |
5369 | JA TANRTN /EXIT | |
5370 | ||
5371 | The library routine ONQI illustrates many of the same conventions. | |
5372 | This listing may also prove valuable as a guide to interfacing with | |
5373 | the run-time system. | |
5374 | ||
5375 | FIELD1 ONQI /ROUTINE TO ADD A | |
5376 | /HANDLER TO INTERRUPT SKIP CHAIN | |
5377 | /PUT THIS CODE IN FIELD 1 | |
5378 | 0 | |
5379 | JMP SETINT /SET UP INT INITIALLY | |
5380 | ISZ ONQI /BUMP ARGUMENT POINTER | |
5381 | ISZ INTQ+1 /BUMP INTERRUPT Q POINTER | |
5382 | DCA% INTQ+1 /STICK IOT ONTO INT Q | |
5383 | TAD XSKP /FOLLOWED BY A SKIP | |
5384 | ISZ INTQ+1 | |
5385 | DCA% INTQ+1 /ONTO INT Q | |
5386 | ISZ ONQI /SKIP FIRST WORD OF ADDR | |
5387 | ISZ INTQ+1 | |
5388 | ONQISW, TAD% ONQI /GET INT HANDLER ADDRESS | |
5389 | ISZ ONQI | |
5390 | DCA% INTADR+1 /ONTO ADDRESS STACK | |
5391 | TAD INTADR+1 /NOW MAKE JMS% | |
5392 | AND L177 | |
5393 | TAD L4600 | |
5394 | DCA% INTQ+1 /ONTO INT Q | |
5395 | ISZ INTADR+1 | |
5396 | ISZ IQSIZE /ROOM FOR MORE? | |
5397 | JMP% ONQI /YES | |
5398 | TAD .-1 /NO, CLOSE OUT THE SUBR | |
5399 | DCA ONQI+1 | |
5400 | JMP% ONQI | |
5401 | SETINT, TAD ONQISW /DO THIS PART ONLY ONCE | |
5402 | DCA ONQI+1 | |
5403 | CDF | |
5404 | TAD XSKP /FIX UP #INT | |
5405 | DCA% XINT+1 /PUT SKIP INST. FIRST | |
5406 | ISZ XINT+1 | |
5407 | TAD INTQ+1 | |
5408 | DCA% XINT+1 /GET ADDR. OF USER'S ROUTINE | |
5409 | ISZ XINT+1 /ADD TO INTERRUPT CALL | |
5410 | TAD CIFCDF /GET FIELD INSTRUCTION | |
5411 | /FIELD1 SECTION INSURES ITS IN FIELD 1 | |
5412 | DCA% XINT+1 | |
5413 | CIFCDF, CDF CIF 10 | |
5414 | JMP ONQI+1 /BACK TO ONQI | |
5415 | EXTERN #INT | |
5416 | XINT, ADDR #INT /POINTS TO INT RTN IN COMMON | |
5417 | INTQ, ADDR IHANDL /MUST USE 15 BIT ADDRESS | |
5418 | ||
5419 | ||
5420 | 5-9 | |
5421 | \f | |
5422 | ||
5423 | ||
5424 | INTADR, ADDR IHADRS / " | |
5425 | ||
5426 | IQSIZE, -5 | |
5427 | XSKP, SKP | |
5428 | L177, 177 | |
5429 | L4600, 4600 | |
5430 | CDF CIF | |
5431 | JMP% IHANDL | |
5432 | IHANDL, 0 | |
5433 | REPEAT 16 | |
5434 | JMP IHANDL-2 | |
5435 | IHADRS, 0;0;0;0;0 /CAN SET UP 1-5 DEVICES | |
5436 | ||
5437 | ||
5438 | ENTRY ONQB /USE "ENTRY" TO PERMIT | |
5439 | /ACCESS FROM OUTSIDE OF SECTION | |
5440 | /ROUTINE TO SET UP AN IDLE JOB | |
5441 | ONQB, 0 | |
5442 | JMP SETBAK /SETUP #IDLE | |
5443 | TAD% ONQB /GET ADDRESS OF IDLE JOB | |
5444 | ONQBSW, ISZ ONQB | |
5445 | DCA% BAKADR+1 /STORE ONTO BACKGROUND JOB Q | |
5446 | TAD BAKADR+1 /MAKE A JMS% | |
5447 | ISZ BAKADR+1 | |
5448 | AND L177 | |
5449 | TAD L4600 | |
5450 | ISZ BAKQ+1 | |
5451 | DCA% BAKQ+1 | |
5452 | ISZ BQSIZE /MORE ROOM? | |
5453 | JMP% ONQB /YES | |
5454 | TAD .-1 /NO, CLOSE THE DOOR | |
5455 | DCA ONQB+1 | |
5456 | JMP% ONQB | |
5457 | SETBAK, TAD ONQBSW /CLOSE OFF #IDLE INITIALIZATION | |
5458 | DCA ONQB+1 | |
5459 | CDF | |
5460 | TAD XSKP /FIX UP #IDLE | |
5461 | DCA% XIDLE+1 /ADD SKIP TO IDLE CALL | |
5462 | TAD BAKQ+1 /GET ADDRESS OF ROUTINE | |
5463 | ISZ XIDLE+1 | |
5464 | DCA% XIDLE+1 | |
5465 | ISZ XIDLE+1 | |
5466 | TAD CIFCDF /GET FIELD INSTR. | |
5467 | DCA% XIDLE+1 | |
5468 | CIF CDF 10 | |
5469 | JMP ONQB+1 | |
5470 | EXTERN #IDLE /EXTERNAL REFERENCE | |
5471 | XIDLE, ADDR #IDLE | |
5472 | ||
5473 | BAKQ, ADDR BAKRND | |
5474 | ||
5475 | BAKADR, ADDR BHADRS | |
5476 | ||
5477 | ||
5478 | ||
5479 | 5-10 | |
5480 | \f | |
5481 | ||
5482 | ||
5483 | BQSIZE, -5 | |
5484 | CDF CIF | |
5485 | JMP# BAKRND | |
5486 | BAKRND, 0 | |
5487 | REPEAT 6 | |
5488 | JMP BAKRND-2 | |
5489 | BHADRS, 0;0;0;0;0 /1-5 JOBS | |
5490 | ||
5491 | ||
5492 | ||
5493 | ||
5494 | ||
5495 | ||
5496 | ||
5497 | ||
5498 | ||
5499 | ||
5500 | ||
5501 | ||
5502 | ||
5503 | ||
5504 | ||
5505 | ||
5506 | ||
5507 | ||
5508 | ||
5509 | ||
5510 | ||
5511 | ||
5512 | ||
5513 | ||
5514 | ||
5515 | ||
5516 | ||
5517 | ||
5518 | ||
5519 | ||
5520 | ||
5521 | ||
5522 | ||
5523 | ||
5524 | ||
5525 | ||
5526 | ||
5527 | ||
5528 | ||
5529 | ||
5530 | ||
5531 | ||
5532 | ||
5533 | ||
5534 | ||
5535 | ||
5536 | ||
5537 | ||
5538 | 5-11 | |
5539 | \f | |
5540 | ||
5541 | ||
5542 | APPENDIX A | |
5543 | ||
5544 | RALF Assembler Permanent Symbol Table | |
5545 | ||
5546 | ||
5547 | ||
5548 | Mnemonic Code Mnemonic Code\r ________ ____ ________ ____ | |
5549 | ||
5550 | FPP Memory Reference Instructions FPP Special Format Instructions | |
5551 | ||
5552 | FADD 1000 ADDX 0110 | |
5553 | FADDM 5000 ALN 0010 | |
5554 | FDIV 3000 ATX 0020 | |
5555 | FLDA 0000 FCLA 0002 | |
5556 | FMUL 4000 FEXIT 0 | |
5557 | FMULM 7000 FNEG 0003 | |
5558 | FSTA 6000 FNOP 0040 | |
5559 | FSUB 2000 FNORM 0004 | |
5560 | FPAUSE 0001 | |
5561 | IOT'S JA 1030 | |
5562 | JAC 0007 | |
5563 | FPINT 6551 JAL 1070 | |
5564 | FPICL 6552 JEQ 1000 | |
5565 | FPCOM 6553 JGE 1010 | |
5566 | FPHLT 6554 JGT 1060 | |
5567 | FPST 6555 JLE 1020 | |
5568 | FPRST 6556 JLT 1050 | |
5569 | FPIST 6557 JNE 1040 | |
5570 | JSA 1120 | |
5571 | 8-Mode Memory Reference Instructions JSR 1130 | |
5572 | JXN 2000 | |
5573 | AND 0000 SETB 1110 | |
5574 | TAD 1000 SETX 1100 | |
5575 | ISZ 2000 STARTD 0006 | |
5576 | DCA 3000 STARTE 0050 | |
5577 | JMS 4000 STARTF 0005 | |
5578 | JMP 5000 TRAP3 3000 | |
5579 | IOT 6000 TRAP4 4000 | |
5580 | OPR 7000 TRAP5 5000 | |
5581 | TRAP6 6000 | |
5582 | TRAP7 7000 | |
5583 | XTA 0030 | |
5584 | ||
5585 | ||
5586 | ||
5587 | ||
5588 | ||
5589 | ||
5590 | ||
5591 | ||
5592 | ||
5593 | ||
5594 | ||
5595 | ||
5596 | ||
5597 | A-1 | |
5598 | \f | |
5599 | ||
5600 | ||
5601 | Mnemonic\r ________ | |
5602 | ||
5603 | Pseudo-Operators | |
5604 | ||
5605 | ADDR | |
5606 | BASE | |
5607 | COMMON | |
5608 | COMMZ | |
5609 | DECIMAL | |
5610 | DPCHK | |
5611 | E | |
5612 | END | |
5613 | ENTRY | |
5614 | EXTERN | |
5615 | F | |
5616 | FIELD1 | |
5617 | IFNDEF | |
5618 | IFNEG | |
5619 | IFNZRO | |
5620 | IFPOS | |
5621 | IFREF | |
5622 | IFZERO | |
5623 | INDEX | |
5624 | LISTOFF | |
5625 | LISTON | |
5626 | OCTAL | |
5627 | ORG | |
5628 | REPEAT | |
5629 | SECT | |
5630 | SECT8 | |
5631 | TEXT | |
5632 | ZBLOCK | |
5633 | IFFLAP | |
5634 | IFRALF | |
5635 | IFSW | |
5636 | IFNSW | |
5637 | ||
5638 | ||
5639 | ||
5640 | ||
5641 | ||
5642 | ||
5643 | ||
5644 | ||
5645 | ||
5646 | ||
5647 | ||
5648 | ||
5649 | ||
5650 | ||
5651 | ||
5652 | ||
5653 | ||
5654 | ||
5655 | ||
5656 | A-2 | |
5657 | \f | |
5658 | ||
5659 | ||
5660 | ||
5661 | APPENDIX B | |
5662 | ||
5663 | ASSEMBLY INSTRUCTIONS for OS/8 | |
5664 | ||
5665 | ||
5666 | The following sequence of commands may be used to assemble the OS/8 | |
5667 | FORTRAN IV system programs. It is assumed that all PAL language | |
5668 | sources reside on DSK. In this example, DTA1 is shown as the target | |
5669 | device, however any other device could be used via the appropriate | |
5670 | ASSIGN command. Note that PASS2O.SV is produced by conditional | |
5671 | assembly of PASS2.PA and that the "O" in PASS2O is an oh, not a zero. | |
5672 | The initial dot and asterisk characters on every command line shown | |
5673 | are printed by the monitor. All other characters (except carriage | |
5674 | return, in some cases) are typed by the user. Type CTRL/Z after each | |
5675 | of the three system pauses at point (1), to continue assembly of | |
5676 | PASS2O. Type ALT MODE to produce the "$" character. | |
5677 | ||
5678 | .ASSIGN DTA1 DEV | |
5679 | .R PAL8 | |
5680 | *F4.BN,LIST.LS<F4$ | |
5681 | .R ABSLDR | |
5682 | *F4$ | |
5683 | .SAVE DEV F4=0;12200$ | |
5684 | .R PAL8 | |
5685 | *PASS2.BN,LIST.LS<PASS2$ | |
5686 | .R ABSLDR | |
5687 | *PASS2$ | |
5688 | .SAVE DEV PASS2=0;5000$ | |
5689 | .R PAL8 | |
5690 | *PASS2O.BN,LIST.LS<TTY:,DSK:PASS2$OVERLY=1 (1) | |
5691 | .R ABSLDR | |
5692 | .PASS2O$ | |
5693 | .SAVE DEV PASS2O=0;7605$ | |
5694 | .R PAL8 | |
5695 | *PASS3.BN,LIST.LS<PASS3$ | |
5696 | .R ABSLDR | |
5697 | *PASS3$ | |
5698 | .SAVE DEV PASS3=0;400$ | |
5699 | .R PAL8 | |
5700 | *RALF.BN,LIST.LS<RALF$ | |
5701 | .R ABSLDR | |
5702 | *RALF$ | |
5703 | .SAVE DEV RALF=0;200$ | |
5704 | .R PAL8 | |
5705 | *LOAD.BN,LIST.LS<LOAD$ | |
5706 | .R ABSLDR | |
5707 | *LOAD$ | |
5708 | .SAVE DEV LOAD=0;200$ | |
5709 | .R PAL8 | |
5710 | *FRTS.BN,LIST.LS<RTS,RTL$ | |
5711 | .R ABSLDR | |
5712 | *FRTS$ | |
5713 | .SAVE DEV FRTS=0;200$ | |
5714 | ||
5715 | B-1 | |
5716 | \f | |
5717 | ||
5718 | ||
5719 | .R PAL8 | |
5720 | *LIBRA.BN,LIST.LS<LIBRA$ | |
5721 | .R ABSLDR | |
5722 | *LIBRA$ | |
5723 | .SAVE DEV LIBRA=0;200$ | |
5724 | . | |
5725 | ||
5726 | ||
5727 | ||
5728 | ASSEMBLY INSTRUCTIONS for OS/278 and OS/78 | |
5729 | ||
5730 | ||
5731 | The following BATCH file lists the sequence of commands that may be | |
5732 | used to assemble the OS/278 FORTRAN IV system programs. All the PAL | |
5733 | language sources reside on the device assigned to SRCE, and all output | |
5734 | files go to the device assigned to TARG. The SYS device is used to | |
5735 | store the binary files until the programs are SAved. Note that | |
5736 | PASS2O.SV is produced by conditional assembly of PASS2.PA and that the | |
5737 | "O" in PASS2O is an oh, not a zero. | |
5738 | ||
5739 | If these commands are typed in, the initial "}" and asterisk (*) | |
5740 | characters on every command line shown are printed by the monitor. | |
5741 | All other characters (except carriage return, in some cases) are typed | |
5742 | by the user. | |
5743 | ||
5744 | To use these commands with OS/78, replace the "}" with a ".". | |
5745 | ||
5746 | ||
5747 | $JOB (FORGEN.BI) ASSEMBLE FORTRAN IV FOR OS278 | |
5748 | ||
5749 | /}ASSIGN XXX SRCE where XXX is the device containing the source files | |
5750 | /}ASSIGN YYY TARG where YYY is the output device for the .SV files | |
5751 | ||
5752 | }PAL F4<SRCE:F4 | |
5753 | }LOAD F4 | |
5754 | }SAVE TARG:F4.SV;12200=100 | |
5755 | }DELETE F4.BN | |
5756 | ||
5757 | }PAL PASS2<SRCE:PASS2 | |
5758 | }LOAD PASS2 | |
5759 | }SAVE TARG:PASS2.SV;5000=100 | |
5760 | }DELETE PASS2.BN | |
5761 | ||
5762 | }PAL PASS2O<SRCE:PASS2O,PASS2 | |
5763 | }LOAD PASS2O | |
5764 | }SAVE TARG:PASS2O.SV;7605=100 | |
5765 | }DELETE PASS2O.BN | |
5766 | ||
5767 | }PAL PASS3<SRCE:PASS3 | |
5768 | }LOAD PASS3 | |
5769 | }SAVE TARG:PASS3.SV;400=100 | |
5770 | }DELETE PASS3.BN | |
5771 | ||
5772 | ||
5773 | ||
5774 | B-2 | |
5775 | \f | |
5776 | ||
5777 | ||
5778 | }PAL LOAD<SRCE:LOAD | |
5779 | }LOAD LOAD | |
5780 | }SAVE TARG:LOAD.SV;200=100 | |
5781 | }DELETE LOAD.BN | |
5782 | ||
5783 | }PAL FRTS<SRCE:RTS,RTL /W/K | |
5784 | }LOAD FRTS | |
5785 | }SAVE TARG:FRTS.SV;200=100 | |
5786 | }DELETE FTRS.BN | |
5787 | ||
5788 | }PAL RALF<SRCE:RALF /W | |
5789 | }LOAD RALF | |
5790 | }SAVE TARG:RALF.SV;200=100 | |
5791 | }DELETE RALF.BN | |
5792 | ||
5793 | }PAL LIBRA<SRCE:LIBRA | |
5794 | }LOAD LIBRA | |
5795 | }SAVE TARG:LIBRA.SV;200=100 | |
5796 | }DELETE LIBRA.BN | |
5797 | ||
5798 | $END | |
5799 | ||
5800 | ||
5801 | ||
5802 | ||
5803 | ||
5804 | ||
5805 | ||
5806 | ||
5807 | ||
5808 | ||
5809 | ||
5810 | ||
5811 | ||
5812 | ||
5813 | ||
5814 | ||
5815 | ||
5816 | ||
5817 | ||
5818 | ||
5819 | ||
5820 | ||
5821 | ||
5822 | ||
5823 | ||
5824 | ||
5825 | ||
5826 | ||
5827 | ||
5828 | ||
5829 | ||
5830 | ||
5831 | ||
5832 | ||
5833 | B-3 | |
5834 | \f | |
5835 | ||
5836 | ||
5837 | ||
5838 | INDEX | |
5839 | ||
5840 | ||
5841 | ||
5842 | Argument passing, 2-7 Idle jobs, 4-1 | |
5843 | Arithmetic expression Indirect addressing, 2-5 | |
5844 | analyzer, 1-1 Interrupts, | |
5845 | Servicing, 4-1, 4-14 | |
5846 | Spurious, 4-14 | |
5847 | Background Jobs, 4-1 | |
5848 | Binary buffer table, 3-9 | |
5849 | Binary section table, 3-10 Keyword, 1-1 | |
5850 | Block count sequence number, 4-13 | |
5851 | ||
5852 | LIBRA, 5-2 | |
5853 | COMMON information block, 1-7 Library, 2-1 | |
5854 | Communication, 2-7 Format, 5-1 | |
5855 | COMMZ sections, 2-10 Line printer handler, 4-13 | |
5856 | Compilation, 1-1 Literals, 1-4, 1-5 | |
5857 | Compiler symbol table, 1-2 Loader, 3-1 | |
5858 | Core maps, 3-2 to 3-4 | |
5859 | Image file, 3-13 | |
5860 | Device handlers, 4-14 Subroutines, | |
5861 | Device flag handlers, 4-2 Loader symbol table, 3-1, 3-7 | |
5862 | Dimension information block, 1-5 | |
5863 | DSRN table, 4-8 | |
5864 | Magic number, 1-5 | |
5865 | Mixing code, 2-6 | |
5866 | Module, 2-1 | |
5867 | Entry point, 2-1 Module count table, 3-12 | |
5868 | EQUIVALENCE information table, Module descriptor table, 3-11 | |
5869 | 1-6 | |
5870 | ESD, 2-1, 2-2, 2-4 | |
5871 | ESD correspondence table, 3-9 Off-page references, 2-17 | |
5872 | External symbol, 2-2 Optimized code, 2-9 | |
5873 | External symbol dictionary, 2-1, Output codes, 1-7 | |
5874 | 2-2, 2-4 Overlay table, 3-10 | |
5875 | ||
5876 | ||
5877 | FIELD1 sections, 2-11 /P option, 4-20 | |
5878 | Files, 4-9 Page boundaries, 2-11 | |
5879 | Formatted I/O, 4-9 PASS1, 1-1 | |
5880 | FRTS Output, 1-7 | |
5881 | Calling sequence, 4-3 Subroutines, 1-10 | |
5882 | Core maps, 4-5 to 4-7 PASS2, 1-12 | |
5883 | Entry points, 4-4 Error list, 1-14 | |
5884 | Initialization, 4-13 Skeleton tables, 1-14 | |
5885 | Page zero, 4-10 Symbol table, 1-14 | |
5886 | Subroutines, 1-16 | |
5887 | Header block, 3-13 Pass3, 1-17 | |
5888 | ||
5889 | ||
5890 | ||
5891 | ||
5892 | X-1 | |
5893 | \f | |
5894 | ||
5895 | ||
5896 | PDP-8 code, 2-5 | |
5897 | Program loading, 3-9 | |
5898 | Program termination, 4-21 | |
5899 | Pseudo-ops, 2-3 to 2-6, | |
5900 | 2-16 to 2-18, 5-3 | |
5901 | ||
5902 | ||
5903 | RALF, 2-1 | |
5904 | Expressions, 2-3 | |
5905 | Symbol table, 2-3 | |
5906 | RALF output file, 2-4 | |
5907 | ||
5908 | ||
5909 | Section, 2-1 | |
5910 | Section types, 2-9 | |
5911 | Statement number, 1-3 | |
5912 | Subroutine calls, 2-7 | |
5913 | Subroutine return sequence, 2-8 | |
5914 | Symbol table, | |
5915 | Compiler, 1-14 | |
5916 | Loader, 3-7 | |
5917 | RALF, 2-4 | |
5918 | ||
5919 | ||
5920 | Termination, program, 4-21 | |
5921 | Text, 2-1 | |
5922 | TRAP3 and TRAP4, 2-6 | |
5923 | ||
5924 | ||
5925 | Variable type word, 1-2 | |
5926 | ||
5927 | ||
5928 | 8-mode sections, 2-11 | |
5929 | ||
5930 | ||
5931 | ||
5932 | ||
5933 | ||
5934 | ||
5935 | ||
5936 | ||
5937 | ||
5938 | ||
5939 | ||
5940 | ||
5941 | ||
5942 | ||
5943 | ||
5944 | ||
5945 | ||
5946 | ||
5947 | ||
5948 | ||
5949 | ||
5950 | ||
5951 | X-2 | |
5952 | \f | |
5953 | ||
5954 | ||
5955 | DEC-S8-LFSSA-A-D | |
5956 | OS/8 FORTRAN IV | |
5957 | SOFTWARE SUPPORT MANUAL | |
5958 | ||
5959 | ||
5960 | READER'S COMMENTS | |
5961 | ||
5962 | ||
5963 | Digital Equipment Corporation maintains a continuous effort to improve | |
5964 | the quality and usefulness of its publications. To do this effectively | |
5965 | we need user feedback--your critical evaluation of this document. | |
5966 | ||
5967 | ||
5968 | Did you find errors in this document? If so, please specify by page. | |
5969 | ||
5970 | ______________________________________________________________________ | |
5971 | ______________________________________________________________________ | |
5972 | ______________________________________________________________________ | |
5973 | ______________________________________________________________________ | |
5974 | ______________________________________________________________________ | |
5975 | ||
5976 | ||
5977 | How can this document be improved? | |
5978 | ||
5979 | ______________________________________________________________________ | |
5980 | ______________________________________________________________________ | |
5981 | ______________________________________________________________________ | |
5982 | ______________________________________________________________________ | |
5983 | ______________________________________________________________________ | |
5984 | ||
5985 | ||
5986 | How does this document compare with other technical documents you | |
5987 | have read? | |
5988 | ||
5989 | ______________________________________________________________________ | |
5990 | ______________________________________________________________________ | |
5991 | ______________________________________________________________________ | |
5992 | ______________________________________________________________________ | |
5993 | ______________________________________________________________________ | |
5994 | ||
5995 | ||
5996 | ||
5997 | Job Title_________________________________ Date:______________________ | |
5998 | ||
5999 | Name:__________________________ Organization:_________________________ | |
6000 | ||
6001 | Street:________________________ Department:___________________________ | |
6002 | ||
6003 | City:_________________ State:___________ Zip or Country_______________ | |
6004 | ||
6005 | ||
6006 | ||
6007 | ||
6008 | ||
6009 | ||
6010 | ||
6011 | \f | |
6012 | ||
6013 | ||
6014 | ||
6015 | ||
6016 | ||
6017 | ||
6018 | ||
6019 | ||
6020 | ||
6021 | ||
6022 | ||
6023 | ||
6024 | ||
6025 | ||
6026 | ||
6027 | ||
6028 | ||
6029 | ||
6030 | ||
6031 | -------------------------------Fold Here------------------------------ | |
6032 | ||
6033 | ||
6034 | ||
6035 | ||
6036 | ||
6037 | ||
6038 | ||
6039 | ||
6040 | ||
6041 | ||
6042 | ||
6043 | ||
6044 | ||
6045 | ||
6046 | ||
6047 | ||
6048 | ||
6049 | -----------------Do Not Tear - Fold Here and Staple------------------- | |
6050 | ||
6051 | +---------------+ | |
6052 | | FIRST CLASS | | |
6053 | | PERMIT NO. 33 | | |
6054 | | MAYNARD. MASS.| | |
6055 | +---------------+ | |
6056 | BUSINESS REPLY MAIL ======== | |
6057 | NO POSTAGE STAMP NECESSARY IF MAILED IN THE UNITED STATES ======== | |
6058 | ====================================================================== | |
6059 | Postage will be paid by: ======== | |
6060 | ======== | |
6061 | +-+-+-+-+-+-+-+ ======== | |
6062 | |d|i|g|i|t|a|l| ======== | |
6063 | +-+-+-+-+-+-+-+ ======== | |
6064 | Digital Equipment Corporation ======== | |
6065 | Software Information Service ======== | |
6066 | Software Engineering and Services ======== | |
6067 | Maynard, Massachusetts 01754 ======== | |
6068 |