README0000600002565200256520000000264113044137400010051 0ustar jncjncThis TAR file includes all the files needed to run, and re-assemble, the DEC MACRO-11 for Unix V6. All the command binaries will run fine under 'vanilla' V6, either under an emulator such as Ersatz-11 (see here: http://www.chiappa.net/~jnc/tech/V6Unix.html for how to do so) or SIMH, or on real hardware (the latter two options are un-tested, but there's no reason to expect they won't work). It's written in MACRO-11, and produces .REL format relocatable binary files. (See the man page for .REL if you care.) The source includes a file to define all the UNIX system calls, unix.mac. The source currently (in dma1.mac) calls for this to be in /include; you can put this wherever you want, provided you edit the location in dma1.mac (at the top). Note that MACRO-11 does currently have a 'mis-feature' where if it can't find an include file, you don't get an error message! Re-building MACRO requires two new (to Unix V6) tools, 'bind' and 'relld'. 'relld' converts from .REL format to a.out. I don't know which version, of the three provided here, corresponds to the binary included here. In any event, since it's in C, that should not be a big deal. 'bind' is a linker for .REL format files: it is written in BCPL, and so there's no point in releasing the source by itself; it will come out when the BCPL compiler does (since re-compiling that requires 'bind'). See the 'run' file for the exact steps to create a new 'macro'. docs/0000700002565200256520000000000013044134472010122 5ustar jncjncdocs/bind.10000600002565200256520000000657213044134472011134 0ustar jncjnc.th BIND I "May 18, 1977" .sh NAME bind \*- .rel module linker .sh SYNOPSIS .bd bind [ \fB\*-m\fR ] [ \fB\*-d\fR ] [ \fB\*-t\fIn\fR ] [ \fB\*-b\fIn\fR ] outfile infile ... .sh DESCRIPTION .it Bind concatenates one or more relocatable object modules (see `rel\ (V)') producing a single relocatable object module as output. The primary use of .it bind is to combine the separate object modules which make up large programs into the single object module required for input to .it "relld (VI)." In addition, all the inter-module references among the bound component modules are pre-linked at bind time. Optionally, .it bind will produce a memory map and/or produce an output file suitable for use by the absolute loader (see `lda\ (V)'). .s3 The options to .it bind are: .s3 .lp +6 5 \fB\*-m\fR Outputs a memory map of the result module to `\fIoutfile\fB.map\fR'. .s3 .lp +6 5 \fB\*-d\fR Prints debugging information. If the .bd \*-m switch is also specified, the map file will contain maps for each input file following the map for the output file. .s3 .lp +6 5 \fB\*-t\fIn\fR Causes .it bind to output an absolute loader format file with the top location program at .it n. Since the absolute loader does not know about separate I and D space, each input file is forced to be .it mixid (see the description of the assembler). .s3 .lp +6 5 \fB\*-b\fIn\fR Like .bd \*-t except .it n specifies the bottom location of the program. .i0 .dt .s2 The action of the binder depends on the options used. If neither .bd \*-t nor .bd \*-b are used, then \fIinfile1\fB.rel\fR \fIinfile2\fB.rel\fP ... \fIinfilen\fB.rel\fR are bound together and placed in \fIoutfile\fB.rel\fR. If an absolute file is needed, then use either the .bd \*-t or .bd \*-b switch. Both switches can be optionally followed by an octal number. Zero is assumed if none is specified. The .bd -t switch tells the binder to make the top of your program at the given number. A .bd \*-t0 or just .bd \*-t is like .bd \*-t200000, which will put your program at the very top of core. The .bd \*-b switch tells the binder to make the bottom of your program at the given number. In either case, the output will be in \fIoutfile\fB.lda\fR. If .bd \*-m is used, then a map file will be produced containing memory maps of the output file and all the input files. If -d was used then the program load point, the program start address, and the program size will be typed along with some debugging information. .s2 Since the binder has all the input files open at once, and UNIX allows only 20 open files at once, there is a limit of 19 input files if no map file is produced and 18 input files if a map file is produced. .s3 .dt Here are some example command lines: .s2 .ft B >bind prog phase1 phase2 phase3 phase4 -m .ft .s2 The above will bind the four phases together and place the result in .bd prog.rel. In addition, a map of the output will be placed in .bd prog.map. .s2 .ft B >bind teco teco tec3 -t0 -m .ft .s2 The above will bind teco and tec3 together and produce .bd teco.load and .bd teco.map. When loaded, .bd teco.load will be at the top of core. The map file tells where each csect and global symbol was allocated. .sh FILES .ta \w'outfile.map 'u outfile.rel output file .br outfile.map map file .br infile.rel input file .sh "SEE ALSO" relld(VI), macro(I), lda(V), rel(V), `MACRO\*-11 Assembler Programmer's Manual'. .sh DIAGNOSTICS The diagnostics are supposed to be self-explanatory. docs/rel.50000600002565200256520000001400713044134377011002 0ustar jncjnc.th REL V "August 1, 1977" .sh NAME \&.rel \*- relocatable object module format .sh DESCRIPTION .it \&.rel files are the runnable object files on the Delphi time-sharing system, and are output by .it macro (I) and .it bind (I), which have been modified to run under UNIX. .s3 Gross structure: .lp +5 5 I. Identification information: title, prerequisite, time/date created. .lp +5 5 II. Symbol directory: gives CSECT names, entry names, global and (if desired) internal symbols, their values and their attributes. .lp +5 5 III. Text: a sequence of text blocks and relocation directives interspersed, which indicate the actual code and data content of the module. .i0 .s3 .lp +5 5 I. Identification information: .lp +10 5 A. Date/time created (6 bytes) - DELPHI format. .lp +10 5 B. Title (.asciz) - object module title. .lp +10 5 C. Prerequisite (.asciz) - a single zero byte means there is no prerequisite. .s3 .lp +5 5 II. Symbol dictionary: a sequence of commands declaring symbols. Associated with each symbol is an implicit numerical ID, which is the index of this command in the directory (i.e., the index of the first symbol is zero, the second is 1, and so on). The first byte of the command identifies the type of symbol and determines the format of the remainder of the command. Arbitrary numbers of zero bytes may be inserted anywhere between commands. The commands are: .lp +10 5 1. CS (byte) - declares a CSECT .lp +12 2 attributes (byte) - bits (starting at bit 0) are: external/internal; I/D space; pure/impure; absolute/relocatable .lp +12 2 length (2 bytes) - length in bytes .lp +12 2 name (.asciz) - .asciz string .lp +10 5 2. ST (byte) - declares a symbol table name (e.g., the name of one object module that was bound into this one). However, any symbol can serve as a symbol table name, so the ST declaration is more of a "place holder" for otherwise homeless symbols than anything else. .lp +12 2 attributes (byte) - no attributes for now .lp +12 2 table (2 bytes) - ID of the symbol table it belongs to (or -1 if none). .lp +12 2 name (.asciz) .lp +10 5 3. SYM (byte) - declares a symbol .lp +12 2 attributes (byte) - bits are external/internal; defined/undefined. Other attributes are determined by what CSECT the symbol belongs to. .lp +12 2 value (2 bytes) - value of the symbol (offset in CSECT) .lp +12 2 CSECT (2 bytes) - ID of the CSECT it belongs to .lp +12 2 table (2 bytes) - ID of the symbol table it belongs to (or -1 if none) .lp +12 2 name (.asciz) - name of the symbol .lp +10 5 4. ENTRY (byte) - declare an entry point .lp +12 2 attributes (byte) - I can't think of any attributes! .lp +12 2 value (2 bytes) - offset in CSECT .lp +12 2 CSECT (2 bytes) - CSECT ID .lp +12 2 spares (10 bytes) - could be used for access, psw, etc. .lp +12 2 name (.asciz) - name of the entry point .lp +10 5 5. END (byte) - marks the end of the symbol directory and the beginning of the text section. .lp +10 5 6. MIXID (byte) - don't distinguish between pure I and pure D space (MIXID must occur before anything else in the symbol directory, and is not indexed with an ID). .lp +10 5 7. HBF (byte) - specifies that the most significant byte of of a 16-bit word has a lower address than the least significant byte (as in the Motorola 6800 and opposed to the DEC PDP-11 and INTEL 8080). HBF must occur before anything (except MIXID) in the symbol directory, and is not indexed with an ID. .lp +10 5 8-20. reserved. .s3 .lp +5 5 III. Text - a sequence of commands, in a format described below. Zero or more zero bytes may serve as filler between successive commands. Each command is introduced by a byte, which indicates what the command is, followed by a variable number of arguments, depending on the command. If the high-order bit of the byte is set, the command operates on bytes rather than on words, except where this distinction is clearly inapplicable (e.g., the "set location counter" request). The commands are listed here by command number: .lp +10 5 21. TXT (byte) - declares a block of binary text .lp +12 2 length (byte) - number of bytes of text that follow .lp +12 2 text ("length" bytes) - put this block of text in core starting at the corrent position of the location counter. .lp +10 5 22. TXTR (byte) - repeat block .lp +12 2 length (byte) .lp +12 2 count (2 bytes) - repeat the text block "count" times. Also causes any relocation directives for this text block to be repeated for each instance of the text block. .lp +12 2 text ("length" bytes) .lp +10 5 23. ABS (byte) - used for #A, where A is in the same CSECT .lp +12 2 offset (byte) - into most recent text block. Adds base address of current CSECT to word/byte at "offset". .lp +10 5 24. REL (byte) - used for A, where A is absolute .lp +12 2 offset (byte) - subtracts base address of current CSECT from datum at "offset" bytes into most recent text block. .lp +10 5 25. ABSX (byte) - used for #A, where A is global or in another CSECT .lp +12 2 offset (byte) - adds value of ID (base address if ID refers to a CSECT, value if ID refers to an external symbol) to datum specified by "offset". .lp +12 2 ID (2 bytes) .lp +10 5 26. RELX (byte) - this turns out to be almost useless! .lp +12 2 offset (byte) - subtracts value of ID from datum. .lp +12 2 ID (2 bytes) .lp +10 5 27. LCS (byte) - used for .BLKW .lp +12 2 constant (2 bytes) - sets location counter to (current CSECT base) + "constant". .lp +10 5 28. LCSX (byte) - used for moving to a new CSECT .lp +12 2 constant (2 bytes) - sets location counter to (value of ID) + "constant". .lp +12 2 ID (2 bytes) .lp +10 5 29.-63. SPEC (byte) - used for, e.g., LISP .lp +12 2 length (byte) - length of text below .lp +12 2 code length (2 bytes) - SPEC block adds this amount to location counter. .lp +12 2 text ("length" bytes) - arbitrary sequence of bytes. The standard loader will not process SPEC blocks, but user-defined loaders might. Relocation directives do not apply to SPEC blocks. .lp +10 5 64-127. Reserved for use by librarian, etc. .i0 .s3 The end of the object module is marked by the end of the file. .sh "SEE ALSO" macro (I), bind (I), relld (VI), reldld (VI), a.out (V) docs/relld.60000600002565200256520000000331013044134450011306 0ustar jncjnc.th RELLD VI "August 1, 1977" .sh NAME relld \*- .rel file loader .sh SYNOPSIS .bd relld [ .bd -srm ] in_file out_file .sh DESCRIPTION .it Relld is a program to convert a file in .rel format (see .it rel (V)) to a file in one of the UNIX exec formats (see .it a.out (V)). .it Relld places IPURE csects into the UNIX text segment, and DPURE and STATIC csects into the UNIX data segment. With no options, .it relld expects .it in_file to be a .rel file and creates .it out_file to be in 411 format, i.e. with separate I and D spaces. When used with the .bd -s option, symbols will be included in the file. When used with the .bd -r option, the file will be in 407 format with relocation bits and symbols. Files in this format can be used with .it ld (I) to bind in other UNIX object files and library routines. The .bd -m option causes a map of the symbols to be output to the standard output (used mainly for .it relld debugging). .s3 .it Relld treats the undefined global symbols ``_etext'', ``_edata'', and ``_end'' the same way .it ld (I) does. i.e. they are defined by .it relld as the first location about the program, the first location above the initialized data, and the first location above all data respectively. .sh FILES .sh "SEE ALSO" .lp +14 14 macro (I) MACRO-11 compatible assembler producing .rel files .lp +14 14 bind (I) .rel file binder and .rel to .lda converter .lp +14 14 ld (I) UNIX loader .lp +14 14 a.out (V) UNIX object file format .lp +14 14 rel (V) .rel file format .i0 .sh BUGS Unlike .it ld (I), it is not an error to define the special symbols ``_etext'', ``_edata'', and ``_end''. .s3 There is no way to produce 410 (pure text) files directly. .s3 The MIXID directive is ignored (should force 410 file). docs/macro.10000600002565200256520000000573613044134304011314 0ustar jncjnc.th MACRO I 15\ March\ 1977 .sh NAME macro \*- macro assembler .sh SYNOPSIS \fBas\fP [ options ] \fIname\fP\*|.\*|.\*|. .sh DESCRIPTION \fIMacro\fP is a (barely recognizable) version of DEC's macro-assembler (DMA-11). It assembles the concatenation of the named files, after first appending the suffix `\fB.mac\fP' to each name. The output of the assembler is left in the files `\fIname\fP\fB.rel\fP' (object file), `\fIname\fP\fB.lst\fP' (assembly listing), and `\fIname\fP\fB.crf\fP' (cross reference information) unless the \fB\*-na\fP option is given. The output of this assembler is in \fIrel\fP-format, so that it must first be converted into the standard load-file format through the use of \fIrelld\fP. .s2 For the use of this assembler, see the DEC publication `\fIMacro-11 Assembler Programmer's Manual\fP'. The major differences and incompatibilities between \fImacro\fP and the description in the manual are listed here. .s2 .lp +8 8 1) Command line options are in standard UNIX form; i.e.\ use `\fB\*-li:me\fP'. .lp +8 8 2) The option `\fB\*-na\fP\ \fIname1\fP' will cause the output files to be named `\fIname1\fP.*' instead of being named after the first specified source file. Note that \fIname1\fP may include a directory specifictaion. .lp +8 8 2) The option `\fB\*-no\fP' will supress the creation of an object file. .lp +8 8 3) The option `\fB\*-li\fP' at the end of the command line will cause an assembly listing to be produced (not normally done). .lp +8 8 4) The default is to accept both lower and upper case, and to distinguish the difference between them in user defined symbols. Lower case text may be passed to macros. .lp +8 8 5) Symbols may be 65 characters long or less. Symbols longer than 65 characters give a \fBT\fP error. Titles may be up to 86 characters long. .lp +8 8 6) \fBP1\fP and \fBP2\fP may be used with .if and .iif to test for pass\ 1 and pass\ 2 of the assembler. .lp +8 8 7) The correct format of a .iif is `.iif\ ,,' (note the use of commas). .lp +8 8 8) The \fB\*-ls\fP option still doesn't work. .lp +8 8 9) The maximum nesting level of .if's is 15. .lp +8 8 10) The pseudo-op `.ENTRY\ ,' defines the (external) entry point to refer to the (internal) location . The symbol must be defined before issuing the .ENTRY directive. .lp +8 8 11) The pseudo-op `.CSECT\ [[,[,EXTERNAL]]]' is used to place attributes on control sections. Premitted attributes are STATIC (read/write data), DPURE (read-only data), and IPURE (read-only instructions). The default attribute is IPURE. EXTERNAL csects will be overlaid by .it bind (I), e.g. like FORTRAN named common. Note that the attribute need only be included once, usually when the csect is first defined. .lp +8 8 12) The pseudo-op's `.INSRT\ ' and `.INSR1\ ' are used to include other files into an assembly. \&.INSRT will textually insert the named file into the source file. \&.INSR1 inserts the named file only on pass\ 1. .dt .i0 .sh SEE\ ALSO bind\ (I), relld\ (VI), rel\ (V). dma1.mac0000600002565200256520000004531102272641032010500 0ustar jncjnc .SBTTL MA1: TITLE PAGE ; COPYRIGHT 1972,1973 DIGITAL EQUIPMENT CORPORATION ; DELPHI COMMAND COURTESY OF GHARRIS ENTERPRISES ; WITH A "LITTLE" HELP FROM CHRIS TERMAN .INSR1 objmod .INSR1 /include/unix .CSECT XCTPRG,IPURE .CSECT XCTPAS,IPURE .CSECT XCTLIN,IPURE .CSECT DPURE,DPURE .CSECT EDTSEC,DPURE .CSECT CNDSEC,DPURE .CSECT TXTBYT,DPURE .CSECT SWTSEC,DPURE .CSECT MAIN,IPURE .CSECT SYSCALLS,STATIC .CSECT PRGLEN=0 ;PROGRAM LENGTH PRGBEG: ;BASE OF PROGRAM .GLOBL PSTBAS,PSTTOP ; POINTERS TO PERMANENT SYMBOL TABLE .GLOBL WRDSYM ;".WORD" DEFAULT .NLIST BEX ;DON'T LIST BINARY EXTENSIONS .SBTTL MA1: ASSEMBLY OPTIONS ;THE FOLLOWING MACRO CAUSES ASSEMBLY OPTIONS TO BE ;PRINTED ON THE LOADER MAP AND ANY IMPLICATIONS ;(SECOND ARGUMENT) TO BE DEFINED. OPTIONS ARE ;SELECTED BY EQUATING THEM TO ZERO. .MACRO LDRMAP MNE,IMPLIES .IF DF MNE .LIST .GLOBL MNE .NLIST .IRP X, X= 0 ;INVOKE IMPLICATIONS .ENDM .ENDC .ENDM LDRMAP ;THE FOLLOWING GROUP ENABLES FUNCTIONS LDRMAP PAL11R, LDRMAP PAL11R, LDRMAP PAL11R, LDRMAP DEBUG ;DEBUG VERSION LDRMAP PDPV45 ;PDP-11/45 INSTRUCTIONS LDRMAP YPHASE ;.PHASE/.DEPHAS ;THE FOLLOWING GROUP DISABLES FUNCTIONS .IIF DF X40&X45, XFLTG= 0 LDRMAP XOVLAY ;SUPPRESS OVERLAYS LDRMAP XMACRO,XSML ;ALL GENERATED CODE (MACRO, REPT, ETC.) LDRMAP XSML ;SYSTEM MACROS LDRMAP X40 ;PDP-11/40 FEATURES LDRMAP X45 ;PDP-11/45 FEATURES LDRMAP XFLTG,XEDFPT ;FLOATING POINT EVALUATION LDRMAP XEDABS ;ED.ABS LDRMAP XEDAMA ;ED.AMA LDRMAP XEDPIC ;ED.PIC LDRMAP XEDFPT ;ED.FPT LDRMAP XEDLSB ;ED.LSB LDRMAP XEDPNC ;ED.PNC LDRMAP XEDLC ;ED.LC LDRMAP XEDCDR ;CARD READER FORMAT LDRMAP XZERR ;"Z" ERRORS LDRMAP XLCTTM ;NO LPT LISTING FORMAT LDRMAP XLCSEQ ;SEQUENCE NUMBERS LDRMAP XCREF,XRUN ;CREF SUPPRESSION LDRMAP XRUN ;NO .RUN EMT USED LDRMAP XRESKB ;NO RESIDENT KB .IF DF TRAPS!OVLAY!SNGBUF!DBLBUF .ERROR 0, .ENDC .IF NDF XRUN!XRESKB!XOVLAY!XEDABS .ERROR 0, .ENDC ;THE FOLLOWING PARAMETERS CAN BE MODIFIED ;AT ASSEMBLY TIME. .MACRO PARAM MNE, VALUE ;DEFINE DEFAULT PARAMETERS .IIF NDF MNE, MNE= VALUE .LIST MNE= MNE .NLIST .ENDM .IF DF PAL11R .IF NDF SRCLEN SRCLEN = 84. .ENDC .ENDC PARAM CPL, 80. ;CHARACTERS PER LISTING LINE PARAM LPP, 60. ;LINES PER PAGE PARAM SRCLEN, 600. ;SOURCE STATEMENT LENGTH PARAM BPMB, 20 ;BYTES PER MACRO BLOCK PARAM OBJLEN, 42. ;OBJECT BLOCK LENGTH PARAM RLDLEN, 42. ;RLD BLOCK LENGTH PARAM STKSIZ, 100.+290. ;STACK SIZE LINLEN=SRCLEN NROL= 13. ;***** CHANGE THIS IF YOU ADD ANOTHER ROLL!!! ***** .IIF NDF,XMACRO,NROL= NROL + 4 .IIF NDF,XEDLSB,NROL= NROL + 1 .IIF NDF,XCREF,NROL= NROL + 1 .CSECT INITRL,STATIC IMPSTR=. ROLLEN=<2*NROL> RBASE= . ROLBAS= RBASE RTOP= RBASE + ROLLEN ROLTOP= RTOP RSIZE= RTOP + ROLLEN ROLSIZ= RSIZE .MACRO GENROL NAME, BASE, TOP, SIZE NAME'ROL= .-ROLBAS .WORD BASE .BLKB ROLLEN-2 .WORD TOP .BLKB ROLLEN-2 .WORD SIZE*2 .=.- RS.'NAME= SIZE .IIF GT SIZE-MAXXMT, MAXXMT=SIZE .ENDM MAXXMT= 0 ;MAX XMIT ;START OF TABLE TO BE FILLED IN GENROL BUF, 0, 0,376/2 ;INPUT BUFFERS GENROL GLB, 0, 0,4 ;GLOBAL SYMBOL LIST GENROL SYM, 0, 0,4 ;SYMBOL TABLE .IF NDF XMACRO GENROL MAC, 0, 0,4 ;MACRO ROLL GENROL DMA, 0, 0,2 ;DUMMY ARGUMENT ROLL .ENDC .IF NDF XEDLSB GENROL LSY, 0, 0,4 ;LOCAL SYMBOL ROLL .ENDC GENROL SEC, 0, 0,5 ;SECTION ROLL GENROL ENT, 0, 0,6 ;; ENTRY POINT ROLL GENROL COD, 0, 0,4 ;CODE ROLL .IF NDF XMACRO GENROL MAB, 0, 0,BPMB/2 GENROL MAA, 0, 0,BPMB/2 .ENDC GENROL DUM, 0, 0,0 ;DUMMY (SEPARATES VARIABLE FROM FIXED) GENROL CND,CNDBAS,CNDTOP,3 ;CONDITIONAL ARGUMENTS GENROL SWT,SWTBAS,SWTTOP,3 ;COMMAND STRING SWITCHES GENROL EDT,EDTBAS,EDTTOP,3 ;ENABL/DSABL GENROL LCD,LCTBAS,LCTTOP,2 ;LISTING CONTROL GENROL CSA,CSABAS,CSATOP,4 ;CSECT OPTIONAL ARGUMENTS GENROL PST,PSTBAS,PSTTOP,4 ;PERMANENT SYMBOL TABLE .IF NDF XCREF GENROL CRF,CRFBAS,CRFTOP,1 ;CREF MNEMONIC ROLL .ENDC .=.+<2*ROLLEN> .SBTTL MA1: SECTOR INITIALIZATION ;SECTORS ARE ENTERED THROUGH THE MACRO ; "ENTSEC", SPECIFYING THE SECTOR NAME FOR THE ;ARGUMENT. THE MACRO "XITSEC" RETURNS TO ;THE DEFAULT SECTOR, "MAIN". THE NULL .CSECT IS ;NEVER USED. .MACRO ENTSEC NAME ;INIT A SECTION .CSECT NAME .ENDM .MACRO XITSEC ;EXIT TO DEFAULT SECTION .CSECT MAIN .ENDM ; "BLKW" AND "BLKB" PROVIDE PSEUDO-.BLKW AND -.BLKB, ;RESPECTIVELY. .MACRO BLKW NAME,LEN .IIF NB,NAME, NAME: .IF NB, .=.+<2*> .IFF .=.+2 .ENDC .ENDM .MACRO BLKB NAME,LEN .IIF NB,NAME, NAME: .IF NB, .=.+ .IFF .=.+1 .ENDC .ENDM ;PSEUDO-SECTORS ARE USED TO DEFINE USERCORE EQUIVALENCES FOR ;IMPURE DATA ;IMPURE STORAGE IS DIVIDED INTO THREE PSEUDO-SECTORS: ; "IMPURE" BEING CLEARED AT THE BEGINNING OF THE ;PROGRAM, "IMPPAS" BEING CLEARED AT THE BEGINNING ;OF EACH PASS, AND "IMPLIN" BEING CLEARED AT THE ;BEGINNING OF EACH LINE. ;THE FOLLOWING PSEUDO-SECTORS ARE USED TO COLLECT THE ;BASE, TOP, AND ENTRY SIZE OF THE VARIOUS ROLLS. ; RBASE - ROLL BASE ; RTOP - ROLL TOP ; RSIZE - ROLL SIZE ENTSEC MAIN ;DEFAULT CODE SECTOR ENTSEC INITRL ;INITIAL VALUES FOR ROLL SECTORS INIROL: TTLLEN=86. ; TITLE LENGTH STLLEN=64. ; SUBTITLE LENGTH .SBTTL MA1: IMPURE DATA DEFINITIONS IMPURE= . BLKW PASS BLKB SYMBUF,64. ;; SYMBOL BUFFER (USED BY GETSYM) ;NEXT GROUP MUST STAY TOGETHER BLKW SYMBOL,2 ;SYMBOL ACCUMULATOR MODE=. BLKB FLAGS,1 ;FLAG BITS BLKB SECTOR,1 ;SYMBOL/EXPRESSION TYPE BLKW VALUE,1 ;EXPRESSION VALUE BLKW RELLVL,1 .REPT MAXXMT-<<.-SYMBOL>/2> ;END OF GROUPED DATA BLKW .ENDR ENTMOD= SYMBOL+10 ;"MODE" FOR ENTRY SYMBOLS ENTVAL= ENTMOD+2 ;"VALUE" BLKW CLCNAM,2 ;CURRENT LOCATION COUNTER SYMBOL BLKB CLCFGS,1 BLKB CLCSEC,1 BLKW CLCLOC,1 BLKW CLCMAX,1 BLKW CSIFLG ;SET WHEN ROUTINES CALLED FROM CSI BLKW PASSSW ;PASS SWITCH BLKW ERRCNT ;ERROR COUNTER BLKW CDRSAV ;SAVED CHAR FROM CARD FORMAT BLKW ENDVEC,4 ;END VECTOR STORAGE BLKW PRGTTL,4 BLKW PRGIDN,4 ;IDENT BLOCK FLTBEG=. ;START OF FLOATING POINT IMPURE BLKW FLTSGN ;SIGN BIT BLKW FLTDOT ;DECIMAL POINT FLAG BLKW FLTEXP ;DECIMAL EXPONENT BLKW FLTBEX,1 ;BINARY EXPONENT (MUST PRECEED FLTBUF) BLKW FLTBUF,4 ;MAIN AC BLKW FLTSAV,4 LCSAVE=. ;LISTING CONTROL SAVE BLOCK BLKW LCMASK ;MASK BITS BLKW LCLVL ;LEVEL COUNT BLKW LCMCSI ;COMMAND STRING STORAGE LCSAVL= .-LCSAVE BLKW LCSBAK,LCSAVL/2 ;FOR INITTING PASS 2 BLKW EDMASK ;CONTAINS SET FLAGS BLKW EDMCSI ;BITS FOR CSI OVERRIDE BLKW EDMBAK ;TO RE-INIT FOR PASS 2 BLKW CRFFLG BLKW CRFVER ;VERSION FLAG BLKW CRFPAG BLKW CRFLIN BLKW CRFPNT BLKW CRFHDR,3 CRFLEN=132. ; CREF LENGTH BLKW CRFBUF,CRFLEN/2 CMILEN= 120. BLKW CMDPTR ;POINTER TO CURRENT POSISION IN COMMAND LINE BLKW CMDBUF,</2> BLKW OBJPNT BLKW RLDPNT BLKW BLKTYP BLKW OBJFLG BLKB LLTBL,5 ;LOGICAL TO PHYSICAL DEVICE MAPPING BLKB LSTMOD,1 ;LOGICAL LISTING FLAGS BLKW LLWAIT,1 ;WAIT FLAG BLKW LSTFLG BLKB TTLBUF,1+TTLLEN ;TITLE STORAGE BLKB TTLBU2,44. ;DATE, PAGE #, ETC. .EVEN BLKW TTLBEG ;TITLE BEGINNING BLKW TTLEND ;TITLE END FNLEN=128. ;MAX FILE NAME LENGTH (MINUS 1 FOR .ASCIZ) PRQLEN=FNLEN BLKB PRQBUF,PRQLEN ;PREREQUISITE NAME .EVEN BLKW UNMIXID ;FLAG TRUE IF SEPARATE I AND D SPACE BLKW FMIXID ;FLAG TRUE IF A .MIXID ENCOUNTERED BLKW SRCLNK,1 BLKB SRCFIL,FNLEN BLKW SRCHDR,3 BLKW SRCBUF,SRCLEN/2+2 BLKW LSTLNK,1 BLKB LSTFIL,FNLEN BLKW LSTHDR,3 OCTLEN=^D<8*6> ; OCTAL PRINT STORAGE BLKW LSTBUF,</2+1> BLKW OBJLNK,1 BLKB OBJFIL,FNLEN BLKB DFLNAM,FNLEN ;STORAGE FOR ^NA SWITCH BLKW OBJHDR,1 BLKW OBJBUF,OBJLEN/2 OCTBUF=. BLKB OCTERP,0 BLKB OCTSEQ,2 BLKB OCTPF0,7 BLKB OCTPF1,OCTLEN-<.-OCTBUF> BLKW LINBUF,LINLEN/2 BLKW LINEND,1 BLKW RLDHDR,1 BLKW RLDBUF,RLDLEN/2 BLKW EXPBAK,5 ;PREVIOUS TERM STORAGE MSBBLK=. ;PUSHABLE BLOCK (MUST BE ORDERED) BLKW MSBTYP ;BLOCK TYPE BLKW MSBPBP ;PREVIOUS BLOCK POINTER BLKW MSBTXT ;POINTER TO BASIC TEXT BLOCK BLKW MSBARG ;POINTER TO ARG BLOCK BLKW MSBCNT,2 ;REPEAT COUNT, ETC. BLKW MSBMRP ;MACRO READ POINTER MSBEND=. ;END OF ORDERED STORAGE BLKW MACNXT BLKW MACLVL ;MACRO LEVEL COUNT BLKW CONCNT BLKW ARGMAX BLKW MACNAM,2 BLKW MACGSB ;MACRO GENERATED SYMBOL BITS BLKW SMLLNK BLKW SMLFLG IMPPAS= . BLKB DEFDIR,FNLEN ;TRYING DEFAULT DIRS IN INSERT BLKW CHRPNT ;CHARACTER POINTER BLKW SYMBEG ;POINTER TO START OF SYMBOL BLKW ENDFLG BLKW CINSRT ;DEPTH OF "INSRT" NESTING BLKW CSISAV ;SET NON-ZERO IF NO SRC FILES LEFT BLKW EOFFLG ;SET NON-ZERO IF INPUT FILE AT EOF BLKW LPPCNT,1 ;FORCE NEW PAGE WHEN NEGATIVE BLKW FFCNT,1 ;UNPROCESSED FF COUNT BLKW PAGNUM,1 ;PAGE NUMBER BLKW PAGEXT,1 ;PAGE NUMBER EXTENSION .IF NDF XLCSEQ BLKW LINNUM,2 ;CREF LINE NUMBER BLKW SEQEND,1 .ENDC BLKW PHAOFF BLKW CRADIX ;CURRENT RADIX ;CONDITIONAL STORAGE (MUST BE ORDERED) BLKW CNDWRD ;TEST WORD BLKW CNDMSK ;CONDITION MASK BLKW CNDLVL ;NESTING LEVEL BLKW CNDMEX ;MEXIT FLAG .ODD BLKB OBJSEC,1 ;OBJECT FILE SECTOR BLKW OBJLOC,1 ;OBJECT FILE LOCATION BLKB STLBUF,STLLEN+1 ;SUB-TITLE BUFFER .EVEN BLKW LSYFLG ;BUMPED AT "LABEL:" BLKW LSYBKN ;BLOCK NUMBER BLKW LSYBAS ;SECTION BASE BLKW LSGBAS ;BASE FOR GENERATED SYMBOLS BLKW GMAPNT,1 ;POINTER TO FOLLOWING BUFFER BLKW GMABLK,1 ;POINTER TO "BORROWED" CHARACTER BLKW ,1 ;CHARACTER ITSELF BLKW ,3*2 ;ROOM FOR MORE PAIRS BLKW SMLCNT ;MCALL HIT COUNT IMPLIN= . BLKW ERRBTS ;ERROR FLAGS BLKW OPCLAS ;OP CODE CLASS BLKW BYTMOD ;BYTE MODE IF NON-ZERO BLKW FLTWDC ;WORD COUNT BLKW LCFLAG ;FLAG BITS BLKW LCBEGL ;POINTER TO START OF LINE BLKW LCENDL ;POINTER TO END OF LINE BLKW LBLEND ;END OF LABEL (FOR PARSING) BLKW LCLLBL ;TRUE IFF LOCAL LABEL BLKB CRFDFL,2 ; "#" AND "*" FLAGS BLKW PF0,2 BLKW PF1,2 BLKW PCRCNT ;EXTENSION LINE FLAG BLKW ARGCNT, ;ARGUMENT COUNT BLKW ARGPNT, ;START OF LAST ARGUMENT BLKW EXPFLG, ;SET WHEN COMMA REQUIRED IMPTOP= . MIXED= . BLKW ROLNDX ;ROLL INDEX BLKW ROLPNT ;ROLL POINTER BLKW ROLUPD ;UPDATE IF NON-ZERO BLKW CRFLNK BLKB CRFFIL,FNLEN BLKW FREBEG ;; BEGINNING OF IMPURE SEGMENT BLKW FREEND ;; END OF IMPURE SEGMENT DOTSTR = '.*400 ;; THE DOT STRING (".") NULSTR = 40*400 ;; THE NULL STRING (" ") ;ASSOCIATED WITH EACH IMPURE AREA IS AN EXECUTION ;SECTOR WHICH DOES THE CLEARING AND EXECUTES ANY ;OTHER CODE FOUND IN THE SECTOR. SEE THE .RADIX ;HANDLER FOR AN EXAMPLE OF THE USE OF THESE SECTORS ;TO INITIALIZE VARIABLES. ENTSEC XCTPRG ;PROGRAM INITIALIZATION CODE XCTPRG: MOV #IMPURE,R0 1$: CLR (R0)+ ;CLEAR IMPURE AREA CMP #IMPTOP,R0 BHI 1$ ENTSEC XCTPAS ;PASS INITIALIZATION CODE XCTPAS: MOV #IMPPAS,R0 2$: CLR (R0)+ ;CLEAR IMPURE PART CMP #IMPTOP,R0 BHI 2$ ENTSEC XCTLIN ;LINE INITIALIZATION CODE XCTLIN: MOV #IMPLIN,R0 3$: CLR (R0)+ CMP #IMPTOP,R0 BHI 3$ ENTSEC DPURE ;D-SPACE, PURE ;THE MACRO .POINT GENERATES A TWO WORD ENTRY IN THE GIVEN CSECT. IF THE ;SYMBOL IS ONE OR TWO CHARACTERS LONG THEN THE FIRST WORD WILL BE ZERO, AND ;THE SECOND WORD WILL CONTAIN THE CHARACTERS IN REVERSE ORDER. IF THE SYMBOL ;WAS LONGER THEN TWO CHARACTERS THEN THE SECOND WORD WILL BE THE SAME AND THE ;FIRST WORD WILL BE A POINTER INTO THE CSECT TXTBYT POINTING TO THE ASCIZ ;REPRESENTATION OF THE REST (LESS THE FIRST TWO CHARACTERS) OF THE SYMBOL. .MACRO .POINT SYMBOL,SECTION COUNT = 0 ;; CHAR = SYMBOL(COUNT) .CSECT TXTBYT,DPURE ;; ENTER ASCIZ CSECT .PTR = . ;; SAVE POINTER TO BEGINNING OF SYMBOL .IRPC CHAR, ;; LOOP THROUGH ALL THE CHARACTERS IN SYMBOL COUNT = COUNT+1 ;; INCREMENT CHARACTER POINTER .IF EQ,COUNT-1 ;; IF FIRST CHARACTER THEN CHAR1 = 400*''CHAR ;; SHIFT AND REMEMBER .IFF ;; ELSE .IF EQ,COUNT-2 ;; IF SECOND CHARACTER THEN CHAR1 = CHAR1!''CHAR ;; SAVE IT IN CHAR1 ALSO .IFF ;; ELSE .BYTE ''CHAR!40 ;; PUT IT IN TXTBYT AREA .ENDC .ENDC .ENDM ;; END OF LOOP .CSECT SECTION ;; ENTER CORRECT SECTION .IF LE,COUNT-2 ;; IF SYMBOL LENGTH <= 2 THEN .WORD 0 ;; CREATE A NULL POINTER TO SYMBOL .IFF ;; ELSE .WORD .PTR ;; POINTER TO REST OF SYMBOL .CSECT TXTBYT ;; RE-ENTER TXTBYT .BYTE 0 ;; TO MAKE SYMBOL ASCIZ .CSECT SECTION ;; AND BACK TO SECTION .ENDC .WORD CHAR1!<400*40>!40 .ENDM ;; FILL IN SECOND WORD (TWO CHARACTERS SWAB'ED) ;THE MACRO "GENSWT" IS USED TO SPECIFY A COMMAND ;STRING SWITCH (1ST ARGUMENT) AND THE ADDRESS OF ;THE ROUTINE TO BE CALLED WHEN ENCOUNTERED (2ND ARG). ENTSEC SWTSEC ;SWITCH TABLE SWTBAS: .MACRO GENSWT MNE,ADDR .POINT MNE,SWTSEC .WORD ADDR XITSEC .ENDM ;THE MACRO "GENEDT" IS USED TO SPECIFY .ENABL/.DSABL ;ARGUMENTS. IT TAKES ONE TO THREE ARGUMENTS: ; 1- MNEMONIC ; 2- SUBROUTINE TO BE CALLED (OPTIONAL) ; 3- IF NON-NULL, .DSABLE IS DEFAULT ENTSEC EDTSEC EDTBAS: .MACRO GENEDT MNE,SUBR,INIT ENTSEC EDTSEC ED.'MNE= 1 .REPT <.-EDTBAS>/6 ED.'MNE= ED.'MNE+ED.'MNE .ENDR .GLOBL ED.'MNE .POINT MNE,EDTSEC .IF NB,SUBR .WORD SUBR .IFF .WORD CPOPJ .ENDC XITSEC .IIF NB,INIT, EDINIT= EDINIT!ED.'MNE .ENDM GENEDT .IIF NDF EDINIT, EDINIT= 0 ;THE MACRO "GENCND" IS USED TO SPECIFY CONDITIONAL ;ARGUMENTS. IT TAKES TWO OR THREE ARGUMENTS: ; 1- MNEMONIC ; 2- SUBROUTINE TO BE CALLED ; 3- IF NON-BLANK, COMPLEMENT CONDITION ENTSEC CNDSEC CNDBAS: .MACRO GENCND MNE,SUBR,TOGGLE ;GENERATE CONDITIONAL .POINT MNE,CNDSEC .IF B .WORD SUBR .IFF .WORD SUBR+1 .ENDC XITSEC .ENDM ;THE FOLLOWING SECTOR IS USED TO COLLECT BYTE STRINGS ;AND NEEDN'T BE LEFT AT AN EVEN LOCATION ENTSEC TXTBYT XITSEC ;ALWAYS LEAVE IN DEFAULT SECTOR .SBTTL MA1: SYMBOLIC EQUIVALENCES .SBTTL MA1: CHARACTERS TAB= 11 LF= 12 VT= 13 FF= 14 CR= 15 SPACE= 40 CH.IOR= '! CH.QTM= '" CH.HSH= '# CH.DOL= '$ CH.PCT= '% CH.AND= '& CH.XCL= '' CH.LP= '( CH.RP= ') CH.MUL= '* CH.ADD= '+ CH.COM= ', CH.SUB= '- CH.DOT= '. CH.DIV= '/ CH.COL= ': CH.SMC= '; CH.LAB= '< CH.EQU= '= CH.RAB= '> CH.QM= '? CH.IND= '@ CH.BSL= '\ CH.UAR= '^ LET.A= 'A LET.B= 'B LET.C= 'C LET.D= 'D LET.E= 'E LET.F= 'F LET.G= 'G LET.O= 'O LET.Z= 'Z DIG.0= '0 DIG.9= '9 .SBTTL MA1: OBJECT FILE RLDT00= 00 ; ABSOLUTE DATA RLDT01= 01 ; INTERNAL RELOCATION TST #C RLDT02= 02 ; GLOBAL RELOCATION TST #G RLDT03= 03 ; INTERNAL DISPLACED RELOCATION TST ABS RLDT04= 04 ; GLOBAL DISPLACED RELOCATION TST X RLDT05= 05 ; GLOBAL ADDITIVE RELOCATION TST #X+6 RLDT06= 06 ; GLOBAL ADDITIVE DISPLACED RELOCATION TST #X+6 RLDT07= 07 ; NEW CSECT RLDT10= 10 ; SEQUENCE BREAK RLDT11= 11 ; LIMIT RLDT15= 15 ; SECTOR ADDITIVE RELOCATION TST #O RLDT16= 16 ; SECTOR ADDITIVE DISPLACED RELOCATION TST #O+6 GSDT00= 00*400 ; OBJECT MODULE NAME GSDT01= 01*400 ; PROGRAM SECTION NAME GSDT02= 02*400 ; INTERNAL SYMBOL TABLE GSDT03= 03*400 ; TRANSFER ADDRESS GSDT04= 04*400 ; SYMBOL DECLARATION GSDT05= 05*400 ; LOCAL SECTION NAME GSDT06= 06*400 ; VERSION IDENTIFICATION BLKT01= 01 ; GSD BLKT02= 02 ; GSD END BLKT03= 03 ; TEXT BLOCK BLKT04= 04 ; RLD BLOCK BLKT05= 05 ; ISD BLKT06= 06 ; MODULE END .SBTTL MA1: MISCELLANEOUS ;FLAGS USED IN SYMBOL TABLE MODE DEFFLG= 000010 ;DEFINED RELFLG= 000040 ;RELOCATABLE GLBFLG= 000100 ;GLOBAL SYMFLG= 000200 ;SYMBOL FOR REL FILE REGFLG= 000001 ;REGISTER LBLFLG= 000002 ;LABEL MDFFLG= 000004 ;MULTILPY DEFINED ISPFLG= 000001 ;I SPACE CSECT PURFLG= 000002 ;PURE CSECT ;ADDRESS MODE FLAGS AM.DEF= 10 ;DEFERRED MODE AM.INC= 20 ;AUTO-INCREMENT MODE AM.DEC= 40 ;AUTO-DECREMENT MODE AM.NDX= 60 ;INDEX MODE AM.PC= 07 ;PC MODE ADDRESSING AM.IMM= AM.INC+AM.PC ;IMMEDIATE MODE AM.REL= AM.NDX+AM.PC ;RELATIVE MODE ;DIRECTIVE FLAGS DEFINED IN PST .GLOBL DFLCND, DFLMAC, DFLGEV .GLOBL DFLGBM, DFLSMC .SBTTL MA1: SUBROUTINE CALL DEFINITIONS ;THE MACRO "CALL" IS THE EQUIVALENT OF "JSR PC," AND ;IS USED FOR SIMPLICITY. THE MACRO "RETURN" IS THE ;EQUIVALENT OF "RTS PC". .MACRO CALL ADDRESS JSR PC,ADDRESS .ENDM .MACRO RETURN RTS PC .ENDM ;THE MACRO "GENCAL" DEFINES A MACRO WHICH CALLS A ;SUBROUTINE OF THE SAME NAME. IF "TRAPS" ARE ENABLED, ;GENCAL CAUSES A TRAP. .MACRO GENCAL NAME ;CAN BE CHANGED TO OPDEFS OR TRAPS .MACRO NAME JSR PC,NAME .ENDM .ENDM GENCAL SAVREG ;SAVE REGISTERS GENCAL EXPR ;CALL THE EXPRESSION EVALUATOR GENCAL TERM GENCAL RELEXP GENCAL RELTST GENCAL ABSEXP GENCAL ABSTST GENCAL ABSERR GENCAL GLBEXP GENCAL ABSTRM ;ABSOLUTE TERM GENCAL RELTRM ;RELOCATABLE TERM GENCAL GLBTRM ;GLOBAL TERM GENCAL GETSYM GENCAL SETSYM GENCAL GETR50 GENCAL SETR50 GENCAL TSTR50 GENCAL GETNB GENCAL SETNB GENCAL GETCHR GENCAL SETCHR GENCAL GSARG GENCAL TSTARG GENCAL SETIMM GENCAL SETDSP GENCAL STCODE GENCAL SSRCH GENCAL OSRCH .IIF NDF XMACRO, GENCAL MSRCH .IIF NDF XEDLSB, GENCAL LSRCH GENCAL SETPF0 GENCAL SETPF1 GENCAL DNC GENCAL CVTNUM GENCAL R50UNP GENCAL MOVBYT GENCAL TYPEST GENCAL TYPELN .SBTTL MA1: MISCELLANEOUS MACRO DEFINITIONS GENCAL SETXPR .IF NDF XCREF GENCAL CRFREF ;CROSS REFERENCE A SYMBOL GENCAL CRFDEF ;DITTO, DEFINING IT .IFF .MACRO CRFREF ;DUMMY IF NO CREF .ENDM .MACRO CRFDEF .ENDM .ENDC ; MACRO TO CATCH UNTRANSLATED DELPHI SYSTEM CALLS .MACRO GENERR NAME .MACRO NAME .ERROR ;NAME EMT USED! .ENDM NAME .ENDM GENERR GENERR OPEN ;PROVIDED THE SYSTEM CALL WAS ONE OF THESE GENERR CLOSE GENERR READCH GENERR TYPECH GENERR GETBLK GENERR PUTBLK GENERR PUTST GENERR PUTLN GENERR SEXIT GENERR EXIT GENERR GETSTK GENERR ALLSTK GENERR GETIMP GENERR ALLIMP GENERR LOWIMP .MACRO PUTKB ADDR ;LIST TO KB MOV ADDR,R1 CALL PUTKB .ENDM .MACRO PUTLP ADDR ;LIST TO LP MOV ADDR,R1 CALL PUTLP .ENDM .MACRO PUTKBL ADDR ;LIST TO KB AND LP MOV ADDR,R1 CALL PUTKBL .ENDM GENCAL PUTLIN ;GENERIC OF ABOVE .MACRO SERROR MSGADR FNAME .IF B,FNAME MOV MSGADR,-(SP) JMP SERROR .IFF MOV FNAME,-(SP) MOV MSGADR,-(SP) JMP FERROR .ENDC .ENDM .MACRO ERROR ARG BIS #ERR.'ARG,ERRBTS .ENDM .MACRO BRJMP ADDR .IF GE .- .IF LE .--254. BR ADDR .MEXIT .ENDC .ENDC JMP ADDR .ENDM .MACRO CHSCAN TABLE ;CHARACTER SCAN MOV #TABLE,R0 CALL CHSCAN .ENDM .MACRO GCHTBL CHAR, ADDR ;GEN CHARACTER SCAN TABLE .WORD ADDR, CHAR .ENDM ENTSEC TXTBYT ERRMNE: .IRPC CHAR, < ABEFILMNOPQRTUZ> ERR.'CHAR= 1 .REPT <.-ERRMNE> ERR.'CHAR= ERR.'CHAR+ERR.'CHAR .ENDR .ASCII /CHAR/ .ENDM XITSEC .MACRO SETNZ ADDR ;SET ADDR TO NON-ZERO FOR T/F FLAGS MOV SP,ADDR .ENDM .MACRO PROCSI FILE ;PROCESS CSI MOV #FILE'FIL,R0 CALL PROCSI .ENDM .MACRO FINDEV ENTRY ;FIN DEVICES MOV #ENTRY,R1 CALL FINDEV .ENDM .MACRO IMULI COUNT,ADDR .LIST MEB T.VAL= COUNT .IF EQ T.VAL CLR ADDR .IFF .IF LT T.VAL T.VAL= -T.VAL NEG ADDR .ENDC T.FLAG= 0 T.MASK= 040000 .REPT ^D14 .IF LE T.MASK-T.VAL .IF NE T.MASK&T.VAL .IF NE T.MASK-T.VAL .IF EQ T.FLAG MOV ADDR,-(SP) T.FLAG= 1 .IFF .IF NE T.MASK-1&T.VAL ADD (SP),ADDR .IFF ADD (SP)+,ADDR T.FLAG= 0 .ENDC .ENDC .ENDC .ENDC ASL ADDR .ENDC T.MASK= T.MASK/2 .ENDR .IF NE T.FLAG ADD (SP)+,ADDR .ENDC .ENDC .NLIST MEB .ENDM dma2.mac0000600002565200256520000005216302271110064010477 0ustar jncjnc .SBTTL MA2: ROLL DEFINITIONS ENTSEC INITRL $LEN=.-IMPSTR XITSEC ;ROLL HANDLER CALLS .MACRO SEARCH ROLNUM ;BINARY SEARCH MOV #ROLNUM,R0 CALL SEARCH .ENDM .MACRO SCAN ROLNUM ;LINEAR SCAN MOV #ROLNUM,R0 CALL SCAN .ENDM .MACRO SCANP ROLNUM ;; LINEAR SCAN, MATCH BOTH UPPER AND LOWER CASE MOV #ROLNUM,R0 CALL SCANP .ENDM .MACRO NEXT ROLNUM ;FETCH NEXT ENTRY MOV #ROLNUM,R0 CALL NEXT .ENDM .MACRO APPEND ROLNUM ;APPEND TO END OF ROLL MOV #ROLNUM,R0 CALL APPEND .ENDM .MACRO ZAP ROLNUM ;CLEAR ROLL MOV #ROLNUM,R0 CALL ZAP .ENDM GENCAL INSERT ;INSERT (MUST BE PRECEDED BY ONE ;OF THE ABOVE TO SET POINTERS) GENCAL SETROL ;SAVE AND SET REGS FOR ABOVE XITSEC .SBTTL MA2: PROGRAM INITIALIZATION .GLOBL DMACRO,FIN ENTSEC MAIN DMACRO: MOV SP,R4 ;SAVE ARGUMENT STRING POINTER TST -(SP) ;ENSURE AT LEAST ONE FREE CELL ON STACK BIC #BPMB-1,SP ;ALIGN SP PROPERLY FOR MAA ROLL MOV R4,(SP) ;REMEMBER WHERE ARG DATA WAS .GLOBL _end ;will be defined by relld MOV #_end,R0 ;end of data segment MOV R0,FREBEG ;save pointer to beginning of free area ADD #<20.*64.>,R0 ;allocate 20 blocks of impure to start MOV R0,FREEND ;this will be end of impure MOV R0,BREAK+2 ;also the new top address SYS S_INDIR,BREAK ;indirect break call to expand impure BCS NOMEM ;complain if it failed MOVB #-1,@FREBEG ;a -1 byte at beginning of area CALL XCTPRG ;CLEAN THINGS UP A BIT MOV #DUMROL,R1 ;POINT TO SEPARATOR ROLL 2$: MOV SP,ROLBAS(R1) ;FILL IN VARIABLE BASE MOV SP,ROLTOP(R1) ; AND TOP CLRB ROLSIZ+1(R1) ;CURRENT SIZE DEC R1 DEC R1 BGE 2$ ;LOOP IF MORE ROLLS CALL XCTPRG ;CLEAN UP MEMORY MOV (SP),R4 ;POINTER TO COMMAND ARGUMENT STRUCTURE TST (R4)+ ;SKIP ARGUMENT COUNT TST (R4)+ ;AND COMMAND NAME MOV #CMDBUF,R5 ;WHERE TO STORE ARGUMENT LINE MOVB #' ,(R5)+ ;SEPARATED BY SPACES 11$: MOV (R4)+,R0 ;PTR TO NEXT COMMAND ARG STRING CMP R0,#-1 ;ANY MORE? BEQ 18$ ;(NOPE) 12$: MOVB (R0)+,(R5)+ ;COPY THIS ARGUMENT INTO SPACE BNE 12$ MOVB #' ,-1(R5) ;SEPARATING ARGS WITH SPACES BR 11$ ;GO BACK TO FETCH NEXT ARGUMENT 18$: MOVB #12,-1(R5) ;END ARGUMENT STRING WITH A NEWLINE CMP R5,#CMDBUF+CMILEN BLOS 19$ ;(DIDN'T OVERFLOW COMMAND BUFFER) MOV #TLMS,-(SP) ;COMMAND LINE TOO LONG, DON'T PROCEED TYPELN BR FIN 19$: CALL SETUP ;SET UP FOR CALL CALL DEFSYM ;DEFINE USEFUL SYMBOLS AHEAD OF TIME CALL ASSEMB ;CALL THE ASSEMBLER CALL SETDN ;CLEAN UP FIN: FINDEV FINTB2 ;CLOSE ALL FILES SYS S_EXIT ;DOT'S IT NOMEM: MOV #MEMMSG,-(SP) ;complain if we can't get memory TYPELN BR FIN ENTSEC SYSCALLS BREAK: .WORD 104421,0 ; indirect break system call XITSEC ENTSEC TXTBYT TLMS: .ASCIZ "COMMAND LINE TOO LONG!" MEMMSG: .ASCIZ "Cannot expand impure segment!" XITSEC .SBTTL MA2: SETUP AND COMMAND LINE PARSING .GLOBL SETUP,OUTNAM,PROCSI SETUP: ;INITIALIZE THINGS MOV #CMDBUF,CMDPTR ;END OF CODE TO READ IN COMMAND LINE MOV #LCSAVE,R1 ;SAVE CURRENT LISTING FLAGS MOV #LCSBAK,R2 CALL XMIT0-LCSAVL MOV EDMASK,EDMBAK ;DITTO FOR ENABL/DSABL FLAGS PROCSI OBJ ;GET FIRST SRC FILE = OBJ,LIST,CREF FILE NAME BNE 21$ ;NOT NULL SERROR #NOFILE 21$: PROCSI SRC ;QUICK SCAN THROUGH COMMAND LINE BNE 21$ ;BRANCH IF NON-NULL TST DFLNAM ;SEE IF WE FOUND "-NA" SWITCH BEQ 22$ ;NOPE SO FORGET I ASKED MOV #DFLNAM,R1 ;OTHERWISE MOVE INTO OBJFIL MOV #OBJFIL,R2 MOVBYT ;CODE TO OPEN LISTING FILE IF ONE IS CALLED FOR 22$: TST LCMCSI ;IF MINUS THEN LISTING BGE 1$ MOV #LST.L+,LLTBL+LST.L ;SAY WE WANT LP MOV #OBJFIL,-(SP) ;PASS LOCATION OF NAME TO BE CHANGED MOV #LSTTXT,-(SP) ;DIDDLE OBJECT NAME TO HAVE CALL OUTNAM ;.LST EXTENSION SYS S_CREAT,OBJFIL,666 BCC 2$ SERROR #NOOUTF,#OBJFIL ;FAILED SO GIVE UP 2$: MOV R0,LSTLNK ;SAVE IDENTIFIER FOR LATER USE 1$: RETURN ENTSEC TXTBYT LSTTXT: .ASCII /lst/ NOFILE: .ASCIZ /NO INPUT FILE SPECIFIED./ NOCORE: .ASCIZ /NO MORE FREE STORAGE/ XITSEC ;THIS SUBROUTINE DEFINES ALL SORTS OF USEFUL SYMBOLS BEFORE THE ;ACTUAL ASSEMBLY BEGINS. DEFSYM: RETURN ;(NO SYMBOLS TO DEFINE!! ;THIS ROUTINE CONVERTS THE NAME POINTED TO BY 4(SP) ;TO HAVE THE EXTENSION POINTED TO BY 2(SP) OUTNAM: MOV 4(SP),R0 ;PICK UP POINTER TO FILE NAME 1$: CMPB @R0,#'. ;ALREADY ONE THERE? BEQ 2$ TSTB (R0)+ ;LOOK FOR END BNE 1$ MOVB #'.,-1(R0) ;PUT A DOT AFTER END 3$: MOV 2(SP),R1 ;POINTER TO EXTENSION MOVB (R1)+,(R0)+ ;THEN STUFF IN EXTENSION MOVB (R1)+,(R0)+ MOVB (R1)+,(R0)+ CLRB (R0)+ ;FINALLY MAKE IT ASCIZ AGAIN MOV (SP)+,(SP) ;POP ARGS OFF STACK MOV (SP)+,(SP) RETURN ;AND WE'RE DONE (NO DEFAULTS OF COURSE) 2$: TSTB (R0)+ BR 3$ SETDN: ;CLEAN UP TST ERRCNT ; ANY ERRORS? BEQ 9$ ; NO MOV #FINMSG,R1 ;YES, SET FOR FINAL MESSAGE MOV #LINBUF,R2 MOVBYT ;MOVE INTO LINBUF MOV ERRCNT,R1 DNC ;PRINT IN DECIMAL MOV #CRLF,R1 MOVBYT CLRB (R2) PUTKBL #LINBUF ;LIST TO KB & LP 9$: RETURN FINDEV: ;CLOSE DEVICES 1$: MOV (R1)+,R2 TST (R2) BEQ 2$ MOV (R2),R0 sys s_close 2$: TST (R1) BNE 1$ RETURN ENTSEC DPURE FINTBL: FINTB2: .IIF NDF XSML, .WORD SMLLNK .IIF NDF XCREF, .WORD CRFLNK .WORD SRCLNK, OBJLNK FINTB3: .WORD LSTLNK .WORD 0 ENTSEC TXTBYT FINMSG: .ASCIZ /ERRORS DETECTED: / CRLF: .ASCIZ // HELLO: .ASCIZ /DELPHI MACRO / XITSEC ;PROCESS CSI FIELD - PARSE DOWN STRING AND DETERMINE IF FILE ;NAME OR OPTION. IF OPTION PROCESS ELSE STORE. ;ON ENTRY R0: POINTER TO FILE NAME AREA ;ON EXIT R0: =0 IF NO FILE NAMES LEFT ; ^=0 IF A FILE NAME LEFT ; R1: POINTER TO LNKBLK PROCSI: MOV R0,R1 TST -(R1) ;POINT TO LNKBLK SAVREG ;SAVE CURRENT REGS TST (R1)+ ;POINT TO FILE NAME 41$: MOV CMDPTR,CHRPNT ;SCAN COMMAND LINE SETNB ;GET NEXT NON-BLANK CHARACTER CMPB R5,#12 ;END OF LINE? BEQ PRO6$ ;YES CMPB R5,#'- ;OPTION? BEQ 10$ ;YES MOVB R5,(R1)+ ;NO - STORE CHARACTER 1$: GETCHR ;GET NEXT CHARACTER CMPB R5,#' ;TERMINATOR? BEQ PRO7$ ;YES - DONE CMPB R5,#12 ;EOL? BEQ PRO7$ ;YES - DONE MOVB R5,(R1)+ ;NO - STORE CHARACTER BR 1$ 10$: GETCHR ;GET THE FIRST CHARACTER OF THE OPTION GETSYM ;GET THE SWITCH CMP R5,#': ;DID IT END WITH A :? BEQ 12$ ;YES, SKIP OVER IT MOV SYMBEG,CHRPNT ;RESCAN SYMBOL SETCHR ;SET UP FIRST CHARACTER 31$: BITB #CT.ALP!CT.NUM!CT.LC,CTTBL(R5) ;IN THE SYMBOL? BEQ 30$ ;NO GETCHR ;GET THE NEXT CHARACTER BR 31$ ;AND LOOP 30$: DEC CHRPNT ;BACK UP OVER THE TERMINATOR 12$: CALL INSYM ;PUT SYMBOL IN THE IMPURE SEGMENT SCANP SWTROL ;DO SO BEQ PRO5$ ;ERROR IF NOT IN TABLE MOV #LINBUF,R2 ;USE LINE BUFFER FOR UNPACKING 2$: MOVB #SPACE,(R2)+ ;SET DELIMITER 3$: GETCHR ;GET CHAR AND TEST FOR A/N BITB #CT.NUM!CT.LC!CT.ALP,CTTBL(R5) BEQ 22$ MOVB R5,(R2)+ ;OK, STUFF IT BR 3$ 22$: TSTB CTTBL(R5) ;EOL? BEQ 4$ BITB #CT.SP!CT.TAB,CTTBL(R5) ;TERMINATOR? BNE 4$ ;YES - DONE CMPB R5,#': ;SEPARATOR? BEQ 2$ ;YES - GET NEXT SUB-OPTION BR PRO5$ 4$: MOV CHRPNT,CMDPTR ;SAVE SCAN POINTER CLRB (R2) ;SET TERMINATOR MOV #LINBUF,CHRPNT SETNB CLR ERRBTS CLR ARGCNT INC CSIFLG ;INDICATE WE'RE IN THE COMMAND STRING MOV SYMBOL+4,VALUE ;MAKE IT LOOK LIKE PST CLR MODE MOV R1,-(SP) CALL PROPC ;PROCESS AS IF DIRECTIVE DEC CSIFLG MOV (SP)+,R1 BIS ERRBTS,R5 ;R5 AND ERROR BITS MUST BOTH BE ZERO BEQ 41$ PRO5$: SERROR #BADOPT PRO6$: CLR R0 ;NO MORE FILES RETURN PRO7$: CLRB (R1) ;MAKE FILE NAME ASCIZ MOV CHRPNT,CMDPTR ;SAVE SCAN POINTER SETNZ R0 ;FILE NAME READ RETURN ENTSEC TXTBYT BADOPT: .ASCIZ /ILLEGAL OPTION./ XITSEC SERROR: ;SYNTAX ERROR TYPELN ;PRINT ERROR MESSAGE ON CONSOLE BRJMP FIN FERROR: TYPEST ;TYPE REASON WHY TYPELN ;TYPE FILE NAME BRJMP FIN ;ROUTINE TO HANDLE -NA SWITCH. THIS SWITCH GOBBLES UP FILE NAME ;WHICH FOLLOWS AND MAKES IT THE NAME THAT WILL BE USED FOR THE OBJECT, ;LISTING AND CREF FILES (WITH APPROPRIATE EXTENSIONS). GENSWT NA,DEFNAM DEFNAM: MOV CMDPTR,CHRPNT ;ARGUMENT FROM COMMAND LINE SETNB ;GET NEXT NON-BLANK CHARACTER CMPB R5,#12 ;EOL?? BNE 1$ SERROR #NAMERR 1$: MOV #DFLNAM,R1 ;LOAD POINTER TO STORAGE FOR NAME MOVB R5,(R1)+ ;STORE FIRST CHARACTER 2$: GETCHR ;GET NEXT CHARACTER CMPB R5,#' ;TERMINATOR?? BNE 3$ ;YES -- DONE MOVB R5,(R1)+ ;STORE CHARACTER BR 2$ 3$: CLRB (R1) ;MAKE FILE NAME ASCIZ CLR R5 ;USED AS FLAG (0 MEANS NO ERROR) MOV CHRPNT,CMDPTR RETURN ENTSEC TXTBYT NAMERR: .ASCIZ /NO FILE NAME FOLLOWING -NA/ XITSEC .SBTTL MA2: ASSEMBLER PROPER ASSEMB: ;ASSEMBLER PROPER APPEND BUFROL ;MAKE ROOM FOR PRIMARY INPUT BUFFER CALL PASS2 ;PROCESS PASS INC PASS ;SET FOR PASS 2 PASS2: CALL XCTPAS ;INIT FOR PASS CALL SECINI ;INIT THE SECTOR ROLL .IF NDF XCREF TST PASS ;PASS 2? BEQ 2$ ;NO TST CRFFLG ;CREF REQUESTED? BEQ 2$ ;NO ;OPEN .CRF FILE MOV #OBJFIL,-(SP) ;PUSH POINTER TO NAME MOV #CRFTXT,-(SP) ;CHANGE NAME TO HAVE .CRF EXTENSION CALL OUTNAM SYS S_CREAT,OBJFIL,666 BCC 5$ SERROR #NOOUTF,#OBJFIL ;FAILED SO ERROR 5$: MOV R0,CRFLNK ;SAVE ID FOR LATER ;END OF CODE TO OPEN CRF FILE MOV #CRFBUF,CRFPNT .ENDC 2$: CALL SETSRC ;SET SOURCE SCAN 3$: CALL GETLIN ;GET THE NEXT INPUT LINE BNE 4$ ; BRANCH IF EOF CALL STMNT ;PROCESS THE STATEMENT 4$: CALL ENDLIN ;POLISH OFF LINE TST ENDFLG ;END SEEN? BEQ 3$ ; NO, CONTINUE CALL ENDP ;PROCESS END-OF-PASS CPOPJ: RETURN ENTSEC TXTBYT R50ABS: .ASCIZ /ABS./ ;; ". ABS." WITHOUT THE FIRST TWO CHARACTERS XITSEC ENTSEC TXTBYT CRFTXT: .ASCII /crf/ NOOUTF: .ASCIZ /CANNOT OPEN OUTPUT FILE: / XITSEC SETSRC: ;SET SOURCE FOR BEGINNING OF PASS MOV #CMDBUF,CMDPTR GETSRC: ;GET THE NEXT SOURCE FILE 1$: CLR PASSSW ;CLEAR PASS SWITCH PROCSI SRC ;PROCESS THE SOURCE FILE BEQ 2$ DEC PASSSW ;ANY PASS SWITCH? BMI GETSR2 ; NO CMP PASSSW,PASS ;YES, THIS PASS? BNE 1$ ; NO, IGNORE FILE BR GETSR2 2$: SETNZ CSISAV ;NO FILE RETURN GETSR2: ; OPEN INPUT FILE FROM SRCFIL TO SRCLNK ; ERROR IF NOT THERE MOV #SRCFIL,-(SP) ;TRY FOR .MAC EXTENSION MOV #MACTXT,-(SP) CALL OUTNAM ;TRANSMUTE NAME SYS S_OPEN,SRCFIL,0 MOV R0,-(SP) BCC 1$ SERROR #NOTHERE,#SRCFIL 1$: MOV #BUFROL,R0 ;FILE ID IS FIRST WORD OF BUFFER MOV ROLBAS(R0),R0 ;SO CALCULATE BUFFER ADDRESS MOV (SP)+,(R0)+ ;STORE FILE ID CLR (R0)+ ;CLEAR REST OF BUFFER HEADER CLR (R0)+ CLR (R0)+ INC SRCLNK ;INDICATE SOURCE FILE OPEN ;THE FORMAT OF AN INPUT BUFFER IS AS FOLLOWS ; ; =============== HIGH CORE ; 400 BYTE BUFFER ; =============== ; ; ; ; LOW CORE ; ;THE CURRENT INPUT BUFFER IS THE BOTTOM-MOST BUFFER IN BUFROL, ;I.E. THE ONE WHOSE FILE ID IS POINTED TO BY ROLBAS(BUFROL). ENTSEC TXTBYT MACTXT: .ASCII /mac/ NOTHERE: .ASCIZ /CANNOT OPEN INPUT FILE: / XITSEC ;END OF CODE TO OPEN SOURCE FILE CLR EOFFLG ;NO EOF YET INC FFCNT ;START A NEW PAGE RETURN INPSRC: ;INPUT A SOURCE BUFFER ; READ FROM SRCLNK INTO BUFFER AT 2(SP). ; SET EOFFLG IF EOF MOV 2(SP),R0 ;GET BUFFER ADDRESS MOV (SP)+,(SP) ;AND WIPE IT OUT ON STACK WITH RETURN ADDRESS MOV R1,-(SP) MOV R2,-(SP) MOV R3,-(SP) MOV R4,-(SP) MOV R0,-(SP) ;PUT BUFFER ADDRESS ON TOP OF STACK 11$: MOV #BUFROL,R4 ;CALCULATE INPUT BUFFER ADDRESS MOV ROLBAS(R4),R4 MOV #SRCLEN,R0 ;FIND OUT MAXIMUM LINE LENGTH MOV (SP),R1 ;AND WHERE TO PUT IT CLR (R1)+ ;CLEAR LINE LENGTH TST (R4)+ ;SKIP OVER FILE ID MOV (R4)+,R2 ;GET BUFFER BYTE COUNT MOV (R4)+,R3 ;AND POINTER OFFSET OF CURRENT BYTE ;R4 NOW POINTS TO EOF INDICATOR 1$: DEC R2 ;DECREMENT BUFFER COUNT BGE 5$ ;STILL SOMETHING LEFT .. SO MOVE IT TST (R4) ;BUFFER EMPTY SO SEE IF EOF BEQ 3$ ;NOPE SO INPUT ANOTHER BUFFER TST @(SP) ;SEE IF WE GAVE HIM ANYTHING AT ALL BNE 6$ ;YEP SO LET HIM HAVE IT TST SMLLNK ;SEE IF WE ARE DOING A SYSMAC.SML BNE 10$ ;YUP SO JUST RETURN TST CINSRT ;SEE IF WE ARE IN AN INSERT BNE 8$ ;YUP, SO DO RIGHT THING 10$: INC EOFFLG ;OTHERWISE SAY WE'RE ALL OUT BR 6$ 8$: DEC CINSRT ;DECREMENT INSERT COUNT MOV -6(R4),R0 ;CLOSE INSERT FILE sys s_close CALL BUFDONE ;COLLAPSE BUFFER ROLL BY 1 BR 11$ ;AND INPUT FROM NEXT PREVIOUS BUFFER 3$: MOV R0,R3 ;SAVE MOV R4,GETEMT+2 ;SET BUFFER ADDR IN READ CALL ADD #2,GETEMT+2 MOV -6(R4),R0 ;FILE ID sys s_indir,GETEMT ;DO THE READ MOV R0,R2 ;# OF BYTES ACTUALLY READ BNE 4$ ;(SOME WAS READ, NOT END OF FILE) INC (R4) ;END OF FILE, SET INDICATOR 4$: MOV R3,R0 ;RESTORE R0 MOV #2,R3 ;AND REINITIALIZE BUFFER POINTER BR 1$ ;AND INPUT SOME CHARACTERS 5$: MOV R4,-(SP) ;TRANSFER A CHARACTER -- FIRST CALCULATE ADD R3,(SP) ;WHERE IT IS THEN MOVE IT INC R3 ;AND INCREMENT BUFFER POINTER MOVB @(SP)+,R5 MOVB R5,(R1)+ INC @(SP) CMPB R5,#LF ;LF FF AND VT ARE DELIMITERS BLO 7$ CMPB R5,#FF BLOS 6$ 7$: DEC R0 ;CHECK MAX. LENGTH BGE 1$ ;STILL ROOM SO GO FOR MORE 6$: MOV R3,-(R4) ;SAVE INPUT POINTER FOR NEXT TIME MOV R2,-(R4) ;SAME FOR INPUT COUNT TST (SP)+ ;POP OFF BUFFER ADDRESS MOV (SP)+,R4 ;RESTORE REGISTERS MOV (SP)+,R3 MOV (SP)+,R2 MOV (SP)+,R1 RETURN ENTSEC SYSCALLS GETEMT: sys s_read, 0, <<*2>> XITSEC GENSWT PA,PASSSP PASSSP: ABSEXP ;/PASS, EVALUATE NUMBER MOV R0,PASSSW ;STORE RESULT RETURN GETLIN: ;GET AN INPUT LINE SAVREG CALL XCTLIN ;INIT LINE-ORIENTED VARIABLES GETL01: MOV FFCNT,R0 ;ANY RESERVED FF'S? BEQ 31$ ; NO ADD R0,PAGNUM ;YES, UPDATE PAGE NUMBER MOV #-1,PAGEXT CLR FFCNT .IF NDF XLCSEQ CLR LINNUM ;INIT NEW CREF SEQUENCE CLR SEQEND .ENDC TST PASS BEQ 31$ CLR LPPCNT 31$: MOV #LINBUF,R2 MOV R2,LCBEGL ;SEAT UP BEGINNING MOV #LINEND,LCENDL ; AND END OF LINE MARKERS .IF NDF XSML TST SMLCNT ;IN SYSTEM MACRO? BNE GETL40 ; YES, SPECIAL .ENDC .IF NDF XMACRO MOV MSBMRP,R1 ;ASSUME MACRO IN PROGRESS BNE GETL10 ;BRANCH IF SO .ENDC MOV #SRCBUF,R1 .IF NDF XLCSEQ INC LINNUM .ENDC MOV #SRCBUF-2,-(SP) CALL INPSRC ;GET NEXT SOURCE BUFFER TST EOFFLG ;EOF? BEQ GETL02 ;NO MOV #BUFROL,R0 ;GET FILE ID AND CLOSE FILE MOV @ROLBAS(R0),R0 sys s_close CLR SRCLNK ;USED AS EOF FLAG BY ENDP CALL GETSRC BIS CSISAV,ENDFLG BEQ GETL01 34$: ERROR E CLRB (R2) ;MAKE INTO NULL LINE BR GETL09 GETL02: MOV -(R1),R4 ;GET BYTE COUNT CLR (R1)+ ;SET STOPPER ADD R1,R4 ;COMPUTE END 3$: CLRB (R4) ;FORM ASCIZ MOVB -(R4),R5 ;GET LAST CHAR CMP R5,#CR ;IF > CR BHI 6$ CMP R5,#LF ; OR < LF BLO 6$ ; MOVE ON CMP R5,#FF ;FORM FEED? BNE 3$ ; NO, LOOP INC FFCNT ;COUNT THE PAGE BR 3$ 5$: MOVB R5,(R2)+ ;MOVE INTO LINBUF 6$: MOVB (R1)+,R5 ;FETCH NEXT CHAR MOVB CTTBL(R5),R0 ;GET CHARACTERISTICS BEQ 7$ ;QUESTIONABLE BIT #CT.LC,R0 ;LOWER CASE? BEQ 5$ ; NO .IF NDF XEDLC BIT #ED.LC,EDMASK ;LOWER CASE ENABLED? BEQ 4$ ;; NO .ENDC SUB #40,R5 ;; ELSE CONVERT TO UPPER CASE 4$: BR 5$ ;STORE 7$: MOVB R5,(R2) ;QUESTIONABLE, ASCIZ NULL? BEQ 8$ ; YES, ALL SET ERROR I ;NO, ILLEGAL CHARACTER MOV #200,R5 ;STORE ZERO WITH FLAG BIT BR 5$ 8$: GETL09: .IF NDF XEDCDR MOVB LINBUF+72.,CDRSAV ;SAVE COLUMN 73 BIT #ED.CDR,EDMASK ;CARD READER TYPE? BNE 38$ ; NO CLRB LINBUF+72. ;YES, FORCE EOL .ENDC 38$: MOV #LINBUF,CHRPNT SETNB BNE 39$ ;ALL SET IF NON-NULL LINE TST FFCNT ;NULL, FORM FEED? BEQ 39$ ; NO BRJMP GETL01 ;YES, JUST BUMP PAGE COUNT 39$: MOV ENDFLG,R0 ;RETURN WITH "ENDFLG" AS ARGUMENT NEG R0 RETURN .IF NDF XSML GETL40: MOV #LINBUF,R1 ;SYSTEM MACRO, CLR -(R1) ; MOVE RIGHT INTO LINBUF CLR -(R1) MOV #SRCLEN,-(R1) ; READ FROM SMLLNK INTO LINBUF ; SET ENDFLG AND BRANCH TO GETL09 IF EOF MOV #LINBUF-2,-(SP) ;GO GET A LINE IN LINBUF CALL INPSRC TST EOFFLG ;SEE IF WE'RE AT END BEQ 1$ ;NOPE SO GIV'EM LINE CLR EOFFLG ;YES -S O CLEAR THIS FLAG INC ENDFLG ;SET SMLEOF FLAG BR GETL09 1$: ;END OF CODE TO READ FROM SML CMP (R1)+,(R1)+ ;ELSE MOVE INDEX DEC (R1)+ ;BYPASS FF, POINT TO LINBUF BR GETL02 ;PROCESS NORMAL .ENDC .IF NDF XMACRO GETL10: CALL 20$ ;MOVE A CHARACTER BGT GETL10 ;LOOP IF GT ZERO BEQ 19$ ;END IF ZERO MOVB -(R2),R0 ;TERMINATOR, BACK UP POINTER CMP R0,#MT.MAX ;END OF TYPE? BLOS 22$ ; YES MOV R1,-(SP) ;REMEMBER READ POINTER MOV MSBARG,R1 TST (R1)+ MOV R2,R3 ; AND WRITE POINTER NEG R0 ;ASSUME MACRO CMP MSBTYP,#MT.MAC ;TRUE? BEQ 12$ ; YES, USE IT MOV MSBCNT,R0 ;GET ARG NUMBER 12$: MOV R3,R2 ;RESET WRITE POINTER 13$: CALL 20$ ;MOVE A BYTE BGT 13$ ;LOOP IF PNZ BLT 14$ ;END IF LESS THAN ZERO SOB R0,12$ ;LOOP IF NOT THROUGH 14$: TSTB -(R2) ;YES, BACK UP POINTER MOV (SP)+,R1 ;RESET READ POINTER BR GETL10 ;END OF ARGUMENT SUBSTITUTION 19$: MOV R1,MSBMRP ;END OF LINE, SAVE POINTER BIS #LC.ME,LCFLAG ;FLAG AS MACRO EXPANSION BR GETL09 20$: BIT #BPMB-1,R1 ;MACRO, END OF BLOCK? BNE 21$ ; NO MOV -BPMB(R1),R1 ;YES, POINT TO NEXT BLOCK TST (R1)+ ;MOVE PAST LINK 21$: CMP R2,#LINBUF+SRCLEN ;OVERFLOW? BLOS 23$ ; NO ERROR L ;YES, FLAG ERROR TSTB -(R2) ; AND MOVE POINTER BACK 23$: MOVB (R1)+,(R2)+ ;MOVE CHAR INTO LINE BUFFER RETURN 22$: CALL ENDMAC ;CLOSE MACRO JMP GETL01 .ENDC GETDBL: ;GET DOUBLE-BUFFERED INPUT ENDLIN: ;END OF LINE PROCESSOR SAVREG CLR ROLUPD ;SET TO FETCH FROM CODE ROLL TSTB CTTBL(R5) ;EOL OR SEMI-COLON? BLE 1$ ; YES ERROR Q 1$: CLR -(SP) ;INIT LISTING FLAG .IF NDF XEDCDR MOVB CDRSAV,LINBUF+72. ;REPLACE BORROWED CHAR .ENDC TST PASS ;PASS 1? BEQ 9$ ; YES TST ERRBTS ;ANY ERRORS? BNE 7$ ; YES, GO DIRECTLY, DO NOT COLLECT, ETC. TSTB LLTBL+LST.L ;ANY LISTING DEVICE? BEQ 9$ ; NO MOV #LST.L,(SP) ;YES, MAKE IT LOGICAL LP BIT #LC.LD,LCFLAG ;LISTING DIRECTIVE? BNE 5$ ; YES TST LCLVL ;TEST OVER-UNDER RIDE BLT 5$ ;IF <0, LIST ONLY IF ERRORS BGT 8$ ;IF >0, LIST UNCONDITIONALLY BIT #LC.COM,LCMASK ;COMMENT SUPPRESSION? BEQ 2$ ; NO MOV CHRPNT,LCENDL ;YES, ASSUME WE'RE SITTING AT COMMENT 2$: BIT #LC.SRC,LCMASK ;LINE SUPPRESSION? BEQ 3$ ; NO MOV #LINBUF,LCENDL ;YES, POINT TO START OF BUFFER 3$: .IF NDF XMACRO TSTB ROLSIZ+CODROL+1 ;ANYTHING IN CODE ROLL? BEQ 4$ ; NO BIT #LC.MEB,LCMASK ;MACRO BINARY EXPANSION? BNE 4$ ; NO BIC #LC.ME,LCFLAG ;YES, IGNORE ME FLAG .ENDC 4$: BIT LCMASK,LCFLAG ;ANYTHING SUPPRESSED? BEQ 9$ ; NO, USE CURRENT FLAGS 5$: CLR (SP) ;YES, CLEAR LISTING MODE BR 9$ 7$: MOVB LLTBL+LST.KL,(SP) ;ERROR, SET PROPER FLAGS .IF NDF XLCSEQ .IF NDF XLCTTM BIT #LC.TTM,LCMASK ;TELETYPE MODE? BNE 8$ ; NO, BYPASS EXTRA LINE .ENDC MOV #STARS,R1 ;"******" MOV #OCTBUF,R2 MOVBYT ;MOVE INTO OCTAL BUFFER MOVB #SPACE,(R2)+ CALL TSTERR ;SET ERRORS CLRB (R2) ;FORM ASCIZ MOVB (SP),LSTMOD MOV #OCTBUF,R1 PUTLIN ;DRAW THE USER'S ATTENTION .ENDC 8$: MOV #LINBUF,LCBEGL ;LIST ENTIRE LINE MOV #LINEND,LCENDL 9$: CALL PCROLL ;PROCESS ENTRY ON CODE ROLL ENDL10: MOVB (SP),LSTMOD ;ANYTHING REQUESTED? BEQ ENDL20 ; NO CLRB @LCENDL ;SET ASCIZ TERMINATOR MOV #OCTBUF,R2 11$: MOV #SPACE*400+SPACE,(R2)+ ;BLANK FILL CMP #LINBUF,R2 ;TEST FOR END (BEGINNING OF LINE BUFFER) BNE 11$ .IF NDF XLCTTM BIT #LC.TTM,LCMASK ;TELETYPE MODE? BNE ENDL50 ; NO .ENDC MOV #PF0,R1 TST (R1) ;ANYTHING FOR FIRST PRINT FIELD? BEQ 14$ ; NO MOV #OCTPF0,R2 ;YES, POINT TO IT CALL SETWRD ;UNPACK INTO BUFFER 14$: CLR (R1) ;CLEAR PF0 MOV #PF1,R1 TST (R1) ;ANYTHING FOR SECOND FIELD? BEQ 15$ ; NO MOV #OCTPF1,R2 CALL SETWDB ;LIST WORD OR BYTE BIT #77*400,(R1) ;TEST FOR LINKER MODIFICATION BEQ 15$ MOVB #CH.XCL,(R2) ; "'" BIT #GLBFLG,(R1) BEQ 15$ MOVB #LET.G,(R2) 15$: CLR (R1) ;CLEAR PF1 .IF NDF XLCSEQ MOV #OCTSEQ,R2 MOV #LINNUM,R0 ;POINT TO CREF LINE NUMBER MOV (R0)+,R1 CMP R1,(R0) ;NEW CREF NUMBER TO PUT OUT? BEQ 16$ ; NO MOV R1,(R0) ;YES, CLEAR FLAG BIT #LC.SEQ,LCMASK ;SUPPRESSED? BNE 16$ ; YES DNC MOV R2,SEQEND ;MARK HIGHEST SEQUENCE END 16$: MOVB #SPACE,(R2)+ CMP R2,SEQEND ;THROUGH? BLOS 16$ ; NO .ENDC MOV #OCTERP,R2 CALL TSTERR ;TEST FOR ERRORS MOV #OCTBUF+16.,R2 ;SET FOR CONCATENATION ENDL19: MOV LCBEGL,R1 ;POINT TO START OF LISTING LINE MOVBYT ;MOVE OVER MOV #OCTBUF,R1 ;POINT TO OCTAL BUFFER PUTLIN ;TEST FOR HEADER AND LIST ENDL20: CLRB @LCBEGL ;DON'T DUPE LINE .IF NDF XLCTTM TST ROLUPD ;FINISHED? BEQ ENDL30 ; YES, DON'T LOOP .ENDC CALL PCROLL BEQ ENDL30 ;EXIT IF EMPTY BIT #LC.BEX!LC.BIN,LCMASK ;BINARY EXTENSION SUPPRESSED? BEQ ENDL10 ; NO BR ENDL20 ;YES, DON'T LIST ENDL30: TST (SP)+ ;PRUNE LISTING FLAG ZAP CODROL ;CLEAR THE CODE ROLL MOV CLCLOC,R0 .IF DF YPHASE SUB PHAOFF,R0 .ENDC CMP R0,CLCMAX ;NEW HIGH FOR SECTOR? BLOS 31$ ; NO MOV R0,CLCMAX ;YES, SET IT 31$: RETURN .IF NDF XLCTTM ENDL50: MOV #OCTBUF,R2 ;POINT TO START OF BUFFER CALL TSTERR ;SET ERROR FLAGS .IF NDF XLCSEQ MOV #LINNUM,R0 MOV (R0)+,R1 CMP R1,(R0) BEQ 2$ MOV R1,(R0) BIT #LC.SEQ,LCMASK BNE 2$ MOV R2,R4 DNC MOV #OCTBUF+7,R0 1$: MOVB -(R2),-(R0) MOVB #SPACE,(R2) CMP R2,R4 BHI 1$ .ENDC MOV #OCTBUF+7,R2 2$: MOVB #TAB,(R2)+ MOV #PF0,R1 BIT #LC.LOC,LCMASK BNE 4$ TST (R1) BEQ 3$ CALL SETWRD 3$: MOVB #TAB,(R2)+ 4$: CLR (R1) MOV #PF1,R1 BIT #LC.BIN,LCMASK BNE ENDL19 MOV #3,R4 5$: TST (R1) BEQ 6$ CALL SETWDB BIT #77*400,(R1) BEQ 6$ MOVB #CH.XCL,(R2)+ BIT #GLBFLG,(R1) BEQ 6$ MOVB #LET.G,-1(R2) 6$: MOVB #TAB,(R2)+ CLR (R1) DEC R4 BEQ ENDL19 TST ROLUPD BEQ 6$ CALL PCROLL BR 5$ .ENDC TSTERR: ;TEST AND PROCESS ERRORS MOV ERRBTS,R0 ;ANY ERRORS? BEQ TSTER9 ; NO BIC #ERR.,R0 ;YES, ".PRINT"? BEQ 4$ ; YES INC ERRCNT ;BUMP ERROR COUNT 4$: MOV #ERRMNE-1,R1 1$: TSTB (R1)+ ;MOVE CHAR PNTR AND CLEAR CARRY ROR ERRBTS ;ROTATE ERROR BITS BCC 2$ MOVB (R1),(R2)+ .IF NDF XCREF MOVB (R1),R0 ;FETCH CHARACTER TSTR50 ;CONVERT TO RAD50 CALL MULR50 ;LEFT JUSTIFY CALL MULR50 MOV R0,SYMBOL ;STORE CLR SYMBOL+2 MOV #ERRROL,ROLNDX ;PREPARE TO CREF CRFREF ;DO SO .ENDC BR 1$ 2$: BNE 1$ TSTER9: RETURN .IF NDF XEDCDR GENEDT CDR,,1 .ENDC dma3.mac0000600002565200256520000000612102355753351010510 0ustar jncjnc .SBTTL MA3: STATEMENT PROCESSOR STMNT: MOV CNDWRD,R0 ;IN CONDITIONAL? BIS CNDMEX,R0 ; OR MEXIT? BNE 40$ ; YES, BRANCH IF SUPPRESSED GETSYM BEQ 20$ CMP R5,#CH.COL ; ":" BEQ LABEL CMP R5,#CH.EQU ; "=" BNE 1$ ; NO JMP ASGMT ;YES, PROCESS IT 1$: .IF NDF XMACRO MSRCH BEQ 2$ CRFREF JMP MACROC ;MACRO CALL .ENDC 2$: OSRCH BEQ 30$ CRFREF 10$: JMP PROPC ;PROCESS OP CODE 20$: .IF NDF XEDLSB MOV #10.,R2 ;NOT SYMBOL, PERHAPS LOCAL SYMBOL? CVTNUM BEQ 30$ ; NO CMP R5,#CH.DOL ;NUMBER, TERMINATED BY "$"? BNE 30$ ; NO GETNB CMP R5,#CH.COL BNE 30$ MOV CLCLOC,R0 SUB LSYBAS,R0 ;COMPUTE LOCAL OFFSET BIT #177400,R0 ;IN RANGE BEQ 21$ ; YES ERROR A ;NO, ERROR 21$: LSRCH ;YES, DO A LOCAL SYMBOL SEARCH BR LABELF ;EXIT THROUGH LABEL PROCESSOR .ENDC 30$: SETSYM ;RESET CHAR POINTER AND FLAGS TSTB CTTBL(R5) BLE 42$ ;NULL IF END OF LINE MOV #WRDSYM,R1 ;NEITHER, FUDGE ".WORD" DIRECTIVE MOV #SYMBOL,R2 CALL XMIT4 ;MOVE PST ENTRY TO "SYMBOL" BR 10$ 40$: CALL SETCLI ;UNSAT CONDITIONAL, TEST DIRECTIVE BMI 41$ ; BRANCH IF EOF BIT #DFLCND,R0 ;CONDITIONAL? BNE 10$ ; YES, PROCESS IT BIS #LC.CND,LCFLAG ;MARK AS UNSAT CONDITIONAL 41$: CLR R5 42$: RETURN ;IGNORE LINE SETCLI: 1$: GETSYM ;TRY FOR SYMBOL .IF NDF XEDLSB BNE 3$ ;BRANCH IF FOUND BITB #CT.NUM,CTTBL(R5) ;PERHAPS A LOCAL? BEQ 5$ ; NO 2$: GETCHR ;PERHAPS, TEST NEXT BITB #CT.ALP!CT.NUM,CTTBL(R5) ;ALPHA/NUMERIC? BNE 2$ ; YES, TRY AGAIN SETNB ;NO, BYPASS ANY BLANKS .IFF BEQ 5$ ; EXIT IF NO SYMBOL .ENDC 3$: CMP R5,#CH.EQU ;ASSIGNMENT (=)? BEQ 5$ ; YES, IGNORE THIS LINE CMP R5,#CH.COL ;LABEL (:)? BNE 4$ ; NO GETNB ;YES, BYPASS COLON BR 1$ ; AND CONTINUE 4$: OSRCH ;TRY FOR OP-CODE MOV MODE,R0 ;MODE TO R0 BPL 6$ ;BRANCH IF DIRECTIVE 5$: CLR R0 ;FALSE 6$: RETURN LABEL: ;LABEL PROCESSOR .ENABL LSB CLR LCLLBL ;SAY IS NOT LOCAL LABEL CMP SYMBOL+2,#DOTSTR;; PERIOD? BEQ 4$ ; YES, ERROR .IF NDF XEDLSB CALL LSBSET ;FLAG START OF NEW LOCAL SYMBOL BLOCK .ENDC SSRCH ;NO, SEARCH THE SYMBOL TABLE CRFDEF BR LABELX LABELF: INC LCLLBL LABELX: SETXPR ;SET EXPRESSION REGISTERS BIT #DEFFLG,(R3) ;ALREADY DEFINED? BNE 1$ ; YES MOV CLCFGS,R0 ;NO, GET CURRENT LOCATION CHARACTERISTICS BIC #377-,R0 ;CLEAR ALL BUT RELOCATION FLAG BIS #DEFFLG!LBLFLG,R0 ;FLAG AS LABEL TST LCLLBL ;LOCAL LABEL? BNE 6$ ;YES DO NOT PUT IN OP SYM TABLE BIT #ED.ISD,EDMASK ;ALL SYMBOLS TO BE INCLUDE? BEQ 7$ ;YEP, ADD IN BIT #ED.SYM,EDMASK ;; SYMBOL TO GO IN REL FILE? BNE 6$ ;; NO 7$: BIS #SYMFLG,R0 ;; ELSE SET SYMFLG 6$: BIS R0,(R3) ;SET MODE MOV CLCLOC,(R4) ; AND CURRENT LOCATION BR 3$ ;INSERT 1$: BIT #LBLFLG,(R3) ;DEFINED, AS LABEL? BEQ 2$ ; NO, INVALID CMP CLCLOC,(R4) ;HAS ANYBODY MOVED? BNE 2$ ; YES CMPB CLCSEC,(R2) ;SAME SECTOR? BEQ 3$ ; YES, OK 2$: ERROR P ;NO, FLAG ERROR BIS #MDFFLG,(R3) ;FLAG AS MULTIPLY DEFINED 3$: INSERT ;INSERT/UPDATE SETPF0 ;BE SURE TO PRINT LOCATION FIELD BR 5$ 4$: ERROR Q 5$: GETNB ;BYPASS COLON MOV CHRPNT,LBLEND ;MARK END OF LABEL BRJMP STMNT ;TRY FOR MORE GENEDT ISD,,1 ;ADD IN ISD OPTION .DSABL LSB dma4.mac0000600002565200256520000007216402271356604010520 0ustar jncjnc .SBTTL MA4: ASSIGNMENT PROCESSOR ASGMT: GETNB ;BYPASS "=" CALL INSYM ;; INSERT SYMBOL IN INPURE MOV #SYMBOL+4,R1 ;SET MIX-MASTER REGISTER MOV -(R1),-(SP) ;STACK SYMBOL MOV -(R1),-(SP) RELEXP ;GET NON-EXTERNAL EXPRESSION MOV (SP)+,(R1)+ ;RESTORE SYMBOL MOV (SP)+,(R1)+ BIT #ERR.U,ERRBTS ;ANY UNDEFINED'S? BNE ASGMTX ; YES, DON'T DEFINE ASGMTF: SETPF1 ;SET LISTING FIELD SETXPR ;SET EXPRESSION REGISTERS BIS #DEFFLG,(R3) ;FLAG AS DEFINED BIT #ED.SYM,EDMASK ;; SYMBOL FOR REL FILE? BNE 6$ ;; NO BIS #SYMFLG,(R3) ;; YES, MARK IT 6$: MOV (R3),-(SP) ;NO, STACK VALUE MOV (R4),-(SP) SSRCH ;SEARCH SYMBOL TABLE MOV (SP)+,(R4) ;RESTORE VALUE BIC #^C,(R3) BIS (SP)+,(R3) CMP 2(R1),#DOTSTR ;; MESSING WITH THE PC? BEQ 1$ ; YES 3$: INSERT ;INSERT NEW VALUE BR ASGMTX 1$: CMPB (R2),CLCSEC ;SAME SECTOR? BNE 2$ ; NO, ERROR MOV (R4),CLCLOC ;YES, SET NEW LOCATION BR ASGMTX 2$: ERROR M ASGMTX: CRFDEF RETURN .SBTTL MA4: OP CODE PROCESSOR PROPC: ;PROCESS OP CODE MOV #MODE,R4 ;POINT TO MODE MOV (R4),R1 ;LEAVE RESULT IN R1 CLR (R4)+ ;SET TO ZERO, POINT TO VALUE MOV #CLCLOC,R2 ;POINT R2 TO LOCATION COUNTER BIT #100000+DFLGEV,R1 ;OP CODE OR EVEN DIRECTIVE? BEQ 1$ ; NO BIT #1,(R2) ;YES, CURRENTLY EVEN? BEQ 1$ ; YES INC (R2) ;NO, MAKE IT EVEN ERROR B ; AND FLAG ERROR 1$: BIT #DFLGBM,R1 ;BYTE MODE DIRECTIVE? BEQ 2$ ; NO INC BYTMOD ;YES, SET FLAG 2$: TST R1 ;OP-CODE? BMI 10$ ; YES MOV (R4),-(SP) ;NO, DIRECTIVE. CLR (R4) ;CLEAR VALUE CLR R3 ;START WITH R3=0 JMP @(SP)+ ;GO TO PROPER HANDLER 10$: MOV #077776,PCRCNT ;LIST LOCATION OF FIRST WORD ONLY STCODE ;STUFF BASIC VALUE .IF NDF XCREF MOVB R1,CRFDFL+1 ;SET "*" CREF MARKERS .IFTF SWAB R1 BIC #177600,R1 ;CLEAR HIGH ORDER BITS MOV R1,OPCLAS ;SAVE CLASS ASL R1 ASL R1 ;FOUR BYTES PER TABLE ENTRY CLR -(SP) ;SET A STOPPER MOV OPJTBL+2(R1),-(SP) ;STACK SECOND ARG BNE 11$ ;BRANCH IF TWO ARGS TST (SP)+ ;ONE ARG, PRUNE TERMINATOR 11$: MOV OPJTBL(R1),R1 ;SET THE FIRST ARGUMENT BEQ 14$ ;BRANCH IF NO ARGS 12$: MOV R1,-(SP) ;SAVE A COPY OF THE ARG SWAB (SP) ;SHIFT COUNT TO RIGHT HALF BIC #177400,R1 ;ISOLATE LOW BYTE TSTARG ;COMMA TEST CLR R0 ;FUNCTION REGISTER CALL OPJBAS(R1) ;CALL PROPER ROUTINE .IFT ROLB CRFDFL+1 ;MOVE SECOND FIELD BIT .ENDC 13$: ASL R0 ;SHIFT RESULT DECB (SP) ;COUNT IN SP, RH BGE 13$ ROR R0 ;WE WENT ONE TOO MANY MOV ROLBAS+CODROL,R1 BIS R0,6(R1) ;SET EXPRESSION BITS TST (SP)+ ;PRUNE WORK ENTRY 14$: MOV (SP)+,R1 ;GET NEXT ARG FROM STACK BNE 12$ ;BRANCH IF NOT TERMINATOR .IF NDF XZERR MOV ROLBAS+CODROL,R1 MOV 6(R1),R0 ;SET FOR "Z" ERROR TESTS MOV R0,R1 BIC #000007,R1 CMP #000120,R1 ; JMP (R)+ BEQ 22$ BIC #000700,R1 CMP #004020,R1 ; JSR X,(R1)+ BEQ 22$ MOV R0,R1 BIT #007000,R1 ;FIRST ARG TYPE 0? BNE 23$ ; NO, OK BIC #100777,R1 BEQ 23$ CMP #070000,R1 ;DOUBLE ADDRESS TYPE? BEQ 23$ ; NO MOV R0,R1 BIC #170017,R1 CMP #000760,R1 ; MOV PC,[@]X(R) BEQ 22$ BIC #177717,R1 CMP #000020,R1 ; (R)+ BEQ 21$ CMP #000040,R1 ; -(R) BNE 23$ 21$: MOV R0,R1 ROL R1 ROL R1 SWAB R1 SUB R0,R1 BIT #000007,R1 ; R1=R2 BNE 23$ 22$: ERROR Z 23$: .ENDC RETURN .MACRO GENOPJ NUMBER,SUBR1,SC1,SUBR2,SC2 ;OP CODE JUMP TABLE .GLOBL OPCL'NUMBER OPCL'NUMBER= <.-OPJTBL>/4 .IIF NB,, .BYTE SUBR1-OPJBAS .IIF B , .BYTE 0 .BYTE SC1+0 .IIF NB,, .BYTE SUBR2-OPJBAS .IIF B , .BYTE 0 .BYTE SC2+0 .ENDM ENTSEC DPURE OPJTBL: ;OP CODE JUMP TABLE GENOPJ 00 GENOPJ 01, AEXP GENOPJ 02, AEXP, 6, AEXP GENOPJ 03, REGEXP GENOPJ 04, BROP GENOPJ 05, REGEXP, 6, AEXP GENOPJ 06, TRAPOP .IF NDF X45 GENOPJ 07, AEXP, 0, REGEXP, 6 GENOPJ 08, REGEXP, 6, SOBOP GENOPJ 09, AEXP, 0, REGEXP, 6 GENOPJ 10, MARKOP GENOPJ 11, AEXP, 0, DRGEXP, 6 GENOPJ 12, DRGEXP, 6, AEXP, 0 GENOPJ 13, SPLOP GENOPJ 14, AEXP, 0, DRGEXP, 6 .ENDC XITSEC ; ENTIMP IMPLIN ; BLKW OPCLAS ;OP CODE CLASS ; XITIMP IMPLIN OPJBAS: ;INDEX BASE FOR FOLLOWING ROUTINES RETURN REGEXP: ;REGISTER EXPRESSION ABSEXP ;EVALUATE ABSOLUTE BIT #177770,R0 ;ANY OVERFLOW? BEQ 1$ ; NO ERROR R ;YES, FLAG ERROR BIC #177770,R0 ;CLEAR OVERFLOW 1$: RETURN BROP: ;BRANCH DISPLACEMENT TYPE RELEXP CMPB SECTOR,CLCSEC BNE 2$ SUB CLCLOC,R0 ASR R0 BCS 2$ DEC R0 MOVB R0,R3 ;EXTEND SIGN CMP R0,R3 ;PROPER? BEQ 3$ ; YES 2$: ERROR A MOV #000377,R0 3$: BIC #177400,R0 ;CLEAR POSSIBLE HIGH BITS RETURN TRAPOP: ;TRAP TYPE SETXPR ;SET EXPRESSION REGISTERS MOV (R4),-(SP) ;SAVE THE VALUE EXPR ;EVALUATE THE EXPRESSION (NULL OK) INC BYTMOD ;TREAT AS BYTE SETIMM CMPB (R2),#200 ;ABSOLUTE? BNE 1$ ; NO TST (SP)+ ;YES, PRUNE STACK MOV (R4),R0 ;VALUE TO MERGE RETURN 1$: ZAP CODROL ;CLEAR CODE ROLL STCODE ;STORE ADDRESS MOV #100000,(R3) ;SET FOR ABSOLUTE BYTE SWAB (SP) MOV (SP)+,(R4) ;SET ORIGIONAL VALUE STCODE CLR R0 RETURN .IF NDF X45 DRGEXP: ;DOUBLE REGISTER EXPRESSION CALL REGEXP ;EVALUATE NORMAL MOV #177774,R3 ;TEST FOR OVERFLOW BR MASKR3 SOBOP: ;SOB OPERATOR CALL BROP ;FREE-LOAD OFF BRANCH OPERATOR MOVB R0,R0 ;EXTEND SIGN NEG R0 ;POSITIVE FOR BACKWARDS BR MASKB6 ;MASK TO SIX BITS SPLOP: ;SPL TYPE ABSEXP MOV #177770,R3 ;ONLY THREE BITS ALLOWED BR MASKR3 MARKOP: ;MARK OPERATOR ABSEXP ;EVALUATE ABSOLUTE MASKB6: MOV #177700,R3 ;SET TO MASK HIGH ORDER MASKR3: BIT R3,R0 ;OVERFLOW? BEQ 1$ ; NO ERROR T ;YES, FLAG TRUNCATION ERROR BIC R3,R0 ;CLEAR EXCESS 1$: RETURN .ENDC AEXP: SAVREG ;ADDRESS EXPRESSION EVALUATION SETXPR ; AND SET "EXPRESSION" TYPE INC EXPFLG CLR -(SP) ;ACCUMULATE ON TOP OF STACK AEXP02: CHSCAN AEXTBL ;TEST FOR OPERATOR BEQ AEXP22 ; NO JMP (R0) ;YES, GO TO IT ENTSEC DPURE AEXTBL: ;ADDRESS EXPRESSION TABLE GCHTBL CH.IND, AEXP03 ; "@" GCHTBL CH.HSH, AEXP06 ; "#" GCHTBL CH.SUB, AEXP10 ; "-" GCHTBL CH.LP, AEXP12 ; "(" .WORD 0 ;TERMINATOR XITSEC AEXP03: TST (SP) ;"@", SECOND TIME AROUND? BEQ 4$ ; NO ERROR Q ; YES 4$: BIS #AM.DEF,(SP) ;SET IT BR AEXP02 AEXP06: ;LITERAL (#) .IF NDF XFLTG CMP #OPCL11,OPCLAS ;CLASS 11? BNE 8$ ; NO CALL FLTG1W ;YES, TRY FOR ONE-WORD FLOATING BNE 9$ ;BRANCH IF OK .ENDC 8$: GLBEXP ;EVALUATE EXPRESSION 9$: BIS #AM.IMM,(SP) ;SET BITS BR AEXP32 ;USE COMMON EXIT AEXP10: ;AUTO-DECREMENT (-) CMP R5,#CH.LP ;FOLLOWED BY "("? BNE AEXP20 ; NOT A CHANCE CALL AEXPLP ;PROCESS PARENS BIS #AM.DEC,(SP) BR AEXP36 AEXP12: ; "(" CALL AEXPL1 ;EVALUATE REGISTER CMP R5,#CH.ADD ;AUTO-INCREMENT (+)? BNE 14$ ; NO GETNB ;YES, POLISH IT OFF BIS #AM.INC,(SP) ;SET BITS BR AEXP36 14$: BIT #AM.DEF,(SP) ;INDIRECT SEEN? BNE 16$ ; YES BIS #AM.DEF,(SP) ;NO, SET BIT BR AEXP36 16$: CLR (R3) ;MODE CLR (R4) ; AND VALUE BR AEXP30 AEXP20: SETSYM ;AUTO-DEC FAILURE, POINT TO - AEXP22: GLBEXP ;GET AN EXPRESSION CMP R5,#CH.LP ;INDEXED? BEQ 24$ ; YES BIT #REGFLG,(R3) ;FLAGS BNE AEXP36 .IF NDF XEDPIC!XEDAMA TST (SP) BNE 23$ .IF NDF XEDPIC BIT #ED.PIC,EDMASK BNE 1$ BIT #GLBFLG,(R3) BNE 2$ CMPB (R2),CLCSEC BEQ 23$ BR 2$ 1$: .ENDC .IF NDF XEDAMA BIT #ED.AMA,EDMASK ;ABSOLUTE MODE REQUESTED? BNE 23$ ; NO .ENDC 2$: BIS #AM.IMM!AM.DEF,(SP) ;OK, SET ABS MODE BR AEXP32 .ENDC 23$: BIS #AM.REL,(SP) ;NO SETDSP ;SET DISPLACEMENT BR AEXP34 24$: BIT #REGFLG,(R3) ;FLAGS BEQ 26$ ERROR R BIC #REGFLG,(R3) ;FLAGS 26$: MOV (R1)+,-(SP) ;STACK CURRENT VALUE MOV (R1)+,-(SP) MOV (R1)+,-(SP) MOV (R1)+,-(SP) CALL AEXPLP ;PROCESS INDEX MOV (SP)+,-(R1) ;RESTORE MOV (SP)+,-(R1) MOV (SP)+,-(R1) MOV (SP)+,-(R1) AEXP30: BIS R0,(SP) BIS #AM.NDX,(SP) AEXP32: SETIMM AEXP34: STCODE CLR R0 AEXP36: BIS (SP)+,R0 RETURN AEXPLP: ;AEXP PAREN PROCESSOR GETNB ;BYPASS PAREN AEXPL1: CALL REGEXP ;GET A REGISTER EXPRESSION CMP R5,#CH.RP ;HAPPY ENDING ")"? BNE 1$ ; NO JMP GETNB ;YES, BYPASS AND EXIT 1$: ERROR Q ;NO RETURN .IF NDF XEDAMA GENEDT AMA,,1 ;ABSOLUTE MODE ADDRESSING .ENDC .IF NDF XEDPIC GENEDT PIC,,1 ;PIC MODE .ENDC .SBTTL MA4: EXPRESSION TO CODE-ROLL CONVERSIONS SETIMM: ;SET IMMEDIATE MODE SAVREG ;SAVE REGISTERS SETXPR ; AND SET "EXPRESSION" TYPE MOV #IMMMOD,R1 ;SET TABLE INDEX BITB #GLBFLG,(R3) ;EXTERNAL? BNE SETDS3 ; YES, USE COMMON HANDLER CMPB (R1)+,(R1)+ ;MOVE INDEX BITB #RELFLG,(R3) ;RELOCATABLE? BEQ SETDSX ; NO, ALL SET TSTB (R1)+ CMPB (R2),CLCSEC ;YES, CURRENT SECTOR? BEQ SETDSX ; YES BR SETDS1 ;NO SETDSP: ;SET DISPLACEMENT MODE SAVREG ;SAVE REGISTERS SETXPR ; AND SET "EXPRESSION" TYPE MOV #DSPMOD,R1 ;SET INDEX BITB #GLBFLG,(R3) ;EXTERNAL? BNE SETDS3 ; YES, TEST FOR ADDITIVE CMPB (R1)+,(R1)+ CMPB (R2),CLCSEC ;CURRENT SECTOR? BEQ SETDS2 ; YES TSTB (R1)+ TSTB (R2) ;LOOKING AT ABSOLUTE? BEQ SETDSX ; YES SETDS1: TSTB (R1)+ CLR R0 ;CLEAR HIGH ORDER BISB (R2),R0 ;SET SECTOR IMULI RS.SEC*2,R0 ;MULTIPLY BY BYTES/BLOCK ADD ROLBAS+SECROL,R0 ;COMPUTE BASE OF SECTOR ROLL MOV (R0)+,SYMBOL ;XFER SECTOR NAME TO SYMBOL MOV (R0)+,SYMBOL+2 BR SETDSX SETDS2: MOVB ROLSIZ+CODROL+1,R0 ;GET CODE ROLL ENTRY NUMBER INC R0 ASL R0 ;MAKE IT 4 OR 6 ADD CLCLOC,R0 .IIF DF YPHASE, SUB PHAOFF,R0 SUB R0,(R4) CLR MODE BR SETDSX SETDS3: TST (R4) ;EXTERNAL, ANY OFFSET? BEQ SETDSX ; NO TSTB (R1)+ ;YES, ADVANCE INDEX SETDSX: .IF NDF XEDPIC BIT #ED.PIC,EDMASK BNE 12$ TSTB (R1) BEQ 12$ CMPB (R2),CLCSEC BEQ 10$ CMP R1,#DSPMOD BHIS 11$ BR 12$ 10$: CMP R1,#DSPMOD BHIS 12$ 11$: ERROR R 12$: .ENDC MOVB (R1),(R2) ;FILL IN TYPE TST BYTMOD ;IN BYTE MODE? BEQ 4$ ; NO TSTB (R4)+ ;MOVE TO HIGH BYTE OF "VALUE" MOVB (R4),R0 ;ANY HIGH ORDER BITES? BEQ 1$ ; NO, OK INC R0 ;YES, ALL ONES? BNE 2$ ; NO, YOU LOSE 1$: CMPB (R2),#RLDT01 ;ERROR IF RLD TYPE 1 BEQ 2$ CMPB (R2),#RLDT15 ; OR 15 BNE 3$ 2$: ABSERR ;FLAG ERROR 3$: CLRB (R4) BISB #200,(R2) ;FLAG AS BYTE 4$: RETURN ENTSEC TXTBYT IMMMOD: .BYTE RLDT02, RLDT05, RLDT00, RLDT01, RLDT15, 0 DSPMOD: .BYTE RLDT04, RLDT06, RLDT00, RLDT03, RLDT16, 0 XITSEC ; ENTIMP IMPLIN ; BLKW BYTMOD ;BYTE MODE IF NON-ZERO ; XITIMP IMPLIN .SBTTL MA4: DIRECTIVES .GLOBL GLOBL GLOBL: ;GLOBAL HANDLER 1$: GSARG ;GET A SYMBOL BEQ 3$ ; END SSRCH ;NO, SEARCH USER SYMBOL TABLE BIT #REGFLG,FLAGS ;REGISTER? BNE 2$ ; YES, ERROR BIS #GLBFLG,FLAGS ;NO, FLAG AS GLOBL INSERT ;UPDATE/INSERT CRFDEF BR 1$ 2$: ERROR R BR 1$ 3$: RETURN .GLOBL END END: ;TEMP END DIRECTIVE EXPR ;EVALUATE THE EXPRESSION BNE 1$ ; BRANCH IF NON-NULL INC (R4) ;NULL, MAKE IT A ONE 1$: INC ENDFLG SETIMM ;FILL OUT BLOCK SETPF1 ;LIST FIELD 1 CMPB SECTOR,#RLDT01 ;INTERNAL RELOCATION? BNE 4$ ;(NO) MOV CLCNAM,SYMBOL ;YES, STUFF NAME OF CURRENT CSECT. MOV CLCNAM+2,SYMBOL+2 4$: MOV #SYMBOL,R1 MOV #ENDVEC,R2 JMP XMIT4 ;MOVE TO END VECTOR ; ENTIMP IMPURE ; BLKW ENDVEC,4 ;END VECTOR STORAGE ; XITIMP IMPURE ENTSEC XCTPRG INC ENDVEC+6 ;DEFAULT TO NO END VECTOR XITSEC .GLOBL ASECT, CSECT ASECT: CALL SETMAX ;CLEAN UP CURRENT SECTOR CALL CSARGS ;PARSE OPTIONAL ARGUMENTS ASECTG: MOV #R50ABS,SYMBOL ;SET ". ABS." MOV #'.*400+40,SYMBOL+2 ;; FIRST 2 CHARACTERS OF ". ABS." BR CSECTG ;USE COMMON EXIT CSECT: CALL SETMAX ;CLEAN UP CURRENT SECTOR GETSYM ;GET ARGUMENT (OR NULL) CALL INSYM ;; MAKE SYMBOL PERMANENT CALL CSARGS ;PUT CLEAR BITS IN R1, SET BITS IN R2 CSECTG: SCAN SECROL ;SCAN FOR MATCH BNE 4$ ; BRANCH IF MATCH MOVB ROLSIZ+1+SECROL,SECTOR ;NEW GUY, SET SECTOR BEQ 2$ ;BRANCH IF ABS SECTOR (FOR NOW) BIS #RELFLG!ISPFLG!PURFLG,MODE ;DEFAULTS FOR CSECT 2$: BIC R1,MODE ;SET CSECT TYPE BIS R2,MODE INSERT ;ATTACH TO ROLL BR 3$ 4$: BIT MODE,R1 ;CLEAR ANY BITS THAT WERE SET? BNE 5$ ;(YES) COM R2 BIS MODE,R2 ;OR SET ANY THAT WERE CLEAR? INC R2 BEQ 3$ ;(NO) 5$: ERROR A ;YES, COMPLAIN. 3$: SETPF1 CRFREF MOV #SYMBOL,R1 MOV #CLCNAM,R2 .IF NDF XEDLSB CALL XMIT5 JMP LSBSET ;SET NEW LOCAL SYMBOL BASE .IFF JMP XMIT5 ;MOVE AND EXIT .ENDC ASECTF: CLR R1 ;PRETEND YOU READ A LINE AND THERE WEREN'T ANY ARGUMENTS. CLR R2 BR ASECTG CSECTF: CLR R1 CLR R2 BR CSECTG CSARGS: ;READ CSECT ARGUMENTS CLR R1 ;INITIALIZE TO NO ARGS CLR R2 MOV R0,-(SP) ;SAVE MOV #SYMBOL+10,R0 MOV -(R0),-(SP) ;SAVE "SYMBOL" MOV -(R0),-(SP) MOV -(R0),-(SP) MOV -(R0),-(SP) INC ARGCNT ;SKIP LEADING COMMAS 1$: GSARG ;GET A SYMBOLIC ARG BEQ 10$ ;(NONE) SETNZ UNMIXID ;A CSECT HAD AN ARG, DON'T MIX I AND D. SCANP CSAROL ;SEE WHAT KIND IT IS BEQ 63$ ;(COULDN'T FIND IT!) BIS MODE,R1 ;CLEAR BITS BIS VALUE,R2 ;AND SET BITS BR 1$ ;LOOK FOR MORE ARGS. 63$: ERROR A ;FLAG THE LINE BR 1$ ;THEN KEEP LOOKING FOR MORE ARGS. 10$: MOV #SYMBOL,R0 MOV (SP)+,(R0)+ ;RESTORE MOV (SP)+,(R0)+ MOV (SP)+,(R0)+ MOV (SP)+,(R0)+ MOV (SP)+,R0 BIT R1,R2 ;ANY CONFLICTS? BEQ 60$ ;(NO, OK) ERROR A ;(YES, SIGNAL ERROR) 60$: RETURN ENTSEC DPURE .MACRO GENCSA NAME,CBITS,SBITS .POINT NAME,DPURE .WORD CBITS .WORD SBITS .ENDM CSABAS: ;ROLL OF CSECT OPTIONS GENCSA IPURE, 0, ISPFLG!PURFLG GENCSA DPURE, ISPFLG, PURFLG GENCSA STATIC, ISPFLG!PURFLG, 0 GENCSA EXTERNAL, 0, GLBFLG GENCSA INTERNAL, GLBFLG, 0 CSATOP: XITSEC .IF DF YPHASE .GLOBL PHASE, DEPHA PHASE: RELEXP CMPB SECTOR,CLCSEC BNE 1$ MOV R0,PHAOFF SUB CLCLOC,PHAOFF MOV R0,CLCLOC RETURN 1$: ERROR A RETURN DEPHA: SUB PHAOFF,CLCLOC CLR PHAOFF RETURN ; ENTIMP IMPPAS ; BLKW PHAOFF ; XITIMP IMPPAS .ENDC SECINI: CALL ASECTF ;MOVE ONTO ROLL CLR SYMBOL ;; NO POINTER MOV #NULSTR,SYMBOL+2;; AND THE STRING " " .IF NDF XEDABS BIT #ED.ABS,EDMASK ;ABS MODE? BNE CSECTF ; NO RETURN .IFF BR CSECTF .ENDC .GLOBL MIXID,NMIXID,PREREQ MIXID: SETNZ FMIXID ;FORCE I AND D TO BE MIXED RETURN NMIXID: SETNZ UNMIXID ;DON'T ALLOW MIXING RETURN PREREQ: MOV #PRQBUF,R2 ;ADDR FOR PREREQ NAME SETNB ;SKIP LEADING BLANKS 2$: TSTB CTTBL(R5) ;ANYTHING THERE? BEQ 1$ ;NO, DONE. MOVB R5,(R2)+ ;YES, STORE CHAR CMP R2,#PRQBUF+PRQLEN ;GOT MORE ROOM? BHIS 63$ ;(NO) GETCHR ;GET THE NEXT BR 2$ ;LOOP BACK. 1$: CLRB (R2) ;MAKE IT .ASCIZ 63$: RETURN .GLOBL ENTRY ENTRY: TSTARG BEQ 63$ ;(NO ARGUMENTS) EXPR ;GET ADDRESS SETIMM ;CONVERT TO CODE ROLL FORMAT SETPF1 ;AND LIST IT. CMPB SECTOR,#RLDT01 ;INTERNAL RELOCATION? BNE 4$ MOV CLCNAM,SYMBOL ;THEN PUT IN CURRENT CSECT NAME. MOV CLCNAM+2,SYMBOL+2 4$: BIT ERRBTS,#ERR.U ;UNDEFINED SYMBOL? BEQ 6$ ;(NO) MOV #1,VALUE ;YES, PUT IN A 1. 6$: MOV #SYMBOL+10,R1 MOV -(R1),-(SP) MOV -(R1),-(SP) MOV -(R1),-(SP) MOV -(R1),-(SP) ;SAVE TSTARG BEQ 62$ ;(NO SECOND ARGUMENT) GETSYM ;; GET THE NAME CALL INSYM ;; MAKE IT PERMINANT MOV SYMBOL,SYMBOL+4 ;; AND SAVE IT MOV SYMBOL+2,SYMBOL+6 ;; BOTH WORDS 3$: MOV (SP)+,SYMBOL ;FILL IN REST OF ENTRY MOV (SP)+,SYMBOL+2 MOV (SP)+,ENTMOD MOV (SP)+,ENTVAL APPEND ENTROL ;STORE IT AWAY. RETURN 62$: ADD #10,SP ;POP STACK 63$: ERROR Q RETURN ;BAD ENTRY SPEC, DO NOTHING. SETMAX: ;SET MAX AND ENTER ONTO ROLL SAVREG ;PLAY IT SAFE MOV #CLCNAM,R1 MOV #SYMBOL,R2 CALL XMIT2 ;MOVE NAME TO SYMBOL SCAN SECROL ;SCAN SECTOR ROLL CALL XMIT3 ;SET REMAINDER OF ENTRIES JMP INSERT ;UPDATE ROLL AND EXIT .GLOBL LIMIT LIMIT: CALL OBJDMP CLR (R4) ;CLEAR VALUE MOV #RLDT11*400,-(R4) ;SET RLD TYPE STCODE CLR (R4) JMP STCODE .GLOBL TITLE, SBTTL, IDENT TITLE: GETSYM ;GET A SYMBOL BNE 1$ ; ERROR IF NULL ERROR A RETURN 1$: CALL INSYM ;; MAKE SYMBOL PERMANENT MOV SYMBOL,PRGTTL ;; MOVE INTO STORAGE MOV SYMBOL+2,PRGTTL+2 ;; MOVE SECOND HALF INTO STORAGE CALL SETSYM ;POINT TO START OF TITLE MOV #TTLBUF,R2 ;POINT TO BUFFER CLRB (R2)+ ;SET STOPPER 2$: MOVB R5,(R2) ;STORE CHARACTER BEQ 3$ ; BRANCH IF END TSTB (R2)+ GETCHR ;GET THE NEXT CMP R2,#TTLBU2-1 ;END OF BUFFER? BLO 2$ ; NO 3$: MOV #TTLBU2,R1 ;SET DESTINATION REG 4$: MOVB -(R2),-(R1) ;MOVE CHARACTER UP BNE 4$ MOVB #FF,(R1) ;SET PAGE EJECT MOV R1,TTLBEG ;MARK BEGINNING CLR R5 ;NO "Q" ERRORS RETURN SBTTL: ;SUB-TITLE DIRECTIVE MOV #STLBUF,R2 ;POINT TO SUB-TITLE BUFFER TST PASS ;PASS ONE? BEQ 2$ ; YES 1$: MOVB R5,(R2)+ ;MOVE CHARACTER IN BEQ 13$ ; BRANCH IF END GETCHR ;GET THE NEXT CHARACTER CMP R2,#STLBUF+STLLEN-1 ;TEST FOR END BLO 1$ TSTB -(R2) ;POLISH OFF LINE BR 1$ 2$: BIT #LC.TOC,LCMASK BNE 13$ TSTB LLTBL+LST.L ;ANY LISTING DEVICE? BEQ 13$ ; NO, EXIT MOV #TOCTXT,R1 MOVBYT ;SET TABLE OF CONTENTS CALL SETSYM ;POINT TO ".SBTTL" 3$: GETCHR ;; GET A CHARACTER BITB CTTBL(R5),#CT.ALP!CT.NUM!CT.LC ;; WAS IT PART OF THE .SBTTL? BNE 3$ ;; IF SO, LOOP AND EAT IT UP MOV CHRPNT,R2 ;SET POINTER .IF NDF XLCSEQ MOV LINNUM,R0 CALL 10$ MOVB #CH.SUB,-(R2) .IFF MOVB #TAB,-(R2) .ENDC MOV PAGNUM,R0 CALL 10$ MOVB #SPACE,-(R2) MOV R2,R1 JMP PUTLP ;OUTPUT IT 10$: MOV #3,R4 11$: MOVB #SPACE,-(R2) MOV R0,R1 BEQ 12$ CLR R0 DIV #^D10,R0 ADD #DIG.0,R1 MOVB R1,(R2) 12$: SOB R4,11$ 13$: RETURN ENTSEC TXTBYT TOCTXT: .ASCIZ /TABLE OF CONTENTS/ XITSEC IDENT: ;IDENT DIRECTIVE CALL RAD50 ;TREAT AS RAD50 CLR ROLUPD ;POINT TO START OF CODE-ROLL MOV #PRGIDN,R2 ; AND TO IDENT BLOCK 1$: NEXT CODROL ;GET NEXT ITEM MOV VALUE,(R2)+ ;STORE IT CMP R2,#PRGIDN+4 ;PROCESSED TWO WORDS? BLO 1$ ; NO MOV #GSDT06,(R2)+ ;YES, SET GSD TYPE ZAP CODROL ;CLEAR CODE ROLL RETURN ; ENTIMP IMPURE ; BLKW PRGTTL,4 ; BLKW PRGIDN,4 ;IDENT BLOCK ; XITIMP IMPURE .GLOBL PRINT, ERROR .ENABL LSB PRINT: ERROR <> ;NULL ERROR (DON'T COUNT) BR 1$ ERROR: ERROR P 1$: SETPF0 ;PRINT LOCATION FIELD EXPR ;EVALUATE EXPRESSION BEQ 2$ ;BRANCH IF NULL SETPF1 ;NON-NULL, LIST VALUE 2$: RETURN .DSABL LSB .GLOBL REM REM: ; ".REM" DIRECTIVE MOV R5,R3 ;SET TERMINATING CHARACTER BNE 1$ ;BRANCH IF NON-NULL ERROR A ;ERROR, NO DELIMITING CHARACTER RETURN 1$: GETCHR ;GET THE NEXT CHARACTER 2$: TST R5 ;END OF LINE? BNE 3$ ; NO CALL ENDLIN ;YES, POLISH OFF LINE CALL GETLIN ;GET NEXT LINE BEQ 2$ ;LOOP IF NO EOF RETURN ;EOF, EXIT 3$: CMP R5,R3 ;IS THIS THE TERMINATOR? BNE 1$ ; NO JMP GETNB ;YES, BYPASS AND EXIT .GLOBL BLKW, BLKB, EVEN, ODD, RADIX, EOT BLKW: INC R3 ;FLAG WORD TYPE BLKB: EXPR ;EVALUATE THE EXPRESSION BNE 1$ ;BRANCH IF NON-NULL INC (R4) ;NULL, MAKE IT ONE 1$: ABSTST ;MUST BE ABSOLUTE 2$: ADD R0,(R2) ;UPDATE PC ASR R3 ;WORD? BCS 2$ ; YES, DOUBLE VALUE RETURN EVEN: INC (R2) ;INCREMENT THE PC BIC #1,(R2) ;CLEAR IF NO CARRY RETURN ODD: BIS #1,(R2) ;SET LOW ORDER PC BYTE EOT: RETURN RADIX: MOV CRADIX,R2 ;SAVE IN CASE OF FAILURE MOV #10.,CRADIX ABSEXP CMP R0,#2. BLT 1$ CMP R0,#10. BLE 2$ 1$: ERROR A MOV R2,R0 2$: MOV R0,CRADIX JMP SETPF1 ; ENTIMP IMPPAS ;IMPURE AREA ; BLKW CRADIX ;CURRENT RADIX ; ; XITIMP IMPPAS ENTSEC XCTPAS ;TO BE EXECUTED EACH PASS MOV #8.,CRADIX ;INIT TO OCTAL RADIX XITSEC ;BACK TO NORMAL .SBTTL MA4: DATA-GENERATING DIRECTIVES .GLOBL BYTE, WORD WORD: INC R3 ;"WORD" DIRECTIVE, SET TO 2 BYTE: INC R3 ;"BYTE" DIRECTIVE, SET TO 1 MOV (R2),-(SP) ;STACK CURRENT PC 1$: TSTARG ;TEST FOR ARGUMENT BEQ 2$ ; END EXPR ;PROCESS GENERAL EXPRESSION SETIMM ;CONVERT TO OBJECT FORMAT STCODE ;PUT ON CODE ROLL ADD R3,(R2) ;UPDATE PC BR 1$ ;TEST FOR MORE 2$: MOV (SP)+,(R2) ;RESTORE INITIAL PC DGTEST: TSTB ROLSIZ+CODROL+1 ;ANY CODE GENERATED? BNE 1$ ; YES CLR MODE ;NO, STORE A ZERO CLR VALUE SETIMM STCODE 1$: RETURN .GLOBL RAD50, ASCII, ASCIZ ASCIZ: INC R3 ; ".ASCIZ", SET TO 1 ASCII: INC R3 ; ".ASCII", SET TO 0 RAD50: DEC R3 ; ".RAD50", SET TO -1 CALL 23$ ;INIT REGS 1$: MOV R5,R2 ;SET TERMINATOR BEQ 8$ ;ERROR IF EOL 2$: CMP R5,#CH.LAB ; "<", EXPRESSION? BEQ 10$ ; YES 3$: GETCHR ;NO, GET NEXT CHAR MOV R5,R0 ;SET IN WORK REGISTER BEQ 8$ ;ERROR IF EOL CMP R5,R2 ;TERMINATOR? BEQ 5$ ; YES TST R3 ;NO BGE 4$ 9$: TSTR50 ;TEST RADIX 50 4$: CALL 20$ ;PROCESS THE ITEM BR 3$ ;BACK FOR ANOTHER 5$: GETNB ;BYPASS TERMINATOR 6$: TSTB CTTBL(R5) ;EOL OR COMMENT? BGT 1$ ; NO BR 7$ 8$: ERROR A ;ERROR, FLAG AND EXIT 7$: CLR R0 ;YES, PREPARE TO CLEAN UP TST R3 ;TEST MODE BEQ 24$ ;NORMAL EXIT IF .ASCII BPL 20$ ;ONE ZERO BYTE IF .ASCIZ TST R1 ;.RAD50, ANYTHING IN PROGRESS? BEQ DGTEST ; NO, NORMAL EXIT CALL 20$ ;YES, PROCESS BR 6$ ;LOOP UNTIL WORD COMPLETED 10$: MOV (R4),-(SP) ;"", SAVE PARTIAL ABSTRM ;ABSOLUTE TERM, SETTING R0 MOV (SP)+,(R4) ;RESTORE PARTIAL CALL 20$ ;PROCESS BYTE BR 6$ ;TEST FOR END 20$: TST R3 ;RAD50? BPL 22$ ; NO CMP R0,#50 ;YES, WITHIN RANGE? BLO 21$ ; YES ERROR T ;NO, ERROR 21$: MOV R0,-(SP) ;SAVE CURRENT CHAR MOV (R4),R0 ;GET PARTIAL CALL MULR50 ;MULTIPLY ADD (SP)+,R0 ;ADD IN CURRENT MOV R0,(R4) ;SAVE INC R1 ;BUMP COUNT CMP R1,#3 ;WORD COMPLETE? BNE 24$ ; NO 22$: MOV R0,(R4) ;STUFF IN VALUE SETIMM ;CONVERT TO OBJ MODE STCODE ;STOW IT 23$: CLR R1 ;CLEAR LOOP COUNT CLR (R4) ; AND VALUE 24$: RETURN .IF NDF XFLTG .GLOBL FLT2, FLT4 FLT4: INC R3 FLT2: INC R3 ;MAKE IT 1 OR 2 ASL R3 ;NOW 2 OR 4 1$: TSTARG BEQ DGTEST MOV FLTPNT-2(R3),-(SP) ;EVALUATE NUMBER CALL @(SP)+ BNE 2$ ;BRANCH IF NON-NULL ERROR A ; NULL, FLAG ERROR 2$: MOV R3,R2 ;GET A WORKING COUNT MOV #FLTBUF,R1 ;POINT TO FLOATING POINT BUFFER 3$: MOV (R1)+,(R4) ;MOVE IN NEXT NUMBER STCODE ;PLACE ON CODE ROLL SOB R2,3$ ;LOOP ON WORD COUNT BR 1$ ;CONTINUE ENTSEC DPURE FLTPNT: .WORD FLTG2W, FLTG4W XITSEC .IF NDF XEDFPT GENEDT FPT,,1 ;FLOATING POINT TRUNCATION .ENDC FLTG4W: INC FLTWDC ;FLOATING POINT NUMBER EVALUATOR FLTG2W: INC FLTWDC FLTG1W: SAVREG ;SAVE REGISTERS MOV CHRPNT,-(SP) ;STACK CURRENT CHARACTER POINTER MOV #FLTBUF,R3 ;CONVENIENT COPY OF POINTERS MOV #FLTSAV,R4 ; TO BUFFER AND SAVE AREA MOV R4,R1 1$: CLR -(R1) ;INIT VARIABLES CMP R1,#FLTBEG BHI 1$ ;LOOP UNTIL DONE MOV #65.,FLTBEX ;INIT BINARY EXPONENT CMP #CH.ADD,R5 ; "+"? BEQ 10$ ; YES, BYPASS AND IGNORE CMP #CH.SUB,R5 ; "-"? BNE 11$ ; NO MOV #100000,FLTSGN ;YES, SET SIGN AND BYPASS CHAR 10$: GETCHR ;GET THE NEXT CHARACTER 11$: BITB #CT.NUM,CTTBL(R5) ;NUMERIC? BEQ 20$ ; NO BIT #174000,(R3) ;NUMERIC, ROOM FOR MULTIPLICATION? BEQ 12$ ; YES INC FLTEXP ;NO, COMPENSATE FOR THE SNUB BR 13$ 12$: CALL FLTM50 ;MULTIPLY BY 5 CALL FLTGLS ;CORRECTION, MAKE THAT *10 SUB #DIG.0,R5 ;MAKE ABSOLUTE MOV R4,R2 ;POINT TO END OF BUFFER ADD R5,-(R2) ;ADD IN ADC -(R2) ;RIPPLE CARRY ADC -(R2) ADC -(R2) 13$: ADD FLTDOT,FLTEXP ;DECREMENT IF PROCESSING FRACTION CLR (SP) ;CLEAR INITIAL CHAR POINTER (WE'RE GOOD) BR 10$ ;TRY FOR MORE 20$: CMP #CH.DOT,R5 ;DECIMAL POINT? BNE 21$ ; NO COM FLTDOT ;YES, MARK IT BMI 10$ ;LOOP IF FIRST TIME AROUND 21$: CMP #LET.E,R5 ;EXPONENT? BEQ 22$ ;; YES CMP #LET.E!40,R5 ;; EXPONENT? (BIG E VS LITTLE E) BNE FLTG3 ; NO 22$: GETNB ;YES, BYPASS "E" AND BLANKS MOV CRADIX,-(SP) ;STACK CURRENT RADIX MOV #10.,CRADIX ;SET TO DECIMAL ABSTRM ;ABSOLUTE TERM MOV (SP)+,CRADIX ;RESTORE RADIX ADD R0,FLTEXP ;UPDATE EXPONENT ; BR FLTG3 ;FALL THROUGH FLTG3: MOV R3,R1 MOV (R1)+,R0 ;TEST FOR ZERO BIS (R1)+,R0 BIS (R1)+,R0 BIS (R1)+,R0 BEQ FLTGEX ;EXIT IF SO 31$: TST FLTEXP ;TIME TO SCALE BEQ FLTG5 ;FINI IF ZERO BLT 41$ ;DIVIDE IF .LT. ZERO CMP (R3),#031426 ;MULTIPLY, CAN WE *5? BHI 32$ ; NO CALL FLTM50 ;YES, MULTIPLY BY 5 INC FLTBEX ; AND BY TWO BR 33$ 32$: CALL FLTM54 ;MULTIPLY BY 5/4 ADD #3.,FLTBEX ; AND BY 8 33$: DEC FLTEXP ; OVER 10 BR 31$ 40$: DEC FLTBEX ;DIVISION, LEFT JUSTIFY BITS CALL FLTGLS 41$: TST (R3) ;SIGN BIT SET? BPL 40$ ; NO, LOOP MOV #16.*2,-(SP) ;16 OUTER, 2 INNER CALL FLTGRS ;SHIFT RIGHT CALL FLTGSV ;PLACE IN SAVE BUFFER 42$: BIT #1,(SP) ;ODD LAP? BNE 43$ ; YES CALL FLTGRS ;MOVE A COUPLE OF BITS RIGHT CALL FLTGRS 43$: CALL FLTGRS ;ONCE MORE TO THE RIGHT CALL FLTGAD ;ADD IN SAVE BUFFER DEC (SP) ;END OF LOOP? BGT 42$ ; NO TST (SP)+ ;YES, PRUNE STACK SUB #3.,FLTBEX INC FLTEXP BR 31$ FLTG5: DEC FLTBEX ;LEFT JUSTIFT CALL FLTGLS BCC FLTG5 ;LOSE ONE BIT ADD #200,FLTBEX ;SET EXCESS 128. BLE 2$ ;BRANCH IF UNDER-FLOW TSTB FLTBEX+1 ;HIGH ORDER ZERO? BEQ 3$ ; YES 2$: ERROR N ;NO, ERROR 3$: MOV R4,R2 ;SET TO SHIFT EIGHT BITS MOV R2,R1 TST -(R1) ;R1 IS ONE LOWER THAN R2 4$: CMP -(R1),-(R2) ;DOWN ONE WORD MOVB (R1),(R2) ;MOVE UP A BYTE SWAB (R2) ;BEWARE OF THE INSIDE-OUT PC!! CMP R2,R3 ;END? BNE 4$ CALL FLTGRS ;SHIFT ONE PLACE RIGHT ROR (R4) ;SET HIGH CARRY .IF NDF XEDFPT BIT #ED.FPT,EDMASK ;TRUNCATION? BEQ 7$ ; YES .ENDC MOV FLTWDC,R2 ;GET SIZE COUNT ASL R2 ;DOUBLE BNE 8$ ;PRESET TYPE INC R2 ;SINGLE WORD 8$: ASL R2 ;CONVERT TO BYTES BIS #077777,FLTBUF(R2) SEC 5$: ADC FLTBUF(R2) DEC R2 DEC R2 BGE 5$ TST (R3) ;TEST SIGN POSITION BPL 7$ ;OK IF POSITIVE 6$: ERROR T 7$: ADD FLTSGN,(R3) ;SET SIGN, IF ANY FLTGEX: CLR MODE ;MAKE ABSOLUTE CLR FLTWDC ;CLEAR COUNT MOV (R3),VALUE ;PLACE FIRST GUY IN VALUE MOV (SP)+,R0 ;ORIGIONAL CHAR POINTER BEQ 1$ ;ZERO (GOOD) IF ANY DIGITS PROCESSED MOV R0,CHRPNT ;NONE, RESET TO WHERE WE CAME IN CLR R3 ;FLAG AS FALSE 1$: MOV R3,R0 ;SET FLAG IN R0 JMP SETNB ;RETURN WITH NON-BLANK FLTM54: ;*5/4 CMP (R3),#146314 ;ROOM? BLO 1$ CALL FLTGRS INC FLTBEX 1$: CALL FLTGSV ;SAVE IN BACKUP CALL FLTGRS ;SCALE RIGHT CALL FLTGRS BR FLTGAD FLTM50: ;*5 CALL FLTGSV CALL FLTGLS CALL FLTGLS FLTGAD: ;ADD SAVE BUFFER TO FLTBUF MOV R4,R2 ;POINT TO SAVE AREA 1$: ADD 6(R2),-(R2) ;ADD IN WORD MOV R2,R1 ;SET FOR CARRIES 2$: ADC -(R1) ;ADD IN BCS 2$ ;CONTINUE RIPPLE, IF NECESSARY CMP R2,R3 ;THROUGH? BNE 1$ ; NO RETURN FLTGRS: CLC ;RIGHT SHIFT MOV R3,R1 ;RIGHT ROTATE ROR (R1)+ ROR (R1)+ ROR (R1)+ ROR (R1)+ RETURN FLTGLS: ;LEFT SHIFT MOV R4,R2 ASL -(R2) ROL -(R2) ROL -(R2) ROL -(R2) RETURN FLTGSV: MOV R3,R1 ;MOVE FLTBUF TO FLTSAV MOV R4,R2 JMP XMIT4 ; ENTIMP IMPURE ;FLTBEG=.BASE ;START OF FLOATING POINT IMPURE ; BLKW FLTSGN ;SIGN BIT ; BLKW FLTDOT ;DECIMAL POINT FLAG ; BLKW FLTEXP ;DECIMAL EXPONENT ; BLKW FLTBEX,1 ;BINARY EXPONENT (MUST PRECEED FLTBUF) ; BLKW FLTBUF,4 ;MAIN AC ; BLKW FLTSAV,4 ; ; XITIMP IMPURE ; ENTIMP IMPLIN ; BLKW FLTWDC ;WORD COUNT ; ; XITIMP IMPLIN .ENDC .SBTTL MA4: .INSRT DIRECTIVE ;THIS ROUTINE PROCESSES A MACRO DIRECTIVE OF THE FORM ; ; .INSRT ; ;WHERE IS THE USUAL DELPHI-FORMAT FILE SPECIFICATION. ;THIS FILE IS OPENED FOR INPUT FIRST LOOKING FOR IT WITH A .MAC ;EXTENSION IN THE CURRENT DEFAULT DIRECTORY AND THEN IN >MACRO.LIB>. ;IF IT IS NOT FOUND IN EITHER PLACE THEN AN "F" ERROR IS INDICATED. ;SUBSEQUENT REQUESTS FOR SOURCE INPUT COME FROM THIS FILE UNTIL ;AN EOF IS FOUND THEN INPUT REVERTS TO THE PREVIOUS SOURCE ;FILE. THE ONLY LIMIT ON THE NUMBER OF INSERTS THAT CAN BE NESTED ;IS THE NUMBER OF FILES WHICH CAN BE OPEN SIMULTANEOUSLY. .GLOBL INSRT INSRT: SETNB ;FIND BEGINNING OF FILE NAME CMPB R5,#12 ;IF WE FOUND AN EOL INSTEAD BNE 1$ 63$: ERROR F ;THEN GIVE AN "F" ERROR AND RETURN RETURN 1$: MOV #SRCFIL,R1 ;THIS IS WHERE WE'LL PUT NAME MOV #DFLNAM,R2 ;SAVE A COPY IN DFLNAM BUFFER MOVB R5,(R1)+ ;SAVE FIRST CHARACTER OF NAME MOVB R5,(R2)+ 2$: GETCHR ;GET NEXT CHARACTER TSTB R5 ;IF EOL THEN DONE BEQ 3$ MOVB R5,(R1)+ ;OTHERWISE STORE CHARACTER MOVB R5,(R2)+ CMP R1,#SRCFIL+FNLEN;IN CASE FILE NAME IS TOO LONG BHIS 63$ ;AUTOMATIC "F" ERROR. BR 2$ ;AND TRY FOR ANOTHER 3$: CLRB (R1) ;MAKE NAME ASCIZ CLRB (R2) SETNB ;READ EXTRA SPACES SYS S_OPEN,SRCFIL,0 ;TRY NAME EXACTLY AS HE SPECIFIED IT BCC 6$ MOV #SRCFIL,-(SP) ;NOW CHANGE NAME TO HAVE MOV #MACTXT,-(SP) ;.MAC EXTENSION CALL OUTNAM SYS S_OPEN,SRCFIL,0 BCC 6$ MOV #DEFINS,R0 ;NOW TRY DEFAULT DIRECTORY MOV #DEFINC,R1 ;BY BY PREPENDING NAME MOV #DEFDIR,R2 ;NOTE THAT IF .INSRT HAD A DIRECTORY 5$: MOVB (R0)+,(R2)+ ;SPECIFICATION THEN THIS MAKES NO SOB R1,5$ ;DIFFERENCE (IT WILL FAIL AGAIN). MOV #SRCFIL,R1 ;ADD ON FILE NAME, ONLY TRY MOVBYT ;WITH .MAC ENDING SYS S_OPEN,DEFDIR,0 BCC 6$ ERROR F ;"F" ERROR RETURN 6$: MOV R0,-(SP) ;STACK FILE ID WHERE DELPHI WOULD HAVE PUT IT 11$: CALL BUFBGN ;ALLOCATE BUFFER IN BUFROL MOV #BUFROL,R0 ;FIND OUT WHERE IT WAS PUT MOV ROLBAS(R0),R0 MOV (SP)+,(R0)+ ;STORE FILE ID AT BEGINNING CLR (R0)+ ;CLEAR REST OF HEADER CLR (R0)+ CLR (R0)+ INC CINSRT ;INCREMENT INSERT COUNT RETURN ENTSEC TXTBYT DEFINS: .ASCII "/insert/" DEFINC= .-DEFINS XITSEC ;INSR1 -- JUST LIKE .INSRT EXCEPT ONLY DONE ON PASS 1 .GLOBL INSR1 INSR1: TST PASS ;FIND OUT WHAT PASS WE'RE ON BNE 1$ ;IF PASS 2 THEN JUST SKIP OVER FILE NAME JMP INSRT ;OTHERWISE ACT NORMAL 1$: SETNB ;SKIP OVER SEPARATORS CLR R1 ;COUNT CHARS CMP R5,#12 ;IF EOL THEN GIVE F ERROR BNE 2$ 4$: ERROR F RETURN 2$: GETCHR ;LOOK FOR NEXT SEPARATOR INC R1 ;BUMP CHAR COUNT TSTB R5 BEQ 3$ CMP R1,#FNLEN-1 ;FILE NAME LENGTH > MAX? BHIS 4$ ;(THEN GIVE F ERROR) BR 2$ 3$: SETNB RETURN ;THIS ROUTINE ALLOCATES ANOTHER INPUT BUFFER IN BUFROL. THE OLD ;BUFFERS ARE "MOVED UP" AND THE NEW BUFFER IS PUT AT THE BOTTOM - ;THUS MAKING IT THE CURRENT INPUT BUFFER. BUFBGN: APPEND BUFROL ;GO MAKE SOME ROOM MOV #BUFROL,R0 ;FIND OUT WHERE IT WAS PUT MOV ROLBAS(R0),R1 ;GET BOTTOM OF ROLL MOV ROLTOP(R0),R0 ;AND TOP. MOV R0,R2 ;FIGURE OUT WHERE OLD TOP IS SUB #,R2 ;BY SUBTRACTING ONE BUFFER'S WORTH 1$: MOV -(R2),-(R0) ;MOVE EVERYTHING UP A BUFFER CMP R2,R1 ;QUIT WHEN WE'VE HIT BOTTOM BHI 1$ RETURN ;THIS ROUTINE DEALLOCATES AN INPUT BUFFER BY MOVING THE SECOND ;THRU LAST INPUT BUFFER "DOWN ONE" AND THEN RESETTING THE TOP OF BUFROL. BUFDONE: MOV #BUFROL,R3 ;FIND OUT WHERE TO BEGIN MOV ROLBAS(R3),R1 MOV ROLTOP(R3),R0 MOV R1,R2 ;"FROM" POINTER = BOTTOM + BUFFER SIZE ADD #,R2 1$: MOV (R2)+,(R1)+ CMP R2,R0 ;QUIT WHEN WE HIT TOP BLO 1$ SUB #,ROLTOP(R3) ;SHRINK BUFROL RETURN dma5.mac0000600002565200256520000004765602141527064010525 0ustar jncjnc .SBTTL MA5: CONDITIONALS .GLOBL IIF IIF: ;IMMEDIATE HANDLERS CALL TCON ;TEST ARGUMENT TST R3 BMI 3$ ; BRANCH IF UNSATISFIED CMP #CH.COM,R5 ;COMMA? BNE 1$ ; NO GETCHR ;YES, BYPASS 1$: MOV CHRPNT,R1 ;SAVE CURRENT LOCATION SETNB ;SET TO NOM-BLANK BIT #LC.CND,LCMASK ;CONDITIONAL SUPPRESSION? BEQ 2$ ; NO MOV R1,LCBEGL ;YES, SUPPRESS ALL UP TO COMMA 2$: CLR ARGCNT JMP STMNT ;BACK TO STATEMENT 3$: CLR R5 ;FALSE, BUT NO "Q" ERROR BR ENDCX ;CONCATENATED CONDITIONALS .IRP ARG, .GLOBL IF'ARG IF'ARG: .ENDM MOV SYMBOL+2,SYMBOL ;TREAT SECOND HALF AS ARGUMENT CALL TCONF ;EXAMINE IT BR IF1 ;INTO THE MAIN STREAM .GLOBL IF, IFT, IFF, IFTF, ENDC IF: ;MICRO-PROGRAMMMED CONDITIONAL CALL TCON ;TEST ARGUMENT IF1: MOV #CNDLVL,R1 ;POINT TO LEVEL CMP (R1),#15. ;ROOM FOR ANOTHER? BGT IFOERR ; NO, ERROR INC (R1) ;YES, BUMP LEVEL ASL R3 ;SET CARRY TO TRUE (0) OR FALSE (1) ROR -(R1) ;ROTATE INTO CNDMSK ASL R3 ROR -(R1) ;DITTO FOR CNDWRD BR ENDCX IFT: ;IF TRUE SUB-CONDITIONAL MOV CNDMSK,R3 ;GET CURRENT BR IFTF ; AND BRANCH IFF: ;IF FALSE SUB-CONDITIONAL MOV CNDMSK,R3 ;GET CURRENT CONDITION COM R3 ;USE COMPLEMENT AND FALL THROUGH IFTF: ;UNCONDITIONAL SUB-CONDITIONAL ;(R3=0 WHEN CALLED DIRECTLY) TST CNDLVL ;CONDITIONAL IN PROGRESS? BLE IFOERR ; NO, ERROR ASL CNDWRD ;MOVE OFF CURRENT FLAG ASL R3 ;SET CARRY ROR CNDWRD ;MOV ON BR ENDCX ENDC: ;END OF CONDITIONAL MOV #CNDLVL,R1 ;POINT TO LEVEL TST (R1) ;IN CONDITIONAL? BLE IFOERR ; NO, ERROR DEC (R1) ;YES, DECREMENT ASL -(R1) ;REDUCE MASK ASL -(R1) ; AND TEST WORD ENDCX: BIT #LC.CND,LCMASK ;SUPPRESSION REQUESTED? BEQ 2$ ; NO MOV LBLEND,R0 ;YES, ANY LABEL? BEQ 1$ ; NO, SUPPRESS WHOLE LINE MOV R0,LCENDL ;YES, LIST ONLY LABEL BR 2$ 1$: BIS #LC.CND,LCFLAG ;MARK CONDITIONAL 2$: RETURN IFOERR: ERROR O ;CONDITION ERROR RETURN TCON: ;TEST CONDITION GSARG ;GET A SYMBOL TCONF: SCANP CNDROL ;SCAN FOR ARGUMENT BEQ IFAERR ; ERROR IF NOT FOUND MOV SYMBOL+4,R1 ;GET ADDRESS ASR R1 ;LOW BIT USED FOR TOGGLE FLAG SBC R3 ;R3 GOES TO -1 IF ODD ASL R1 ;BACK TO NORMAL (AND EVEN) TST CNDWRD ;ALREADY UNSAT? BNE IFAERX ; YES, JUST EXIT TSTARG ;BYPASS COMMA JMP @R1 ;JUMP TO HANDLER IFAERR: ERROR A IFAERX: CLR R5 ;NO "Q" ERROR RETURN GENCND EQ, TCONEQ GENCND NE, TCONEQ, F GENCND Z, TCONEQ GENCND NZ, TCONEQ, F GENCND GT, TCONGT GENCND LE, TCONGT, F GENCND G, TCONGT GENCND LT, TCONLT GENCND GE, TCONLT, F GENCND L, TCONLT GENCND DF, TCONDF GENCND NDF, TCONDF, F GENCND P1, TCONP1 GENCND P2, TCONP1, F TCONEQ: ABSEXP ;EQ/NE, TEST EXPRESSION BEQ TCONTR ;BRANCH IF SAT TCONFA: COM R3 ; FALSE, TOGGLE TCONTR: RETURN ;TRUE, JUST EXIT TCONGT: ABSEXP BGT TCONTR BR TCONFA TCONLT: ABSEXP BLT TCONTR BR TCONFA TCONP1: TST PASS ;; PASS 1? BEQ TCONTR ;; YES BR TCONFA ;; NO TCONDF: ;IF/IDF MOV R3,R1 ;SAVE INITIAL CONDITION CLR R2 ;SET "&" CLR R3 ;START OFF TRUE 1$: GETSYM ;GET A SYMBOL BEQ IFAERR ; ERROR IF NOT A SYM SSRCH ;SEARCH USER SYMBOL TABLE CRFREF CLR R0 ;ASSUME DEFINED BIT #DEFFLG,MODE ;GOOD GUESS? BNE 2$ ; YES COM R0 ;NO, TOGGLE 2$: CMP R0,R3 ;YES, MATCH? BEQ 3$ ; YES, ALL SET MOV R2,R3 ; NO COM R3 3$: MOV R1,R2 ;ASSUME "&" CMP R5,#CH.AND ; "&" BEQ 4$ ; BRANCH IF GOOD GUESS CMP R5,#CH.IOR ;PERHAPS OR? BNE 5$ ; NO COM R2 ;YES, TOGGLE MODE 4$: GETNB ;BYPASS OP BR 1$ ;TRY AGAIN 5$: TST R1 ;IFDF? BEQ 6$ ; YES COM R3 ;NO, TOGGLE 6$: RETURN ; ENTIMP IMPPAS ; ;CONDITIONAL STORAGE (MUST BE ORDERED) ; BLKW CNDWRD ;TEST WORD ; BLKW CNDMSK ;CONDITION MASK ; BLKW CNDLVL ;NESTING LEVEL ; BLKW CNDMEX ;MEXIT FLAG ; XITIMP IMPPAS .SBTTL MA5: LISTING CONTROL .GLOBL NLIST, LIST NLIST: COM R3 ;MAKE R3 -1 LIST: ASL R3 ;MAKE R3 0/-2 INC R3 ;NOW 1/-1 1$: TSTARG ;TEST FOR ANOTHER ARGUMENT BNE 2$ ; VALID TST ARGCNT ;NULL, FIRST? BNE 7$ ; NO, WE'RE THROUGH INC ARGCNT ;YES, MARK IT 2$: GETSYM ;TRY FOR A SYMBOL SCANP LCDROL ;LOOK IT UP IN THE TABLE BEQ 6$ ; ERROR IF NOT FOUND CLR R2 SEC 3$: ROL R2 SOB R0,3$ TST CSIFLG ;CALLED FROM COMMAND STRING? BEQ 11$ ; NO BIS R2,LCMCSI ;YES, SET DISABLE BITS BR 12$ ; AND SKIP TEST 11$: BIT R2,LCMCSI ;THIS FLAG OFF LIMITS? BNE 5$ ; YES 12$: BIC R2,LCMASK BIT R2,#LC. ;NULL? BEQ 4$ ; NO ADD R3,LCLVL ;YES, UPDATE LEVEL COUNT CALL PAGEX ;SET LISTING CONTROL 4$: TST R3 BPL 5$ ;.LIST, BRANCH BIS R2,LCMASK 5$: BR 1$ ;TRY FOR MORE 6$: ERROR A 7$: RETURN GENSWT LI,LIST ;GENERATE /LI GENSWT NL,NLIST ; AND /NL SWITCH ENTRIES .GLOBL PAGE PAGE: INC FFCNT ;SIMULATE FF AFTER THIS LINE PAGEX: BIS #LC.LD,LCFLAG ;FLAG AS LISTING DIRECTIVE RETURN .MACRO GENLCT MNE,INIT ;GENERATE LISTING CONTROL TABLE LC.'MNE= 1 .REPT <.-LCTBAS>/4 LC.'MNE= LC.'MNE+LC.'MNE .ENDR .GLOBL LC.'MNE .POINT ,DPURE .IF NB, LCINIT= LCINIT+LC.'MNE .ENDC .ENDM LCINIT= 0 ENTSEC DPURE LCTBAS: GENLCT SEQ GENLCT LOC GENLCT BIN GENLCT SRC GENLCT COM GENLCT BEX,1 GENLCT MD GENLCT MC GENLCT ME ,1 GENLCT MEB,1 GENLCT CND GENLCT LD ,1 GENLCT TTM,1 GENLCT TOC GENLCT SYM GENLCT < > ;NULL LCTTOP: XITSEC ; ENTIMP IMPURE ;LCSAVE=.BASE ;LISTING CONTROL SAVE BLOCK ; BLKW LCMASK ;MASK BITS ; BLKW LCLVL ;LEVEL COUNT ; BLKW LCMCSI ;COMMAND STRING STORAGE ;LCSAVL= .BASE-LCSAVE ; ; BLKW LCSBAK,LCSAVL/2 ;FOR INITTING PASS 2 ; ; XITIMP IMPURE ; ENTIMP IMPLIN ; BLKW LCFLAG ;FLAG BITS ; BLKW LCBEGL ;POINTER TO START OF LINE ; BLKW LCENDL ;POINTER TO END OF LINE ; BLKW LBLEND ;END OF LABEL (FOR PARSING) ; XITIMP IMPLIN ENTSEC XCTPRG .GLOBL LCBITS .BLKW 1 LCBITS: .BLKW -1 MOV #LCINIT,LCSBAK+ ;DEFAULT FLAGS ENTSEC XCTPAS ;EXECUTE THIS CODE EACH PASS MOV #LCSBAK,R1 ;RESET LISTING FLAGS MOV #LCSAVE,R2 CALL XMIT0-LCSAVL XITSEC .SBTTL MA5: ENABL/DSABL FUNCTIONS .GLOBL ENABL, DSABL DSABL: COM R3 ;R3=-1 ENABL: ;R3=0 1$: GSARG ;GET A SYMBOLIC ARGUMENT BEQ 8$ ;END IF NULL SCANP EDTROL ;SEARCH THE TABLE BEQ 7$ ; NOT THERE, ERROR CLR R2 ;COMPUTE BIT POSITION SEC 2$: ROL R2 SOB R0,2$ TST CSIFLG ;CALLED FROM COMMAND STRING? BEQ 3$ ; NO BIS R2,EDMCSI ;YES, SET DISABLE BITS BR 4$ ; AND BYPASS TEST 3$: BIT R2,EDMCSI ;OVER-RIDDEN FROM CSI? BNE 1$ ; YES, IGNORE IT 4$: BIC R2,EDMASK ;NO, CLEAR SELECTED BIT TST R3 ;ENDBLE? BEQ 5$ ; YES, LEAVE IT CLEAR BIS R2,EDMASK ;NO, CLEAR IT 5$: MOV SYMBOL+4,-(SP) ;MAKE IT PIC TST R3 ;SET FLAGS CALL @(SP)+ ;CALL ROUTINE BR 1$ 7$: ERROR A 8$: RETURN ; ENTIMP IMPURE ; BLKW EDMASK ;CONTAINS SET FLAGS ; BLKW EDMCSI ;BITS FOR CSI OVERRIDE ; BLKW EDMBAK ;TO RE-INIT FOR PASS 2 ; XITIMP IMPURE ENTSEC XCTPRG .GLOBL EDBITS .BLKW 1 EDBITS: .BLKW -1 MOV #EDINIT,EDMBAK ;SET DEFAULT CONDITIONS ENTSEC XCTPAS MOV EDMBAK,EDMASK ;SET EACH PASS XITSEC GENSWT EN,ENABL ;GENERATE /EN GENSWT DS,DSABL ; AND /DS SWITCH TABLE ENTRIES GENEDT SYM,,1 ;; THE SYMBOL TO REL FILE OPTION .SBTTL MA5: CROSS REFERENCE HANDLERS .IF NDF XCREF CR.VER= 001+<001*400> ;TYPE 1, VERSION #1 CR.PAG= 002 ;NEW PAGE CR.LIN= 003 ;NEW LINE CR.SYM= 020 ;SYMBOL GENSWT CR,CRFSET ERRROL= 1 ;DUMMY ROLL CRFSET: ;CREF SWITCH PROCESSOR 1$: GSARG ;TRY FOR ARGUMENT BEQ 3$ ; FINISHED SCANP CRFROL ;SCAN ROLL FOR IT BEQ 6$ ; NOT THERE, ERROR MOV #1,R2 2$: ASL R2 SOB R0,2$ BIS R2,R3 ;ACCUMULATE FLAGS BR 1$ 3$: TST R3 ;ANY ARGS? BNE 4$ ; YES MOV #^C10,R3 ; NO, ALL BUT "P" 4$: MOV R3,CRFFLG ;SAVE FLAG RETURN 6$: ERROR A RETURN ENTSEC DPURE CRFBAS: .IRPC ARG,SMPCE .POINT MNE,DPURE .ENDM CRFTOP: XITSEC CRFDEF: INCB CRFDFL ;CREF DEFINITION CRFREF: ;CREF REFERENCE TST CRFPNT ;ANY CREF OUTPUT AT THIS TIME? BEQ 9$ ; NO SAVREG MOV CRFPNT,R2 ;PRESET BUFFER POINTER TST CRFVER ;VERSION NUMBER SENT YET? BNE 1$ ; YES MOV #CR.VER,R1 MOV R1,CRFVER ;SET FLAG CALL CRFTST ;TEST AND DEPOSIT SWAB R1 MOVB R1,(R2)+ ;STUFF VERSION NUMBER 1$: CMP CRFPAG,PAGNUM ;NEW PAGE? BHIS 2$ ; NO MOV #CR.PAG,R1 ;YES, SEND FLAG CALL CRFTST INC CRFPAG CLR CRFLIN BR 1$ 2$: CMP CRFLIN,LINNUM ;NEW LINE NUMBER? BHIS 3$ ; NO MOV #CR.LIN,R1 CALL CRFTST INC CRFLIN BR 2$ 3$: MOV #CRFTYP,R1 MOV CRFFLG,R0 4$: ASR R0 CMPB ROLNDX,(R1)+ ;MAP ROLL NUMBER TO CREF TYPE BNE 4$ ASR R0 BCC 8$ SUB #CRFTYP+1-CR.SYM,R1 CALL CRFTST R50UNP 5$: CMPB #SPACE,-(R2) ;TRIM TRAILING BLANKS BEQ 5$ TSTB (R2)+ MOV CRFDFL,R1 ;SET "#" BIT BPL 6$ ;BRANCH IF NO "*" BIS #2,R1 6$: BIS #CR.SYM,R1 ;SET TERMINATOR MOVB R1,(R2)+ 8$: MOV R2,CRFPNT ;STORE NEW POINTER 9$: CLRB CRFDFL RETURN CRFTST: ;TEST FOR ROOM AND STORE BYTE CMP #CRFBUF+CRFLEN-12,R2 ;ROOM TO STORE A FEW? BHI 1$ ; YES CALL CRFDMP ;NO, DUMP CURRENT MOV #CRFBUF,R2 ;START NEW LINE 1$: MOVB R1,(R2)+ ;STORE THE BYTE RETURN CRFDMP: ;DUMP CREF BUFFER MOVB #VT,(R2)+ ;SET END ; WRITE TO CRFLNK FROM CRFBUF ; MOV #CRFBUF,-(SP) ; MOV #CRFLEN,-(SP) ; MOV CRFLNK,-(SP) ; PUTBLK MOV CRFLNK,R0 sys s_write,CRFBUF,CRFLEN ;END OF CODE TO WRITE OUT CRFBUF CLR CRFPNT ; AND CLOSE RETURN ; ENTIMP IMPURE ; BLKW CRFFLG ; BLKW CRFVER ;VERSION FLAG ; BLKW CRFPAG ; BLKW CRFLIN ; BLKW CRFPNT ; ; BLKW CRFHDR,3 ; BLKW CRFBUF,CRFLEN/2 ; XITIMP IMPURE ; ENTIMP IMPLIN ; BLKB CRFDFL,2 ; "#" AND "*" FLAGS ; XITIMP IMPLIN ENTSEC TXTBYT CRFTYP: .BYTE SYMROL .IF NDF XMACRO .BYTE MACROL .IFF .BYTE -1 .ENDC .BYTE PSTROL .BYTE SECROL .BYTE ERRROL XITSEC ; ENTIMP MIXED ; BLKW CRFLNK ; BLKB CRFFIL,38. ; ; XITIMP MIXED .ENDC .SBTTL MA5: LISTING STUFF SETPF0: ;SET PRINT FIELD ZERO MOV CLCFGS,PF0 ;SET CURRENT LOCATION FLAGS BISB #100,PF0+1 ;ASSUME WORD MOV CLCLOC,PF0+2 ;SET LOCATION RETURN SETPF1: ;SET PRINT FIELD ONE MOV MODE,PF1 ;SET MODE OF CURRENT VALUE BISB #100,PF1+1 ;ASSUME WORD MOV VALUE,PF1+2 RETURN ; ENTIMP IMPLIN ; BLKW PF0,2 ; BLKW PF1,2 ; XITIMP IMPLIN SETWDB: ;SET WORD OR BYTE TST (R1) ;POSITIVE? BGE SETWRD ;; YES, WORD MOV #SPACE,R0 ;; GET A SPACE MOVB R0,(R2)+ ;; PAD WITH SPACES MOVB R0,(R2)+ ;; PAD WITH SPACES MOVB R0,(R2)+ ;; PAD WITH SPACES BR SETBYT ;; AND UNPACK A BYTE SETWRD: MOV R1,-(SP) ;STACK REG MOV 2(R1),R1 ;GET ACTUAL VALUE MOVB #DIG.0/2,(R2) ;SET PRIMITIVE ASL R1 ROLB (R2)+ ;MOVE IN BIT MOV #5,R0 BR SETBYX SETBYT: MOV R1,-(SP) ;STACK INDEX MOVB 2(R1),R1 ;GET VALUE MOV #SPACE,R0 SWAB R1 ;MANIPULATE TO LEFT HALF RORB R1 ;GET THE LAST GUY CLC ROR R1 MOV #3,R0 SETBYX: SWAB R0 ADD #3,R0 MOVB #DIG.0/10,(R2) 1$: ASL R1 ROLB (R2) DECB R0 BGT 1$ TSTB (R2)+ SWAB R0 SOB R0,SETBYX MOV (SP)+,R1 RETURN .SBTTL MA5: KEYBOARD HANDLERS ; ENTIMP IMPURE ; ;CMILEN= 120. ; ; BLKW CMDPTR ;POINTER TO CURRENT POSISION IN COMMAND LINE ; BLKW CMDBUF,</2> ; XITIMP IMPURE TYPEST: MOV R0,-(SP) ;TYPEST EMT EMULATOR, SAVE R0 MOV 4(SP),R0 ;FETCH STACKED ARGUMENT MOV R0,TYPEMT+2 ;THAT'S THE DATA ADDRESS MOV #-1,TYPEMT+4 ;GET READY TO COMPUTE COUNT 1$: INC TYPEMT+4 ;COUNT THIS BYTE TSTB (R0)+ ;THEN CHECK IF MORE BNE 1$ MOV #1,R0 ;STANDARD OUTPUT STREAM ID sys s_indir,TYPEMT ;DO THE WRITE MOV (SP)+,R0 ;RESTORE R0 MOV (SP)+,(SP) ;REMOVE ARG FROM STACK RETURN ENTSEC SYSCALLS TYPEMT: sys s_write,0,0 XITSEC TYPELN: MOV 2(SP),-(SP) ;TYPELN EMULATOR, JUST DO A TYPEST TYPEST MOV #NLSTRING,2(SP) JMP TYPEST ;FOLLOWED BY A TYPEST OF A NEWLINE ENTSEC TXTBYT NLSTRING:.BYTE 12,0 XITSEC .SBTTL MA5: OBJECT CODE HANDLERS ENDP: ;END OF PASS HANDLER CALL SETMAX CALL TSTCOR ;TEST CORE SIZE TST PASS ;PASS ONE? BEQ 2$ JMP ENDP2 ;BRANCH IF PASS 2 1$: CALL GETLIN ;MOVE TO EOF 2$: TST SRCLNK ;FOUND? BNE 1$ ; NO TST OBJFLG ;PASS ONE, ANY OBJECT? BNE 3$ ; YES JMP ENDP1B ; NO 3$: ;PARSE AS .REL MOV #OBJFIL,-(SP) MOV #OBJTXT,-(SP) 8$:; OPEN OBJECT FILE CALL OUTNAM ;SET EXTENSION ON OUTPUT NAME ; MOV #1,-(SP) ; MOV #OBJFIL,-(SP) ; OPEN ; BVC 21$ sys s_creat,OBJFIL,666 BCC 21$ SERROR #NOOUTF,#OBJFIL 21$: MOV R0,OBJLNK ENTSEC TXTBYT OBJTXT: .ASCII /rel/ MMIXID: .BYTE C.MIXID XITSEC ;END OF CODE TO OPEN OUTPUT FILE SETNZ BLKTYP ;INDICATE OBJECT FILE HAS BEEN WRITTEN INTO CALL OBJINI ;INIT THE POINTERS ; DATIME ;GET TIME AND DATE MODULE CREATED CLR -(SP) CLR -(SP) ;DUMMY UP PHONEY DATE AND TIME CLR -(SP) MOV R6,R1 MOV RLDPNT,R2 ;USE RLD BUFFER TO OUTPUT SYMBOL DIRECTORY MOV #6,R3 CALL GSDDMP ;PUT OUT THE TIME AND DATE. MOV R1,R6 ;RESET SP. MOV PRGTTL,SYMBOL MOV PRGTTL+2,SYMBOL+2 CALL R50DMP ;PUT OUT THE TITLE MOV #PRQBUF,R1 ;PREREQUISITE NAME CALL ASCDMP ;DUMP IN .ASCIZ FORMAT. TST FMIXID ;MIX I AND D SPACE? BNE 30$ ;(YES) TST UNMIXID ;TEST THE OTHER FLAG BNE 9$ ;(NO) 30$: MOV #MMIXID,R1 MOV #1,R3 CALL GSDDMP ;WRITE OUT A "MIXID" DIRECTIVE 9$: CLR ROLUPD ;INIT FOR SECTOR SCAN CLR R4 ;HERE WE KEEP TRACK OF THE CURRENT SYMBOL ID. 10$: NEXT SECROL ;GET THE NEXT SECTOR BEQ ENDP1S ;BRANCH IF THROUGH MOV #MODE,R1 MOV (R1),R5 ;SAVE SECTOR MOV #C.CS,(R1) BIT R5,#RELFLG ;RELOCATABLE? BNE 11$ ;(YES) BIS #S.ABS*400,(R1) ;NO, SET ABS BIT. 11$: BIT R5,#ISPFLG ;COPY OTHER ATTRIBUTES BEQ 12$ BIS #S.ISPC*400,(R1);I SPACE 12$: BIT R5,#PURFLG BEQ 13$ BIS #S.PURE*400,(R1);PURE 13$: BIT R5,#GLBFLG BEQ 14$ BIS #S.EXT*400,(R1) ;EXTERNAL 14$: MOV #2,R3 CALL GSDDMP ;WRITE OUT HEADER TST (R1)+ ;SKIP LOCATION COUNTER MOV #2,R3 CALL GSDDMP ;WRITE OUT LENGTH CALL R50DMP ;AND CSECT NAME INC R4 ;COUNT THIS SYMBOL BR 10$ ;AND LOOP. ENDP1S: ;WROTE OUT ALL THE CSECTS, NOW ATTACK SYMBOLS. CLR ROLUPD ;PREPARE TO SCAN SYMBOL TABLE 21$: NEXT SYMROL ;GET A SYMBOL BEQ 40$ ;(NO MORE, DONE) BIT MODE,#GLBFLG ;GLOBAL? BNE 1$ ;; YES, PROCESS IT BIT MODE,#SYMFLG ;; SYMBOL TO GO INTO REL FILE? BNE 23$ ;; YES, (DON'T STICH IN GLOBL SYMBOL ROLL) BR 21$ ;; NO, DON'T STICK IT ANYWHERE 1$: BIT MODE,#DEFFLG ;DEFINED? BNE 23$ ;YES, DON'T NEED IT IN GLBROL. MOV VALUE,R5 ;SAVE MOV ROLUPD,R3 MOV R4,VALUE ;STORE ITS ID APPEND GLBROL ;AND APPEND IT TO GLOBAL ROLL. MOV R5,VALUE ;RESTORE MOV R3,ROLUPD 23$: INC R4 ;AND BUMP ID. MOV #MODE,R1 MOV (R1),R5 ;SAVE MOV #C.SYM,(R1) ;PUT TOGETHER HEADER BIT R5,#GLBFLG ;; INTERNAL? BEQ 2$ ;; YES BIS #S.EXT*400,(R1) ;; ELSE SET EXTERNAL BIT 2$: BIT R5,#DEFFLG ;DEFINED? BEQ 22$ ;(NO) BIS #S.DEF*400,(R1) ;YES, MARK IT. 22$: MOV #4,R3 CALL GSDDMP ;WRITE DECLARATION AND VALUE MOV #MODE+2,R1 MOV #-1,(R1) ;NO SUPERIOR SYMBOL TABLE CLRB R5 SWAB R5 ;GET CSECT ID MOV R5,-(R1) ;STORE IT. MOV #4,R3 CALL GSDDMP ;WRITE CSECT ID, SYMBOL TABLE. CALL R50DMP ;FINALLY, WRITE OUT THE SYMBOL NAME. BR 21$ ;GO ON TO NEXT! 40$: CLR ROLUPD ;GET READY TO SCAN ENTRY POINT ROLL 41$: NEXT ENTROL ;GET ONE BEQ ENDP1A ;(DONE, NO MORE) CALL ENTDMP ;WRITE OUT THE "ENTRY" DECLARATION BR 41$ ;DONE, LOOK FOR MORE WORK! ENDP1A: MOV #ENDVEC,R1 CMP 6(R1),#1 ;ANY TRANSFER ADDRESS? BEQ 50$ ;(NO) MOV #SYMBOL,R4 MOV (R1)+,(R4)+ MOV (R1)+,(R4)+ CLR (R4)+ MOV #NULSTR,(R4)+ ;; " " MOV (R1)+,(R4)+ ;FINISH DUMMYING UP ENTRY MOV (R1)+,(R4)+ CALL ENTDMP ;THEN WRITE IT OUT. 50$: MOV #ENDGSD,R1 MOV #1,R3 CALL GSDDMP ;END OF GSD CALL PCRDMP ;FINALIZE IT. ZAP ENTROL ;CLEAR OUT THE ENTRY ROLL FOR THE NEXT PASS. ENDP1B: CLR ROLUPD ;SET FOR RE-INIT SCAN 31$: NEXT SECROL ;GET THE NEXT ENTRY BEQ 32$ ; BRANCH IF FINISHED CLR VALUE ;FOUND, RESET PC INSERT ;PUT BACK IN TABLE BR 31$ 32$: RETURN ENTSEC TXTBYT ENTRYN: .ASCIZ " " ENDGSD: .BYTE C.END XITSEC GSDDMP: ;DUMP SOME SYMBOL DIRECTORY STUFF. MOV R2,-(SP) ;CURRENT BUFFER POINTER ADD R3,(SP) ;ADD BYTE COUNT CMP (SP)+,#RLDBUF+RLDLEN ;PAST BUFFER END? BLOS 1$ ;(NO) CALL PCRDMP ;YES, DUMP BUFFER FIRST. 1$: MOVB (R1)+,(R2)+ ;MOVE DATA INTO BUFFER. SOB R3,1$ RETURN R50DMP: ;DUMP "SYMBOL" IN .ASCIZ FORMAT. MOV R1,-(SP) ;; SAVE R1 CMP R2,#RLDBUF+RLDLEN+2 ;; GOT ROOM? BLO 1$ ;; YES CALL PCRDMP ;; ELSE MAKE SOME 1$: MOVB SYMBOL+3,(R2)+ ;; GET FIRST BYTE MOVB SYMBOL+2,(R2)+ ;; GET SECOND BYTE (COULD BE 0) BEQ 5$ ;; DONE IF SO MOV SYMBOL,R1 BNE 3$ ;; BRANCH IF MORE SYMBOL IN IMPURE CLRB (R2)+ ;; ELSE ADD A ZERO BYTE BR 5$ ;; AND EXIT 3$: CALL ASCDMP ;; DUMP THE REST 5$: MOV (SP)+,R1 ;; RESTORE R1 RETURN ;; AND RETURN ASCDMP: ;DUMP A .ASCIZ STRING CMP R2,#RLDBUF+RLDLEN;GOT ROOM? BLO 1$ CALL PCRDMP ;(NO, MAKE SOME) 1$: MOVB (R1)+,(R2)+ ;MOVE A BYTE BEQ 2$ ;(END, DONE!) BR ASCDMP 2$: RETURN ENTDMP: ;DUMP AN ENTRY SYMBOL. CALL 10$ ;DO THE WORK MOV RLDPNT,R2 ;UPDATE RLD POINTER RETURN 10$: SAVREG MOVB ENTMOD+1,R4 BIC #177600,R4 ;GET THE RLD TYPE MOVB ENTTBL(4),R4 ;FIND OUT WHAT TO DO. ASLB R4 ;NO RELOCATION? BCC 1$ ;(NO) CMP ENTVAL,#1 ;YES, UNDEFINED? BEQ 44$ ;(YES, IGNORE IT) CLR ENTVAL+2 ;NO, IT BELONGS TO ASECT. BR 20$ 1$: ASLB R4 ;CSECT RELOCATION? BCC 2$ ;(NO) MOV #MODE+6,R1 MOV -(R1),-(SP) ;SAVE STUFF MOV -(R1),-(SP) MOV -(R1),-(SP) MOV ROLUPD,-(SP) SCAN SECROL ;FIND THE CSECT MOV (SP)+,ROLUPD ;RESTORE MOV (SP)+,(R1)+ MOV (SP)+,(R1)+ MOV (SP)+,(R1)+ DEC R0 ;COMPUTE CSECT ID 19$: MOV R0,ENTVAL+2 ;AND STORE IT. BR 20$ 2$: ASLB R4 ;GLOBAL RELOCATION? BCC 3$ ;(NO) MOV #MODE+4,R1 MOV -(R1),-(SP) MOV -(R1),-(SP) ;SAVE MOV ROLUPD,-(SP) SEARCH GLBROL MOV VALUE,R0 ;GET THE GLOBAL'S ID MOV (SP)+,ROLUPD MOV (SP)+,(R1)+ ;RESTORE MOV (SP)+,(R1)+ BR 19$ 3$: ;SCREWED UP, PRETEND IT DIDN'T HAPPEN. 20$: MOV #ENTMOD,R1 MOV #C.ENTRY,(R1) ;"ENTRY" COMMAND MOV #16.,R3 ;BYTE COUNT CALL GSDDMP ;OUTPUT THE "ENTRY" DECLARATION MOV SYMBOL+4,SYMBOL ;; GET ENTRY NAME MOV SYMBOL+6,SYMBOL+2 CALL R50DMP ;; AND DUMP NAME MOV R2,RLDPNT ;SAVE NEW BUFFER POINTER 44$: RETURN ;DONE! ENTSEC TXTBYT ENTTBL: ;TABLE BY RLD TYPE .BYTE 200 ;NO RELOCATION .BYTE 100 ;RLDT01 -- ABS + C .BYTE 040 ;RLDT02 -- ABSX + 0 .BYTE 0 ;IMPOSSIBLE .BYTE 0 .BYTE 040 ;RLDT05 -- ABSX + C .BYTE 0 .BYTE 0 .BYTE 0 .BYTE 0 .BYTE 0 .BYTE 0 .BYTE 0 .BYTE 100 ;RLDT15 -- ABSX + C XITSEC ENDP2: ;END OF PASS 2 .IF NDF XCREF MOV CRFPNT,R2 ;ANY CREF IN PROGRESS? BEQ 8$ ; NO CALL CRFDMP ;YES, DUMP AND CLOSE BUFFER 8$: .ENDC MOV #SYMTXT,R1 MOV #STLBUF,R2 MOVBYT ;SET "SYMBOL TABLE" SUB-TITLE MOVB #FF,@TTLBEG ;; GET RID OF TITLE INC TTLBEG ;; GET READY TO MOVE A ZERO BYTE CLRB @TTLBEG ;; MAKE FF ASCIZ DEC TTLBEG ;; BAC TO POINT TO FF TST BLKTYP ;ANY OBJECT OUTPUT? BEQ 1$ ; NO CALL OBJDMP ;YES, DUMP IT 1$: TSTB LLTBL+LST.L ;ANY LISTING OUTPUT? BEQ ENDP2D ; NO BIT #LC.SYM,LCMASK ;SYMBOL TABLE SUPPRESSION? BNE ENDP2D ; YES CLR LPPCNT ;FORCE NEW PAGE CLR ROLUPD ;SET FOR SYMBOL TABLE SCAN MOV #LINBUF,R2 ;POINT TO STORAGE CALL ENDP2B ;; PRINT IT 3$: NEXT SYMROL ;GET THE NEXT SYMBOL BEQ ENDP2A ; NO MORE MOV #SECTOR,R1 ;; WHAT CSECT IS IT IN? CMPB #1,(R1) ;; THE BLANK CSECT? BGE 10$ ;; YES, SO DON'T PRINT THE NUMBER CMPB -(R1),-(R1) ;; BACK UP R1 CALL SETBYT ;; AND PRINT THE CSECT NUMBER BR 11$ 10$: MOV #BBB,R1 ;; MOVE 3 BLANKS MOVBYT ;; DO IT 11$: MOVB #SPACE,(R2)+ ;; AND A BLANK MOV #ENDP2T,R3 ;; SET POINTER TO %=RG TABLE CALL ENDP2C ;; PRINT OUT % MOV #MODE,R1 ;; UNDEFINED? BIT #DEFFLG,(R1) ;; WELL? BEQ 4$ ;; NO CALL SETWRD ;; ELSE PRINT VALUE IN OCTAL BR 6$ 4$: MOV #STARS,R1 ;; POINTER TO ****** MOVBYT ;; FILL VALUE WITH THEM 6$: CALL ENDP2C ;; PRINT OUT R CALL ENDP2C ;; PRINT OUT G CALL ENDP2C ;; PRINT OUT = MOVB #SPACE,(R2)+ ;; AND A BLANK CALL R50DMP ;; PRINT OUT SYMBOL CALL ENDP2B ;; PRINT WHOLE LINE BR 3$ ;NEXT LINE ENDP2A: CLR ROLUPD ;SET FOR SECTOR SCAN 21$: CALL ENDP2B ;OUTPUT LINE NEXT SECROL ;GET THE NEXT ENTRY BEQ ENDP2D ; EXIT IF END OF ROLL MOV #SECTOR-2,R1 ;; ENTRY NUMBER CALL SETBYT ;; MAKE INTO NUMBER MOVB #SPACE,(R2)+ ;; AND A SPACE MOV #VALUE,R1 ;; CSECT VALUE CALL SETWRD ;; MAKE INTO A WORD MOVB #TAB,(R2)+ ;; AND A TAB CALL R50DMP ;; THEN DUMP THE SYMBOL NAME BR 21$ ENDP2B: CLRB (R2) PUTLP #LINBUF MOV #7,LPPCNT ;; NEVER DO A TOP OF FORM (ALWAYS 7 MORE LINES!) MOV #LINBUF,R2 ;RESET TO START OF BUFFER ENDP2D: RETURN ENDP2C: MOV (R3)+,R0 BIT (R3)+,MODE BNE 32$ SWAB R0 32$: MOVB R0,(R2)+ RETURN ENTSEC DPURE ENDP2T: .ASCII /% / .WORD REGFLG .ASCII /R / .WORD RELFLG .ASCII /G / .WORD GLBFLG .ASCII / =/ .WORD LBLFLG ENTSEC TXTBYT STARS: .ASCIZ /******/ BBB: .ASCIZ / / SYMTXT: .ASCIZ /SYMBOL TABLE/ XITSEC dma6.mac0000600002565200256520000002545302141527064010515 0ustar jncjnc .SBTTL MA6: CODE ROLL HANDLERS STCODE: APPEND CODROL ;APPEND TO CODROL STCOD1: RETURN PCROLL: ;PROCESS CODE ROLL NEXT CODROL ;GET NEXT CODE ROLL ENTRY BEQ STCOD1 ; END SAVREG CLR R5 ;ASSUME BYTE CLR R4 BISB SECTOR,R4 ;GET THE RLD TYPE BMI 1$ ;BRANCH IF BYTE INC R5 ; WORD, BUMP TO 1 1$: TST PASS ;PASS ONE? BEQ 9$ ; YES, JUST UPDATE PC INC PCRCNT ;EXTENSION LINE? BMI 2$ ; YES SETPF0 ;LIST COLUMN ZERO 2$: SETPF1 ;SET PRINT FIELD ONE ASLB R4 ;BYTE? TST BLKTYP ;ANY OBJECT CODE CALLED FOR? BEQ 9$ ; NO .IF NDF XEDPNC BIT #ED.PNC,EDMASK ;PUNCH DISABLED? BNE 9$ ; YES .ENDC MOV PCRTBL(R4),R4 ;GET PROPER TABLE ENTRY MOV RLDPNT,R2 ;SET POINTER TO RLD BUFFER CMPB CLCSEC,OBJSEC ;SECTOR CHANGE? BEQ 10$ ; NO CMP R2,#RLDBUF+RLDLEN-10 ;ROOM IN CURRENT RLD? BLOS 4$ ; YES CALL PCRDMP ;YES, DUMP CURRENT BUFFERS 4$: MOVB #C.LCSX,(R2)+ ;OBJECT COMMAND MOV R2,R3 ;SAVE PTR FOR VALUE CMPB (R2)+,(R2)+ ;THEN SKIP TWO BYTES MOVB CLCSEC,(R2) ;CSECT ID. MOVB (R2)+,OBJSEC CLRB (R2)+ BR 12$ 9$: BR PCROL2 10$: CMP CLCLOC,OBJLOC ;DID PC MOVE ON US? BEQ 14$ ; NO CMP R2,#RLDBUF+RLDLEN-4 ;ROOM IN CURRENT RLD BUFFER? BLOS 11$ ; YES CALL PCRDMP ;YES, DUMP CURRENT BUFFER 11$: MOVB #C.LCS,(R2)+ ;COMMAND MOV R2,R3 ;SAVE PTR TO VALUE CMPB (R2)+,(R2)+ ;THEN SKIP OVER IT. 12$: MOV CLCLOC,R0 ;NEW VALUE OF LOCATION COUNTER .IF DF YPHASE SUB PHAOFF,R0 .ENDC MOVB R0,(R3)+ ;STUFF IT. SWAB R0 MOVB R0,(R3)+ 13$: CALL PCRDMP ;DUMP BUFFER 14$: MOV OBJPNT,R0 ;GET CODE POINTER ADD R5,R0 ;COMPUTE NEW END CMP R0,#OBJBUF+OBJLEN-1 ;ROOM? BHI 13$ ; NO MOVB R4,R0 ;YES, GET RLD SIZE ADD R2,R0 CMP R0,#RLDBUF+RLDLEN BHI 13$ ; NO ROOM, DUMP BUFFER MOV OBJPNT,R1 CMP R1,#OBJBUF ;FIRST ITEM? BNE PCROL0 ; NO MOV #C.TXT,(R1)+ ;YES, SET BLOCK TYPE. PCROL0: ASL R4 ;ANY RLD? BCC PCROL1 ;(NO) ASL R4 ;DISPLACED RELOCATION? BCC 17$ ;(NO) SUB CLCLOC,VALUE ;YES, FIX UP VALUE BY SUB #2,VALUE ;CALCULATING DISPLACEMENT. MOV #C.REL,R3 CALL RLDCMD ;PUT IN A "REL" DIRECTIVE FOR IT. 17$: ASL R4 ;INTERNAL RELOCATION? BCC 18$ ;(NO) MOV #C.ABS,R3 CALL RLDCMD ;YES, PUT IN THE "ABS" DIRECTIVE BR PCROL1 ;THAT'S IT!! 18$: ASL R4 ;GLOBAL RELOCATION? BCC 19$ ;(NO) MOV #C.ABSX,R3 CALL RLDCMD ;YES, PUT IN "ABSX". MOV VALUE,R3 ;SAVE MOV ROLUPD,-(SP) SEARCH GLBROL ;NOW FIND THE GLOBAL SYMBOL MOVB VALUE,(R2)+ ;COPY ITS ID. MOVB VALUE+1,(R2)+ BR 20$ ;ALMOST DONE. 19$: ASL R4 ;CSECT RELOCATION? BCC PCROL1 ;(NO) MOV #C.ABSX,R3 CALL RLDCMD ;YES, PUT IN "ABSX". MOV VALUE,R3 MOV ROLUPD,-(SP) SCAN SECROL ;SEARCH CSECT ROLL DEC R0 ;COMPUTE ID MOVB R0,(R2)+ ;AND OUTPUT IT. CLRB (R2)+ 20$: MOV R3,VALUE ;RESTORE MOV (SP)+,ROLUPD PCROL1: MOV R2,RLDPNT ;SAVE POINTER MOVB VALUE,(R1)+ TST R5 BEQ 29$ ;BRANCH IF BYTE INSTRUCTION MOVB VALUE+1,(R1)+ 29$: MOV R1,OBJPNT PCROL2: INC R5 ;MAKE COUNT 1 OR 2 ADD R5,CLCLOC ;UPDATE PC MOV CLCLOC,OBJLOC ;SET SEQUENCE BREAK SETNZ R0 ;SET TRUE RETURN PCROL3: RETURN ; ENTIMP IMPLIN ; BLKW PCRCNT ;EXTENSION LINE FLAG ; XITIMP IMPLIN PCRDMP: MOV R2,RLDPNT ;SET RLD POINTER CALL OBJDMP MOV RLDPNT,R2 RETURN RLDCMD: ;PUT OUT AN RLD COMMAND AND OFFSET. TST R5 ;BYTE COMMAND? BNE 1$ ;(NO) BIS #200,R3 ;YES, DO BYTE RELOCATION. 1$: MOVB R3,(R2)+ ;PUT THE OBJECT COMMAND MOV R1,R0 ;OBJ POINTER SUB #OBJBUF+2,R0 ;COMPUTE TEXT OFFSET MOVB R0,(R2)+ ;AND OUTPUT IT. RETURN ;DONE! ENTSEC DPURE PCRTBL: ;TABLE BY RLD TYPE .WORD 0 ;NO RELOCATION .WORD 120002 ;RLDT01 -- ABS + C .WORD 110004 ;RLDT02 -- ABSX + 0 .WORD 140002 ;RLDT03 -- REL + (C-CLCLOC-2) .WORD 150006 ;RLDT04 -- REL + ABSX + (-CLCLOC-2) .WORD 110004 ;RLDT05 -- ABSX + C .WORD 150006 ;RLDT06 -- REL + ABSX + (C-CLCLOC-2) .WORD 0 .WORD 0 .WORD 0 ;RLDT11 -- NO EQUIVALENT IN DELPHI OBJECT MODULES .WORD 0 .WORD 0 .WORD 0 .WORD 104004 ;RLDT15 -- ABSX + C .WORD 144006 ;RLDT16 -- REL + ABSX + (C-CLCLOC-2) XITSEC ; ENTIMP IMPPAS ; ODD ; BLKB OBJSEC,1 ;OBJECT FILE SECTOR ; BLKW OBJLOC,1 ;OBJECT FILE LOCATION ; XITIMP IMPPAS ENTSEC XCTPAS ;EXECUTE EACH PASS COMB OBJSEC ;FORCE SEQUENCE BREAK XITSEC .IF NDF XEDPNC GENEDT PNC,PNCSET ;PUNCH CONTROL PNCSET: MOVB #377,OBJSEC ;FORCE SEQUENCE BREAK RETURN .ENDC OBJDMP: ;DUMP THE OBJECT BUFFER MOV #OBJHDR,R0 MOV OBJPNT,(R0) BEQ OBJINX ;EXIT IF NULL (NOT INITTED) SUB #OBJBUF,(R0) ;COMPUTE SIZE BEQ 1$ ; BRANCH IF EMPTY ; WRITE FROM OBJHDR TO OBJLNK MOV (R0),-(SP) ;BLOCK SIZE SUB #2,(SP) ;COMPUTE ACTUAL TEXT SIZE MOVB (SP)+,3(R0) ;STUFF IT IN CALL BINIO ;END OF CODE TO WRITE OBJHDR 1$: CMP RLDPNT,#RLDBUF ;ANYTHING IN RLD? BLOS OBJINI ; NO, JUST INIT RLDDMP: MOV #RLDHDR,R0 MOV RLDPNT,(R0) SUB #RLDBUF,(R0) ; WRITE FROM RLDHDR TO OBJLNK CALL BINIO ;END OF CODE TO WRITE RLDHDR OBJINI: MOV #OBJBUF,OBJPNT MOV #RLDBUF,RLDPNT OBJINX: RETURN ; ENTIMP IMPURE ; BLKW OBJPNT ; BLKW RLDPNT ; BLKW BLKTYP ; XITIMP IMPURE GENSWT NO,NOBJSW ; ENTIMP IMPURE ; BLKW OBJFLG ; XITIMP IMPURE ENTSEC XCTPRG SETNZ OBJFLG XITSEC NOBJSW: CLR OBJFLG ;SUPPRESS OBJECT RETURN BINIO:; TST (R0)+ ;WRITE AN OBJECT BLOCK ROUTINE. ; MOV R0,-(SP) ;PUSH POINTER TO BUFFER ; MOV -(R0),-(SP) ;# OF BYTES ; MOV OBJLNK,-(SP) ;FILE ID ; PUTBLK ;AND WRITE OUT THE BUFFER. MOV R0,-(SP) ;SAVE R0 TST (R0)+ ;BUFFER POINTER MOV R0,PUTEMT+2 ;STORE IN WRITE CALL MOV -(R0),PUTEMT+4 ;BYTE COUNT MOV OBJLNK,R0 ;FILE ID FOR OBJECT CODE OUTPUT sys s_indir,PUTEMT ;DO THE WRITE MOV (SP)+,R0 ;RESTORE R0 RETURN ENTSEC SYSCALLS PUTEMT: sys s_write,0,0 XITSEC LST.K= 1 ;LISTING TO KEYBOARD LST.L= 2 ;LISTING TO LP LST.KL= LST.K!LST.L ;LISTING TO BOTH LST.ER= 4 ;ERROR DEVICE PUTKBL: INCB LSTMOD ;LIST TO BOTH PUTLP: INCB LSTMOD ;LIST TO LP PUTKB: INCB LSTMOD ;LIST TO KB PUTLIN: ;OUTPUT A LINE SAVREG ;STACK REGISTERS MOVB LSTMOD,R3 ;GET LOGICAL INDEX CLRB LSTMOD ;CLEAR FOR ABOVE INC'S MOVB LLTBL(R3),R4 ;MAP TO PHYSICAL DEVICE BEQ PUTLI9 ; EXIT IF NULL ASR R3 ;SHIFT OUT KB FLAG BEQ PUTLI2 ;BRANCH IF NO LOGICAL LP DEC LPPCNT ;YES, DECREMENT COUNT BGT PUTLI2 ;SKIP IF NOT TIME PUTLI1: MOV #LPP,LPPCNT ;RESET COUNT MOV R1,-(SP) ;STACK CURRENT POINTER MOV TTLEND,R2 ;POINT TO PAGE NUMBER TST PASS BEQ 11$ MOV #TSTHD1,R1 MOVBYT ;MOVE "PAGE" INTO POSITION MOV PAGNUM,R1 DNC ;CONVERT TO DECIMAL INC PAGEXT BEQ 11$ MOVB #'.,(R2)+ MOV PAGEXT,R1 DNC 11$: CLRB (R2) PUTLP TTLBEG ;PRINT TITLE PUTLP #STLBUF ; SUB-TITLE, PUTLP #CRLF ; AND A BLANK LINE MOV (SP)+,R1 PUTLI2: ASR LLWAIT ;LISTING REQUIRE WAIT? BCC 1$ ; NO 1$: MOV #LSTBUF-2,R2 ;SET DESTINATION INDEX CLR (R2)+ ;SET STOPPER MOV R2,R3 ;SAVE A COPY 21$: MOVB (R1)+,(R2)+ ;MOVE CHARACTER TO OUTPUT BUFFER BGT 21$ ;LOOP IF NOTHING SPECIAL MOVB -(R2),R0 ;SPECIAL, BACK UP AND SET R0 BEQ 22$ ;END IF NULL .IF NDF XEDLC BICB #200,-(R1) ;CLEAR SIGN BIT IN SOURCE BNE 21$ ;RE-STORE IF LOWER CASE MOVB #CH.QM,(R1) ;MUST BE ERROR .IFF MOVB #CH.QM,-(R1) ;ILLEGAL CHAR, SET "?" .ENDC BR 21$ 22$: MOVB -(R2),R0 ;FETCH PRECEDING CHAR BITB #CT.SP!CT.TAB,CTTBL(R0) ;BLANK? BNE 22$ ; YES, TRIM IT CMPB #VT,(R2)+ ;MOVE TO END, A VT? BEQ 23$ ; YES, NO LF MOVB #LF,(R2)+ 23$: CLRB (R2) ;MAKE ASCIZ ASR R4 ;KB REQUESTED? BCC 25$ ; NO ; WRITE FROM LSTBUF TO OUTSTRM MOV #LSTBUF,-(SP) TYPEST 25$: MOV R4,LLWAIT ;LISTING REQUESTED? BEQ PUTLI9 ; NO ; WRITE FROM LSTBUF TO LSTLNK ; MOV #LSTBUF,-(SP) ; MOV LSTLNK,-(SP) ; PUTST MOV #LSTBUF,R0 MOV R0,PUTEMT+2 MOV #-1,PUTEMT+4 ;GET READY TO COUNT BYTES OF LISTING OUTPUT 30$: INC PUTEMT+4 TSTB (R0)+ ;GO THROUGH WHOLE .ASCIZ STRING BNE 30$ MOV LSTLNK,R0 ;FILE ID FOR LISTING sys s_indir,PUTEMT ;DO THE WRITE PUTLI9: RETURN ; ENTIMP IMPURE ; BLKB LLTBL,5 ;LOGICAL TO PHYSICAL DEVICE MAPPING ; BLKB LSTMOD,1 ;LOGICAL LISTING FLAGS ; BLKW LLWAIT,1 ;WAIT FLAG ; XITIMP IMPURE ENTSEC XCTPRG INCB LLTBL+LST.K ;INIT TO KB INCB LLTBL+LST.KL INCB LLTBL+LST.ER ;DEFAULT ERROR DEVICE ENTSEC TXTBYT TSTHD1: .ASCIZ / PAGE / XITSEC GENSWT LS,LISTSW XITSEC ; ENTIMP IMPURE ; BLKW LSTFLG ; XITIMP IMPURE LISTSW: SETNZ LSTFLG ;REQUEST LISTING MOVB #LST.L+,LLTBL+LST.L INCB LLTBL+LST.ER ;ERRORS TO LOGICAL LP RETURN ENTSEC XCTPRG CALL SETHDR ;COME HERE AT START OF PROGRAM XITSEC SETHDR: ;INIT THE HEADER BUFFER MOV #SETHD1,CHRPNT ;PRETEND WE'RE LOOKING AT REAL LINE SETCHR CALL TITLE ;SET TITLE AND BUFFER MOV #TTLBU2,R2 ;POINT TO CONSTANT AREA MOVB #TAB,(R2)+ MOV #HELLO,R1 MOVBYT ;DITTO FOR VERSION # ; MOVE IN DATE/TIME ; DATIME ;GET CURRENT TIME CLR -(6) CLR -(6) ;PHONEY DATE AND TIME CLR -(6) ADD #4,SP ;THROW AWAY TIME FOR NOW MOV (SP)+,R5 ;GET DATE MOV R5,R1 ;OUTPUT DAY NUMBER BIC #177740,R1 INC R1 CLR R0 DIV #10.,R0 ;FIRST DIGIT IN R0, SECOND IN R1 ADD #60,R0 ADD #60,R1 MOVB R0,(R2)+ ;OUTPUT NUMBER MOVB R1,(R2)+ MOVB #'-,(R2)+ MOV R5,R0 ;OUTPUT MONTH BIC #177037,R0 ASH #-3,R0 ADD #MONTHS,R0 MOVB (R0)+,(R2)+ MOVB (R0)+,(R2)+ MOVB (R0)+,(R2)+ MOVB #'-,(R2)+ MOV R5,R1 ASH #-9.,R1 ;OUTPUT YEAR BIC #177600,R1 CLR R0 DIV #10.,R0 ADD #60,R0 ADD #60,R1 MOVB R0,(R2)+ MOVB R1,(R2)+ MOVB #40,(R2)+ ENTSEC TXTBYT MONTHS: .ASCII /JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC / XITSEC ; DATIME ;NOW OUTPUT TIME CLR -(6) CLR -(6) ;PHONEY DATE AND TIME CLR -(6) MOV (SP)+,R1 ;PUT IN R0 AND R1 MOV (SP)+,R0 TST (SP)+ ;IGNORE DATE DIV #3600.,R0 ;R0 = HRS*60 + MINS, R1 = SECS*60+TICS MOV R0,R1 ;ONLY OUTPUT HRS AND MINS CLR R0 DIV #60.,R0 MOV R0,R5 ;OUTPUT HRS CLR R4 DIV #10.,R4 ADD #60,R4 ADD #60,R5 MOVB R4,(R2)+ MOVB R5,(R2)+ MOVB #':,(R2)+ CLR R0 DIV #10.,R0 ADD #60,R0 ;OUTPUT MINS ADD #60,R1 MOVB R0,(R2)+ MOVB R1,(R2)+ MOVB #40,(R2)+ MOV R2,TTLEND RETURN ENTSEC TXTBYT SETHD1: .ASCIZ /.MAIN./ ;DEFAULT TITLE XITSEC ; ENTIMP IMPURE ; BLKB TTLBUF,1+TTLLEN ;TITLE STORAGE ; BLKB TTLBU2,44. ;DATE, PAGE #, ETC. ; EVEN ; BLKW TTLBEG ;TITLE BEGINNING ; BLKW TTLEND ;TITLE END ; XITIMP IMPURE ; ENTIMP IMPPAS ; BLKB STLBUF,STLLEN+1 ;SUB-TITLE BUFFER ; EVEN ; ; XITIMP IMPPAS DNC: ;DECIMAL NUMBER CONVERSION MOV #10.,R3 ;SET DIVISOR DNCF: ;ENTRY FOR OTHER THAN DECIMAL CLR R0 DIV R3,R0 ;DIVIDE R1 MOV R1,-(SP) ;SAVE REMAINDER MOV R0,R1 ;SET FOR NEXT DIVIDE BEQ 1$ ; UNLESS ZERO CALL DNCF ;RECURSE 1$: MOV (SP)+,R1 ;RETRIEVE NUMBER ADD #DIG.0,R1 ;CONVERT TO ASCII MOVB R1,(R2)+ ;STORE RETURN R50UNP: ;RAD 50 UNPACK ROUTINE MOV R4,-(SP) ;SAVE REG MOV #SYMBOL,R4 ;POINT TO SYMBOL STORAGE 1$: MOV (R4)+,R1 ;GET NEXT WORD MOV #50*50,R3 ;SET DIVISOR CALL 10$ ;DIVIDE AND STUFF IT MOV #50,R3 CALL 10$ ;AGAIN FOR NEXT MOV R1,R0 CALL 11$ ;FINISH LAST GUY CMP R4,#SYMBOL+4 ;THROUGH? BNE 1$ ; NO MOV (SP)+,R4 ;YES, RESTORE REGISTER RETURN 10$: CLR R0 DIV R3,R0 11$: TST R0 ;SPACE? BEQ 23$ ; YES CMP R0,#33 ;TEST MIDDLE BLT 22$ ;ALPHA BEQ 21$ ;DOLLAR ADD #22-11,R0 ;DOT OR DOLLAR 21$: ADD #11-100,R0 22$: ADD #100-40,R0 23$: ADD #40,R0 MOVB R0,(R2)+ ;STUFF IT RETURN dma7.mac0000600002565200256520000003347302141527064010517 0ustar jncjnc .SBTTL MA7: I/O BUFFERS ; ENTIMP IMPURE ; BLKW SRCLNK,1 ; BLKB SRCFIL,38. ; ; BLKW SRCHDR,3 ; BLKW SRCBUF,SRCLEN/2+2 ; ; ; BLKW LSTLNK,1 ; BLKB LSTFIL,38. ; ; BLKW LSTHDR,3 ; BLKW LSTBUF,</2+1> ; ; ; BLKW OBJLNK,1 ; BLKB OBJFIL,38. ; ; BLKW OBJHDR,1 ; BLKW OBJBUF,OBJLEN/2 ; ; ; ;OCTBUF=.BASE ; BLKB OCTERP,0 ; BLKB OCTSEQ,2 ; BLKB OCTPF0,7 ; BLKB OCTPF1,OCTLEN-<.BASE-OCTBUF> ; BLKW LINBUF,LINLEN/2 ; BLKW LINEND,1 ; ; BLKW RLDHDR,1 ; BLKW RLDBUF,RLDLEN/2 ; ; XITIMP IMPURE .SBTTL MA7: EXPRESSION EVALUATOR EXPR: ;EXPRESSION EVALUATION SAVREG ;SAVE REGISTERS TERM ;TRY FOR A TERM BEQ 5$ ;EXIT IF NULL CLR -(SP) ;NON-NULL, SET REGISTER FLAG STORAGE 1$: SETXPR ;SET EXPRESSION REGISTERS BIS (R3),(SP) ;SAVE REGISTER FLAG CHSCAN BOPTBL ;SCAN THE BINARY OPERATOR TABLE BEQ 2$ ; BRANCH IF NOT FOUND CALL 10$ ;FOUND, CALL HANDLER BR 1$ ;TEST FOR MORE 2$: BIC #-1-REGFLG,(SP) ;MASK ALL BUT REGISTER FLAG BEQ 6$ ;BRANCH IF NOT REGISTER BIT #177770,(R4) ;IN BOUNDS? BNE 7$ ; NO, ERROR 6$: ASR RELLVL ;TEST RELOCATON LEVEL BNE 3$ ;BRANCH IF NOT 0 OR 1 BCC 4$ ;BRANCH IF 0 TST (SP) ;RELOCATABLE, TEST REGISTER FLAG BEQ 4$ ;BRANCH IF NOT SET 7$: ERROR R ;REL AND REG, ERROR CLR (SP) ;CLEAR REGISTER BIT BR 4$ 3$: ERROR A ;IMPROPER RELOCATION 4$: BIS (SP)+,(R3) ;MERGE REGISTER BIT SETNZ R0 ;SET TRUE 5$: RETURN 10$: MOV R0,-(SP) ;STACK OPERATOR ADDRESS MOV R1,R3 ;LEAVE POINTER TO "SYMBOL" IN R3 MOV (R1)+,-(SP) ;STACK SYMBOL MOV (R1)+,-(SP) MOV (R1)+,-(SP) ; MODE, MOV (R1)+,-(SP) ; VALUE, MOV (R1)+,-(SP) ; AND REL LEVEL GLBTRM ;EVALUATE NEXT TERN MOV #EXPBAK+^D10,R1 ;SET TO UNSTACK PREVIOUS MOV (SP)+,-(R1) ;REL LEVEL MOV (SP)+,-(R1) ;VALUE MOV R1,R2 ;R2 POINTS TO PREVIOUS VALUE MOV (SP)+,-(R1) ;MODE MOV (SP)+,-(R1) MOV (SP)+,-(R1) ;R1 POINTS TO PREVIOUS SYMBOL ASR (SP) ;ABSOLUTE ONLY? BCS 12$ ; NO BIS -(R2),-(R4) ;YES, MERGE FLAGS ABSTST ;TEST FOR ABSOLUTE CMP (R2)+,(R4)+ ;RESTORE REGISTERS 12$: ASL (SP) ;EVEN OUT ADDRESS JMP @(SP)+ ;EXIT THROUGH HANDLER ; ENTIMP IMPURE ; BLKW EXPBAK,5 ;PREVIOUS TERM STORAGE ; XITIMP IMPURE ENTSEC DPURE BOPTBL: ;BINARY OP TABLE GCHTBL CH.ADD, BOPADD+1 ; "+" GCHTBL CH.SUB, BOPSUB+1 ; "-" GCHTBL CH.MUL, BOPMUL ; "*" GCHTBL CH.DIV, BOPDIV ; "/" GCHTBL CH.AND, BOPAND ; "&" GCHTBL CH.IOR, BOPIOR ; "!" .WORD 0 XITSEC BOPSUB: RELTST ;MAKE SURE NO GLOBALS NEG (R4) ; -, NEGATE VALUE NEG RELLVL ; AND RELLVL BOPADD: ADD (R2)+,(R4)+ ; +, ADD VALUES ADD (R2),(R4) ; AND RELOCATION LEVELS CMP -(R2),-(R4) ;POINT BACK TO VALUES BIT #GLBFLG!RELFLG,-(R2) ;ABS * XXX? BEQ 3$ ; YES, ALL SET BIT #GLBFLG!RELFLG,-(R4) ;XXX * ABS? BEQ 4$ ; YES, OLD FLAGS BITB #GLBFLG,(R2)+ ;ERROR IF EITHER GLOBAL BNE 5$ BITB #GLBFLG,(R4)+ BNE 5$ CMPB (R4),(R2) ;REL +- REL, SAME SECTOR? BNE 5$ ; NO, ERROR BISB #RELFLG,-(R4) TST RELLVL BNE 3$ BIC #177400!RELFLG,(R4) 3$: RETURN 4$: MOV (R1)+,(R3)+ MOV (R1)+,(R3)+ BIS (R1)+,(R3)+ RETURN 5$: JMP ABSERR BOPAND: COM (R2) BIC (R2),(R4) RETURN BOPIOR: BIS (R2),(R4) RETURN BOPMUL: ; * MOV (R2),R0 ;FETCH FIRST ARG MOV R0,-(SP) ;SAVE A COPY BPL 1$ ;POSITIVE? NEG R0 ; NO, MAKE IT SO 1$: MOV (R4),R3 ;SET SECOND ARG BPL 2$ ;BRANCH IF POSITIVE NEG R3 ;NEGATIVE, MAKE IT + COM (SP) ;TOGGLE RESULT SIGN 2$: MUL R3,R0 ;MULTIPLY MOV R1,R0 ;SET FOR EXIT BR BOPDVX ;EXIT THROUGH DIVIDE BOPDIV: ; / MOV (R4),R3 ;SET DIVISOR MOV R3,-(SP) ;SAVE A COPY BPL 1$ ;BRANCH IF PLUS NEG R3 ;MAKE IT THUS 1$: MOV (R2),R1 ;SET QUOTIENT BPL 2$ ;AGAIN!!! NEG R1 COM (SP) 2$: CLR R0 ;OPERATE DIV R3,R0 BOPDVX: TST (SP)+ ;TEST RESULT BPL 1$ ; OK AS IS NEG R0 ;NO, NEGATE IT 1$: MOV R0,(R4) ;SET RESULT RETURN ;SPECIAL ENTRY POINT TO EXPR ;NULL FIELD CAUSES ERROR ;R0 SET TO VALUE GLBTRM: TERM BEQ ABSERR BR ABSERX GLBEXP: ;NON-NULL EXPRESSION EXPR BEQ ABSERR BR ABSERX RELTRM: GLBTRM BR RELTST RELEXP: GLBEXP RELTST: BIT #GLBFLG,FLAGS BEQ ABSERX BR ABSERR ABSTRM: GLBTRM BR ABSTST ABSEXP: GLBEXP ABSTST: BIT #GLBFLG!RELFLG,FLAGS BEQ ABSERX ABSERR: CLR MODE CLR RELLVL ABSERF: ERROR A ABSERX: MOV VALUE,R0 ;RETURN WITH VALUE IN R0 RETURN .SBTTL MA7: TERM EVALUATOR TERM: ;TERM EVALUATOR SAVREG ;SAVE REGISTERS SETXPR ; AND SET "EXPRESSION" TYPE CLR (R3) ;CLEAR MODE CLR (R4) ; AND VALUE CALL TERM10 ;PROCESS BIC #DEFFLG!LBLFLG!MDFFLG,(R3) ;CLEAR EXTRANEOUS CLR RELLVL ;ASSUME ABSOLUTE BIT #RELFLG,(R3) ;TRUE? BEQ 1$ INC RELLVL ; NO, RELOCATABLE 1$: INC EXPFLG ;MARK AS EXPRESSION JMP SETNB ;EXIT WITH NON-BLANK AND R0 SET TERM10: GETSYM ;TRY FOR A SYMBOL BEQ TERM20 ;BRANCH IF NOT A SYMBOL .IF NDF XCREF MOV #SYMROL,ROLNDX CRFREF .ENDC CMP SYMBOL+2,#DOTSTR;; LOCATION COUNTER? BEQ 14$ ; YES, TREAT SPECIAL SSRCH ;SEARCH THE SYMBOL TABLE BEQ 16$ ;BRANCH IF NOT FOUND BIT #MDFFLG,(R3) ;MULTIPLY DEFINED? BEQ 11$ ; NO ERROR M ; YES 11$: BIT #DEFFLG,(R3) ;DEFINED? BNE 12$ ; YES BIT #GLBFLG,(R3) ;NO, GLOBAL? BNE TERM28 ; YES ERROR U ;NO, UNDEFINED ERROR 12$: BIC #GLBFLG,(R3) ;CLEAR INTERNAL GLOBAL FLAG BR TERM28 14$: MOV #CLCNAM,R1 ;DOT, MOVE TO WORKING AREA MOV #SYMBOL,R2 CALL XMIT4 CLRB (R3) ;CLEAR FLAGS TST (R3) ;ABSOLUTE SECTION? BEQ TERM28 ; YES BIS #RELFLG,(R3) ;NO, SET FLAG BR TERM28 16$: OSRCH ;NOT USER DEFINED, PERHAPS AN OP-CODE? TST (R3) ;OP CODE? BMI 17$ ;YES SSRCH ;SET SEARCH POINTERS INSERT ;NOT IN TABLE, INSERT AS UNDEFINED ERROR U 17$: BIC #^C,(R3) ;CLEAR IRRELEVANT BITS BR TERM28 TERM20: MOV CRADIX,R2 ;ASSUME NUMBER, CURRENT RADIX 21$: CVTNUM ;CONVERT BEQ TERM30 ; NOPE, MISSED AGAIN BPL 22$ ;NUMBER, ANY OVERFLOW? ERROR T ; YES, FLAG IT 22$: CMP R5,#CH.DOT ;NUMBER, DECIMAL? BEQ 24$ ; YES .IF NDF XEDLSB CMP R5,#CH.DOL ;NO, LOCAL SYMBOL? BEQ 24$ ; YES .ENDC TSTB R0 ;NO, ANY NUMBERS OUT OF RANGE? BEQ TERM28 ; NO ERROR N ;YES, FLAG IT BR 23$ 24$: CMP R2,#10. ;"." OR "$", WERE WE DECIMAL? BEQ 25$ ; YES 23$: SETSYM ;NO, MOV #10.,R2 ; TRY AGAIN WITH DECIMAL RADIX BR 21$ 25$: CMP R5,#CH.DOT ;DECIMAL? BEQ TERM27 ; YES .IF NDF XEDLSB LSRCH ;NO, LOCAL SYMBOL BNE TERM27 ;BRANCH IF FOUND .ENDC TERM26: ERROR U ; NO, FLAG AS UNDEFINED TERM27: GETCHR ;BYPASS DOT OR DOLLAR TERM28: SETNB ;RETURN POINTING TO NON-BLANK SETNZ R0 ;FLAG AS FOUND TERM29: RETURN TERM30: CHSCAN UOPTBL ;SCAN UNARY OPERATOR TABLE BEQ TERM29 ; NOT THERE CLR R2 ;CLEAR FOR FUTURE USE CALL (R0) ;FOUND, GO AND PROCESS BR TERM28 ;EXIT TRUE ENTSEC DPURE UOPTBL: GCHTBL CH.ADD, GLBTRM ; "+" GCHTBL CH.SUB, TERM42 ; "-" GCHTBL CH.QTM, TERM44 ; """ GCHTBL CH.XCL, TERM45 ; "'" GCHTBL CH.PCT, TERM46 ; "%" GCHTBL CH.LAB, TERM47 ; "<" GCHTBL CH.UAR, TERM50 ; "^" .WORD 0 XITSEC TERM42: ABSTRM ;EVALUATE ABSOLUTE NEG (R4) ;NEGATE VALUE RETURN TERM44: INC R2 ; """, MARK IT TERM45: MOV R4,R1 ; "'", SET TEMP STORE REGISTER SETSYM ;POINT BACK TO OPERATOR 1$: GETCHR ;GET THE NEXT CHARACTER BEQ TERM48 ;ERROR IF EOL .IF NDF XEDLC MOVB @CHRPNT,(R1) ;STORE ABSOLUTE CHAR BICB #200,(R1)+ ;CLEAR POSSIBLE SIGN BIT AND INDEX .IFF MOVB R5,(R1)+ .ENDC DEC R2 ;ANOTHER CHARACTER BEQ 1$ ; YES BR TERM27 ;BYPASS LAST CHAR TERM46: ABSTRM ;REGISTER EXPRESSION BIS #REGFLG,(R3) ;FLAG IT RETURN TERM47: ; "<" GLBEXP ;PROCESS NON-NULL EXPRESSION CMP R5,#CH.RAB ;">"? BEQ TERM27 ; YES, BYPASS AND EXIT TERM48: JMP ABSERF ;ERROR, FLAG IT TERM50: ; "^" CHSCAN UARTBL ;SCAN ON NEXT CHARACTER BEQ TERM48 ; INVALID, ERROR JMP (R0) ;CALL ROUTINE ENTSEC DPURE UARTBL: ;UP ARROW TABLE GCHTBL LET.C, TERM51 ; ^C GCHTBL LET.C!40,TERM51 ;; ^c GCHTBL LET.D, TERM52 ; ^D GCHTBL LET.D!40,TERM52 ;; ^d GCHTBL LET.O, TERM53 ; ^O GCHTBL LET.O!40,TERM53 ;; ^o GCHTBL LET.B TERM54 ; ^B GCHTBL LET.B!40,TERM54 ;; ^b .IF NDF XFLTG GCHTBL LET.F, TERM55 ; ^F GCHTBL LET.F!40,TERM55 ;; ^f .ENDC .WORD 0 XITSEC TERM51: ABSTRM ;PROCESS ABSOLUTE COM (R4) ;COMPLEMENT VALUE RETURN TERM52: ADD #2.,R2 TERM53: ADD #6.,R2 TERM54: ADD #2.,R2 MOV CRADIX,-(SP) ;STACK CURRENT RADIX MOV R2,CRADIX ;REPLACE WITH LOCAL GLBTRM ;EVALUATE TERM MOV (SP)+,CRADIX ;RESTORE RADIX RETURN .IF NDF XFLTG TERM55: CALL FLTG1W ;PROCESS ONE WORD FLOATING BEQ TERM48 ;ERROR IF NULL RETURN .ENDC .SBTTL MA7: SYMBOL/CHARACTER HANDLERS GETSYM: SAVREG ;; SAVE THE REGISTERS MOV CHRPNT,SYMBEG ;; SAVE IN CASE OF RESCAN CLR SYMBOL ;; ZERO POINTER FOR SHORT SYMBOLS MOV #NULSTR,SYMBOL+2;; IN CASE CHARACTER ISN'T A SYMBOL BITB CTTBL(R5),#CT.ALP!CT.LC ;; MUST START WITH A LETTER BEQ 5$ ;; EXIT IF FALSE MOVB R5,SYMBOL+3 ;; STORE IN HIGH BYTE GETCHR ;; GET THE NEXT CHARACTER BITB CTTBL(R5),#CT.ALP!CT.NUM!CT.LC ;; IS IT A LEGAL SYMBOL CHARACTER? BEQ 4$ ;; EXIT IF NOT MOVB R5,SYMBOL+2 ;; THIS CHARACTER GOES IN LOW BYTE GETCHR ;; GET THE THIRD CHARACTER BITB CTTBL(R5),#CT.ALP!CT.NUM!CT.LC ;; ARE WE DONE BEQ 4$ ;; EXIT IF SO MOV #SYMBUF,R1 ;; POINTER TO BUFFER TO ASSEMBLE SYMBOL IN MOV R1,SYMBOL ;; SAVE POINTER TO SYMBOL 1$: MOVB R5,(R1)+ ;; SAVE CHARACTER GETCHR ;; GET NEXT CHARACTER BITB CTTBL(R5),#CT.ALP!CT.NUM!CT.LC ;; IS IT A LEGAL SYMBOL CHARACTER? BEQ 6$ ;; NO, ALL DONE CMP R1,#SYMBUF+63. ;; ABOUT TO OVERFLOW THE BUFFER? BNE 1$ ;; NO ERROR T ;; GIVE A TRUNCATION ERROR 3$: GETCHR ;; AND FLUSH REST OF SYMBOL BITB CTTBL(R5),#CT.ALP!CT.NUM!CT.LC ;; A LEGAL SYMBOL CHARACTER? BNE 3$ ;; YES, SO LOOP 6$: CLRB (R1) ;; MAKE SYMBOL ASCIZ 4$: SETNB ;; SKIP TO THE NEXT NONBLANK CHARACTER 5$: MOV SYMBOL+2,R0 ;; 0 OR POINTER TO SYMBOL SUB #NULSTR,R0 ;; SEE IF IT WAS THE BLANK STRING RETURN MULR50: ;MULTIPLY R0 * 50 IMULI 50,R0 RETURN TSTR50: BITB #CT.ALP!CT.NUM!CT.SP,CTTBL(R0) ;ALPHA, NUMERIC, OR SPACE? BEQ 1$ ; NO, EXIT MINUS CMP R0,#CH.DOL ;YES, TRY DOLLAR BLO 2$ ;SPACE BEQ 3$ ;DOLLAR CMP R0,#LET.A BLO 4$ ;DOT OR DIGIT BR 5$ ;ALPHA 1$: MOV #100000+SPACE,R0 ;INVALID, FORCE MINUS 2$: SUB #SPACE-11,R0 ;SPACE 3$: SUB #11-22,R0 ;DOLLAR 4$: SUB #22-100,R0 ;DOT, DIGIT 5$: SUB #100,R0 ;ALPHABETIC RETURN CVTNUM: ;CONVERT TEXT TO NUMERIC ; IN - R2 RADIX ; OUT - VALUE RESULT ; R0 - HIGH BIT - OVERFLOW ; - HIGH BYTE - CHARACTER COUNT ; - LOW BYTE - OVERSIZE COUNT SAVREG CLR R0 ;RESULT FLAG REGISTER CLR R1 ;NUMERIC ACCUMULATOR MOV CHRPNT,SYMBEG ;SAVE FOR RESCAN 1$: MOV R5,R3 ;GET A COPY OF THE CURRENT CHAR SUB #DIG.0,R3 ;CONVERT TO ABSOLUTE CMP R3,#9. ;NUMERIC? BHI 9$ ; NO, WE'RE THROUGH CMP R3,R2 ;YES, LESS THAN RADIX? BLO 2$ ; YES INC R0 ;NO, BUMP "N" ERROR COUNT 2$: MUL R2,R1 ADD R3,R1 ;ADD IN CURRENT NUMBER GETCHR ;GET ANOTHER CHARACTER ADD #000400,R0 ;TALLY CHARACTER COUNT BR 1$ 9$: MOV R1,VALUE ;RETURN RESULT IN "VALUE" RETURN ;RETURN, TESTING R0 GSARG: ;GET A SYMBOLIC ARGUMENT .ENABL LSB TSTARG ;TEST GENERAL BEQ 2$ ; EXIT NULL GSARGF: GETSYM ;ARG, TRY FOR SYMBOL BEQ 1$ ; ERROR IF NOT SYMBOL CMP SYMBOL+2,#DOTSTR;; "."? BNE 2$ ; NO, OK 1$: ERROR A CLR R0 ;TREAT ALL ERRORS AS NULL 2$: RETURN .DSABL LSB TSTARG: ;TEST ARGUMENT 1$: MOVB CTTBL(R5),R0 ;GET CHARACTERISTICS BLE 12$ ;THROUGH IF EOL OR SEMI-COLON TST ARGCNT ;FIRST ARGUMENT? BEQ 11$ ; YES, GOOD AS IS BIT #CT.COM,R0 ;NO, COMMA? BNE 10$ ; YES, BYPASS IT TST EXPFLG ;NO, WAS ONE REQUIRED? BEQ 2$ ; NO ERROR A ;YES, FLAG ERROR 2$: CMP CHRPNT,ARGPNT ;DID ANYBODY USE ANYTHING? BNE 11$ ; YES, OK 3$: GETCHR ;NO, BYPASS TO AVOID LOOPS BITB #CT.PC+CT.SP+CT.TAB-CT.COM-CT.SMC,CTTBL(R5) BNE 3$ ; YES, BYPASS SETNB ;NO, SET TO NON-BLANK ERROR A ;FLAG ERROR BR 1$ ;NOW TRY AGAIN 10$: GETNB ;BYPASS COMMA 11$: INC ARGCNT ;INCREMENT ARGUMENT COUNT 12$: CLR EXPFLG MOV CHRPNT,ARGPNT ;SAVE POINTER BIC #177600,R0 ;SET FLAGS RETURN ; ENTIMP IMPLIN ;CLEAR EACH LINE ; BLKW ARGCNT, ;ARGUMENT COUNT ; BLKW ARGPNT, ;START OF LAST ARGUMENT ; BLKW EXPFLG, ;SET WHEN COMMA REQUIRED ; XITIMP IMPLIN CT.EOL= 000 ; EOL CT.COM= 001 ; COMMA CT.TAB= 002 ; TAB CT.SP= 004 ; SPACE CT.PCX= 010 ; PRINTING CHARACTER CT.NUM= 020 ; NUMERIC CT.ALP= 040 ; ALPHA, DOT, DOLLAR CT.LC= 100 ; LOWER CASE ALPHA CT.SMC= 200 ; SEMI-COLON (MINUS BIT) CT.PC= CT.COM!CT.SMC!CT.PCX!CT.NUM!CT.ALP!CT.LC;PRINTING CHARS .MACRO GENCTT ARG ;GENERATE CHARACTER TYPE TABLE .IRP A, .BYTE CT.'A .ENDM .ENDM ENTSEC DPURE CTTBL: ;CHARACTER TYPE TABLE GENCTT GENCTT GENCTT GENCTT GENCTT GENCTT GENCTT GENCTT GENCTT GENCTT GENCTT GENCTT GENCTT GENCTT GENCTT GENCTT XITSEC SETSYM: ;SET SYMBOL FOR RE-SCAN MOV SYMBEG,CHRPNT ;SET THE POINTER BR SETCHR ;SET CHARACTER AND FLAGS GETNB: ;GET A NON-BLANK CHARACTER INC CHRPNT ;BUMP POINTER SETNB: SETCHR ;SET REGISTER AND FLAGS BITB #CT.SP!CT.TAB,CTTBL(R5) ;BLANK? BNE GETNB ; YES, BYPASS BR SETCHR ;EXIT, SETTING FLAGS GETCHR: ;GET THE NEXT CHARACTER INC CHRPNT ;BUMP POINTER SETCHR: MOVB @CHRPNT,R5 ;SET REGISTER AND FLAGS .IF NDF XEDLC GENEDT LC,CPOPJ ;LOWER CASE, DEFAULT TO ON .ENDC BMI GETCHR ;LOOP IF INVALID CHARACTER RETURN CHSCAN: ;CHARACTER SCAN ROUTINE 1$: TST (R0)+ ;END (ZERO)? BEQ 2$ ; YES CMP (R0)+,R5 ;THIS THE ONE? BNE 1$ ; NO TST -(R0) ;YES, MOVE POINTER BACK MOV CHRPNT,SYMBEG ;SAVE CURRENT POINTER GETNB ;GET NEXT NON-BLANK 2$: MOV -(R0),R0 ;MOVE ADDR OR ZERO INTO R0 RETURN dma8.mac0000600002565200256520000002774202271107560010521 0ustar jncjnc .SBTTL MA8: ROLL HANDLERS SSRCH: ;USER DEFINED OPERAND SEARCH SEARCH SYMROL RETURN .IF NDF XMACRO MSRCH: SEARCH MACROL RETURN .ENDC .IF NDF XEDLSB LSRCH: ;LOCAL SYMBOL SEARCH TST LSYFLG ;FLAG SET? BEQ 11$ ; NO CLR LSYFLG ;YES, CLEAR IT INC LSYBKN ;BUMP BLOCK NUMBER 11$: MOV #SYMBOL,R0 ;; GET POINTER TO SYMBOL MOV LSYBKN,(R0)+ ;; FIRST WORD IS LOCAL SYMBOL BLOCK NUMBER MOV VALUE,(R0) ;; SECOND WORD IS N OF N$: BEQ 12$ ;; CAN'T BE 0$ CMP (R0),#^D127 ;; OR > 127 BLOS 13$ ;; NOT AN ERROR 12$: ERROR T ;; GIVE A T ERROR 13$: MOV #LSYROL,R0 ;; ROLL NUMBER CALL LSYSCH ;; DO THE SEARCH (SPECIAL BINARY STYLE) RETURN ;; AND RETURN ; ENTIMP IMPPAS ; BLKW LSYFLG ;BUMPED AT "LABEL:" ; BLKW LSYBKN ;BLOCK NUMBER ; BLKW LSYBAS ;SECTION BASE ; BLKW LSGBAS ;BASE FOR GENERATED SYMBOLS ; XITIMP IMPPAS GENEDT LSB,LSBTST,1 ;LOCAL SYMBOL BLOCK .ENABL LSB LSBTST: BNE 2$ ;BYPASS IF /DS BR 1$ LSBSET: BIT #ED.LSB,EDMASK ;IN LSB OVER-RIDE? BEQ 2$ ; YES 1$: INC LSYFLG ;FLAG NEW BLOCK MOV CLCLOC,LSYBAS ;SET NEW BASE BIC #1,LSYBAS ;BE SURE ITS EVEN CLR LSGBAS ;CLEAR GENERATED SYMBOL BASE 2$: RETURN .DSABL LSB .ENDC SEARCH: ;BINARY ROLL SEARCH SETROL ;SET ROLL REGISTERS MOV R3,-(SP) SUB R3,R1 ;POINT ONE SLOT LOW MOV R2,R3 SUB R1,R3 ;COMPUTE SIZE CLR R0 ;GET SET TO COMPUTE SEARCH OFFSET SEC ; (R0 DOUBLES AS T/F FLAG) 1$: ROL R0 ;SHIFT BIT BIC R0,R3 ;CLEAR CORRESPONDING BIT. LAST ONE? BNE 1$ ; NO 2$: ADD R0,R1 3$: ASR R0 ;END OF ITERATION, HALVE OFFSET BIC #2,R0 ;END? BEQ 7$ ; YES 4$: CMP R2,R1 ;OFF IN NO-MANS'S LAND? BLOS 6$ ; YES CMP R1,ROLBAS(R5) ;DID WE WRAP AROUND ZERO? BLO 6$ ; YES CALL STRCMP ;; A MATCH? BEQ 8$ ; YES, FOUND 5$: BGT 2$ ;NO, BRANCH IF TOO HIGH 6$: SUB R0,R1 ;LOWER INDEX BR 3$ 7$: CMP (R1)+,(R1)+ ;POINT TO INSERTION SLOT 8$: MOV (SP)+,R3 BR SCANX ;EXIT THROUGH SCAN LSYSCH: ;; OLD STYLE BINARY ROLL SEARCH FOR LOCAL SYMBOLS SETROL ;SET ROLL REGISTERS MOV R3,-(SP) SUB R3,R1 ;POINT ONE SLOT LOW MOV R2,R3 SUB R1,R3 ;COMPUTE SIZE CLR R0 ;GET SET TO COMPUTE SEARCH OFFSET SEC ; (R0 DOUBLES AS T/F FLAG) 1$: ROL R0 ;SHIFT BIT BIC R0,R3 ;CLEAR CORRESPONDING BIT. LAST ONE? BNE 1$ ; NO 2$: ADD R0,R1 3$: ASR R0 ;END OF ITERATION, HALVE OFFSET BIC #2,R0 ;END? BEQ 7$ ; YES 4$: CMP R2,R1 ;OFF IN NO-MANS'S LAND? BLOS 6$ ; YES CMP R1,ROLBAS(R5) ;DID WE WRAP AROUND ZERO? BLO 6$ ; YES CMP (R4),(R1) ;; FIRST WORDS MATCH? BNE 5$ ;; NO CMP 2(R4),2(R1) ;; SECOND WORDS MATCH? BEQ 8$ ;; YES, A MATCH! 5$: BHI 2$ ;; NO, TRY AGAIN 6$: SUB R0,R1 ;; LOWER INDEX BR 3$ 7$: CMP (R1)+,(R1)+ ;POINT TO INSERTION SLOT 8$: MOV (SP)+,R3 BR SCANX ;EXIT THROUGH SCAN OSRCH: MOV #PSTROL,R0 ;; NUMBER OF ROLL TO SEARCH SETROL ;SET ROLL REGISTERS MOV R3,-(SP) SUB R3,R1 ;POINT ONE SLOT LOW MOV R2,R3 SUB R1,R3 ;COMPUTE SIZE CLR R0 ;GET SET TO COMPUTE SEARCH OFFSET SEC ; (R0 DOUBLES AS T/F FLAG) 1$: ROL R0 ;SHIFT BIT BIC R0,R3 ;CLEAR CORRESPONDING BIT. LAST ONE? BNE 1$ ; NO 2$: ADD R0,R1 3$: ASR R0 ;END OF ITERATION, HALVE OFFSET BIC #2,R0 ;END? BEQ 7$ ; YES 4$: CMP R2,R1 ;OFF IN NO-MANS'S LAND? BLOS 6$ ; YES CMP R1,ROLBAS(R5) ;DID WE WRAP AROUND ZERO? BLO 6$ ; YES CALL PSTCMP ;; A MATCH? BEQ 8$ ; YES, FOUND 5$: BGT 2$ ;NO, BRANCH IF TOO HIGH 6$: SUB R0,R1 ;LOWER INDEX BR 3$ 7$: CMP (R1)+,(R1)+ ;POINT TO INSERTION SLOT 8$: MOV (SP)+,R3 BR SCANX ;EXIT THROUGH SCAN NEXT: ;GET THE NEXT ENTRY SETROL MOV ROLUPD,R0 ADD R0,R1 ADD R3,R0 CMP R1,R2 BLO SCANX BR SCANXF SCANP: ;LINEAR ROLL SCAN GOOD FOR PERMANENT SYMBOLS SETROL ;SET ROLL REGISTERS CLR R0 ;ASSUME FALSE 1$: CMP R2,R1 ;END? BEQ SCANXF ; YES, EXIT FALSE INC R0 CALL PSTCMP ;; A MATCH (CASE DOESN'T MATTER)? BEQ SCANX ; YES 2$: ADD R3,R1 ;INCREMENT BY SIZE BR 1$ SCAN: ;LINEAR ROLL SCAN SETROL ;SET ROLL REGISTERS CLR R0 ;ASSUME FALSE 1$: CMP R2,R1 ;END? BEQ SCANXF ; YES, EXIT FALSE INC R0 CALL STRCMP ;; A MATCH?? BEQ SCANX ; YES 2$: ADD R3,R1 ;INCREMENT BY SIZE BR 1$ .ENABL LSB SCANXF: CLR R0 ;FALSE EXIT SCANX: MOV R1,ROLPNT ;SET ENTRY POINTER MOV R0,ROLUPD ;SAVE FLAG BEQ 1$ ;BRANCH IF NOT FOUND SCANY: MOV R4,R2 ;POINTER TO "SYMBOL" NEG R3 ;NEGATE ENTRY SIZE JMP XMIT0(R3) ;FOUND, XFER ARGUMENTS 1$: CMP (R4)+,(R4)+ ;BYPASS SYMBOL ITSELF ASR R3 ;GET WORD COUNT SUB #2,R3 ;COMPENSATE FOR ABOVE CMP BLE 3$ ;BRANCH IF END 2$: CLR (R4)+ ;CLEAR WORD SOB R3,2$ 3$: RETURN .DSABL LSB APPEND: ;APPEND TO END OF ROLL SETROL MOV R2,ROLPNT ;SET POINTER CLR ROLUPD BR INSERF INSERT: ;INSERT IN ROLL CALL SETROF ;SET ROLL REGISTERS (BUT NO ARG) INSERF: CALL TSTCOR ;MAKE SURE WE HAVE ENOUGH CORE CMP R1,#LSYBAS ;; IS THIS A LOCAL SYMBOL BEQ 1$ ;; YES, DON'T INSERT IN IMPURE CMP SYMBOL,#SYMBUF ;; SYMBOL IN IMPURE SEGMENT? BNE 1$ ;; YES CALL INSYM ;; ELSE INSERT IT 1$: MOV ROLPNT,R0 ;POINTS TO PROPER SLOT TST ROLUPD ;WAS SEARCH TRUE? BNE 5$ ; YES INCB ROLSIZ+1(R5) ;UPDATE ENTRY COUNT ADD R3,ROLTOP(R5) ;UPDATE TOP POINTER CMP R2,ROLBAS+2(R5) ;GAP BETWEEN ROLLS? BNE 5$ ; YES, JUST STUFF IT MOV SP,R1 ;"FROM" ADDRESS SUB R3,SP ;WE'RE ABOUT TO MOVE STACK MOV SP,R2 ;"TO" ADDRESS SUB R1,R0 ;COMPUTE BYTE COUNT ASR R0 ; NOW WORD COUNT 2$: MOV (R1)+,(R2)+ ;MOVE AN ENTRY DOWN SOB R0,2$ 4$: SUB R3,ROLBAS(R5) ;DECREMENT POINTERS SUB R3,ROLTOP(R5) SUB #2,R5 ;MORE ROLLS? BGE 4$ ; YES MOV R2,R0 ;POINT TO INSERTION SLOT 5$: ASR R3 ;HALVE SIZE COUNT 6$: MOV (R4)+,(R0)+ ;MOVE AN ENTRY INTO PLACE SOB R3,6$ ;LOOP IF NOT END TSTCOR: ;TEST FREE CORE SIZE ; MOV SP,R0 ;GET CURRENT SP ; SUB R3,R0 ;SUBTRACT AMOUNT NEEDED ; NEG R0 ; MAKE INTO LENGTH ; SUB FRECOR,R0 ; SUBTRACT LENGTH OF IMPURE SEGMENT ; CMP R0,#-2000. ; LESS THAN 1000. WORDS OF STACK LEFT? ; BGE GETMOR ; YES, GET MORE CORE 11$: RETURN ; NO, OK ; NO ROOM--TRY TO EXPAND CORE ;GETMOR: MOV R3,-(R6) ; SAVE AMT OF CORE NEEDED FOR A WHILE ; MOV R2,-(R6) ; SAVE POINTER ; ADD #63.,R3 ; CLR R2 ; DIV #100,R2 ; # OF BLOCKS ; ADD #20.,R2 ; ASK FOR 20. BLOCKS EXTRA ; GETSTK ; GET CURRENT LENGTH OF STACK SEGMENT ; ADD R2,(R6) ; ADD IN AMT NEEDED ; ALLSTK ; SET THE STACK SIZE ; ASH #6,R2 ; ADD R2,FRECOR ; SET FRECOR TO REFLECT EXPANSION ; CALL CHKCOR ;; STACK AND IMPURE COLLIDE YET? ; MOV (R6)+,R2 ; DONE, RESTORE R2 ; MOV (R6)+,R3 ; AND R3 ; RETURN ; ; ; ; ;CHKCOR: MOV R0,-(SP) ;; SAVE R0 ; GETSTK ;; GET CURRENT STACK SEGMENT ; MOV (SP)+,R0 ;; PUT IT IN R0 ; ASH #6,R0 ;; MAKE IT ACTUAL ADDRESS ; NEG R0 ;; NEGATE IT ; BIC #17777,R0 ;; ROUND TO NEAREST 20000 BOUNDRY ; CMP R0,FREEND ;; OK? ; BLO 1$ ;; NO, ELSE ; MOV (SP)+,R0 ;; RESTORE R0 AND ; RETURN ;; RETURN ; ;1$: MOV #OUTMSG,-(SP) ;; TELL THE POOR USER ; TYPELN ;; I BET HE WAITED A LONG TIME FOR THIS! ; SEXIT ;; BACK TO THE RATRACE ; ; ENTSEC TXTBYT ; .ENABL LC ;OUTMSG: .ASCIZ "Symbol table overflow or stack underflow. Lose, lose." ; .DSABL LC ; XITSEC ZAP: ;EMPTY A ROLL SETROL MOV R1,ROLTOP(R5) ;MAKE TOP = BOTTOM CLRB ROLSIZ+1(R5) ;CLEAR ENTRY COUNT RETURN .SBTTL MA8: UTILITIES SETROL: ;SET ROLL REGISTERS MOV R0,ROLNDX ;SET ARGUMENT SETROF: MOV (SP)+,R0 ;SAVE RETURN ADDRESS SAVREG ;SAVE REGISTERS MOV R5,-(SP) ; AND CURRENT CHARACTER MOV ROLNDX,R5 ;SET INDEX MOV ROLBAS(R5),R1 ;CURRENT BASE MOV ROLTOP(R5),R2 ;CURRENT TOP MOVB ROLSIZ(R5),R3 ;ENTRY SIZE BIC #177400,R3 ;ALLOW ENTRIES .LE. 377 BYTES MOV #SYMBOL,R4 ;POINTER TO SYMBOL CALL (R0) ;CALL PROPER ROUTINE MOV (SP)+,R5 ;RESTORE CURRENT CHARACTER RETURN ; AND REST OF REGS SETXPR: ;SET EXPRESSION REGISTERS MOV #SYMBOL,R1 MOV #SECTOR,R2 MOV #MODE,R3 MOV #VALUE,R4 RETURN SAVREG: ;SAVE REGISTERS MOV R3,-(SP) MOV R2,-(SP) MOV R1,-(SP) CLR -(SP) MOV 8.(SP),(SP) ;PLACE RETURN ADDRESS ON TOP MOV R4,8.(SP) CALL @(SP)+ ;RETURN THE CALL MOV (SP)+,R1 ;RESTORE REGISTERS MOV (SP)+,R2 MOV (SP)+,R3 MOV (SP)+,R4 TST R0 ;SET CONDITION CODES RETURN STRCMP: ;; STRING COMPARE R4 POINTS TO SYMBOL ;; R1 POINTS TO ENTRY IN ROLL CMP 2(R4),2(R1) ;; ARE THE FIRST TWO CHARACTERS THE SAME BNE 5$ ;; NO, QUICK EXIT! CMP (R4),(R1) ;; POINTERS THE SAME? BEQ 5$ ;; YES, SYMBOLS MUST BE THE SAME 7$: CLR -(SP) ;; PLACE FOR THE ANSWER MOV R1,-(SP) ;; SAVE R1 MOV R4,-(SP) ;; AND R4 MOV (R1),R1 ;; GET POINTER TO STRING BEQ 3$ ;; EXIT IF NO STRING MOV (R4),R4 ;; DITTO BEQ 6$ ;; EXIT IF NO STRING 4$: TSTB (R1) ;; OUT OF STRING? BEQ 2$ ;; YES CMPB (R4)+,(R1)+ ;; HOW DO THESE TWO CHARACTERS COMPARE? BEQ 4$ ;; THE SAME BGT 3$ ;; DIFFERENT, SET ANSWER AND RETURN 6$: DEC 4(SP) ;; SAY ONE WAS LESS THEN THE OTHER BR 1$ ;; AND RETURN 2$: TSTB (R4) ;; OUT OF OTHER STRING ALSO? BEQ 1$ ;; YES, STRINGS WERE THE SAME 3$: INC 4(SP) ;; OTHERWISE ONE WAS GREATER THEN THE OTHER 1$: MOV (SP)+,R4 ;; RESTORE R4 MOV (SP)+,R1 ;; AND R1 TST (SP)+ ;; SET CONDITION CODES (-1, 0, OR 1) 5$: RETURN ;; AND RETURN PSTCMP: ;; STRING COMPARE R4 POINTS TO SYMBOL ;; R1 POINTS TO ENTRY IN ROLL MOV 2(R4),-(SP) ;; GET FIRST TWO CHARACTERS BIS #400*40+40,(SP) ;; SET LOWER CASE BITS CMP (SP)+,2(R1) ;; ARE THE FIRST TWO CHARACTERS THE SAME? BNE 5$ ;; NO, QUICK EXIT! CMP (R4),(R1) ;; POINTERS THE SAME (OR NULL)? BEQ 5$ ;; YES, QUICK EXIT! 7$: CLR -(SP) ;; PLACE FOR THE ANSWER MOV R1,-(SP) ;; SAVE R1 MOV R4,-(SP) ;; AND R4 MOV (R1),R1 ;; GET POINTER TO STRING BEQ 3$ ;; EXIT IF NO STRING MOV (R4),R4 ;; DITTO BEQ 6$ ;; EXIT IF NO STRING 4$: TSTB (R1) ;; OUT OF STRING? BEQ 2$ ;; YES MOVB (R4)+,-(SP) ;; GET CHARACTER OUT OF BUFFER BISB #40,(SP) ;; LOWER CASE IT CMPB (SP)+,(R1)+ ;; HOW DO THESE TWO CHARACTERS COMPARE? BEQ 4$ ;; THE SAME BGT 3$ ;; DIFFERENT, SET ANSWER AND RETURN 6$: DEC 4(SP) ;; SAY ONE WAS LESS THEN THE OTHER BR 1$ ;; AND RETURN 2$: TSTB (R4) ;; OUT OF OTHER STRING ALSO? BEQ 1$ ;; YES, STRINGS WERE THE SAME 3$: INC 4(SP) ;; OTHERWISE ONE WAS GREATER THEN THE OTHER 1$: MOV (SP)+,R4 ;; RESTORE R4 MOV (SP)+,R1 ;; AND R1 TST (SP)+ ;; SET CONDITION CODES (-1, 0, OR 1) 5$: RETURN ;; AND RETURN INSYM: ;; INSERT SYMBOL IN SYMBUF INTO IMPURE SEGMENT ;; RETURN POINTER TO STRING IN SYMBOL TST SYMBOL ;; ANY POINTER? BEQ 10$ ;; IF NONE, QUICK EXIT SAVREG ;; SAVE THE REGISTERS MOV FREBEG,R0 ;; POINTER TO FIRST SYMBOL IN IMPURE MOV R0,R4 ;; SAVE POINTER TO BEGINNING OF SYMBOL 6$: MOV #SYMBUF,R1 ;; POINTER TO SYMBOL TO BE INSERTED CMPB (R0),#-1 ;; END OF SYMBOLS? BEQ 8$ ;; YES, ADD SYMBOL TO END 4$: TSTB (R0) ;; END OF SYMBOL? BEQ 2$ ;; YES CMPB (R0)+,(R1)+ ;; ARE THE SYMBOLS EQUAL BEQ 4$ ;; YES, LOOP THROUGH WHOLE SYMBOL 5$: TSTB (R0)+ ;; NO, SKIP TO A ZERO BYTE BNE 5$ ;; SKIP TO A ZERO BYTE 1$: MOV R0,R4 ;; SAVE POINTER TO BEGINNING OF NEXT SYMBOL CMPB (R0),#-1 ;; END OF SYMBOLS? BNE 6$ ;; NO, ON TO NEXT SYMBOL 8$: MOV R0,R2 ;; GET CURRENT END OF SYMBOLS ADD #64.,R2 ;; ADD IN MAXIMUM LENGTH OF A SYMBOL CMP R2,FREEND ;; ENOUGH ROOM BLO 7$ ;; YES, JUST INSERT THE SYMBOL MOV FREEND,R2 ;set up call to expand impure area ADD #<20.*64.>,R2 ;expand area by 20 blocks MOV R2,BREAK+2 ;this is new top of impure MOV R2,FREEND ;and end of impure area SYS S_INDIR,BREAK ;do it! BCS CORE ;complain if expansion failed 7$: MOV R0,SYMBOL ;; SAVE ANSWER MOV #SYMBUF,R1 ;; GET POINTER TO BEGINNING OF SYMBOL TO BE INSERTED 9$: MOVB (R1)+,(R0)+ ;; COPY ONE CHARACTER BNE 9$ ;; LOOP THROUGH WHOLE SYMBOL MOVB #-1,(R0) ;; ADD AN END OF MEMORY MARKER BR 10$ ;; AND EXIT 2$: TSTB (R1) ;; END OF OTHER STRING? BEQ 3$ ;; YES INC R0 ;; OTHERWISE SKIP THE ZERO BYTE BR 1$ ;; AND TRY AGAIN 3$: MOV R4,SYMBOL ;; SAVE ANSWER 10$: RETURN ;; AND RETURN CORE: MOV #NOCORE,-(SP) ;; POINTER TO NO MORE CORE MESSAGE TYPELN ;; TELL USER sys s_exit ;; AND RETURN TO THE SYSTEM .REPT MAXXMT-7 MOV (R1)+,(R2)+ ;PAD TO MAX NEEDED .ENDR XMIT7: MOV (R1)+,(R2)+ XMIT6: MOV (R1)+,(R2)+ XMIT5: MOV (R1)+,(R2)+ XMIT4: MOV (R1)+,(R2)+ XMIT3: MOV (R1)+,(R2)+ XMIT2: MOV (R1)+,(R2)+ XMIT1: MOV (R1)+,(R2)+ XMIT0: RETURN MOVBYT: ;MOVE BYTE STRING 1$: MOVB (R1)+,(R2)+ ;MOVE ONE BNE 1$ ;LOOP IF NON-NULL TSTB -(R2) ;END, POINT BACK TO NULL RETURN dma9.mac0000600002565200256520000003552402141527064010520 0ustar jncjnc .SBTTL MA9: MACRO HANDLERS .IF NDF XMACRO MT.RPT= 177601 MT.IRP= 177602 MT.MAC= 177603 MT.MAX= MT.MAC .GLOBL REPT, ENDR, ENDM REPT: ;REPEAT HANDLER ABSEXP ;EVALUATE COUNT MOV R0,-(SP) ;SAVE COUNT SETPF1 ;MARK THE LISTING CALL GETBLK ;GET A STORAGE BLOCK CLR (R2)+ ;START IN THIRD WORD CLR -(SP) ;NO ARGUMENTS MOV R0,-(SP) ; AND START OF BLOCK CALL ENDLIN ;POLISH OFF LINE ZAP DMAROL ;NO DUMMY ARGS FOR REPEAT CALL PROMT ;USE MACRO STUFF MOV #MT.RPT,R5 ;FUDGE AN "END OF REPEAT" REPTF: CALL WCIMT CALL MPUSH ;PUSH PREVIOUS MACRO BLOCK MOV (SP)+,(R2)+ ;STORE TEXT POINTER MOV (SP)+,(R2)+ ;STORE ARG POINTER CLR (R2)+ ;COUNTER MOV (SP)+,(R2)+ ;MAX SETCHR ;RESTORE CHARACTER ENDMAC: MOV #MSBCNT,R0 ;SET POINTER TO COUNT INC (R0) ;BUMP IT CMP (R0)+,(R0)+ ;THROUGH? BGT 1$ ; YES MOV MSBTXT,(R0) ;NO, SET READ POINTER ADD #4,(R0) ;BYPASS LINK RETURN 1$: CLR CNDMEX ;CLEAR MEXIT FLAG JMP MPOP ENDM: ENDR: .IFTF .GLOBL OPCERR OPCERR: ERROR O RETURN .IFT .GLOBL MACRO, MACR MACRO: MACR: ;MACRO DEFINITION GSARG ;GET THE NAME BEQ OPCERR ; ERROR IF NULL MACROF: TSTARG ;BYPASS POSSIBLE COMMA CALL INSYM ;; MAKE SYMBOL PERMANENT MOV SYMBOL,MACNAM MOV SYMBOL+2,MACNAM+2 MSRCH ;SEARCH THE TABLE MOV (R4),R0 ;GET THE POINTER BEQ 1$ ;BRANCH IF NULL CALL DECMAC ;DECREMENT THE REFERENCE 1$: CALL GETBLK ;GET A STORAGE BLOCK MOV R0,-(SP) ;SAVE POINTER MSRCH ;GETBLK MIGHT HAVE MOVED THINGS MOV (SP)+,(R4) ;SET POINTER INSERT ;INSERT IN TABLE CRFDEF CALL PROMA ;PROCESS DUMMY ARGS CLR (R2)+ ;CLEAR LEVEL COUNT MOV ARGCNT,(R2)+ ;KEEP NUMBER OF ARGS MOV MACGSB,(R2)+ ; AND GENERATED SYMBOL BITS BIS #LC.MD,LCFLAG CALL ENDLIN ;POLISH OFF LINE CALL PROMT ;PROCESS THE TEXT GETSYM BEQ 3$ CALL INSYM ;; INSERT SYMBOL IN IMPURE SO CAN CMP POINTERS CMP SYMBOL,MACNAM ;; POINTERS MATCH? BNE 2$ ;; NO, ERROR CMP SYMBOL+2,MACNAM+2 ;; FIRST TWO CHARACTERS MATCH? BEQ 3$ ;; GOOD IF SO, ELSE FALL THROUGH TO ERROR 2$: ERROR A 3$: MOV #MT.MAC,R5 CALL WCIMT ;SET END MARKER SETCHR RETURN MACROC: ;MACRO CALL SETPF0 ;MARK LOCATION MOV VALUE,R0 ;GET BLOCK POINTER BEQ OPCERR ; ERROR IF NULL MOV R0,-(SP) CALL INCMAC ;INCREMENT REFERENCE CMP (R0)+,(R0)+ ;MOVE UP A COUPLE OF SLOTS MOV (R0)+,ARGMAX ;SET NUMBER OF ARGS MOV (R0)+,MACGSB ; AND GENERATED SYMBOL BITS MOV R0,-(SP) ;SAVE POINTER CALL PROMC ;PROCESS CALL ARGUMENTS MOV R0,R3 ;SAVE BLOCK POINTER MOV #MT.MAC,R5 CALL MPUSH ;PUSH NESTING LEVEL MOV (SP)+,MSBMRP MOV (SP)+,(R2)+ ;SET TEXT POINTER MOV R3,(R2)+ ; AND ARGUMENT POINTER MOV ARGCNT,(R2) ;FILL IN ARGUMENT COUNT MOV (R2)+,(R2)+ ; AND REPLECATE SETCHR RETURN .GLOBL IRP, IRPC IRPC: INC R3 IRP: CALL GMARG BEQ 1$ CALL PROMA CALL RMARG CALL GMARG BEQ 1$ MOV #177777,ARGMAX ;ANY NUMBER OF ARGUMENTS CALL PROMCF MOV R0,R3 CALL RMARG CALL GETBLK CLR (R2)+ MOV ARGCNT,-(SP) MOV R3,-(SP) MOV R0,-(SP) CALL ENDLIN CALL PROMT MOV #MT.IRP,R5 JMP REPTF 1$: ERROR A RETURN PROMA: ;PROCESS MACRO ARGS ZAP DMAROL ;CLEAR DUMMY ARGUMENT ROLL CLR ARGCNT ;GET A FRESH START WITH ARGUMENTS CLR MACGSB ;CLEAR GENERATED BIT PATTERN MOV #100000,-(SP) ;STACK FIRST GENERATED SYMBOL BIT 1$: TSTARG ;ANY MORE ARGS? BEQ 3$ ; NO, QUIT AND GO HOME CMP #CH.QM,R5 ;YES, GENERATED TYPE? BNE 2$ ; NO BIS (SP),MACGSB ;YES, SET PROPER BIT GETNB ;BYPASS IT 2$: CALL GSARGF ;GET SYMBOLIC ARGUMENT APPEND DMAROL ;APPEND TO DMA ROLL CLC ROR (SP) ;SHIFT GENERATED SYM BIT BR 1$ 3$: TST (SP)+ ;PRUNE STACK RETURN PROMC: CLR R3 PROMCF: CLR ARGCNT CALL GETBLK MOV R0,-(SP) TST R3 BNE 7$ 1$: CMP ARGMAX,ARGCNT BLOS 10$ TSTARG ;BYPASS ANY COMMA BNE 9$ ;OK IF NON-NULL TST MACGSB ;NULL, ANY GENERATED STUFF LEFT? BEQ 10$ ; NO, THROUGH 9$: CMP #CH.BSL,R5 ; "\"? BEQ 20$ ; YES CALL GMARGF ;GET ARGUMENT .IF NDF XEDLSB TST R5 ;ANY ARGUMENTS? BNE 2$ ; YES TST MACGSB ;NO, GENERATION REQUESTED? BMI 30$ ; YES .ENDC 2$: 3$: CALL WCIMT BEQ 4$ GETCHR BR 3$ 4$: CALL RMARG 5$: ASL MACGSB ;MOVE GENERATION BIT OVER ONE BR 1$ 6$: INC ARGCNT GETCHR 7$: CALL WCIMT BEQ 10$ CLR R5 CALL WCIMT BR 6$ 10$: COM R5 CALL WCIMT COM R5 BIT #LC.MC,LCMASK ;MACRO CALL SUPPRESSION? BEQ 12$ ; NO MOV LBLEND,R0 ;YES, HAVE WE A LABEL? BEQ 11$ ; NO, SUPPRESS ENTIRE LINE MOV R0,LCENDL ;YES, LIST ONLY LABEL BR 12$ 11$: BIS #LC.MC,LCFLAG 12$: MOV (SP)+,R0 RETURN 20$: GETNB ; "\", BYPASS ABSEXP ;EVALUATE EXPRESSION, ABS MOV R5,-(SP) ;STACK CHARACTER MOV R3,-(SP) MOV CRADIX,R3 ;BREAK OUT IN CURRENT RADIX MOV R0,R1 ;VALUE TO R1 CALL 40$ ;CONVERT TO ASCII CLR R5 CALL WCIMT MOV (SP)+,R3 ;RESTORE REGS MOV (SP)+,R5 BR 5$ .IF NDF XEDLSB 30$: INC LSGBAS ;GENERATED SYMBOL, BUMP COUNT MOV LSGBAS,R1 ;FETCH IT ADD #^D<64-1>,R1 ;START AT 64. MOV R5,-(SP) ;STACK CURRENT CHAR MOV R3,-(SP) ;AND R3 MOV #10.,R3 ;MAKE IT DECIMAL CALL 40$ ;CONVERT TO ASCII MOV #CH.DOL,R5 CALL WCIMT ;WRITE "$" CLR R5 CALL WCIMT MOV (SP)+,R3 ;RESTORE REGS MOV (SP)+,R5 BR 4$ ;RETURN .ENDC 40$: ;MACRO NUMBER CONVERTER CLR R0 DIV R3,R0 MOV R1,-(SP) ;STACK REMAINDER MOV R0,R1 ;SET NEW NUMBER BEQ 41$ ;DOWN TO ZERO? CALL 40$ ; NO, RECURSE 41$: MOV (SP)+,R5 ;GET NUMBER ADD #DIG.0,R5 ;CONVERT TO ASCII JMP WCIMT ;WRITE IN TREE AND EXIT PROMT: CLR R3 1$: CALL GETLIN BNE 2$ BIS #LC.MD,LCFLAG CALL SETCLI BIT #DFLMAC,R0 BEQ 63$ INC R3 CMP #ENDM,VALUE BNE 3$ DEC R3 DEC R3 BPL 3$ 2$: RETURN 63$: .IF NDF XSML TST SMLCNT ;IN SYSTEM MACRO? BEQ 3$ ; NO BIT #DFLSMC,R0 ;YES, NESTED? BEQ 3$ ; NO CALL SMLTST ;YES, TEST FOR MORE .ENDC 3$: MOV #LINBUF,CHRPNT SETCHR 4$: GETSYM BEQ 7$ SCAN DMAROL MOV R0,R4 BEQ 5$ MOV ROLUPD,R5 NEG R5 DEC CONCNT CALL WCIMT DEC CONCNT 5$: SETSYM 6$: TST R4 BNE 61$ CALL WCIMT 61$: GETCHR BITB CTTBL(R5),#CT.ALP!CT.NUM!CT.LC BNE 6$ 7$: CMP R5,#CH.XCL BEQ 8$ CALL WCIMT BNE 9$ CALL ENDLIN BR 1$ 8$: INC CONCNT 9$: GETCHR BR 4$ .GLOBL NARG, NCHR, NTYPE, MEXIT NARG: ;NUMBER OF ARGUMENTS CALL GSARG ;GET A SYMBOL BEQ NTYPER ;ERROR IF MISSING MOV MSBCNT+2,R3 ;SET NUMBER BR NTYPEX NCHR: ;NUMBER OF CHARACTERS CALL GSARG BEQ NTYPER ; ERROR ID NO SYMBOL CALL GMARG ;ISOLATE ARGUMENT BEQ NTYPEX ; ZERO IF NULL TST R5 ;QUICK TEST FOR COMPLETION BEQ 2$ ; YES 1$: INC R3 ;BUMP COUNT GETCHR ;GET THE NEXT CHARACTER BNE 1$ ;LOOP IF NOT END 2$: CALL RMARG ;REMOVE ARG DELIMITERS BR NTYPEX NTYPE: ;TEST EXPRESSION MODE CALL GSARG ;GET THE SYMBOL BEQ NTYPER ; ERROR TSTARG ;BYPASS ANY COMMAS MOV #SYMBOL,R1 MOV (R1)+,-(SP) ;PRESERVE SYMBOL MOV (R1)+,-(SP) CALL AEXP ;EVALUATE MOV R0,R3 ;SET RESULT ZAP CODROL ;CLEAR ANY GENERATED CODE MOV (SP)+,-(R1) ;RESTORE SYMBOL MOV (SP)+,-(R1) NTYPEX: CLR MODE ;CLEAR MODE MOV R3,VALUE ; AND SET VALUE JMP ASGMTF ;EXIT THROUGH ASSIGNMENT NTYPER: ERROR A BR NTYPEX MEXIT: ;MACRO/REPEAT EXIT MOV MACLVL,CNDMEX ;IN MACRO? BNE 1$ ; YES, POP ERROR O ; NO, ERROR 1$: RETURN GENCND B, TCB GENCND NB, TCB, F GENCND IDN, TCID GENCND DIF, TCID, F TCB: ; "IFB" CONDITIONAL BEQ TCBERX ;OK IF NULL CALL GMARGF ;ISOLATE ARGUMENT SETNB ;BYPASS ANY BLANKS BEQ TCIDT ;TRUE IF POINTING AT DELIMITER BR TCIDF ;ELSE FALSE TCBERR: ERROR A ;NAUGHTY TCBERX: RETURN TCID: ; "IFIDN" CONDITIONAL BEQ TCBERR ;ERROR IF NULL ARG CALL GMARGF ;ISOLATE FIRST ARG MOV CHRPNT,R1 ;SAVE CHARACTER POINTER TST -(R0) MOV -(R0),R2 ;POINTER TO TERMINATOR CALL RMARG ;RETURN THIS ARG CALL GMARG ;GET THE NEXT BEQ TCBERR 1$: MOVB (R1),R0 ;SET CHARACTER FROM FIRST FIELD CMP R1,R2 ;IS IT THE LAST? BNE 2$ ; NO CLR R0 ;YES, CLEAR IT 2$: CMP R0,R5 ;MATCH? BNE TCIDF ; NO TST R5 ;YES, FINISHED? BEQ TCIDT ; YES, GOOD SHOW GETCHR ;NO, GET THE NEXT CHARACTER INC R1 ;ADVANCE FIRST ARG POINTER BR 1$ ;TRY AGAIN TCIDF: COM R3 ;FALSE, TOGGLE CONDITION TCIDT: JMP RMARG ;OK, RESTORE ARGUMENT GMARG: ;GET MACRO ARGUMENT TSTARG ;TEST FOR NULL BEQ GMARGX ; YES, JUST EXIT GMARGF: SAVREG ;STASH REGISTERS CLR R1 ;CLEAR COUNT MOV #CHRPNT,R2 MOV (R2),-(SP) ;SAVE INITIAL CHARACTER POINTER MOV #CH.LAB,R3 ;ASSUME "<>" MOV #CH.RAB,R4 CMP R5,R3 ;TRUE? BEQ 11$ ; YES CMP R5,#CH.UAR ;UP-ARROW? BEQ 10$ ; YES 1$: BITB #CT.PC-CT.COM-CT.SMC,CTTBL(R5) ;PRINTING CHARACTER? BEQ 21$ ; NO GETCHR ;YES, MOVE ON BR 1$ 10$: GETNB ; "^", BYPASS IT BEQ 20$ ;ERROR IF NULL MOV (R2),(SP) ;SET NEW POINTER COM R3 ;NO "<" EQUIVALENT MOV R5,R4 ;">" EQUIVALENT 11$: GETCHR BEQ 20$ ; ERROR IF EOL CMP R5,R3 ; "<"? BEQ 12$ ; YES CMP R5,R4 ;NO, ">"? BNE 11$ ; NO, TRY AGAIN DEC R1 ;YES, DECREMENT LEVEL COUNT DEC R1 12$: INC R1 BPL 11$ ;LOOP IF NOT THROUGH INC (SP) ;POINT PAST "<" BIS #100000,R5 ;MUST MOVE PAST IN RMARG BR 21$ 20$: ERROR A 21$: MOV GMAPNT,R0 ;GET CURRENT ARG SAVE POINTER BNE 22$ ;BRANCH IF INITIALIZED MOV #GMABLK,R0 ;DO SO 22$: MOV (R2),(R0)+ ;SAVE POINTER MOV R5,(R0)+ ; AND CHARACTER CLRB @(R2) ;SET NULL TERMINATOR MOV (SP)+,(R2) ;POINT TO START OF ARG SETCHR ;SET REGISTER 5 MOV R0,GMAPNT ;SAVE NEW BUFFER POINTER GMARGX: RETURN RMARG: ;REMOVE MACRO ARGUMENT MOV GMAPNT,R0 ;SET POINTER TO SAVED ITEMS MOV -(R0),R5 ;SET CHARACTER TST -(R0) MOVB R5,@(R0) ;RESTORE VIRGIN CHARACTER ASL R5 ADC (R0) MOV (R0),CHRPNT SETNB MOV R0,GMAPNT RETURN ; ENTIMP IMPPAS ; BLKW GMAPNT,1 ;POINTER TO FOLLOWING BUFFER ; BLKW GMABLK,1 ;POINTER TO "BORROWED" CHARACTER ; BLKW ,1 ;CHARACTER ITSELF ; BLKW ,3*2 ;ROOM FOR MORE PAIRS ; XITIMP IMPPAS WCIMT: ;WRITE CHARACTER IN MACRO TREE DEC CONCNT ;ANY CONCATENATION CHARS PENDING? BMI 1$ ; NO MOV R5,-(SP) ;YES, STACK CURRENT CHARACTER MOV #CH.XCL,R5 CALL 2$ MOV (SP)+,R5 BR WCIMT 1$: CLR CONCNT 2$: BIT #BPMB-1,R2 ;ROOM IN THIS BLOCK? BNE 3$ ; YES SUB #BPMB,R2 ;NO, POINT TO LINK MOV R2,-(SP) CALL GETBLK MOV R0,@(SP)+ ;SET NEW LINK 3$: MOVB R5,(R2)+ ;WRITE, LEAVING FLAGS SET RETURN GETBLK: ;GET A MACRO BLOCK MOV MACNXT,R0 ;TEST FOR BLOCK IN GARBAGE BNE 1$ ; YES, USE IT APPEND MABROL ;NO, GET BLOCK IN ROLL MOV ROLBAS+MABROL,R0 ;GET START MOV R0,ROLTOP+MABROL ;ZAP MAB ROLL MOV R0,ROLBAS+MAAROL ;AWARD SPACE TO MAA BR 2$ 1$: MOV (R0),MACNXT ;SET NEW CHAIN 2$: MOV R0,R2 CLR (R2)+ ;CLEAR LINK CELL, POINT PAST IT RETURN INCMAC: INC 2(R0) ;INCREMENT MACRO REFERENCE RETURN DECMAC: DEC 2(R0) ;DECREMENT MACRO STORAGE BPL REMMAX ;JUST EXIT IF NON-NEGATIVE REMMAC: MOV R0,-(SP) ;SAVE POINTER 1$: TST (R0) ;END OF CHAIN? BEQ 2$ ; YES MOV (R0),R0 ;NO, LINK BR 1$ 2$: MOV MACNXT,(R0) MOV (SP)+,MACNXT REMMAX: RETURN MPUSH: ;PUSH MACRO NESTING LEVEL CALL GETBLK ;GET A STORAGE BLOCK TST -(R2) ;POINT TO START MOV #MSBBLK,R1 ;POINTER TO START OF PROTOTYPE MOV R2,-(SP) ;SAVE DESTINATION MOV R1,-(SP) ; AND CORE POINTERS 1$: MOV (R1),(R2)+ ;XFER AN ITEM CLR (R1)+ ;CLEAR CORE SLOT CMP #MSBEND,R1 ;THROUGH? BNE 1$ ; NO MOV (SP)+,R2 ;YES, MAKE CORE DESTINATION MOV R5,(R2)+ ;SAVE TYPE MOV (SP)+,(R2)+ ; AND PREVIOUS BLOCK POINTER INC MACLVL ;BUMP LEVEL COUNT RETURN ;RETURN WITH R2 POINTING AT MSBTXT MPOP: ;POP MACRO NESTING LEVEL MOV #MSBARG+2,R2 ;POINT ONE SLOT PAST ARG MOV -(R2),R0 ;GET POINTER TO ARG BLOCK BEQ 1$ ;BRANCH IF NULL CALL REMMAC ;REMOVE IT 1$: MOV -(R2),R0 ;POINT TO TEXT BLOCK BEQ 2$ ;BRANCH IF NULL CALL DECMAC ;DECREMENT LEVEL 2$: MOV -(R2),R1 ;GET PREVIOUS BLOCK TST -(R2) ;POINT TO START MOV R1,R0 ;SAVE BLOCK POINTER CALL XMIT0- ;XFER BLOCK CLR (R0) ;CLEAR LINK CALL REMMAC ;RETURN BLOCK FOR DEPOSIT DEC MACLVL ;DECREMENT LEVEL COUNT RETURN ; ENTIMP IMPURE ;MSBBLK=.BASE ;PUSHABLE BLOCK (MUST BE ORDERED) ; BLKW MSBTYP ;BLOCK TYPE ; BLKW MSBPBP ;PREVIOUS BLOCK POINTER ; BLKW MSBTXT ;POINTER TO BASIC TEXT BLOCK ; BLKW MSBARG ;POINTER TO ARG BLOCK ; BLKW MSBCNT,2 ;REPEAT COUNT, ETC. ; BLKW MSBMRP ;MACRO READ POINTER ;MSBEND=.BASE ;END OF ORDERED STORAGE ; ; BLKW MACNXT ; BLKW MACLVL ;MACRO LEVEL COUNT ; BLKW CONCNT ; BLKW ARGMAX ; BLKW MACNAM,2 ; BLKW MACGSB ;MACRO GENERATED SYMBOL BITS ; XITIMP IMPURE .GLOBL MCALL ;.MCALL MCALL: CALL SMLTST ;TEST FOR UNDEFINED ARGUMENTS BEQ 5$ ; BRANCH IF NONE .IF NDF XSML ;ERROR IF NOT IMPLEMENTED TST PASS ;FOUND SOME, PASS ONE? BNE 4$ ; NO, ERROR CLR SMLFLG 10$:; CLR -(SP) MOV #SMLLOC,R1 ;MAKE IT USE THE DEFAULT DIR. MOV #SRCFIL,R2 MOVBYT MOV #SRCFIL,-(SP) MOV #SMLTXT,-(SP) CALL OUTNAM ; MOV #SRCFIL,-(SP) ; OPEN ; BVC 13$ ; TST (SP)+ ; BR 11$ sys s_open,SRCFIL,0 BCS 11$ MOV R0,-(SP) ;SUCCESSFUL OPEN, PUSH FILE ID 13$: CALL BUFBGN ;START A NEW BUFFER MOV #BUFROL,R0 ;PUT FILE ID IN FIRST WORD MOV ROLBAS(R0),R0 MOV (SP),(R0)+ CLR (R0)+ ;CLEAR REST OF HEADER CLR (R0)+ CLR (R0)+ MOV (SP)+,SMLLNK 1$: CLR R3 ;SET COUNT TO ZERO 2$: CALL GETLIN ;GET A NEW LINE BNE 3$ ;EXIT IF EOF CALL SETCLI ;TEST FOR DIRECTIVE BIT #DFLMAC,R0 ;MACRO/ENDM? BEQ 2$ ; NO MOV #VALUE,R4 ;SET FOR LOCAL AND MACROF DEC R3 ;YES, ASSUME .ENDM CMP #ENDM,(R4) ;GOOD GUESS? BEQ 2$ ; YES INC R3 ;NO, BUMP COUNT INC R3 CMP #1,R3 ;OUTER LEVEL? BNE 2$ ; NO GSARG ;YES, GET NAME BEQ 3$ ; ERROR IF NULL MSRCH ;SEARCH TABLE BEQ 2$ ;IGNORE IF NOT THERE TST (R4) ;FOUND, VALUE OF ZERO? BNE 2$ ; NO, NOT INTERESTED CALL MACROF ;GOOD, DEFINE IT DEC SMLCNT ;DECREMENT COUNT BGT 1$ ;LOOP IF MORE TO GO 3$: MOV SMLLNK,R0 ;CLOSE IT sys s_close CLR ENDFLG ;CLEAR END OF FILE FLAG CLR SMLLNK ;SAY WE'RE DONE WITH SMLFILES CALL BUFDONE ;DEALLOCATE BUFFER TST SMLCNT ;ANY MORE? BEQ 5$ SMLERR=. TST SMLFLG ;SEE IF WE SHOULD TRY ANOTHER DIRECTORY BNE 5$ 11$: INC SMLFLG ; CLR -(SP) ;OPEN DEFAULT SMP IN [1,1] ; MOV #SMLDEF,-(SP) ; OPEN ; BVS 12$ sys s_open,SMLDEF,0 BCS 5$ MOV R0,-(SP) ;OPEN WORKED, PUSH FILE ID CALL BUFBGN ;ALLOCATE INPUT BUFFER MOV #BUFROL,R0 MOV ROLBAS(R0),R0 MOV (SP),(R0)+ ;PUT FILE ID IN FIRST WORD CLR (R0)+ ;CLEAR REST OF HEADER CLR (R0)+ CLR (R0)+ MOV (SP)+,SMLLNK BR 1$ 12$: TST (SP)+ BR 5$ .IFTF 4$: ERROR U 5$: CLR SMLCNT ;MAKE SURE COUNT IS ZAPPED CLR ENDFLG ;DITTO FOR END FLAG RETURN .IFT SMLERX: BR SMLERR .IFTF SMLTST: ;TEST MCALL ARGUMENTS 1$: GSARG ;FETCH NEXT ARGUMENT BEQ 3$ ; EXIT IF THROUGH MSRCH ;OK, TEST FOR MACROS BNE 2$ ; FOUND, NOT INTERESTED INSERT ;INSERT WITH ZERO POINTER INC SMLCNT ;BUMP COUNT 2$: CRFDEF ;CREF IT BR 1$ 3$: MOV SMLCNT,R0 ;FINISHED, COUNT TO R0 RETURN ; ENTIMP IMPPAS ; BLKW SMLCNT ;MCALL HIT COUNT ; XITIMP IMPPAS .IFT ; ENTIMP IMPURE ; ; BLKW SMLLNK ; BLKB SMLFIL,38. ; ; XITIMP IMPURE ENTSEC TXTBYT SMLLOC: .ASCIZ /sysmac/ SMLTXT: .ASCII /sml/ SMLDEF: .ASCIZ "/lib/macro/sysmac.sml" XITSEC .ENDC ;XSML .ENDC ;XMACRO ; FIN ENTSEC XCTPRG JMP XCTPAS ; LAST THING TO DO IS INIT FOR PASS ENTSEC XCTPAS JMP XCTLIN ; LAST THING TO DO IS INIT FOR LINE ENTSEC XCTLIN RETURN ; JUST RETURN WHEN DONE ENTSEC SWTSEC SWTTOP: ENTSEC EDTSEC EDTTOP: ENTSEC CNDSEC CNDTOP: ;TOP OF CONDITIONAL ROLL XITSEC ;BE NEAT ; .ENTRY DMACRO,ASS ; .ENTRY DMACRO,BIGASS .END DMACRO dmacro.mac0000600002565200256520000000057402141527064011130 0ustar jncjnc.TITLE DELPHI MACRO (MAY 1974) .SBTTL HEADER FILE -- ASSEMBLY PARAMETERS XOVLAY=0 XRUN=0 XRESKB=0 ;DON'T USE RESIDENT KEYBOARD XZERR=0 ;NO Z ERRORS XEDABS=0 ;.ENABL ABS MAKES NO SENSE WITH DELPHI OBJECT MODULES. PDPV45=0 ;ASSEMBLE FOR PDP 11/45 .INSRT dma1 .INSRT dma2 .INSRT dma3 .INSRT dma4 .INSRT dma5 .INSRT dma6 .INSRT dma7 .INSRT dma8 .INSRT dma9 objmod.mac0000600002565200256520000000136102141527064011130 0ustar jncjnc ; FORMAT OF OBJECT MODULE DIRECTIVES. S.NEXT=0 ;HASH LINK FOR ALL SYMBOL DECLARATIONS S.NAME=2 ;PTR TO SYMBOL NAME S.CMD=4 ;TYPE OF DIRECTIVE (BYTE) S.ATT=5 ;ATTRIBUTES S.EXT=1 ; EXTERNAL S.ISPC=2 ; I SPACE S.PURE=4 ; PURE S.ABS=10 ; ABSOLUTE S.DEF=20 ; DEFINED CS.LENGTH=6 ;CSECT LENGTH CS.ADDR=10 ;ADDRESS CS.L=4 ;# OF BYTES IN OBJECT MODULE DECLARATION ST.TABLE=6 ;ST PREVIOUS TABLE ST.L=4 SY.VAL=6 ;VALUE OF SYMBOL SY.CS=10 ;CSECT SY.TABLE=12 ;SYMBOL TABLE SY.L=10 EN.VAL=6 ;VALUE OF ENTRY POINT EN.CS=10 ;AND CSECT EN.L=16. ;LOTS OF SPARES AT END. C.CS=1 ;NUMBERS OF VARIOUS COMMANDS C.ST=2 C.SYM=3 C.ENTRY=4 C.END=5 C.MIXID=6 C.TXT=21. C.TXTR=22. C.ABS=23. C.REL=24. C.ABSX=25. C.RELX=26. C.LCS=27. C.LCSX=28. pst.mac0000600002565200256520000002063702266374550010503 0ustar jncjnc ; PERMANENT SYMBOL TABLE FOR DMACRO .CSECT PST,DPURE .GLOBL PSTBAS,PSTTOP ; POINTERS TO SYMBOL TABLE DR1= 200 ;DESTRUCTIVE REFERENCE IN FIRST FIELD DR2= 100 ;DESTRUCTIVE REFERENCE IN SECOND FIELD REGFLG=1 ; REGISTER FLAG DEFFLG=10 ; DEFINED FLAG DFLGEV= 020 ;DIRECTIVE REQUIRES EVEN LOCATION DFLGBM= 010 ;DIRECTIVE USES BYTE MODE DFLCND= 004 ;CONDITIONAL DIRECTIVE DFLMAC= 002 ;MACRO DIRECTIVE DFLSMC= 001 ;MCALL .GLOBL WRDSYM,DFLCND,DFLGEV,DFLGBM,DFLMAC,DFLSMC .MACRO OPCDEF NAME, CLASS, VALUE, FLAGS, COND .IF NB, .IF DF COND .MEXIT .ENDC .ENDC POINT NAME .BYTE FLAGS+0 .GLOBL OPCL'CLASS .BYTE 200+OPCL'CLASS .WORD VALUE .ENDM .MACRO DIRDEF NAME, FLAGS, COND POINT .'NAME .BYTE FLAGS+0, 0 .IF NB, .IF DF COND .WORD OPCERR .MEXIT .ENDC .ENDC .GLOBL NAME .WORD NAME .ENDM .MACRO REGDEF NAME,VALUE POINT NAME .BYTE DEFFLG!REGFLG,200 .WORD VALUE .ENDM .MACRO POINT SYMBOL ;; GENERATES NEW FORMAT SYMBOL TABLE COUNT = 0 ;; CHAR = SYMBOL(COUNT) .CSECT TXTBYT,DPURE ;; ENTER ASCIZ CSECT .PTR = . ;; SAVE POINTER TO BEGINNING OF SYMBOL .IRPC CHAR,SYMBOL ;; LOOP THROUGH ALL THE CHARACTERS IN SYMBOL COUNT = COUNT+1 ;; INCREMENT CHARACTER COUNT .IF EQ,COUNT-1 ;; IF FIRST CHARACTER THEN CHAR1 = <''CHAR!40>*400 ;; SHIFT AND LOWER CASE AND REMEMBER IN CHAR1 .IFF ;; ELSE .IF EQ,COUNT-2 ;; IF SECOND CHARACTER THEN CHAR1 = CHAR1!''CHAR!40 ;; LOWER CASE AND REMEMBER IN LOW BYTE OF CHAR1 .IFF ;; ELSE .BYTE ''CHAR!40 ;; PUT IT IN TXTBYT AREA .ENDC .ENDC .ENDM ;; END OF LOOP .CSECT PST ;; ENTER PST ROLL .IF LE,COUNT-2 ;; IF SYMBOL LENGTH <= 2 THEN .WORD 0 ;; CREATE A NULL POINTER TO SYMBOL .IFF ;; ELSE .WORD .PTR ;; CREATE A REAL POINTER .CSECT TXTBYT ;; RE-ENTER TXTBYT .BYTE 0 ;; TO MAKE SYMBOL ASCIZ .CSECT PST ;; AND BACK TO ROLL .ENDC .WORD CHAR1 ;; SECOND WORD IN ROLL IS SWAB OF FIRST TWO CHARS .ENDM PSTBAS: ;BASE DIRDEF , DFLGBM DIRDEF , DFLGBM DIRDEF DIRDEF DIRDEF , DFLGEV DIRDEF , DFLGBM DIRDEF .IF DF YPHASE DIRDEF .ENDC DIRDEF DIRDEF DIRDEF DIRDEF , DFLCND DIRDEF , DFLMAC, XMACRO DIRDEF , DFLMAC, XMACRO DIRDEF DIRDEF DIRDEF DIRDEF DIRDEF , DFLGEV, XFLTG DIRDEF , DFLGEV, XFLTG DIRDEF DIRDEF , DFLCND DIRDEF , DFLCND DIRDEF , DFLCND DIRDEF , DFLCND DIRDEF , DFLCND DIRDEF , DFLCND DIRDEF , DFLCND DIRDEF , DFLCND DIRDEF , DFLCND DIRDEF , DFLCND DIRDEF , DFLCND DIRDEF , DFLCND DIRDEF , DFLCND DIRDEF , DFLCND DIRDEF , DFLCND DIRDEF , DFLCND DIRDEF DIRDEF DIRDEF DIRDEF , DFLMAC, XMACRO DIRDEF , DFLMAC, XMACRO DIRDEF DIRDEF , DFLMAC, XMACRO DIRDEF , DFLMAC, XMACRO DIRDEF , DFLSMC, XSML DIRDEF , , XMACRO DIRDEF DIRDEF , , XMACRO DIRDEF , , XMACRO DIRDEF DIRDEF DIRDEF , , XMACRO DIRDEF DIRDEF .IF DF YPHASE DIRDEF .ENDC DIRDEF DIRDEF DIRDEF , DFLGEV DIRDEF DIRDEF DIRDEF , DFLMAC, XMACRO DIRDEF DIRDEF WRDSYM: DIRDEF <WORD >, DFLGEV OPCDEF <ABSD >, 01, 170600, DR1, X45 OPCDEF <ABSF >, 01, 170600, DR1, X45 OPCDEF <ADC >, 01, 005500, DR1 OPCDEF <ADCB >, 01, 105500, DR1 OPCDEF <ADD >, 02, 060000, DR2 OPCDEF <ADDD >, 11, 172000, DR2, X45 OPCDEF <ADDF >, 11, 172000, DR2, X45 OPCDEF <ASH >, 09, 072000, DR2, X45 OPCDEF <ASHC >, 09, 073000, DR2, X45 OPCDEF <ASL >, 01, 006300, DR1 OPCDEF <ASLB >, 01, 106300, DR1 OPCDEF <ASR >, 01, 006200, DR1 OPCDEF <ASRB >, 01, 106200, DR1 OPCDEF <BCC >, 04, 103000, OPCDEF <BCS >, 04, 103400, OPCDEF <BEQ >, 04, 001400, OPCDEF <BGE >, 04, 002000, OPCDEF <BGT >, 04, 003000, OPCDEF <BHI >, 04, 101000, OPCDEF <BHIS >, 04, 103000, OPCDEF <BIC >, 02, 040000, DR2 OPCDEF <BICB >, 02, 140000, DR2 OPCDEF <BIS >, 02, 050000, DR2 OPCDEF <BISB >, 02, 150000, DR2 OPCDEF <BIT >, 02, 030000, OPCDEF <BITB >, 02, 130000, OPCDEF <BLE >, 04, 003400, OPCDEF <BLO >, 04, 103400, OPCDEF <BLOS >, 04, 101400, OPCDEF <BLT >, 04, 002400, OPCDEF <BMI >, 04, 100400, OPCDEF <BNE >, 04, 001000, OPCDEF <BPL >, 04, 100000, OPCDEF <BPT >, 00, 000003, , X45 OPCDEF <BR >, 04, 000400, OPCDEF <BVC >, 04, 102000, OPCDEF <BVS >, 04, 102400, OPCDEF <CCC >, 00, 000257, OPCDEF <CFCC >, 00, 170000, , X45 OPCDEF <CLC >, 00, 000241, OPCDEF <CLN >, 00, 000250, OPCDEF <CLR >, 01, 005000, DR1 OPCDEF <CLRB >, 01, 105000, DR1 OPCDEF <CLRD >, 01, 170400, DR1, X45 OPCDEF <CLRF >, 01, 170400, DR1, X45 OPCDEF <CLV >, 00, 000242, OPCDEF <CLZ >, 00, 000244, OPCDEF <CMP >, 02, 020000, OPCDEF <CMPB >, 02, 120000, OPCDEF <CMPD >, 11, 173400, , X45 OPCDEF <CMPF >, 11, 173400, , X45 OPCDEF <COM >, 01, 005100, DR1 OPCDEF <COMB >, 01, 105100, DR1 OPCDEF <DEC >, 01, 005300, DR1 OPCDEF <DECB >, 01, 105300, DR1 OPCDEF <DIV >, 07, 071000, DR2, X45 OPCDEF <DIVD >, 11, 174400, DR2, X45 OPCDEF <DIVF >, 11, 174400, DR2, X45 OPCDEF <EMT >, 06, 104000, REGDEF <F0 >, 0 REGDEF <F1 >, 1 REGDEF <F2 >, 2 REGDEF <F3 >, 3 REGDEF <F4 >, 4 REGDEF <F5 >, 5 OPCDEF <HALT >, 00, 000000, OPCDEF <INC >, 01, 005200, DR1 OPCDEF <INCB >, 01, 105200, DR1 OPCDEF <IOT >, 00, 000004, OPCDEF <JMP >, 01, 000100, OPCDEF <JSR >, 05, 004000, DR1 OPCDEF <LDCDF >, 11, 177400, DR2, X45 OPCDEF <LDCFD >, 11, 177400, DR2, X45 OPCDEF <LDCID >, 14, 177000, DR2, X45 OPCDEF <LDCIF >, 14, 177000, DR2, X45 OPCDEF <LDCLD >, 14, 177000, DR2, X45 OPCDEF <LDCLF >, 14, 177000, DR2, X45 OPCDEF <LDD >, 11, 172400, DR2, X45 OPCDEF <LDEXP >, 14, 176400, DR2, X45 OPCDEF <LDF >, 11, 172400, DR2, X45 OPCDEF <LDFPS >, 01, 170100, , X45 OPCDEF <MARK >, 10, 006400, , X45 OPCDEF <MFPD >, 01, 106500, , X45 OPCDEF <MFPI >, 01, 006500, , X45 OPCDEF <MFPS >, 01, 106700, OPCDEF <MODD >, 11, 171400, DR2, X45 OPCDEF <MODF >, 11, 171400, DR2, X45 OPCDEF <MOV >, 02, 010000, DR2 OPCDEF <MOVB >, 02, 110000, DR2 OPCDEF <MTPD >, 01, 106600, DR1, X45 OPCDEF <MTPI >, 01, 006600, DR1, X45 OPCDEF <MTPS >, 01, 106400, DR1, OPCDEF <MUL >, 07, 070000, DR2, X45 OPCDEF <MULD >, 11, 171000, DR2, X45 OPCDEF <MULF >, 11, 171000, DR2, X45 OPCDEF <NEG >, 01, 005400, DR1 OPCDEF <NEGB >, 01, 105400, DR1 OPCDEF <NEGD >, 01, 170700, DR1, X45 OPCDEF <NEGF >, 01, 170700, DR1, X45 OPCDEF <NOP >, 00, 000240, REGDEF <PC >, 7 REGDEF <R0 >, 0 REGDEF <R1 >, 1 REGDEF <R2 >, 2 REGDEF <R3 >, 3 REGDEF <R4 >, 4 REGDEF <R5 >, 5 REGDEF <R6 >, 6 REGDEF <R7 >, 7 OPCDEF <RESET >, 00, 000005, OPCDEF <ROL >, 01, 006100, DR1 OPCDEF <ROLB >, 01, 106100, DR1 OPCDEF <ROR >, 01, 006000, DR1 OPCDEF <RORB >, 01, 106000, DR1 OPCDEF <RTI >, 00, 000002, OPCDEF <RTS >, 03, 000200, DR1 OPCDEF <RTT >, 00, 000006, , X45 OPCDEF <SBC >, 01, 005600, DR1 OPCDEF <SBCB >, 01, 105600, DR1 OPCDEF <SCC >, 00, 000277, OPCDEF <SEC >, 00, 000261, OPCDEF <SEN >, 00, 000270, OPCDEF <SETD >, 00, 170011, , X45 OPCDEF <SETF >, 00, 170001, , X45 OPCDEF <SETI >, 00, 170002, , X45 OPCDEF <SETL >, 00, 170012, , X45 OPCDEF <SEV >, 00, 000262, OPCDEF <SEZ >, 00, 000264, OPCDEF <SOB >, 08, 077000, DR1, X45 REGDEF <SP >, 6 OPCDEF <SPL >, 13, 000230, , X45 OPCDEF <STCDF >, 12, 176000, DR2, X45 OPCDEF <STCDI >, 12, 175400, DR2, X45 OPCDEF <STCDL >, 12, 175400, DR2, X45 OPCDEF <STCFD >, 12, 176000, DR2, X45 OPCDEF <STCFI >, 12, 175400, DR2, X45 OPCDEF <STCFL >, 12, 175400, DR2, X45 OPCDEF <STD >, 12, 174000, DR2, X45 OPCDEF <STEXP >, 12, 175000, DR2, X45 OPCDEF <STF >, 12, 174000, DR2, X45 OPCDEF <STFPS >, 01, 170200, DR1, X45 OPCDEF <STST >, 01, 170300, DR1, X45 OPCDEF <SUB >, 02, 160000, DR2 OPCDEF <SUBD >, 11, 173000, DR2, X45 OPCDEF <SUBF >, 11, 173000, DR2, X45 OPCDEF <SWAB >, 01, 000300, DR1 OPCDEF <SXT >, 01, 006700, DR1, X45 OPCDEF <TRAP >, 06, 104400, OPCDEF <TST >, 01, 005700, OPCDEF <TSTB >, 01, 105700, OPCDEF <TSTD >, 01, 170500, , X45 OPCDEF <TSTF >, 01, 170500, , X45 OPCDEF <WAIT >, 00, 000001, OPCDEF <XOR >, 05, 074000, DR2, X45 PSTTOP: ;TOP LIMIT .END �������������������������������������������������������������������������������������������������unix.mac��������������������������������������������������������������������������������������������0000600�0025652�0025652�00000002655�13044135240�010643� 0����������������������������������������������������������������������������������������������������ustar �jnc�����������������������������jnc��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.macro sys type,arg1,arg2,arg3 .word trap+type .if nb arg1 .word arg1 .endc .if nb arg2 .word arg2 .endc .if nb arg3 .word arg3 .endc .endm s_indir = 0 s_exit = 1 s_fork = 2 s_read = 3 s_write = 4 s_open = 5 s_close = 6 s_wait = 7 s_creat = 8. s_link = 9. s_unlink= 10. s_exec = 11. s_chdir = 12. s_time = 13. s_mknod = 14. s_chmod = 15. s_chown = 16. s_break = 17. s_stat = 18. s_seek = 19. s_getpid= 20. s_mount = 21. s_umount= 22. s_setuid= 23. s_getuid= 24. s_stime = 25. s_ptrace= 26. s_fstat = 28. s_smdate= 30. s_stty = 31. s_gtty = 32. s_nice = 34. s_sleep = 35. s_sync = 36. s_kill = 37. s_switch= 38. s_dup = 41. s_pipe = 42. s_times = 43. s_profil= 44. s_setgid= 46. s_getgid= 47. s_signal= 48. s_ttymod= 49. .MACRO SYS TYPE,ARG1,ARG2,ARG3 .WORD TRAP+TYPE .IF NB ARG1 .WORD ARG1 .ENDC .IF NB ARG2 .WORD ARG2 .ENDC .IF NB ARG3 .WORD ARG3 .ENDC .ENDM S_INDIR = 0 S_EXIT = 1 S_FORK = 2 S_READ = 3 S_WRITE = 4 S_OPEN = 5 S_CLOSE = 6 S_WAIT = 7 S_CREAT = 8. S_LINK = 9. S_UNLINK= 10. S_EXEC = 11. S_CHDIR = 12. S_TIME = 13. S_MKNOD = 14. S_CHMOD = 15. S_CHOWN = 16. S_BREAK = 17. S_STAT = 18. S_SEEK = 19. S_GETPID= 20. S_MOUNT = 21. S_UMOUNT= 22. S_SETUID= 23. S_GETUID= 24. S_STIME = 25. S_PTRACE= 26. S_FSTAT = 28. S_SMDATE= 30. S_STTY = 31. S_GTTY = 32. S_NICE = 34. S_SLEEP = 35. S_SYNC = 36. S_KILL = 37. S_SWITCH= 38. S_DUP = 41. S_PIPE = 42. S_TIMES = 43. S_PROFIL= 44. S_SETGID= 46. S_GETGID= 47. S_SIGNAL= 48. S_TTYMOD= 49. �����������������������������������������������������������������������������������run�������������������������������������������������������������������������������������������������0000700�0025652�0025652�00000000171�13044115327�007721� 0����������������������������������������������������������������������������������������������������ustar �jnc�����������������������������jnc��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������macro dmacro macro pst bind macro dmacro pst relld -r macro.rel macro.o ld -n -s macro.o mv a.out macro chmod 755 macro �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������macro�����������������������������������������������������������������������������������������������0000700�0025652�0025652�00000047144�13044134674�010237� 0����������������������������������������������������������������������������������������������������ustar �jnc�����������������������������jnc��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������@0���������_��„æ ÆE�À^7`RÀe�7ZR7XY�‰xY;‡ÿ•ÿÿHR÷ °/Á�±ŒB±²B1ŠÙBÁ Á ÷÷ –/„Ô Ô Å(EÕ• �� ÿÿ”þõ• �ÿÿöõ• �ÿÿW! EƒæžY÷ �÷ �÷ ”�÷ 4÷ ¸�Ál@÷ Þ�‰æµY÷ Üö÷(ExDÁ€D†D÷ €(÷ÎCÐCÀ¶L÷ Â�æÖYw�¦ÀÀF÷ °�û÷ VLÁ6M¶L÷ T(÷ ’C÷°Dæ¶LæÓY÷ �‰¶L¶†æ¶Læ[Zw�f7„H‡�‡�€�¢.�Ћûð•.�ÿÿ�P”P”P”ŠŽŽ‡�Ћõ÷ üBÁZÂN÷ ä'ÁêB÷ ¶ÁZ÷ Ô' ŠÁN÷ æ‡�BÊ €‰É ù‡�á ÷ ˜%Ñ ÷ŽC¨O÷ "#W¡ �bW¡-� Q‘÷ #W¡ �[W¡ �XQ‘ö÷ #÷ Œ!W!:�÷rOnO÷ ú"õµp�ÖA÷ ê"ù÷ XO÷ Ú%À�÷ 4$4ÂNÒ• �÷ Ê"õµp�ÖAR‘øõ‹ÖAõµ�ÖAW¡:�ì÷OúB Š÷NO÷ ˆ"7 ŽO7 ¨O· B÷ü@ü@7 ö@f÷ Î÷ ðAÅ]lOšæ(Zw��� ‡� Š÷ÐN²B€‡�÷ w�þ÷ Ø÷ úw�þ÷–B°N÷ *"W¡ �æ8Zw�ÔÿÁ6MQ‘÷ "W¡ �Q‘ù Š ÷‚NdB‡�À��÷ ®#÷ �· *@÷ Þ,÷   ÷ @÷ ¬Aæ¶LæXZ÷ .þ‰¶L¶†æ¶Læ[Zw�xÿ7èN÷¢DˆA÷ �÷ 0÷ (÷ ¼÷ Nö÷ f‡�÷(EðA7 AÀÀF÷ Hþ÷ A÷-ü@®?ò·òM‡�æÀFævZ÷ ¼ý‰ÀF��&†æÀFæyZw�ÿÀ���ŒB   · .C7 ¸M· ¸M‡�€�Žf¦æ&&Ä��ŒBÀX Ô  'Ì þ ��1÷ ìL÷ pM· nM(÷ dM�úÿ‰÷ èÝ7ˆU÷e�‚U�úÿ�‰|YŒ ÀÃ�×&Î`ƒ …—Q‘¾ ��W¡ �‡W¡ �ƒÀ Èä¤Ö „ƒ‚‡�÷ r7@‡�÷ Ü"÷ V+ÀúL7`öL÷ÿÿòL7 êL7 ìL7 ìL÷ Œ>7 ÖLÂN·TM÷jPPM÷ >M_ÁLqÁFG· ¼LæDG÷ øþ÷ ¦LÀ���ŒB‰7 B÷ |þ÷]ŒL†LÈ÷U�M Š(D D` Š™W! � ‚W! �‡W! �õ· dLòR‘E”@ÖA À5@�ø÷5€�ˆ?Åå �ñJ‘÷U �´LÅ€�é÷:I,?÷5�d?7Š,I÷NL÷ ˆ÷ LˆÀ�L� ‡�ÁN! ! áXæN÷ <þ÷ êK7 äK· ÚK×Q$Ñ ¬÷ B�ý€˜ ƒÿ*ƒfÁKÑ ƒ� ×-KƒÿÀKÂ÷ �ý~â‹ãwüJ÷U�L±Á5�AðÿÑ — jPƒ÷U@�øKâ‹R”‡�÷ ª#w�rþ÷ F!7 Lõ‹ÖA÷U�ÖK& ÷T>^H÷ þ<K÷ ÄK+÷‹ž?EÎ�÷5�ºK ÷ d>5÷5�X>÷K¦K÷5�J>÷N˜K÷‹§<÷5�6>÷E�€K÷=*>zK ÎI?÷5�>Á[ÂâM÷ Ì"Ò• �÷ † Š·“)?ÁâM÷ Þ÷NBK÷jP>K÷ Þ·“ ?L?Š0KÂâMÒ Â%Nû÷5�Æ=YÁÞQÉ ÂäM÷ J ÁâQÉ ÂëM÷ (É5�?Ê•'�É5@�Ê•G� ÂâMÀVQH H÷5�v=÷ ·FJÒ• �· >JûƒÂâM÷ Þ�ÂòMÁ¦J÷ "ÁâM÷ 0?Š–J÷ °J÷ 2÷5$�0=¥óÖ À�÷ ‚Àâ<7 à<ƒ7Ú<‡�ÂâM÷ Ž�ÀVQH H÷5�ø< „÷ ŒÀéM ˜Ê• �„ û‚ÂéMÒ• �ÁÞQ÷5�Ð<É ÷ \Ò• � ÁâQ÷5�¶<¯Ä�É ÷ .É5�?Ò•'�É5@�ò•G�ÿÿÒ• � Ä ™÷ öIø÷ xæÀÂIÀE�· 8<ÁYÑ‹7 ¬I†R’@’÷ ¶÷ ¢÷ ž7 ;7 ;÷�°I÷ àêé‡�ÀIÀ]I?÷ þW!:�cW!=�w�L÷ ÷ °w�¸!÷ ^÷ ¢w�žÂ �÷ €W!$�÷ $W!:� À¢;Àí IÀ5�ÿ÷U�I÷ PC÷ øõ‹ÖAÁjTÂ@C÷ j Ø÷ �À5�Ò÷U�ðH ‡�÷ j õµ�ÖA÷ Öõµ0�ÖAú÷ ¼W!=� W!:�÷ ¨è÷ ¾À&:€� ‡�7 ²H×-:�.8÷ ÷ º÷ â · ˜H÷ ÒË5�Àò:ÀEß�ÀU �÷ ~H ÷5�(;÷5 � ;ÀU€� PÌÌ:Ë5�Ì-À:Ê­¹:÷U�8HËU�÷ î÷ @÷U�$H÷ ÷”G(Hw�”þ÷ ÷ ÁDCff÷ Ú‘‘÷5�@øG$÷ ÷ <ËU�÷5 �¦:ËU€�æ&÷ þŒËE¿ÿ‹UW,��.÷ € ·¢5:70:÷U€�®G÷ þ ‡�ÄDC ÂDDÁ5€Ê5�Š ÷U�ˆGÁ5�· ‚GÁ &  ^�÷þˆG÷ wwGÁ�ÁE€ÿw\GÁ Á & fz@Ö Ax@fÎ�ÁE�ÿ÷ Î� ñ ² wŒCGÀ Ίý� Áö71P�Ö ê‡�‡�÷ þÀ5øÿ÷U�GÀEøÿ‡�÷ Ô÷­s8o9Àíj9€ ‡À  ÷U�ÞFÀÿ�ÀE�ÿ‡�÷ &÷ „· ÊF÷ l—¢€�Ö �‡�À�÷ Ä÷ PË�€Î�Œ÷ D� ‡�÷ €ÿÃüÿ÷ Œÿ�� ÷ nÃøÿ÷ dÃÀÿÀ0÷U� jFÀ@‡�÷ Â÷ ¬· |F& À´@÷ `2H�Î ÷U�BFÎU�ò÷% �8F÷ Z÷ ôÎU�SW!(�÷ ª�ÎU �P÷ ¤�W!+�÷ øÎU�FÎ5�ÎU�@ 5÷ Ô÷ °W!(�Ë5�3Î ÷5�’8Ë5@�·¢=8÷5�|8ÎU�ÎU7�÷ x�Ë5�÷U�œEËE�ffff÷ �¡¡¡¡PÎU0�÷ $�÷ � €U‡�÷ ^÷ RþW!)�w�P÷U�XE‡�÷ ²÷ œÁ›Z˵@�2Q¤Ëµ �1Ñ‹·¢¯7-÷ Ž÷ xÁ¡Z˵@� Q¤·¢“7Ñ‹Ê‹Ñ‹� €Ò&À À €eÀ ÀmÌ57p67n6 À6€ À Àmb7 à7 \6Ì Ñ‹÷5�–7É‹ ·¢C7W ¡Z†W ¡Z†÷U�´DJ’÷ ²DÔ‹�“€ —¢�—¢ �÷ Š ŠÊÕ€�‡�÷ ü÷ ¨÷5�ô5÷U@�ì5÷ ,÷ ¾ ï÷U�bDë‡�÷ Œ · ÎC÷ øþ÷ r ×­Á5�÷²6²5÷®6®5Á@CÂPDw�˜÷ ”÷ ~�÷SZ’5÷ .Ž5÷ ~÷ –÷ ÷ `�À �÷ r÷5o5÷U#�f5w@b5·P^5÷ ž Á=T5B Â]L5‚ ÷U�ÈC÷ ì ÷  Á@CÂ>D÷ w�"  Ä  Ð  &ÀHC&&&&· ¬C÷ �·t8À �÷ ÜÁ]ð4Â]î4ñ÷U�jCíÀ@C€B0÷U�PC‡�÷ šÿ7 ¼4÷� ¸4Ê·,8‡�·$8‡�Â:F÷ õ‹ÖAR‘— ºF†÷ ö Š‡�÷ ¢9÷ Â÷ ®ý÷ ( ×­w4�÷h5h4÷d5d4×=èB�@÷�Z4ÁHCffff÷ b÷ R÷ Â÷6484÷2444·*4·(4·*4·(4À�÷ P‡�Æe�÷U�”B‡�÷ îÁ>DÂ@C÷ ôÀ �÷ ð÷ æw�0÷   ä� ÷ w� ÷ ä÷U�RB‡�÷ J÷¾3Ô4÷º3Ð4÷ &²EŠJ‘Ò‹÷ 0— Fø‡Á F¡˜þÉ• �w‚6 ‡�ÂlQ÷ >3 R‘8÷ — «Qù‡â‹÷÷5� ¦4-÷‹Ê5*ÁÂZ÷ X÷ Æ÷ ÜW½ÖAp�úÂDAÀTA÷ �â•-�ÀDA÷ �â• �w�FÄ�â• �� r �Áe0�J ‡�÷ ö�7 ²AÂ`DÀ�÷ ÌÒö2— dD÷‡Ò�À�÷ ~‡�÷U�`A÷U�XA÷ h÷ ÷ r‡�C÷U�>A‡�÷ <Å ÷ Fõ÷ ¬óù‡�C!ôw�ƒ ÷ ÔŒ ÷  `ƒ ý‡‡�Š ÊE�‡�ÊU�‡�ÂŒ@÷ �†@÷ Ú � �÷U�Ü@€7j@w�úƒ ƒ ¦÷ \÷ |÷ hû÷ ` Ê`õŠ÷‹Ï17 $27 "2÷ Lû÷ D ‡�ƒ ƒ à ÷ „�BW!<�÷ ˆ@B!à ÷ ˆ÷ 4�ó÷ \õ‹ÖAé÷U�\@� à & €Á Î÷ �ð&÷ *Œ÷ �éà € (�‡÷U� ,@&�÷ (€e  W � ÷ ¼ú÷ ´  ‡�ƒ ƒ à ÷ ’¤æì@Þ ÷U�î?ÂÁpDL÷ ˆ „~î· à?· Ü?÷ 2æF?ÃpDÄxD! W hDü‚÷A�Z2Å%+�Å%-�÷�€B2÷ ¤õµ�ÖAË5�ø· 02 ÷ b÷ ŠÅå0�bab b b ÷m22 äÅ%.�w 2ÞÅ%E�Å%e� ÷ Bæà>÷ �Ú>÷ (·Ò>7`Ü1Á@@T@T@Th÷ Ì11×"3‚÷ ö�· ¼1÷ Ð�÷e�°1÷ ª1ì÷ ¦1÷ Ë ú€æ �÷ ê�÷ �Î5�÷ Ü�÷ Ø�÷ Ô�÷ ¾�Î óÖ ÷å�p1· j1Ì÷ f1÷ Ä�û†÷e€�Z1÷‹U1÷U�¨>á b(J’Ê�ƒ û÷ Œ� ÷5�N1ÂŒ> ‚  òUÿpD±�r pD  ûË €÷U� b>Ëmü07 Ô/7 \>÷Î/€7Â= Àw�8×"Ì̇÷ 0�· Ø0÷ B�÷ $�÷ �÷ 4�÷ $�÷ �¢l�a þ‡ƒ ù‡�¡�Á    ‡�â b b b ‡�Áw�T÷ ØW¡ �÷U�Ö=‡�ÁÀFÂ6MQ‘R‘÷ ÈÅ‹Q‘R‘W @Gí†ö Š Š÷ ¢‰ÀF��†æÀFævZ÷ ðì‰ÀF��†ÀÖZÁ�ÂÂP”B~ÁÀF÷ ð‰ÂP��†÷U�j=‡�&÷ L�À���ŒB   · Ì<‡�÷ |.w�\ÿ÷ 4 W! �÷U�0=‡�÷ . Å‹W �ô†÷÷ ‡�À��÷ ¾À��ŒB�²BÂåþ�  ý‚‡�Ã��ÁŒBÀ²BBÂeþ�‘€ ý‡óåþ�²B‡�÷ ¤�à Å%,�÷ ÆÁ6<÷ °÷5�j/w¸<7 È<w�$ó )÷..÷ p�÷ f�ÁdQW"�*‰ à ! à ! Ã<à <C ÷ <÷ ü;à 7 ö;ÁdQÉ É á á ÷5��/ ÀR<7J<÷U�><‡�÷U�.<‡�÷ žÀ�÷ € Á”- ƒ Á ÷ ¦;÷ žI�÷U�< ‡�÷ æ C ‡�÷ Ü üú÷ Ô øö÷ -ôòÁ  ÷ \ ä÷ ô÷ � ÷5�:-@  ƒC BW!&�W!!�B ÷ ’äÁ C ‡�C à ƒ ÷ ÷ ¤;'· ž;÷  À�÷ Ô ±�B ~÷ ä-·P.·0. ·@ .—0�€÷`.÷ �à €·Pô-Ö÷U�6;‡�· ¶:÷U�2;‡�C ÷ ˜ À�÷ x ±�B ~÷ ˆ-·PÈ-·0Â-ë·@º-à ·P²-æf,Ã Þ à÷U�à:‡�÷ P À$�÷ 0 Â� ~ƒPòà Ã÷ÿ÷~-‡�÷U�®:‡�·Šº:÷ t-E÷ þÂj-÷ `-ÁwV-÷ v�Á�R÷-L-: †Á�÷ b�· <-7 :-ó÷-4-ð9†Á�÷ H�· $-õÁ[À-€ Ñ­j:ü€ †ÁåóZ÷ &�÷ ¢⥠�ýÒ‹Á::€ÁU�ÁU�R·è,7Š&:‡�Â%E‚÷ �¢DR‡�Ò• �À":‰¢D„�7 ¾,‡�÷`,ú9÷Õ@�õ9÷V,ð9‡�÷N+ê9÷Õ@�å9÷D+à9‡�É À � fA�Ê•�Á RŒÀ� fAœ�À �Á�Œ¡� À�À�Àe�Ê•�Á JŒÀŠüÒ‹À� ~‡�&€�7A÷ÿÿA· AЋüÀ��‰‚Y€Ž‡�¦�÷ Òÿö[�w�Èÿ÷  ö÷ B÷ ^*w�Ä÷  ë÷ .û÷ ò,w�¤æ¶Læ [÷ \艶L¶†æ¶Læ[Zw�¦é7Ö3·Â,÷ L& & & °,Ã�÷ ~F÷X+>*÷T+:*÷ €Á:F÷  ÷ ¤-÷ œ-Á [Ã�÷ L7 Â8 À �÷ Þ &ÁDCEÉ�W1 �ÉU�W1�ÉU�W1�ÉU�W1@�ÉU�Ã�÷ Ñ Ã�÷ ø�÷ „ Õ7 f8À�÷ „ =×=ª)@�×=¢)€�ò×=˜)�Å’)Ã:87Š)À�÷ ¶ w~)÷&8„ ÁDCEÉ�W1@�ÉU�W1�ÉU�Ã�÷ „�ÁFCÉÿÿŠÅ�aÃ�÷ n�÷ ~�¾7 Þ7À�÷ ü ÷ ¤�øÁPDW,�� Ä@CTT Ô� TT÷ €�Á[Ã�÷ &�÷ |À�÷ ‚ 7 7À �÷ ® 7 Ö(÷  ö‡�¦Î`—%˜Pƒ÷ LR”Â~‡�f— šP‡÷ :Ò§(Ò¢(Áš(Š÷ �‡�— ˜P‡÷ R”ø‡�÷ �ÂÔ*‡�÷ V Äq(ÄE€ÿ[ÄŒ†×-b(�>7 \()ÄŒ†ÁJCfffæî6À �÷ 4 ·â6‘‘‘À 70(ÄŒ†ÁHCffæÄ6À�÷ $ À (·´6‘‘êÁHCÉ�Ã�÷ $ÿ÷ì'æ'÷è'â'÷ (ÿ·:*‡�Â,)÷ VüÁ)[ÂlQ÷  ÿ• �°*· ¬*?Š¨*÷ ¤*÷ *÷ `÷‹ *_÷5�@Ø([7  57 @6ÂN÷ ’�À�÷ V ,ÁECÉ¥�a¨÷ VüÁ%[÷ d Ò• �ÃFA÷ x�ÁDCÉ5�÷ üÁ[÷ @ ÷ \�÷ X�÷ T�Ò• �÷ vþ÷ 2�Ï7 Ò5÷ (�À �÷ ì ÁCC÷ ôûÒ• �ÁFC÷ ÔûÒ• �÷ Bþê ŠÁN÷ ÷�ò4ÂN‡�À÷4Ü&À�‡�À�÷  ‡�À�÷ – ú÷ ¢   Äݵ&… ÷ f&&· H5÷ :û÷ JûÄŒ÷ ö(÷5@�Ö'VAÂâ(÷­'£4— Pƒ÷ �Ò•�ƒ’¤Êe'·”‡4Šm÷-X'|4— ”Pƒ÷ Ø�Ò•�ƒ’¤À>'À�÷ Â�ÀŒ(@a áMø‚�‘€` ˜Pó‚Áv(W ¸MÑ�Ä ;†Ä †÷í'&÷å�þ%Ã�÷ �Ä †Ã�÷ „�(Ä †Ã�÷ v�ÃØ%æ€4À�÷ àÒÈ%ÒÅ%Ä †Ã�÷ P�ò%æZ4À �÷  À Š÷œ%·D4·ð'Ñ%Å щ%wÞ'… wa|&÷x&œ3€‡�·Ì'÷ "�ÂÄ'‡�Å ÃU€�Ò@ÀåºM‡�÷•ÿ�o3‡�À¶MÈœ'Èå¸M&Îå�°•�÷ ,�×-„'nPƒÀlPÈx'ÈånP÷ �÷¸Mh'÷nPd'‡�7 b'‡�&Ð 7<;7:;À^.�‰ˆY€‡�·ŠK'·ŠG'·ŠC'÷ ¼Ã;'7Š7'Äœ¨Eaƒ +÷ Ê2(÷<�Â2f¦'÷ h$Á8[÷ ¢ Á®2÷ t· ¨2Ò•.�Áž2÷ b ŠÁv'÷ žÿÁlQ÷ –ÿÁZ÷ Žÿ· Ô&�†Â(J ƒR”þ€˜áÅ€�ùÉ•?�ö€˜ðµ�ÖAûÒ¥ �Ò• � Š„ †æ*J÷ Bù7&À*J7b:÷ÿÿ^:· Z:ЋüÀh*�‰ˆY‡�·l&÷•`&·Š^&‡�÷o[ì1÷ x÷ ð FÒ• �ÁZ÷ Ô & & & Æe�…AÁEàÿ � r �Àe0�Áe0�RÒ•-�@ÀEþtýÿÀe?[”””Ò•-�AWt÷ÿÁE€ÿ� r �Àe0�Áe0�RÒ• �& & & €Ö r� r<� s �Äe0�Åe0�‘R‘Ò•:�� r �Àe0�Áe0�RÒ• �·&‡�à �� rf÷ òÿÁe0�R‡�&Ä@CÃ@÷ �Ã(�÷ �@÷ �!DCñ„‡�� rÀ  �Àe �ÀeÉÿÀe �Àe �‡�÷ ¢÷ J"& ÷ „ÎRÀtA÷ <÷ 0�õÎEþÿÌ5øÿ· ’" †Î ÷U�1 ÷U�ü0‹U€‡�&Cfffff÷ ¦�Á¢P¡¡B¡¡¡Ž ‡¤X÷ º�”$Î ^�÷ œ� 7 8"”dŒb¤(â5`�ä5`�Òµ@�Ôµ@� £ äÕ �÷ "ÌE ÿ‡�SSST‡�w�t�J ŒB‡�ŒR‡�€&€� € N p@ æ€ € N � rÖ €� ‡�÷ F�÷ ìþ÷ ìÿ÷ îÿ÷5@�˜! ÷ Øÿ÷ Úÿ÷5`�„!7 ~!7 ~!÷U�ú/Àr!‡�÷ P÷ : ÷ �ËE�7 Z!Ë5 �· P!· ð/w�À÷ P8÷�â/÷ õ×-.!�.÷ ÖË5�÷U€� /Ë5�Ë5@�H÷U�@Ž/ËE@�BÁ>DÂ@C÷ ê ŠË 9ËU �6÷ zË ÷ Œ÷ ÷U�@Z/ËEöÿ(Âä.÷ Ž'€÷U� B/W!.� W!$�À‹÷U�,/— �÷  �åW!.�÷ L÷U�@/÷ ÷ ö€‡�ÀŽA÷ ú È ô÷ Îþ ‡�‚ ÷ Æ÷ ÜÉŸJ.ÑÅ€� ÷à÷ ªþËU�‡�÷ „þW!>�Öw�°þÀ¬A÷ ¸ùH�÷ †þL ‡�Âe�Âe�Âe�æ .·.÷ Fþ·.‡�÷ ¤îâ‡�÷ Ò÷æ-æ-7 Þ÷� ÚW½ÖA`�*w‘Ï÷ VW½ÖAp� w‘¾÷ FW½ÖAp�Á�Cw¨Q‘÷ 0W½ÖAp� W ?Cö÷U� .÷ W½ÖAp�ú Š÷ ü�ÀzÀå� ‡�&À À €eÀ À À ‡�ðµ4�ÖA $�‡ A�‡À €Àå�Àå÷ÿÀåÒÿÀå@�‡�÷ �  ÷*-*-CÃå0�× � ‚ ‡€ BpÁ`÷ š�Àe�ðw‡�÷ � ÷ ÿ×-ò�.÷U�p-� ‡�@ÖA ÷ €-À5�÷ x-÷U�N-÷-Â,h-÷ F�õµ~�ÖAú÷ ,�÷U�0-á÷ �· D-7 D-÷–,<-ÀE€ÿ‡�÷Œ,ˆ, · ‚,÷ �õµ�ÖAø· p,ÅŸl,û‡�Ð $üà ÷Z,Z,÷ Îÿ�‡�À�÷ `�‡�À�÷ V�‡�÷ ¤,7 ž,· œ,À@CД,È&"�ƒ÷U� œ,À �÷ `�‡�÷5�J · f,÷ød,÷E�^,7 \,‡�÷ æÁàƒCà� ±�@ @ý`€ ÀE�  ƒu ŒB‡÷ ÀòàñQ$ƒa÷ TæÁàƒCà� ±�@ @ý`€ ÀE� ƒu ŒB‡ #1-��ï‚àîQ$ƒ@À"�÷ æÁàƒCà� ±�@ @ý`€ ÀE�  ƒu ŒB‡÷ xòàñQ$ƒ ÷ Ò�ÀÒ+`À`B ‡÷ À�� € ÷ HÁ`ø÷ ª�� € ÷ ø�Á`ø� w”+7’+ s�@)%ƒ Ãå� Â~‡�÷ p�·n+7 l+÷ f�÷ N�W ²Q×-¦�C÷ &ÀJ+÷ H+µŠÙBõ`²Bµ ŽBÆà‚@à€ R~õàŒBõà²BÅå�ù€ƒ Â~‡�÷ �u²B5ŠÙB‡�7ü*€÷ 2�fÅð*AŒBB²BCØBÃE�ÿÄ@CÈ …‡�Á@CÂECÃDCÄFC‡�æ¦f& Ž�6�Þ ‚ƒ„À ‡�1-�� #& f&A É‹¥üö �Ì‹¶ �„Ö ‡�&�ÎU ±%� #& f&AÉ‹ &•ÎÕ �‘¥ùö �Ì‹¶ �„Ö ‡�÷ t4÷ XÿÀ *Á�C¢ÿÿ È‹"¤üЋþ¢ÿÿñÂe@�· x* ‡Âr*Âe�·l1·f*�‰xY‡7$Á�CP”þÈ•ÿÿÉ‹€ Þ7 ‡�æïY÷ Bð‰RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR‡�R”þ⋇�÷ hø&÷ žî÷ ´ & &÷ ~ÜÀ�÷ vý÷ xÅÿ÷ h÷ Ø’’ ’÷ LûÀªPˆ $È'Èe�‡�7 È'w�Ô÷U�"(‡�÷ ’úù÷ ªú÷ þ÷„ú&÷€ö&÷ 4û�÷ h÷ 8&÷ "ûŒ÷ ¨ü÷ :í÷ Ð� Òú'ÒÊ&÷U@�Ú'÷ äÛ÷ æ÷ Pù ÷ ¾ý÷-2¨&÷-,¢&÷U�ª'Ńÿ÷ ¶÷ ¦ú‡�÷ ¬íÀµ&÷ ô$7r&7t&&÷ ¨�Ńÿ÷ ú·R&’ÒÊ„'’÷ hú‡�ƒ ÷ Î÷ @�÷ D÷ À÷ÿÿ.&÷ l�÷ .÷ v æL'æ&÷ <Û÷ >Å‚ÿw�Âþ÷U�'‡�À�÷ ü7 $'7 ô%æ�€÷ ŽùÅ%?�·Sà%÷ Üù÷ bùÀ�÷ Žû¡� íÖ ‡� 7 ì&÷ &à #÷-¬%Ü&&ƒ÷ Lù÷ ¤% Å%\�0÷ "Å ÷ %:÷ ¬÷ –ùú÷ ‚÷ z%á·  &÷ ‚ù÷ Ž ÷ †õE ÷ ~E ÷5€� Àj&7b&÷U€�V&€‡�÷ 8ù÷ .öfæÃÎ%÷ 8� ÷ Bƒ…η &Á &Áe?�fæà �÷ �Å$�÷  ÷ ƒ…¶� rf÷ òÿ…Åe0�w�ø ÷ ^Ø÷U@�Þ%÷ îÜÀ5� ƒ ÷%¢)@ à à €‡�÷ ´%À5�÷ h÷N%÷ ¨ø÷ &÷À�÷ ú Ų% ÷ n$÷ ”÷ f$÷ bøÄ ÷ „÷ pøW½ÖAp�öW!'�÷ n÷ jÙ¸· 8$÷ NøÔ÷ º÷*à $!÷ ®÷$÷ ¨�Å ƒ ÷ *øü÷ ÷ ÷÷ ¨÷Á@Cff÷ ¢ÞÀ�÷ ú¡¡7 p÷nw�øÜ÷U�è$ö÷Ê#|$÷U�Ø$‡� ÷ L�÷ Â÷÷U�Â$‡�û÷ 6�Á.$à ÷ ¤�÷ �ð@’B �  Å ÷ ˜÷ ôC w�€�÷ ÷<÷ àù ÂBQ¦Ã<�Ä>�C!W!^�õµx�ÖA÷ ^÷ù÷ F÷ŽC D÷ L÷ C!D!ùÁ Á õ€Ž ÅU�€÷U�($À$À¸QP:Š��Š÷ ÷7ø#‡�Àò#à x‘��Å H 7n#÷ èö7Ú#‡�÷ Ò"fÅ'�÷ �…ö7 ¾"Â5�Âå�¦÷ �R‘‡�À " À�÷ `øÀ€7¢7z7„" ‡�° �‡�ð � €&È �üÈd"·`"‡�÷ ¶ÿâ Á¢P¦fR Á%°Pû‚R’· >"‡�ªP€÷ ¼ÿ€÷ ®ÿâ @÷ žú ÷ ¤ÿ÷ "‡�÷ ä�k÷ Te7 "Á|[ÂÀF÷ †úæÀFæƒ[÷ ZÒ‰ÀF��=‡&÷ ÞåÀ���ŒB   ·Ô! ÷ ZÕ÷ ðÙÀ5�øÄFCà Ì%¢)òƒ ƒ Ã%�í÷ *õ ÷ àõçÌ å÷ Šú÷ ž"ßÀŽ!‰7 "7 „!÷ ˜å÷ †"÷ x!· r!‰†[��‡&÷ XåÀ���ŒB   ·N!¼Ö ÷U�@N"7 H"7 Â!‡�Þ÷ ´ô ÷ jõ÷ ðö· ,"÷ ~çóÀ""‡�ÀÊQ À%îQü‚‡�ÀÂP À%îQü‚÷�–!Á†D€D÷ fù÷¸²wŠ‹!w�ÆÿÀþB À%îQü‚· d÷ Ž÷?’·¤·Š£·Š¡·Šž÷ >ïw� ÿ��������������������������������������������qeÌ��enÍ�� zÌ��znÍ��tgÖ��el×�� gÖ��tlÞ��egß�� lÞ��fdîÞZdnï��1pæ��2pç�� bô,��bnõ,x[di -z[id -¾PôQ¾F´L¢I������²���²²�������²�D���²�ˆ�²�œ���²�~~²�’���²�~~ @�Ž #�¦ -�¶ (���§Zpi���«Zpd��¯Zts���´Zxe��@�»Zni@���ðìàZesâZoläZibæZrsèZocêZeb��dm��cm��emìZemîZnc��dlðZttòZotôZys�� øZnmúZnmüZnmþZnm�[nm% �R �G @� =��� ÀÐÐ������������ˆÈ!+�!-�X!*�n!/�N!&�T!!���Œ!+�Þ"-�æ""�è"'�#%� #<�#^���&#C�&#c�.#D�.#d�2#O�2#o�6#B�6#b�L#F�L#f����������������������������������  €  @@@@@@@@@@@@@@@@@@@@@@@@@@€�“Zdc.•Zsi.—Zma.™Zip.ÔZpf.öZys.6[npô��cl.v[sl8%�������������������������@BYVBò@Æ@zR2A������������������������l@xYŒB2Aî@BYFAþ������ � �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������œ[a.�0¡[a.�.¦[a.��  «[b.��¬¯[b.�ª³[b.�ú·[c.��¶ ¼[d.��¢Á[e.��¤Æ[e.��l É[e.�lÍ[e.�¢)Ñ[e.�¢)Õ[e.��¸Ú[e.��ÌÝ[e.��lâ[e.��Àæ[f.�Äê[f.�Âî[g.��@ ó[i.�4õ[i.�(ù[i.�(ý[i.�T�\i.�(\i.�(\i.�( \i.�(\i.�(\i.�(\i.�(\i.�(\i.�(#\i.�N&\i.�Z*\i.�(-\i.��ö0\i.��~5\i.��ä:\i.�n*=\i.�l*A\l.��6E\m.�ª)I\m.�ª)N\m.� .S\m.��ä,X\m.��Œ]\n.��‚,a\n.��Ž,e\n.��4j\n.��’p\n.��¬,u\o.��Èx\p.��–|\p.��˜‚\p.��d‡\r.�2Œ\r.��Α\r.��‚”\r.�J)˜\s.��¸\t.��l¢\w.�ø¦\ba€€ñ©\ba€€ñ¬\da€@ ®\da€@‹±\da@‚�`³\da@‹�ô¶\da@‹�ô¹\sa@‰�t»\sa@‰�v¾\sa€À À\sa€ÀŒÃ\sa€€ Å\sa€€ŒÈ\cb�„�†Ê\cb�„�‡Ì\eb�„�Î\gb�„�Ð\gb�„�Ò\hb�„�‚Ô\hb�„�†×\ib@‚�@Ù\ib@‚�ÀÜ\ib@‚�PÞ\ib@‚�Ðá\ib�‚�0ã\ib�‚�°æ\lb�„�è\lb�„�‡ê\lb�„�ƒí\lb�„�ï\mb�„�ñ\nb�„�ó\pb�„�€õ\pb�€���rb�„�÷\vb�„�„ù\vb�„�…û\cc�€¯�ý\fc�€�ð�]lc�€¡�]lc�€¨�]lc€� ]lc€�Š ]lc€�ñ ]lc€�ñ]lc�€¢�]lc�€¤�]mc�‚� ]mc�‚� ]mc�‹�÷]mc�‹�÷]oc€@ ]oc€@Š#]ed€À %]ed€ÀŠ(]id@‡�r*]id@‹�ù-]id@‹�ù0]me�†�ˆ��0f €����1f €���2f €���3f €���4f €���5f €�2]ah�€��5]ni€€ 7]ni€€Š:]oi�€�<]mj�@�>]sj€…�@]dl@‹�ÿD]dl@‹�ÿH]dl@Ž�þL]dl@Ž�þP]dl@Ž�þT]dl@Ž�þX]dl@‹�õZ]dl@Ž�ý^]dl@‹�õ`]dl�@ðd]am�Š� g]fm�@j]fm�@ m]fm�Àp]om@‹�ós]om@‹�óv]om@‚�x]om@‚�{]tm€€~]tm€€ ]tm€�„]um@‡�p†]um@‹�ò‰]um@‹�òŒ]en€� Ž]en€�‹‘]en€Àñ”]en€Àñ—]on�€ ���cp €���0r €����1r €���2r €���3r €���4r €���5r €���6r €���7r €�™]er�€�]or€@ Ÿ]or€@Œ¢]or€� ¤]or€�Œ§]tr�€�©]tr€ƒ€�«]tr�€�­]bs€€ ¯]bs€€‹²]cs�€¿�´]es�€±�¶]es�€¸�¸]es�€ ð»]es�€ð¾]es�€ðÁ]es�€ ðÄ]es�€²�Æ]es�€´�È]os€ˆ�~��ps €�Ê]ps�˜�Ì]ts@Œ�üÐ]ts@Œ�ûÔ]ts@Œ�ûØ]ts@Œ�üÜ]ts@Œ�ûà]ts@Œ�ûä]ts@Œ�øæ]ts@Œ�úê]ts@Œ�øì]ts€€ðð]ts€Àðó]us@‚�àõ]us@‹�öø]us@‹�öû]ws€À�þ]xs€À �^rt�†�‰^st�À ^st�À‹^st�@ñ ^st�@ñ^aw�€�^ox@…�x��anŒ��ap@��il6��ln4��ne¤��sd¢��rcì��on@��sl@‰��‰��ö�‰����‰���� ABEFILMNOPQRTUZCOMMAND LINE TOO LONG!�Cannot expand impure segment!�lstNO INPUT FILE SPECIFIED.�NO MORE FREE STORAGE � ERRORS DETECTED: ��DELPHI MACRO �ILLEGAL OPTION.�NO FILE NAME FOLLOWING -NA�ABS.�crfCANNOT OPEN OUTPUT FILE: �macCANNOT OPEN INPUT FILE: �r�d�a�c�� ���ure�ure�atic�ternal�ternal�TABLE OF CONTENTS�t�/insert/f�q�c�n�c�m�x�b�d�m�c�m�m�e�e�e�e�e�"  �rel �€@ �� �������@******� �SYMBOL TABLE�c� PAGE �JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC .MAIN.�b�n�f�sysmac�sml/lib/macro/sysmac.sml�scii�sciz�sect�lkb�lkw�yte�sect�sabl�nabl�nd�ndc�ndm�ndr�ntry�ot�rror�ven�lt2�lt4�lobl�f�fdf�feq�ff�fg�fge�fgt�fl�fle�flt�fndf�fne�fnz�ft�ftf�fz�if�nsr1�nsrt�rp�rpc�ist�acr�acro�call�exit�ixid�arg�chr�list�mixid�type�dd�age�rereq�rint�ad50�adix�em�ept�bttl�itle�ord�sd�sf�c�cb�d�dd�df�h�hc�l�lb�r�rb�c�s�q�e�t�i�is�c�cb�s�sb�t�tb�e�o�os�t�i�e�l�t�c�s�c�cc�c�n�r�rb�rd�rf�v�z�p�pb�pd�pf�m�mb�c�cb�v�vd�vf�t�lt�c�cb�t�p�r�cdf�cfd�cid�cif�cld�clf�d�exp�f�fps�rk�pd�pi�ps�dd�df�v�vb�pd�pi�ps�l�ld�lf�g�gb�gd�gf�p�set�l�lb�r�rb�i�s�t�c�cb�c�c�n�td�tf�ti�tl�v�z�b�l�cdf�cdi�cdl�cfd�cfi�cfl�d�exp�f�fps�st�b�bd�bf�ab�t�ap�t�tb�td�tf�it�r������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������bind������������������������������������������������������������������������������������������������0000700�0025652�0025652�00000054156�13044134717�010051� 0����������������������������������������������������������������������������������������������������ustar �jnc�����������������������������jnc��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ÀKª ��ô�����_�êà&& æ`c÷ ¤7ð_7ú_æ�æ`c÷ 7Þ_7è_†e‡�à&÷ Œ†e‡�& Á N’Îe�ÎE�†å N’Îe�ÎE�& f¦‚Âe�‚b¶�æƒÃe � BÔS”‚~Šƒ‚‡� Â�Â�Â�à&÷ šÿ¦æ�Ža÷ †e†e‡�À Áÿÿ†e‡�w<_‡�w8_‡�à&æ,_÷ öéà&æ _øà&æ_÷ ôàà&æ_÷ ðÙà&fæø^÷ ÌÑÁì^‡�Áè^‡�à&& ÷ ÿ ·ºg÷e�´g�‰êh.Âÿÿ Ä�@ ÂÿÿÃ�@ Â�ŠÂÐ  à&& ÷ Ôþà&÷ Êþ‚Ò ÷ Àþ·dg·bg÷e�\g�‰äh‡·Vg�‰êhÁ��†Á Á Á †e†e†e‡�à&÷ ˆþ€Ð 7Bg� ÷ nþ ‰ôhüh†e†e‡�à&…÷ bþÖ ·g � € Ò ý¦~„� ÷ :þ7öf÷ :þÖ ”ù�‰îhFA †e‡�à&…Æå�€ à €æ þ„&�!ý‡„÷ �þÖ ·¬fÖà&Á�†e‡�@pr‡�à&@ ·¤f�‰ i‡  †e‡�à&æòæòæòæôæ & æ\c÷ *B÷ ª °”�°�†e‡�à&æòæòæ*æòæòæ�æ\c÷ îB÷ n °�Š°�†e‡�‡�ð ��ž�ÀE�ÿ‡�Àýÿ‡�ð � &ž�° �ð �€•ÀE�ÿ‡�Àýÿ‡�¸Š�¸��° �‡�à&& & & @À "à&Á ÷ z à&Á ÷ và&÷  à&÷ ü à&÷ $ à&Á ÷ Ä †e‡�à& ÷ X øà&Á B÷ š ñà&Á B÷ T êà&Á B÷ F ãà& ÷ b Ýà& ÷ Ì ×à& ÷ p Ñà& ÷  ËÁ ‘‰ ‡�Á FNÁÿÿ‡�à&D…… Å  …aA ¥FÀ�Ì ††e‡� ŠJЇ� BÒ‡�à&� ÷ âû@‰Á   CÒÄR” à ü€Â5� Š¡� ‡�Á   CÒÄR”ŠÃ ü€‡�B Á  J¢ @”‚ R¤~Áÿÿ‡� ‡�Á    C”„”à Ä R¤ ‚ ‡Ã Ä Ã Ä ÷Ä ‚Áÿÿ‡�Á�‡� ‡�„Æ …Õƒ à Ca— ÿÿ ƒ ÃE�ÁŠ‰Š“”ýÉŠÃ Uï•Á�ÂäZ� Ê Á FàÎ F`� ÷ Êú � ÿ ¾Z� ÿ ºZà&…å eö üÿüÿÀ�ÿ ÎZö�úÿvøÿúÿmüÿÀ �ÿ ²ZÀ�ÿ –Z¶ úÿ¶-úÿøÿî†e‡�à&…å e¥å%üÿÁ ‚‚ Âå�väÿ¶âÿäÿ vàÿäÿÀ�ÿ ^ZmäÿvÞÿ_àÿÀ �ÿ HZvÜÿö%%�ÜÿrâÿÁ 6 ÚÿvØÿ6 Öÿ¶ àÿIw�àÿÀ,�ÿ ZÀ(�ÿ øYröZÚÿw�T�öèYÚÿw�J�ö�ZÚÿw�(�öJZÚÿw�6�ö>ZÚÿw��öàYÚÿw� �öÖYÚÿw��¶ àÿàÿÀ(�ÿ ´YÁå0�vÖÿ‚ÖÿØÿÀ(�þ Úÿö âÿ8w�‚�àÿÀ(�ÿ †YB— X�— C�¼— H�È— I�Ê— N�Ì— O�µ— S�¨œw�4�³— c�¦— h�²— i�´— n�¶— o�Ÿ— s�’— x�žƒw���ÜÿÀ"�ÿ �Y¶ àÿ¶-àÿÞÿw�°þ†e‡�à&…å e¥ Áå�vøÿ6 öÿ¶üÿôÿö üÿüÿÁ Á Ádc À �ÿ ÐX†e‡�ö üÿö úÿüÿ vôÿƒôÿ —r �öÿmøÿÁ Ƀôÿ —r �¶ôÿ¶ öÿö ôÿéöÿ vÜÿ¶úÿÚÿÁ �À$�ÿ HX¶ Üÿ¶-ÜÿÚÿôö üÿÁ-�À �ÿ *XöÿÁ vÜÿÜÿmøÿÁ AÁe0�À"�ÿ Xö Üÿö Üÿï†e‡�à&…å e üÿÀ�ÿ �X†e‡�à&Á �� ÿ ÎW†e‡�à&6 üÿ6 úÿÀ�ÿ ´WwÜW w�îÿöÿÿúÿÀ�ÿ œWwÄWÁ¾WW �ïW �ìW �éW +�ëW -�å�üÿWp �ÁmWÁå0�vüÿÀ�ÿ TWw|W÷%0�vW×-pW9�èö úÿ6 üÿüÿ�†e‡�à&…å e¥ Áå�vøÿ6 öÿ¶üÿôÿôÿÁEðÿ‚öÿ‚møÿ J¶ öÿôÿ¡� Wtýÿvôÿö ôÿéöÿ vÜÿ¶úÿÚÿÁ0�À$�ÿ ÀV¶ Üÿ¶-ÜÿÚÿôöÿÁ vÜÿ ÜÿmøÿÁ ‚Üÿ‚møÿ vÖÿ—" �ö0�Ôÿö7�ÔÿÖÿmÔÿÀ"�ÿ lVö Üÿö Üÿ݆e‡�à&…å e üÿÀ�ÿ ºV†e‡�à&…å e¥ Áå�vøÿ6 öÿ¶üÿôÿôÿÁEøÿ‚öÿ‚møÿ J¶ öÿôÿ¡� Wtþÿvôÿö ôÿéöÿ vÜÿ¶úÿÚÿÁ0�À$�ÿ ÔU¶ Üÿ¶-ÜÿÚÿôöÿÁ vÜÿÜÿmøÿÁ AÁe0�À"�ÿ ¤Uö Üÿö Üÿï†e‡�à&…å e üÿÀ�ÿ  U†e‡�à&…å e¥å%À�ÿ fUvâÿüÿÀ �ÿ äUÀ�ÿ >U…Åå*�¥òÿ¥ðÿ¥îÿ¥ìÿ¥êÿ¥èÿ¥æÿ¥äÿ„ôÿƒöÿ‚øÿúÿÀ�ÿ 2UÀ�ÿ �UâÿÀ�ÿ ìT†e‡� � ÿ ÒTà&÷ �÷ h†e‡�@À Ä U‡�à&÷ îÿ÷ Þòà&÷ àÿ÷ ëà&÷ Òÿ÷ äà&÷ ÄÿÁ ÷ ¼Úà&÷ °ÿÁ ÷ ÆÐà&÷ œÿ ÷ ZÈà&÷ Œÿ÷ LÁà&÷ ~ÿ ÷ "¹A ·à&÷ jÿ÷ °à&÷ \ÿ §à&÷ Jÿ÷ ¢�Ÿà&÷ :ÿ $  Ä $‚‡ Á�ŒÁÿÿ‰& &  †¯�� †N`v �N`v �pv�e@ €e‡�à&€÷ Ìÿs�à ƒ Á†e‡�à&÷ Êþfaa& � Á€÷ žÿe@ K& Ö †e‡�&¦æ& Â& —vÿÿN r¯�B ˆ —v�ƒeB r`Á„ƒ‚€‡�&f&„€‡�&&Ð „€´�‡�„€¯�‡�&f¦æ&f… È ÷ È�à  Á'÷ vÿf‚ ÷ ºÿ÷à  &¦    Ba � ÿ êR‚€ >� r �fÎe0�� r �fÎe0�� r �fÎe0�� r �fÎe0�&¦� ÿ |R‚€&¦� ÿ lR‚€&¦� ÿ \R‚€&¦� ÿ LR‚€À…„ƒ‚€‡�&&�a�a¯�`  „€‡�f¦‚áᎶ�¶�Áe�÷ Àþ‚‡�f€Àe�÷ ¬þ@aa¡¡aa‡�&f&aa�a�a¯�a h„€‡�&f&aa�a�a¯�¡ è„€‡�&&�a�a¯�` „€‡�&& Ä  „€‡�÷ š�f¦æááF÷ z�æ &f� ÿ ¶Qv�€—#0�(‡—#9�%‚æ &f� ÿ 4Qv�€Ö ÷ äý÷ „ÿ÷ €ÿ÷ @ÿ÷ 0�@÷ pÿaa¢Êå0�÷ $ÿB€ËÖ aaFƒ‚‡�&& „€‡�æ &f� ÿ .Qv�€—%!�‡‡�æ &f� ÿ °Pv�€Ö æf÷ �� r‡�À†YÀm„Y· €Y7pzYv �Àei7nY¯�� € ‡�Á & ‰x€wTY÷ PY‡�Àe�ì�r �†2��‡�€ �€l�2�� ‡�7„ƒ�B� Ë ‡�Á r �†l �r��A‡� ‡�€��Ô ‡� �÷ ¶2 ��2 �2 �2 �‡�74E ÷ ´ÿ€��÷ šÿ÷ lÿú‡���‡�7E€ �ƒ�Ä`Àå�Ä�Ä ý„ !��a †÷ Tÿô2��Á ‡��áí Àe�ö7¾�€ �€l�ƒl� 2��òe��H‡�E�Cl�r�÷ ì„ ��r �ƒ Â~r��Iòe��÷ ÐA‡�7\�C÷ .�E÷ Žÿ„�„ Ä Dá… �…l�å Ä u�Ír��Á‡���ì � ‡�7�EÁ �÷ pq�±�Bw�¶þ¦æ&f&€ �Þ …„ƒ‚€Á ‡�–%…„ƒ‚¦6�€‡�¦æ&f¦ �6 �ã·¼W÷ v�Æe�Ç°W·¬W÷ D�Æe�÷·žW÷ ðÖ ñ·’W÷  ê·ˆW÷ Úô·~W÷ hï·tW÷ èÛ·jW÷ Ö¦�¦�÷ �Æe�À ‡��Bi‚Âe�[÷ ÂÁBiW jiw�à�Ñ ùá wWÁ�÷ |@‚�—¤^�w�ö‹�·�¦V�‰i—­��‡—­�� ‚·�V�‰ i ‡‰���·�‚V�‰&i&@2‡Á@÷ p�ˆ/4'Ä�€ö‹� 0�Â@°�°�° �Â*cÄ�Å*cÃe�£å ×"ÿÿK?`VÀ\VÀåBi÷ ÆÖ Àýÿ ÷ ºÖ Àþÿ÷ ®Ö ÀÿÿÁ2VÂ0VÃ.VÄ,VÅ*V‡�€�ÀeBi Bië‡ jiè†È æ7V�‡�Ã*cwVÄ� … Á”ÁE�ÿR ÁU �r ÿÿó‹ÿÿ ñÃe�CáBáÁÒUw�¾þ —­��¸‚ö‹��!þÿ!ÿÿ�w�úþ÷ *÷ xÿ7 Uø �À˜U,�ð÷ �� ‡�÷ `�"ÿÿ8Š�ÁzU1 Bi÷ÿÿlUÁfU1 Bi÷ÿÿXU÷ î"ÿÿ&�‰€�÷  ÷ š? "Uw�êþ"þÿöõ÷ ¼‡�"ÿÿ�ÁE�€ 7�¼TwºT&��‰,i€ð�€�‡�÷ n÷ ¼þø �w�žþ� "ÿÿ"þÿÂE�€,�÷ œÿ l�Š�° �� w�jþ·�@TÀ�‰i�ôw�Dþ¸��° �ì÷ ÷ Vþø �w�8þ"ÿÿ°��� ‡�"þÿûú÷ à÷ .þ÷ ò"ÿÿö �ð �÷ ÿ�÷ œ°���÷ „p�w�Þý°� �‡�w�Âý÷ ’÷ àýø �w�Âý÷ ¤�"ÿÿ""þÿÀ’ÀE�ÿw�¨ý÷-„S„S‡÷izS÷ivS� ‰i�À · fSÀŸ`SçÖ Àüÿw�týÀ’ßw�Lý÷ *÷ xýø �w�Zý÷ <�"ÿÿ"þÿð �É÷- S S ‡� ‰i�À áÀ S½ÀŸS· S¸° �Ó�0÷ î�‡�"ÿÿ, -0,��"0, �� �÷ ”0 ���÷ |p�7�ÐR7�ÌR��‰2i1�@q��w�–üw�žü�‡��l�ì�‡�·�œR·�”R�‰8i ‡·�ŽR�‰>i‡� w�xüw�düw�lüw®RÁBiW ji É fÎåBi÷ òúÑ ôÁŽR� ÷ÿÿŒR÷ÿÿˆR‡�wnR·lR÷jR7hRwfR‡��Bi"þÿ‚"üÿ†Îe�‡�f¦ÂXR×-bR�÷ ZR÷mVRFR�‰„i‡€‚‡�÷íBR2R· <R×-8R�íÀ�‰6c�� ‰&fÀªi7R7R÷ ¤ÿ7R7R7úQÁôQHp�€‡�f¦÷ €ÿÈÜQ?ÚQŠi€,�‚�úòÄQ�·ÈQ÷ ¢�‚‡�&¦æ×-¤Qÿÿ÷ ˆÿ7 ¨Q¢QÁe�ÁE�· ŒQ†€�7 ‚Q ‡÷ ˆQ· ‚QŠió÷ „ÿŠiîàCà"‡× �†� C` È3��÷ BQ‡÷<Qò�7 8Q‚÷2QÑ ÷,Qƒ‚€‡�Æ&¦ÂŽi,�‡ÂŠi€�@ ‡ú"Jw ðP‡·êPr�1�@"7 ÔP†7 ÐP‡wÊP7 ÊP‚ñÄP�w¾P á ·¸P‚€‡�á ÷ Œÿ ‡�à&Álc ÂâH r�†e‡�à&÷�ŽP†e‡�à&…å e¥ Áåvøÿ`à&…å e¥üÿÁmœHÁ 6 øÿvöÿö�ôÿúÿÁ Á€HÁ ‰-üÿüÿ BöÿÁ môÿÀ �ÿ ¸FvòÿöÿÁ À�ÿ ¦F-ôÿ¶ ôÿ¶ øÿøÿmúÿÁ ‰òÿÞw�èúÿÁ ‰øÿö øÿüÿ vòÿ üÿ ‚úÿÀ �÷ Jÿvòÿòÿw� †e‡�à&…å e¥üÿÁ ‚‚ Âå �…Åå�e¥å�% öÿ BúÿÀ�ÿ FöÿÁ A� ‚öÿ JöÿÁ ñ.��ôÿmüÿÁ W"[�¶ ôÿ¶-ôÿøÿñôÿÁ vòÿøÿmüÿÁ ‚öÿ ‚‚møÿ‚müÿ Jö øÿ¶-òÿøÿëüÿÁ ‚öÿ Ab‚üÿ JöÿÁ ö�äÿvâÿäÿmöÿÁ ‚äÿ‚mòÿ‚müÿ J¶ äÿ¶-äÿâÿí†e‡�‚øÿÁšNÀ÷ "þwŽNøÿÁ É  -øÿÁ W,�-�øÿÁ AÁ ‚øÿ r�øÿ Àÿ LNÕ‚úÿøÿÀ÷ ”þ‚üÿøÿÀÿ ÊDÁÿÿ�†e‡�à&…å e†e‡�à&…å e·üÿN†e‡� � ÿ dDà&…å eö�úÿ¶üÿøÿÀ�ÿ F¶ úÿ¶-úÿøÿö†e‡�à&…å e6 úÿ6 øÿÀ�ÿ ØEvøÿö øÿ ¶ úÿúÿmüÿÁ ‰øÿ—-úÿÿ�éüÿÁ ‰úÿ†e‡�à&…å e Áåvúÿ‚úÿüÿÀÿ ôCúÿÁ ö�øývöý øýmúÿÁ AÀÿ ´C¶ øý¶-øýöýð Àÿ žC†e‡�w�úà&� ÿ ìCvüÿö%ÿÿüÿüÿÁnCÀ�ÿ bCÁnc À�ÿ „CÀ�ÿ >C†e‡�à&� ÿ HCvüÿö%ÿÿüÿüÿÁ,CÀ�ÿ CÁnc À�ÿ BCÀ�ÿ üB†e‡�à&…å eüÿÁ AÀ�ÿ Dvúÿúÿ À�ÿ Cvøÿúÿ 6 öÿvôÿ öÿmüÿÁ ‚öÿ‚møÿ J¶ öÿ¶-öÿôÿïøÿ�†e‡�à&…å eüÿÀ�ÿ &DÀ�ÿ †BüÿÀ�ÿ DÀ�ÿ rB†e‡�à&…å eö üÿÁÿÿÀ�ÿ ðC üÿÁ A�À�ÿ ÜC†e‡�à&…å e¥å%öBêÿÁBÀ�ÿ Bö%�üÿö%�üÿ Áˆc ¦C ‚�À�ÿ B…Åå"�¥òÿ¥ðÿ¥îÿ¥ìÿ„ôÿƒöÿ‚øÿúÿÀ�ÿ èAö üÿö%�üÿÀ�ÿ ’AêÿÀ�ÿ ”A†e‡� � ÿ zAà&…å e Áål�‚‚ Âåv�ƒƒ Ãå{�…Åå�e% ¥% åmà&…å eüÿÁ ö�úÿvøÿaúÿmüÿÁ vöÿ—-öÿa�—-öÿz�öå �öÿaÁ¶BÁ ÉÿÿpÁªBÁ ñÿÿ�iö%B�öÿÁ”BÁ ñ � ö%T�öÿÁ€BÁ ñ � Á¶c À�ÿ ò@À�ÿ ¬@öÿÿôÿö%B�öÿö�òÿw��ö�òÿòÿÁm:BÁ ‰ôÿÁ0BÁ ñÿÿ�7 :B#w�®�w�š�úÿ müÿÁ vöÿ—-öÿ0�—-öÿ7�w�F�Á�wpBmöÿÁå0�wöA¶ úÿüÿÁ ‰-úÿÛ�w�F�Áèc ‚öÿÀ�ÿ B@À�ÿ ú?ðöÿW B�‚W D�w�ìþW M�w�ÖþW T�w�æþݶ úÿ¶-úÿøÿw�”þ†e‡�·üÿˆA6 ÿö �ÿÿmöÿÁ ¶ ÿ¶-ÿÿô·öÿ@A·òÿAÀô�ÿ AÀô�ÿ AÁ d Àô�ÿ AÁ¾Àô�ÿ AÁd BúÿÀô�ÿ Ö@Á Ád BÁ�Àô�ÿ ô@÷ ü@Á.d vÿÁ4d vÿ¶ÿøÿ�Á8d BúÿÀô�ÿ †@Á ôÁ¤@Á ñ �Ád vøÿÀô�ÿ b@Á d Àô�ÿ l@‚øÿúÿÀô�ÿ F@úÿÀô�ÿ ´>Â:@ JÁ2@Á É Á:d ƒúÿBÁ�Àô�ÿ F@úÿÀô�ÿ 0@Â@ r�Á@Á É %Àô�ÿ æ?ÁXd BúÿÀô�ÿ Ô?úÿÀô�ÿ B>wä?÷ à? Á\d ƒúÿBÁ�Àô�ÿ Ü?ÂÿÿÁ�Àô�ÿ n>w˜?Ád ƒöÿBúÿÀô�ÿ z?Á 7Á�Àô�ÿ >w–?úÿÀô�ÿ Ð=†? JúÿÀô�ÿ p?Âr? r�Â<?Ád?Àô�ÿ >ÁX?Á É Áxd ƒúÿBÁ�Àô�ÿ >?ºÁ?Àô�ÿ Ø=Áü>Àô�ÿ Ê=vôÿö ôÿ Á–d BÁ�Àô�ÿ ?Áò>Á ñ �Á²d Â`‚  Âå�ƒBÁ�Àô�ÿ Ø>Á¢>Á AÀô�ÿ =Àô�ÿ ˜>Àô�ÿ ’>Á¤>Á ñ � Àô�ÿ ¦>Àô�ÿ  >Àô�ÿ n>Àô�ÿ h>Àô�ÿ Ò<Án>Á É Á^>Àô�ÿ ´<Àô�ÿ ´<Àô�ÿ –<†e‡� � ÿ Š<à& Áå‚‚ Â刃ƒ Ãå„„ Ä刅Åå�e¥å%% % % øÿÁ öÿÁ ÷ÿÿ>ÂÎ= Àÿ ˜<wì=Áè=Á AÀÿ &<Á�Àÿ  =üÿÀÿ š=‚úÿüÿÀÿ $<úÿÀÿ ¢=¤= r�Á¼d BúÿÀÿ z<Á øÿÁ É 6 îúw�bîúmúÿÁ ‚îú‚møÿ J¶ îú—-îú2�ïüÿÀÿ =‚úÿüÿÀÿ ¤;ÁÄd BúÿÀÿ <Á WÂì< Àÿ ¶;vîúîúÁ B�úÿÀÿ ä;Á Áÿÿ Áº<Àÿ Š;vîúö îúåÁ 1öÿÁ É 6 îú îúmúÿÁ ‚îú‚möÿ J¶ îú—-îú2�ï‚öÿúÿÀÿ |;Á ÁÆd „úÿƒöÿB Àÿ r<Àÿ d<vòÿö%�òÿ Àÿ ¨:Àÿ H<vòÿöÿÿôÿö%�òÿÀÿ †:÷ @< Áîd B Àÿ <÷�&<÷%�< Áîd B Àÿ ú;7 <¶ ðÿ¾;ðÿÀÿ †:wÚ; ÷ Ô;A �Á w�ÚýÁ¶;Á ñ �HüÿÀÿ Š:6 îúö�ìúüÿÁ mîúÀÿ ü9Àÿ à9¶ îú¶-îúìúíøÿÁ É Á¼d vøÿøÿÀÿ 4;öÿÀÿ (;ö ôÿÁ�Àÿ –9÷%�L;Á�Àÿ ‚9øÿÀÿ ;Âì: r�†e‡� � ÿ F9Á�ŠÁ�‡�Á�ŠÐÁ�‡�à& Áåvüÿ6 úÿ6 øÿ®: À&ÿ x9wÌ:®:Á�À&ÿ b9w :Á†:Á ñ–:�ÂŽ:Á �À&ÿ B9vÖý6 ÔýÁ:Á ±Öý�Á„:Á AÀ*ÿ Â8:üÿÀ*÷ RvúÿÂJ:úÿÀ*ÿ 9vøÿö øÿÂ0:úÿÀ*ÿ ò8‚ÖýúÿÀ*ÿ Þ8w�®‚úÿøÿÀ*÷ ÌvÒý‚ÖýÒýÀ,ÿ ´8üÿÀ*÷ Á ¾ÖýÀ*ÿ 8vÔý6 Òý¶ÔýÐý‚ÖýÒýÀ.ÿ n8vúÿ‚ÖýúÿÀ.÷ ^¶ Òý¶-ÒýÐýèÁv9À&ÿ F8w–9 ÷ 9A �Á w�ÖþÂf9 À&ÿ 8vúÿÁT9À&ÿ 8‚úÿ r�Á>9À&ÿ ú7vúÿö úÿê†e‡�à&…å e¥6 øÿö�öÿüÿÁ ‚úÿ J" üÿÁ ‚úÿ AâküÿÁe�‚úÿÂe�À�ÿ à7vøÿ^üÿÁ A�ÁE�€‚úÿ ‚�ÂE�€àvöÿüÿÁ A�ÁEþÿÁ úÿÁ A�ÁEþÿÁ \w�Œ�üÿÁ A�ÁEþÿÁ úÿÁ A�ÁEþÿÁ GüÿÁ A�ÁEþÿÁ úÿÁ A�ÁEþÿÁ üÿÁ A�ÁEïÿ‚úÿ ‚�ÂEïÿB $w�N�w�&�üÿÁ A�ÁEþÿÁ öÿÿöÿö øÿ¶öÿøÿ üÿÁ B— �— � z�ew���øÿ׆e‡�à&…å e6 úÿ6 øÿÀ�ÿ ¾7vøÿö øÿ÷üÿÁ ‰øÿö�úÿ#ö�úÿö�úÿö�úÿ 6ÁBe B À�ÿ z7 øÿW �ñW �îÁ y�eúÿÁ ö�öÿvôÿ À �ÿ @7‚öÿ‚müÿ J¶ öÿ¶-öÿôÿðüÿÁe�À�ÿ ò6†e‡�à&…å eüÿÁ A � Áe�vúÿúÿÀ�ÿ r5vøÿüÿÁ ‚øÿ JüÿÁ A�ÁU�€‚øÿ r�müÿÁ ‚üÿ ‚�A�À�ÿ Ž6‚øÿ r�øÿÁ 1 �øÿÁ ±øÿ �wüÿÁ ‚üÿ ‚�A�À�ÿ P6‚øÿ r �cüÿÁ ‚üÿ ‚�A�À�ÿ (6‚øÿ r�üÿÁ ‚üÿ ‚ �A�À�ÿ 6‚øÿ r�üÿÁ ‚üÿ ‚�A �À�ÿ Ü5‚øÿ r �)w�R�üÿÁ ‚üÿ ‚�A�À�ÿ °5‚øÿ r�üÿÁ ‚üÿ ‚ �A�À�ÿ Š5‚øÿ r��w��øÿÁ B— �÷— �ô z�(eüÿÁe�‚øÿÂe�À�ÿ Î3øÿ�†e‡�à&…å e¥6 øÿüÿÁ A�ÁEÿÁ †e‡�7üÿÁ ‚úÿA�À�ÿ ¾3vøÿüÿÁ ‚øÿ A�l�‚üÿ r�øÿÁ ‚üÿ r ��üÿÁ ‚úÿA�À�ÿ r3‚üÿ r� üÿÁ B— �ø— �õ z�,eüÿÁ ‚úÿA �À�ÿ 43‚üÿ r � üÿÁ B— �ø— �õ z�2eüÿÁ A�ÁE�€‚üÿ r�†e‡�à&…å e¥lúÿÁ A�ÁE�€‚üÿ r �Áfe ‚üÿÂe�ƒB À�ÿ 4úÿÁ A�ÁEöÿÁ 4üÿÁ A� ÁE�vøÿüÿÁ A�møÿ‚úÿ r�úÿÁ A�møÿ‚üÿ r�üÿÁ ‚úÿ r � �úÿÁ ñÿÿ�úÿ^úÿÁ ‚üÿ r,�� úÿÁ ‚üÿ r��iw�´�úÿÁ A�ÁEïÿÁ ]üÿÁ A�ÁEïÿÁ Áže ‚üÿÂe�ƒBÁ�À�ÿ 3DúÿÁ ‚üÿ r��úÿÁ ‚üÿ r��úÿÁ ‚üÿ r��úÿÁ ‚üÿ r � �w�P�Á¼e ‚üÿÂe�ƒBÁ�À�ÿ ²2 üÿÁ B— �— � z�8ew���úÿÀ�ÿ 1üÿÖ†e‡� � ÿ ®0à&…å e¥Áèe ‚üÿ ƒ�‚úÿÀ�ÿ Æ0sÁòe À�ÿ ´0üÿÁ A�ÁEþÿÁ ö �ôÿöG�ôÿôÿÀ�ÿ d0üÿÁ A�ÁEýÿÁ öD�ôÿöI�ôÿôÿÀ�ÿ 80üÿÁ A�ÁEûÿÁ ö �ôÿöP�ôÿôÿÀ�ÿ 0üÿÁ A�ÁE÷ÿÁ öR�ôÿw�ºöA�ôÿôÿÀ�ÿ Ü/Áúe ‚üÿ ƒüÿà Ã�‚�À�ÿ à/kw�2Áf À�ÿ Ê/üÿÁ A�ÁEþÿÁ ö �ôÿöG�ôÿôÿÀ�ÿ z/Á �À�ÿ n/üÿÁ A�ÁEïÿÁ öU�ôÿö �ôÿôÿÀ�ÿ B/üÿÁ A�ÁEïÿÁ Á f À�ÿ F/Áf ‚üÿ ‚�À�ÿ ./üÿÁ A�À�÷ ¨�üÿÁ A �À�÷ –��w�v�Á$f À�ÿ ô.üÿÁ A �À�÷ p�íÁ:f ‚üÿ ‚�À�ÿ Ê.üÿÁ A�À�÷ D�ÁJf À�ÿ ¨.ÐüÿÁ B— �É— �Æ z�ÞeÁPf ‚üÿÂe�À�ÿ x.†e‡�à&…å eö üÿÁJf À�ÿ T. ÁTf ‚üÿ ‚�À�ÿ <.†e‡�à&…å eÁZf ‚üÿ ƒüÿà Ã�‚�À�ÿ .Á~f À�ÿ ü-Á¦f À�ÿ î-†e‡�à&…å eüÿÁ v�úÿ‚úÿ À�ÿ ò-vøÿÁ0/À�ÿ †-üÿÀ�÷ tÿúÿÀ �ÿ Ì-BøÿÀ�÷ ¤üúÿÀ�ÿ ´-vøÿö øÿèÁÊf À�ÿ l-Á¾.Á AÀ�ÿ ,-†e‡� � ÿ -à&´. � ÿ l-vüÿüÿÀ�÷ ª�Á˜.À�ÿ T-vüÿö üÿïÁ�À�ÿ ê,Á‚.Á É ÁV.À�ÿ h.Ál.Á ñ �Á`.Á É Â6. À�ÿ �-wT.ÁP.À�ÿ 4.Á.À�ÿ è,w8.÷ 4.ïÁ".Á ñ � ÁÖf BÁ�À�ÿ .†e‡�w�´à&…å eüÿÁ AÀ�ÿ H,üÿÁ A�À�ÿ 6,yüÿÁ A�À�ÿ À-qüÿÁ A �À�ÿ ®-güÿÁ A�À�ÿ ˜-üÿÁ A�À�ÿ ˆ-üÿÁ A �À�ÿ v-KüÿÁ A�Á W"�üÿÁ ‚üÿ ‚� A�l�‚üÿ r�üÿÁ A�Á ‚üÿ r ��/üÿÁ A�Á A�ÁEïÿÁ #üÿÁ ‚üÿ ‚� A�l�‚üÿ r�üÿw�b�w�x�Á A�Á ‚üÿ r��üÿÁ A�À�ÿ ²,üÿÁ A�À�ÿ ¢,ö�úÿö �øÿ À�ÿ ê*¶ úÿ¶-úÿøÿõÏüÿÁ B— �È— �Å z�ÌfüÿÁe�À�ÿ 2,†e‡� � ÿ Œ*à&� ÷ ¨�� ÷ &Á.,Á ñ �!Áðf Ã6,BÁ�� ÿ ,Ág Ã,BÁ�� ÿ ,Ág Ã,BÁ�� ÿ ô+Áà+Á É � ÿ ¨*†e‡�à&Á¦+� ÿ º+ž+ � ÿ j*w¾+Áº+� ÿ  +Á„+� ÿ V*w¦+÷ ¢+ñ†e‡�à&Â|+ � ÿ 4*vüÿ7 +üÿÁ W"�üÿÁ A�ÁE÷ÿÁ üÿÁ wl�f+w�öÁ\+ÁEþÿÁ · P+Á(+À�ÿ ä)vüÿö üÿÕÁ+Á ñ �÷í*+&+†e‡�à&Âø* � ÿ °)vüÿ6 úÿö+øÿ÷ÿÿ+SüÿÁ A�ÁE÷ÿÁ üÿÁ ±øÿ�üÿÁ vl�øÿøÿÁEþÿÁ ¶ øÿBüÿÁ ‚üÿ ‚� A�l�‚üÿ r�üÿÁ W"�÷%ÿÿŽ*Á.g ‚üÿ „�Ãx*BÁ�À�ÿ `*üÿÁ w�^* üÿÁ B— �ø— �õ z�æfÁ*À�ÿ Ò(vüÿö üÿ”Âì) À�ÿ ¶(w *Á*Á v�úÿ‚úÿ À�ÿ ˜(vüÿüÿÁ W,�ÿÿüÿÁ W"� Á\g B À�ÿ Ä)üÿÁ W,�ÿÿüÿÁ ‚üÿ ‚ � A�l�‚üÿ r�úÿÀ�ÿ .(vüÿö üÿÆÁH)À�ÿ (wh)÷ d)¬†e‡� � ÿ ”'à&6 üÿ6 úÿÂ) À�ÿ ä'w8) Áå ‚‚ Â僃 ÃåÄ)Ä …Åå�e¥% å% %�Á)Á AÀÿ @'øÿÁ øÿÁ 1 �øÿÁ 1 �Àÿ Š'vðÿ2Àÿ 'ô—-ðÿ�—-ðÿ?�ö%ÿÿðÿ Á”g ƒðÿB Àÿ ˜( Áå�‚‚ Âå�„C‚öÿøÿÀ÷ ²;w� ðÿÁE€�W � W �õW �ÆW �ÃÁ y�VgW ��¸W �ÑW �ζ‚òÿîÿÀ÷ î� Áå�vêù„öÿƒúÿ‚øÿòÿÀ÷ Bö%ÿÿðÿ;ö%�ðÿö%�ðÿ Áå�‚‚ Âå�ƒîÿÀ÷ ¤"ö%�ðÿ ö%�ðÿ—-ðÿ� —-ðÿ?�øÿÀ÷  Á”g ƒðÿB Àÿ €'w�žþÁH'À�ÿ &wh' ÷ b'A �Á w�þÁD'Á ñ � Á®g BÁ�À�ÿ 8'†e‡�à&…å e¥À�ÿ 'vøÿøÿÁE€�vöÿ ö%�öÿA  ö%�öÿB PvôÿúÿÁ ‰øÿÀ �ÿ Ø&‚úÿ r�ö ôÿ†e‡�À�ÿ ¼&vêÿÀ�ÿ °&BêÿÀ�ÿ &‚üÿÀ �ÿ B%‚úÿ r�†e‡�à&…å eÀ�ÿ v&vúÿÀ�ÿ j&vøÿüÿÁ É�üÿÁ ±øÿ�üÿÁ ±øÿ�vÀ �ÿ :&vòÿÀ �ÿ .&BòÿÀ�ÿ &‚üÿ JüÿÁ Avpøÿ‚üÿ r�øÿÁe�ö�öÿvôÿ À �ÿ æ%‚öÿ‚müÿ J¶ öÿ¶-öÿôÿðWúÿÀ�ÿ $øÿÀ�ÿ $üÿÁ üÿÁ 1 �À �ÿ š%vòÿÀ �ÿ Ž%BòÿÀ�ÿ n%‚üÿ r�üÿÁ A�À�ÿ ^%ö�öÿ¶øÿôÿ w��À�ÿ J%À �ÿ ž#¶ öÿ¶-öÿôÿò úÿW �¯W �¬Á y�fg†e‡�à&…å e¥åÀ�ÿ %vöÿÀ �ÿ ø$vðÿÀ�ÿ ì$BðÿÀ�ÿ Ì$‚úÿ vôÿ¶òÿö%�öÿAÀ�ÿ À$vìÿÀ�ÿ ´$BìÿÀ �ÿ ”$vòÿ‚øÿòÿÀ �ÿ >#vòÿòÿÁ W"�òÿÁ A�môÿ‚üÿ JòÿÁ v�òÿ òÿÁ A�môÿ‚üÿ J òÿÁ A�môÿ‚üÿ JúÿÁ É òÿÁ ‚úÿ ‚ r, � �Á�À �ÿ ^"üÿÁ AÀ �ÿ ì#Á�À �ÿ @"üÿÁ AÀ �ÿ Î#òÿÁ A �À �ÿ ¾#úÿÁ ‰òÿ†e‡�à&…å e¥å%üÿÁ vòÿòÿÁE€�‚òÿÂEÿ  C C vðÿöîÿ ö%�ðÿA  ö%�ðÿB P ö%�ðÿB  ö%�ðÿC ÂPƒüÿà „øÿÄ …Åå�e¥å�% % �% ö îÿ÷%�.#6 àÿö�àÿàÿmèÿ‚úÿ r � ÁÀg BÁ�À�ÿ è"†e‡�èÿÁe�múÿÁ vÜÿö îÿ6 Úÿ èÿÁe�múÿÁ vÚÿ‚ÚÿÜÿÀ�ÿ Š"væÿö ìÿgüÿÁ v�äÿUäÿÁ A�ÁEïÿÁ Xö êÿ äÿÁ A�mæÿvàÿ äÿÁ ‚æÿBì�¶àÿ¶àÿæÿäÿÁ v�äÿö êÿ äÿÁ A�mæÿvàÿ äÿÁ ‚æÿBì�¶àÿ¶àÿæÿäÿÁ v �äÿÁÞg BÁ�À�ÿ æ!†e‡�äÿÁ B— �Í— �¡éw�4�øÿÁ v, �äÿö êÿö�àÿö�àÿ¶àÿðÿ¶ðÿòÿ6 ìÿö êÿ øÿÁ A�mæÿvàÿ øÿÁ ‚æÿBì�¶àÿ¶àÿæÿæÿÀ �ÿ B!‚úÿÂe�‚mèÿ À�ÿ ªö îÿæÿÀ�ÿ !Á Áøg BÁ�À�ÿ !†e‡�æÿÀ �ÿ ò ‚úÿÂe�‚ ‚mèÿ À�ÿ VäÿÁ W"� äÿÁ A�ÁE÷ÿÁ †e‡�ö ìÿ8ôÿÁ vàÿàÿÁe� W ô Áh B À�ÿ ˜ àÿÁe� ‚ôÿ JàÿmöÿÁ ‰òÿàÿ möÿÁ ‰èÿàÿÁe�möÿÁ ‰äÿGèÿÁe�múÿÁ vàÿ6 Úÿö êÿö�ØÿöÿÿØÿ‚ØÿÚÿÀ�ÿ � ‚àÿB`¶âÿöE�ÀâÿèÿÁe�múÿÁ AÁEÿ?vPâÿö îÿö�€àÿö�@àÿàÿ]âÿ‚èÿÂe�‚múÿ J†e‡�à&…å e¥å%üÿÁ É GüÿÁ W"�ö�ðÿö�ðÿðÿÀ�ÿ ÖüÿÁ A�À�ÿ ÄüÿÁ W"�üÿÁ AÀ�ÿ FüÿÁ A�Áe�ö�ôÿvòÿ ôÿmüÿÁ AÀ �ÿ z¶ ôÿ¶-ôÿòÿðöÿÁ ‚üÿ Al�‚öÿ JüÿÁ A�Áe�ö�ôÿvòÿbôÿmüÿÁ vðÿðÿÁE�ÀÀ�ÿ ¶‚ðÿÂEÿ  C vîÿöìÿö îÿ[ö ìÿðÿÁEÿ¿Á Á.h B À�ÿ „ðÿÁEÿßÁ öå@�îÿö îÿö ìÿö—�æÿö�æÿæÿÀ�ÿ  ôÿÁå�À�ÿ ö îÿö îÿãö ìÿö˜�æÿw�0�ö�æÿæÿÀ�ÿ `ôÿÁå�À�ÿ P¶ îÿö îÿᶠôÿ¶-ôÿòÿ€üÿÁ üÿÁ 1 �üÿÁ 1 �øÿÁ AÁå�6 ôÿvòÿ$ôÿmúÿÁ AÀ �ÿ ôôÿ múÿÁ AÀ �ÿ ÞôÿÁe�múÿÁ AÀ �ÿ föe�ôÿ¶-ôÿòÿØøÿÁ †e‡� � ÿ Šà& Áå‚‚ ÂåŠvüÿ¶úÿúÿÁ É�úÿÁ 1 �Âì Àÿ ¶w ÁÁ v�êüÁúÁ AÀÿ 8Àÿ <w¼$÷%ÿÿ¶$rsó‚úÿüÿÀ÷ ÌúÿÀ÷ l÷%�Œ$Á„$Á v�èüÀÿ òvâüÀÿ æBâüÀÿ l‚èüB`·X$Kw�RÀÿ ÀväüÀÿ ´BäüÀÿ :w,$Àÿ švàüÀÿ ŽBàüÀÿ ‚êüÀÿ Æwò#Áî#Á W"�Áâ#Á wl�â#ÁÖ#Á w�Î# w�w�Ä�ÁÀ#Á wl�À#n‚úÿüÿÀ÷ ÖÀÿ w¤#÷%�–#ö�èüÀÿ �väüÀÿ ôBäüÀÿ zvèü·èüd#Ád#Á 6 èüvæü Àÿ Ä‚èü‚müÿ J¶ èü¶-èüæüð)‚êüüÿÀ÷ È� ÁTh Ã#BÁ�Àÿ .Áþ"ÁE€�W �W �àW �æW �ãÁ y�hw��W ��w�þW �ˆW �…Òw�ôý‚úÿüÿÀ÷ ÚúÿÀ÷ zÀÿ ÁŽÀÿ ^w®÷ ªw�šý÷%ÿÿ¬÷¦v"÷ÿÿf"7 `"úÿÀ÷ 4†e‡�à&…å e¥À�ÿ ¾Â>"ÂEÿ  C  ÷%�*"B  ÷%�"D Q ÷%�"D � ÷%�"@ P…Åå�eå¥%% % % ö öÿ÷%�6 êÿö�êÿêÿmøÿw Ì!Ánh BÁ�À�ÿ Øö ôÿÀ�ÿ À�ÿ †e‡�øÿmüÿÁ væÿö öÿ6 äÿ÷%�®öÿÿäÿö�äÿäÿmøÿmüÿÁ väÿ‚äÿæÿÀ�ÿ Rvðÿö ôÿZÀ�ÿ ¬vâÿÀ�ÿ  BâÿÀ�ÿ &‚úÿÀ�ÿ Øvìÿ4ìÿÁ v�îÿ8ìÿÁ A�ÁEïÿÁ ÁŒh ‚ìÿÂe�ƒBÁ�À�ÿ ð6 îÿìÿÁ v�îÿÁ²h BÁ�À�ÿ È ìÿÁ B— �Å— �ÉêÁ~ Á v�îÿö òÿîÿmðÿvêÿðÿíîÿvêÿ¶êÿðÿðÿÀ�ÿ \‚øÿ‚müÿ Jö öÿðÿÀ�ÿ @Á ÁÌh BÁ�À�ÿ :ðÿÀ�ÿ vêÿ÷%�2öÿÿèÿö�èÿèÿmøÿmüÿÁ ‰êÿ†e‡�à&…å e¥÷ Ê)ö�øÿöºöÿÁ¶Á 6 ôÿvòÿôÿmüÿÁ ‚úÿAÀ �÷ �¶ ôÿ¶-ôÿòÿî¶ øÿ¶-øÿöÿà7 v†e‡�à&…å e¥÷%~�Z úÿÀ�÷ $�÷mHJ7 B· >Á:Áe�múÿÁ ‰üÿ†e‡�à&…å e÷ ÷ u6 úÿÁ Áe�À�ÿ ‚üÿ r�ÁðÁe�À�ÿ ú‚üÿ r�ÁÚÀ�ÿ â‚üÿ r�ÁÄÀ�ÿ ΂üÿ r �÷mª¬Á¤Áe�6 øÿvöÿ øÿmüÿÁ vâúÿ¶ øÿ¶-øÿöÿóúÿÀ�ÿ „ÂlÂe�‚müÿ JÁ\ÁEþÿÁ ÷ H · JÁFÁe�müÿÁ Á6Áe�6 øÿvöÿw�$�øÿmüÿÁ AÀ�ÿ Œ¶ øÿ¶-øÿöÿð7 �†e‡� � ÿ V��������������������ŠF������ˆ�˜�Æ�Ì�����Ò�à�ê��2�"lþ>8TvB&2Ü J˜T��®P^2 ž Þ p ð v Š Z h L ¼ � V �ˆ˜¤²ÀÎÚæòø���Ð ˆ ¤ ������ê5® ðÀ >JVR\F:jt~Œ�’�z´œ�Œ®Ò��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������è� ����Ð��z#Ð&ò2p8v†(��Æ&X2��¾&À&��z° ʈ��„äx5zD������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Üt˜ðþÿÿ�ÿÿ�TT�CO�Out of free storage -- FREE/dev/kmem/�^CO�^tt�-32768��� Unexpected end of file. - Bind error detected processing file %S: 0 top and bottom cannot be used at the same time.�! Bad option in command line: %C >>�rel No output file specified. load�lda�� Can't open output file: %S map Can't open map file: %S � Can't open input file: %S � No input files specified. G = %O6 .MAIN.���'Prerequisites do not agree: %S and %S (Order of bytes in words is inconsistent �Ü(´)()À)*"***2*:*+D+l+ä+š,æ,$-$-Š-4/f.ú.#Symbol format error in input file. 7Differing attributes specified for external CSECT: %S Multiply-defined symbol: %S "Multiply-defined entry point: %S �€/@1j0b1 %I3 %I3 CSECT � %O6 %O6SYM � � %O6ST ENTRY %O6� � %S %I3�" LOAD MAP FOR MODULE %S (FILE %S) �' N ID TYPE ATTR VALUE CS ST NAME# (ADDR) (SIZE)  �ê3þ34J4 End of phase 3.�Ô6x777ProgStartAddress = %O6 ProgSize = %O6 ProgLoadPoint = %O6 �,ProgStartAddress redeclared from %O6 to %O6 �. Binder error (Tell Clark): ID=-1 & TYPE\\=CCS�2929À;€;Bad text directive: %O3  End of phase 4.�Bad offset into text block. �Bad relocation operand. �Byte relocation error. Relocation buffer overflow. � Relocation directives conflict. �òDòDBad text directive: %O3 �Bad offset into text block. �%Relocation with undefined symbol: %S Bad relocation operand. �Byte relocation error. ‰���� ‰�� ‰����/bin/sh�ii����sh�-c�1‰��€ ����ii‰����‰���‰��¶‰����‰���� ‰���� ‰����������������������������������������������������������ÿÿÿÿÿÿÿÿÿÿ‰ÿÿÿÿÿÿÿÿÿÿÿÿ�� �����ÿÿ��������������bind.o����� ���������. ABS.�����GLOBAL�����data����� dpure����\dpure����dstatic���ä ��������æ_end����$�ªiavail���#�Šibset����"�bsetp���"�chk1����"�Pclosal��"�Æclose���"�Ìclosep��"�Ôdelete��"�¬endio���"�2�frebeg��#�‚ifree����"�Ôfreend��#�†ifret����"�Þhigh����#�ˆiinitio��"��last����#�Žilinks���#� cmeminc��#�”imset����"�îmsetp���"�þopen����"�4openp���"�¶pass����#�’ipeek����"�dpeekp���"�ôphdev1��"�popreg��"�random��"�„ranno���"�xrappend�"�°read����"�Ìreadp���"�êrename��"�šrfind���"�úrinsert�"�rndize��"�ªrnewroll"�Vrnext���"�rscan���"�:rsearch�"�`rwhere��"�Jrzap����"�savcall�"�¤savreg��"�rstart���"�êstrm.i��#�zistrm.o��#�|itty.i���#�~itty.o���#�€ivopen���"�vopenp��"�Æwrite���"�ˆwritep��"�à������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������relld�����������������������������������������������������������������������������������������������0000700�0025652�0025652�00000020330�13044134701�010213� 0����������������������������������������������������������������������������������������������������ustar �jnc�����������������������������jnc��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������@˜t5ð ����� ð€&Ð 6�÷ �–%ß Ê‰w ’Æå�õ%��ÎL ß Ü÷ ”N�ß Î À¼À @m�&ß 4Ö À À¦À @m�æk ß ÜÖ  ß Ê· ˆN�ß Î¤ÀxÀ @m�&ß Ö 7QÀ`À @m�æ ß ÜÖ  ß Ê· BN�ß Î�ß  ÷ Š 5öÿß ÷ | 5øÿÈ‹æš ß ÜÖ Nøÿß ÷ œ�÷ °÷‹’P÷ |w�¨w ˜æ ÀäÀ @m��È¥-�7ÀÒÀ · Ì@m��€ 5øÿ@ŸøÿÁ 7 þy� �÷•�@Pµ øÿðÀ�72P7,Pö÷•�*Pò÷•�$Pî÷•�Pê@Ÿøÿæ¾ ß ÜÖ áw�w Æå�5 ìÿ7 ì 7 ê 7Šâ ÷‹àOÀÀ 7´O7 ²O7 °O7 ®O7 ¬O7 ªO7 ¨O÷‹´O� À�7˜O_�0õ%ÿÿøÿ_�B@øÿÀå� �ƒ_�0À x� Î*ß ˜5öÿÎß R5ôÿ÷ & 5îÿõµ�öÿ*÷ 8Oõ ôÿÎÛ ß ÜNîÿ& & & ÷5�O· ONîÿ& & æO@öÿ&føÿß Æe �wmôÿìN_�0õµ�öÿâ÷5�ÜN· ÖNNîÿ& & æÊN@öÿ&føÿß Æe �wmôÿ²N_�0Îrß ˜5öÿÎfß R5ðÿ÷ n 5îÿfðÿ& & @öÿ&føÿß Æe �_�0Î2ß ˜5öÿÎ&ß R5ôÿÎß R5òÿÎß R5ðÿ÷  5îÿõµ�öÿ!õµ�öÿAòÿWp �ñµ�Ÿ"AòÿWp �ul "ôÿ÷‹N AòÿWp �ñµ�Ÿ"õmìMôÿNîÿfðÿfòÿfôÿ«Îžß ˜5öÿÎ’ß R5ôÿ렧 R5òÿÎ �ß  ÷ †5îÿ& fòÿfôÿ@öÿ&føÿß Æe �µ ìÿõ%�ìÿNîÿæò ß ÜÖ AòÿWp �A "Amôÿw^M·Šh÷ 5øÿÀ%�_�ø÷‹VMÁPWp �w2M÷5�&M· M÷5�M· M÷‹*M÷ ðÎ�æ~Qæ"Mß €–%w�0 w ÀìLt÷ÿÀE€ÿÁâLWt÷ÿÁE€ÿ@`ÀÐLÀE�þÁÊLÁE�þ@`÷‹ÖL à Ãe�Î�¦æÌLß \–%Î�ææ¼Lß \–%÷‹¬LÎ!ß Ü ß „ Ä-Žùw�ª w š æ A�Wp �DÄež"÷‹vLÌ¥�Ì¥�c÷‹fLô³�]5 øÿ@øÿ�`p’ŽQµ øÿõ%�øÿòõ%�øÿ�æ=!ß ÜÖ @øÿ0ŠŽQµ øÿõ%�øÿö7 L�“Àå� �‚À x�, ÷�êK7�æK÷‹èK��Wp �AœŸ"f&���&�“&&�f�æS!ß ÜÆe�Î �æŽQæ¬Kß €–%w�º ÷�ŽKÑô³�÷ �€Kôµ��÷U��rKÃ�Wp �ñµ�Ÿ"÷U�ZK·�Wp �ñµ�Ÿ"÷U�BK«÷U�:K§÷�2K£w F  KWp �@ð¥�Ÿ"BÎp!Wp �f¦"ß ( Ö À Îu!Wp �f¦"ß ( Ö À Wp �N¦"& & æÂJæ�Î|!Wp �f¦"ß ( Ö À Wp �N¦"& & æJæ�æ�&ß VÆe �„ Ä-’²w�® w ž N�f �f �f�@�&f�æj· fß VÆe �÷%èX΃!ß Ü ß Êw�f w V A�Wp �DÄež"L�t��t ��t ��t��t��÷‹JÌ¥�Ì¥� ÷‹Jô³�ôð �· êw� w ö Æå�7 äI7 âI_�€ õ5€�øÿ� À�5öÿ@øÿÀE€ÿ5øÿÀå� �ƒ_�x À x�4 ÷ ÞÎDß ˜7žI÷�”I÷ ‚_�€ ÷ ÀÎ&ß ˜7€IÎß R7pIíÎ ß ˜ÀE�ÿ5òÿ@öÿ& æTIfòÿß Ú Æe�@öÿ& æ<Ifòÿß ¬ Æe�_�€ ÎÈß ˜ÀE�ÿ5òÿ@öÿæ�æIfòÿß Ú Æe�@öÿæ�ÛÎ’ß ˜ÀE�ÿ5òÿÎ‚ß R5ôÿ@öÿ& fôÿfòÿß Ú Æe�@öÿ& fôÿ¼ÎPß ˜ÀE�ÿ5òÿÎ@ß R5ôÿ@öÿæ�fôÿfòÿß Ú ¦÷ ²�Îß RÁpHWp �@l "7`H÷ ”�Îúß R5òÿÎîß R7FHWp �A "Amòÿw0HΛ!ß Ü÷ Â5øÿÀ%ÿÿ_�Ê÷ J�w�"w æ 5 øÿ Î ß ˜Aøÿ1®Qµ øÿõ-îGøÿò5 øÿ@øÿ0Š®Rµ øÿõ-ÔGøÿöw�Üw ÌÄ�qøG×t÷ÿÃE€ÿ¬GÂE�þÂe�Á¤GWp �ñµ �Ÿ" ÀjGt÷ÿÀE€ÿ`À\GÀE�þ`Î�ææpGß \–%Î�¦æ`Gß \–%Î^Gæ®QæNGß €–%÷‹:G1ÀGt÷ÿÀE€ÿÁGWt÷ÿÁE€ÿ@``ÀþFÀE�þÁøFÁE�þ@``Î�ææGß \–%Î�¦æøFß \–%ÎöFæ®RææFß €–%÷mäFÜF„ Ä-ØFŒ7 ÒFw�âw ÒÆå�õ‹ �α!ß Ü[@�œ®QÄE�ÿ�œ¯Qt�`A�Wp �C "÷‹‚F0A�Wp �AœŸ"@5øÿÀ5�$A�Wp �Aœž"@5öÿÀ%�õµ�øÿ� À�õ¥�öÿ Á�@Põµ�øÿÃmFõ‹�À� Ä`@�ÁE�ÿp®Q@�WtøÿÁE�ÿp¯Qw�w �D�C�æ õ‹ � ÎÏ!ß ÜôÕ�®Rw�èõ‹�øÁWp �Aœž"@Àå� �ð‚À x�D ÁWp �ñµ�Ÿ"ôÕ�®RâôÕ�®RÞÁWp �A¨"Wt�ÁU�uøÿ@ÀE�ÿ4ЮR@øÿtøÿÀE�ÿ4ЯRÅw fæ Îúß ˜5øÿùw�^w NÆåh�5 ’ÿÎÜß ˜AAm’ÿ1–ÿN’ÿŽ ß N 5”ÿ @”ÿ@m’ÿAAm’ÿHœ–ÿõ ’ÿõ ’ÿò@”ÿw� µ ’ÿõ%d�’ÿÖ5ŠùÿNÎe–ÿæü!ß ÜÖ Îd�ß N 5”ÿ5 ’ÿ@”ÿ@m’ÿAAm’ÿHœ–ÿµ ’ÿõ%d�’ÿñÔw ªæ õ�øÿÎ6ß ˜µ øÿu-�øÿöw�”w „D�C�Ì‹À�w�z„ ƒ Ì¢ö� øf…&æ¦& D�Äe�ÄE�êË5� ‹ÂÊ5�ûÀ�a€ ‡À�aÀ +‡ÂÃÃE�Â-|èƒÃ-vå‚Î�ß Â%ÿÿÀÿÿw�¿ZÀVÀe�€ ÿU�H€Àeþ 7<ÿ"6ÄÀ�a7* †ÿ"ÀÀU� ÀÀe�Ø€�Àeþÿ7ÈE�‡�f…w�úw�ö�‰"†w�r…‡�f…w�â�‰"J‡A� � …‡�7 ^Gf…A�ñå��W,�ÿÿfž�÷ B�@�÷ 8�ñ �@�&”6”�1�€…‡�f…A�ñ �÷ �� @Þ�± �…‡�@Àe�7d1�@�‰$"‡À 1�‡�w�Æw ÐÆå~�w�ÐFDÄe�ÀŸÆF · ÀF %�ß ~ôw�°7 ¬F7 ¬Fׯ¢F-�· šF· ˜F÷¸wŒF7 ŽF .�÷¦w‚FƒÃe�Á*"BÚ üJ� Ó•-�ÀŸXF· TF o�^ x�U d�÷ >F�÷ �w�� r �f÷ ðÿ€Àe0�‡��&Ä €  ‚ Ô•-�÷ �„k À �—v�A W �‡Áå �ƒ ~Áe0�f—v��÷ Öÿ”•‡�•à •Oà MÁ¼E Ân"ŒÒ‹ƒ D~C�� Âb"�� Âh"v��÷ ‚EÓ•0�÷ �(f v€L�v��÷ îÿ€€L�Àe0� 9�Àe�‡�ÀHEÂBE÷ X À:EÂ4E÷ ˜7$Ew�Vþ‚Âe�ƒà&æ �Ä ÃmE÷ Eß ~Ã~Ä Ž”ß ~à Î �ß ~Ã~Ö „w�þ7 ÚD ÀŸÐD· ÌDÀå0� úÿ� �‚· ¸DWp �`ìÀe0�ƒ�f…÷^Zwm�T�‰v"†w�t�ÀHwm�B…‡�f…w�2�‰v"†w�R�w�$� …‡�f…@�w�w��‰|"†w�(�� …‡�f…@�w�öw�ò�‰‚"†w��…‡�7DÀÿÿF…‡�@…&æ¦È B„ƒ‚F…‡�f…÷ @�‰7º ÷�°õ÷ <Á Ó•-� Ó•0�”B~ÁŽÓ•.� Á Ó•0�…~Á ”B~‡�7l ÷�bõ÷ ô�Á Ó•-�”Ó•.�ÁJÁ ”B~Ó•e� Ó•-� Ó•+�� r �Àe0�Áe0�S‡�f…À@C÷ ,�À6CP�· ,C÷ &C÷ �@�…‡�f…÷ �…‡�À C ÀåÈU7ÆÀøB€ �‰ˆ"÷ÈUîB÷�æB×-àB�‚÷�ØB‡�‡�f…¦5õ�w �–÷ *� f…¦5õ�w �€÷ �½�}�‚…‡�7 ÞD÷�ÖD¦ðWð€�&øføæÁÈW 7 ¾D@ñ�ð%· ²DÀñó€@Añ�ð&ø@øÃX7ó ø@ø—ôL>—ó BÀûÀe0�#‚ @ñ�ððÁÈWÑ”× Xü‡õ ‚  ó BAñ�ðú‚ ÷ �÷ � üW X†Îe�ó B@ûÀe0�‡�ÀÈWÀm¾÷ .D€` ÈW‡’Ãe�È¢9� È•0� ÈWƒ ŠöÈ•1�‚ ÁüCÀ†÷ öC€`0ŠÈWÀÈWƒVõõVð‡����������������������������a�l�m�r�s���špx€bVˆÔ¨0,¦ ^þ:~´ö* H ö Ð  ®S >relld {-sralm} infil outfil �File not found: %s �Cannot open %s for output �Prereqs not permitted, %s ignored. �Unknown option: %c ignored. �ASECT not first entry �additional entry %s ignored/n� id name type atrb csect csatr value �Symbol %s truncated. �%3d %8s %5d %5o %5d %5o %6o �_end�_edata�_etext�Symbol table overflow! �Unknown txt command! �Byte relocation not defined! �Byte relocation not allowed in a.out files! �Name truncated: %s �""""‰����‰����‰���Rd�,o� x�tf�‚e�òc��s�^l�~u�r�¢D�(O�X�����üÿðÿ�ðýÿøÿ�à(null)��‰�� X‰����‰����‰ÈU��Ì>ÌÌÌÌÍÌ �crt0.o�����relld.o���~main�����argc������argv������prereq���øÿtitle����öÿ~optchk��argv������cptr�����øÿ~symbld��žcmd������øÿattrib���öÿvalue����ôÿcs�������òÿtable����ðÿname�����îÿnentries�ìÿ~symput��Œns��������off�������sect������~symput1�symb������ns��������cs��������i��������øÿ~symefix�fns��������~symdef��cmd�������attrib����val�������cs������� �tbl������ �nm��������~symfix��Vsymid�����cmd�������attrib����val������ �cs������� �tbl�������nm��������s���������~txtbld��¶cmd������øÿbytflg���öÿvalue����ôÿoffset���òÿ~txtget��š i��������øÿ~txtput��à i���������sect������offs������~txtfix��Ú offset����id��������sign������bytflg��� �oldwrd����newwrd����atr������øÿtyp������öÿ~txtrel��¬ offset����id��������pc_rel����bytflg��� �fixval���øÿ~getcmd��F cmd������øÿ~gets����^ string���–ÿnew_str��”ÿi��������’ÿ~skip���� cnt�������i��������øÿ~cmpstr��( s1��������s2��������alloc.o��N ~alloc���N p���������q���������nbytes����nb��������~free����p���������creat.o��getc.o���4badret���Øfill�����¸printf.o�Üformp����ºUloop�����ðrjust����¼Undigit���ÀUgnum�����àwidth����¸Undfnd����¾Uswtab����*"decimal��Roctal����,hex������ float����tscien����‚charac���òstring����longorun�^unsigned�~remote���long�����¢loct�����(lhex�����prbuf����šnulstr���n"prstr����¢sbrk.o���nd�������z"seek.o���\write.o��€cerror.o�¢csv.o����°exit.o���Êfltpr.o��Øputchr.o�~fl�������¸cleanup.�îecvt.o���ðeflag���� Xbuf������ÈWsign�����Xzer������šone������€@lss������žgtr������bbuftop���Xtenth����Ž"epsilon��L>ten������ Bpad������°digit1���Ædigit����¸out������Ðoutout���savr5���$�¶U_exit���"�Êstart���"���_main���"��_sym����$�˜"_hdr����$�~Q_asym���$�ŽQ_rflag��$�šQ_sflag��$�œQ_mflag��$�žQ_aflag��$� Q_lflag��$�¢Q_p������#� csv�����"�°_printf�"�Ü_optchk�"�_input��#�J _fopen��"�4_creat��"�_output�$�¤Q_skip���"� _gets���"�^ _free���"�_symbld�"�ž_txtbld�"�¶_symput�"�Œcret����"�¼_getc���"�˜_getw���"�R_symdef�"�_getcmd�"�F _symefix"�f_write��"�€_seek���"�\_symput1"�_cmpstr�"�( _symfix�"�V_txt����$�¦Q_txtput�"�à _txtget�"�š _txtfix�"�Ú _txtrel�"�¬ _in_buf�$�®S_alloc��"�N _allocs�#�"_allocp�#�"_alloct�#�"_sbrk���"�cerror��"�¢_errno��$�´Upfloat��"�Øpscien��"�&_putchar"�~_end����$� X_brk����"�<__cleanu"�îfltused�"�Ø_ndigit�#�–"ecvt����"�.fcvt����"�(_flush��"�¬_fout���$�ÂU_ecvt���"�ð_fcvt���"���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������relld.c���������������������������������������������������������������������������������������������0000600�0025652�0025652�00000053403�13044137031�010441� 0����������������������������������������������������������������������������������������������������ustar �jnc�����������������������������jnc��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# /* RELLD: .rel to a.out converter Program converts files in .rel format to files in a.out format It expects two arguments, the first is a file in .rel format and the second is a filename for the resulting a.out format file. */ /* Define the .rel commands */ #define CMD_CS 1 #define CMD_ST 2 #define CMD_SYM 3 #define CMD_ENTRY 4 #define CMD_END 5 #define CMD_MIXID 6 #define CMD_TXT 21 #define CMD_TXTR 22 #define CMD_ABS 23 #define CMD_REL 24 #define CMD_ABSX 25 #define CMD_RELX 26 #define CMD_LCS 27 #define CMD_LCSX 28 /* Define the command attribute bits */ #define A_EXT 01 /* external variable */ #define A_ISPC 02 /* csect in i space */ #define A_PURE 04 /* csect is pure */ #define A_ABS 010 /* absolute csect, used only for symbols */ #define A_DEF 020 /* symbol is defined */ /* Define the relocation bits for a.out files */ #define R_ABS 00 /* absolute reference */ #define R_RELOC 01 /* pc relative reference */ #define R_TEXT 02 /* text segment reference */ #define R_DATA 04 /* data segment reference */ #define R_EXT 010 /* external reference */ /* Define a.out symbol types */ #define S_EXTERN 040 /* external symbol */ #define S_UNDEF 00 /* undefined symbol */ #define S_ABS 01 /* absolute symbol */ #define S_TEXT 02 /* text segment symbol */ #define S_DATA 03 /* data segment symbol */ #define S_CSECT 06 /* csect symbol */ #define S_ST 07 /* symbol table symbol */ #define S_ENTRY 010 /* entry symbol */ /* Define some miscellanious parameters */ #define nsymbols 1000 /* number of entries in symbol table */ #define RELFLG 01 /* flag indicates relative rather than abs */ /* Define the major data structures */ /* Symbol Table Entries */ struct symbol { char type; /* type from command type */ char attributes; /* attributes depending on type */ int value; /* value depending on type */ int csect; /* csect id of csect containing symbol */ int table; /* tbl id of symbol table containing symbol */ char *name; /* pointer to asciz string name */ int newnum; /* number in new numbering scheme */ }; /* Symbol Table and related data */ struct { char mixid; /* flag indicating I=D loading */ int next; /* next free symbol table entry */ int num; /* total number of symbols output */ struct symbol tbl[nsymbols]; /* actual symbol table */ } sym; /* Define the header data structures */ struct header { int magic; /* magic number to specify how to load */ int txtsiz; /* size of the text segment */ int datsiz; /* size of the tata segment*/ int bsssiz; /* size of the bss segment */ int symsiz; /* size of the symbol table */ int entry; /* entry location */ int unused; /* unused slot */ int relflg; /* flag which specifies surpress relocation */ } hdr; /* Define storage for a.out symbols. */ struct { char aname[8]; /* name of the symbol */ int atype; /* type of the symbol */ int aval; /* value of the symbol */ } asym; /* A few useful macros to do things with symbols */ #define symval(symb) (((sym.tbl)[symb]).value) #define symatr(symb) (((sym.tbl)[symb]).attributes) #define symtyp(symb) (((sym.tbl)[symb]).type) #define symnam(symb) (((sym.tbl)[symb]).name) /* Main is the top level routine. It processes the arguments by opening the input and output files, then calls symbld to build the symbol table, txtbld to process the text and symput to output any symbols. */ char rflag,sflag,mflag,aflag,lflag; /* storage for the options flags */ int p 1; /* current argument number */ main(argc, argv) int argc; char **argv;{ char *prereq, *title; /* temporary variable to hold prereq */ extern char *input; /* pointer to input buffer */ extern int output; /* output file id */ if (argc == 1) { printf("\n>relld {-sralm} infil outfil\n"); exit(); } optchk(argv); /* check for options argument */ if (fopen(argv[p], input) < 0) { printf("File not found: %s\n", argv[p]); exit(0); } else p++; optchk(argv); /* check for options argument again */ if ((output = creat(argv[p], 0644)) < 0) { printf("Cannot open %s for output\n", argv[p]); exit(0); } else p++; optchk(argv); /* last chance for options */ skip(6); /* skip the creation date/time */ title = gets(); /* get the title */ free(title); /* free up the string */ if ((prereq = gets())[0] != 0) { printf("Prereqs not permitted, %s ignored.\n", prereq); }; free(prereq); /* release the prereq string */ symbld(); /* build the symbol table from input file */ txtbld(); /* build the text part of the output file */ if (sflag) symput(); /* output symbols from the symbol table */ }; /* Subroutine to set option flags and advance arg pointer p, if this was an argument of the form -x where x is: s for symbols r for relocation bits, implies s also a for including all symbols l for deleting all local symbols m for map (outputs relld debugging info) */ optchk(argv) char **argv; { char *cptr; /* which option char we are looking at */ if (argv[p][0] == '-') { for (cptr = &argv[p++][1];; cptr++) switch (cptr[0]) { case 's': sflag = 1; break; case 'r': rflag = sflag = 1; break; case 'a': aflag = 1; break; case 'l': lflag = 1; break; case 'm': mflag = 1; break; case 0: return; default: printf("Unknown option: %c ignored.\n", cptr[0]); } } } /* Symbld reads in the symbol part of the input file and builds up the symbol table. When the end of the symbol section is found, via the END command, and the csects will be defined. */ symbld(){ int cmd; /* type of current command */ char attrib; /* attributes byte of command */ int value; /* value word of command */ int cs; /* csect of symbol */ int table; /* symbol table id of symbol */ char *name; /* pointer to name string */ int nentries; /* number of entry commands seen */ extern char *input; /* pointer to input buffer */ extern int output; /* output file id */ nentries = 0; /* have not seen any so far */ sym.next = 0; /* initially symtab empty */ sym.num = 0; /* and none selected for output */ sym.mixid = 0; /* initially not I=D */ hdr.magic = rflag ? 0407 : 0411; /* magic number */ hdr.txtsiz = 0; /* account for ehack */ hdr.datsiz = 0; /* or any data csects */ hdr.bsssiz = 0; /* bss should always be 0 for now */ hdr.symsiz = 0; /* no symbols yet */ hdr.entry = 0; /* entry 0 for now */ hdr.unused = 0; /* as it says... */ hdr.relflg = (rflag == 0); /* suppress relocation if rflag == 0 */ while ((cmd = getcmd()) != CMD_END && cmd != -1) switch (cmd) { /* Csect commands define new csects. Their value is the current value of hdr.txtsiz or hdr.datsiz depending on the type of the csect. The appropriate offset is incremented by the length of the csect. */ case CMD_CS: attrib = getc(input); /* get the attributes byte */ value = getw(input); /* get the length of the csect */ name = gets(); /* get the name of the csect */ if (attrib & A_ABS) { if ((hdr.txtsiz != 0) && (value != 0)) printf("ASECT not first entry\n"); symdef(cmd, attrib, 0, 0, 0, name); hdr.txtsiz =+ value; break; } if (attrib & A_ISPC) { if (hdr.txtsiz & 1) hdr.txtsiz =+ 1; /* word aligned */ symdef(cmd, attrib, hdr.txtsiz, 0, 0, name); hdr.txtsiz =+ value; break; } else { if (hdr.datsiz & 1) hdr.datsiz =+ 1; /* word aligned */ symdef(cmd, attrib, hdr.datsiz, 0, 0, name); hdr.datsiz =+ value; break; }; /* ST commands define a new symbol table name. They have no attributes, no value, and no csect. */ case CMD_ST: attrib = getc(input); /* get the attributes byte */ table = getw(input); /* get the id of symbol table it belongs to */ name = gets(); /* get the name of this symbol table */ symdef(cmd, attrib, 0, 0, table, name); break; /* SYM commands define normal symbols. They have the full complement of attributes, value, csect, table, and name. Relative symbols defined for i space or d space references are relocated. */ case CMD_SYM: attrib = getc(input); /* get the attributes byte */ value = getw(input); /* get the value of the symbol */ cs = getw(input); /* get the CSECT this symbol belongs to */ table = getw(input); /* get the symbol table it belongs to */ name = gets(); /* get the name of the symbol */ if ((attrib & A_DEF) && !(attrib & A_ABS) && !(symatr(cs) & A_ABS)) { value =+ symval(cs); if (rflag && ((symatr(cs) & A_ISPC) == 0)) value =+ hdr.txtsiz; } symdef(cmd, attrib, value, cs, table, name); break; /* ENTRY commands define entry points into the module. Any additional ENTRY commands will cause an error. They have a csect, a spares field which is skipped, and a name. */ case CMD_ENTRY: attrib = getc(input); /* get the attributes byte */ value = getw(input); /* get the entry value */ cs = getw(input); /* get the csect of this entry */ skip(10); /* skip the spares field */ name = gets(); /* get the name of this entry */ symdef(cmd, attrib, value, cs, 0, name); if ( ++nentries > 1 ) { printf("additional entry %s ignored/n", name); } else { hdr.entry = value + symval(cs); /* entry is offset in csect */ }; break; /* MIXID commands simply set the sym.mixid flag. */ case CMD_MIXID: ++(sym.mixid); /* increment the flag */ break; }; /* Now write out the header */ if (sflag) /* if doing syms, set size */ hdr.symsiz = sym.num * sizeof(asym); if (hdr.txtsiz & 1) hdr.txtsiz =+ 1; /* text space word aligned */ if (hdr.datsiz & 1) hdr.datsiz =+ 1; /* data space word aligned */ if (rflag == 0) symefix(); /* fill in values for _end etc */ write(output, &hdr, sizeof hdr); /* write out the header */ }; /* Routine outputs the symbol table in a.out format. It first seeks to the right spot in the output file, which is twice the size of txt and data segments (to account for relocation bits), plus the size of the header. Then it outputs symbols in a.out form. */ symput() { register int ns,off,sect; /* symbol, offset and sector vars */ extern int output; /* file id of output file */ sect = (((hdr.txtsiz >> 9) & 0177) + ((hdr.datsiz >> 9) & 0177)); off = (hdr.txtsiz & 0777) + (hdr.datsiz & 0777); if (rflag) { sect =* 2; /* double sizes to include rel bits */ off =* 2; } off =+ sizeof hdr; /* be sure we skip the header */ seek(output, sect, 3); /* seek to right block */ seek(output, off, 1); /* seek to here plus offset */ if (mflag) printf(" id name type atrb csect csatr value\n"); for (ns = 0; ns < sym.next; ns++) symput1(ns); } /* Routine to ouput one symbol in a.out format */ symput1(symb) int symb; /* ID of current symbol */ { register struct symbol *ns, *cs; /* pointers to current symb and cs */ int i; /* index variable */ extern int output; /* file id of output file */ ns = &sym.tbl[symb]; if ((aflag == 0) && (ns->type != CMD_SYM) && (ns->type != CMD_ENTRY)) return; if ((lflag != 0) && (((ns->attributes) & A_EXT) == 0)) return; for ( i = 0; i < 8; i++) if((asym.aname[i] = ns->name[i]) == 0) break; if ( i > 8) printf("Symbol %s truncated.\n", ns->name); for ( ; i < 8; i++) (asym.aname)[i] = 0; asym.atype = 0; /* initially, undefined, then or in type */ switch (ns->type) { /* set up type based on type of symbol */ case CMD_CS: asym.atype = S_CSECT; break; case CMD_ST: asym.atype = S_ST; break; case CMD_SYM: if ((ns->attributes) & A_EXT) asym.atype = S_EXTERN; if (((ns->attributes) & A_DEF) == 0) asym.atype =| S_UNDEF; else { if (symatr(ns->csect) & A_ABS) asym.atype =| S_ABS; else if (symatr(ns->csect)&A_ISPC)asym.atype =| S_TEXT; else asym.atype =| S_DATA; }; break; case CMD_ENTRY: asym.atype = S_ENTRY; break; }; /* close switch */ asym.aval = ns->value; /* get value of symbol */ if (mflag) printf("%3d %8s %5d %5o %5d %5o %6o\n", symb, ns->name, ns->type, ns->attributes, ns->csect, symatr(ns->csect), ns->value); write(output, &asym, sizeof asym); /* write out this symbol */ }; /* close routine */ /* Subroutine to search the symbol table for the symbols _end, _etext, and _edata, and fill in values if these symbols are global and undefined. Symbols _end and _edata will give the address of the first location after the data segment ie hdr.datsiz. Symbol _etext will be hdr.txtsiz. */ symefix() { register int ns; for (ns = 0; ns < sym.next; ns++) if (symatr(ns) == A_EXT) { /* must be extern and undef */ if (cmpstr(symnam(ns),"_end")||cmpstr(symnam(ns),"_edata")) symfix(ns,CMD_SYM,A_EXT|A_DEF,hdr.datsiz,0,0,symnam(ns)); else if (cmpstr(symnam(ns), "_etext")) symfix(ns,CMD_SYM,A_EXT|A_DEF|A_ISPC,hdr.txtsiz,0,0,symnam(ns)); } } /* Subroutine to define a symbol table entry. */ symdef(cmd, attrib, val, cs, tbl, nm) int cmd; /* the command type */ char attrib; /* attributes char */ int val; /* value word */ int cs; /* csect id */ int tbl; /* symbol table id */ char *nm; { /* pointer to name string */ symfix((sym.next)++, cmd, attrib, val, cs, tbl, nm); if (sym.next >= nsymbols) { printf("Symbol table overflow!\n"); exit(0); } } /* Subroutine to store the values of a symbol table entry. */ symfix(symid, cmd, attrib, val, cs, tbl, nm) int symid; /* index of symbol in symbol table */ char attrib; /* attributes char */ int val; /* value word */ int cs; /* csect id of csect symbol belongs to */ int tbl; /* symbol table id of table of this symbol */ char *nm; { /* pointer to name of the symbol */ register struct symbol *s; /* pointer to symbol we are defining */ s = &((sym.tbl)[symid]); s->type = cmd; s->attributes = attrib; s->value = val; s->csect = cs; s->table = tbl; s->name = nm; if ((aflag == 0) && (s->type != CMD_SYM) && (s->type != CMD_ENTRY)) return; if ((lflag != 0) && (((s->attributes) & A_EXT) == 0)) return; s->newnum = sym.num++; }; /* Define txt data structures */ /* txt buffer and associated data */ struct { int lc; /* location counter */ int rpt; /* repeat count */ int csid; /* csect id (in symbol table) */ int length; /* number of bytes in txt buffer */ char buffer[256]; /* the text buffer */ char reloc[256]; /* relocation words buffer */ } txt; /* Routine builds the txt and data parts of the output file by reading txt commands from the input file and outputtting txt blocks after rel and abs fixups. */ txtbld() { int cmd; /* command type */ char bytflg; /* 1=>byte command, 0=>word command */ int value; /* temporary used in reading in stuff */ int offset; /* temp used to read in buffer offsets */ extern char *input; /* input file pointer */ txt.lc = 0; /* init location counter at 0 */ txt.rpt = 0; /* so our initial txtput won't put anyghing */ /* read a command, set byte flag and dispatch on bits 0-6 as cmd type */ while ((cmd = getcmd()) != -1) { /* -1 means eof */ bytflg = ((cmd & 0200) != 0); /* check high order bit */ cmd = (cmd & 0177); /* clear the high order bit to dispatch */ switch (cmd) { /* dispatch on command */ /* Txt command, first empties the txt buffer then reads a new block of txt into the buffer. Rpt count is set to 1, to output code once. */ case CMD_TXT: txtput(); /* empty anything currently in buffer */ txt.length = getc(input); /* get the length of the text */ txt.rpt = 1; /* set rpt count to 1 */ txtget(); /* finally, read in the block of txt */ break; /* Txtr command is just like txt except that it has a rpt count built in so it may output the txt many times. */ case CMD_TXTR: txtput(); /* flush anything currently in buffer */ txt.length = getc(input); /* get the length of txt in bytes */ txt.rpt = getw(input); /* set the rpt count */ txtget(); /* finally, read in the block of txt */ break; /* ABS command adds base address of current CSECT to word/byte at offset */ case CMD_ABS: offset = getc(input) & 0377; /* get offset into current txt blk to fix */ txtfix(offset, txt.csid, 0, bytflg); /* fix it in positive */ txtrel(offset, txt.csid, 0, bytflg); /* set up relocation */ break; /* REL command subtracts base of CSECT to word/byte at offset */ case CMD_REL: offset = getc(input) & 0377; /* get offset */ txtfix(offset, txt.csid, 1, bytflg); /* subtract the fix */ txtrel(offset, txt.csid, 1, bytflg); /* we want pc relocation */ break; /* ABSX command like ABS except has ID argument. */ case CMD_ABSX: offset = getc(input) & 0377; /* get offset */ value = getw(input); /* get ID whose value is the fix value */ txtfix(offset, value, 0, bytflg); /* fix it positive */ txtrel(offset, value, 0, bytflg); /* setup relocation word */ break; /* RELX command like REL except has ID argument. */ case CMD_RELX: offset = getc(input) & 0377; /* get offset */ value = getw(input); /* get id */ txtfix(offset, value, 1, bytflg); /* fix it */ break; /* LCS command just moves the location counter. */ case CMD_LCS: txtput(); /* flush txt buffer */ txt.lc = symval(txt.csid) + getw(input); break; /* LCSX command like LCS but with ID argument. */ case CMD_LCSX: txtput(); /* flush txt buffer */ offset = getw(input); /* the new lc offset */ txt.csid = getw(input); /* set this to current CSECT */ txt.lc = symval(txt.csid) + offset; break; default: printf("Unknown txt command!\n"); }; /* close switch */ }; /* close while loop */ txtput(); /* empty anything remaining in buffer */ }; /* Routine to read in a block of txt from input file into txt.buffer. Uses txt.length as count. */ txtget() { int i; /* counter */ extern char *input; /* pointer to input buffer */ for ( i = 0; i < txt.length; i++) txt.buffer[i] = getc(input); for ( i = 0; i < txt.length; i++) txt.reloc[i] = 0; }; /* Routine to output the contents of txt.buffer into the right place in the file. Finds offset in file of this CSECT from symspc, and finds offset of CSECT in its space, from symoff, and uses txt.lc as the final offset for the place to put txt.buffer. Updates txt.lc by the length of the stuff in txt.buffer. */ txtput() { extern int output; /* file id of output file */ register int i,sect,offs; /* variables */ for (i = 1 ; i <= txt.rpt; i++ ) { sect = (txt.lc >> 9) & 0177; offs = txt.lc & 0777; offs =+ sizeof hdr; if ((symatr(txt.csid) & (A_ISPC | A_ABS)) == 0) { sect =+ (hdr.txtsiz >> 9) & 0177; offs =+ hdr.txtsiz & 0777; }; seek(output, sect, 3); seek(output, offs, 1); write(output, txt.buffer, txt.length); if (rflag) { sect =+ ((hdr.txtsiz >> 9) & 0177) + ((hdr.datsiz >> 9) & 0177); offs =+ (hdr.txtsiz & 0777) + (hdr.datsiz & 0777); seek(output, sect, 3); seek(output, offs, 1); write(output, txt.reloc, txt.length); }; txt.lc =+ txt.length; }; txt.rpt = 0; }; /* Routine to fix a word or byte in txt.buffer by adding a value to that wrd. */ txtfix(offset, id, sign, bytflg) int offset; /* offset in txt.buffer to change */ int id; /* the id of csect or symbol to fix */ char sign; /* 0=> add value of id, 1 => subtract */ char bytflg; { /* 0=> word fix, 1 => byte fix */ register int oldwrd, newwrd; char atr,typ; /* will contain attributes of id */ if (bytflg) printf("Byte relocation not defined!\n"); else { oldwrd = txt.buffer[offset] & 0377; oldwrd =+ txt.buffer[offset + 1] << 8; newwrd = symval(id); if (rflag && (((atr = symatr(id)) & A_ABS) == 0)) if ((((typ = symtyp(id))==CMD_SYM) && (atr & A_DEF)) | (typ == CMD_CS)) if ((atr & A_ISPC) == 0) newwrd =+ hdr.txtsiz; if (sign) newwrd = -newwrd; oldwrd =+ newwrd; txt.buffer[offset] = oldwrd & 0377; txt.buffer[offset+1] = (oldwrd >> 8) & 0377; } }; /* Subroutine to put the proper kind of relocation bits in relocation word */ txtrel(offset, id, pc_rel, bytflg) register int offset; /* offset into current block */ register int id; /* symbol or csect id */ char pc_rel; /* 1 => set the pc rel bit and return */ char bytflg; { /* 1 => the fix should be on a byte */ int fixval; /* the value we intend to install */ if (bytflg) { printf("Byte relocation not allowed in a.out files!\n"); return; }; if (pc_rel) { txt.reloc[offset] =| R_RELOC; /* specify pc relative reloc */ return; /* that's all for now */ } switch (symtyp(id)) { /* switch on the type of symbol */ case CMD_CS: if (symatr(id) & A_ISPC) txt.reloc[offset] =| R_TEXT; else txt.reloc[offset] =| R_DATA; break; case CMD_SYM: fixval = R_EXT | ((sym.tbl)[id].newnum << 4); txt.reloc[offset] =| fixval & 0377; txt.reloc[offset + 1] =| (fixval >> 8) & 0377; break; }; }; /* io buffer for input file */ struct iobuf { int fildef; int nleft; char *nextp; char buff[512]; } in_buf; /* miscellanious variables */ int output; /* file id of output file */ char *input &in_buf; /* pointer to input buffer */ /* Miscellanious Subroutines */ /* Subroutine to get a command byte from input file. Ignores leading bzeros. */ getcmd() { int cmd; /* temporary for value we will return */ while ((cmd = getc(input)) == 0); /* get a non-zero char */ return (cmd); /* return the first non-zero command */ }; /* Subroutine to get an asciz string from input file. It allocates a buffer for the string from free storage. Names have a maximum length of namesize characters. */ gets() { char string[100]; /* temporary to hold string as we read in */ char *new_str; /* temporary pointer to newly allocate string */ int i; /* temporary index */ for ( i = 0; i < 100; i++) if ((string[i] = getc(input)) == 0) { new_str = alloc(i + 1); /* allocate a new string */ for ( ; i >= 0; i--) new_str[i] = string[i]; return (new_str); }; string[99] = 0; /* force a zero at end of string */ printf("Name truncated: %s\n", string); new_str = alloc(100); for (i = 0; i < 100; i++) new_str[i] = string[i]; return (new_str); }; /* Routine to skip chars in the input file */ skip(cnt) int cnt; { /* number of chars to skip */ int i; /* temporary for loop */ for ( i = 1; i <= cnt; i++) getc(input); }; /* Routine to compare two character strings */ cmpstr(s1, s2) register char *s1, *s2; { /* pointers to strings we are comparing */ while (*s1 == *s2) { if (*s1 == 0) return(1); s1++; s2++; } return(0); } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������relld.c.new�����������������������������������������������������������������������������������������0000600�0025652�0025652�00000050147�13044137031�011233� 0����������������������������������������������������������������������������������������������������ustar �jnc�����������������������������jnc��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# /* RELLD: .rel to a.out converter * This program converts files in .rel format to files in a.out format; * it expects two arguments; the first is a file in .rel format * and the second is a filename for the resulting a.out format * file. */ /* Define the .rel commands */ #define CMD_CS 1 #define CMD_ST 2 #define CMD_SYM 3 #define CMD_ENTRY 4 #define CMD_END 5 #define CMD_MIXID 6 #define CMD_TXT 21 #define CMD_TXTR 22 #define CMD_ABS 23 #define CMD_REL 24 #define CMD_ABSX 25 #define CMD_RELX 26 #define CMD_LCS 27 #define CMD_LCSX 28 /* Define the command attribute bits */ #define A_EXT 01 /* external variable */ #define A_ISPC 02 /* csect in i space */ #define A_PURE 04 /* csect is pure */ #define A_ABS 010 /* absolute csect, used only for symbols */ #define A_DEF 020 /* symbol is defined */ /* Define the relocation bits for a.out files */ #define R_ABS 00 /* absolute reference */ #define R_RELOC 01 /* pc relative reference */ #define R_TEXT 02 /* text segment reference */ #define R_DATA 04 /* data segment reference */ #define R_EXT 010 /* external reference */ /* Define a.out symbol types */ #define S_UNDEF 00 /* undefined symbol */ #define S_ABS 01 /* absolute symbol */ #define S_TEXT 02 /* text segment symbol */ #define S_DATA 03 /* data segment symbol */ #define S_CSECT 06 /* csect symbol */ #define S_ST 07 /* symbol table symbol */ #define S_ENTRY 010 /* entry symbol */ #define S_EXTERN 040 /* external symbol */ /* Define some miscellanious parameters */ #define NSYMBOLS 1000 /* number of entries in symbol table */ #define RELFLG 01 /* flag indicates relative rather than abs */ /* The header data structures */ struct header { int magic; /* magic number */ int txtsiz; /* size of the text segment */ int datsiz; /* size of the tata segment*/ int bsssiz; /* size of the bss segment */ int symsiz; /* size of the symbol table */ int entry; /* entry location */ int unused; /* unused slot */ int relflg; /* flag which specifies relocation */ } hdr; /* Define storage for a.out symbols. */ struct { char aname[8]; /* name of the symbol */ int atype; /* type of the symbol */ int aval; /* value of the symbol */ } asym; /* Symbol Table Entries */ struct symbol { char type; /* type from command type */ char attributes; /* attributes depending on type */ int value; /* value depending on type */ int csect; /* csect id of csect containing sym */ int table; /* table id of symtab containing sym */ char *name; /* pointer to asciz string name */ }; struct symbol tbl[NSYMBOLS]; /* actual symbol table */ int next; /* next free symbol table entry */ /* A few useful macros to do things with symbols */ #define symval(symb) (((tbl)[symb]).value) #define symatr(symb) (((tbl)[symb]).attributes) #define symtyp(symb) (((tbl)[symb]).type) #define symnam(symb) (((tbl)[symb]).name) /* I/O buffer for input file */ struct iobuf { int fildef; int nleft; char *nextp; char buff[512]; } in_buf; int output; /* file id of output file */ char *input &in_buf; /* pointer to input buffer */ char mixid; /* flag indicating I=D loading */ char rflag, iflag, nflag, mflag; /* storage for the options flags */ char sflag 1; /* default is to include symbols */ int p 1; /* current argument number */ /* Main is the top level routine. It processes the arguments by * opening the input and output files, then calls symbld to build * the symbol table, txtbld to process the text and symput to output * any symbols. */ main(argc, argv) char *argv[]; { char *prereq, *title; /* temporary variable to hold prereq */ optchk(argv); if (fopen(argv[p], input) < 0) { printf("File not found: %s\n", argv[p]); exit(0); } else p++; optchk(argv); if ((output = creat(argv[p], 0644)) < 0) { printf("Cannot open %s for output\n", argv[p]); exit(0); } else p++; optchk(argv); skip(6); /* skip the creation date/time */ title = gets(); free(title); if (*(prereq = gets()) != 0) { printf("Prereqs not permitted, %s ignored.\n", prereq); }; free(prereq); symbld(); /* build the symbol table from input file */ txtbld(); /* build the text part of the output file */ if (sflag) symput(); /* output symbols from the symbol table */ }; /* Subroutine to set option flags and advance arg pointer p, args are: * s for symbol supression * r for relocation bits * i for separate spaces * n for pure in one space * m for map (outputs relld debugging info) */ optchk(argv) char *argv[]; { char *cptr; if (argv[p][0] == '-') { for (argv[p++][1]; ; cptr++) switch (cptr[0]) { case 's': sflag = 0; break; case 'r': rflag = 1; break; case 'i': iflag = 1; break; case 'n': nflag = 1; break; case 'm': mflag = 1; break; case 0: return; default: printf("Bad option: %c ignored.\n", cptr[0]); } } } /* Symbld reads in the symbol part of the input file and builds up * symbol tabl until end of the symbol section is found, via the END * command. Since we have all the CSECTS before their symbols, and no * references to resolve, we can allocate memory on the fly. */ symbld() { int cmd; /* type of current command */ char attrib; /* attributes byte of command */ int value; /* value word of command */ int cs; /* csect of symbol */ int table; /* symbol table id of symbol */ char *name; /* pointer to name string */ int nentries; /* number of entry commands seen */ nentries = 0; next = 0; if (iflag) hdr.magic = 0411; else if (nflag) hdr.magic = 0410; else hdr.magic = 0407; hdr.txtsiz = 0; hdr.datsiz = 0; hdr.bsssiz = 0; /* bss should always be 0 for now */ hdr.symsiz = 0; hdr.entry = 0; hdr.unused = 0; hdr.relflg = (rflag == 0); while ((cmd = getcmd()) != CMD_END && cmd != -1) switch (cmd) { /* CSECT commands define new CSECTs. CSECTs are allocated memory on the * end of the correct area; the ASECT is handled by allocating it first * and putting everybody else on top of it. It goes in the text area * so that it will win if you are not linking for two spaces. */ case CMD_CS: attrib = getc(input); value = getw(input); name = gets(); if (attrib & A_ABS) { if ((hdr.txtsiz != 0) && (value != 0)) printf("ASECT not first CSECT\n"); symdef(cmd, attrib, 0, 0, 0, name); ++hdr.txtsiz =& ~1; /* Round to word */ hdr.txtsiz =+ value; break; } if (attrib & A_ISPC) { ++hdr.txtsiz =& ~1; symdef(cmd, attrib, hdr.txtsiz, 0, 0, name); hdr.txtsiz =+ value; break; } ++hdr.datsiz =& ~1; symdef(cmd, attrib, hdr.datsiz, 0, 0, name); hdr.datsiz =+ value; break; /* ST commands simply insert a symbol in the table. They have no * attributes, no value, and no CSECT. */ case CMD_ST: attrib = getc(input); table = getw(input); name = gets(); symdef(cmd, attrib, 0, 0, table, name); break; /* SYM commands define normal symbols. They have the full complement * of attributes, value, csect, table, and name. Relative symbols * defined for i space or d space references are relocated. */ case CMD_SYM: attrib = getc(input); value = getw(input); cs = getw(input); table = getw(input); name = gets(); if ((attrib & A_DEF) && !(attrib & A_ABS) && !(symatr(cs) & A_ABS)) { value =+ symval(cs); if (!iflag && !(symatr(cs) & A_ISPC)) value =+ hdr.txtsiz; } symdef(cmd, attrib, value, cs, table, name); break; /* ENTRY commands define entry points into the module. Any additional ENTRY commands will cause an error. They have a csect, a spares field which is skipped, and a name. */ case CMD_ENTRY: attrib = getc(input); /* get the attributes byte */ value = getw(input); /* get the entry value */ cs = getw(input); /* get the csect of this entry */ skip(10); /* skip the spares field */ name = gets(); /* get the name of this entry */ symdef(cmd, attrib, value, cs, 0, name); if ( ++nentries > 1 ) { printf("additional entry %s ignored/n", name); } else { hdr.entry = value + symval(cs); /* entry is offset in csect */ }; break; /* MIXID commands simply set the mixid flag. */ case CMD_MIXID: mixid++; /* increment the flag */ break; }; /* Now write out the header */ if (sflag) hdr.symsiz = next * 12; /* if outputing symbols, set size */ if (hdr.txtsiz & 1) hdr.txtsiz =+ 1; /* text space word aligned */ if (hdr.datsiz & 1) hdr.datsiz =+ 1; /* data space word aligned */ if (rflag == 0) symefix(); /* fill in values for _end etc */ write(output, &hdr, sizeof hdr); /* write out the header */ }; /* Routine outputs the symbol table in a.out format. It first seeks to the right spot in the output file, which is twice the size of txt and data segments (to account for relocation bits), plus the size of the header. Then it outputs symbols in a.out form. */ symput() { register int ns,off,sect; /* symbol, offset and sector vars */ extern int output; /* file id of output file */ sect = (((hdr.txtsiz >> 9) & 0177) + ((hdr.datsiz >> 9) & 0177)); off = (hdr.txtsiz & 0777) + (hdr.datsiz & 0777); if (rflag) { sect =* 2; /* double sizes to include rel bits */ off =* 2; } off =+ sizeof hdr; /* be sure we skip the header */ seek(output, sect, 3); /* seek to right block */ seek(output, off, 1); /* seek to here plus offset */ if (mflag) printf(" id name type atrb csect csatr value\n"); for (ns = 0; ns < next; ns++) symput1(ns); } /* Routine to ouput one symbol in a.out format */ symput1(symb) int symb; /* ID of current symbol */ { register struct symbol *ns, *cs; /* pointers to current symb and cs */ int i; /* index variable */ extern int output; /* file id of output file */ ns = &tbl[symb]; for ( i = 0; i < 8; i++) if((asym.aname[i] = ns->name[i]) == 0) break; if ( i > 8) printf("Symbol %s truncated.\n", ns->name); for ( ; i < 8; i++) (asym.aname)[i] = 0; asym.atype = 0; /* initially, undefined, then or in type */ switch (ns->type) { /* set up type based on type of symbol */ case CMD_CS: asym.atype = S_CSECT; break; case CMD_ST: asym.atype = S_ST; break; case CMD_SYM: if ((ns->attributes) & A_EXT) asym.atype = S_EXTERN; if (((ns->attributes) & A_DEF) == 0) asym.atype =| S_UNDEF; else { if (symatr(ns->csect) & A_ABS) asym.atype =| S_ABS; else if (symatr(ns->csect)&A_ISPC)asym.atype =| S_TEXT; else asym.atype =| S_DATA; }; break; case CMD_ENTRY: asym.atype = S_ENTRY; break; }; /* close switch */ asym.aval = ns->value; /* get value of symbol */ if (mflag) printf("%3d %8s %5d %5o %5d %5o %6o\n", symb, ns->name, ns->type, ns->attributes, ns->csect, symatr(ns->csect), ns->value); write(output, &asym, sizeof asym); /* write out this symbol */ }; /* close routine */ /* Subroutine to search the symbol table for the symbols _end, _etext, and _edata, and fill in values if these symbols are global and undefined. Symbols _end and _edata will give the address of the first location after the data segment ie hdr.datsiz. Symbol _etext will be hdr.txtsiz. */ symefix() { register int ns; for (ns = 0; ns < next; ns++) if (symatr(ns) == A_EXT) { /* must be extern and undef */ if (cmpstr(symnam(ns),"_end")||cmpstr(symnam(ns),"_edata")) symfix(ns,CMD_SYM,A_EXT|A_DEF,hdr.datsiz,0,0,symnam(ns)); else if (cmpstr(symnam(ns), "_etext")) symfix(ns,CMD_SYM,A_EXT|A_DEF|A_ISPC,hdr.txtsiz,0,0,symnam(ns)); } } /* Subroutine to define a symbol table entry. */ symdef(cmd, attrib, val, cs, tbl, nm) int cmd; /* the command type */ char attrib; /* attributes char */ int val; /* value word */ int cs; /* csect id */ int tbl; /* symbol table id */ char *nm; { /* pointer to name string */ symfix(next++, cmd, attrib, val, cs, tbl, nm); if (next >= nsymbols) { printf("Symbol table overflow!\n"); exit(0); } } /* Subroutine to store the values of a symbol table entry. */ symfix(symid, cmd, attrib, val, cs, tbl, nm) int symid; /* index of symbol in symbol table */ char attrib; /* attributes char */ int val; /* value word */ int cs; /* csect id of csect symbol belongs to */ int tbl; /* symbol table id of table of this symbol */ char *nm; { /* pointer to name of the symbol */ register struct symbol *s; /* pointer to symbol we are defining */ s = &(tbl[symid]); s->type = cmd; s->attributes = attrib; s->value = val; s->csect = cs; s->table = tbl; s->name = nm; }; /* Define txt data structures */ /* txt buffer and associated data */ struct { int lc; /* location counter */ int rpt; /* repeat count */ int csid; /* csect id (in symbol table) */ int length; /* number of bytes in txt buffer */ char buffer[256]; /* the text buffer */ char reloc[256]; /* relocation words buffer */ } txt; /* Routine builds the txt and data parts of the output file by reading txt commands from the input file and outputtting txt blocks after rel and abs fixups. */ txtbld() { int cmd; /* command type */ char bytflg; /* 1=>byte command, 0=>word command */ int value; /* temporary used in reading in stuff */ int offset; /* temp used to read in buffer offsets */ extern char *input; /* input file pointer */ txt.lc = 0; /* init location counter at 0 */ txt.rpt = 0; /* so our initial txtput won't put anyghing */ /* read a command, set byte flag and dispatch on bits 0-6 as cmd type */ while ((cmd = getcmd()) != -1) { /* -1 means eof */ bytflg = ((cmd & 0200) != 0); /* check high order bit */ cmd = (cmd & 0177); /* clear the high order bit to dispatch */ switch (cmd) { /* dispatch on command */ /* Txt command, first empties the txt buffer then reads a new block of txt into the buffer. Rpt count is set to 1, to output code once. */ case CMD_TXT: txtput(); /* empty anything currently in buffer */ txt.length = getc(input); /* get the length of the text */ txt.rpt = 1; /* set rpt count to 1 */ txtget(); /* finally, read in the block of txt */ break; /* Txtr command is just like txt except that it has a rpt count built in so it may output the txt many times. */ case CMD_TXTR: txtput(); /* flush anything currently in buffer */ txt.length = getc(input); /* get the length of txt in bytes */ txt.rpt = getw(input); /* set the rpt count */ txtget(); /* finally, read in the block of txt */ break; /* ABS command adds base address of current CSECT to word/byte at offset */ case CMD_ABS: offset = getc(input) & 0377; /* get offset into current txt blk to fix */ txtfix(offset, txt.csid, 0, bytflg); /* fix it in positive */ txtrel(offset, txt.csid, 0, bytflg); /* set up relocation */ break; /* REL command subtracts base of CSECT to word/byte at offset */ case CMD_REL: offset = getc(input) & 0377; /* get offset */ txtfix(offset, txt.csid, 1, bytflg); /* subtract the fix */ txtrel(offset, txt.csid, 1, bytflg); /* we want pc relocation */ break; /* ABSX command like ABS except has ID argument. */ case CMD_ABSX: offset = getc(input) & 0377; /* get offset */ value = getw(input); /* get ID whose value is the fix value */ txtfix(offset, value, 0, bytflg); /* fix it positive */ txtrel(offset, value, 0, bytflg); /* setup relocation word */ break; /* RELX command like REL except has ID argument. */ case CMD_RELX: offset = getc(input) & 0377; /* get offset */ value = getw(input); /* get id */ txtfix(offset, value, 1, bytflg); /* fix it */ break; /* LCS command just moves the location counter. */ case CMD_LCS: txtput(); /* flush txt buffer */ txt.lc = symval(txt.csid) + getw(input); break; /* LCSX command like LCS but with ID argument. */ case CMD_LCSX: txtput(); /* flush txt buffer */ offset = getw(input); /* the new lc offset */ txt.csid = getw(input); /* set this to current CSECT */ txt.lc = symval(txt.csid) + offset; break; default: printf("Unknown txt command!\n"); }; /* close switch */ }; /* close while loop */ txtput(); /* empty anything remaining in buffer */ }; /* Routine to read in a block of txt from input file into txt.buffer. Uses txt.length as count. */ txtget() { int i; /* counter */ extern char *input; /* pointer to input buffer */ for ( i = 0; i < txt.length; i++) txt.buffer[i] = getc(input); for ( i = 0; i < txt.length; i++) txt.reloc[i] = 0; }; /* Routine to output the contents of txt.buffer into the right place in the file. Finds offset in file of this CSECT from symspc, and finds offset of CSECT in its space, from symoff, and uses txt.lc as the final offset for the place to put txt.buffer. Updates txt.lc by the length of the stuff in txt.buffer. */ txtput() { extern int output; /* file id of output file */ register int i,sect,offs; /* variables */ for (i = 1 ; i <= txt.rpt; i++ ) { sect = (txt.lc >> 9) & 0177; offs = txt.lc & 0777; offs =+ sizeof hdr; if ((symatr(txt.csid) & (A_ISPC | A_ABS)) == 0) { sect =+ (hdr.txtsiz >> 9) & 0177; offs =+ hdr.txtsiz & 0777; }; seek(output, sect, 3); seek(output, offs, 1); write(output, txt.buffer, txt.length); if (rflag) { sect =+ ((hdr.txtsiz >> 9) & 0177) + ((hdr.datsiz >> 9) & 0177); offs =+ (hdr.txtsiz & 0777) + (hdr.datsiz & 0777); seek(output, sect, 3); seek(output, offs, 1); write(output, txt.reloc, txt.length); }; txt.lc =+ txt.length; }; txt.rpt = 0; }; /* Routine to fix a word or byte in txt.buffer by adding a value to that wrd. */ txtfix(offset, id, sign, bytflg) int offset; /* offset in txt.buffer to change */ int id; /* the id of csect or symbol to fix */ char sign; /* 0=> add value of id, 1 => subtract */ char bytflg; { /* 0=> word fix, 1 => byte fix */ register int oldwrd, newwrd; char atr,typ; /* will contain attributes of id */ if (bytflg) printf("Byte relocation not defined!\n"); else { oldwrd = txt.buffer[offset] & 0377; oldwrd =+ txt.buffer[offset + 1] << 8; newwrd = symval(id); if (rflag && (((atr = symatr(id)) & A_ABS) == 0)) if ((((typ = symtyp(id))==CMD_SYM) && (atr & A_DEF)) | (typ == CMD_CS)) if ((atr & A_ISPC) == 0) newwrd =+ hdr.txtsiz; if (sign) newwrd = -newwrd; oldwrd =+ newwrd; txt.buffer[offset] = oldwrd & 0377; txt.buffer[offset+1] = (oldwrd >> 8) & 0377; } }; /* Subroutine to put the proper kind of relocation bits in relocation word */ txtrel(offset, id, pc_rel, bytflg) int offset; /* offset into current block */ int id; /* symbol or csect id */ char pc_rel; /* 1 => set the pc rel bit and return */ char bytflg; { /* 1 => the fix should be on a byte */ int fixval; /* the value we intend to install */ if (bytflg) { printf("Byte relocation not allowed in a.out files!\n"); return; }; if (pc_rel) { txt.reloc[offset] =| R_RELOC; /* specify pc relative reloc */ return; /* that's all for now */ } switch (symtyp(id)) { /* switch on the type of symbol */ case CMD_CS: if (symatr(id) & A_ISPC) txt.reloc[offset] =| R_TEXT; else txt.reloc[offset] =| R_DATA; break; case CMD_SYM: fixval = R_EXT | (id << 4); txt.reloc[offset] =| fixval & 0377; txt.reloc[offset + 1] =| (fixval >> 8) & 0377; break; }; }; /* Miscellanious Subroutines */ /* Subroutine to get a command byte from input file. Ignores leading bzeros. */ getcmd() { int cmd; /* temporary for value we will return */ while ((cmd = getc(input)) == 0); /* get a non-zero char */ return (cmd); /* return the first non-zero command */ }; /* Subroutine to get an asciz string from input file. It allocates a buffer for the string from free storage. Names have a maximum length of namesize characters. */ gets() { char string[100]; /* temporary to hold string as we read in */ char *new_str; /* temporary pointer to newly allocate string */ int i; /* temporary index */ for ( i = 0; i < 100; i++) if ((string[i] = getc(input)) == 0) { new_str = alloc(i + 1); /* allocate a new string */ for ( ; i >= 0; i--) new_str[i] = string[i]; return (new_str); }; string[99] = 0; /* force a zero at end of string */ printf("Name truncated: %s\n", string); new_str = alloc(100); for (i = 0; i < 100; i++) new_str[i] = string[i]; return (new_str); }; /* Routine to skip chars in the input file */ skip(cnt) int cnt; { /* number of chars to skip */ int i; /* temporary for loop */ for ( i = 1; i <= cnt; i++) getc(input); }; /* Routine to compare two character strings */ cmpstr(s1, s2) register char *s1, *s2; { /* pointers to strings we are comparing */ while (*s1 == *s2) { if (*s1 == 0) return(1); s1++; s2++; } return(0); } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������relld.c.old�����������������������������������������������������������������������������������������0000600�0025652�0025652�00000055051�13044137031�011217� 0����������������������������������������������������������������������������������������������������ustar �jnc�����������������������������jnc��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# /********************************** * * * RELLD: .rel to a.out converter * * * **********************************/ /*Program converts files in .rel format to files in a.out format It expects two arguments, the first is a file in .rel format and the second is a filename for the resulting a.out format file.*/ /* Define the .rel commands */ #define CMD_CS 1 #define CMD_ST 2 #define CMD_SYM 3 #define CMD_ENTRY 4 #define CMD_END 5 #define CMD_MIXID 6 #define CMD_TXT 21 #define CMD_TXTR 22 #define CMD_ABS 23 #define CMD_REL 24 #define CMD_ABSX 25 #define CMD_RELX 26 #define CMD_LCS 27 #define CMD_LCSX 28 /* Define the command attribute bits */ #define A_EXT 01 /* external variable */ #define A_ISPC 02 /* csect in i space */ #define A_PURE 04 /* csect is pure */ #define A_ABS 010 /* absolute csect, used only for symbols */ #define A_DEF 020 /* symbol is defined */ /* Define the relocation bits for a.out files */ #define R_ABS 00 /* absolute reference */ #define R_RELOC 01 /* pc relative reference */ #define R_TEXT 02 /* text segment reference */ #define R_DATA 04 /* data segment reference */ #define R_EXT 010 /* external reference */ /* Define a.out symbol types */ #define S_EXTERN 040 /* external symbol */ #define S_UNDEF 00 /* undefined symbol */ #define S_ABS 01 /* absolute symbol */ #define S_TEXT 02 /* text segment symbol */ #define S_DATA 03 /* data segment symbol */ #define S_CSECT 06 /* csect symbol */ #define S_ST 07 /* symbol table symbol */ #define S_ENTRY 010 /* entry symbol */ /* Define some miscellanious parameters */ #define nsymbols 1000 /* number of entries in symbol table */ #define RELFLG 01 /* flag indicates relative rather than abs */ /* Main is the top level routine. It processes the arguments by opening the input and output files, then calls symbld to build the symbol table, txtbld to process the text and symput to output any symbols. */ char rflag,sflag,mflag; /* storage for the options flags */ int p 1; /* current argument number */ main(argc, argv) int argc; char **argv;{ char *prereq, *title; /* temporary variable to hold prereq */ extern char *input; /* pointer to input buffer */ extern int output; /* output file id */ optchk(argv); /* check for options argument */ /* open input file */ if (fopen(argv[p], input) < 0) { printf("File not found: %s\n", argv[p]); exit(0); } else p++; optchk(argv); /* check for options argument again */ /* create output file */ if ((output = creat(argv[p], 0777)) < 0) { printf("Cannot open %s for output\n", argv[p]); exit(0); } else p++; optchk(argv); /* last chance for options */ /* skip the identification section of .rel file */ skip(6); /* skip the creation date/time */ title = gets(); /* get the title */ free(title); /* free up the string */ if ((prereq = gets())[0] != 0) { printf("Prereqs not permitted, %s ignored.\n", prereq); }; free(prereq); /* release the prereq string */ /* do the work of the program */ symbld(); /* build the symbol table from input file */ txtbld(); /* build the text part of the output file */ if (sflag) symput(); /* output symbols from the symbol table */ }; /* Subroutine to set option flags and advance arg pointer p, if this was an argument of the form -x where x is: s for symbols r for relocation bits, implies s also m for map (outputs relld debugging info) */ optchk(argv) char **argv; { /* pointer to our argument array as passed to main */ char *cptr; /* which option char we are looking at */ if (argv[p][0] == '-') { for (cptr = &argv[p++][1];; cptr++) switch (cptr[0]) { case 's': sflag = 1; break; case 'r': rflag = sflag = 1; break; case 'm': mflag = 1; break; case 0: return; default: printf("Unknown option: %c ignored.\n", cptr[0]); } } } /* Define the major data structures */ /* Symbol Table Entries */ struct symbol { char type; /* type from command type */ char attributes; /* attributes depending on type */ int value; /* value depending on type */ int csect; /* csect id of csect containing symbol */ int table; /* table id of symbol table containing symbol */ char *name; /* pointer to asciz string name */ }; /* Symbol Table and related data */ struct { char mixid; /* flag indicating I=D loading */ int next; /* next free symbol table entry */ struct symbol tbl[nsymbols]; /* actual symbol table */ } sym; /* Define the header data structures */ struct header { int magic; /* magic number to specify how to load */ int txtsiz; /* size of the text segment */ int datsiz; /* size of the tata segment*/ int bsssiz; /* size of the bss segment */ int symsiz; /* size of the symbol table */ int entry; /* entry location, alway 0 for now */ int unused; /* unused slot */ int relflg; /* flag which specifies surpress relocation */ } hdr; /* Define storage for the entry hack. This is the jmp instructuction which is inserted at the beginning of the text segment to take care of the fact that a.out files must have entry at 0. */ struct entryv { int inst; /* initialize to the jump instruction */ int eval; /* address to jump to */ } ehack; /* Define storage for a.out symbols. */ struct { char aname[8]; /* name of the symbol */ int atype; /* type of the symbol */ int aval; /* value of the symbol */ } asym; /* Symbld reads in the symbol part of the input file and builds up the symbol table. When the end of the symbol section is found, via the END command, and the csects will be defined. */ symbld(){ int cmd; /* type of current command */ char attrib; /* attributes byte of command */ int value; /* value word of command */ int cs; /* csect of symbol */ int table; /* symbol table id of symbol */ char *name; /* pointer to name string */ int nentries; /* number of entry commands seen */ extern char *input; /* pointer to input buffer */ extern int output; /* output file id */ nentries = 0; /* have not seen any so far */ sym.next = 0; /* initially symtab empty */ sym.mixid = 0; /* initially not I=D */ /* initialize the header data */ hdr.magic = rflag ? 0407 : 0411; /* magic number */ hdr.txtsiz = 4; /* account for ehack */ hdr.datsiz = 0; /* or any data csects */ hdr.bsssiz = 0; /* bss should always be 0 for now */ hdr.symsiz = 0; /* no symbols yet */ hdr.entry = 0; /* entry always 0 for now */ hdr.unused = 0; /* as it says... */ hdr.relflg = (rflag == 0); /* suppress relocation if rflag == 0 */ /* initialize ehack data ie, jump instruction and location */ ehack.inst = 0137; /* jmp instruction */ ehack.eval = 0; /* somebody had better fix this... */ /* Read in a command and dispatch to proper routine. */ while ((cmd = getcmd()) != CMD_END && cmd != -1) switch (cmd) { /* Csect commands define new csects. Their value is the current value of hdr.txtsiz or hdr.datsiz depending on the type of the csect. The appropriate offset is incremented by the length of the csect. */ case CMD_CS: attrib = getc(input); /* get the attributes byte */ value = getw(input); /* get the length of the csect */ name = gets(); /* get the name of the csect */ if (attrib & A_ABS) { symdef(cmd, attrib, 0, 0, 0, name); break; }; if (attrib & A_ISPC) { if (hdr.txtsiz & 1) hdr.txtsiz =+ 1; /* word aligned */ symdef(cmd, attrib, hdr.txtsiz, 0, 0, name); hdr.txtsiz =+ value; break; } else { if (hdr.datsiz & 1) hdr.datsiz =+ 1; /* word aligned */ symdef(cmd, attrib, hdr.datsiz, 0, 0, name); hdr.datsiz =+ value; break; }; /* ST commands define a new symbol table name. They have no attributes, no value, and no csect. */ case CMD_ST: attrib = getc(input); /* get the attributes byte */ table = getw(input); /* get the id of symbol table it belongs to */ name = gets(); /* get the name of this symbol table */ symdef(cmd, attrib, 0, 0, table, name); break; /* SYM commands define normal symbols. They have the full complement of attributes, value, csect, table, and name. Relative symbols defined for i space or d space references are relocated. */ case CMD_SYM: attrib = getc(input); /* get the attributes byte */ value = getw(input); /* get the value of the symbol */ cs = getw(input); /* get the CSECT this symbol belongs to */ table = getw(input); /* get the symbol table it belongs to */ name = gets(); /* get the name of the symbol */ if ((attrib & A_DEF) && ((attrib & A_ABS) == 0)) { value =+ symval(cs); if (rflag && ((symatr(cs) & A_ISPC) == 0)) value =+ hdr.txtsiz; } symdef(cmd, attrib, value, cs, table, name); break; /* ENTRY commands define entry points into the module. Files in a.out format permit only one entry point at zero, so the first entry command will insert a jmp to its value at the beginning of the ispace, and any additional ENTRY commands will cause an error. They have a csect, a spares field which is skipped, and a name. */ case CMD_ENTRY: attrib = getc(input); /* get the attributes byte */ value = getw(input); /* get the entry value */ cs = getw(input); /* get the csect of this entry */ skip(10); /* skip the spares field */ name = gets(); /* get the name of this entry */ symdef(cmd, attrib, value, cs, 0, name); if ( ++nentries > 1 ) { printf("additional entry %s ignored/n", name); } else { ehack.eval = value + symval(cs); /* entry is offset in csect */ }; break; /* MIXID commands simply set the sym.mixid flag. */ case CMD_MIXID: ++(sym.mixid); /* increment the flag */ break; }; /* Now write out the head and entry hack */ if (sflag) hdr.symsiz = sym.next * 12; /* if outputing symbols, set size */ if (hdr.txtsiz & 1) hdr.txtsiz =+ 1; /* text space word aligned */ if (hdr.datsiz & 1) hdr.datsiz =+ 1; /* data space word aligned */ if (rflag == 0) symefix(); /* fill in values for _end etc */ write(output, &hdr, sizeof hdr); /* write out the header */ write(output, &ehack, sizeof ehack); /* write out the ehack */ }; /* Routine outputs the symbol table in a.out format. It first seeks to the right spot in the output file, which is twice the size of txt and data segments (to account for relocation bits), plus the size of the header. Then it outputs symbols in a.out form. */ symput() { register int ns,off,sect; /* symbol, offset and sector vars */ extern int output; /* file id of output file */ sect = (((hdr.txtsiz >> 9) & 0177) + ((hdr.datsiz >> 9) & 0177)); off = (hdr.txtsiz & 0777) + (hdr.datsiz & 0777); if (rflag) { sect =* 2; /* double sizes to include rel bits */ off =* 2; } off =+ sizeof hdr; /* be sure we skip the header */ seek(output, sect, 3); /* seek to right block */ seek(output, off, 1); /* seek to here plus offset */ if (mflag) printf(" id name type atrb csect csatr value\n"); for (ns = 0; ns < sym.next; ns++) symput1(ns); } /* Routine to ouput one symbol in a.out format */ symput1(symb) int symb; { /* id of current symbol */ register struct symbol *ns, *cs; /* pointers to current symb and cs */ int i; /* index variable */ extern int output; /* file id of output file */ /* get a pointer to current symbol */ ns = &sym.tbl[symb]; /* First write out symbol name. If more than 8 chars, truncate, if less, pad */ for ( i = 0; i < 8; i++) if((asym.aname[i] = ns->name[i]) == 0) break; if ( i > 8) printf("Symbol %s truncated.\n", ns->name); for ( ; i < 8; i++) (asym.aname)[i] = 0; /* Next, put int the type of the symbol. */ asym.atype = 0; /* initially, undefined, then or in type */ switch (ns->type) { /* set up type based on type of symbol */ case CMD_CS: asym.atype = S_CSECT; break; case CMD_ST: asym.atype = S_ST; break; case CMD_SYM: if ((ns->attributes) & A_EXT) asym.atype = S_EXTERN; if (((ns->attributes) & A_DEF) == 0) asym.atype =| S_UNDEF; else { if (symatr(ns->csect) & A_ABS) asym.atype =| S_ABS; else if (symatr(ns->csect)&A_ISPC)asym.atype =| S_TEXT; else asym.atype =| S_DATA; }; break; case CMD_ENTRY: asym.atype = S_ENTRY; break; }; /* close switch */ /* Finally, put in the value of the symbol and write it out */ asym.aval = ns->value; /* get value of symbol */ if (mflag) printf("%3d %8s %5d %5o %5d %5o %6o\n", symb, ns->name, ns->type, ns->attributes, ns->csect, symatr(ns->csect), ns->value); write(output, &asym, sizeof asym); /* write out this symbol */ }; /* close routine */ /* Subroutine to search the symbol table for the symbols _end, _etext, and _edata, and fill in values if these symbols are global and undefined. Symbols _end and _edata will give the address of the first location after the data segment ie hdr.datsiz. Symbol _etext will be hdr.txtsiz. */ symefix() { register int ns; for (ns = 0; ns < sym.next; ns++) if (symatr(ns) == A_EXT) { /* must be extern and undef */ if (cmpstr(symnam(ns),"_end")||cmpstr(symnam(ns),"_edata")) symfix(ns,CMD_SYM,A_EXT|A_DEF,hdr.datsiz,0,0,symnam(ns)); else if (cmpstr(symnam(ns), "_etext")) symfix(ns,CMD_SYM,A_EXT|A_DEF|A_ISPC,hdr.txtsiz,0,0,symnam(ns)); } } /* Subroutine to define a symbol table entry. */ symdef(cmd, attrib, val, cs, tbl, nm) int cmd; /* the command type */ char attrib; /* attributes char */ int val; /* value word */ int cs; /* csect id */ int tbl; /* symbol table id */ char *nm; { /* pointer to name string */ symfix((sym.next)++, cmd, attrib, val, cs, tbl, nm); if (sym.next >= nsymbols) { printf("Symbol table overflow!\n"); exit(0); } } /* Subroutine to store the values of a symbol table entry. */ symfix(symid, cmd, attrib, val, cs, tbl, nm) int symid; /* index of symbol in symbol table */ char attrib; /* attributes char */ int val; /* value word */ int cs; /* csect id of csect symbol belongs to */ int tbl; /* symbol table id of table of this symbol */ char *nm; { /* pointer to name of the symbol */ register struct symbol *s; /* pointer to symbol we are defining */ s = &((sym.tbl)[symid]); s->type = cmd; s->attributes = attrib; s->value = val; s->csect = cs; s->table = tbl; s->name = nm; }; /* Subroutine to return the offset of a csect within its own space, i or d. */ int symval(symb) int symb; { /* symbol id */ return(((sym.tbl)[symb]).value); }; /* Subroutine to return the attributes of a symbol */ symatr(symb) int symb; { return(((sym.tbl)[symb]).attributes); }; /* Subroutine to return the type of a symbol */ char symtyp(symb) int symb; { return (((sym.tbl)[symb]).type); }; /* Subroutine to return the name pointer of a symbol */ symnam(symb) int symb; { return (((sym.tbl)[symb]).name); }; /* Define txt data structures */ /* txt buffer and associated data */ struct { int lc; /* location counter */ int rpt; /* repeat count */ int csid; /* csect id (in symbol table) */ int length; /* number of bytes in txt buffer */ char buffer[256]; /* the text buffer */ char reloc[256]; /* relocation words buffer */ } txt; /* Routine builds the txt and data parts of the output file by reading txt commands from the input file and outputtting txt blocks after rel and abs fixups. */ txtbld() { int cmd; /* command type */ char bytflg; /* 1=>byte command, 0=>word command */ int value; /* temporary used in reading in stuff */ int offset; /* temp used to read in buffer offsets */ extern char *input; /* input file pointer */ txt.lc = 0; /* init location counter at 0 */ txt.rpt = 0; /* so our initial txtput won't put anyghing */ /* read a command, set byte flag and dispatch on bits 0-6 as cmd type */ while ((cmd = getcmd()) != -1) { /* -1 means eof */ bytflg = ((cmd & 0200) != 0); /* check high order bit */ cmd = (cmd & 0177); /* clear the high order bit to dispatch */ switch (cmd) { /* dispatch on command */ /* Txt command, first empties the txt buffer then reads a new block of txt into the buffer. Rpt count is set to 1, to output code once. */ case CMD_TXT: txtput(); /* empty anything currently in buffer */ txt.length = getc(input); /* get the length of the text */ txt.rpt = 1; /* set rpt count to 1 */ txtget(); /* finally, read in the block of txt */ break; /* Txtr command is just like txt except that it has a rpt count built in so it may output the txt many times. */ case CMD_TXTR: txtput(); /* flush anything currently in buffer */ txt.length = getc(input); /* get the length of txt in bytes */ txt.rpt = getw(input); /* set the rpt count */ txtget(); /* finally, read in the block of txt */ break; /* ABS command adds base address of current CSECT to word/byte at offset */ case CMD_ABS: offset = getc(input) & 0377; /* get offset into current txt blk to fix */ txtfix(offset, txt.csid, 0, bytflg); /* fix it in positive */ txtrel(offset, txt.csid, 0, bytflg); /* set up relocation */ break; /* REL command subtracts base of CSECT to word/byte at offset */ case CMD_REL: offset = getc(input) & 0377; /* get offset */ txtfix(offset, txt.csid, 1, bytflg); /* subtract the fix */ txtrel(offset, txt.csid, 1, bytflg); /* we want pc relocation */ break; /* ABSX command like ABS except has ID argument. */ case CMD_ABSX: offset = getc(input) & 0377; /* get offset */ value = getw(input); /* get ID whose value is the fix value */ txtfix(offset, value, 0, bytflg); /* fix it positive */ txtrel(offset, value, 0, bytflg); /* setup relocation word */ break; /* RELX command like REL except has ID argument. */ case CMD_RELX: offset = getc(input) & 0377; /* get offset */ value = getw(input); /* get id */ txtfix(offset, value, 1, bytflg); /* fix it */ break; /* LCS command just moves the location counter. */ case CMD_LCS: txtput(); /* flush txt buffer */ txt.lc = symval(txt.csid) + getw(input); break; /* LCSX command like LCS but with ID argument. */ case CMD_LCSX: txtput(); /* flush txt buffer */ offset = getw(input); /* the new lc offset */ txt.csid = getw(input); /* set this to current CSECT */ txt.lc = symval(txt.csid) + offset; break; default: printf("Unknown txt command!\n"); }; /* close switch */ }; /* close while loop */ txtput(); /* empty anything remaining in buffer */ }; /* Routine to read in a block of txt from input file into txt.buffer. Uses txt.length as count. */ txtget() { int i; /* counter */ extern char *input; /* pointer to input buffer */ for ( i = 0; i < txt.length; i++) txt.buffer[i] = getc(input); for ( i = 0; i < txt.length; i++) txt.reloc[i] = 0; }; /* Routine to output the contents of txt.buffer into the right place in the file. Finds offset in file of this CSECT from symspc, and finds offset of CSECT in its space, from symoff, and uses txt.lc as the final offset for the place to put txt.buffer. Updates txt.lc by the length of the stuff in txt.buffer. */ txtput() { extern int output; /* file id of output file */ register int i,sect,offs; /* variables */ for (i = 1 ; i <= txt.rpt; i++ ) { sect = (txt.lc >> 9) & 0177; offs = txt.lc & 0777; offs =+ sizeof hdr; if ((symatr(txt.csid) & A_ISPC) == 0) { sect =+ (hdr.txtsiz >> 9) & 0177; offs =+ hdr.txtsiz & 0777; }; seek(output, sect, 3); seek(output, offs, 1); write(output, txt.buffer, txt.length); if (rflag) { sect =+ ((hdr.txtsiz >> 9) & 0177) + ((hdr.datsiz >> 9) & 0177); offs =+ (hdr.txtsiz & 0777) + (hdr.datsiz & 0777); seek(output, sect, 3); seek(output, offs, 1); write(output, txt.reloc, txt.length); }; txt.lc =+ txt.length; }; txt.rpt = 0; }; /* Routine to fix a word or byte in txt.buffer by adding a value to that wrd. */ txtfix(offset, id, sign, bytflg) int offset; /* offset in txt.buffer to change */ int id; /* the id of csect or symbol to fix */ char sign; /* 0=> add value of id, 1 => subtract */ char bytflg; { /* 0=> word fix, 1 => byte fix */ register int oldwrd, newwrd; char atr,typ; /* will contain attributes of id */ if (bytflg) printf("Byte relocation not defined!\n"); else { oldwrd = txt.buffer[offset] & 0377; oldwrd =+ txt.buffer[offset + 1] << 8; newwrd = symval(id); if (rflag && (((atr = symatr(id)) & A_ABS) == 0)) if ((((typ = symtyp(id))==CMD_SYM) && (atr & A_DEF)) | (typ == CMD_CS)) if ((atr & A_ISPC) == 0) newwrd =+ hdr.txtsiz; if (sign) newwrd = -newwrd; oldwrd =+ newwrd; txt.buffer[offset] = oldwrd & 0377; txt.buffer[offset+1] = (oldwrd >> 8) & 0377; } }; /* Subroutine to put the proper kind of relocation bits in relocation word */ txtrel(offset, id, pc_rel, bytflg) int offset; /* offset into current block */ int id; /* symbol or csect id */ char pc_rel; /* 1 => set the pc rel bit and return */ char bytflg; { /* 1 => the fix should be on a byte */ int fixval; /* the value we intend to install */ if (bytflg) { printf("Byte relocation not allowed in a.out files!\n"); return; }; if (pc_rel) { txt.reloc[offset] =| R_RELOC; /* specify pc relative reloc */ return; /* that's all for now */ } switch (symtyp(id)) { /* switch on the type of symbol */ case CMD_CS: if (symatr(id) & A_ISPC) txt.reloc[offset] =| R_TEXT; else txt.reloc[offset] =| R_DATA; break; case CMD_SYM: fixval = R_EXT | (id << 4); txt.reloc[offset] =| fixval & 0377; txt.reloc[offset + 1] =| (fixval >> 8) & 0377; break; }; }; /* io buffer for input file */ struct iobuf { int fildef; int nleft; char *nextp; char buff[512]; } in_buf; /* miscellanious variables */ int output; /* file id of output file */ char *input &in_buf; /* pointer to input buffer */ /* Miscellanious Subroutines */ /* Subroutine to get a command byte from input file. Ignores leading bzeros. */ getcmd() { int cmd; /* temporary for value we will return */ while ((cmd = getc(input)) == 0); /* get a non-zero char */ return (cmd); /* return the first non-zero command */ }; /* Subroutine to get an asciz string from input file. It allocates a buffer for the string from free storage. Names have a maximum length of namesize characters. */ gets() { char string[100]; /* temporary to hold string as we read in */ char *new_str; /* temporary pointer to newly allocate string */ int i; /* temporary index */ for ( i = 0; i < 100; i++) if ((string[i] = getc(input)) == 0) { new_str = alloc(i + 1); /* allocate a new string */ for ( ; i >= 0; i--) new_str[i] = string[i]; return (new_str); }; string[99] = 0; /* force a zero at end of string */ printf("Name truncated: %s\n", string); new_str = alloc(100); for (i = 0; i < 100; i++) new_str[i] = string[i]; return (new_str); }; /* Routine to skip chars in the input file */ skip(cnt) int cnt; { /* number of chars to skip */ int i; /* temporary for loop */ for ( i = 1; i <= cnt; i++) getc(input); }; /* Routine to compare two character strings */ cmpstr(s1, s2) register char *s1, *s2; { /* pointers to strings we are comparing */ while (*s1 == *s2) { if (*s1 == 0) return(1); s1++; s2++; } return(0); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������