--- /dev/null
+/
+/ (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
+/
+/ This product is part of the Amsterdam Compiler Kit.
+/
+/ Permission to use, sell, duplicate or disclose this software must be
+/ obtained in writing. Requests for such permissions may be sent to
+/
+/ Dr. Andrew S. Tanenbaum
+/ Wiskundig Seminarium
+/ Vrije Universiteit
+/ Postbox 7161
+/ 1007 MC Amsterdam
+/ The Netherlands
+/
+/
+/------------------------------------------------------------------------------
+/\f
+/ This is an interpreter for EM programs with no virtual memory
+/ which is adapted from an EM1 interpreter by Hans van Staveren
+/ by Evert Wattel
+/ Vrije Universiteit
+/ Amsterdam
+/
+/ Memory layout:
+/
+/ interpreter em-text pd global tables heap unused stack
+/ __________________________________________________________________
+/ | | | | | | | | | |
+/ | | | | | | | | | |
+/ | 1 | 2 | 3 | 4 | 5 | 6 | | 7 | 8|
+/ | | | | | | | | | |
+/ |____________|_______|____|_______|_______|_____|______|______|__|
+/
+/ 1: Interpreter text+data+bss
+/ 2: EM text
+/ 3: EM procedure descriptors
+/ 4: EM global data area
+/ 5: flow, count and profile tables
+/ 6: EM heap area
+/ 7: EM local data and stack
+/ 8: Arguments to interpreter
+/
+/ Assembly time flags:
+/ .test : controls checking for undefined variables,nil pointers,
+/ array indices, etc....
+/ .prof : controls generation of a runtime profile
+/ .opfreq: controls runtime frequency count per opcode
+/ .flow : controls generation of a flow bitmap
+/ .count : controls generation of a flow count
+/ .last : controls generation of file with last 16
+/ consecutive blocks of lines executed
+/
+/ Register layout:
+/ pcx = EM programcounter
+/ lb = EM base-address
+/ nxt = address of start of interpreter loop
+/
+/ The general structure of this interpreter is as follows:
+/ The opcode byte of the instruction is placed in r0
+/ with sign-extension and multiplied by 2.
+/ If .opfreq is nonzero each occurence of each opcode is counted.
+/ Then, if .prof is nonzero an estimation of the time required
+/ to execute the instruction is added to a counter associated
+/ with the source-line number. This estimation is roughly the
+/ number of memory-cycles needed. At the end of this accounting
+/ loprof points to the loword of the double precision counter.
+/ This can be used by individual execution routines to add some
+/ more to the counter depending on their operand.
+/
+/ NOTE: This interpreter can be loaded in separate I and D space
+/
+/\f
+/------------------------------------------------------------------------------
+/ Declaring of some constants
+/------------------------------------------------------------------------------
+
+ nxt = r4
+ pcx = r3
+ lb = r2
+
+ statd = -8.
+
+ unixextra= 1280. / extra memory asked by heap overflow
+ und = 100000 / undefined memory pattern
+ signext = 177400 / high bits for signextension
+ EINVAL = 22. / UNIX error code for bad signal
+
+/ Interpreter options
+ .float = 1
+ .opfreq = 0
+ .last = 1
+ V7 = 1
+ V6 = 0
+ VPLUS = 0
+ HARDWARE_FP = 1
+/------------------------------------------------------------------------------
+/ EM1 machine errors (in the range 0-63)
+/------------------------------------------------------------------------------
+
+ EARRAY = 0.
+ ERANGE = 1.
+ ESET = 2.
+ EIOVFL = 3.
+ EFOVFL = 4.
+ EFUNFL = 5.
+ EIDIVZ = 6.
+ EFDIVZ = 7.
+ EIUND = 8.
+ EFUND = 9.
+ ECONV = 10.
+ ESTACK = 16.
+ EHEAP = 17.
+ EILLINS = 18.
+ EODDZ = 19.
+ ECASE = 20.
+ EMEMFLT = 21.
+ EBADPTR = 22.
+ EBADPC = 23.
+ EBADLAE = 24.
+ EBADMON = 25.
+ EBADLIN = 26.
+ EBADGTO = 27.
+
+/------------------------------------------------------------------------------
+/ Declaring of some instructions unknown to the assembler
+/------------------------------------------------------------------------------
+
+ next = 10407 / = mov nxt,pc; jump to decode loop
+ rti = 2 / return from interrupt
+ iot = 4 / force core dump
+ stst = 170300^tst / store floating point status
+ indir = 0 / for sys indir
+ exit = 1
+ fork = 2
+ read = 3
+ write = 4
+ open = 5
+ close = 6
+ creat = 8.
+ break = 17.
+ alarm = 27.
+ pause = 29.
+ sleep = 35.
+ signal = 48.
+
+/------------------------------------------------------------------------------
+/ External references
+/------------------------------------------------------------------------------
+
+ .globl _end
+
+/\f
+/------------------------------------------------------------------------------
+/ Now the real program starts
+/------------------------------------------------------------------------------
+
+startoff:
+ mov sp,r0
+ mov sp,ml
+ mov 02(sp),filb / pointer to argv in filb for error message
+ dec (r0)
+ mov (r0)+,argc / pass to userprogram later
+ bgt 0f / go for argument
+ mov $emfile,forward+2 / e.out is load file default
+ mov $forward+2,argv
+ br 1f
+0:
+ tst (r0)+ / skip interpreter name
+ mov r0,argv / pass to userprogram later
+ mov (r0),forward+2 / argv filename to open call
+1:
+.if V7
+ tst (r0)+ / increment r0 look for last arg
+ bne 1b
+ mov r0,environ
+.endif
+ sys indir;forward
+ .data
+forward: sys open;0;0
+emfile: <e.out\0>
+.even
+ .text
+ jes badarg
+ mov r0,saver0 / save filedescriptor
+ mov r0,r5 / duplicate filedescriptor
+ sys read;header;16. / skip first header
+ jes badarg / failed
+ mov r5,r0 / recall fildes
+ sys read;header;16. / read second header
+ jes badarg / failed
+ cmp r0,$16. / long enough ?
+ jne badarg / no.
+ mov $_end,r0 / Bottom em-text
+ mov r0,pb / program base
+ add txtsiz,r0 / reserve space for text
+ mov r0,pd / set up proc.descr base
+ mov nprocs, r3 / number of procs
+ ash $2,r3 / proc. descr is 4 bytes
+.if .count +.prof + .flow
+ mul $3,r3 / or 12 bytes
+.endif
+ add r3,r0 / reserve space
+ mov r0,eb / top of pd space
+ mov r0,r3 / base for data fill
+
+ add szdata,r0 / size of external data
+ jcs toolarge / too much text and data
+ mov r0,globmax / maximum global
+ add $1280.,r0 / bit extra core for setup
+ mov r0,sybreak+2 / set up for core claim
+ sys indir;sybreak / ask for the core
+ jes toolarge / too much, sorry
+
+ mov txtsiz,leescal+4 / set up for text read
+ mov pb,leescal+2 / start address text read
+ mov r5,r0 / file descriptor input
+ sys indir;leescal / read!!
+ .data
+leescal:
+1: sys read;0;0 / read call
+ .text
+lblread:
+
+
+/ hier is nu dus de tekst ingelezen. De sybreak voor de
+/ tabellen en de data moet opnieuw gebeuren.
+
+
+.if .last
+ mov $47.,r0
+ mov $lasttab,r5
+3: clr (r5)+
+ sob r0,3b
+ mov $-1,(r5)
+ sub $96.,r5
+ mov r5,linused
+.endif
+lblfloat:
+.if .float
+ sys signal;8.;sig8 / catch floating exception
+ ldfps $7600
+ movf $50200,fr3 / load 2^32 in fr3 for conversion
+ / unsigned to float
+.endif
+
+
+ sys signal;11.;sig11 / catch segmentation violation
+ sys signal;12.;sig12 / catch bad system calls
+
+ / We make a 1024 buffer for reading in
+ / data descriptors. When the number of
+ / bytes in the buffer is less than 512
+ / we read another block. Descriptors of
+ / more than 512 bytes are not allowed.
+ / This is no restriction since they do
+ / not fit in the descriptor format.
+lblbuf:
+
+ sub $02000,sp / new buffer bottom
+ tst (sp) / ask for core
+ mov sp,r4 / pointer in descriptor
+ mov saver0,r0 / recall fildes
+ clr r1 / clear registers for byte
+ clr r2 / format instruction and data
+ mov sp,r5 / copy
+ mov r5,leescal+2 / set up for read
+ mov $02000,leescal+4 / idem
+ sys indir;leescal / read
+ jes badarg / read failed
+ cmp $02000,r0 / not yet eof?
+ bgt 0f / eof encountered
+
+ add $01000,r5 / buffer middle
+ mov r5,saver1 / save buffermiddle to compare
+ br datloop / start data initialization
+0: add r0,r5 / now pointer at top of file
+ mov r5,saver1 / still set up for compare
+
+
+
+
+datloop:
+ cmp r4,saver1 / descriptor over middle?
+ ble 9f / no? go ahead
+ jsr pc,blshift / yes? shift block down, read next
+
+9: dec ndatad / still data to initialize?
+ blt finito / no? go on
+ movb (r4)+,r1 / opcode descriptor
+ beq 0f / if 0 then go there
+ mov r3,r5 / copy data pointer
+ clr r2 / unsigned integer byte
+ bisb (r4)+,r2 / "ored" in for data size
+ asl r1 / make opcode even
+ mov datswi(r1),pc / main data swich
+
+.data
+datswi: 0; dat1; dat2; dat3; dat4; dat5; dat6; dat6; dofloat
+.text
+dat3: asl r2 / multiply with 2
+dat2: 2: movb (r4)+,(r3)+ / copy byte from buffer to data
+ sob r2,2b / until r2 is 0
+ br datloop / next datadescriptor
+
+
+dat4: mov eb,r0 / external base should be added
+ br 2f / for data pointers
+
+dat5: mov pb,r0 / and program base for procedures
+
+2: movb (r4)+,(r3) / move in first byte of pointer
+ movb (r4)+,1(r3) / move in second byte of pointer
+ add r0,(r3)+ / add pointer base
+ sob r2,2b / jump back if there is more
+ br datloop / next data descriptor
+
+dat1: mov $und,(r3)+ / reserve words with undefineds
+ sob r2,2b / jump back if more
+ br datloop / next data descriptor
+
+0: mov r3,r1 / copy data pointer (odd register)
+ sub r5,r1 / subtract previous pointer
+ movb (r4)+,(r3) / copy first byte of operand
+ movb (r4)+,1(r3) / copy second byte
+ mul (r3),r1 / the number of bytes to copy
+1: movb (r5)+,(r3)+ / is the product of the operand
+ sob r1,1b / and the number of bytes in the
+ br datloop / previous operation
+
+dat6: add r2,r3 / new data pointer, the old is
+ mov r3,r0 / still in r5
+ asr r2 / divide by 2
+ beq 6f / case 1 byte is special
+ sub $2,r0 / this is the least significant
+ / byte in PDP11-standard
+2: movb (r4)+,(r0)+ / copy low byte
+ movb (r4)+,(r0) / copy high byte
+ sub $3,r0 / next lowest byte
+ sob r2,2b / jump if not ready
+ br datloop / next descriptor
+6: movb (r4)+,(r5) / copy one byte
+ br datloop / next descriptor
+
+blshift:
+ mov saver1,r1 / bottom of top half
+ mov r1,r2 / set up bottom
+ sub $01000,r2
+ mov $1000,r0 / number to copy
+ mov r0,leescal+4 / amount to read
+ sub r0,r4 / decrease pointer
+ asr r0 / 512 bytes is 256 words
+3: mov (r1)+,(r2)+ / copy top half in bottom half
+ sob r0,3b
+ mov saver1,leescal+2 / set up for read
+blockr:
+ mov saver0,r0 / filedescriptor
+ sys indir;leescal
+ jes badarg
+ clr r1 / clear registers which contain
+ clr r2 / descriptor bytes later
+ cmp $01000,r0 / look if eof is encountered
+ beq 3f / yes? go on
+ add r0,saver1 / no extra read necessary
+3: rts pc
+
+finito:
+ cmp globmax,r3 / test if data size ok
+ jne badarg / load file error
+ mov eb,filb
+ add $4,filb
+
+
+ mov nprocs,r5 / set up for procdesc read
+ mov pd,r3 / proc descriptor base
+ asl r5 / multiply with 4 because
+ asl r5 / procdes is 4 bytes
+1: mov saver1,r1 / look what is available
+ sub r4,r1 / in buffer to be read
+ add $3,r1 / let it be a multiple
+ bic $3,r1 / of four
+ sub r1,r5 / subtract what can be read
+ asr r1; asr r1; / divide by four
+0:
+ movb (r4)+,(r3)+ / copy byte
+ movb (r4)+,(r3)+ / copy byte
+ movb (r4)+,(r3)+ / copy byte
+ movb (r4)+,(r3)+ / copy byte
+ add pb,-2(r3) / change em-address in pdp-address
+.if .count + .prof + .flow
+ clr (r3)+
+ clr (r3)+
+ clr (r3)+
+ clr (r3)+
+.endif
+ sob r1,0b / look if there is more
+ tst r5 / is there still a descriptor
+ ble 2f; / no? go on
+ jsr pc,blshift / yes? read again
+ br 1b
+
+2:
+ cmp eb,r3 / test if procdes is ok
+ jne badarg / load file error
+ mov saver0,r0 / fildes in r0
+ sys close / close input load file
+ mov ml,sp / fresh stack
+ mov 2(sp),*filb
+.if .flow + .count + .prof
+/ |==================|
+/ Here we fill the fields in the procedure | bytes for locals |
+/ descriptor with table information. The |------------------|
+/ procedure descriptor has six fields, | start address |
+/ like described in this picture. We |------------------|
+/ construct a linked list of the proc. | count pointer |
+/ descriptors, such that the defined |------------------|
+/ order of procedures is compatible | first line nr |
+/ with the text order. Thereafter we |------------------|
+/ scan the text for line information to | link next proc |
+/ fill the countpointer and startline |------------------|
+/ field. The link to the first proc. | current file name|
+/ is in firstp, links are descriptor |==================|
+/ start addresses. The last procedure
+/ links to the external base. All lines in the text get a count
+/ number, lines of a procedure get consecutive count numbers,
+/ the procedure count pointer gives the number of the first line.
+/ Count pointer zero is reserved for the case that no line number
+/ is yet defined.
+
+makelink:
+ mov pd,r0 / first descriptor
+ mov r0,r3 / points to first proc
+ mov r0,r4 / pd in register
+ mov eb,r5 / eb in register
+
+0: mov r0,r1 / copy old descriptor bottom
+ add $12.,r0 / next descriptor
+ cmp r0,r5 / top of descriptor space
+ bhis 4f / ready? continue
+1: cmp 2(r0),2(r1) / compare start addresses
+ bhis 2f / 2(r0) large? follow link
+ sub $12.,r1 / 2(r0) small? previous descriptor
+ cmp r1,r4 / is r1 smaller than pd?
+ bhis 1b / no? try again
+ mov r3,8.(r0) / yes? then r0 has small text address
+ mov r0,r3 / now r3 again points to first proc
+ br 0b / next descriptor
+
+2: mov 8.(r1),r2 / follow link to compare with 2(r0)
+ beq 3f / if 0 then no link defined
+ cmp 2(r0),2(r2) / compare start addresses
+ blo 3f / r0 between r1 and r2
+ mov r2,r1 / r0 above r2,
+ br 2b / look again.
+
+3: mov r0,8.(r1) / link of r1 points to r0
+ mov r2,8.(r0) / link of r0 points to r2
+ br 0b / next descriptor
+
+4: mov r3,firstp / firstp links to first procedure
+
+procinf:
+ mov $1,maxcount / countptr for first proc
+ mov r3,r4 / points to first proc
+
+0: mov r3,-(sp) / stack current procedure
+ mov $-1,r1 / minimal line number 0177777
+ clr r5 / maximum line number on 0
+ mov 8.(r3),r4 / bottom address next descriptor
+ beq 6f / if 0 last procedure
+ mov 2(r4),r4 / top of current procedure
+ br 2f / start looking for lines
+6: mov pd,r4 / top of last procedure
+2:
+ mov 2(r3),r3 / start text address procedure
+8: movb (r3)+,r2 / first opcode for scanning
+ cmp $-2,r2 / case escape
+ beq 1f / escape treated at label 1
+ cmp $-106.,r2 / case lni
+ blt 7f / ordinary skip at label 7
+ beq 2f / lni treated at label 2
+ cmp $-108.,r2 / case lin.l
+ bgt 7f / ordinary skip at label 7
+ beq 3f / lin.l at label 3
+ clr r0 / lin.s0 treated here
+ bisb (r3)+,r0 / line number in r0
+ br 4f / compares at label 4
+2: inc r0 / lni increases line number
+ br 4f / compares at label 4
+3: jsr pc,wrdoff / get 2 byte number
+4:
+ cmp r1,r0 / look if r0 less than minimum
+ blo 5f / nothing to declare
+ mov r0,r1 / r0 new minimum
+5: cmp r0,r5 / look if r0 more than maximum
+ blo 9f / nothing spectacular
+ mov r0,r5 / r0 new maximum
+ br 9f / line processed
+
+1: clr r2
+ bisb (r3)+,r2 / escaped instruction opcode
+ add $128.,r2 / ready for table entry
+7: movb skipdisp(r2),r2 / skip the required number of bytes
+ add r2,r3
+
+9: cmp r3,r4 / still more text in this proc?
+ blt 8b / yes? again
+filpd:
+ mov (sp)+,r3 / get bottom descriptor back
+ sub r1,r5 / number of lines encountered
+ bcs 9f / no lines then no file information
+ mov maxcount,4(r3) / this is the count pointer
+ mov r1,6(r3) / minimum line in descriptor
+ inc r5
+ add r5,maxcount / this is the new maximum
+9: mov 8.(r3),r3 / follow link to next procedure
+ bne 0b / restart
+.data
+.byte 2; .byte 2; .byte 0; .byte 0; .byte 1; .byte 1; .byte 1; .byte 0;
+.byte 0; .byte 2; .byte 1; .byte 0; .byte 1; .byte 0; .byte 0; .byte 1;
+.byte 1; .byte 1; .byte 0; .byte 0; .byte 2; .byte 1; .byte 0; .byte 2;
+.byte 0; .byte 1; .byte 1; .byte 2; .byte 1; .byte 1; .byte 1; .byte 1;
+.byte 1; .byte 2; .byte 0; .byte 0; .byte 0; .byte 0; .byte 1; .byte 2;
+.byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 1; .byte 2; .byte 2;
+.byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0;
+.byte 0; .byte 0; .byte 0; .byte 0; .byte 1; .byte 1; .byte 0; .byte 0;
+
+.byte 0; .byte 1; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 1;
+.byte 0; .byte 0; .byte 1; .byte 0; .byte 0; .byte 1; .byte 1; .byte 1;
+.byte 1; .byte 0; .byte 2; .byte 1; .byte 1; .byte 1; .byte 2; .byte 0;
+.byte 0; .byte 1; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 1;
+.byte 2; .byte 2; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0;
+.byte 0; .byte 1; .byte 0; .byte 0; .byte 0; .byte 0; .byte 2; .byte 1;
+.byte 1; .byte 1; .byte 1; .byte 1; .byte 1; .byte 1; .byte 1; .byte 1;
+.byte 2; .byte 1; .byte 0; .byte 0; .byte 1; .byte 2; .byte 7; .byte 5;
+
+skipdisp:
+.byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0;
+.byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0;
+.byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0;
+.byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0;
+.byte 0; .byte 0; .byte 0; .byte 1; .byte 0; .byte 0; .byte 2; .byte 0;
+.byte 0; .byte 1; .byte 1; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0;
+.byte 0; .byte 0; .byte 1; .byte 2; .byte 1; .byte 1; .byte 1; .byte 1;
+.byte 1; .byte 1; .byte 1; .byte 2; .byte 1; .byte 1; .byte 1; .byte 1;
+
+.byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0;
+.byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0;
+.byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0;
+.byte 0; .byte 0; .byte 0; .byte 0; .byte 1; .byte 0; .byte 0; .byte 0;
+.byte 1; .byte 0; .byte 0; .byte 0; .byte 1; .byte 0; .byte 0; .byte 0;
+.byte 1; .byte 1; .byte 0; .byte 1; .byte 0; .byte 2; .byte 0; .byte 2;
+.byte 1; .byte 0; .byte 0; .byte 0; .byte 1; .byte 1; .byte 0; .byte 1;
+.byte 2; .byte 1; .byte 1; .byte 1; .byte 1; .byte 1; .byte 1; .byte 1;
+
+/escaped opcodes
+
+.byte 2; .byte 0; .byte 2; .byte 0; .byte 2; .byte 0; .byte 2; .byte 0;
+.byte 2; .byte 0; .byte 2; .byte 0; .byte 2; .byte 2; .byte 0; .byte 2;
+.byte 2; .byte 2; .byte 2; .byte 2; .byte 0; .byte 2; .byte 2; .byte 0;
+.byte 2; .byte 0; .byte 0; .byte 0; .byte 2; .byte 0; .byte 2; .byte 0;
+.byte 2; .byte 0; .byte 2; .byte 0; .byte 2; .byte 0; .byte 2; .byte 0;
+.byte 2; .byte 0; .byte 0; .byte 0; .byte 0; .byte 2; .byte 2; .byte 2;
+.byte 2; .byte 2; .byte 0; .byte 2; .byte 0; .byte 2; .byte 0; .byte 2;
+.byte 0; .byte 2; .byte 0; .byte 2; .byte 0; .byte 2; .byte 2; .byte 2;
+
+.byte 0; .byte 2; .byte 0; .byte 2; .byte 0; .byte 2; .byte 2; .byte 2;
+.byte 2; .byte 2; .byte 2; .byte 2; .byte 0; .byte 2; .byte 0; .byte 1;
+.byte 2; .byte 2; .byte 2; .byte 2; .byte 0; .byte 2; .byte 0; .byte 2;
+.byte 0; .byte 0; .byte 2; .byte 0; .byte 2; .byte 0; .byte 0; .byte 2;
+.byte 0; .byte 2; .byte 2; .byte 0; .byte 2; .byte 0; .byte 2; .byte 0;
+.byte 2; .byte 0; .byte 0; .byte 2; .byte 0; .byte 2; .byte 0; .byte 2;
+.byte 0; .byte 2; .byte 0; .byte 2; .byte 0; .byte 2; .byte 2; .byte 2;
+.byte 2; .byte 2; .byte 0; .byte 0; .byte 2; .byte 2; .byte 0; .byte 2;
+
+.byte 0; .byte 2; .byte 0; .byte 2; .byte 0; .byte 2; .byte 0; .byte 2;
+.byte 2; .byte 0; .byte 1; .byte 0; .byte 0; .byte 0; .byte 2; .byte 0;
+.byte 2; .byte 0; .byte 2; .byte 2; .byte 2; .byte 2; .byte 2; .byte 2;
+.byte 0; .byte 2; .byte 0; .byte 1; .byte 2; .byte 0; .byte 0; .byte 2;
+.text
+ mov globmax,r3 / bottom of table space
+ mov r3,r5 / copy
+.if .prof
+ mov r3,ltime / set up pointer to base
+mov r3,hiprof
+mov r3,loprof
+add $2,loprof
+ mov maxcount,r0 / number of lines
+ inc r0
+ asl r0 / four byter per prof count
+ asl r0
+ add r0,r3
+ mov r0,profsiz
+.endif
+.if .flow
+ mov r3,lflow / set up pointer to base
+ mov maxcount,r0
+ ash $-3,r0 / divide by 8
+ add $2,r0
+ bic $1,r0 / Rounded up to an integral number of words
+ add r0,r3
+ mov r0,flowsiz
+.endif
+.if .count
+ mov r3,lcount / set up pointer
+ mov maxcount,r0
+ inc r0
+ ash $2,r0 / multiply by 4
+ add r0,r3
+ mov r0,countsiz
+.endif
+ mov r3,tblmax
+ cmp r3,sybreak+2 / core available for tables?
+ blos 2f
+ mov r3,sybreak+2
+ sys indir;sybreak / ask for core
+2: sub r5,r3 / this amount of space required
+ asr r3
+2: clr (r5)+ / clear table space
+ sob r3,2b
+.endif
+.if [1 - .count] * [1 - .flow] * [1 - .prof]
+ mov globmax,tblmax
+.endif
+
+ / start calling sequence here
+calseq:
+ mov tblmax,hp
+ mov pd,r3 / top of em-text and top of stack
+ clr r2 / are dummy return values
+ mov environ,-(sp) / setup environment pointer
+ mov argv,-(sp) / setup argument pointer
+ mov *argv,*filb / setup first file message
+ mov argc,-(sp) / setup argument count
+ mov entry.,-(sp) / start procedure to call
+precal:
+ mov $loop,r4 / main loop address in r4
+ jbr cai.z / according to the cai
+
+noarg: mov r0,argv
+ mov $0f,r0; jbr rude_error
+badarg: mov $1f,r0; jbr rude_error
+toolarge:mov $2f,r0; jbr rude_error
+
+
+ .data
+0: <no load file\0>
+1: <load file error\0>
+2: <program too large\0>
+ .even
+ .text
+
+
+dofloat:
+ jsr pc,atof
+ mov r5,r3 / restore r3
+ / Assumed that the result is 8
+ / bytes Recall r2 and move the
+ / amount of bytes asked for
+ clr r1 / restore for opcode
+ sub $8.,r2 / 8 bytes?
+ beq 1f / yes! later, 4 bytes next
+ movfo fr0,-(sp) / push result
+ mov (sp)+,(r3)+ / write result in data
+ mov (sp)+,(r3)+ / idem
+ jbr datloop / next loop
+1: movf fr0,-(sp) / push result
+ mov (sp)+,(r3)+ / write result in data
+ mov (sp)+,(r3)+ / write result in data
+ mov (sp)+,(r3)+ / write result in data
+ mov (sp)+,(r3)+ / write result in data
+ jbr datloop
+atof:
+ mov r2,-(sp) / save byte count
+ clr -(sp)
+ clrf fr0
+ clr r2
+1:
+ movb (r4)+,r0 / get byte
+ cmp $' ,r0
+ bge 1b
+ cmpb r0,$'+
+ beq 1f
+ cmpb r0,$'-
+ bne 2f
+ inc (sp)
+1:
+ movb (r4)+,r0 / get next byte
+2:
+ sub $'0,r0
+ cmp r0,$9.
+ bhi 2f
+ jsr pc,digit
+ br 1b
+ inc r2
+ br 1b
+2:
+ cmpb r0,$'.-'0
+ bne 2f
+1:
+ movb (r4)+,r0 / get next byte
+ sub $'0,r0
+ cmp r0,$9.
+ bhi 2f
+ jsr pc,digit
+ dec r2
+ br 1b
+2:
+ cmpb r0,$'E-'0
+ beq 3f
+ cmpb r0,$'e-'0
+ bne 1f
+3:
+ clr r3
+ clr r1
+ movb (r4)+,r0 / get next byte
+ cmpb r0,$'+
+ beq 3f
+ cmpb r0,$'-
+ bne 5f
+ inc r3
+3:
+ movb (r4)+,r0 / get next byte
+5:
+ sub $'0,r0
+ cmp r0,$9.
+ bhi 3f
+ mul $10.,r1
+ add r0,r1
+ br 3b
+3:
+ tst r3
+ bne 3f
+ neg r1
+3:
+ sub r1,r2
+1:
+ movf $one,fr1
+ movf $one,fr2
+ mov r2,-(sp)
+ beq 2f
+ bgt 1f
+ neg r2
+1:
+ mulf $twohalf,fr1
+ mulf $four,fr2
+ sob r2,1b
+2:
+ tst (sp)+
+ bge 1f
+ divf fr1,fr0
+ divf fr2,fr0
+ br 2f
+1:
+ mulf fr1,fr0
+ mulf fr2,fr0
+2:
+ tst (sp)+
+ beq 1f
+ negf fr0
+1: mov (sp)+,r2
+ rts pc
+
+
+digit:
+ cmpf $big,fr0
+ cfcc
+ blt 1f
+ mulf $ten,fr0
+ movif r0,fr1
+ addf fr1,fr0
+ rts pc
+1:
+ add $2,(sp)
+ rts pc
+/
+/
+one = 40200
+twohalf = 40440
+four = 40600
+ten = 41040
+big = 56200
+huge = 77777
+
+
+/------------------------------------------------------------------------------
+/------------------------------------------------------------------------------
+/ Main loop of interpreter starts here
+/------------------------------------------------------------------------------
+
+loop:
+ movb (pcx)+,r0 / pickup opcode + sign extend
+9: asl r0 / opcode now -256 .. 254 & even
+
+.if .opfreq
+ mov r0,r1
+ asl r1 / multiply by two again
+ add $1,counttab+514.(r1) / cannot be inc
+ adc counttab+512.(r1) / double precision counters
+.endif
+.if .prof
+ add timeinf(r0),*loprof
+ adc *hiprof / double precision
+.endif
+ mov dispat(r0),pc / fast dispatch
+
+/------------------------------------------------------------------------------
+/ Two byte opcodes come here for decoding of second byte
+/------------------------------------------------------------------------------
+
+escape1:
+ clr r0
+ bisb (pcx)+,r0 / fetch second byte no sign extend
+ asl r0 / 0 to 512 & even
+ cmp $0500,r0 / look for righ range
+ jlt e.illins
+
+.if .opfreq
+ mov r0,r1
+ asl r1 / multiply by two again
+ add $1,counttab+1026.(r1) / cannot be inc
+ adc counttab+1024.(r1) / double precision counters
+.endif
+.if .prof
+ add time2inf(r0),*loprof
+ adc *hiprof / double precision
+.endif
+ mov dispae1(r0),pc / fast dispatch
+
+/----------------------------------------------------------------------------
+escape2:
+ movb (pcx)+,r0 / fetch second byte and sign extend
+ jne e.illins
+
+.if .opfreq
+ add $1,counttab+1666. / cannot be inc
+ adc counttab+1664. / double precision counters
+.endif
+ jbr loc.f / fast dispatch
+/------------------------------------------------------------------------------
+/ dispatch tables, first the unescaped opcodes
+/
+/ name convention is as follows:
+/ each execution routine has as a name the name of the instruction
+/ followed by a dot and a suffix.
+/ suffix can be an integer (sometimes followed by a W),
+/ an 's'or a 'w', followed by an integer, an 'l' ,a 'p' ,
+/ a 'n', sometimes followed by a 'w', or a 'z'.
+/ loc.1 routine to execute loc 1
+/ zge.s0 routine to execute zge 0 thru 255
+/ lae.w1 routine to execute lae 1024 thru lae 2046
+/ lof.2W routine to execute lof 2*the word size
+/ lol.pw routine to execute positive lol instructions
+/ loe.l routine to execute all loe instructions
+/ add.z routine to execute instruction without operand
+/ or with operand on the stack.
+/------------------------------------------------------------------------------
+ .data
+
+
+
+lal.p; lal.n; lal.0; lal._1; lal.w0; lal.w_1; lal.w_2; lar.1W
+ldc.0; lde.lw; lde.w0; ldl.0; ldl.w_1; lfr.1W; lfr.2W; lfr.s0
+lil.w_1; lil.w0; lil.0; lil.1W; lin.l; lin.s0; lni.z; loc.l
+loc._1; loc.s0; loc.s_1; loe.lw; loe.w0; loe.w1; loe.w2; loe.w3
+loe.w4; lof.l; lof.1W; lof.2W; lof.3W; lof.4W; lof.s0; loi.l
+loi.1; loi.1W; loi.2W; loi.3W; loi.4W; loi.s0; lol.pw; lol.nw
+lol.0; lol.1W; lol.2W; lol.3W; lol._1W; lol._2W; lol._3W; lol._4W
+lol._5W; lol._6W; lol._7W; lol._8W; lol.w0; lol.w_1; lxa.1; lxl.1
+lxl.2; mlf.s0; mli.1W; mli.2W; rck.1W; ret.0; ret.1W; ret.s0
+rmi.1W; sar.1W; sbf.s0; sbi.1W; sbi.2W; sdl.w_1; set.s0; sil.w_1
+sil.w0; sli.1W; ste.lw; ste.w0; ste.w1; ste.w2; stf.l; stf.1W
+stf.2W; stf.s0; sti.1; sti.1W; sti.2W; sti.3W; sti.4W; sti.s0
+stl.pw; stl.nw; stl.0; stl.1W; stl._1W; stl._2W; stl._3W; stl._4W
+stl._5W; stl.w_1; teq.z; tgt.z; tlt.z; tne.z; zeq.l; zeq.s0
+zeq.s1; zer.s0; zge.s0; zgt.s0; zle.s0; zlt.s0; zne.s0; zne.s_1
+zre.lw; zre.w0; zrl._1W; zrl._2W; zrl.w_1; zrl.nw; escape1; escape2
+
+
+dispat: / dispatch table for unescaped opcodes
+
+
+loc.0; loc.1; loc.2; loc.3; loc.4; loc.5; loc.6; loc.7
+loc.8; loc.9; loc.10; loc.11; loc.12; loc.13; loc.14; loc.15
+loc.16; loc.17; loc.18; loc.19; loc.20; loc.21; loc.22; loc.23
+loc.24; loc.25; loc.26; loc.27; loc.28; loc.29; loc.30; loc.31
+loc.32; loc.33; aar.1W; adf.s0; adi.1W; adi.2W; adp.l ; adp.1
+adp.2; adp.s0; adp.s_1; ads.1W; and.1W; asp.1W; asp.2W; asp.3W
+asp.4W; asp.5W; asp.w0; beq.l; beq.s0; bge.s0; bgt.s0; ble.s0
+blm.s0; blt.s0; bne.s0; bra.l; bra.s_1; bra.s_2; bra.s0; bra.s1
+cal.1; cal.2; cal.3; cal.4; cal.5; cal.6; cal.7; cal.8
+cal.9; cal.10; cal.11; cal.12; cal.13; cal.14; cal.15; cal.16
+cal.17; cal.18; cal.19; cal.20; cal.21; cal.22; cal.23; cal.24
+cal.25; cal.26; cal.27; cal.28; cal.s0; cff.z; cif.z; cii.z
+cmf.s0; cmi.1W; cmi.2W; cmp.z; cms.s0; csa.1W; csb.1W; dec.z
+dee.w0; del.w_1; dup.1W; dvf.s0; dvi.1W; fil.l; inc.z; ine.lw
+ine.w0; inl._1W; inl._2W; inl._3W; inl.w_1; inn.s0; ior.1W; ior.s0
+lae.l; lae.w0; lae.w1; lae.w2; lae.w3; lae.w4; lae.w5; lae.w6
+
+
+
+/------------------------------------------------------------------------------
+/ now dispatch table for escaped opcodes
+/------------------------------------------------------------------------------
+
+dispae1: /dispatch escaped opcodes 1
+
+aar.l; aar.z; adf.l; adf.z; adi.l; adi.z; ads.l; ads.z
+adu.l; adu.z; and.l; and.z; asp.lw; ass.l; ass.z; bge.l
+bgt.l; ble.l; blm.l; bls.l; bls.z; blt.l; bne.l; cai.z
+cal.l; cfi.z; cfu.z; ciu.z; cmf.l; cmf.z; cmi.l; cmi.z
+cms.l; cms.z; cmu.l; cmu.z; com.l; com.z; csa.l; csa.z
+csb.l; csb.z; cuf.z; cui.z; cuu.z; dee.lw; del.pw; del.nw
+dup.l; dus.l; dus.z; dvf.l; dvf.z; dvi.l; dvi.z; dvu.l
+dvu.z; fef.l; fef.z; fif.l; fif.z; inl.pw; inl.nw; inn.l
+inn.z; ior.l; ior.z; lar.l; lar.z; ldc.l; ldf.l; ldl.pw
+ldl.nw; lfr.l; lil.pw; lil.nw; lim.z; los.l; los.z; lor.s0
+lpi.l; lxa.l; lxl.l; mlf.l; mlf.z; mli.l; mli.z; mlu.l
+mlu.z; mon.z; ngf.l; ngf.z; ngi.l; ngi.z; nop.z; rck.l
+rck.z; ret.l; rmi.l; rmi.z; rmu.l; rmu.z; rol.l; rol.z
+ror.l; ror.z; rtt.z; sar.l; sar.z; sbf.l; sbf.z; sbi.l
+sbi.z; sbs.l; sbs.z; sbu.l; sbu.z; sde.l; sdf.l; sdl.pw
+sdl.nw; set.l; set.z; sig.z; sil.pw; sil.nw; sim.z; sli.l
+
+
+
+
+
+
+sli.z; slu.l; slu.z; sri.l; sri.z; sru.l; sru.z; sti.l
+sts.l; sts.z; str.s0; tge.z; tle.z; trp.z; xor.l; xor.z
+zer.l; zer.z; zge.l; zgt.l; zle.l; zlt.l; zne.l; zrf.l
+zrf.z; zrl.pw; dch.z; exg.s0; exg.l; exg.z; lpb.z; gto.l
+
+/------------------------------------------------------------------------------
+/ timeinf tables, first the unescaped opcodes
+/ these tables are parallel to the tables dispat and dispae1
+/ Each entry contains a reasonable estimate of
+/ the number of memory-cycles needed to
+/ execute that instruction. The exact amount cannot be
+/ supplied, since this can depend rather heavily on the
+/ size of the object in set, array case instructions etc.
+/ The table timeinf also contains, added to each entry,
+/ the number of memory-cycles needed to decode the instruction.
+/ This number is currently 6. The number is computed for
+/ the case that all check and runinf options are off.
+/------------------------------------------------------------------------------
+.if .prof
+23.; 23.; 12.; 12.; 18.; 17.; 19.; 61.
+11.; 31.; 21.; 15.; 20.; 30.; 30.; 31.
+20.; 18.; 18.; 19.; 29.; 18.; 13.; 20.
+10.; 14.; 13.; 27.; 20.; 20.; 20.; 20.
+20.; 23.; 16.; 16.; 16.; 16.; 17.; 38.
+14.; 26.; 26.; 26.; 26.; 28.; 26.; 25.
+11.; 11.; 11.; 11.; 11.; 11.; 11.; 11.
+11.; 11.; 11.; 11.; 16.; 16.; 26.; 24.
+
+24.; 53.; 25.; 25.; 18.; 27.; 44.; 54.
+30.; 59.; 53.; 21.; 28.; 19.; 51.; 18.
+18.; 21.; 27.; 19.; 20.; 18.; 25.; 16.
+16.; 15.; 12.; 24.; 24.; 24.; 24.; 25.
+26.; 25.; 15.; 13.; 11.; 11.; 11.; 11.
+11.; 16.; 14.; 14.; 14.; 14.; 20.; 16.
+16.; 21.; 16.; 16.; 16.; 16.; 16.; 16.
+26.; 16.; 10.; 10.; 15.; 24.; 10.; 40.
+
+timeinf:
+
+ 9.; 10.; 10.; 10.; 10.; 10.; 10.; 10.
+10.; 10.; 10.; 10.; 10.; 10.; 10.; 10.
+10.; 10.; 10.; 10.; 10.; 10.; 10.; 10.
+10.; 10.; 10.; 10.; 10.; 10.; 10.; 10.
+10.; 10.; 48.; 53.; 21.; 28.; 20.; 10.
+10.; 12.; 13.; 11.; 44.; 11.; 11.; 11.
+11.; 11.; 27.; 21.; 17.; 17.; 17.; 17.
+81.; 17.; 17.; 21.; 12.; 12.; 11.; 12.
+
+54.; 54.; 54.; 54.; 54.; 54.; 54.; 54.
+54.; 54.; 54.; 54.; 54.; 54.; 54.; 54.
+54.; 54.; 54.; 54.; 54.; 54.; 54.; 54.
+54.; 54.; 54.; 54.; 54.; 41.; 49.; 37.
+40.; 53.; 53.; 51.; 60.; 24.; 41.; 11.
+20.; 19.; 10.; 53.; 30.; 29.; 11.; 30.
+20.; 15.; 15.; 15.; 19.; 44.; 37.; 36.
+25.; 19.; 19.; 19.; 19.; 19.; 19.; 19.
+
+/------------------------------------------------------------------------------
+/ time2inf table for escaped opcodes
+/ cycles necessary for decoding is already accounted for in timeinf
+/------------------------------------------------------------------------------
+
+time2inf:
+
+57.; 46.; 61.; 50.; 37.; 26.; 30.; 19.
+45.; 34.; 52.; 41.; 37.; 42.; 31.; 21.
+21.; 21.; 91.; 108.; 97.; 21.; 21.; 53.
+60.; 56.; 55.; 26.; 53.; 42.; 62.; 51.
+72.; 61.; 72.; 61.; 38.; 27.; 40.; 29.
+53.; 46.; 54.; 38.; 23.; 30.; 30.; 28.
+36.; 45.; 34.; 61.; 50.; 39.; 28.; 44.
+33.; 68.; 57.; 68.; 57.; 30.; 28.; 54.
+
+45.; 44.; 33.; 70.; 59.; 22.; 27.; 28.
+29.; 37.; 28.; 27.; 11.; 47.; 40.; 21.
+20.; 35.; 33.; 61.; 50.; 34.; 23.; 39.
+28.; 500.; 47.; 36.; 41.; 30.; 100.; 38.
+27.; 62.; 39.; 28.; 44.; 33.; 88.; 77.
+92.; 81.; 32.; 68.; 57.; 61.; 50.; 37.
+26.; 33.; 22.; 45.; 34.; 29.; 28.; 30.
+28.; 61.; 52.; 16.; 28.; 27.; 11.; 30.
+
+19.; 36.; 25.; 32.; 21.; 36.; 25.; 31.
+39.; 32.; 32.; 14.; 14.; 117.; 45.; 34.
+31.; 22.; 20.; 20.; 20.; 20.; 20.; 27.
+16.; 26.; 17.; 39.; 47.; 36.; 10.; 29.
+.endif
+ .text
+/------------------------------------------------------------------------------
+/ LOAD CONSTANT, LOAD LOCAL, STORE LOCAL
+/------------------------------------------------------------------------------
+
+loc.0: clr -(sp)
+ next
+loc.1: loc.2: loc.3: loc.4: loc.5: loc.6: loc.7: loc.8:
+loc.9: loc.10: loc.11: loc.12: loc.13: loc.14: loc.15: loc.16:
+loc.17: loc.18: loc.19: loc.20: loc.21: loc.22: loc.23: loc.24:
+loc.25: loc.26: loc.27: loc.28: loc.29: loc.30: loc.31: loc.32:
+loc.33:
+ asr r0 / make multiplication undone
+ mov r0,-(sp)
+ next
+loc._1:
+ mov $-1,-(sp)
+ next
+loc.s0:
+ clr r0
+ br 2f
+loc.s_1:
+ mov $-400,r0
+2: bisb (pcx)+,r0
+ mov r0,-(sp)
+ next
+lpi.l: / let op, dit is een pointer
+ / zonder offset op het moment!
+loc.l:
+ jsr pc,wrdoff
+ mov r0,-(sp)
+ next
+ldc.0:
+ clr -(sp)
+ clr -(sp)
+ next
+ldc.l:
+ jsr pc,wrdoff
+ mov r0,-(sp)
+ sxt -(sp)
+ next
+
+loc.f: jsr pc,wrdoff; mov r0,r1
+ jsr pc,wrdoff; mov r0,-(sp)
+ mov r1,-(sp); next
+
+/__________________________________________________________________________
+
+lol.0: mov 010(r2),-(sp); next
+lol.1W: mov 012(r2),-(sp); next
+lol.2W: mov 014(r2),-(sp); next
+lol.3W: mov 016(r2),-(sp); next
+lol._1W: mov -02(r2),-(sp); next
+lol._2W: mov -04(r2),-(sp); next
+lol._3W: mov -06(r2),-(sp); next
+lol._4W: mov -010(r2),-(sp); next
+lol._5W: mov -012(r2),-(sp); next
+lol._6W: mov -014(r2),-(sp); next
+lol._7W: mov -016(r2),-(sp); next
+lol._8W: mov -020(r2),-(sp); next
+
+lol.w0: clr r0; bisb (pcx)+,r0
+5: asl r0; add r2,r0
+ mov 010(r0),-(sp); next
+lol.w_1: mov $-400,r0; bisb (pcx)+,r0
+2: asl r0; add r2,r0
+ mov (r0),-(sp); next
+lol.pw: jsr pc,wrdoff; br 5b
+lol.nw: jsr pc,wrdoff; br 2b
+
+/------------------------------------------------------------------------------
+
+ldl.0: mov 10.(r2),-(sp); mov 8.(r2),-(sp); next
+ldl.w_1: mov $-400,r0; bisb (pcx)+,r0
+2: asl r0; add r2,r0
+ mov 2(r0),-(sp); mov (r0),-(sp); next
+ldl.pw: jsr pc,wrdoff; asl r0
+ add r2,r0; mov 10.(r0),-(sp)
+ mov 8.(r0),-(sp); next
+ldl.nw: jsr pc,wrdoff; br 2b
+
+/------------------------------------------------------------------------------
+loe.lw: jsr pc,wrdoff; br 2f
+loe.w0: loe.w1: loe.w2: loe.w3: loe.w4:
+ asr r0; add $0144,r0
+ swab r0; bisb (pcx)+,r0
+2: asl r0; add eb,r0
+ mov (r0),-(sp); next
+lde.lw: jsr pc,wrdoff; br 2f
+lde.w0: clr r0; bisb (pcx)+,r0
+2: asl r0; add eb,r0
+ mov 2(r0),-(sp); mov (r0),-(sp); next
+
+
+/------------------------------------------------------------------------------
+lil.0: clr r0; br 1f
+lil.1W: mov $1,r0; br 1f
+lil.pw: jsr pc,wrdoff; br 1f
+lil.w0: clr r0; bisb (pcx)+,r0
+1: add $04,r0
+2: asl r0; add r2,r0
+ mov (r0),-(sp); jsr pc,chckptr
+ mov *(sp),(sp); next
+lil.w_1: mov $-400,r0; bisb (pcx)+,r0; br 2b
+lil.nw: jsr pc,wrdoff; br 2b
+/------------------------------------------------------------------------------
+lof.l: jsr pc,wrdoff
+1: jsr pc,chckptr; add (sp)+,r0;
+ mov (r0),-(sp); next
+
+lof.1W: lof.2W: lof.3W: lof.4W:
+ add $0276,r0;
+ br 1b
+lof.s0: clr r0; bisb (pcx)+,r0; br 1b
+ldf.l: jsr pc,wrdoff; add (sp)+,r0
+ mov 2(r0),-(sp); mov (r0),-(sp); next
+/------------------------------------------------------------------------------
+lal.p: jsr pc,wrdoff
+5: add r2,r0; add $8.,r0
+ mov r0,-(sp); next
+lal.0: mov r2,-(sp); add $8.,(sp); next
+lal.w0: clr r0; bisb (pcx)+,r0
+ asl r0; br 5b
+lal.n: jsr pc,wrdoff; br 2f
+lal._1: mov $-1,r0
+2: add r2,r0; mov r0,-(sp); next
+lal.w_1: mov $-400,r0
+3: bisb (pcx)+,r0; asl r0; br 2b
+lal.w_2: mov $-1000,r0; br 3b
+
+lae.l: jsr pc,wrdoff; br 1f
+lae.w0: lae.w1: lae.w2: lae.w3: lae.w4: lae.w5: lae.w6:
+ asr r0
+ sub $0171,r0; swab r0
+ bisb (pcx)+,r0; asl r0
+1: add eb,r0;
+.if .test
+ cmp globmax,r0;
+ bhi 1f; jsr pc,e.badlae;
+.endif
+1: mov r0,-(sp); next
+/------------------------------------------------------------------------------
+lxl.1: mov $1,r0; br 1f
+lxl.2: mov $2,r0; br 1f
+lxl.l: jsr pc,wrdoff
+ bgt 1f; jlt e.oddz
+ mov r2,-(sp); next
+1: mov r2,r1
+2: mov 8(r1),r1; sob r0,2b
+ mov r1,-(sp); next
+
+lxa.1: mov $1,r0; br 1f
+lxa.l: jsr pc,wrdoff; bgt 1f
+ jlt e.oddz; mov r2,-(sp)
+ add $10,(sp); next
+1: mov r2,r1
+2: mov 8(r1),r1; sob r0,2b
+ add $10,r1; mov r1,-(sp); next
+
+/------------------------------------------------------------------------------
+loi.l: jsr pc,wrdoff; br 2f
+loi.1W: loi.2W: loi.3W: loi.4W:
+ add $260,r0; br 1f
+loi.s0: clr r0; bisb (pcx)+,r0
+2: cmp $1,r0; beq loi.1
+1: jsr pc,chckptr; mov (sp)+,r1; add r0,r1
+ asr r0; jcs e.oddz
+1: mov -(r1),-(sp); sob r0,1b; next
+loi.1: jsr pc,chckptb; mov (sp),r1; clr r0
+ bisb (r1),r0; mov r0,(sp); next
+los.z:
+ mov (sp)+,r0
+ br 0f
+los.l:
+ jsr pc,wrdoff
+0:
+ cmp $04,r0
+ beq 4f
+
+ cmp $02,r0; beq 3f
+ jbr e.oddz
+4: mov (sp)+,r0
+3: mov (sp)+,r0; br 2b
+
+/------------------------------------------------------------------------------
+ /Store group
+/------------------------------------------------------------------------------
+stl.pw: jsr pc,wrdoff; asl r0; br 0f
+stl.0: clr r0; br 0f
+stl.1W: mov $2,r0
+0: add r2,r0; mov(sp)+,8.(r0); next
+
+stl.nw: jsr pc,wrdoff; br 0f
+stl.w_1: mov $-400,r0; bisb (pcx)+,r0
+0: asl r0; add r2,r0
+ mov (sp)+,(r0); next
+stl._1W: mov (sp)+,-2(r2); next
+stl._2W: mov (sp)+,-4(r2); next
+stl._3W: mov (sp)+,-6(r2); next
+stl._4W: mov (sp)+,-10(r2); next
+stl._5W: mov (sp)+,-12(r2); next
+
+sdl.w_1: mov $-400,r0; bisb (pcx)+,r0
+0: asl r0; add r2,r0
+2: mov (sp)+,(r0)+; mov (sp)+,(r0); next
+sdl.nw: jsr pc,wrdoff; br 0b
+sdl.pw: jsr pc,wrdoff; asl r0
+ add r2,r0; add $8.,r0; br 2b
+
+/------------------------------------------------------------------------------
+
+sde.l: jsr pc,wrdoff; add eb,r0
+ br 2b
+ste.lw: jsr pc,wrdoff; br 1f
+ste.w0: clr r0; br 0f
+ste.w1: mov $400,r0; br 0f
+ste.w2: mov $1000,r0
+0: bisb (pcx)+,r0
+1: asl r0; add eb,r0
+ mov (sp)+,(r0); next
+
+
+/------------------------------------------------------------------------------
+
+stf.l: jsr pc,wrdoff; br 6f
+stf.1W: mov $2,r0; br 6f
+stf.2W: mov $4,r0; br 6f
+stf.s0: clr r0; bisb (pcx)+,r0
+6: add (sp)+,r0; br 7f
+sdf.l: jsr pc,wrdoff; add (sp)+,r0
+ jbr 2b
+
+
+/------------------------------------------------------------------------------
+sil.w0: clr r0; bisb (pcx)+,r0
+5: asl r0; add r2,r0
+ mov 8.(r0),r0; br 7f
+sil.w_1: mov $-400,r0; bisb (pcx)+,r0
+2: asl r0; add r2,r0
+ mov (r0),r0;
+7: mov (sp),r1; mov r0,(sp);
+ jsr pc,chckptr; mov r1,*(sp)+; next
+sil.pw: jsr pc,wrdoff; br 5b
+sil.nw: jsr pc,wrdoff; br 2b
+/------------------------------------------------------------------------------
+sti.1: jsr pc,chckptb; mov (sp)+,r1;
+ movb (sp)+,(r1); next
+sti.1W: sti.2W: sti.3W: sti.4W:
+ add $114,r0; br 1f
+sti.s0: clr r0; bisb (pcx)+,r0; br 1f
+sti.l: jsr pc,wrdoff
+1: asr r0; beq 3f
+ jcs e.oddz; jsr pc,chckptr;
+ mov (sp)+,r1
+2: mov (sp)+,(r1)+; sob r0,2b; next
+3: jcs sti.1; jbr e.oddz
+sts.l: jsr pc,wrdoff
+0: cmp $2,r0; beq 2f
+ cmp $4,r0; beq 4f; jbr e.oddz
+4: mov (sp)+,r0
+2: mov (sp)+,r0; br 1b
+sts.z: mov (sp)+,r0; br 0b
+
+/------------------------------------------------------------------------------
+/ POINTER ARITHMETIC
+/------------------------------------------------------------------------------
+adp.l: jsr pc,wrdoff; add r0,(sp); next
+adp.1: add $1,(sp); next
+adp.2: add $2,(sp); next
+adp.s0: clr r0; bisb (pcx)+,r0
+ add r0,(sp); next
+adp.s_1: mov $-400,r0; bisb (pcx)+,r0
+ add r0,(sp); next
+ads.l: jsr pc,wrdoff; br 0f
+ads.z: mov (sp)+,r0
+0: cmp $1,r0; beq 1f
+ asr r0; jcs e.oddz
+2: mov (sp)+,r1; sob r0,2b
+ add r1,(sp); next
+ads.1W: mov (sp)+,r1; add r1,(sp); next
+1: movb (sp)+,r1
+ add r1,(sp); next
+sbs.l: jsr pc,wrdoff; br 0f
+sbs.z: mov (sp)+,r0
+0: mov (sp)+,r1; sub r1,(sp)
+ beq 0f; mov $-1,r1
+ br 1f
+0: clr r1
+1: dec r0; beq 3f
+ dec r0; beq 2f
+ asr r0
+4: mov r1,-(sp); sob r0,4b
+2: next
+3: clrb 1(sp); next
+
+
+/------------------------------------------------------------------------------
+/------------------------------------------------------------------------------
+/ Clears, increments and decrements
+/------------------------------------------------------------------------------
+inc.z: mov sp,r1;
+4:
+.if .test
+ cmp (r1),$und; jne 3f;
+ jsr pc,e.iund; 3:
+.endif
+ inc (r1); bvs 9f; next
+inl._1W: mov r2,r1; sub $2,r1; br 4b
+inl._2W: mov r2,r1; sub $4,r1; br 4b
+inl._3W: mov r2,r1; sub $6,r1; br 4b
+inl.w_1: mov $-400,r0; bisb (pcx)+,r0;
+1: asl r0; mov r2,r1;
+ add r0,r1; br 4b
+inl.pw: jsr pc,wrdoff; add $4,r0;
+ br 1b; / !! proc frame 4 words
+inl.nw: jsr pc,wrdoff; br 1b
+ine.lw: jsr pc,wrdoff; br 1f
+ine.w0: clr r0; bisb (pcx)+,r0;
+1: asl r0; add eb,r0;
+ mov r0,r1; br 4b
+dec.z: mov sp,r1;
+4:
+.if .test
+ cmp (r1),$und; jne 3f;
+ jsr pc,e.iund; 3:
+.endif
+ dec (r1); bvs 9f; next
+del.w_1: mov $-400,r0; bisb (pcx)+,r0;
+1: asl r0; mov r0,r1;
+ add r2,r1; br 4b
+del.pw: jsr pc,wrdoff; add $4,r0;
+ br 1b; / !proc frame 4 words
+del.nw: jsr pc,wrdoff; br 1b
+dee.w0: clr r0; bisb (pcx)+,r0;
+1: asl r0; add eb,r0;
+ mov r0,r1; br 4b
+dee.lw: jsr pc,wrdoff; br 1b;
+9: jsr pc,e.iovfl; next
+ / jump to an error routine for integer overflow
+zrl._1W: clr -2(r2); next
+zrl._2W: clr -4(r2); next
+zrl.w_1: mov $-400,r0; bisb (pcx)+,r0;
+1: asl r0; add r2,r0;
+ clr (r0); next
+zrl.nw: jsr pc,wrdoff; br 1b
+zrl.pw: jsr pc,wrdoff; add $4,r0;
+ br 1b
+zre.lw: jsr pc,wrdoff; br 1f
+zre.w0: clr r0; bisb (pcx)+,r0;
+1: asl r0; add eb,r0;
+ clr (r0); next
+zrf.l: jsr pc,wrdoff; br 1f
+zrf.z: mov (sp)+,r0;
+1: asr r0;
+2: clr -(sp); sob r0,2b; next
+zer.s0: clr r0; bisb (pcx)+,r0;
+3: bit $1,r0; jne e.illins
+ / test if number of bytes is even
+ br 1b
+zer.l: jsr pc,wrdoff; br 3b
+zer.z: mov (sp)+,r0; br 3b
+/------------------------------------------------------------------------------
+/ LOGICAL GROUP
+/------------------------------------------------------------------------------
+
+and.1W: mov $1,r1; mov $2,r0;
+ br lbland;
+and.l: jsr pc,wrdoff; br 0f
+and.z: mov (sp)+,r0;
+0: ble 9f; mov r0,r1;
+ asr r1; bcs 9f;
+lbland: add sp,r0;
+1: mov (sp)+,r5; com r5;
+ bic r5,(r0)+; sob r1,1b;
+ next
+ior.1W: mov $1,r1; mov $2,r0;
+ br 0f
+ior.s0: clr r0; bisb (pcx)+,r0;
+ br 0f
+ior.l: jsr pc,wrdoff; br 0f
+ior.z: mov (sp)+,r0;
+lblior:
+
+0: ble 9f; bit $1,r0;
+ bne 9f; mov r0,r1;
+ mov sp,r5; add r0,r5; asr r1;
+1: bis (sp)+,(r5)+; sob r1,1b; next
+xor.l: jsr pc,wrdoff; br 0f;
+xor.z: mov (sp)+,r0;
+0: ble 9f; bit $1,r0;
+ bne 9f; mov r0,r1;
+ mov sp,r5; add r0,r5; asr r1
+1: mov (sp)+,r0;
+ xor r0,(r5)+; sob r1,1b; next
+com.l: jsr pc,wrdoff; br 1f
+com.z: mov (sp)+,r0;
+1: bit $1,r0; bne 9f
+ mov r0,r1; asr r1
+ add sp,r0;
+2: com -(r0); sob r1,2b
+ next
+rol.l: jsr pc,wrdoff; br 3f
+rol.z: mov (sp)+,r0;
+3: clr r4;
+ mov (sp)+,r5; ash $3,r0;
+ div r0,r4; mov r5,r4;
+ bge 1f; add r0,r4;
+1: ash $-3,r0; mov sp,r1;
+ cmp r0,$1; beq 1f;
+ add r0,r1; mov r1,r5;
+ asr r0; jcs 9f
+ mov r3,saver0; mov r0,r3;
+4: mov r3,r0; mov r5,r1;
+2: rol -(r1); sob r0,2b;
+ adc -2(r5); sob r4,4b;
+ mov saver0,r3; mov $loop,r4; next
+1: rolb (r1)+; adc (r1);
+ sob r4,1b; mov saver1,r4; next
+ror.l: jsr pc,wrdoff; neg (sp); br 3b
+ror.z: mov (sp)+,r0; neg (sp); br 3b
+9: jsr pc,e.oddz /error codes for odd or
+ /negative number of bytes
+
+/------------------------------------------------------------------------------
+/ SET GROUP
+/------------------------------------------------------------------------------
+
+set.s0: clr r0; bisb (pcx)+,r0
+1:
+.if .test
+ bgt 9f; jsr pc,e.set
+9:
+.endif
+ mov (sp)+,r1
+ jsr pc,settest; inc r0
+ asr r0; / if r0 odd choose next even
+2: clr -(sp); sob r0,2b; / empty set
+ mov r1,r0; ash $-3,r0;
+ add sp,r0; bic $177770,r1;
+ bisb bits(r1),(r0); next
+set.l: jsr pc,wrdoff; br 1b
+set.z: mov (sp)+,r0; br 1b
+inn.s0: clr r0; bisb (pcx)+,r0
+1:
+.if .test
+ bgt 9f; jsr pc,e.set
+9:
+.endif
+ mov sp,r5;
+ add r0,r5; mov (sp)+,r1;
+ jsr pc,settest; mov r1,r0
+ ash $-3,r0; add sp,r0;
+ clr -(sp);
+ bic $177770,r1; bitb bits(r1),(r0)
+ beq 2f; mov r5,sp;
+ mov $1,(sp); next
+2: mov r5,sp; clr (sp); next
+inn.l: jsr pc,wrdoff; br 1b
+inn.z: mov (sp)+,r0; br 1b
+ .data
+bits: .byte 1
+ .byte 2
+ .byte 4
+ .byte 10
+ .byte 20
+ .byte 40
+ .byte 100
+ .byte 200
+ .even
+ .text
+settest: mov r0,-(sp); clc
+ ash $3,r0; sub r1,r0;
+.if .test
+ bgt 3f; jsr pc,e.set
+.endif
+3: mov (sp)+,r0; rts pc
+/------------------------------------------------------------------------------
+/ ARRAY GROUP
+/------------------------------------------------------------------------------
+
+
+
+lar.1W: mov $2,r0; br 1f
+lar.l: jsr pc,wrdoff; br 1f
+lar.z: mov (sp)+,r0;
+1: jsr pc,calcarr; clr -2(sp);
+ sub r5,sp; bic $1,sp;
+ mov sp,r0;
+2: movb (r1)+,(r0)+; sob r5,2b; next
+sar.1W: mov $2,r0; br 1f
+sar.l: jsr pc,wrdoff; br 1f
+sar.z: mov (sp)+,r0;
+1: jsr pc,calcarr; mov sp,r0;
+ add r5,sp; inc sp;
+ bic $1,sp;
+2: movb (r0)+,(r1)+; sob r5,2b; next
+aar.1W: mov $2,r0; br 1f
+aar.l: jsr pc,wrdoff; br 1f
+aar.z: mov (sp)+,r0;
+1: jsr pc,calcarr; mov r1,-(sp); next
+
+calcarr: sub $02,r0; beq 0f;
+ jsr pc,e.oddz;
+0: tst (sp)+;
+ mov (sp)+,r0; mov (sp)+,r1;
+ sub (r0)+,r1; bge 9f
+ jsr pc,e.array
+9:
+ cmp (r0)+,r1; bge 9f
+ jsr pc,e.array
+9:
+ mov (r0),r5;
+ mul r5,r1; add (sp)+,r1;
+ mov -010(sp),-(sp); rts pc;
+
+
+
+/------------------------------------------------------------------------------
+/--------------------------------------------------------------
+/ CONVERT GROUP
+/--------------------------------------------------------------
+
+cii.z:
+ / convert int to int
+ / 1 byte -> ? : sign extension
+ mov (sp)+,r0
+ inc r0 / dest 1 byte = dest 1 word
+ bic $1,r0
+.if .test
+ cmp (sp),$2 / if size 2 then trap for undefined
+ bne 7f
+ cmp 2(sp),$und
+ bne 7f
+ jsr pc,e.iund / this is the trap
+7:
+.endif
+ sub (sp)+,r0
+0: blt 1f
+ asr r0
+ bcc 2f
+ movb (sp),r1
+ mov r1,(sp)
+2: tst r0
+ beq 3f
+ tst (sp)
+4: sxt -(sp)
+ sob r0,4b
+3: next
+1: sub r0,sp
+.if .test
+ mov sp,r1
+ neg r0
+ asr r0
+ tst (sp)
+ blt 3f
+5: tst -(r1)
+ bne 9f
+ sob r0,5b
+ next
+3: cmp -(r1),$-1
+ bne 9f
+ sob r0,3b
+.endif
+ next
+/-------
+cui.z: mov (sp)+,r0
+ sub (sp)+,r0
+ clr -(sp)
+ add $-2,r0
+ br 0b
+cif.z:
+ mov (sp)+,r0
+ jsr pc,setfloat
+ mov (sp)+,r0
+.if .test
+ cmp r0,$2 / trap if size 2 undefined integer
+ bne 7f
+ cmp (sp),$und
+ bne 7f
+ jsr pc,e.iund / trap for undefined integer
+7:
+.endif
+ jsr pc,setint
+ movif (sp)+,fr0
+ movf fr0,-(sp)
+ next
+cuf.z:
+ mov (sp)+,r0
+ jsr pc,setfloat
+ mov (sp)+,r0
+ cmp r0,$02
+ bne 1b
+ clr -(sp)
+ mov $04,r0
+ jsr pc,setint
+ movif (sp)+,fr0
+ cfcc
+ bge 1f
+ addf fr3,fr0
+1: movf fr0,-(sp)
+ next
+/-------
+cff.z:
+ mov (sp)+,r0
+ cmp (sp)+,r0
+ beq 1f
+ jsr pc,setfloat
+ movof (sp)+,fr0
+ movf fr0,-(sp)
+1: next
+/-------
+ciu.z: mov (sp)+,r0
+.if .test
+ cmp (sp),$2 / trap undefined of size 2
+ bne 7f
+ cmp 2(sp),$und
+ bne 7f
+ jsr pc,e.iund / this is the trap
+7:
+.endif
+ sub (sp)+,r0
+ asr r0
+ bcc 2f
+ clrb 1(sp)
+2: tst (sp)
+.if .test
+ jlt 9f
+.endif
+6: tst r0
+ beq 3f
+ blt 5f
+4: clr -(sp)
+ sob r0,4b
+3: next
+9: jsr pc,e.conv; next
+5: neg r0
+4: tst (sp)+
+.if .test
+ jne 9b
+.endif
+ sob r0,4b
+ next
+cuu.z:
+ mov (sp)+,r0
+ sub (sp)+,r0
+ asr r0
+ jbr 6b
+/-------
+cfu.z:
+ mov (sp)+,r0
+ jsr pc,setint
+ mov (sp)+,r0
+ jsr pc,setfloat
+ movf (sp)+,fr0
+ movfi fr0,-(sp)
+.if .test
+ jcs 9b
+ jlt 9b
+.endif
+ next
+/-------
+cfi.z:
+ mov (sp)+,r0
+ jsr pc,setint
+ mov (sp)+,r0
+ jsr pc,setfloat
+ movf (sp)+,fr0
+ movfi fr0,-(sp)
+ jcs e.conv
+ next
+/--------------------------------------------------------------
+/ INTEGER ARITHMETIC
+/--------------------------------------------------------------
+
+adi.l: jsr pc,wrdoff; br 0f
+adi.z: mov (sp)+,r0
+0: cmp r0,$04
+ bgt 1f
+ cmp r0,$02
+ bgt 2f
+ bne 1f
+adi.1W:
+.if .test
+ cmp (sp),$und / trap undefineds of size 2
+ beq 6f
+ cmp 2(sp),$und
+ bne 7f
+6: jsr pc,e.iund / this is the trap
+7:
+.endif
+ add (sp)+,(sp)
+.if .test
+ bvs 9f
+.endif
+ next
+adi.2W: 2: add (sp)+,02(sp)
+.if .test
+ bvc 2f
+ jsr pc,e.iovfl
+2:
+.endif
+ add (sp)+,02(sp)
+ adc (sp)
+.if .test
+ bvs 9f
+.endif
+
+ next
+1:
+ jsr pc,e.oddz ; next
+/-------
+sbi.l: jsr pc,wrdoff; br 0f
+sbi.z: mov (sp)+,r0
+0: cmp r0,$04
+ bgt 1b
+ cmp r0,$02
+ bgt 2f
+ bne 1b
+sbi.1W:
+.if .test
+ cmp (sp),$und / trap for size 2 undefineds
+ beq 6f
+ cmp 2(sp),$und
+ bne 7f
+6: jsr pc,e.iund / this is the trap
+7:
+.endif
+ sub (sp)+,(sp)
+.if .test
+ bvs 9f
+.endif
+ next
+sbi.2W: 2: sub (sp)+,02(sp)
+.if .test
+ bvc 2f
+ jsr pc,e.iovfl
+2:
+.endif
+ sub (sp)+,02(sp)
+ sbc (sp)
+.if .test
+ bvs 9f
+ next
+9: jsr pc,e.iovfl
+.endif
+ next
+/------
+mli.l: jsr pc,wrdoff; br 0f
+mli.z: mov (sp)+,r0
+0:
+ cmp r0,$04
+ bgt 1f
+ beq mli4
+ cmp r0,$02
+ bne 1f
+mli.1W: mov (sp)+,r1
+.if .test
+ cmp r1,$und / trap for undefineds of size 2
+ beq 6f
+ cmp (sp),$und
+ bne 7f
+6: jsr pc,e.iund / this is the trap
+7:
+.endif
+ mul (sp)+,r1
+.if .test
+
+ bcc 9f / overflow
+ jsr pc,e.iovfl
+9:
+.endif
+ mov r1,-(sp)
+ next
+1: jmp e.oddz
+/------
+mli.2W: mli4:
+.if .prof
+ add $91.,*loprof
+ adc *hiprof
+.endif
+ jsr pc,regsave
+ tst 02(sp)
+ sxt r0
+ sub (sp),r0
+ tst 06(sp)
+ sxt r2
+ sub 04(sp),r2
+ mov r0,r4
+ mul r2,r4
+ mul 06(sp),r0
+.if .test
+ bge 2f
+ inc r4
+2:
+.endif
+ mul 02(sp),r2
+.if .test
+ bge 2f
+ inc r4
+2: sub r2,r5
+ sbc r4
+ sub r0,r5
+ sbc r4
+ add r1,r3
+ sbc r5
+ sbc r4
+.endif
+ mov 02(sp),r0
+ mul 06(sp),r0
+.if .test
+ bge 2f
+ sub $1,r5
+ sbc r4
+.endif
+2: sub r3,r0
+.if .test
+ sxt r2
+ sbc r5
+ sbc r4
+ cmp r2,r4
+ bne 2f
+ cmp r2,r5
+ beq 9f
+2: jsr pc,e.iovfl
+9:
+.endif
+ add $010,sp
+ mov r1,-(sp);
+ mov r0,-(sp);
+ jsr pc,regretu; next
+
+
+/-------
+dvi.l: jsr pc,wrdoff; br 0f
+dvi.z: mov (sp)+,r0
+0: cmp r0,$04
+ bgt 1f
+ beq dvi4
+ cmp r0,$02
+ bne 1f
+dvi.1W: mov 02(sp),r1
+ sxt r0
+.if .test
+ cmp r1,$und / trap for undifined of size 2
+ beq 6f
+ cmp (sp),$und
+ bne 7f
+6: jsr pc,e.iund / this is the trap
+7:
+.endif
+ div (sp)+,r0
+ jcs 9f
+ mov r0,(sp)
+ next
+1: jmp e.oddz
+/-------
+dvi4:
+.if .prof
+ add $100.,*loprof
+ adc *hiprof
+.endif
+ jsr pc,regsave
+ mov 02(sp),r3
+ bne 1f
+ tst (sp)
+ bne 1f
+9: jsr pc,e.idivz
+1: sxt r4
+ bpl 1f
+ neg r3
+1: cmp r4,(sp)
+ bne hardldiv
+ mov 06(sp),r2
+ mov 04(sp),r1
+ bge 2f
+ neg r1
+ neg r2
+ sbc r1
+ com r4
+2: mov r4,-(sp)
+ clr r0
+ div r3,r0
+ mov r0,-(sp)
+ mov r1,r0
+ mov r1,r4
+ mov r2,r1
+ div r3,r0
+ bvc 3f
+ mov r2,r1
+ mov r4,r0
+ sub r3,r0
+ div r3,r0
+ tst r1
+ sxt r1
+ add r1,r0
+3: mov r0,r1
+ mov (sp)+,r0
+ br 4f
+hardldiv:
+.if .prof
+ add $75.,*loprof
+ adc *hiprof
+.endif
+ clr -(sp)
+ mov 010(sp),r2
+ mov 06(sp),r1
+ bpl 5f
+ com (sp)
+ neg r1
+ neg r2
+ sbc r1
+5: clr r0
+ mov 02(sp),r3
+ bge 6f
+ neg r3
+ neg 04(sp)
+ sbc r3
+ com (sp)
+6: mov $16.,r4
+9: clc
+ rol r2
+ rol r1
+ rol r0
+ cmp r3,r0
+ bhi 7f
+ bcs 8f
+ cmp 04(sp),r1
+ blos 8f
+7: sob r4,9b
+ br 1f
+8: sub 04(sp),r1
+ sbc r0
+ sub r3,r0
+ inc r2
+ sob r4,9b
+1:
+ mov r2,r1
+ clr r0
+4: tst (sp)+
+ beq 1f
+ neg r0
+ neg r1
+ sbc r0
+1: add $010,sp
+ mov r1,-(sp);
+ mov r0,-(sp);
+ jsr pc,regretu; next
+/-------
+rmi.l: jsr pc,wrdoff; br 0f
+rmi.z: mov (sp)+,r0
+0: cmp r0,$04
+ bgt 1f
+ beq rmi4
+ cmp r0,$02
+ bne 1f
+rmi.1W: mov 02(sp),r1
+ sxt r0
+.if .test
+ cmp r1,$und / trap for undefineds of size 2
+ beq 6f
+ cmp (sp),$und
+ bne 7f
+6: jsr pc,e.iund / this is the trap
+7:
+.endif
+ div (sp)+,r0
+ bcs 9f
+ mov r1,(sp)
+ next
+1: jmp e.oddz
+/-------
+rmi4:
+.if .prof
+ add $100.,*loprof
+ adc *hiprof
+.endif
+ jsr pc,regsave
+ mov 02(sp),r3
+ bne 1f
+ tst (sp)
+ bne 1f
+9: jsr pc,e.idivz
+1: tst r3
+ sxt r4
+ bpl 1f
+ neg r3
+1: cmp r4,(sp)
+ bne hardrmi4
+ mov 06(sp),r2
+ mov 04(sp),r1
+ mov r1,r4
+ bge 2f
+ neg r1
+ neg r2
+ sbc r1
+2: mov r4,-(sp)
+ clr r0
+ div r3,r0
+ mov r1,r0
+ mov r1,r4
+ mov r2,r1
+ div r3,r0
+ bvc 3f
+ mov r2,r1
+ mov r4,r0
+ sub r3,r0
+ div r3,r0
+ tst r1
+ beq 3f
+ add r3,r1
+3: tst (sp)+
+ bpl 4f
+ neg r1
+4: sxt r0
+ br 9f
+hardrmi4:
+.if .prof
+ add $75.,*loprof
+ adc *hiprof
+.endif
+ mov 06(sp),r2
+ mov 04(sp),r1
+ bpl 5f
+ neg r1
+ neg r2
+ sbc r1
+5: clr r0
+ mov (sp),r3
+ bge 6f
+ neg r3
+ neg 02(sp)
+ sbc r3
+6: mov $16.,r4
+1: clc
+ rol r2
+ rol r1
+ rol r0
+ cmp r3,r0
+ bhi 7f
+ bcs 8f
+ cmp 02(sp),r1
+ blos 8f
+7: sob r4,1b
+ br 2f
+8: sub 02(sp),r1
+ sbc r0
+ sub r3,r0
+ sob r4,1b
+2: tst 04(sp)
+ bge 9f
+ neg r0
+ neg r1
+ sbc r0
+9: add $010,sp
+ mov r1,-(sp)
+ mov r0,-(sp)
+ jsr pc,regretu; next
+/-------
+ngi.l: jsr pc,wrdoff; br 1f
+ngi.z: mov (sp)+,r0
+1:
+lblngi:
+ cmp r0,$02
+ bgt 1f
+.if .test
+ cmp (sp),$und / trap for undefineds of size 2
+ bne 7f
+ jsr pc,e.iund
+7:
+.endif
+ neg (sp)
+3: next
+1: cmp r0,$04
+ bgt 2f
+ mov (sp),r0
+ neg (sp)
+ mov 02(sp),r1
+ neg 02(sp)
+ sbc (sp)
+ cmp r0,(sp)
+.if .test
+ bne 3b
+ cmp r1,02(sp)
+ bne 3b
+2: jsr pc,e.iovfl
+.endif
+ next
+/-------
+sli.l: jsr pc,wrdoff; br 0f
+sli.z: mov (sp)+,r0
+0: cmp r0,$02
+ bgt 1f
+sli.1W: mov (sp)+,r1
+ mov (sp)+,r0
+.if .test
+ cmp r0,$und / trap for undefined size 2
+ bne 7f
+ jsr pc,e.iund
+7:
+.endif
+ ash r1,r0
+.if .test
+ bvc 7f
+ jsr pc,e.iovfl
+7:
+.endif
+ mov r0,-(sp)
+ next
+1: cmp r0,$04
+ bgt 2f
+ mov 02(sp),r0
+ mov 04(sp),r1
+ ashc (sp)+,r0
+.if .test
+ bvc 7f
+ jsr pc,e.iovfl
+7:
+.endif
+ mov r0,(sp)
+ mov r1,02(sp)
+ next
+2: jmp e.oddz
+/-------
+sri.l: jsr pc,wrdoff; br 0f
+sri.z: mov (sp)+,r0
+0: cmp r0,$02
+ bgt 1f
+ mov (sp)+,r1
+ mov (sp)+,r0
+.if .test
+ cmp r0,$und / trap for undefined size 2
+ bne 7f
+ jsr pc,e.iund
+7:
+.endif
+ neg r1
+ ash r1,r0
+ mov r0,-(sp)
+ next
+1: cmp r0,$04
+ bgt 2f
+ mov 02(sp),r0
+ mov 04(sp),r1
+ neg (sp)
+ ashc (sp)+,r0
+ mov r0,(sp)
+ mov r1,02(sp)
+ next
+2: jmp e.oddz
+/--------------------------------------------------------------
+adu.l: jsr pc,wrdoff; br 0f
+adu.z: mov (sp)+,r0
+0: jsr pc,tstr0; add r0,sp
+ mov sp,r1; add r0,sp; asr r0
+2: adc -(sp); add -(r1),(sp); sob r0,2b
+ next
+sbu.l: jsr pc,wrdoff; br 0f
+sbu.z: mov (sp)+,r0
+0: jsr pc,tstr0; add r0,sp
+ mov sp,r1; add r0,sp; asr r0;
+2: sbc -(sp); sub -(r1),(sp); sob r0,2b
+ next
+mlu.l: jsr pc,wrdoff; br 0f
+mlu.z: mov (sp)+,r0
+0: jsr pc,tstr0
+ cmp r0,$04
+ bgt 1f
+ beq mlu4
+ mov (sp)+,r1
+ mul (sp)+,r1
+ mov r1,-(sp)
+ next
+1: jmp e.oddz
+mlu4:
+.if .prof
+ add $90.,*loprof
+ adc *hiprof
+.endif
+ jsr pc,regsave
+ clr r0
+ mov 02(sp),r1
+ mov 06(sp),r3
+ mul r3,r0
+ tst r3
+ bge 1f
+ ashc $15.,r0
+1: mov 02(sp),r3
+ clr r2
+ mul 04(sp),r2
+ add r3,r0
+ mov 06(sp),r3
+ clr r2
+ mul (sp),r2
+ add r3,r0
+ add $010,sp
+ mov r1,-(sp)
+ mov r0,-(sp)
+ jsr pc,regretu; next
+9: jmp e.oddz
+/-------
+dvu.l: jsr pc,wrdoff; br 0f
+dvu.z: mov (sp)+,r0
+0:
+ clr saver0;
+ cmp r0,$04
+ bgt 9b
+ beq dvu4
+ clr r0
+ mov 02(sp),r1
+ tst (sp)
+ blt 1f
+ div (sp)+,r0
+ mov r0,(sp); next
+1: mov (sp),-(sp);
+ clr 02(sp);
+ clr -(sp);
+ mov $1,saver0;
+dvu4:
+.if .prof
+ add $95.,*loprof
+ adc *hiprof
+.endif
+ jsr pc,regsave
+ clr r0
+ tst (sp)
+ bne harddvu4
+ tst 02(sp)
+ blt harddvu4
+ mov 06(sp),r2
+ mov 04(sp),r1
+ mov 02(sp),r3
+ div r3,r0
+ mov r0,-(sp)
+ mov r1,r0
+ mov r1,r4
+ mov r2,r1
+ div r3,r0
+ bvc 1f
+ mov r2,r1
+ mov r4,r0
+ sub r3,r0
+ div r3,r0
+ tst r1
+ sxt r1
+ add r1,r0
+1: mov r0,r1
+ mov (sp)+,r0
+ br 2f
+harddvu4:
+.if .prof
+ add $75.,*loprof
+ adc *hiprof
+.endif
+ mov 06(sp),r2
+ mov 04(sp),r1
+ mov (sp),r3
+ mov $17.,r4
+ br 3f
+6: rol r2
+ rol r1
+ rol r0
+3: cmp r3,r0
+ bhi 4f
+ blo 5f
+ cmp 02(sp),r1
+ blos 5f
+4: clc
+ sob r4,6b
+ br 7f
+5: sub 02(sp),r1
+ sbc r0
+ sub r3,r0
+ sec
+ sob r4,6b
+7: rol r2
+ bcc 8f
+ mov $01,r0
+ br 9f
+8: clr r0
+9: mov r2,r1
+2: add $010,sp
+ mov r1,-(sp)
+ mov r0,-(sp)
+ jsr pc,regretu
+ tst saver0;
+ beq 2f;
+ tst (sp)+
+2:
+ next
+/-------
+9: jbr e.oddz
+rmu.l: jsr pc,wrdoff; br 0f
+rmu.z: mov (sp)+,r0
+0: clr saver0;
+ cmp r0,$04
+ bgt 9b
+ beq rmu4
+ cmp r0,$02
+ bne 9b
+ mov $1,saver0;
+ mov 02(sp),r1
+ tst (sp)
+ blt 1f
+ clr r0
+ div (sp)+,r0
+ mov r1,(sp); next
+1: mov (sp),-(sp)
+ clr 02(sp)
+ clr -(sp)
+rmu4:
+.if .prof
+ add $95.,*loprof
+ adc *hiprof
+.endif
+ jsr pc,regsave
+ clr r0
+ tst (sp)
+ bne hardrmu4
+ tst 02(sp)
+ blt hardrmu4
+ mov 06(sp),r2
+ mov 04(sp),r1
+ mov 02(sp),r3
+ div r3,r0
+ mov r1,r0
+ mov r1,r4
+ mov r2,r1
+ div r3,r0
+ bvc 1f
+ mov r2,r1
+ mov r4,r0
+ sub r3,r0
+ div r3,r0
+ tst r1
+ beq 1f
+ add r3,r1
+1: clr r0
+ br 2f
+hardrmu4:
+.if .prof
+ add $75.,*loprof
+ adc *hiprof
+.endif
+ mov 06(sp),r2
+ mov 04(sp),r1
+ mov (sp),r3
+ mov $17.,r4
+ br 3f
+6: clc
+ rol r2
+ rol r1
+ rol r0
+3: cmp r3,r0
+ bhi 4f
+ bcs 5f
+ cmp 02(sp),r1
+ blos 5f
+4: sob r4,6b
+ br 2f
+5: sub 02(sp),r1
+ sbc r0
+ sub r3,r0
+ sob r4,6b
+2: add $010,sp
+ mov r1,-(sp)
+ mov r0,-(sp)
+ jsr pc,regretu
+ tst saver0
+ beq 2f;
+ tst (sp)+;
+2: next
+/-------
+slu.l: jsr pc,wrdoff; br 0f
+slu.z: mov (sp)+,r0
+0:
+ cmp r0,$02
+ bgt 1f
+ mov (sp)+,r1
+ mov (sp)+,r0
+ ash r1,r0
+ mov r0,-(sp)
+ next
+1: cmp r0,$04
+ bgt 2f
+ mov 02(sp),r0
+ mov 04(sp),r1
+ ashc (sp)+,r0
+ mov r0,(sp)
+ mov r1,02(sp)
+ next
+2: jmp e.oddz
+/-------
+sru.l: jsr pc,wrdoff; br 0f
+sru.z: mov (sp)+,r0
+0:
+ cmp r0,$02
+ bgt 1f
+ mov 2(sp),r1
+ neg (sp)
+ clr r0
+ ashc (sp)+,r0
+2: mov r1,-(sp)
+ next
+1: cmp r0,$04
+ bgt 3f
+ mov 02(sp),r0
+ mov 04(sp),r1
+ neg (sp)
+ beq 4f
+ ashc $-1,r0
+ bic $0100000,r0
+ inc (sp)
+ beq 4f
+ ashc (sp)+,r0
+4: mov r0,(sp)
+ mov r1,02(sp)
+ next
+3: jmp e.oddz
+/-------
+
+/--------------------------------------------------------------
+ / FLOATING POINT INSTRUCTIONS
+/--------------------------------------------------------------
+
+adf.s0: clr r0; bisb (pcx)+,r0; br 0f
+adf.l: jsr pc,wrdoff; br 0f
+adf.z: mov (sp)+,r0
+0:
+ jsr pc,setfloat
+ movf (sp)+,fr0
+ addf (sp)+,fr0
+ movf fr0,-(sp)
+ next
+/-------
+
+sbf.s0: clr r0; bisb (pcx)+,r0; br 0f
+sbf.l: jsr pc,wrdoff; br 0f
+sbf.z: mov (sp)+,r0
+0:
+ jsr pc,setfloat
+ movf (sp)+,fr0
+ subf (sp)+,fr0
+ negf fr0
+ movf fr0,-(sp)
+ next
+/-------
+
+mlf.s0: clr r0; bisb (pcx)+,r0; br 0f
+mlf.l: jsr pc,wrdoff; br 0f
+mlf.z: mov (sp)+,r0
+0:
+ jsr pc,setfloat
+ movf (sp)+,fr0
+ mulf (sp)+,fr0
+ movf fr0,-(sp)
+ next
+/-------
+
+dvf.s0: clr r0; bisb (pcx)+,r0; br 0f
+dvf.l: jsr pc,wrdoff; br 0f
+dvf.z: mov (sp)+,r0
+0:
+ jsr pc,setfloat
+ movf (sp)+,fr0
+ movf (sp)+,fr1
+ divf fr0,r1
+ movf fr1,-(sp)
+ next
+/-------
+
+ngf.l: jsr pc,wrdoff; br 0f
+ngf.z: mov (sp)+,r0
+0:
+ jsr pc,setfloat
+ negf (sp)
+ next
+/-------
+
+fif.l: jsr pc,wrdoff; br 0f
+fif.z: mov (sp)+,r0
+0:
+ jsr pc,setfloat
+ movf (sp)+,fr0
+ modf (sp)+,fr0
+ movf fr0,-(sp)
+ movf fr1,-(sp)
+ next
+/-------
+
+fef.l: jsr pc,wrdoff; br 0f
+fef.z: mov (sp)+,r0
+0:
+ jsr pc,setfloat
+ movf (sp),fr0
+ movei fr0,-(sp)
+ movie $0,fr0
+ movf fr0,02(sp)
+ next
+/----------------------------------------------------------------------------
+/ TEST AND BRANCH GROUP
+/----------------------------------------------------------------------------
+tlt.z: tst (sp)+; blt true; clr -(sp); next
+tle.z: tst (sp)+; ble true; clr -(sp); next
+teq.z: tst (sp)+; beq true; clr -(sp); next
+tne.z: tst (sp)+; bne true; clr -(sp); next
+tge.z: tst (sp)+; bge true; clr -(sp); next
+tgt.z: tst (sp)+; bgt true; clr -(sp); next
+/----------------------------------------------------------------------------
+zlt.s0: tst (sp)+; blt yesbr2; br nobr2
+zlt.l: tst (sp)+; blt yesbr3; br nobr3
+zle.s0: tst (sp)+; ble yesbr2; br nobr2
+zle.l: tst (sp)+; ble yesbr3; br nobr3
+zeq.s0: tst (sp)+; beq yesbr2; br nobr2
+zeq.s1: tst (sp)+; beq yesbr4; br nobr2
+zeq.l: tst (sp)+; beq yesbr3; br nobr3
+zne.s0: tst (sp)+; bne yesbr2; br nobr2
+zne.l: tst (sp)+; bne yesbr3; br nobr3
+zne.s_1: tst (sp)+; bne yesbr5; br nobr2
+zge.s0: tst (sp)+; bge yesbr2; br nobr2
+zge.l: tst (sp)+; bge yesbr3; br nobr3
+zgt.s0: tst (sp)+; bgt yesbr2; br nobr2
+zgt.l: tst (sp)+; bgt yesbr3; br nobr3
+great:
+true: mov $1,-(sp)
+ next
+
+/------------------------------------------------------------------------------
+
+blt.s0: cmp (sp)+,(sp)+; bgt yesbr2; br nobr2
+blt.l: cmp (sp)+,(sp)+; bgt yesbr3; br nobr3
+ble.s0: cmp (sp)+,(sp)+; bge yesbr2; br nobr2
+ble.l: cmp (sp)+,(sp)+; bge yesbr3; br nobr3
+beq.l: cmp (sp)+,(sp)+; beq yesbr3; br nobr3
+beq.s0: cmp (sp)+,(sp)+; beq yesbr2; br nobr2
+bne.s0: cmp (sp)+,(sp)+; bne yesbr2; br nobr2
+bne.l: cmp (sp)+,(sp)+; bne yesbr3; br nobr3
+bge.s0: cmp (sp)+,(sp)+; ble yesbr2; br nobr2
+bge.l: cmp (sp)+,(sp)+; ble yesbr3; br nobr3
+bgt.s0: cmp (sp)+,(sp)+; blt yesbr2; br nobr2
+bgt.l: cmp (sp)+,(sp)+; blt yesbr3; br nobr3
+
+bra.s0: yesbr2:
+ clr r0;
+5: bisb (pcx)+,r0
+1: add r0,pcx
+ next
+bra.l: yesbr3:
+ jsr pc,wrdoff
+ br 1b
+bra.s1: yesbr4: mov $400,r0; br 5b
+bra.s_1: yesbr5: mov $-400,r0; br 5b
+bra.s_2: mov $-800,r0; br 5b
+nobr2: tstb (pcx)+
+ next
+nobr3: cmpb (pcx)+,(pcx)+
+ next
+/\f
+/------------------------------------------------------------------------------
+/ Compare group
+/------------------------------------------------------------------------------
+
+calccomp: mov (sp)+,saver1; / old pc
+ mov sp,r1;
+ add r0,r1; mov r1,r5;
+ add r0,r1; mov r1,saver0; / new sp
+ mov r0,r1; asr r1;
+2: cmp (r5)+,(sp)+; blt 3f;
+ bgt 4f; dec r1;
+ beq 5f
+2: cmp (r5)+,(sp)+; blo 3f;
+ bhi 4f; sob r1,2b;
+5: mov saver0,sp; clr -(sp);
+ br 5f
+4: mov saver0,sp; mov $1,-(sp);
+ br 5f
+3: mov saver0,sp; mov $-1,-(sp);
+ br 5f
+5: mov saver1,-(sp); rts pc
+
+cmi.1W: mov $2,r0; br 1f
+cmi.2W: mov $4,r0; br 1f
+cmi.l: jsr pc,wrdoff; br 1f
+cmi.z: mov (sp)+,r0;
+1: jsr pc,calccomp; next
+cms.s0: clr r0; bisb (pcx)+,r0
+1: jsr pc,calccomp; tst (sp)+;
+ bne great; clr -(sp); next
+cms.l: jsr pc,wrdoff; br 1b
+cms.z: mov (sp)+,r0; br 1b
+cmu.l: jsr pc,wrdoff; br 1f
+cmu.z: mov (sp)+,r0; br 1f
+cmp.z: mov $2,r0;
+1: jsr pc,calccomp; mov (sp)+,r1;
+ jlo less; jhi great;
+ clr -(sp); next
+cmf.s0: clr r0; bisb (pcx)+,r0;
+1: cmp $4,r0; beq 3f
+ cmp $8,r0; beq 3f
+ jsr pc,e.oddz;
+3: jsr pc,setfloat
+ movf (sp)+,fr0; cmpf (sp)+,fr0;
+4: cfcc; jlt less; jgt great;
+ clr -(sp); next
+cmf.l: jsr pc,wrdoff; br 1b
+cmf.z: mov (sp)+,r0; br 1b
+less: mov $-1,-(sp); next
+
+/------------------------------------------------------------------------------
+/------------------------------------------------------------------------------
+/------------------------------------------------------------------------------
+/ call and return group
+/------------------------------------------------------------------------------
+/
+/ Frame format on the stack is:
+/
+/ | Parameter 1 |
+/ | - - - - - - - - - - - - |
+/ | Static link = param 0 | < AB
+/ |_________________________| ____
+/ |-------------------------| | P
+/ | Saved line number | | R
+/ |-------------------------| | O
+/ | Saved file address | | C
+/ |-------------------------| | F
+/ | Return address | | R
+/ |-------------------------| | A
+/ | Dynamic link | < LB | M
+/ |_________________________| ____| E
+/ |-------------------------|
+/ | |
+/ | local variable -1 |
+/ |-------------------------|
+/ | |
+/
+/
+/ The static link and the parameters are set by the
+/ calling procedure; the frame is set by cal which reserves
+/ also the space for local variables.
+/------------------------------------------------------------------------------
+
+cal.1: cal.2: cal.3: cal.4: cal.5: cal.6: cal.7: cal.8:
+cal.9: cal.10: cal.11: cal.12: cal.13: cal.14: cal.15: cal.16:
+cal.17: cal.18: cal.19: cal.20: cal.21: cal.22: cal.23: cal.24:
+cal.25: cal.26: cal.27: cal.28:
+
+ asr r0; sub $077,r0; br 1f
+cal.s0: clr r0; bisb (pcx)+,r0; br 1f
+cai.z: mov (sp)+,r0; br 1f
+cal.l: jsr pc,wrdoff
+lblcal:
+1:
+ cmp nprocs,r0
+ jlos e.badpc
+1: asl r0; asl r0;
+.if .flow + .count + .prof
+ mov r0,r5;
+ asl r5
+ add r5,r0 / procdes 12 bytes in this case
+.endif
+ add pd,r0; / now r0 points to the bottom
+ / of the proc descriptor
+ mov *eb,-(sp) / save line number
+ mov *filb,-(sp) / save file address
+
+.if .prof + .count + .flow
+ tst 10.(r0) / yet a filename defined in this proc?
+ bne 4f / yes? continue
+ mov (sp),10.(r0) / no? Then take the old filename
+4: mov curproc,(sp) / save old procdescriptor
+ mov r0,curproc / continue with the new one
+ mov 4(r0),countfld / count pointer minus line number
+ sub 6(r0),countfld / to add at line numbers
+.endif
+ mov pcx,-(sp) / return address
+ mov r2,-(sp) / old local base
+ mov sp,r2 / new local base
+ mov (r0)+,r1 / number of bytes for locals
+ beq 3f / no locals
+ inc r1; asr r1 / make even
+2: mov $und,-(sp) / make undefined
+ sob r1,2b / for r1 words local
+3: mov (r0),pcx / em start address
+ next / ready
+/------------------------------------------------------------------------------
+
+ret.l: jsr pc,wrdoff; br 1f
+ret.1W: mov $2,r0; br 1f
+ret.s0: clr r0; bisb (pcx)+,r0;
+ jlt e.oddz / bad result size
+ beq ret.0 / no result
+ cmp $32.,r0; bge 1f; jsr pc,e.badlfr
+1: inc r0; asr r0 / make even
+ mov r0,retsize / result size
+ mov $retarea,r1 / must point to retarea
+2: mov (sp)+,(r1)+ / load result
+ sob r0,2b / continue when there is more
+ br 3f
+retcount:
+ret.0: clr retsize / no function result
+3: mov r2,sp / set sp to bottom frame
+ mov (sp)+,r2 / restore (dynamic) local base
+ jeq lblhalt; / if zero then main procedure returns
+ mov (sp)+,pcx / return address in program counter
+ mov eb,r1 / must point to external base
+ mov (sp)+,r0 / file or procdesbase in r0
+.if .count + .flow + .prof
+ mov r0,curproc / save procdesbase current proc
+ mov 4(r0),countfld / restore pointer to
+ beq 5f / countfield 0 non interesting
+ sub 6(r0),countfld / table entries
+ mov countfld,countptr
+ add (sp),countptr
+.if .prof
+ tst (sp)
+ beq 5f
+ mov countptr,r5
+ asl r5
+ asl r5
+ add ltime,r5
+ mov r5,hiprof
+ add $2,r5
+ mov r5,loprof
+.endif
+5:
+ mov 10.(r0),r0 / pointer to file name in r0
+.endif
+retlast:
+.if .last
+ tst 4(r1) / file 0 not stacked
+ beq 4f
+ cmp r0,4(r1) / same file name?
+ beq 4f / yes continue
+ jsr pc,nexttab / next line table entry in r5
+ clr (r5) / 0 indicates file pointer follows
+ jsr pc,nexttab / next entry in r5
+ mov 4(r1),(r5) / store pointer to file name
+5: mov (sp),(r1) / restored line number in *eb
+ beq 4f / do not put 0 in last table
+ jsr pc,nexttab / next entry in r5
+ mov (sp),(r5) / line number in table
+4: cmp (sp),(r1) / line number different?
+ bne 5b / yes? put it in table
+.endif
+ mov r0,4(r1) / old file address
+ mov (sp)+,(r1) / reset line number
+ next / main loop again
+
+lfr.l: jsr pc,wrdoff;
+8: bit $1,r0; jne e.illins
+ cmp r0,retsize; jeq 7f; jsr pc,e.badlfr
+7: asr r0; / number of words
+ tst r0; beq 0f;
+ mov $retarea,r1; / must point to retarea
+ add r0,r1;
+ add r0,r1; / top of result
+2: mov -(r1),-(sp); / move word of result
+ sob r0,2b; / look for more
+0: next
+lfr.1W: mov $2,r0; br 8b
+lfr.2W: mov $4,r0; br 8b
+lfr.s0: clr r0; bisb (pcx)+,r0; br 8b
+/\f
+/------------------------------------------------------------------------------
+
+/ miscellaneous
+/------------------------------------------------------------------------------
+exg.s0: clr r0; bisb (pcx)+,r0; br 1f
+exg.l: jsr pc,wrdoff; br 1f
+exg.z: mov (sp)+,r0;
+1: cmp r0,$1; beq 0f;
+ blt 9f; bit $1,r0;
+ bne 9f;
+ add r0,sp;
+ mov r0,r1; asr r1;
+ add sp,r0;
+2: mov -(sp),r5; mov -(r0),(sp);
+ mov r5,(r0); sob r1,2b;
+ next
+0: swab (sp); next
+9: jsr pc,e.oddz; next
+
+
+
+
+/------------------------------------------------------------------------------
+
+dup.1W: mov (sp),-(sp); next
+dup.l: jsr pc,wrdoff; br 1f;
+dus.l: jsr pc,wrdoff; br 0f;
+dus.z: mov (sp)+,r0;
+0: ble 9b; bit $1,r0;
+ bne 9b; add r0,sp;
+ tst -(sp); mov (sp)+,r0;
+1: ble 9b; inc r0;
+ bic $1,r0; mov r0,r1;
+ mov sp,r5; add r0,r5;
+ asr r1;
+2: mov -(r5),-(sp); sob r1,2b; next
+
+nop.z:
+ next
+
+/------------------------------------------------------------------------------
+fil.l: jsr pc,wrdoff; add eb,r0
+ cmp r0,*filb; beq 1f;
+.if .last
+ clr *eb / new file asks for new line
+ jsr pc,nexttab; clr (r5);
+ jsr pc,nexttab; mov *filb,(r5);
+.endif
+.if .flow + .count + .prof
+ mov curproc,r1 / current proc descriptor
+ mov 4(r1),countfld
+ sub 6(r1),countfld / start countptr for this proc
+ mov r0,10.(r1) / file pointer in procdes
+.endif
+ mov r0,*filb
+1: next
+lni.z: inc *eb;
+.if .count + .flow + .prof
+ inc countptr
+.if .prof
+ add $4,hiprof
+ add $4,loprof
+.endif
+.endif
+ br 8f
+lin.l: jsr pc,wrdoff; br 1f
+lin.s0: clr r0; bisb (pcx)+,r0
+1: cmp *eb,r0; beq 9f;
+ mov r0,*eb
+.if .count + .flow + .prof
+ mov countfld,r5
+ add r0,r5 / this is the right countptr
+ mov r5,countptr
+.if .prof
+ asl r5
+ asl r5
+ add ltime,r5
+ mov r5,hiprof
+ add $2,r5
+ mov r5,loprof
+.endif
+.endif
+8:
+.if .last
+ jsr pc,nexttab / next entry in lasttab
+ mov *eb,(r5) / set endline
+.endif
+.if .count
+ mov countptr,r1 / line number in r1
+ asl r1
+ asl r1 / multiply by 4
+ add lcount,r1 / r1 is pointer to long integer now
+ add $1,2(r1) / cannot be inc
+ adc (r1) / that was all
+.endif
+.if .flow
+ mov countptr,r1 / line number in r1
+ clr r0 / get ready for divide
+ div $8.,r0 / r0 = byte offset; r1 = bit offset
+ add lflow,r0 / r0 is byte pointer now
+ bisb bits(r1),(r0) / set bit
+.endif
+9: next
+
+/------------------------------------------------------------------------------
+
+bls.l: jsr pc,wrdoff; br 0f;
+bls.z: mov (sp)+,r0;
+0: asr r0
+ bhi 1f
+ jbr e.oddz
+1: mov (sp)+,r1; sob r0,1b;
+ mov r1,r0; br 1f;
+blm.l: jsr pc,wrdoff
+ tst r0
+ br 1f
+blm.s0: clr r0; bisb (pcx)+,r0
+1: jsr pc,regsave; jsr pc,chckptr
+ mov (sp)+,r2; jsr pc,chckptr
+ mov (sp)+,r3
+ mov r0,r1
+ asr r0
+ beq 2f / Now avoid wrong copy. The pieces may overlap !
+ cmp r3,r2
+ beq 2f
+ blt 3f
+1: mov (r3)+,(r2)+
+ sob r0,1b
+2: jsr pc,regretu; next
+3: add r1,r3; add r1,r2;
+1: mov -(r3),-(r2); sob r0,1b; br 2b
+/------------------------------------------------------------------------------
+/ Range check and case instructions
+/------------------------------------------------------------------------------
+csa.l: jsr pc,wrdoff; br 1f;
+csa.z: mov (sp)+,r0;
+1: sub $2,r0; jne e.illins;
+csa.1W: mov (sp)+,r0;
+ mov (sp)+,r1; sub 2(r0),r1;
+ blt 6f; cmp 4(r0),r1;
+ blo 6f; asl r1;
+ add $6,r1; add r0,r1;
+5: mov (r1),pcx;
+ jeq e.case; next
+6: mov r0,r1; br 5b;
+
+csb.z: mov (sp)+,r0; br 1f;
+csb.l: jsr pc,wrdoff;
+1: sub $2,r0; jne e.illins;
+csb.1W: mov (sp)+,r0; mov (sp)+,r1;
+ mov 2(r0),r5; mov r0,pcx;
+ /use pcx as ordinary register
+2: add $4,r0; cmp (r0),r1;
+ beq 4f; sob r5,2b;
+ mov (pcx),pcx; jeq e.case; next
+4: mov 2(r0),pcx; jeq e.case; next
+
+rck.l: jsr pc,wrdoff; br 1f;
+rck.z: mov (sp)+,r0;
+1: sub $2,r0; beq rck.1W;
+ sub $2,r0; jne e.oddz;
+ mov (sp)+,r1; cmp (sp),(r1);
+ blt 9f; cmp (sp),4(r1);
+ bgt 9f; next
+rck.1W: mov (sp)+,r1; cmp (sp),(r1);
+ blt 9f; cmp (sp),2(r1);
+ bgt 9f; next
+9: mov $ERANGE,-(sp); jmp trp.z;
+
+/------------------------------------------------------------------------------
+/ Load and store register
+/------------------------------------------------------------------------------
+lbllor:
+lor.s0: clr r0; bisb (pcx)+,r0
+ cmp r0,$2; jhi e.illins
+ asl r0; jmp 1f(r0)
+1: br 2f; br 3f; br 4f
+2: mov lb,-(sp); next
+3: mov sp,r1; mov r1,-(sp); next
+4: mov hp,-(sp); next
+lblstr:
+str.s0: clr r0; bisb (pcx)+,r0
+ cmp r0,$2; jhi e.illins
+ asl r0; jmp 1f(r0)
+1: br 2f; br 3f; br 4f
+2: mov (sp)+,lb; next
+3: mov (sp)+,r1; mov r1,sp; next
+4: mov (sp)+,r1;
+5: cmp r1,sybreak+2;
+ blos 5f; add $unixextra,sybreak+2;
+ sys indir;sybreak / ask for more core
+ jec 5b;
+ jsr pc,e.heap; / core claim failed
+5: cmp r1,globmax; jlo e.heap;
+ mov r1,hp; next
+
+/------------------------------------------------------------------------------
+
+ass.l: jsr pc,wrdoff; br 1f
+ass.z: mov (sp)+,r0;
+1: cmp $2,r0; beq 2f
+ cmp $4,r0; jne e.oddz
+ mov (sp)+,r0;
+2: mov (sp)+,r0; br 3f
+asp.lw: jsr pc,wrdoff; br 2f
+asp.w0: clr r0; bisb (pcx)+,r0;
+2: asl r0; br 3f
+asp.1W: asp.2W: asp.3W: asp.4W: asp.5W:
+ sub $88.,r0;
+3: blt 4f; add r0,sp; next
+4: neg r0; asr r0;
+2: mov $und,-(sp); sob r0,2b; next
+
+
+/------------------------------------------------------------------------------
+
+dch.z: mov (sp)+,r1; mov (r1),-(sp);
+ cmp (sp),ml; jge e.badptr;
+ next / dch adjusts local base to
+ / dynamically previous local base
+
+lpb.z: add $8.,(sp); next / static link 8 bytes from lb
+
+/------------------------------------------------------------------------------
+
+gto.l: jsr pc,wrdoff; / get descriptor address
+ add eb,r0 / descriptor is in external address space
+ mov 4(r0),r2; / new local base after jump
+ mov 2(r0),sp; / new stack pointer after jump
+ mov (r0),pcx; / new program counter
+.if .prof + .flow + .count
+ mov firstp,r0
+1: mov 8.(r0),r1
+ cmp r3,2(r1)
+ blos 2f
+ mov r1,r0
+ br 1b
+2: mov r0,curproc / procdesbase current proc
+ mov 4(r0),countfld / restore pointer to
+ sub 6(r0),countfld / table entries
+ mov 10.(r0),*filb / file name restored
+.endif
+ next
+/------------------------------------------------------------------------------
+/ Ignore mask
+/------------------------------------------------------------------------------
+
+lim.z: mov ignmask,-(sp); next / load ignore mask
+sim.z: mov (sp)+,ignmask; next / store ignore mask
+ / for trap routines
+
+sig.z: mov (sp),r1; / exchange previous
+ mov uerrorp,(sp); / and stacked error
+ mov r1,uerrorp; / procedure pointer
+ next
+/------------------------------------------------------------------------------
+/ Signals generated by UNIX
+/------------------------------------------------------------------------------
+
+sig1:
+ mov $sig.trp+0.,-(sp); br 1f
+sig2:
+ mov $sig.trp+2.,-(sp); br 1f
+sig3:
+ mov $sig.trp+4.,-(sp); br 1f
+sig13:
+ mov $sig.trp+24.,-(sp); br 1f
+sig14:
+ mov $sig.trp+26.,-(sp); br 1f
+sig15:
+ mov $sig.trp+28.,-(sp); br 1f
+sig16:
+ mov $sig.trp+30.,-(sp) / push address trap number
+1: mov *(sp),-2(sp); / save trap number
+ mov $-2,*(sp) / set defold trap number
+ mov $retutrap,(sp) / set return address to rti
+ tst -(sp) / trap number position on stack
+ jbr error
+
+sig12: mov r0,-(sp)
+ mov $2,r0; / fildes standard error
+ sys 0; 9b / call write message
+ sys signal;12.;sig12 / this is a mon-error
+ jsr pc,e.badmon
+ mov (sp)+,r0
+ rti
+
+sig11: mov r0,saver1 /save r0
+ mov sybreak+2,r0
+ sub sp,r0
+ jgt e.memflt /real trap
+ mov $7f,r0
+ mov argv,sp /setup a new stack
+ jbr rude_error
+
+ .data
+7: <stack overflow\n\0>
+ .even
+sybreak:sys break;_end /For indirect calling of break
+ .text
+sig8: mov r0,saver1;
+ sys signal;8.;sig8
+ mov $ECONV,fpperr+6
+ stfps r0
+ bit $100,r0
+ beq 1f
+ mov $ECONV,fpperr+6
+1: stst r0
+ mov $retutrap,-(sp)
+ mov fpperr(r0),-(sp)
+ mov saver1,r0
+ jbr error
+retutrap: rti
+ .data
+fpperr: EILLINS; EILLINS; EFDIVZ; ECONV; EFOVFL; EFUNFL; EFUND; EILLINS
+ .text
+/------------------------------------------------------------------------------
+/ Errors,traps and all their friends
+
+/------------------------------------------------------------------------------
+
+savereg: mov r1,-(sp) / stack r1 so r1 scratch register
+ mov 2(sp),r1 / now r1 contains return address
+ mov r0,2(sp) / save r0
+ mov r2,-(sp) / save r2
+ mov r3,-(sp) / save r3
+ mov r4,-(sp) / save r4
+ mov r5,-(sp) / save r5
+ mov 12.(sp),r0 / copy error number or param 0
+ movf fr0,-(sp) / save float registers
+ movf fr1,-(sp) / fr0 and fr1
+ stfps -(sp) / and status
+ mov $retsize+26.,r5
+ mov $13.,r2
+8: mov -(r5),-(sp); sob r2,8b
+ mov r0,-(sp) / extra errno (param 0) on stack
+ mov r1,-(sp) / set return address
+ rts pc
+
+restoreg: mov (sp)+,r1 / return address in r1
+ add $2,sp / skip error number (param 0)
+ mov $13.,r2;
+ mov $retsize,r5;
+8: mov (sp)+,(r5)+; sob r2,8b
+ ldfps (sp)+ / restore floating point status
+ movf (sp)+,fr1 / restore float registers
+ movf (sp)+,fr0 / fr0 and fr1
+ mov (sp)+,r5 / restore r5
+ mov (sp)+,r4 / restore r4
+ mov (sp)+,r3 / restore r3
+ mov (sp)+,r2 / restore r2
+ mov 2(sp),r0 / restore r0
+ mov r1,2(sp) / reset return address
+ mov (sp)+,r1 / restore r1
+ rts pc
+
+/------------------------------------------------------------------------------
+/ Various error entries
+/------------------------------------------------------------------------------
+
+e.badlfr: mov r0,r5; mov $2,r0; mov $blfr,9f+2
+ sys 0;9f;
+ mov r5,r0; rts pc
+.data
+9: sys write;7;0;
+blfr: <badlfr\n\0>
+.even
+.text
+
+e.iund: mov $EIUND,-(sp); br error
+e.iovfl: mov $EIOVFL,-(sp); br error
+e.idivz: mov $EIDIVZ,-(sp); br error
+e.range: mov $ERANGE,-(sp); br error
+e.set: mov $ESET,-(sp); br error
+e.badptr: mov $EBADPTR,-(sp); br fatal
+e.fovfl: mov $EFOVFL,-(sp); br error
+e.funfl: mov $EFUNFL,-(sp); br error
+e.fdivz: mov $EFDIVZ,-(sp); br error
+e.fund: mov $EFUND,-(sp); br error
+e.conv: mov $ECONV,-(sp); br error
+e.stack: mov $ESTACK,-(sp); br fatal
+e.badpc: mov $EBADPC,-(sp); br fatal
+e.badlin: mov $EBADLIN,-(sp); br error
+e.badlae: mov $EBADLAE,-(sp); br error
+e.array: mov $EARRAY,-(sp); br error
+e.badmon: mov $EBADMON,-(sp); br error
+e.case: mov $ECASE,-(sp); br fatal
+e.oddz: mov $EODDZ,-(sp); br fatal
+e.illins: mov $EILLINS,-(sp); br fatal
+e.heap: mov $EHEAP,-(sp); br fatal
+e.memflt: mov $EMEMFLT,-(sp); br fatal
+e.badgto: mov $EBADGTO,-(sp); br error
+/------------------------------------------------------------------------------
+
+fatal: mov $hlt.z,-(sp) / return from fatal halts
+ mov 2(sp),-(sp) / dup error number
+error:
+ jsr pc,savereg / save old register contents
+ cmp $16.,r0;
+ ble 9f;
+ mov $1,r1
+ ash r0,r1
+ bic ignmask,r1
+ bne 9f
+ jsr pc,restoreg
+ add $2,sp / remove error number from stack
+ rts pc
+9:
+ cmp uerrorp,$-1 / has the user defined a trapprocedure ?
+ beq notrap / if not kill it off fast
+ mov uerrorp,-(sp) / go for cal
+ mov $-1,uerrorp / user must set trap again
+ jbr precal / call trap routine
+
+/------------------------------------------------------------------------------
+
+rtt.z: mov r2,sp / sp to bottom frame
+ add $8,sp / set to top frame
+ jsr pc,restoreg / restore status and registers
+ add $2,sp / skip error number
+ rts pc
+/------------------------------------------------------------------------------
+trp.z: mov (sp),-(sp); / error number one down
+ mov r4,2(sp); / set return address to main loop
+ jbr error / call error routine
+
+/------------------------------------------------------------------------------
+
+notrap: mov (sp),r1 / error number
+ mov $num+9.,r0
+ mov r1,retarea / set error number for exit status
+ jsr pc,itoa / make string
+ mov $num,r0
+rude_error:
+ mov r0,8f+4
+ mov *filb,8f / pointer to file name
+ mov *eb,r1 / line number
+ mov $line,8f+6 / line message
+ mov $line+21.,r0
+ jsr pc,itoa / convert to string
+1: mov $8f,r4
+2: mov (r4)+,r0 / next string
+ beq 5f
+3: mov r0,9f+2
+4: tstb (r0)+ / find zero byte
+ bne 4b
+ dec r0
+ sub 9f+2,r0 / string length
+ mov r0,9f+4
+ mov $2,r0 / diagnostic output
+ sys 0; 9f
+ jbr 2b
+5: / no file
+ mov $-1,argc
+ jbr hlt.z
+
+itoa: mov r5,-(sp)
+ mov r0,r5
+1: clr r0
+ div $10.,r0
+ add $'0,r1
+ movb r1,-(r5)
+ mov r0,r1
+ bne 1b
+ mov r5,r0
+ mov (sp)+,r5
+ rts pc
+
+ .data
+uerrorp: -1 / undefined trap procedure
+sep: <: \0>
+line: < on source line \n\0>
+num: <error \0>
+ .even
+8: 0 / name of text file
+ sep / separator
+ 0 / error
+ line+21. / line number if present
+ 0 / end of list
+lblwri:
+9: sys write;0;0
+ .text
+/------------------------------------------------------------------------------
+/ Exit instruction, with all it's crud
+/------------------------------------------------------------------------------
+
+hlt.z:
+ mov (sp)+,retarea
+.if .count + .flow + .prof
+ br 9f
+.endif
+ bne 9f
+ clr r0
+ sys exit
+9:
+lblhalt:
+ sys creat;1f;666
+.data
+1: <em_runinf\0>
+2: <runinf file failed\n\0>
+.even
+.text
+ bec 2f
+3: mov $2b,lblwri+2
+ mov $19.,lblwri+4
+ mov $2.,r0
+ sys indir;lblwri
+ br 9f
+2: mov r0,saver0
+ mov $hp,r1
+ mov r1,ndatad
+ mov $txtsiz,r5
+ mov r5,txtsiz
+ sub r5,r1
+ mov r5,lblwri+2
+ mov r1,lblwri+4
+ clr r1
+.if .last
+ add $1,r1
+.endif
+.if .opfreq
+ add $2,r1
+.endif
+.if .count
+ add $4,r1
+.endif
+.if .flow
+ add $8.,r1
+.endif
+.if .prof
+ add $16.,r1
+.endif
+ mov r1,entry.
+ sys indir;lblwri
+ bes 3b
+ mov pd,lblwri+2
+ mov tblmax,lblwri+4
+ sub pd,lblwri+4
+ mov saver0,r0
+ sys indir;lblwri
+ bes 3b
+ mov ml,lblwri+2
+ mov ml,lblwri+4
+ neg lblwri+4
+ mov saver0,r0
+ sys indir;lblwri
+ bes 3b
+9:
+ mov retarea,r0 / set exit status
+2: sys exit
+
+/------------------------------------------------------------------------------
+/ System call interface routine
+/------------------------------------------------------------------------------
+R0_IN = 0200
+R1_IN = 0100
+R0_OUT = 040
+R1_OUT = 020
+CBIT = 010
+
+lblmon:
+mon.z:
+ mov (sp)+,r0; / call number from stack
+ cmp r0,$1 / sys exit ?
+ jeq hlt.z / go there
+ bit $177700,r0; / range 0-63?
+ bne mon.bad; / no? bad call
+ movb r0,call; / move call number in system call
+ movb tab(r0),r5; / table lookup call conditions
+ cmp r5,$-1; / compare for special context
+ beq mon.special; / yes? jump to special context
+monmon: mov r5,r4; / save call conditions
+ rolb r5 / R0_IN
+ bcc 1f / check if bit 7 is on
+ mov (sp)+,r0; / call argument in r0
+1: rolb r5 / R1_IN
+ bcc 1f / check if bit 6 is on
+ mov (sp)+,r1; / argument in r1
+1: bic $177770,r4 / clear all exept bits 2,1,0
+ beq 2f / if 0 forget about args
+ mov r3,saver1 / save r3
+ mov $call+2,r3 / base of args for call
+1: mov (sp)+,(r3)+ / move argument
+ sob r4,1b / look for more
+ mov saver1,r3 / restore r3
+2: sys indir;call / this is it folks
+ bcc 1f / no error set? forward
+ mov r0,r4 / copy error in r4
+1: rolb r5 / R0_OUT
+ bcc 1f / check original bit 5
+ mov r0,-(sp) / stack r0 from errno
+1: rolb r5 / R1_OUT
+ bcc 1f / check original bit 4
+ mov r1,-(sp) / stack r1
+1: rolb r5 / CBIT
+ bcc mon.end / no c-bit then ready
+mon.cbit:
+ mov r4,-(sp) / stack errno
+ beq mon.end / only once if no error
+ mov r4,-(sp) / stack errno twice when error
+mon.end:
+ mov $loop,r4 / restore r4
+ next / ready
+
+mon.special: / special calls decoded here
+ cmp r0,$fork / fork?
+ beq mon.fork
+ cmp r0,$signal / signal?
+ beq mon.signal
+mon.bad: / otherwise undecodable
+ mov saver0,r4 / restore r4
+ jsr pc,e.badmon / mon call error routine
+ next
+
+mon.fork:
+ clr r5
+ clr r4
+ sys fork
+ inc r5
+ bcc 1f
+ mov r0,r4
+1: mov r0,-(sp)
+ mov r5,-(sp)
+ br mon.cbit
+mon.signal:
+msign:
+ mov (sp)+,r1 / trap number
+ mov (sp)+,r0 / signal number
+ cmp r0,$16. / only 1 - 16 legal
+ bhi sig.bad
+ mov r0,call+2 / move signal number into call
+ beq sig.bad / 0 illegal
+ asl r0 / make 2-32 and even
+ mov sig.trp-2(r0),r5 / previous trap number
+ cmp r1,$256. / values -1 and -2 special
+ bhis 1f
+ mov sig.adr-2(r0),r4 / zero label means illegal signal
+ bne 2f
+sig.bad:
+ mov $EINVAL,r4 / bad signal
+ jbr mon.cbit / and continue
+1: cmp r1,$-3 / -2: reset default, -3: ignore
+ blo sig.bad
+ mov r1,r4 / trap number in r4
+ inc r4
+ inc r4 / -2 -> 0, -3 -> -1
+2: mov r1,sig.trp-2(r0) / new trap number
+ / -3 if ignored; -2 if default action
+ mov r4,call+4 / translated trap number in call
+ clr r4
+ sys indir;call
+ bcs sig.bad / unlikely to happen
+ asr r0 / special if old label odd
+ bcc 1f
+ mov $-3,r5 / set ignore signal
+1: mov r5,-(sp) / push trap number
+ jbr mon.cbit
+
+
+ .data
+
+call: sys 0; 0; 0; 0; 0
+sig.trp:
+ -2; -2; -2; -2; -2; -2; -2; -2
+ -2; -2; 21.; 25.; -2; -2; -2; -2
+sig.adr:
+ sig1; sig2; sig3; 0; 0; 0; 0; sig8
+ 0; 0; sig11; sig12; sig13; sig14; sig15; sig16
+
+tab:
+.if V6
+.byte -1 / 0 = indir
+.byte -1 / 1 = exit
+.byte -1 / 2 = fork
+.byte 2 +R0_IN +R0_OUT +CBIT / 3 = read
+.byte 2 +R0_IN +R0_OUT +CBIT / 4 = write
+.byte 2 +R0_OUT +CBIT / 5 = open
+.byte 0 +R0_IN +CBIT / 6 = close
+.byte 0 +R0_OUT +R1_OUT +CBIT / 7 = wait
+.byte 2 +R0_OUT +CBIT / 8 = creat
+.byte 2 +CBIT / 9 = link
+.byte 1 +CBIT / 10 = unlink
+.byte 2 +CBIT / 11 = exec
+.byte 1 +CBIT / 12 = chdir
+.byte 0 +R0_OUT +R1_OUT / 13 = time
+.byte 3 +CBIT / 14 = mknod
+.byte 2 +CBIT / 15 = chmod
+.byte 2 +CBIT / 16 = chown
+.byte -1 / 17 = break
+.byte 2 +CBIT / 18 = stat
+.byte 2 +R0_IN +CBIT / 19 = seek
+.byte 0 +R0_OUT / 20 = getpid
+.byte 3 +CBIT / 21 = mount
+.byte 1 +CBIT / 22 = umount
+.byte 0 +R0_IN +CBIT / 23 = setuid
+.byte 0 +R0_OUT / 24 = getuid
+.byte 0 +R1_IN +R0_IN +CBIT / 25 = stime
+.byte 3 +R0_IN +R0_OUT +CBIT / 26 = ptrace
+.byte -1 / 27 = x
+.byte 1 +R0_IN +CBIT / 28 = fstat
+.byte -1 / 29 = x
+.byte -1 / 30 = x
+.byte 1 +R0_IN +CBIT / 31 = stty
+.byte 1 +R0_IN +CBIT / 32 = gtty
+.byte -1 / 33 = x
+.byte 0 +R0_IN +CBIT / 34 = nice
+.byte 0 +R0_IN / 35 = sleep
+.byte 0 / 36 = sync
+.byte 1 +R0_IN +CBIT / 37 = kill
+.byte 0 +R0_OUT / 38 = csw
+.byte -1 / 39 = x
+.byte -1 / 40 = x
+.byte 0 +R0_IN +R0_OUT +CBIT / 41 = dup
+.byte 0 +R0_OUT +R1_OUT +CBIT / 42 = pipe
+.byte 1 / 43 = times
+.byte 4 / 44 = prof
+.byte -1 / 45 = x
+.byte 0 +R0_IN +CBIT / 46 = setgid
+.byte 0 +R0_OUT / 47 = getgid
+.byte -1 / 48 = signal
+.byte -1 / 49 = reserved for USG
+.byte -1 / 50 = reserved for USG
+.byte -1 / 51 = x
+.byte -1 / 52 = x
+.byte -1 / 53 = x
+.byte -1 / 54 = x
+.byte -1 / 55 = x
+.byte -1 / 56 = x
+.byte -1 / 57 = x
+.byte -1 / 58 = x
+.byte -1 / 59 = x
+.byte -1 / 60 = x
+.byte -1 / 61 = x
+.byte -1 / 62 = x
+.byte -1 / 63 = x
+.endif
+
+.if VPLUS
+.byte -1 / 0 = indir
+.byte -1 / 1 = exit
+.byte -1 / 2 = fork
+.byte 2 +R0_IN +R0_OUT +CBIT / 3 = read
+.byte 2 +R0_IN +R0_OUT +CBIT / 4 = write
+.byte 2 +R0_OUT +CBIT / 5 = open
+.byte 0 +R0_IN +CBIT / 6 = close
+.byte 0 +R0_OUT +R1_OUT +CBIT / 7 = wait
+.byte 2 +R0_OUT +CBIT / 8 = creat
+.byte 2 +CBIT / 9 = link
+.byte 1 +CBIT / 10 = unlink
+.byte 2 +CBIT / 11 = exec
+.byte 1 +CBIT / 12 = chdir
+.byte 0 +R0_OUT +R1_OUT / 13 = time
+.byte 3 +CBIT / 14 = mknod
+.byte 2 +CBIT / 15 = chmod
+.byte 2 +CBIT / 16 = chown
+.byte -1 / 17 = break
+.byte 2 +CBIT / 18 = stat
+.byte 2 +R0_IN +CBIT / 19 = seek
+.byte 0 +R0_OUT / 20 = getpid
+.byte 3 +CBIT / 21 = mount
+.byte 1 +CBIT / 22 = umount
+.byte 0 +R0_IN +CBIT / 23 = setuid
+.byte 0 +R0_OUT / 24 = getuid
+.byte 0 +R1_IN +R0_IN +CBIT / 25 = stime
+.byte 3 +R0_IN +R0_OUT +CBIT / 26 = ptrace
+.byte 0 +R0_IN +R0_OUT / 27 = alarm
+.byte 1 +R0_IN +CBIT / 28 = fstat
+.byte 0 / 29 = pause
+.byte -1 / 30 = x
+.byte 1 +R0_IN +CBIT / 31 = stty
+.byte 1 +R0_IN +CBIT / 32 = gtty
+.byte 2 +CBIT / 33 = access
+.byte 0 +R0_IN +CBIT / 34 = nice
+.byte 0 +R0_IN / 35 = sleep
+.byte 0 / 36 = sync
+.byte 1 +R0_IN +CBIT / 37 = kill
+.byte 0 +R0_OUT / 38 = csw
+.byte -1 / 39 = x
+.byte 0 +R0_IN +R0_OUT +R1_OUT +CBIT / 40 = tell
+.byte 0 +R0_IN +R0_OUT +CBIT / 41 = dup
+.byte 0 +R0_OUT +R1_OUT +CBIT / 42 = pipe
+.byte 1 / 43 = times
+.byte 4 / 44 = prof
+.byte -1 / 45 = x
+.byte 0 +R0_IN +CBIT / 46 = setgid
+.byte 0 +R0_OUT / 47 = getgid
+.byte -1 / 48 = signal
+.byte -1 / 49 = reserved for USG
+.byte -1 / 50 = reserved for USG
+.byte 1 +CBIT / 51 = acct
+.byte -1 / 52 = x
+.byte -1 / 53 = x
+.byte -1 / 54 = x
+.byte -1 / 55 = x
+.byte -1 / 56 = x
+.byte -1 / 57 = x
+.byte -1 / 58 = x
+.byte -1 / 59 = x
+.byte -1 / 60 = x
+.byte -1 / 61 = x
+.byte -1 / 62 = x
+.byte -1 / 63 = x
+.endif
+
+.if V7
+.byte -1 / 0 = indir
+.byte 0 / 1 = exit
+.byte -1 / 2 = fork
+.byte 2 +R0_IN +R0_OUT +CBIT / 3 = read
+.byte 2 +R0_IN +R0_OUT +CBIT / 4 = write
+.byte 2 +R0_OUT +CBIT / 5 = open
+.byte 0 +R0_IN +CBIT / 6 = close
+.byte 0 +R0_OUT +R1_OUT +CBIT / 7 = wait
+.byte 2 +R0_OUT +CBIT / 8 = creat
+.byte 2 +CBIT / 9 = link
+.byte 1 +CBIT / 10 = unlink
+.byte -1 / 11 = x no exec in em code
+.byte 1 +CBIT / 12 = chdir
+.byte -1 / 13 = x time is obsolete
+.byte 3 +CBIT / 14 = mknod
+.byte 2 +CBIT / 15 = chmod
+.byte 3 +CBIT / 16 = chown
+.byte -1 / 17 = break
+.byte 2 +CBIT / 18 = stat
+.byte 3 +R0_IN +R0_OUT +R1_OUT +CBIT / 19 = lseek
+.byte 0 +R0_OUT / 20 = getpid
+.byte 3 +CBIT / 21 = mount
+.byte 1 +CBIT / 22 = umount
+.byte 0 +R0_IN +CBIT / 23 = setuid
+.byte 0 +R0_OUT +R1_OUT / 24 = getuid
+.byte 0 +R1_IN +R0_IN +CBIT / 25 = stime
+.byte 3 +R0_IN +R0_OUT +CBIT / 26 = ptrace
+.byte 0 +R0_IN +R0_OUT / 27 = alarm
+.byte 1 +R0_IN +CBIT / 28 = fstat
+.byte 0 / 29 = pause
+.byte 2 +CBIT / 30 = utime
+.byte -1 / 31 = x
+.byte -1 / 32 = x
+.byte 2 +CBIT / 33 = access
+.byte 0 +R0_IN +CBIT / 34 = nice
+.byte 1 / 35 = ftime
+.byte 0 / 36 = sync
+.byte 1 +R0_IN +CBIT / 37 = kill
+.byte -1 / 38 = x
+.byte -1 / 39 = x
+.byte -1 / 40 = x
+.byte 0 +R1_IN +R0_IN +R0_OUT +CBIT / 41 = dup
+.byte 0 +R0_OUT +R1_OUT +CBIT / 42 = pipe
+.byte 1 / 43 = times
+.byte 4 / 44 = prof
+.byte -1 / 45 = x
+.byte 0 +R0_IN +CBIT / 46 = setgid
+.byte 0 +R0_OUT +R1_OUT / 47 = getgid
+.byte -1 / 48 = signal
+.byte -1 / 49 = reserved for USG
+.byte -1 / 50 = reserved for USG
+.byte 1 +CBIT / 51 = acct
+.byte 3 +CBIT / 52 = phys
+.byte 1 +CBIT / 53 = lock
+.byte 3 +CBIT / 54 = ioctl
+.byte -1 / 55 = x
+.byte 2 +CBIT / 56 = mpxcall
+.byte -1 / 57 = x
+.byte -1 / 58 = x
+.byte 3 +CBIT / 59 = exece
+.byte 1 +CBIT / 60 = umask
+.byte 1 +CBIT / 61 = chroot
+.byte -1 / 62 = x
+.byte -1 / 63 = x
+.endif
+
+ .text
+/------------------------------------------------------------------------------
+/ General subroutines
+/------------------------------------------------------------------------------
+
+wrdoff: movb (pcx)+,r0 /get first byte
+ swab r0 /put it in high byte
+ clrb r0 /clear low byte of r0
+ bisb (pcx)+,r0 /"or" second byte in
+ rts pc /done
+
+/------------------------------------------------------------------------------
+
+tstr0: cmp r0,$04; jgt e.oddz;
+ cmp r0,$02; jne e.oddz; rts pc
+
+chckptr: / this routine traps a pointer outside
+ / the globals, the stack or the heap
+ bit $1,2(sp); bne 8f
+chckptb:
+ mov 2(sp),r5;
+ cmp r5,sp; bhis 9f
+ cmp r5,hp; bhis 8f
+.if .count + .prof + .flow
+ cmp r5,tblmax; bhis 9f
+ cmp r5,globmax; bhis 8f
+.endif
+ cmp r5,eb; bhis 9f
+8: jsr pc,e.badptr
+9: rts pc
+
+.if .last
+nexttab: mov linused,r5;
+ add $2,r5 / increment lasttab
+ cmp r5,$linused / top of table reached?
+ blo 1f
+ sub $96.,r5
+1: mov r5,linused
+ rts pc
+.endif
+regsave:
+ mov r5,savearea
+ mov $[savearea+2],r5
+ mov r4,(r5)+
+ mov r3,(r5)+
+ mov r2,(r5)
+ rts pc
+regretu:
+ mov $[savearea+6],r5
+ mov (r5),r2
+ mov -(r5),r3
+ mov -(r5),r4
+ mov -(r5),r5
+ rts pc
+
+setfloat:
+ cmp r0,$8.
+ bne 1f
+ setd
+ rts pc
+1: cmp r0,$04
+ bne 3f
+ setf
+2: rts pc
+3: jmp e.oddz
+setint:
+ cmp r0,$04
+ bne 4f
+ setl
+ rts pc
+4: cmp r0,$02
+ bne 3b
+ seti
+5: rts pc
+
+
+
+/------------------------------------------------------------------------------
+/ Leftover data
+/------------------------------------------------------------------------------
+
+
+
+
+ .bss
+filb: .=.+2
+curproc:.=.+2
+linmax: .=.+2
+countptr:.=.+2
+countfld:.=.+2
+hiprof: .=.+2
+loprof: .=.+2
+ignmask:.=.+2 / ignore mask for trap
+retsize:.=.+2 / size of return value of function
+retarea:.=.+8 / return area for function value
+savearea: .=.+8 / save register area
+saver0: .=.+2
+saver1: .=.+2
+header:
+ txtsiz: .=.+2 / program textsize in bytes
+ ndatad: .=.+2 / number of loadfile descriptors
+ nprocs: .=.+2 / number of entries in procedure descriptors
+option: entry.: .=.+2 / procedure number to start
+ nlines: .=.+2 / maximum sorceline number
+ szdata: .=.+2 / address of lowest uninitialized byte
+ firstp: .=.+2 / descriptor address first basic block of text
+ maxcount: .=.+2 / total number of processable source lines
+argc: .=.+2
+argv: .=.+2
+environ:
+ .=.+2
+pb: .=.+2
+pd: .=.+2
+eb: .=.+2
+globmax:
+ .=.+2
+tblmax: .=.+2
+ml: .=.+2
+.if .last
+lasttab:.=.+96. / 16 descriptors of integers + index at the end
+linused:.=.+2
+.endif
+
+.if .opfreq
+counttab:
+ .=.+1664.
+.endif
+
+.if .count
+lcount: .=.+2
+countsiz:.=.+2
+.endif
+
+.if .flow
+lflow: .=.+2
+flowsiz:.=.+2
+.endif
+
+.if .prof
+ltime: .=.+2
+profsiz:.=.+2
+.endif
+
+hp: .=.+2