/
/  (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The	Netherlands.
/ See the copyright notice in the ACK home directory, in the file "Copyright".
/------------------------------------------------------------------------------
/
/	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
/
/
/------------------------------------------------------------------------------
/	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

/
/------------------------------------------------------------------------------
/	Now the	real program starts
/------------------------------------------------------------------------------

startoff:
	mov	sp,r0
	mov	sp,ml
	mov	sp,filb
	add	$2,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,hp		/ top of pd space, temporarily in hp
	mov	r0,r3		/ base for data	fill

	mov	$retsize,eb	/ address of value containing 0, temporarily
	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	hp,eb		/ top of pd space
	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?
	blt	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,dat1		/ 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:
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)+
	sob	r0,4b
	next
cuu.z:
	mov	(sp)+,r0
	sub	(sp)+,r0
	asr	r0
	jbr	6b
/-------
cfu.z:
	mov	(sp)+,r1
	mov	$4,r0
	jsr	pc,setint
	mov	(sp)+,r0
	jsr	pc,setfloat
	movf	(sp)+,fr0
	movfi	fr0,-(sp)
/ unfortunately, this does not work for numbers >= 2^31
.if .test
	jcs	9b
	jlt	9b
.endif
	mov	$4,-(sp)
	mov	r1,-(sp)
	jbr	cuu.z
/-------
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
/
/------------------------------------------------------------------------------
/	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
/
/------------------------------------------------------------------------------

/	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 	r0,pcx;		mov	2(r0),r5
					/use pcx as ordinary register
	ble	3f
2:	add	$4,r0;		cmp	(r0),r1;
	beq	4f;		sob	r5,2b;
3:	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;
1:
	jsr	pc,e.heap;		   / core claim	failed
	next
5:	cmp	r1,globmax;	jlo	1b
	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      error
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
